123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205 |
- #pragma once
- #ifdef __GNUC__
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wunused-parameter"
- #endif
- //===--- ASTConcept.h - Concepts Related AST Data Structures ----*- C++ -*-===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- ///
- /// \file
- /// \brief This file provides AST data structures related to concepts.
- ///
- //===----------------------------------------------------------------------===//
- #ifndef LLVM_CLANG_AST_ASTCONCEPT_H
- #define LLVM_CLANG_AST_ASTCONCEPT_H
- #include "clang/AST/Expr.h"
- #include "clang/Basic/SourceLocation.h"
- #include "llvm/ADT/PointerUnion.h"
- #include "llvm/ADT/SmallVector.h"
- #include <utility>
- namespace clang {
- class ConceptDecl;
- /// The result of a constraint satisfaction check, containing the necessary
- /// information to diagnose an unsatisfied constraint.
- class ConstraintSatisfaction : public llvm::FoldingSetNode {
- // The template-like entity that 'owns' the constraint checked here (can be a
- // constrained entity or a concept).
- const NamedDecl *ConstraintOwner = nullptr;
- llvm::SmallVector<TemplateArgument, 4> TemplateArgs;
- public:
- ConstraintSatisfaction() = default;
- ConstraintSatisfaction(const NamedDecl *ConstraintOwner,
- ArrayRef<TemplateArgument> TemplateArgs) :
- ConstraintOwner(ConstraintOwner), TemplateArgs(TemplateArgs.begin(),
- TemplateArgs.end()) { }
- using SubstitutionDiagnostic = std::pair<SourceLocation, StringRef>;
- using Detail = llvm::PointerUnion<Expr *, SubstitutionDiagnostic *>;
- bool IsSatisfied = false;
- /// \brief Pairs of unsatisfied atomic constraint expressions along with the
- /// substituted constraint expr, if the template arguments could be
- /// substituted into them, or a diagnostic if substitution resulted in an
- /// invalid expression.
- llvm::SmallVector<std::pair<const Expr *, Detail>, 4> Details;
- void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &C) {
- Profile(ID, C, ConstraintOwner, TemplateArgs);
- }
- static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &C,
- const NamedDecl *ConstraintOwner,
- ArrayRef<TemplateArgument> TemplateArgs);
- };
- /// Pairs of unsatisfied atomic constraint expressions along with the
- /// substituted constraint expr, if the template arguments could be
- /// substituted into them, or a diagnostic if substitution resulted in
- /// an invalid expression.
- using UnsatisfiedConstraintRecord =
- std::pair<const Expr *,
- llvm::PointerUnion<Expr *,
- std::pair<SourceLocation, StringRef> *>>;
- /// \brief The result of a constraint satisfaction check, containing the
- /// necessary information to diagnose an unsatisfied constraint.
- ///
- /// This is safe to store in an AST node, as opposed to ConstraintSatisfaction.
- struct ASTConstraintSatisfaction final :
- llvm::TrailingObjects<ASTConstraintSatisfaction,
- UnsatisfiedConstraintRecord> {
- std::size_t NumRecords;
- bool IsSatisfied : 1;
- const UnsatisfiedConstraintRecord *begin() const {
- return getTrailingObjects<UnsatisfiedConstraintRecord>();
- }
- const UnsatisfiedConstraintRecord *end() const {
- return getTrailingObjects<UnsatisfiedConstraintRecord>() + NumRecords;
- }
- ASTConstraintSatisfaction(const ASTContext &C,
- const ConstraintSatisfaction &Satisfaction);
- static ASTConstraintSatisfaction *
- Create(const ASTContext &C, const ConstraintSatisfaction &Satisfaction);
- };
- /// \brief Common data class for constructs that reference concepts with
- /// template arguments.
- class ConceptReference {
- protected:
- // \brief The optional nested name specifier used when naming the concept.
- NestedNameSpecifierLoc NestedNameSpec;
- /// \brief The location of the template keyword, if specified when naming the
- /// concept.
- SourceLocation TemplateKWLoc;
- /// \brief The concept name used.
- DeclarationNameInfo ConceptName;
- /// \brief The declaration found by name lookup when the expression was
- /// created.
- /// Can differ from NamedConcept when, for example, the concept was found
- /// through a UsingShadowDecl.
- NamedDecl *FoundDecl;
- /// \brief The concept named.
- ConceptDecl *NamedConcept;
- /// \brief The template argument list source info used to specialize the
- /// concept.
- const ASTTemplateArgumentListInfo *ArgsAsWritten;
- public:
- ConceptReference(NestedNameSpecifierLoc NNS, SourceLocation TemplateKWLoc,
- DeclarationNameInfo ConceptNameInfo, NamedDecl *FoundDecl,
- ConceptDecl *NamedConcept,
- const ASTTemplateArgumentListInfo *ArgsAsWritten)
- : NestedNameSpec(NNS), TemplateKWLoc(TemplateKWLoc),
- ConceptName(ConceptNameInfo), FoundDecl(FoundDecl),
- NamedConcept(NamedConcept), ArgsAsWritten(ArgsAsWritten) {}
- ConceptReference()
- : FoundDecl(nullptr), NamedConcept(nullptr), ArgsAsWritten(nullptr) {}
- const NestedNameSpecifierLoc &getNestedNameSpecifierLoc() const {
- return NestedNameSpec;
- }
- const DeclarationNameInfo &getConceptNameInfo() const { return ConceptName; }
- SourceLocation getConceptNameLoc() const {
- return getConceptNameInfo().getLoc();
- }
- SourceLocation getTemplateKWLoc() const { return TemplateKWLoc; }
- NamedDecl *getFoundDecl() const {
- return FoundDecl;
- }
- ConceptDecl *getNamedConcept() const {
- return NamedConcept;
- }
- const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten() const {
- return ArgsAsWritten;
- }
- /// \brief Whether or not template arguments were explicitly specified in the
- /// concept reference (they might not be in type constraints, for example)
- bool hasExplicitTemplateArgs() const {
- return ArgsAsWritten != nullptr;
- }
- };
- class TypeConstraint : public ConceptReference {
- /// \brief The immediately-declared constraint expression introduced by this
- /// type-constraint.
- Expr *ImmediatelyDeclaredConstraint = nullptr;
- public:
- TypeConstraint(NestedNameSpecifierLoc NNS,
- DeclarationNameInfo ConceptNameInfo, NamedDecl *FoundDecl,
- ConceptDecl *NamedConcept,
- const ASTTemplateArgumentListInfo *ArgsAsWritten,
- Expr *ImmediatelyDeclaredConstraint) :
- ConceptReference(NNS, /*TemplateKWLoc=*/SourceLocation(), ConceptNameInfo,
- FoundDecl, NamedConcept, ArgsAsWritten),
- ImmediatelyDeclaredConstraint(ImmediatelyDeclaredConstraint) {}
- /// \brief Get the immediately-declared constraint expression introduced by
- /// this type-constraint, that is - the constraint expression that is added to
- /// the associated constraints of the enclosing declaration in practice.
- Expr *getImmediatelyDeclaredConstraint() const {
- return ImmediatelyDeclaredConstraint;
- }
- void print(llvm::raw_ostream &OS, PrintingPolicy Policy) const;
- };
- } // clang
- #endif // LLVM_CLANG_AST_ASTCONCEPT_H
- #ifdef __GNUC__
- #pragma GCC diagnostic pop
- #endif
|