Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

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