ASTConcept.h 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===--- ASTConcept.h - Concepts Related AST Data Structures ----*- C++ -*-===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. ///
  14. /// \file
  15. /// \brief This file provides AST data structures related to concepts.
  16. ///
  17. //===----------------------------------------------------------------------===//
  18. #ifndef LLVM_CLANG_AST_ASTCONCEPT_H
  19. #define LLVM_CLANG_AST_ASTCONCEPT_H
  20. #include "clang/AST/Expr.h"
  21. #include "clang/Basic/SourceLocation.h"
  22. #include "llvm/ADT/PointerUnion.h"
  23. #include "llvm/ADT/SmallVector.h"
  24. #include <utility>
  25. namespace clang {
  26. class ConceptDecl;
  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. public:
  35. ConstraintSatisfaction() = default;
  36. ConstraintSatisfaction(const NamedDecl *ConstraintOwner,
  37. ArrayRef<TemplateArgument> TemplateArgs) :
  38. ConstraintOwner(ConstraintOwner), TemplateArgs(TemplateArgs.begin(),
  39. TemplateArgs.end()) { }
  40. using SubstitutionDiagnostic = std::pair<SourceLocation, StringRef>;
  41. using Detail = llvm::PointerUnion<Expr *, SubstitutionDiagnostic *>;
  42. bool IsSatisfied = false;
  43. /// \brief Pairs of unsatisfied atomic constraint expressions along with the
  44. /// substituted constraint expr, if the template arguments could be
  45. /// substituted into them, or a diagnostic if substitution resulted in an
  46. /// invalid expression.
  47. llvm::SmallVector<std::pair<const Expr *, Detail>, 4> Details;
  48. void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &C) {
  49. Profile(ID, C, ConstraintOwner, TemplateArgs);
  50. }
  51. static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &C,
  52. const NamedDecl *ConstraintOwner,
  53. ArrayRef<TemplateArgument> TemplateArgs);
  54. };
  55. /// Pairs of unsatisfied atomic constraint expressions along with the
  56. /// substituted constraint expr, if the template arguments could be
  57. /// substituted into them, or a diagnostic if substitution resulted in
  58. /// an invalid expression.
  59. using UnsatisfiedConstraintRecord =
  60. std::pair<const Expr *,
  61. llvm::PointerUnion<Expr *,
  62. std::pair<SourceLocation, StringRef> *>>;
  63. /// \brief The result of a constraint satisfaction check, containing the
  64. /// necessary information to diagnose an unsatisfied constraint.
  65. ///
  66. /// This is safe to store in an AST node, as opposed to ConstraintSatisfaction.
  67. struct ASTConstraintSatisfaction final :
  68. llvm::TrailingObjects<ASTConstraintSatisfaction,
  69. UnsatisfiedConstraintRecord> {
  70. std::size_t NumRecords;
  71. bool IsSatisfied : 1;
  72. const UnsatisfiedConstraintRecord *begin() const {
  73. return getTrailingObjects<UnsatisfiedConstraintRecord>();
  74. }
  75. const UnsatisfiedConstraintRecord *end() const {
  76. return getTrailingObjects<UnsatisfiedConstraintRecord>() + NumRecords;
  77. }
  78. ASTConstraintSatisfaction(const ASTContext &C,
  79. const ConstraintSatisfaction &Satisfaction);
  80. static ASTConstraintSatisfaction *
  81. Create(const ASTContext &C, const ConstraintSatisfaction &Satisfaction);
  82. };
  83. /// \brief Common data class for constructs that reference concepts with
  84. /// template arguments.
  85. class ConceptReference {
  86. protected:
  87. // \brief The optional nested name specifier used when naming the concept.
  88. NestedNameSpecifierLoc NestedNameSpec;
  89. /// \brief The location of the template keyword, if specified when naming the
  90. /// concept.
  91. SourceLocation TemplateKWLoc;
  92. /// \brief The concept name used.
  93. DeclarationNameInfo ConceptName;
  94. /// \brief The declaration found by name lookup when the expression was
  95. /// created.
  96. /// Can differ from NamedConcept when, for example, the concept was found
  97. /// through a UsingShadowDecl.
  98. NamedDecl *FoundDecl;
  99. /// \brief The concept named.
  100. ConceptDecl *NamedConcept;
  101. /// \brief The template argument list source info used to specialize the
  102. /// concept.
  103. const ASTTemplateArgumentListInfo *ArgsAsWritten;
  104. public:
  105. ConceptReference(NestedNameSpecifierLoc NNS, SourceLocation TemplateKWLoc,
  106. DeclarationNameInfo ConceptNameInfo, NamedDecl *FoundDecl,
  107. ConceptDecl *NamedConcept,
  108. const ASTTemplateArgumentListInfo *ArgsAsWritten)
  109. : NestedNameSpec(NNS), TemplateKWLoc(TemplateKWLoc),
  110. ConceptName(ConceptNameInfo), FoundDecl(FoundDecl),
  111. NamedConcept(NamedConcept), ArgsAsWritten(ArgsAsWritten) {}
  112. ConceptReference()
  113. : FoundDecl(nullptr), NamedConcept(nullptr), ArgsAsWritten(nullptr) {}
  114. const NestedNameSpecifierLoc &getNestedNameSpecifierLoc() const {
  115. return NestedNameSpec;
  116. }
  117. const DeclarationNameInfo &getConceptNameInfo() const { return ConceptName; }
  118. SourceLocation getConceptNameLoc() const {
  119. return getConceptNameInfo().getLoc();
  120. }
  121. SourceLocation getTemplateKWLoc() const { return TemplateKWLoc; }
  122. NamedDecl *getFoundDecl() const {
  123. return FoundDecl;
  124. }
  125. ConceptDecl *getNamedConcept() const {
  126. return NamedConcept;
  127. }
  128. const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten() const {
  129. return ArgsAsWritten;
  130. }
  131. /// \brief Whether or not template arguments were explicitly specified in the
  132. /// concept reference (they might not be in type constraints, for example)
  133. bool hasExplicitTemplateArgs() const {
  134. return ArgsAsWritten != nullptr;
  135. }
  136. };
  137. class TypeConstraint : public ConceptReference {
  138. /// \brief The immediately-declared constraint expression introduced by this
  139. /// type-constraint.
  140. Expr *ImmediatelyDeclaredConstraint = nullptr;
  141. public:
  142. TypeConstraint(NestedNameSpecifierLoc NNS,
  143. DeclarationNameInfo ConceptNameInfo, NamedDecl *FoundDecl,
  144. ConceptDecl *NamedConcept,
  145. const ASTTemplateArgumentListInfo *ArgsAsWritten,
  146. Expr *ImmediatelyDeclaredConstraint) :
  147. ConceptReference(NNS, /*TemplateKWLoc=*/SourceLocation(), ConceptNameInfo,
  148. FoundDecl, NamedConcept, ArgsAsWritten),
  149. ImmediatelyDeclaredConstraint(ImmediatelyDeclaredConstraint) {}
  150. /// \brief Get the immediately-declared constraint expression introduced by
  151. /// this type-constraint, that is - the constraint expression that is added to
  152. /// the associated constraints of the enclosing declaration in practice.
  153. Expr *getImmediatelyDeclaredConstraint() const {
  154. return ImmediatelyDeclaredConstraint;
  155. }
  156. void print(llvm::raw_ostream &OS, PrintingPolicy Policy) const;
  157. };
  158. } // clang
  159. #endif // LLVM_CLANG_AST_ASTCONCEPT_H
  160. #ifdef __GNUC__
  161. #pragma GCC diagnostic pop
  162. #endif