Coverage Report

Created: 2020-09-15 12:33

/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
#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
8.28M
  ConstraintSatisfaction() = default;
38
39
  ConstraintSatisfaction(const NamedDecl *ConstraintOwner,
40
                         ArrayRef<TemplateArgument> TemplateArgs) :
41
      ConstraintOwner(ConstraintOwner), TemplateArgs(TemplateArgs.begin(),
42
772
                                                     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
1.54k
  void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &C) {
56
1.54k
    Profile(ID, C, ConstraintOwner, TemplateArgs);
57
1.54k
  }
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
93
  const UnsatisfiedConstraintRecord *begin() const {
84
93
    return getTrailingObjects<UnsatisfiedConstraintRecord>();
85
93
  }
86
87
93
  const UnsatisfiedConstraintRecord *end() const {
88
93
    return getTrailingObjects<UnsatisfiedConstraintRecord>() + NumRecords;
89
93
  }
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
1.03k
      NamedConcept(NamedConcept), ArgsAsWritten(ArgsAsWritten) {}
134
135
  ConceptReference() : NestedNameSpec(), TemplateKWLoc(), ConceptName(),
136
30
      FoundDecl(nullptr), NamedConcept(nullptr), ArgsAsWritten(nullptr) {}
137
138
559
  const NestedNameSpecifierLoc &getNestedNameSpecifierLoc() const {
139
559
    return NestedNameSpec;
140
559
  }
141
142
520
  const DeclarationNameInfo &getConceptNameInfo() const { return ConceptName; }
143
144
3
  SourceLocation getConceptNameLoc() const {
145
3
    return getConceptNameInfo().getLoc();
146
3
  }
147
148
464
  SourceLocation getTemplateKWLoc() const { return TemplateKWLoc; }
149
150
488
  NamedDecl *getFoundDecl() const {
151
488
    return FoundDecl;
152
488
  }
153
154
958
  ConceptDecl *getNamedConcept() const {
155
958
    return NamedConcept;
156
958
  }
157
158
1.83k
  const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten() const {
159
1.83k
    return ArgsAsWritten;
160
1.83k
  }
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
94
  bool hasExplicitTemplateArgs() const {
165
94
    return ArgsAsWritten != nullptr;
166
94
  }
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
217
      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
614
  Expr *getImmediatelyDeclaredConstraint() const {
188
614
    return ImmediatelyDeclaredConstraint;
189
614
  }
190
191
  void print(llvm::raw_ostream &OS, PrintingPolicy Policy) const;
192
};
193
194
} // clang
195
196
#endif // LLVM_CLANG_AST_ASTCONCEPT_H