clang 20.0.0git
ASTConcept.h
Go to the documentation of this file.
1//===--- ASTConcept.h - 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 provides AST data structures related to concepts.
11///
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CLANG_AST_ASTCONCEPT_H
15#define LLVM_CLANG_AST_ASTCONCEPT_H
16
21#include "llvm/ADT/FoldingSet.h"
22#include "llvm/ADT/PointerUnion.h"
23#include "llvm/ADT/SmallVector.h"
24#include <utility>
25
26namespace clang {
27
28class ConceptDecl;
29class Expr;
30class NamedDecl;
31struct PrintingPolicy;
32
33/// The result of a constraint satisfaction check, containing the necessary
34/// information to diagnose an unsatisfied constraint.
35class ConstraintSatisfaction : public llvm::FoldingSetNode {
36 // The template-like entity that 'owns' the constraint checked here (can be a
37 // constrained entity or a concept).
38 const NamedDecl *ConstraintOwner = nullptr;
40
41public:
42
44
45 ConstraintSatisfaction(const NamedDecl *ConstraintOwner,
46 ArrayRef<TemplateArgument> TemplateArgs)
47 : ConstraintOwner(ConstraintOwner), TemplateArgs(TemplateArgs) {}
48
49 using SubstitutionDiagnostic = std::pair<SourceLocation, StringRef>;
50 using Detail = llvm::PointerUnion<Expr *, SubstitutionDiagnostic *>;
51
52 bool IsSatisfied = false;
53 bool ContainsErrors = false;
54
55 /// \brief The substituted constraint expr, if the template arguments could be
56 /// substituted into them, or a diagnostic if substitution resulted in an
57 /// invalid expression.
59
60 void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &C) {
61 Profile(ID, C, ConstraintOwner, TemplateArgs);
62 }
63
64 static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &C,
65 const NamedDecl *ConstraintOwner,
66 ArrayRef<TemplateArgument> TemplateArgs);
67
69 for (const auto &Detail : Details)
70 if (Detail.dyn_cast<SubstitutionDiagnostic *>())
71 return true;
72 return false;
73 }
74};
75
76/// Pairs of unsatisfied atomic constraint expressions along with the
77/// substituted constraint expr, if the template arguments could be
78/// substituted into them, or a diagnostic if substitution resulted in
79/// an invalid expression.
81 llvm::PointerUnion<Expr *, std::pair<SourceLocation, StringRef> *>;
82
83/// \brief The result of a constraint satisfaction check, containing the
84/// necessary information to diagnose an unsatisfied constraint.
85///
86/// This is safe to store in an AST node, as opposed to ConstraintSatisfaction.
88 llvm::TrailingObjects<ASTConstraintSatisfaction,
89 UnsatisfiedConstraintRecord> {
90 std::size_t NumRecords;
91 bool IsSatisfied : 1;
93
95 return getTrailingObjects<UnsatisfiedConstraintRecord>();
96 }
97
99 return getTrailingObjects<UnsatisfiedConstraintRecord>() + NumRecords;
100 }
101
103 const ConstraintSatisfaction &Satisfaction);
105 const ASTConstraintSatisfaction &Satisfaction);
106
108 Create(const ASTContext &C, const ConstraintSatisfaction &Satisfaction);
110 Rebuild(const ASTContext &C, const ASTConstraintSatisfaction &Satisfaction);
111};
112
113/// A reference to a concept and its template args, as it appears in the code.
114///
115/// Examples:
116/// template <int X> requires is_even<X> int half = X/2;
117/// ~~~~~~~~~~ (in ConceptSpecializationExpr)
118///
119/// std::input_iterator auto I = Container.begin();
120/// ~~~~~~~~~~~~~~~~~~~ (in AutoTypeLoc)
121///
122/// template <std::derives_from<Expr> T> void dump();
123/// ~~~~~~~~~~~~~~~~~~~~~~~ (in TemplateTypeParmDecl)
125 // \brief The optional nested name specifier used when naming the concept.
126 NestedNameSpecifierLoc NestedNameSpec;
127
128 /// \brief The location of the template keyword, if specified when naming the
129 /// concept.
130 SourceLocation TemplateKWLoc;
131
132 /// \brief The concept name used.
133 DeclarationNameInfo ConceptName;
134
135 /// \brief The declaration found by name lookup when the expression was
136 /// created.
137 /// Can differ from NamedConcept when, for example, the concept was found
138 /// through a UsingShadowDecl.
139 NamedDecl *FoundDecl;
140
141 /// \brief The concept named.
142 ConceptDecl *NamedConcept;
143
144 /// \brief The template argument list source info used to specialize the
145 /// concept.
146 const ASTTemplateArgumentListInfo *ArgsAsWritten;
147
149 DeclarationNameInfo ConceptNameInfo, NamedDecl *FoundDecl,
150 ConceptDecl *NamedConcept,
151 const ASTTemplateArgumentListInfo *ArgsAsWritten)
152 : NestedNameSpec(NNS), TemplateKWLoc(TemplateKWLoc),
153 ConceptName(ConceptNameInfo), FoundDecl(FoundDecl),
154 NamedConcept(NamedConcept), ArgsAsWritten(ArgsAsWritten) {}
155
156public:
157 static ConceptReference *
159 SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo,
160 NamedDecl *FoundDecl, ConceptDecl *NamedConcept,
161 const ASTTemplateArgumentListInfo *ArgsAsWritten);
162
164 return NestedNameSpec;
165 }
166
167 const DeclarationNameInfo &getConceptNameInfo() const { return ConceptName; }
168
170 return getConceptNameInfo().getLoc();
171 }
172
173 SourceLocation getTemplateKWLoc() const { return TemplateKWLoc; }
174
176
177 SourceLocation getBeginLoc() const LLVM_READONLY {
178 // Note that if the qualifier is null the template KW must also be null.
179 if (auto QualifierLoc = getNestedNameSpecifierLoc())
180 return QualifierLoc.getBeginLoc();
182 }
183
184 SourceLocation getEndLoc() const LLVM_READONLY {
185 return getTemplateArgsAsWritten() &&
189 }
190
191 SourceRange getSourceRange() const LLVM_READONLY {
192 return SourceRange(getBeginLoc(), getEndLoc());
193 }
194
196 return FoundDecl;
197 }
198
200 return NamedConcept;
201 }
202
204 return ArgsAsWritten;
205 }
206
207 /// \brief Whether or not template arguments were explicitly specified in the
208 /// concept reference (they might not be in type constraints, for example)
210 return ArgsAsWritten != nullptr;
211 }
212
213 void print(llvm::raw_ostream &OS, const PrintingPolicy &Policy) const;
214 void dump() const;
215 void dump(llvm::raw_ostream &) const;
216};
217
218/// Models the abbreviated syntax to constrain a template type parameter:
219/// template <convertible_to<string> T> void print(T object);
220/// ~~~~~~~~~~~~~~~~~~~~~~
221/// Semantically, this adds an "immediately-declared constraint" with extra arg:
222/// requires convertible_to<T, string>
223///
224/// In the C++ grammar, a type-constraint is also used for auto types:
225/// convertible_to<string> auto X = ...;
226/// We do *not* model these as TypeConstraints, but AutoType(Loc) directly.
228 /// \brief The immediately-declared constraint expression introduced by this
229 /// type-constraint.
230 Expr *ImmediatelyDeclaredConstraint = nullptr;
231 ConceptReference *ConceptRef;
232
233public:
235 Expr *ImmediatelyDeclaredConstraint)
236 : ImmediatelyDeclaredConstraint(ImmediatelyDeclaredConstraint),
237 ConceptRef(ConceptRef) {}
238
239 /// \brief Get the immediately-declared constraint expression introduced by
240 /// this type-constraint, that is - the constraint expression that is added to
241 /// the associated constraints of the enclosing declaration in practice.
243 return ImmediatelyDeclaredConstraint;
244 }
245
246 ConceptReference *getConceptReference() const { return ConceptRef; }
247
248 // FIXME: Instead of using these concept related functions the callers should
249 // directly work with the corresponding ConceptReference.
250 ConceptDecl *getNamedConcept() const { return ConceptRef->getNamedConcept(); }
251
253 return ConceptRef->getConceptNameLoc();
254 }
255
257 return ConceptRef->hasExplicitTemplateArgs();
258 }
259
261 return ConceptRef->getTemplateArgsAsWritten();
262 }
263
265 return ConceptRef->getTemplateKWLoc();
266 }
267
268 NamedDecl *getFoundDecl() const { return ConceptRef->getFoundDecl(); }
269
271 return ConceptRef->getNestedNameSpecifierLoc();
272 }
273
275 return ConceptRef->getConceptNameInfo();
276 }
277
278 void print(llvm::raw_ostream &OS, const PrintingPolicy &Policy) const {
279 ConceptRef->print(OS, Policy);
280 }
281};
282
283} // clang
284
285#endif // LLVM_CLANG_AST_ASTCONCEPT_H
static char ID
Definition: Arena.cpp:183
Defines the clang::SourceLocation class and associated facilities.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:188
Declaration of a C++20 concept.
A reference to a concept and its template args, as it appears in the code.
Definition: ASTConcept.h:124
bool hasExplicitTemplateArgs() const
Whether or not template arguments were explicitly specified in the concept reference (they might not ...
Definition: ASTConcept.h:209
const NestedNameSpecifierLoc & getNestedNameSpecifierLoc() const
Definition: ASTConcept.h:163
NamedDecl * getFoundDecl() const
Definition: ASTConcept.h:195
const DeclarationNameInfo & getConceptNameInfo() const
Definition: ASTConcept.h:167
SourceRange getSourceRange() const LLVM_READONLY
Definition: ASTConcept.h:191
SourceLocation getConceptNameLoc() const
Definition: ASTConcept.h:169
ConceptDecl * getNamedConcept() const
Definition: ASTConcept.h:199
SourceLocation getLocation() const
Definition: ASTConcept.h:175
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: ASTConcept.h:177
void print(llvm::raw_ostream &OS, const PrintingPolicy &Policy) const
Definition: ASTConcept.cpp:96
const ASTTemplateArgumentListInfo * getTemplateArgsAsWritten() const
Definition: ASTConcept.h:203
SourceLocation getEndLoc() const LLVM_READONLY
Definition: ASTConcept.h:184
void dump(llvm::raw_ostream &) const
SourceLocation getTemplateKWLoc() const
Definition: ASTConcept.h:173
The result of a constraint satisfaction check, containing the necessary information to diagnose an un...
Definition: ASTConcept.h:35
llvm::PointerUnion< Expr *, SubstitutionDiagnostic * > Detail
Definition: ASTConcept.h:50
ConstraintSatisfaction(const NamedDecl *ConstraintOwner, ArrayRef< TemplateArgument > TemplateArgs)
Definition: ASTConcept.h:45
std::pair< SourceLocation, StringRef > SubstitutionDiagnostic
Definition: ASTConcept.h:49
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &C)
Definition: ASTConcept.h:60
llvm::SmallVector< Detail, 4 > Details
The substituted constraint expr, if the template arguments could be substituted into them,...
Definition: ASTConcept.h:58
This represents one expression.
Definition: Expr.h:110
This represents a decl that may have a name.
Definition: Decl.h:253
A C++ nested-name-specifier augmented with source location information.
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
A trivial tuple used to represent a source range.
Models the abbreviated syntax to constrain a template type parameter: template <convertible_to<string...
Definition: ASTConcept.h:227
const ASTTemplateArgumentListInfo * getTemplateArgsAsWritten() const
Definition: ASTConcept.h:260
void print(llvm::raw_ostream &OS, const PrintingPolicy &Policy) const
Definition: ASTConcept.h:278
ConceptDecl * getNamedConcept() const
Definition: ASTConcept.h:250
Expr * getImmediatelyDeclaredConstraint() const
Get the immediately-declared constraint expression introduced by this type-constraint,...
Definition: ASTConcept.h:242
NamedDecl * getFoundDecl() const
Definition: ASTConcept.h:268
const NestedNameSpecifierLoc & getNestedNameSpecifierLoc() const
Definition: ASTConcept.h:270
const DeclarationNameInfo & getConceptNameInfo() const
Definition: ASTConcept.h:274
bool hasExplicitTemplateArgs() const
Definition: ASTConcept.h:256
SourceLocation getConceptNameLoc() const
Definition: ASTConcept.h:252
SourceLocation getTemplateKWLoc() const
Definition: ASTConcept.h:264
TypeConstraint(ConceptReference *ConceptRef, Expr *ImmediatelyDeclaredConstraint)
Definition: ASTConcept.h:234
ConceptReference * getConceptReference() const
Definition: ASTConcept.h:246
The JSON file list parser is used to communicate input to InstallAPI.
@ Create
'create' clause, allowed on Compute and Combined constructs, plus 'data', 'enter data',...
llvm::PointerUnion< Expr *, std::pair< SourceLocation, StringRef > * > UnsatisfiedConstraintRecord
Pairs of unsatisfied atomic constraint expressions along with the substituted constraint expr,...
Definition: ASTConcept.h:81
The result of a constraint satisfaction check, containing the necessary information to diagnose an un...
Definition: ASTConcept.h:89
const UnsatisfiedConstraintRecord * end() const
Definition: ASTConcept.h:98
static ASTConstraintSatisfaction * Rebuild(const ASTContext &C, const ASTConstraintSatisfaction &Satisfaction)
Definition: ASTConcept.cpp:69
const UnsatisfiedConstraintRecord * begin() const
Definition: ASTConcept.h:94
Represents an explicit template argument list in C++, e.g., the "<int>" in "sort<int>".
Definition: TemplateBase.h:676
SourceLocation getRAngleLoc() const
Definition: TemplateBase.h:697
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspon...
SourceLocation getLoc() const
getLoc - Returns the main location of the declaration name.
SourceLocation getBeginLoc() const
getBeginLoc - Retrieve the location of the first token.
SourceLocation getEndLoc() const LLVM_READONLY
Describes how types, statements, expressions, and declarations should be printed.
Definition: PrettyPrinter.h:57