diff options
Diffstat (limited to 'contrib/llvm-project/clang/include/clang/AST/DeclTemplate.h')
-rwxr-xr-x | contrib/llvm-project/clang/include/clang/AST/DeclTemplate.h | 241 |
1 files changed, 163 insertions, 78 deletions
diff --git a/contrib/llvm-project/clang/include/clang/AST/DeclTemplate.h b/contrib/llvm-project/clang/include/clang/AST/DeclTemplate.h index cbaa287f225a..7cd505218f2b 100755 --- a/contrib/llvm-project/clang/include/clang/AST/DeclTemplate.h +++ b/contrib/llvm-project/clang/include/clang/AST/DeclTemplate.h @@ -15,6 +15,7 @@ #define LLVM_CLANG_AST_DECLTEMPLATE_H #include "clang/AST/ASTConcept.h" +#include "clang/AST/ASTContext.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclBase.h" #include "clang/AST/DeclCXX.h" @@ -38,6 +39,7 @@ #include <cstddef> #include <cstdint> #include <iterator> +#include <optional> #include <utility> namespace clang { @@ -115,6 +117,8 @@ public: SourceLocation RAngleLoc, Expr *RequiresClause); + void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &C) const; + /// Iterates through the template parameters in this list. using iterator = NamedDecl **; @@ -128,11 +132,9 @@ public: unsigned size() const { return NumParams; } - ArrayRef<NamedDecl*> asArray() { - return llvm::makeArrayRef(begin(), end()); - } + ArrayRef<NamedDecl *> asArray() { return llvm::ArrayRef(begin(), end()); } ArrayRef<const NamedDecl*> asArray() const { - return llvm::makeArrayRef(begin(), size()); + return llvm::ArrayRef(begin(), size()); } NamedDecl* getParam(unsigned Idx) { @@ -203,7 +205,8 @@ public: void print(raw_ostream &Out, const ASTContext &Context, const PrintingPolicy &Policy, bool OmitTemplateKW = false) const; - static bool shouldIncludeTypeForArgument(const TemplateParameterList *TPL, + static bool shouldIncludeTypeForArgument(const PrintingPolicy &Policy, + const TemplateParameterList *TPL, unsigned Idx); }; @@ -272,8 +275,7 @@ public: /// /// This operation assumes that the input argument list outlives it. /// This takes the list as a pointer to avoid looking like a copy - /// constructor, since this really really isn't safe to use that - /// way. + /// constructor, since this really isn't safe to use that way. explicit TemplateArgumentList(const TemplateArgumentList *Other) : Arguments(Other->data()), NumArguments(Other->size()) {} @@ -288,7 +290,7 @@ public: /// Produce this as an array ref. ArrayRef<TemplateArgument> asArray() const { - return llvm::makeArrayRef(data(), size()); + return llvm::ArrayRef(data(), size()); } /// Retrieve the number of template arguments in this @@ -372,11 +374,19 @@ public: /// Set that the default argument was inherited from another parameter. void setInherited(const ASTContext &C, ParmDecl *InheritedFrom) { - assert(!isInherited() && "default argument already inherited"); InheritedFrom = getParmOwningDefaultArg(InheritedFrom); if (!isSet()) ValueOrInherited = InheritedFrom; - else + else if (auto *D = ValueOrInherited.template dyn_cast<ParmDecl *>()) { + assert(C.isSameDefaultTemplateArgument(D, InheritedFrom)); + ValueOrInherited = + new (allocateDefaultArgStorageChain(C)) Chain{InheritedFrom, get()}; + } else if (auto *Inherited = + ValueOrInherited.template dyn_cast<Chain *>()) { + assert(C.isSameDefaultTemplateArgument(Inherited->PrevDeclWithDefaultArg, + InheritedFrom)); + Inherited->PrevDeclWithDefaultArg = InheritedFrom; + } else ValueOrInherited = new (allocateDefaultArgStorageChain(C)) Chain{InheritedFrom, ValueOrInherited.template get<ArgType>()}; } @@ -430,6 +440,9 @@ public: /// Get the underlying, templated declaration. NamedDecl *getTemplatedDecl() const { return TemplatedDecl; } + // Should a specialization behave like an alias for another type. + bool isTypeAlias() const; + // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } @@ -446,18 +459,17 @@ protected: NamedDecl *TemplatedDecl; TemplateParameterList *TemplateParams; +public: void setTemplateParameters(TemplateParameterList *TParams) { TemplateParams = TParams; } -public: - /// Initialize the underlying templated declaration and - /// template parameters. - void init(NamedDecl *templatedDecl, TemplateParameterList* templateParams) { - assert(!TemplatedDecl && "TemplatedDecl already set!"); - assert(!TemplateParams && "TemplateParams already set!"); - TemplatedDecl = templatedDecl; - TemplateParams = templateParams; + /// Initialize the underlying templated declaration. + void init(NamedDecl *NewTemplatedDecl) { + if (TemplatedDecl) + assert(TemplatedDecl == NewTemplatedDecl && "Inconsistent TemplatedDecl"); + else + TemplatedDecl = NewTemplatedDecl; } }; @@ -497,7 +509,7 @@ private: TemplateSpecializationKind TSK, const TemplateArgumentList *TemplateArgs, const ASTTemplateArgumentListInfo *TemplateArgsAsWritten, SourceLocation POI, MemberSpecializationInfo *MSInfo) - : Function(FD, MSInfo ? 1 : 0), Template(Template, TSK - 1), + : Function(FD, MSInfo ? true : false), Template(Template, TSK - 1), TemplateArguments(TemplateArgs), TemplateArgumentsAsWritten(TemplateArgsAsWritten), PointOfInstantiation(POI) { @@ -606,7 +618,7 @@ public: static void Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs, - ASTContext &Context) { + const ASTContext &Context) { ID.AddInteger(TemplateArgs.size()); for (const TemplateArgument &TemplateArg : TemplateArgs) TemplateArg.Profile(ID, Context); @@ -729,6 +741,10 @@ public: /// Returns the number of explicit template arguments that were given. unsigned getNumTemplateArgs() const { return NumArgs; } + llvm::ArrayRef<TemplateArgumentLoc> arguments() const { + return llvm::ArrayRef(getTemplateArgs(), getNumTemplateArgs()); + } + /// Returns the nth template argument. const TemplateArgumentLoc &getTemplateArg(unsigned I) const { assert(I < getNumTemplateArgs() && "template arg index out of range"); @@ -831,6 +847,15 @@ protected: /// The first value in the array is the number of specializations/partial /// specializations that follow. uint32_t *LazySpecializations = nullptr; + + /// The set of "injected" template arguments used within this + /// template. + /// + /// This pointer refers to the template arguments (there are as + /// many template arguments as template parameters) for the + /// template, and is allocated lazily, since most templates do not + /// require the use of this information. + TemplateArgument *InjectedArgs = nullptr; }; /// Pointer to the common data shared by all declarations of this @@ -938,6 +963,14 @@ public: getCommonPtr()->InstantiatedFromMember.setPointer(TD); } + /// Retrieve the "injected" template arguments that correspond to the + /// template parameters of this template. + /// + /// Although the C++ standard has no notion of the "injected" template + /// arguments for a template, the notion is convenient when + /// we need to perform substitutions inside the definition of a template. + ArrayRef<TemplateArgument> getInjectedTemplateArgs(); + using redecl_range = redeclarable_base::redecl_range; using redecl_iterator = redeclarable_base::redecl_iterator; @@ -982,15 +1015,6 @@ protected: /// template, including explicit specializations and instantiations. llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> Specializations; - /// The set of "injected" template arguments used within this - /// function template. - /// - /// This pointer refers to the template arguments (there are as - /// many template arguments as template parameaters) for the function - /// template, and is allocated lazily, since most function templates do not - /// require the use of this information. - TemplateArgument *InjectedArgs = nullptr; - Common() = default; }; @@ -1090,21 +1114,12 @@ public: return makeSpecIterator(getSpecializations(), true); } - /// Retrieve the "injected" template arguments that correspond to the - /// template parameters of this function template. - /// - /// Although the C++ standard has no notion of the "injected" template - /// arguments for a function template, the notion is convenient when - /// we need to perform substitutions inside the definition of a function - /// template. - ArrayRef<TemplateArgument> getInjectedTemplateArgs(); - /// Return whether this function template is an abbreviated function template, /// e.g. `void foo(auto x)` or `template<typename T> void foo(auto x)` bool isAbbreviated() const { // Since the invented template parameters generated from 'auto' parameters // are either appended to the end of the explicit template parameter list or - // form a new template paramter list, we can simply observe the last + // form a new template parameter list, we can simply observe the last // parameter to determine if such a thing happened. const TemplateParameterList *TPL = getTemplateParameters(); return TPL->getParam(TPL->size() - 1)->isImplicit(); @@ -1143,23 +1158,40 @@ public: /// parameters and is not part of the Decl hierarchy. Just a facility. class TemplateParmPosition { protected: - // FIXME: These probably don't need to be ints. int:5 for depth, int:8 for - // position? Maybe? - unsigned Depth; - unsigned Position; + enum { DepthWidth = 20, PositionWidth = 12 }; + unsigned Depth : DepthWidth; + unsigned Position : PositionWidth; + + static constexpr unsigned MaxDepth = (1U << DepthWidth) - 1; + static constexpr unsigned MaxPosition = (1U << PositionWidth) - 1; - TemplateParmPosition(unsigned D, unsigned P) : Depth(D), Position(P) {} + TemplateParmPosition(unsigned D, unsigned P) : Depth(D), Position(P) { + // The input may fill maximum values to show that it is invalid. + // Add one here to convert it to zero. + assert((D + 1) <= MaxDepth && + "The depth of template parmeter position is more than 2^20!"); + assert((P + 1) <= MaxPosition && + "The position of template parmeter position is more than 2^12!"); + } public: TemplateParmPosition() = delete; /// Get the nesting depth of the template parameter. unsigned getDepth() const { return Depth; } - void setDepth(unsigned D) { Depth = D; } + void setDepth(unsigned D) { + assert((D + 1) <= MaxDepth && + "The depth of template parmeter position is more than 2^20!"); + Depth = D; + } /// Get the position of the template parameter within its parameter list. unsigned getPosition() const { return Position; } - void setPosition(unsigned P) { Position = P; } + void setPosition(unsigned P) { + assert((P + 1) <= MaxPosition && + "The position of template parmeter position is more than 2^12!"); + Position = P; + } /// Get the index of the template parameter within its parameter list. unsigned getIndex() const { return Position; } @@ -1189,10 +1221,10 @@ class TemplateTypeParmDecl final : public TypeDecl, /// Whether the type constraint has been initialized. This can be false if the /// constraint was not initialized yet or if there was an error forming the - /// type constriant. + /// type constraint. bool TypeConstraintInitialized : 1; - /// Whether this non-type template parameter is an "expanded" + /// Whether this type template parameter is an "expanded" /// parameter pack, meaning that its type is a pack expansion and we /// already know the set of types that expansion expands to. bool ExpandedParameterPack : 1; @@ -1206,23 +1238,20 @@ class TemplateTypeParmDecl final : public TypeDecl, DefArgStorage DefaultArgument; TemplateTypeParmDecl(DeclContext *DC, SourceLocation KeyLoc, - SourceLocation IdLoc, IdentifierInfo *Id, - bool Typename, bool HasTypeConstraint, - Optional<unsigned> NumExpanded) + SourceLocation IdLoc, IdentifierInfo *Id, bool Typename, + bool HasTypeConstraint, + std::optional<unsigned> NumExpanded) : TypeDecl(TemplateTypeParm, DC, IdLoc, Id, KeyLoc), Typename(Typename), - HasTypeConstraint(HasTypeConstraint), TypeConstraintInitialized(false), - ExpandedParameterPack(NumExpanded), - NumExpanded(NumExpanded ? *NumExpanded : 0) {} + HasTypeConstraint(HasTypeConstraint), TypeConstraintInitialized(false), + ExpandedParameterPack(NumExpanded), + NumExpanded(NumExpanded.value_or(0)) {} public: - static TemplateTypeParmDecl *Create(const ASTContext &C, DeclContext *DC, - SourceLocation KeyLoc, - SourceLocation NameLoc, - unsigned D, unsigned P, - IdentifierInfo *Id, bool Typename, - bool ParameterPack, - bool HasTypeConstraint = false, - Optional<unsigned> NumExpanded = None); + static TemplateTypeParmDecl * + Create(const ASTContext &C, DeclContext *DC, SourceLocation KeyLoc, + SourceLocation NameLoc, unsigned D, unsigned P, IdentifierInfo *Id, + bool Typename, bool ParameterPack, bool HasTypeConstraint = false, + std::optional<unsigned> NumExpanded = std::nullopt); static TemplateTypeParmDecl *CreateDeserialized(const ASTContext &C, unsigned ID); static TemplateTypeParmDecl *CreateDeserialized(const ASTContext &C, @@ -1358,7 +1387,7 @@ public: /// \brief Get the associated-constraints of this template parameter. /// This will either be the immediately-introduced constraint or empty. /// - /// Use this instead of getConstraintExpression for concepts APIs that + /// Use this instead of getTypeConstraint for concepts APIs that /// accept an ArrayRef of constraint expressions. void getAssociatedConstraints(llvm::SmallVectorImpl<const Expr *> &AC) const { if (HasTypeConstraint) @@ -2054,7 +2083,7 @@ public: static void Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs, - ASTContext &Context) { + const ASTContext &Context) { ID.AddInteger(TemplateArgs.size()); for (const TemplateArgument &TemplateArg : TemplateArgs) TemplateArg.Profile(ID, Context); @@ -2230,7 +2259,7 @@ public: static void Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs, - TemplateParameterList *TPL, ASTContext &Context); + TemplateParameterList *TPL, const ASTContext &Context); static bool classof(const Decl *D) { return classofKind(D->getKind()); } @@ -2280,9 +2309,15 @@ protected: return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr()); } + void setCommonPtr(Common *C) { + RedeclarableTemplateDecl::Common = C; + } + public: + friend class ASTDeclReader; friend class ASTDeclWriter; + friend class TemplateDeclInstantiator; /// Load any lazily-loaded specializations from the external source. void LoadLazySpecializations() const; @@ -2457,10 +2492,10 @@ private: SourceLocation FriendLoc; FriendTemplateDecl(DeclContext *DC, SourceLocation Loc, - MutableArrayRef<TemplateParameterList *> Params, + TemplateParameterList **Params, unsigned NumParams, FriendUnion Friend, SourceLocation FriendLoc) - : Decl(Decl::FriendTemplate, DC, Loc), NumParams(Params.size()), - Params(Params.data()), Friend(Friend), FriendLoc(FriendLoc) {} + : Decl(Decl::FriendTemplate, DC, Loc), NumParams(NumParams), + Params(Params), Friend(Friend), FriendLoc(FriendLoc) {} FriendTemplateDecl(EmptyShell Empty) : Decl(Decl::FriendTemplate, Empty) {} @@ -2697,7 +2732,7 @@ class VarTemplateSpecializationDecl : public VarDecl, /// The template arguments used to describe this specialization. const TemplateArgumentList *TemplateArgs; - TemplateArgumentListInfo TemplateArgsInfo; + const ASTTemplateArgumentListInfo *TemplateArgsInfo = nullptr; /// The point where this template was instantiated (if any). SourceLocation PointOfInstantiation; @@ -2752,8 +2787,9 @@ public: // TODO: Always set this when creating the new specialization? void setTemplateArgsInfo(const TemplateArgumentListInfo &ArgsInfo); + void setTemplateArgsInfo(const ASTTemplateArgumentListInfo *ArgsInfo); - const TemplateArgumentListInfo &getTemplateArgsInfo() const { + const ASTTemplateArgumentListInfo *getTemplateArgsInfo() const { return TemplateArgsInfo; } @@ -2898,13 +2934,15 @@ public: return ExplicitInfo ? ExplicitInfo->TemplateKeywordLoc : SourceLocation(); } + SourceRange getSourceRange() const override LLVM_READONLY; + void Profile(llvm::FoldingSetNodeID &ID) const { Profile(ID, TemplateArgs->asArray(), getASTContext()); } static void Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs, - ASTContext &Context) { + const ASTContext &Context) { ID.AddInteger(TemplateArgs.size()); for (const TemplateArgument &TemplateArg : TemplateArgs) TemplateArg.Profile(ID, Context); @@ -3055,6 +3093,8 @@ public: return First->InstantiatedFromMember.setInt(true); } + SourceRange getSourceRange() const override LLVM_READONLY; + void Profile(llvm::FoldingSetNodeID &ID) const { Profile(ID, getTemplateArgs().asArray(), getTemplateParameters(), getASTContext()); @@ -3062,7 +3102,7 @@ public: static void Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs, - TemplateParameterList *TPL, ASTContext &Context); + TemplateParameterList *TPL, const ASTContext &Context); static bool classof(const Decl *D) { return classofKind(D->getKind()); } @@ -3227,7 +3267,7 @@ public: static bool classofKind(Kind K) { return K == VarTemplate; } }; -/// Declaration of a C++2a concept. +/// Declaration of a C++20 concept. class ConceptDecl : public TemplateDecl, public Mergeable<ConceptDecl> { protected: Expr *ConstraintExpr; @@ -3256,8 +3296,12 @@ public: return isa<TemplateTypeParmDecl>(getTemplateParameters()->getParam(0)); } - ConceptDecl *getCanonicalDecl() override { return getFirstDecl(); } - const ConceptDecl *getCanonicalDecl() const { return getFirstDecl(); } + ConceptDecl *getCanonicalDecl() override { + return cast<ConceptDecl>(getPrimaryMergedDecl(this)); + } + const ConceptDecl *getCanonicalDecl() const { + return const_cast<ConceptDecl *>(this)->getCanonicalDecl(); + } // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } @@ -3268,6 +3312,40 @@ public: friend class ASTDeclWriter; }; +// An implementation detail of ConceptSpecialicationExpr that holds the template +// arguments, so we can later use this to reconstitute the template arguments +// during constraint checking. +class ImplicitConceptSpecializationDecl final + : public Decl, + private llvm::TrailingObjects<ImplicitConceptSpecializationDecl, + TemplateArgument> { + unsigned NumTemplateArgs; + + ImplicitConceptSpecializationDecl(DeclContext *DC, SourceLocation SL, + ArrayRef<TemplateArgument> ConvertedArgs); + ImplicitConceptSpecializationDecl(EmptyShell Empty, unsigned NumTemplateArgs); + +public: + static ImplicitConceptSpecializationDecl * + Create(const ASTContext &C, DeclContext *DC, SourceLocation SL, + ArrayRef<TemplateArgument> ConvertedArgs); + static ImplicitConceptSpecializationDecl * + CreateDeserialized(const ASTContext &C, unsigned ID, + unsigned NumTemplateArgs); + + ArrayRef<TemplateArgument> getTemplateArguments() const { + return ArrayRef<TemplateArgument>(getTrailingObjects<TemplateArgument>(), + NumTemplateArgs); + } + void setTemplateArguments(ArrayRef<TemplateArgument> Converted); + + static bool classofKind(Kind K) { return K == ImplicitConceptSpecialization; } + static bool classof(const Decl *D) { return classofKind(D->getKind()); } + + friend TrailingObjects; + friend class ASTDeclReader; +}; + /// A template parameter object. /// /// Template parameter objects represent values of class type used as template @@ -3305,14 +3383,17 @@ private: public: /// Print this template parameter object in a human-readable format. - void printName(llvm::raw_ostream &OS) const override; + void printName(llvm::raw_ostream &OS, + const PrintingPolicy &Policy) const override; /// Print this object as an equivalent expression. void printAsExpr(llvm::raw_ostream &OS) const; + void printAsExpr(llvm::raw_ostream &OS, const PrintingPolicy &Policy) const; /// Print this object as an initializer suitable for a variable of the /// object's type. void printAsInit(llvm::raw_ostream &OS) const; + void printAsInit(llvm::raw_ostream &OS, const PrintingPolicy &Policy) const; const APValue &getValue() const { return Value; } @@ -3365,7 +3446,7 @@ inline TemplateDecl *getAsTypeTemplateDecl(Decl *D) { /// /// In \c A<int,int>::B, \c NTs and \c TTs have expanded pack size 2, and \c Us /// is not a pack expansion, so returns an empty Optional. -inline Optional<unsigned> getExpandedPackSize(const NamedDecl *Param) { +inline std::optional<unsigned> getExpandedPackSize(const NamedDecl *Param) { if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) { if (TTP->isExpandedParameterPack()) return TTP->getNumExpansionParameters(); @@ -3381,9 +3462,13 @@ inline Optional<unsigned> getExpandedPackSize(const NamedDecl *Param) { return TTP->getNumExpansionTemplateParameters(); } - return None; + return std::nullopt; } +/// Internal helper used by Subst* nodes to retrieve the parameter list +/// for their AssociatedDecl. +TemplateParameterList *getReplacedTemplateParameterList(Decl *D); + } // namespace clang #endif // LLVM_CLANG_AST_DECLTEMPLATE_H |