Coverage Report

Created: 2021-06-15 06:44

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