1 //===--- ASTConcept.cpp - Concepts Related AST Data Structures --*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 ///
10 /// \file
11 /// \brief This file defines AST data structures related to concepts.
12 ///
13 //===----------------------------------------------------------------------===//
14 
15 #include "clang/AST/ASTConcept.h"
16 #include "clang/AST/ASTContext.h"
17 #include "clang/AST/Decl.h"
18 #include "clang/AST/TemplateBase.h"
19 #include "llvm/ADT/ArrayRef.h"
20 #include "llvm/ADT/FoldingSet.h"
21 using namespace clang;
22 
23 ASTConstraintSatisfaction::ASTConstraintSatisfaction(const ASTContext &C,
24     const ConstraintSatisfaction &Satisfaction):
25     NumRecords{Satisfaction.Details.size()},
26     IsSatisfied{Satisfaction.IsSatisfied} {
27   for (unsigned I = 0; I < NumRecords; ++I) {
28     auto &Detail = Satisfaction.Details[I];
29     if (Detail.second.is<Expr *>())
30       new (getTrailingObjects<UnsatisfiedConstraintRecord>() + I)
31          UnsatisfiedConstraintRecord{Detail.first,
32                                      UnsatisfiedConstraintRecord::second_type(
33                                          Detail.second.get<Expr *>())};
34     else {
35       auto &SubstitutionDiagnostic =
36           *Detail.second.get<std::pair<SourceLocation, StringRef> *>();
37       unsigned MessageSize = SubstitutionDiagnostic.second.size();
38       char *Mem = new (C) char[MessageSize];
39       memcpy(Mem, SubstitutionDiagnostic.second.data(), MessageSize);
40       auto *NewSubstDiag = new (C) std::pair<SourceLocation, StringRef>(
41           SubstitutionDiagnostic.first, StringRef(Mem, MessageSize));
42       new (getTrailingObjects<UnsatisfiedConstraintRecord>() + I)
43          UnsatisfiedConstraintRecord{Detail.first,
44                                      UnsatisfiedConstraintRecord::second_type(
45                                          NewSubstDiag)};
46     }
47   }
48 }
49 
50 
51 ASTConstraintSatisfaction *
52 ASTConstraintSatisfaction::Create(const ASTContext &C,
53                                   const ConstraintSatisfaction &Satisfaction) {
54   std::size_t size =
55       totalSizeToAlloc<UnsatisfiedConstraintRecord>(
56           Satisfaction.Details.size());
57   void *Mem = C.Allocate(size, alignof(ASTConstraintSatisfaction));
58   return new (Mem) ASTConstraintSatisfaction(C, Satisfaction);
59 }
60 
61 void ConstraintSatisfaction::Profile(
62     llvm::FoldingSetNodeID &ID, const ASTContext &C,
63     const NamedDecl *ConstraintOwner, ArrayRef<TemplateArgument> TemplateArgs) {
64   ID.AddPointer(ConstraintOwner);
65   ID.AddInteger(TemplateArgs.size());
66   for (auto &Arg : TemplateArgs)
67     Arg.Profile(ID, C);
68 }
69