//===- DeclTemplate.h - Classes for representing C++ templates --*- 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 /// Defines the C++ template declaration subclasses. // //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_AST_DECLTEMPLATE_H #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" #include "clang/AST/DeclarationName.h" #include "clang/AST/Redeclarable.h" #include "clang/AST/TemplateBase.h" #include "clang/AST/Type.h" #include "clang/Basic/LLVM.h" #include "clang/Basic/SourceLocation.h" #include "clang/Basic/Specifiers.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/iterator.h" #include "llvm/ADT/iterator_range.h" #include "llvm/Support/Casting.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/TrailingObjects.h" #include <cassert> #include <cstddef> #include <cstdint> #include <iterator> #include <optional> #include <utility> namespace clang { enum BuiltinTemplateKind : int; class ClassTemplateDecl; class ClassTemplatePartialSpecializationDecl; class Expr; class FunctionTemplateDecl; class IdentifierInfo; class NonTypeTemplateParmDecl; class TemplateDecl; class TemplateTemplateParmDecl; class TemplateTypeParmDecl; class ConceptDecl; class UnresolvedSetImpl; class VarTemplateDecl; class VarTemplatePartialSpecializationDecl; /// Stores a template parameter of any kind. TemplateParameter; NamedDecl *getAsNamedDecl(TemplateParameter P); /// Stores a list of template parameters for a TemplateDecl and its /// derived classes. class TemplateParameterList final : private llvm::TrailingObjects<TemplateParameterList, NamedDecl *, Expr *> { … }; /// Stores a list of template parameters and the associated /// requires-clause (if any) for a TemplateDecl and its derived classes. /// Suitable for creating on the stack. template <size_t N, bool HasRequiresClause> class FixedSizeTemplateParameterListStorage : public TemplateParameterList::FixedSizeStorageOwner { … }; /// A template argument list. class TemplateArgumentList final : private llvm::TrailingObjects<TemplateArgumentList, TemplateArgument> { … }; void *allocateDefaultArgStorageChain(const ASTContext &C); /// Storage for a default argument. This is conceptually either empty, or an /// argument value, or a pointer to a previous declaration that had a default /// argument. /// /// However, this is complicated by modules: while we require all the default /// arguments for a template to be equivalent, there may be more than one, and /// we need to track all the originating parameters to determine if the default /// argument is visible. template<typename ParmDecl, typename ArgType> class DefaultArgStorage { … }; //===----------------------------------------------------------------------===// // Kinds of Templates //===----------------------------------------------------------------------===// /// \brief The base class of all kinds of template declarations (e.g., /// class, function, etc.). /// /// The TemplateDecl class stores the list of template parameters and a /// reference to the templated scoped declaration: the underlying AST node. class TemplateDecl : public NamedDecl { … }; /// Provides information about a function template specialization, /// which is a FunctionDecl that has been explicitly specialization or /// instantiated from a function template. class FunctionTemplateSpecializationInfo final : public llvm::FoldingSetNode, private llvm::TrailingObjects<FunctionTemplateSpecializationInfo, MemberSpecializationInfo *> { … }; /// Provides information a specialization of a member of a class /// template, which may be a member function, static data member, /// member class or member enumeration. class MemberSpecializationInfo { … }; /// Provides information about a dependent function-template /// specialization declaration. /// /// This is used for function templates explicit specializations declared /// within class templates: /// /// \code /// template<typename> struct A { /// template<typename> void f(); /// template<> void f<int>(); // DependentFunctionTemplateSpecializationInfo /// }; /// \endcode /// /// As well as dependent friend declarations naming function template /// specializations declared within class templates: /// /// \code /// template \<class T> void foo(T); /// template \<class T> class A { /// friend void foo<>(T); // DependentFunctionTemplateSpecializationInfo /// }; /// \endcode class DependentFunctionTemplateSpecializationInfo final : private llvm::TrailingObjects<DependentFunctionTemplateSpecializationInfo, FunctionTemplateDecl *> { … }; /// Declaration of a redeclarable template. class RedeclarableTemplateDecl : public TemplateDecl, public Redeclarable<RedeclarableTemplateDecl> { … }; template <> struct RedeclarableTemplateDecl:: SpecEntryTraits<FunctionTemplateSpecializationInfo> { … }; /// Declaration of a template function. class FunctionTemplateDecl : public RedeclarableTemplateDecl { … }; //===----------------------------------------------------------------------===// // Kinds of Template Parameters //===----------------------------------------------------------------------===// /// Defines the position of a template parameter within a template /// parameter list. /// /// Because template parameter can be listed /// sequentially for out-of-line template members, each template parameter is /// given a Depth - the nesting of template parameter scopes - and a Position - /// the occurrence within the parameter list. /// This class is inheritedly privately by different kinds of template /// parameters and is not part of the Decl hierarchy. Just a facility. class TemplateParmPosition { … }; /// Declaration of a template type parameter. /// /// For example, "T" in /// \code /// template<typename T> class vector; /// \endcode class TemplateTypeParmDecl final : public TypeDecl, private llvm::TrailingObjects<TemplateTypeParmDecl, TypeConstraint> { … }; /// NonTypeTemplateParmDecl - Declares a non-type template parameter, /// e.g., "Size" in /// @code /// template<int Size> class array { }; /// @endcode class NonTypeTemplateParmDecl final : public DeclaratorDecl, protected TemplateParmPosition, private llvm::TrailingObjects<NonTypeTemplateParmDecl, std::pair<QualType, TypeSourceInfo *>, Expr *> { … }; /// TemplateTemplateParmDecl - Declares a template template parameter, /// e.g., "T" in /// @code /// template <template <typename> class T> class container { }; /// @endcode /// A template template parameter is a TemplateDecl because it defines the /// name of a template and the template parameters allowable for substitution. class TemplateTemplateParmDecl final : public TemplateDecl, protected TemplateParmPosition, private llvm::TrailingObjects<TemplateTemplateParmDecl, TemplateParameterList *> { … }; /// Represents the builtin template declaration which is used to /// implement __make_integer_seq and other builtin templates. It serves /// no real purpose beyond existing as a place to hold template parameters. class BuiltinTemplateDecl : public TemplateDecl { … }; /// Provides information about an explicit instantiation of a variable or class /// template. struct ExplicitInstantiationInfo { … }; SpecializationOrInstantiationInfo; /// Represents a class template specialization, which refers to /// a class template with a given set of template arguments. /// /// Class template specializations represent both explicit /// specialization of class templates, as in the example below, and /// implicit instantiations of class templates. /// /// \code /// template<typename T> class array; /// /// template<> /// class array<bool> { }; // class template specialization array<bool> /// \endcode class ClassTemplateSpecializationDecl : public CXXRecordDecl, public llvm::FoldingSetNode { … }; class ClassTemplatePartialSpecializationDecl : public ClassTemplateSpecializationDecl { … }; /// Declaration of a class template. class ClassTemplateDecl : public RedeclarableTemplateDecl { … }; /// Declaration of a friend template. /// /// For example: /// \code /// template \<typename T> class A { /// friend class MyVector<T>; // not a friend template /// template \<typename U> friend class B; // not a friend template /// template \<typename U> friend class Foo<T>::Nested; // friend template /// }; /// \endcode /// /// \note This class is not currently in use. All of the above /// will yield a FriendDecl, not a FriendTemplateDecl. class FriendTemplateDecl : public Decl { … }; /// Declaration of an alias template. /// /// For example: /// \code /// template \<typename T> using V = std::map<T*, int, MyCompare<T>>; /// \endcode class TypeAliasTemplateDecl : public RedeclarableTemplateDecl { … }; /// Represents a variable template specialization, which refers to /// a variable template with a given set of template arguments. /// /// Variable template specializations represent both explicit /// specializations of variable templates, as in the example below, and /// implicit instantiations of variable templates. /// /// \code /// template<typename T> constexpr T pi = T(3.1415926535897932385); /// /// template<> /// constexpr float pi<float>; // variable template specialization pi<float> /// \endcode class VarTemplateSpecializationDecl : public VarDecl, public llvm::FoldingSetNode { … }; class VarTemplatePartialSpecializationDecl : public VarTemplateSpecializationDecl { … }; /// Declaration of a variable template. class VarTemplateDecl : public RedeclarableTemplateDecl { … }; /// Declaration of a C++20 concept. class ConceptDecl : public TemplateDecl, public Mergeable<ConceptDecl> { … }; // 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> { … }; /// A template parameter object. /// /// Template parameter objects represent values of class type used as template /// arguments. There is one template parameter object for each such distinct /// value used as a template argument across the program. /// /// \code /// struct A { int x, y; }; /// template<A> struct S; /// S<A{1, 2}> s1; /// S<A{1, 2}> s2; // same type, argument is same TemplateParamObjectDecl. /// \endcode class TemplateParamObjectDecl : public ValueDecl, public Mergeable<TemplateParamObjectDecl>, public llvm::FoldingSetNode { … }; inline NamedDecl *getAsNamedDecl(TemplateParameter P) { … } inline TemplateDecl *getAsTypeTemplateDecl(Decl *D) { … } /// Check whether the template parameter is a pack expansion, and if so, /// determine the number of parameters produced by that expansion. For instance: /// /// \code /// template<typename ...Ts> struct A { /// template<Ts ...NTs, template<Ts> class ...TTs, typename ...Us> struct B; /// }; /// \endcode /// /// 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 std::optional<unsigned> getExpandedPackSize(const NamedDecl *Param) { … } /// 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