Coverage Report

Created: 2022-07-16 07:03

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