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