1 //===--- ASTConcept.cpp - Concepts Related AST Data Structures --*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 ///
9 /// \file
10 /// \brief This file defines AST data structures related to concepts.
11 ///
12 //===----------------------------------------------------------------------===//
13
14 #include "clang/AST/ASTConcept.h"
15 #include "clang/AST/ASTContext.h"
16 #include "clang/AST/Decl.h"
17 #include "clang/AST/TemplateBase.h"
18 #include "llvm/ADT/ArrayRef.h"
19 #include "llvm/ADT/FoldingSet.h"
20 using namespace clang;
21
22 namespace {
CreatUnsatisfiedConstraintRecord(const ASTContext & C,const UnsatisfiedConstraintRecord & Detail,UnsatisfiedConstraintRecord * TrailingObject)23 void CreatUnsatisfiedConstraintRecord(
24 const ASTContext &C, const UnsatisfiedConstraintRecord &Detail,
25 UnsatisfiedConstraintRecord *TrailingObject) {
26 if (Detail.second.is<Expr *>())
27 new (TrailingObject) UnsatisfiedConstraintRecord{
28 Detail.first,
29 UnsatisfiedConstraintRecord::second_type(Detail.second.get<Expr *>())};
30 else {
31 auto &SubstitutionDiagnostic =
32 *Detail.second.get<std::pair<SourceLocation, StringRef> *>();
33 unsigned MessageSize = SubstitutionDiagnostic.second.size();
34 char *Mem = new (C) char[MessageSize];
35 memcpy(Mem, SubstitutionDiagnostic.second.data(), MessageSize);
36 auto *NewSubstDiag = new (C) std::pair<SourceLocation, StringRef>(
37 SubstitutionDiagnostic.first, StringRef(Mem, MessageSize));
38 new (TrailingObject) UnsatisfiedConstraintRecord{
39 Detail.first, UnsatisfiedConstraintRecord::second_type(NewSubstDiag)};
40 }
41 }
42 } // namespace
43
ASTConstraintSatisfaction(const ASTContext & C,const ConstraintSatisfaction & Satisfaction)44 ASTConstraintSatisfaction::ASTConstraintSatisfaction(
45 const ASTContext &C, const ConstraintSatisfaction &Satisfaction)
46 : NumRecords{Satisfaction.Details.size()},
47 IsSatisfied{Satisfaction.IsSatisfied}, ContainsErrors{
48 Satisfaction.ContainsErrors} {
49 for (unsigned I = 0; I < NumRecords; ++I)
50 CreatUnsatisfiedConstraintRecord(
51 C, Satisfaction.Details[I],
52 getTrailingObjects<UnsatisfiedConstraintRecord>() + I);
53 }
54
ASTConstraintSatisfaction(const ASTContext & C,const ASTConstraintSatisfaction & Satisfaction)55 ASTConstraintSatisfaction::ASTConstraintSatisfaction(
56 const ASTContext &C, const ASTConstraintSatisfaction &Satisfaction)
57 : NumRecords{Satisfaction.NumRecords},
58 IsSatisfied{Satisfaction.IsSatisfied},
59 ContainsErrors{Satisfaction.ContainsErrors} {
60 for (unsigned I = 0; I < NumRecords; ++I)
61 CreatUnsatisfiedConstraintRecord(
62 C, *(Satisfaction.begin() + I),
63 getTrailingObjects<UnsatisfiedConstraintRecord>() + I);
64 }
65
66 ASTConstraintSatisfaction *
Create(const ASTContext & C,const ConstraintSatisfaction & Satisfaction)67 ASTConstraintSatisfaction::Create(const ASTContext &C,
68 const ConstraintSatisfaction &Satisfaction) {
69 std::size_t size =
70 totalSizeToAlloc<UnsatisfiedConstraintRecord>(
71 Satisfaction.Details.size());
72 void *Mem = C.Allocate(size, alignof(ASTConstraintSatisfaction));
73 return new (Mem) ASTConstraintSatisfaction(C, Satisfaction);
74 }
75
Rebuild(const ASTContext & C,const ASTConstraintSatisfaction & Satisfaction)76 ASTConstraintSatisfaction *ASTConstraintSatisfaction::Rebuild(
77 const ASTContext &C, const ASTConstraintSatisfaction &Satisfaction) {
78 std::size_t size =
79 totalSizeToAlloc<UnsatisfiedConstraintRecord>(Satisfaction.NumRecords);
80 void *Mem = C.Allocate(size, alignof(ASTConstraintSatisfaction));
81 return new (Mem) ASTConstraintSatisfaction(C, Satisfaction);
82 }
83
Profile(llvm::FoldingSetNodeID & ID,const ASTContext & C,const NamedDecl * ConstraintOwner,ArrayRef<TemplateArgument> TemplateArgs)84 void ConstraintSatisfaction::Profile(
85 llvm::FoldingSetNodeID &ID, const ASTContext &C,
86 const NamedDecl *ConstraintOwner, ArrayRef<TemplateArgument> TemplateArgs) {
87 ID.AddPointer(ConstraintOwner);
88 ID.AddInteger(TemplateArgs.size());
89 for (auto &Arg : TemplateArgs)
90 Arg.Profile(ID, C);
91 }
92