1 //===--- ASTConcept.cpp - Concepts Related AST Data Structures --*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
10 /// \brief This file defines AST data structures related to concepts.
12 //===----------------------------------------------------------------------===//
14 #include "clang/AST/ASTConcept.h"
15 #include "clang/AST/ASTContext.h"
16 #include "clang/AST/PrettyPrinter.h"
17 #include "llvm/ADT/StringExtras.h"
19 using namespace clang
;
22 CreateUnsatisfiedConstraintRecord(const ASTContext
&C
,
23 const UnsatisfiedConstraintRecord
&Detail
,
24 UnsatisfiedConstraintRecord
*TrailingObject
) {
25 if (Detail
.is
<Expr
*>())
26 new (TrailingObject
) UnsatisfiedConstraintRecord(Detail
.get
<Expr
*>());
28 auto &SubstitutionDiagnostic
=
29 *Detail
.get
<std::pair
<SourceLocation
, StringRef
> *>();
30 StringRef Message
= C
.backupStr(SubstitutionDiagnostic
.second
);
31 auto *NewSubstDiag
= new (C
) std::pair
<SourceLocation
, StringRef
>(
32 SubstitutionDiagnostic
.first
, Message
);
33 new (TrailingObject
) UnsatisfiedConstraintRecord(NewSubstDiag
);
37 ASTConstraintSatisfaction::ASTConstraintSatisfaction(
38 const ASTContext
&C
, const ConstraintSatisfaction
&Satisfaction
)
39 : NumRecords
{Satisfaction
.Details
.size()},
40 IsSatisfied
{Satisfaction
.IsSatisfied
}, ContainsErrors
{
41 Satisfaction
.ContainsErrors
} {
42 for (unsigned I
= 0; I
< NumRecords
; ++I
)
43 CreateUnsatisfiedConstraintRecord(
44 C
, Satisfaction
.Details
[I
],
45 getTrailingObjects
<UnsatisfiedConstraintRecord
>() + I
);
48 ASTConstraintSatisfaction::ASTConstraintSatisfaction(
49 const ASTContext
&C
, const ASTConstraintSatisfaction
&Satisfaction
)
50 : NumRecords
{Satisfaction
.NumRecords
},
51 IsSatisfied
{Satisfaction
.IsSatisfied
},
52 ContainsErrors
{Satisfaction
.ContainsErrors
} {
53 for (unsigned I
= 0; I
< NumRecords
; ++I
)
54 CreateUnsatisfiedConstraintRecord(
55 C
, *(Satisfaction
.begin() + I
),
56 getTrailingObjects
<UnsatisfiedConstraintRecord
>() + I
);
59 ASTConstraintSatisfaction
*
60 ASTConstraintSatisfaction::Create(const ASTContext
&C
,
61 const ConstraintSatisfaction
&Satisfaction
) {
63 totalSizeToAlloc
<UnsatisfiedConstraintRecord
>(
64 Satisfaction
.Details
.size());
65 void *Mem
= C
.Allocate(size
, alignof(ASTConstraintSatisfaction
));
66 return new (Mem
) ASTConstraintSatisfaction(C
, Satisfaction
);
69 ASTConstraintSatisfaction
*ASTConstraintSatisfaction::Rebuild(
70 const ASTContext
&C
, const ASTConstraintSatisfaction
&Satisfaction
) {
72 totalSizeToAlloc
<UnsatisfiedConstraintRecord
>(Satisfaction
.NumRecords
);
73 void *Mem
= C
.Allocate(size
, alignof(ASTConstraintSatisfaction
));
74 return new (Mem
) ASTConstraintSatisfaction(C
, Satisfaction
);
77 void ConstraintSatisfaction::Profile(
78 llvm::FoldingSetNodeID
&ID
, const ASTContext
&C
,
79 const NamedDecl
*ConstraintOwner
, ArrayRef
<TemplateArgument
> TemplateArgs
) {
80 ID
.AddPointer(ConstraintOwner
);
81 ID
.AddInteger(TemplateArgs
.size());
82 for (auto &Arg
: TemplateArgs
)
87 ConceptReference::Create(const ASTContext
&C
, NestedNameSpecifierLoc NNS
,
88 SourceLocation TemplateKWLoc
,
89 DeclarationNameInfo ConceptNameInfo
,
90 NamedDecl
*FoundDecl
, ConceptDecl
*NamedConcept
,
91 const ASTTemplateArgumentListInfo
*ArgsAsWritten
) {
92 return new (C
) ConceptReference(NNS
, TemplateKWLoc
, ConceptNameInfo
,
93 FoundDecl
, NamedConcept
, ArgsAsWritten
);
96 void ConceptReference::print(llvm::raw_ostream
&OS
,
97 const PrintingPolicy
&Policy
) const {
99 NestedNameSpec
.getNestedNameSpecifier()->print(OS
, Policy
);
100 ConceptName
.printName(OS
, Policy
);
101 if (hasExplicitTemplateArgs()) {
103 llvm::ListSeparator
Sep(", ");
104 // FIXME: Find corresponding parameter for argument
105 for (auto &ArgLoc
: ArgsAsWritten
->arguments()) {
107 ArgLoc
.getArgument().print(Policy
, OS
, /*IncludeType*/ false);