Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  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
  208.