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.begin(),
48 TemplateArgs.end()) { }
49
50 using SubstitutionDiagnostic = std::pair<SourceLocation, StringRef>;
51 using Detail = llvm::PointerUnion<Expr *, SubstitutionDiagnostic *>;
52
53 bool IsSatisfied = false;
54 bool ContainsErrors = false;
55
56 /// \brief The substituted constraint expr, if the template arguments could be
57 /// substituted into them, or a diagnostic if substitution resulted in an
58 /// invalid expression.
60
61 void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &C) {
62 Profile(ID, C, ConstraintOwner, TemplateArgs);
63 }
64
65 static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &C,
66 const NamedDecl *ConstraintOwner,
67 ArrayRef<TemplateArgument> TemplateArgs);
68
70 for (const auto &Detail : Details)
71 if (Detail.dyn_cast<SubstitutionDiagnostic *>())
72 return true;
73 return false;
74 }
75};
76
77/// Pairs of unsatisfied atomic constraint expressions along with the
78/// substituted constraint expr, if the template arguments could be
79/// substituted into them, or a diagnostic if substitution resulted in
80/// an invalid expression.
82 llvm::PointerUnion<Expr *, std::pair<SourceLocation, StringRef> *>;
83
84/// \brief The result of a constraint satisfaction check, containing the
85/// necessary information to diagnose an unsatisfied constraint.
86///
87/// This is safe to store in an AST node, as opposed to ConstraintSatisfaction.
89 llvm::TrailingObjects<ASTConstraintSatisfaction,
90 UnsatisfiedConstraintRecord> {
91 std::size_t NumRecords;
92 bool IsSatisfied : 1;
94
96 return getTrailingObjects<UnsatisfiedConstraintRecord>();
97 }
98
100 return getTrailingObjects<UnsatisfiedConstraintRecord>() + NumRecords;
101 }
102
104 const ConstraintSatisfaction &Satisfaction);
106 const ASTConstraintSatisfaction &Satisfaction);
107
109 Create(const ASTContext &C, const ConstraintSatisfaction &Satisfaction);
111 Rebuild(const ASTContext &C, const ASTConstraintSatisfaction &Satisfaction);
112};
113
114/// A reference to a concept and its template args, as it appears in the code.
115///
116/// Examples:
117/// template <int X> requires is_even<X> int half = X/2;
118/// ~~~~~~~~~~ (in ConceptSpecializationExpr)
119///
120/// std::input_iterator auto I = Container.begin();
121/// ~~~~~~~~~~~~~~~~~~~ (in AutoTypeLoc)
122///
123/// template <std::derives_from<Expr> T> void dump();
124/// ~~~~~~~~~~~~~~~~~~~~~~~ (in TemplateTypeParmDecl)
126 // \brief The optional nested name specifier used when naming the concept.
127 NestedNameSpecifierLoc NestedNameSpec;
128
129 /// \brief The location of the template keyword, if specified when naming the
130 /// concept.
131 SourceLocation TemplateKWLoc;
132
133 /// \brief The concept name used.
134 DeclarationNameInfo ConceptName;
135
136 /// \brief The declaration found by name lookup when the expression was
137 /// created.
138 /// Can differ from NamedConcept when, for example, the concept was found
139 /// through a UsingShadowDecl.
140 NamedDecl *FoundDecl;
141
142 /// \brief The concept named.
143 ConceptDecl *NamedConcept;
144
145 /// \brief The template argument list source info used to specialize the
146 /// concept.
147 const ASTTemplateArgumentListInfo *ArgsAsWritten;
148
150 DeclarationNameInfo ConceptNameInfo, NamedDecl *FoundDecl,
151 ConceptDecl *NamedConcept,
152 const ASTTemplateArgumentListInfo *ArgsAsWritten)
153 : NestedNameSpec(NNS), TemplateKWLoc(TemplateKWLoc),
154 ConceptName(ConceptNameInfo), FoundDecl(FoundDecl),
155 NamedConcept(NamedConcept), ArgsAsWritten(ArgsAsWritten) {}
156
157public:
158 static ConceptReference *
160 SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo,
161 NamedDecl *FoundDecl, ConceptDecl *NamedConcept,
162 const ASTTemplateArgumentListInfo *ArgsAsWritten);
163
165 return NestedNameSpec;
166 }
167
168 const DeclarationNameInfo &getConceptNameInfo() const { return ConceptName; }
169
171 return getConceptNameInfo().getLoc();
172 }
173
174 SourceLocation getTemplateKWLoc() const { return TemplateKWLoc; }
175
177
178 SourceLocation getBeginLoc() const LLVM_READONLY {
179 // Note that if the qualifier is null the template KW must also be null.
180 if (auto QualifierLoc = getNestedNameSpecifierLoc())
181 return QualifierLoc.getBeginLoc();
183 }
184
185 SourceLocation getEndLoc() const LLVM_READONLY {
186 return getTemplateArgsAsWritten() &&
190 }
191
192 SourceRange getSourceRange() const LLVM_READONLY {
193 return SourceRange(getBeginLoc(), getEndLoc());
194 }
195
197 return FoundDecl;
198 }
199
201 return NamedConcept;
202 }
203
205 return ArgsAsWritten;
206 }
207
208 /// \brief Whether or not template arguments were explicitly specified in the
209 /// concept reference (they might not be in type constraints, for example)
211 return ArgsAsWritten != nullptr;
212 }
213
214 void print(llvm::raw_ostream &OS, const PrintingPolicy &Policy) const;
215 void dump() const;
216 void dump(llvm::raw_ostream &) const;
217};
218
219/// Models the abbreviated syntax to constrain a template type parameter:
220/// template <convertible_to<string> T> void print(T object);
221/// ~~~~~~~~~~~~~~~~~~~~~~
222/// Semantically, this adds an "immediately-declared constraint" with extra arg:
223/// requires convertible_to<T, string>
224///
225/// In the C++ grammar, a type-constraint is also used for auto types:
226/// convertible_to<string> auto X = ...;
227/// We do *not* model these as TypeConstraints, but AutoType(Loc) directly.
229 /// \brief The immediately-declared constraint expression introduced by this
230 /// type-constraint.
231 Expr *ImmediatelyDeclaredConstraint = nullptr;
232 ConceptReference *ConceptRef;
233
234public:
236 Expr *ImmediatelyDeclaredConstraint)
237 : ImmediatelyDeclaredConstraint(ImmediatelyDeclaredConstraint),
238 ConceptRef(ConceptRef) {}
239
240 /// \brief Get the immediately-declared constraint expression introduced by
241 /// this type-constraint, that is - the constraint expression that is added to
242 /// the associated constraints of the enclosing declaration in practice.
244 return ImmediatelyDeclaredConstraint;
245 }
246
247 ConceptReference *getConceptReference() const { return ConceptRef; }
248
249 // FIXME: Instead of using these concept related functions the callers should
250 // directly work with the corresponding ConceptReference.
251 ConceptDecl *getNamedConcept() const { return ConceptRef->getNamedConcept(); }
252
254 return ConceptRef->getConceptNameLoc();
255 }
256
258 return ConceptRef->hasExplicitTemplateArgs();
259 }
260
262 return ConceptRef->getTemplateArgsAsWritten();
263 }
264
266 return ConceptRef->getTemplateKWLoc();
267 }
268
269 NamedDecl *getFoundDecl() const { return ConceptRef->getFoundDecl(); }
270
272 return ConceptRef->getNestedNameSpecifierLoc();
273 }
274
276 return ConceptRef->getConceptNameInfo();
277 }
278
279 void print(llvm::raw_ostream &OS, const PrintingPolicy &Policy) const {
280 ConceptRef->print(OS, Policy);
281 }
282};
283
284} // clang
285
286#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:186
Declaration of a C++20 concept.
A reference to a concept and its template args, as it appears in the code.
Definition: ASTConcept.h:125
bool hasExplicitTemplateArgs() const
Whether or not template arguments were explicitly specified in the concept reference (they might not ...
Definition: ASTConcept.h:210
const NestedNameSpecifierLoc & getNestedNameSpecifierLoc() const
Definition: ASTConcept.h:164
NamedDecl * getFoundDecl() const
Definition: ASTConcept.h:196
const DeclarationNameInfo & getConceptNameInfo() const
Definition: ASTConcept.h:168
SourceRange getSourceRange() const LLVM_READONLY
Definition: ASTConcept.h:192
SourceLocation getConceptNameLoc() const
Definition: ASTConcept.h:170
ConceptDecl * getNamedConcept() const
Definition: ASTConcept.h:200
SourceLocation getLocation() const
Definition: ASTConcept.h:176
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: ASTConcept.h:178
void print(llvm::raw_ostream &OS, const PrintingPolicy &Policy) const
Definition: ASTConcept.cpp:97
const ASTTemplateArgumentListInfo * getTemplateArgsAsWritten() const
Definition: ASTConcept.h:204
SourceLocation getEndLoc() const LLVM_READONLY
Definition: ASTConcept.h:185
void dump(llvm::raw_ostream &) const
SourceLocation getTemplateKWLoc() const
Definition: ASTConcept.h:174
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:51
ConstraintSatisfaction(const NamedDecl *ConstraintOwner, ArrayRef< TemplateArgument > TemplateArgs)
Definition: ASTConcept.h:45
std::pair< SourceLocation, StringRef > SubstitutionDiagnostic
Definition: ASTConcept.h:50
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &C)
Definition: ASTConcept.h:61
llvm::SmallVector< Detail, 4 > Details
The substituted constraint expr, if the template arguments could be substituted into them,...
Definition: ASTConcept.h:59
This represents one expression.
Definition: Expr.h:110
This represents a decl that may have a name.
Definition: Decl.h:249
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:228
const ASTTemplateArgumentListInfo * getTemplateArgsAsWritten() const
Definition: ASTConcept.h:261
void print(llvm::raw_ostream &OS, const PrintingPolicy &Policy) const
Definition: ASTConcept.h:279
ConceptDecl * getNamedConcept() const
Definition: ASTConcept.h:251
Expr * getImmediatelyDeclaredConstraint() const
Get the immediately-declared constraint expression introduced by this type-constraint,...
Definition: ASTConcept.h:243
NamedDecl * getFoundDecl() const
Definition: ASTConcept.h:269
const NestedNameSpecifierLoc & getNestedNameSpecifierLoc() const
Definition: ASTConcept.h:271
const DeclarationNameInfo & getConceptNameInfo() const
Definition: ASTConcept.h:275
bool hasExplicitTemplateArgs() const
Definition: ASTConcept.h:257
SourceLocation getConceptNameLoc() const
Definition: ASTConcept.h:253
SourceLocation getTemplateKWLoc() const
Definition: ASTConcept.h:265
TypeConstraint(ConceptReference *ConceptRef, Expr *ImmediatelyDeclaredConstraint)
Definition: ASTConcept.h:235
ConceptReference * getConceptReference() const
Definition: ASTConcept.h:247
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:82
The result of a constraint satisfaction check, containing the necessary information to diagnose an un...
Definition: ASTConcept.h:90
const UnsatisfiedConstraintRecord * end() const
Definition: ASTConcept.h:99
static ASTConstraintSatisfaction * Rebuild(const ASTContext &C, const ASTConstraintSatisfaction &Satisfaction)
Definition: ASTConcept.cpp:70
const UnsatisfiedConstraintRecord * begin() const
Definition: ASTConcept.h:95
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