Coverage Report

Created: 2021-09-21 08:58

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