]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/clang/include/clang/AST/ASTConcept.h
Merge ^/vendor/llvm-project/release-10.x up to its last change (upstream
[FreeBSD/FreeBSD.git] / contrib / llvm-project / clang / include / clang / AST / ASTConcept.h
1 //===--- ASTConcept.h - Concepts Related AST Data Structures ----*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 ///
10 /// \file
11 /// \brief This file provides AST data structures related to concepts.
12 ///
13 //===----------------------------------------------------------------------===//
14
15 #ifndef LLVM_CLANG_AST_ASTCONCEPT_H
16 #define LLVM_CLANG_AST_ASTCONCEPT_H
17 #include "clang/AST/Expr.h"
18 #include "clang/Basic/SourceLocation.h"
19 #include "llvm/ADT/PointerUnion.h"
20 #include "llvm/ADT/SmallVector.h"
21 #include <string>
22 #include <utility>
23 namespace clang {
24 class ConceptDecl;
25 class ConceptSpecializationExpr;
26
27 /// The result of a constraint satisfaction check, containing the necessary
28 /// information to diagnose an unsatisfied constraint.
29 class ConstraintSatisfaction : public llvm::FoldingSetNode {
30   // The template-like entity that 'owns' the constraint checked here (can be a
31   // constrained entity or a concept).
32   const NamedDecl *ConstraintOwner = nullptr;
33   llvm::SmallVector<TemplateArgument, 4> TemplateArgs;
34
35 public:
36
37   ConstraintSatisfaction() = default;
38
39   ConstraintSatisfaction(const NamedDecl *ConstraintOwner,
40                          ArrayRef<TemplateArgument> TemplateArgs) :
41       ConstraintOwner(ConstraintOwner), TemplateArgs(TemplateArgs.begin(),
42                                                      TemplateArgs.end()) { }
43
44   using SubstitutionDiagnostic = std::pair<SourceLocation, StringRef>;
45   using Detail = llvm::PointerUnion<Expr *, SubstitutionDiagnostic *>;
46
47   bool IsSatisfied = false;
48
49   /// \brief Pairs of unsatisfied atomic constraint expressions along with the
50   /// substituted constraint expr, if the template arguments could be
51   /// substituted into them, or a diagnostic if substitution resulted in an
52   /// invalid expression.
53   llvm::SmallVector<std::pair<const Expr *, Detail>, 4> Details;
54
55   void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &C) {
56     Profile(ID, C, ConstraintOwner, TemplateArgs);
57   }
58
59   static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &C,
60                       const NamedDecl *ConstraintOwner,
61                       ArrayRef<TemplateArgument> TemplateArgs);
62 };
63
64 /// Pairs of unsatisfied atomic constraint expressions along with the
65 /// substituted constraint expr, if the template arguments could be
66 /// substituted into them, or a diagnostic if substitution resulted in
67 /// an invalid expression.
68 using UnsatisfiedConstraintRecord =
69     std::pair<const Expr *,
70               llvm::PointerUnion<Expr *,
71                                  std::pair<SourceLocation, StringRef> *>>;
72
73 /// \brief The result of a constraint satisfaction check, containing the
74 /// necessary information to diagnose an unsatisfied constraint.
75 ///
76 /// This is safe to store in an AST node, as opposed to ConstraintSatisfaction.
77 struct ASTConstraintSatisfaction final :
78     llvm::TrailingObjects<ASTConstraintSatisfaction,
79                           UnsatisfiedConstraintRecord> {
80   std::size_t NumRecords;
81   bool IsSatisfied : 1;
82
83   const UnsatisfiedConstraintRecord *begin() const {
84     return getTrailingObjects<UnsatisfiedConstraintRecord>();
85   }
86
87   const UnsatisfiedConstraintRecord *end() const {
88     return getTrailingObjects<UnsatisfiedConstraintRecord>() + NumRecords;
89   }
90
91   ASTConstraintSatisfaction(const ASTContext &C,
92                             const ConstraintSatisfaction &Satisfaction);
93
94   static ASTConstraintSatisfaction *
95   Create(const ASTContext &C, const ConstraintSatisfaction &Satisfaction);
96 };
97
98 /// \brief Common data class for constructs that reference concepts with
99 /// template arguments.
100 class ConceptReference {
101 protected:
102   // \brief The optional nested name specifier used when naming the concept.
103   NestedNameSpecifierLoc NestedNameSpec;
104
105   /// \brief The location of the template keyword, if specified when naming the
106   /// concept.
107   SourceLocation TemplateKWLoc;
108
109   /// \brief The concept name used.
110   DeclarationNameInfo ConceptName;
111
112   /// \brief The declaration found by name lookup when the expression was
113   /// created.
114   /// Can differ from NamedConcept when, for example, the concept was found
115   /// through a UsingShadowDecl.
116   NamedDecl *FoundDecl;
117
118   /// \brief The concept named.
119   ConceptDecl *NamedConcept;
120
121   /// \brief The template argument list source info used to specialize the
122   /// concept.
123   const ASTTemplateArgumentListInfo *ArgsAsWritten;
124
125 public:
126
127   ConceptReference(NestedNameSpecifierLoc NNS, SourceLocation TemplateKWLoc,
128                    DeclarationNameInfo ConceptNameInfo, NamedDecl *FoundDecl,
129                    ConceptDecl *NamedConcept,
130                    const ASTTemplateArgumentListInfo *ArgsAsWritten) :
131       NestedNameSpec(NNS), TemplateKWLoc(TemplateKWLoc),
132       ConceptName(ConceptNameInfo), FoundDecl(FoundDecl),
133       NamedConcept(NamedConcept), ArgsAsWritten(ArgsAsWritten) {}
134
135   ConceptReference() : NestedNameSpec(), TemplateKWLoc(), ConceptName(),
136       FoundDecl(nullptr), NamedConcept(nullptr), ArgsAsWritten(nullptr) {}
137
138   const NestedNameSpecifierLoc &getNestedNameSpecifierLoc() const {
139     return NestedNameSpec;
140   }
141
142   const DeclarationNameInfo &getConceptNameInfo() const { return ConceptName; }
143
144   SourceLocation getConceptNameLoc() const {
145     return getConceptNameInfo().getLoc();
146   }
147
148   SourceLocation getTemplateKWLoc() const { return TemplateKWLoc; }
149
150   NamedDecl *getFoundDecl() const {
151     return FoundDecl;
152   }
153
154   ConceptDecl *getNamedConcept() const {
155     return NamedConcept;
156   }
157
158   const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten() const {
159     return ArgsAsWritten;
160   }
161
162   /// \brief Whether or not template arguments were explicitly specified in the
163   /// concept reference (they might not be in type constraints, for example)
164   bool hasExplicitTemplateArgs() const {
165     return ArgsAsWritten != nullptr;
166   }
167 };
168
169 class TypeConstraint : public ConceptReference {
170   /// \brief The immediately-declared constraint expression introduced by this
171   /// type-constraint.
172   Expr *ImmediatelyDeclaredConstraint = nullptr;
173
174 public:
175   TypeConstraint(NestedNameSpecifierLoc NNS,
176                  DeclarationNameInfo ConceptNameInfo, NamedDecl *FoundDecl,
177                  ConceptDecl *NamedConcept,
178                  const ASTTemplateArgumentListInfo *ArgsAsWritten,
179                  Expr *ImmediatelyDeclaredConstraint) :
180       ConceptReference(NNS, /*TemplateKWLoc=*/SourceLocation(), ConceptNameInfo,
181                        FoundDecl, NamedConcept, ArgsAsWritten),
182       ImmediatelyDeclaredConstraint(ImmediatelyDeclaredConstraint) {}
183
184   /// \brief Get the immediately-declared constraint expression introduced by
185   /// this type-constraint, that is - the constraint expression that is added to
186   /// the associated constraints of the enclosing declaration in practice.
187   Expr *getImmediatelyDeclaredConstraint() const {
188     return ImmediatelyDeclaredConstraint;
189   }
190
191   void print(llvm::raw_ostream &OS, PrintingPolicy Policy) const;
192 };
193
194 } // clang
195
196 #endif // LLVM_CLANG_AST_ASTCONCEPT_H