summaryrefslogtreecommitdiffstats
path: root/include/clang/AST/DeclTemplate.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/AST/DeclTemplate.h')
-rw-r--r--include/clang/AST/DeclTemplate.h2927
1 files changed, 0 insertions, 2927 deletions
diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h
deleted file mode 100644
index a9109ef..0000000
--- a/include/clang/AST/DeclTemplate.h
+++ /dev/null
@@ -1,2927 +0,0 @@
-//===-- DeclTemplate.h - Classes for representing C++ templates -*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// \brief Defines the C++ template declaration subclasses.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_AST_DECLTEMPLATE_H
-#define LLVM_CLANG_AST_DECLTEMPLATE_H
-
-#include "clang/AST/DeclCXX.h"
-#include "clang/AST/Redeclarable.h"
-#include "clang/AST/TemplateBase.h"
-#include "llvm/ADT/PointerUnion.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/TrailingObjects.h"
-#include <limits>
-
-namespace clang {
-
-enum BuiltinTemplateKind : int;
-class TemplateParameterList;
-class TemplateDecl;
-class RedeclarableTemplateDecl;
-class FunctionTemplateDecl;
-class ClassTemplateDecl;
-class ClassTemplatePartialSpecializationDecl;
-class TemplateTypeParmDecl;
-class NonTypeTemplateParmDecl;
-class TemplateTemplateParmDecl;
-class TypeAliasTemplateDecl;
-class VarTemplateDecl;
-class VarTemplatePartialSpecializationDecl;
-
-/// \brief Stores a template parameter of any kind.
-typedef llvm::PointerUnion3<TemplateTypeParmDecl*, NonTypeTemplateParmDecl*,
- TemplateTemplateParmDecl*> TemplateParameter;
-
-/// \brief Stores a list of template parameters for a TemplateDecl and its
-/// derived classes.
-class TemplateParameterList final
- : private llvm::TrailingObjects<TemplateParameterList, NamedDecl *> {
-
- /// The location of the 'template' keyword.
- SourceLocation TemplateLoc;
-
- /// The locations of the '<' and '>' angle brackets.
- SourceLocation LAngleLoc, RAngleLoc;
-
- /// The number of template parameters in this template
- /// parameter list.
- unsigned NumParams : 31;
-
- /// Whether this template parameter list contains an unexpanded parameter
- /// pack.
- unsigned ContainsUnexpandedParameterPack : 1;
-
-protected:
- size_t numTrailingObjects(OverloadToken<NamedDecl *>) const {
- return NumParams;
- }
-
- TemplateParameterList(SourceLocation TemplateLoc, SourceLocation LAngleLoc,
- ArrayRef<NamedDecl *> Params, SourceLocation RAngleLoc);
-
-public:
- static TemplateParameterList *Create(const ASTContext &C,
- SourceLocation TemplateLoc,
- SourceLocation LAngleLoc,
- ArrayRef<NamedDecl *> Params,
- SourceLocation RAngleLoc);
-
- /// \brief Iterates through the template parameters in this list.
- typedef NamedDecl** iterator;
-
- /// \brief Iterates through the template parameters in this list.
- typedef NamedDecl* const* const_iterator;
-
- iterator begin() { return getTrailingObjects<NamedDecl *>(); }
- const_iterator begin() const { return getTrailingObjects<NamedDecl *>(); }
- iterator end() { return begin() + NumParams; }
- const_iterator end() const { return begin() + NumParams; }
-
- unsigned size() const { return NumParams; }
-
- ArrayRef<NamedDecl*> asArray() {
- return llvm::makeArrayRef(begin(), end());
- }
- ArrayRef<const NamedDecl*> asArray() const {
- return llvm::makeArrayRef(begin(), size());
- }
-
- NamedDecl* getParam(unsigned Idx) {
- assert(Idx < size() && "Template parameter index out-of-range");
- return begin()[Idx];
- }
-
- const NamedDecl* getParam(unsigned Idx) const {
- assert(Idx < size() && "Template parameter index out-of-range");
- return begin()[Idx];
- }
-
- /// \brief Returns the minimum number of arguments needed to form a
- /// template specialization.
- ///
- /// This may be fewer than the number of template parameters, if some of
- /// the parameters have default arguments or if there is a parameter pack.
- unsigned getMinRequiredArguments() const;
-
- /// \brief Get the depth of this template parameter list in the set of
- /// template parameter lists.
- ///
- /// The first template parameter list in a declaration will have depth 0,
- /// the second template parameter list will have depth 1, etc.
- unsigned getDepth() const;
-
- /// \brief Determine whether this template parameter list contains an
- /// unexpanded parameter pack.
- bool containsUnexpandedParameterPack() const {
- return ContainsUnexpandedParameterPack;
- }
-
- SourceLocation getTemplateLoc() const { return TemplateLoc; }
- SourceLocation getLAngleLoc() const { return LAngleLoc; }
- SourceLocation getRAngleLoc() const { return RAngleLoc; }
-
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(TemplateLoc, RAngleLoc);
- }
-
- friend TrailingObjects;
- template <size_t N> friend class FixedSizeTemplateParameterListStorage;
-};
-
-/// \brief Stores a list of template parameters for a TemplateDecl and its
-/// derived classes. Suitable for creating on the stack.
-template <size_t N> class FixedSizeTemplateParameterListStorage {
- // This is kinda ugly: TemplateParameterList usually gets allocated
- // in a block of memory with NamedDecls appended to it. Here, to get
- // it stack allocated, we include the params as a separate
- // variable. After allocation, the TemplateParameterList object
- // treats them as part of itself.
- TemplateParameterList List;
- NamedDecl *Params[N];
-
-public:
- FixedSizeTemplateParameterListStorage(SourceLocation TemplateLoc,
- SourceLocation LAngleLoc,
- ArrayRef<NamedDecl *> Params,
- SourceLocation RAngleLoc)
- : List(TemplateLoc, LAngleLoc, Params, RAngleLoc) {
- // Because we're doing an evil layout hack above, have some
- // asserts, just to double-check everything is laid out like
- // expected.
- assert(sizeof(*this) ==
- TemplateParameterList::totalSizeToAlloc<NamedDecl *>(N) &&
- "Object layout not as expected");
- assert(this->Params == List.getTrailingObjects<NamedDecl *>() &&
- "Object layout not as expected");
- }
- TemplateParameterList *get() { return &List; }
-};
-
-/// \brief A template argument list.
-class TemplateArgumentList final
- : private llvm::TrailingObjects<TemplateArgumentList, TemplateArgument> {
- /// \brief The template argument list.
- const TemplateArgument *Arguments;
-
- /// \brief The number of template arguments in this template
- /// argument list.
- unsigned NumArguments;
-
- TemplateArgumentList(const TemplateArgumentList &Other) = delete;
- void operator=(const TemplateArgumentList &Other) = delete;
-
- // Constructs an instance with an internal Argument list, containing
- // a copy of the Args array. (Called by CreateCopy)
- TemplateArgumentList(const TemplateArgument *Args, unsigned NumArgs);
-
-public:
- /// \brief Type used to indicate that the template argument list itself is a
- /// stack object. It does not own its template arguments.
- enum OnStackType { OnStack };
-
- /// \brief Create a new template argument list that copies the given set of
- /// template arguments.
- static TemplateArgumentList *CreateCopy(ASTContext &Context,
- const TemplateArgument *Args,
- unsigned NumArgs);
-
- /// \brief Construct a new, temporary template argument list on the stack.
- ///
- /// The template argument list does not own the template arguments
- /// provided.
- explicit TemplateArgumentList(OnStackType, const TemplateArgument *Args,
- unsigned NumArgs)
- : Arguments(Args), NumArguments(NumArgs) {}
-
- /// \brief Produces a shallow copy of the given template argument list.
- ///
- /// 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.
- explicit TemplateArgumentList(const TemplateArgumentList *Other)
- : Arguments(Other->data()), NumArguments(Other->size()) {}
-
- /// \brief Retrieve the template argument at a given index.
- const TemplateArgument &get(unsigned Idx) const {
- assert(Idx < NumArguments && "Invalid template argument index");
- return data()[Idx];
- }
-
- /// \brief Retrieve the template argument at a given index.
- const TemplateArgument &operator[](unsigned Idx) const { return get(Idx); }
-
- /// \brief Produce this as an array ref.
- ArrayRef<TemplateArgument> asArray() const {
- return llvm::makeArrayRef(data(), size());
- }
-
- /// \brief Retrieve the number of template arguments in this
- /// template argument list.
- unsigned size() const { return NumArguments; }
-
- /// \brief Retrieve a pointer to the template argument list.
- const TemplateArgument *data() const { return Arguments; }
-
- friend TrailingObjects;
-};
-
-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 {
- /// Storage for both the value *and* another parameter from which we inherit
- /// the default argument. This is used when multiple default arguments for a
- /// parameter are merged together from different modules.
- struct Chain {
- ParmDecl *PrevDeclWithDefaultArg;
- ArgType Value;
- };
- static_assert(sizeof(Chain) == sizeof(void *) * 2,
- "non-pointer argument type?");
-
- llvm::PointerUnion3<ArgType, ParmDecl*, Chain*> ValueOrInherited;
-
- static ParmDecl *getParmOwningDefaultArg(ParmDecl *Parm) {
- const DefaultArgStorage &Storage = Parm->getDefaultArgStorage();
- if (auto *Prev = Storage.ValueOrInherited.template dyn_cast<ParmDecl*>())
- Parm = Prev;
- assert(!Parm->getDefaultArgStorage()
- .ValueOrInherited.template is<ParmDecl *>() &&
- "should only be one level of indirection");
- return Parm;
- }
-
-public:
- DefaultArgStorage() : ValueOrInherited(ArgType()) {}
-
- /// Determine whether there is a default argument for this parameter.
- bool isSet() const { return !ValueOrInherited.isNull(); }
- /// Determine whether the default argument for this parameter was inherited
- /// from a previous declaration of the same entity.
- bool isInherited() const { return ValueOrInherited.template is<ParmDecl*>(); }
- /// Get the default argument's value. This does not consider whether the
- /// default argument is visible.
- ArgType get() const {
- const DefaultArgStorage *Storage = this;
- if (auto *Prev = ValueOrInherited.template dyn_cast<ParmDecl*>())
- Storage = &Prev->getDefaultArgStorage();
- if (auto *C = Storage->ValueOrInherited.template dyn_cast<Chain*>())
- return C->Value;
- return Storage->ValueOrInherited.template get<ArgType>();
- }
- /// Get the parameter from which we inherit the default argument, if any.
- /// This is the parameter on which the default argument was actually written.
- const ParmDecl *getInheritedFrom() const {
- if (auto *D = ValueOrInherited.template dyn_cast<ParmDecl*>())
- return D;
- if (auto *C = ValueOrInherited.template dyn_cast<Chain*>())
- return C->PrevDeclWithDefaultArg;
- return nullptr;
- }
- /// Set the default argument.
- void set(ArgType Arg) {
- assert(!isSet() && "default argument already set");
- ValueOrInherited = Arg;
- }
- /// 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
- ValueOrInherited = new (allocateDefaultArgStorageChain(C))
- Chain{InheritedFrom, ValueOrInherited.template get<ArgType>()};
- }
- /// Remove the default argument, even if it was inherited.
- void clear() {
- ValueOrInherited = ArgType();
- }
-};
-
-//===----------------------------------------------------------------------===//
-// 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 {
- void anchor() override;
-protected:
- // This is probably never used.
- TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
- DeclarationName Name)
- : NamedDecl(DK, DC, L, Name), TemplatedDecl(nullptr),
- TemplateParams(nullptr) {}
-
- // Construct a template decl with the given name and parameters.
- // Used when there is not templated element (tt-params).
- TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
- DeclarationName Name, TemplateParameterList *Params)
- : NamedDecl(DK, DC, L, Name), TemplatedDecl(nullptr),
- TemplateParams(Params) {}
-
- // Construct a template decl with name, parameters, and templated element.
- TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
- DeclarationName Name, TemplateParameterList *Params,
- NamedDecl *Decl)
- : NamedDecl(DK, DC, L, Name), TemplatedDecl(Decl),
- TemplateParams(Params) { }
-public:
- /// Get the list of template parameters
- TemplateParameterList *getTemplateParameters() const {
- return TemplateParams;
- }
-
- /// Get the underlying, templated declaration.
- NamedDecl *getTemplatedDecl() const { return TemplatedDecl; }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) {
- return K >= firstTemplate && K <= lastTemplate;
- }
-
- SourceRange getSourceRange() const override LLVM_READONLY {
- return SourceRange(TemplateParams->getTemplateLoc(),
- TemplatedDecl->getSourceRange().getEnd());
- }
-
-protected:
- NamedDecl *TemplatedDecl;
- TemplateParameterList* TemplateParams;
-
-public:
- /// \brief 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;
- }
-};
-
-/// \brief Provides information about a function template specialization,
-/// which is a FunctionDecl that has been explicitly specialization or
-/// instantiated from a function template.
-class FunctionTemplateSpecializationInfo : public llvm::FoldingSetNode {
- FunctionTemplateSpecializationInfo(FunctionDecl *FD,
- FunctionTemplateDecl *Template,
- TemplateSpecializationKind TSK,
- const TemplateArgumentList *TemplateArgs,
- const ASTTemplateArgumentListInfo *TemplateArgsAsWritten,
- SourceLocation POI)
- : Function(FD),
- Template(Template, TSK - 1),
- TemplateArguments(TemplateArgs),
- TemplateArgumentsAsWritten(TemplateArgsAsWritten),
- PointOfInstantiation(POI) { }
-
-public:
- static FunctionTemplateSpecializationInfo *
- Create(ASTContext &C, FunctionDecl *FD, FunctionTemplateDecl *Template,
- TemplateSpecializationKind TSK,
- const TemplateArgumentList *TemplateArgs,
- const TemplateArgumentListInfo *TemplateArgsAsWritten,
- SourceLocation POI);
-
- /// \brief The function template specialization that this structure
- /// describes.
- FunctionDecl *Function;
-
- /// \brief The function template from which this function template
- /// specialization was generated.
- ///
- /// The two bits contain the top 4 values of TemplateSpecializationKind.
- llvm::PointerIntPair<FunctionTemplateDecl *, 2> Template;
-
- /// \brief The template arguments used to produce the function template
- /// specialization from the function template.
- const TemplateArgumentList *TemplateArguments;
-
- /// \brief The template arguments as written in the sources, if provided.
- const ASTTemplateArgumentListInfo *TemplateArgumentsAsWritten;
-
- /// \brief The point at which this function template specialization was
- /// first instantiated.
- SourceLocation PointOfInstantiation;
-
- /// \brief Retrieve the template from which this function was specialized.
- FunctionTemplateDecl *getTemplate() const { return Template.getPointer(); }
-
- /// \brief Determine what kind of template specialization this is.
- TemplateSpecializationKind getTemplateSpecializationKind() const {
- return (TemplateSpecializationKind)(Template.getInt() + 1);
- }
-
- bool isExplicitSpecialization() const {
- return getTemplateSpecializationKind() == TSK_ExplicitSpecialization;
- }
-
- /// \brief True if this declaration is an explicit specialization,
- /// explicit instantiation declaration, or explicit instantiation
- /// definition.
- bool isExplicitInstantiationOrSpecialization() const {
- return isTemplateExplicitInstantiationOrSpecialization(
- getTemplateSpecializationKind());
- }
-
- /// \brief Set the template specialization kind.
- void setTemplateSpecializationKind(TemplateSpecializationKind TSK) {
- assert(TSK != TSK_Undeclared &&
- "Cannot encode TSK_Undeclared for a function template specialization");
- Template.setInt(TSK - 1);
- }
-
- /// \brief Retrieve the first point of instantiation of this function
- /// template specialization.
- ///
- /// The point of instantiation may be an invalid source location if this
- /// function has yet to be instantiated.
- SourceLocation getPointOfInstantiation() const {
- return PointOfInstantiation;
- }
-
- /// \brief Set the (first) point of instantiation of this function template
- /// specialization.
- void setPointOfInstantiation(SourceLocation POI) {
- PointOfInstantiation = POI;
- }
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, TemplateArguments->asArray(),
- Function->getASTContext());
- }
-
- static void
- Profile(llvm::FoldingSetNodeID &ID, ArrayRef<TemplateArgument> TemplateArgs,
- ASTContext &Context) {
- ID.AddInteger(TemplateArgs.size());
- for (unsigned Arg = 0; Arg != TemplateArgs.size(); ++Arg)
- TemplateArgs[Arg].Profile(ID, Context);
- }
-};
-
-/// \brief 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 {
- // The member declaration from which this member was instantiated, and the
- // manner in which the instantiation occurred (in the lower two bits).
- llvm::PointerIntPair<NamedDecl *, 2> MemberAndTSK;
-
- // The point at which this member was first instantiated.
- SourceLocation PointOfInstantiation;
-
-public:
- explicit
- MemberSpecializationInfo(NamedDecl *IF, TemplateSpecializationKind TSK,
- SourceLocation POI = SourceLocation())
- : MemberAndTSK(IF, TSK - 1), PointOfInstantiation(POI) {
- assert(TSK != TSK_Undeclared &&
- "Cannot encode undeclared template specializations for members");
- }
-
- /// \brief Retrieve the member declaration from which this member was
- /// instantiated.
- NamedDecl *getInstantiatedFrom() const { return MemberAndTSK.getPointer(); }
-
- /// \brief Determine what kind of template specialization this is.
- TemplateSpecializationKind getTemplateSpecializationKind() const {
- return (TemplateSpecializationKind)(MemberAndTSK.getInt() + 1);
- }
-
- bool isExplicitSpecialization() const {
- return getTemplateSpecializationKind() == TSK_ExplicitSpecialization;
- }
-
- /// \brief Set the template specialization kind.
- void setTemplateSpecializationKind(TemplateSpecializationKind TSK) {
- assert(TSK != TSK_Undeclared &&
- "Cannot encode undeclared template specializations for members");
- MemberAndTSK.setInt(TSK - 1);
- }
-
- /// \brief Retrieve the first point of instantiation of this member.
- /// If the point of instantiation is an invalid location, then this member
- /// has not yet been instantiated.
- SourceLocation getPointOfInstantiation() const {
- return PointOfInstantiation;
- }
-
- /// \brief Set the first point of instantiation.
- void setPointOfInstantiation(SourceLocation POI) {
- PointOfInstantiation = POI;
- }
-};
-
-/// \brief Provides information about a dependent function-template
-/// specialization declaration.
-///
-/// Since explicit function template specialization and instantiation
-/// declarations can only appear in namespace scope, and you can only
-/// specialize a member of a fully-specialized class, the only way to
-/// get one of these is in a friend declaration like the following:
-///
-/// \code
-/// template \<class T> void foo(T);
-/// template \<class T> class A {
-/// friend void foo<>(T);
-/// };
-/// \endcode
-class DependentFunctionTemplateSpecializationInfo final
- : private llvm::TrailingObjects<DependentFunctionTemplateSpecializationInfo,
- TemplateArgumentLoc,
- FunctionTemplateDecl *> {
- /// The number of potential template candidates.
- unsigned NumTemplates;
-
- /// The number of template arguments.
- unsigned NumArgs;
-
- /// The locations of the left and right angle brackets.
- SourceRange AngleLocs;
-
- size_t numTrailingObjects(OverloadToken<TemplateArgumentLoc>) const {
- return NumArgs;
- }
- size_t numTrailingObjects(OverloadToken<FunctionTemplateDecl *>) const {
- return NumTemplates;
- }
-
- DependentFunctionTemplateSpecializationInfo(
- const UnresolvedSetImpl &Templates,
- const TemplateArgumentListInfo &TemplateArgs);
-
-public:
- static DependentFunctionTemplateSpecializationInfo *
- Create(ASTContext &Context, const UnresolvedSetImpl &Templates,
- const TemplateArgumentListInfo &TemplateArgs);
-
- /// \brief Returns the number of function templates that this might
- /// be a specialization of.
- unsigned getNumTemplates() const { return NumTemplates; }
-
- /// \brief Returns the i'th template candidate.
- FunctionTemplateDecl *getTemplate(unsigned I) const {
- assert(I < getNumTemplates() && "template index out of range");
- return getTrailingObjects<FunctionTemplateDecl *>()[I];
- }
-
- /// \brief Returns the explicit template arguments that were given.
- const TemplateArgumentLoc *getTemplateArgs() const {
- return getTrailingObjects<TemplateArgumentLoc>();
- }
-
- /// \brief Returns the number of explicit template arguments that were given.
- unsigned getNumTemplateArgs() const { return NumArgs; }
-
- /// \brief Returns the nth template argument.
- const TemplateArgumentLoc &getTemplateArg(unsigned I) const {
- assert(I < getNumTemplateArgs() && "template arg index out of range");
- return getTemplateArgs()[I];
- }
-
- SourceLocation getLAngleLoc() const {
- return AngleLocs.getBegin();
- }
-
- SourceLocation getRAngleLoc() const {
- return AngleLocs.getEnd();
- }
-
- friend TrailingObjects;
-};
-
-/// Declaration of a redeclarable template.
-class RedeclarableTemplateDecl : public TemplateDecl,
- public Redeclarable<RedeclarableTemplateDecl>
-{
- typedef Redeclarable<RedeclarableTemplateDecl> redeclarable_base;
- RedeclarableTemplateDecl *getNextRedeclarationImpl() override {
- return getNextRedeclaration();
- }
- RedeclarableTemplateDecl *getPreviousDeclImpl() override {
- return getPreviousDecl();
- }
- RedeclarableTemplateDecl *getMostRecentDeclImpl() override {
- return getMostRecentDecl();
- }
-
-protected:
- template <typename EntryType> struct SpecEntryTraits {
- typedef EntryType DeclType;
-
- static DeclType *getDecl(EntryType *D) {
- return D;
- }
- static ArrayRef<TemplateArgument> getTemplateArgs(EntryType *D) {
- return D->getTemplateArgs().asArray();
- }
- };
-
- template <typename EntryType, typename SETraits = SpecEntryTraits<EntryType>,
- typename DeclType = typename SETraits::DeclType>
- struct SpecIterator
- : llvm::iterator_adaptor_base<
- SpecIterator<EntryType, SETraits, DeclType>,
- typename llvm::FoldingSetVector<EntryType>::iterator,
- typename std::iterator_traits<typename llvm::FoldingSetVector<
- EntryType>::iterator>::iterator_category,
- DeclType *, ptrdiff_t, DeclType *, DeclType *> {
- SpecIterator() {}
- explicit SpecIterator(
- typename llvm::FoldingSetVector<EntryType>::iterator SetIter)
- : SpecIterator::iterator_adaptor_base(std::move(SetIter)) {}
-
- DeclType *operator*() const {
- return SETraits::getDecl(&*this->I)->getMostRecentDecl();
- }
- DeclType *operator->() const { return **this; }
- };
-
- template <typename EntryType>
- static SpecIterator<EntryType>
- makeSpecIterator(llvm::FoldingSetVector<EntryType> &Specs, bool isEnd) {
- return SpecIterator<EntryType>(isEnd ? Specs.end() : Specs.begin());
- }
-
- template <class EntryType> typename SpecEntryTraits<EntryType>::DeclType*
- findSpecializationImpl(llvm::FoldingSetVector<EntryType> &Specs,
- ArrayRef<TemplateArgument> Args, void *&InsertPos);
-
- template <class Derived, class EntryType>
- void addSpecializationImpl(llvm::FoldingSetVector<EntryType> &Specs,
- EntryType *Entry, void *InsertPos);
-
- struct CommonBase {
- CommonBase() : InstantiatedFromMember(nullptr, false) { }
-
- /// \brief The template from which this was most
- /// directly instantiated (or null).
- ///
- /// The boolean value indicates whether this template
- /// was explicitly specialized.
- llvm::PointerIntPair<RedeclarableTemplateDecl*, 1, bool>
- InstantiatedFromMember;
- };
-
- /// \brief Pointer to the common data shared by all declarations of this
- /// template.
- mutable CommonBase *Common;
-
- /// \brief Retrieves the "common" pointer shared by all (re-)declarations of
- /// the same template. Calling this routine may implicitly allocate memory
- /// for the common pointer.
- CommonBase *getCommonPtr() const;
-
- virtual CommonBase *newCommon(ASTContext &C) const = 0;
-
- // Construct a template decl with name, parameters, and templated element.
- RedeclarableTemplateDecl(Kind DK, ASTContext &C, DeclContext *DC,
- SourceLocation L, DeclarationName Name,
- TemplateParameterList *Params, NamedDecl *Decl)
- : TemplateDecl(DK, DC, L, Name, Params, Decl), redeclarable_base(C),
- Common() {}
-
-public:
- template <class decl_type> friend class RedeclarableTemplate;
-
- /// \brief Retrieves the canonical declaration of this template.
- RedeclarableTemplateDecl *getCanonicalDecl() override {
- return getFirstDecl();
- }
- const RedeclarableTemplateDecl *getCanonicalDecl() const {
- return getFirstDecl();
- }
-
- /// \brief Determines whether this template was a specialization of a
- /// member template.
- ///
- /// In the following example, the function template \c X<int>::f and the
- /// member template \c X<int>::Inner are member specializations.
- ///
- /// \code
- /// template<typename T>
- /// struct X {
- /// template<typename U> void f(T, U);
- /// template<typename U> struct Inner;
- /// };
- ///
- /// template<> template<typename T>
- /// void X<int>::f(int, T);
- /// template<> template<typename T>
- /// struct X<int>::Inner { /* ... */ };
- /// \endcode
- bool isMemberSpecialization() const {
- return getCommonPtr()->InstantiatedFromMember.getInt();
- }
-
- /// \brief Note that this member template is a specialization.
- void setMemberSpecialization() {
- assert(getCommonPtr()->InstantiatedFromMember.getPointer() &&
- "Only member templates can be member template specializations");
- getCommonPtr()->InstantiatedFromMember.setInt(true);
- }
-
- /// \brief Retrieve the member template from which this template was
- /// instantiated, or NULL if this template was not instantiated from a
- /// member template.
- ///
- /// A template is instantiated from a member template when the member
- /// template itself is part of a class template (or member thereof). For
- /// example, given
- ///
- /// \code
- /// template<typename T>
- /// struct X {
- /// template<typename U> void f(T, U);
- /// };
- ///
- /// void test(X<int> x) {
- /// x.f(1, 'a');
- /// };
- /// \endcode
- ///
- /// \c X<int>::f is a FunctionTemplateDecl that describes the function
- /// template
- ///
- /// \code
- /// template<typename U> void X<int>::f(int, U);
- /// \endcode
- ///
- /// which was itself created during the instantiation of \c X<int>. Calling
- /// getInstantiatedFromMemberTemplate() on this FunctionTemplateDecl will
- /// retrieve the FunctionTemplateDecl for the original template \c f within
- /// the class template \c X<T>, i.e.,
- ///
- /// \code
- /// template<typename T>
- /// template<typename U>
- /// void X<T>::f(T, U);
- /// \endcode
- RedeclarableTemplateDecl *getInstantiatedFromMemberTemplate() const {
- return getCommonPtr()->InstantiatedFromMember.getPointer();
- }
-
- void setInstantiatedFromMemberTemplate(RedeclarableTemplateDecl *TD) {
- assert(!getCommonPtr()->InstantiatedFromMember.getPointer());
- getCommonPtr()->InstantiatedFromMember.setPointer(TD);
- }
-
- typedef redeclarable_base::redecl_range redecl_range;
- typedef redeclarable_base::redecl_iterator redecl_iterator;
- using redeclarable_base::redecls_begin;
- using redeclarable_base::redecls_end;
- using redeclarable_base::redecls;
- using redeclarable_base::getPreviousDecl;
- using redeclarable_base::getMostRecentDecl;
- using redeclarable_base::isFirstDecl;
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) {
- return K >= firstRedeclarableTemplate && K <= lastRedeclarableTemplate;
- }
-
- friend class ASTReader;
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-};
-
-template <> struct RedeclarableTemplateDecl::
-SpecEntryTraits<FunctionTemplateSpecializationInfo> {
- typedef FunctionDecl DeclType;
-
- static DeclType *getDecl(FunctionTemplateSpecializationInfo *I) {
- return I->Function;
- }
- static ArrayRef<TemplateArgument>
- getTemplateArgs(FunctionTemplateSpecializationInfo *I) {
- return I->TemplateArguments->asArray();
- }
-};
-
-/// Declaration of a template function.
-class FunctionTemplateDecl : public RedeclarableTemplateDecl {
- static void DeallocateCommon(void *Ptr);
-
-protected:
- /// \brief Data that is common to all of the declarations of a given
- /// function template.
- struct Common : CommonBase {
- Common() : InjectedArgs(), LazySpecializations() { }
-
- /// \brief The function template specializations for this function
- /// template, including explicit specializations and instantiations.
- llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> Specializations;
-
- /// \brief 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;
-
- /// \brief If non-null, points to an array of specializations known only
- /// by their external declaration IDs.
- ///
- /// The first value in the array is the number of of specializations
- /// that follow.
- uint32_t *LazySpecializations;
- };
-
- FunctionTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L,
- DeclarationName Name, TemplateParameterList *Params,
- NamedDecl *Decl)
- : RedeclarableTemplateDecl(FunctionTemplate, C, DC, L, Name, Params,
- Decl) {}
-
- CommonBase *newCommon(ASTContext &C) const override;
-
- Common *getCommonPtr() const {
- return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
- }
-
- friend class FunctionDecl;
-
- /// \brief Retrieve the set of function template specializations of this
- /// function template.
- llvm::FoldingSetVector<FunctionTemplateSpecializationInfo> &
- getSpecializations() const;
-
- /// \brief Add a specialization of this function template.
- ///
- /// \param InsertPos Insert position in the FoldingSetVector, must have been
- /// retrieved by an earlier call to findSpecialization().
- void addSpecialization(FunctionTemplateSpecializationInfo* Info,
- void *InsertPos);
-
-public:
- /// \brief Load any lazily-loaded specializations from the external source.
- void LoadLazySpecializations() const;
-
- /// Get the underlying function declaration of the template.
- FunctionDecl *getTemplatedDecl() const {
- return static_cast<FunctionDecl*>(TemplatedDecl);
- }
-
- /// Returns whether this template declaration defines the primary
- /// pattern.
- bool isThisDeclarationADefinition() const {
- return getTemplatedDecl()->isThisDeclarationADefinition();
- }
-
- /// \brief Return the specialization with the provided arguments if it exists,
- /// otherwise return the insertion point.
- FunctionDecl *findSpecialization(ArrayRef<TemplateArgument> Args,
- void *&InsertPos);
-
- FunctionTemplateDecl *getCanonicalDecl() override {
- return cast<FunctionTemplateDecl>(
- RedeclarableTemplateDecl::getCanonicalDecl());
- }
- const FunctionTemplateDecl *getCanonicalDecl() const {
- return cast<FunctionTemplateDecl>(
- RedeclarableTemplateDecl::getCanonicalDecl());
- }
-
- /// \brief Retrieve the previous declaration of this function template, or
- /// NULL if no such declaration exists.
- FunctionTemplateDecl *getPreviousDecl() {
- return cast_or_null<FunctionTemplateDecl>(
- static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
- }
-
- /// \brief Retrieve the previous declaration of this function template, or
- /// NULL if no such declaration exists.
- const FunctionTemplateDecl *getPreviousDecl() const {
- return cast_or_null<FunctionTemplateDecl>(
- static_cast<const RedeclarableTemplateDecl *>(this)->getPreviousDecl());
- }
-
- FunctionTemplateDecl *getMostRecentDecl() {
- return cast<FunctionTemplateDecl>(
- static_cast<RedeclarableTemplateDecl *>(this)
- ->getMostRecentDecl());
- }
- const FunctionTemplateDecl *getMostRecentDecl() const {
- return const_cast<FunctionTemplateDecl*>(this)->getMostRecentDecl();
- }
-
- FunctionTemplateDecl *getInstantiatedFromMemberTemplate() const {
- return cast_or_null<FunctionTemplateDecl>(
- RedeclarableTemplateDecl::getInstantiatedFromMemberTemplate());
- }
-
- typedef SpecIterator<FunctionTemplateSpecializationInfo> spec_iterator;
- typedef llvm::iterator_range<spec_iterator> spec_range;
-
- spec_range specializations() const {
- return spec_range(spec_begin(), spec_end());
- }
- spec_iterator spec_begin() const {
- return makeSpecIterator(getSpecializations(), false);
- }
-
- spec_iterator spec_end() const {
- return makeSpecIterator(getSpecializations(), true);
- }
-
- /// \brief 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();
-
- /// \brief Create a function template node.
- static FunctionTemplateDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation L,
- DeclarationName Name,
- TemplateParameterList *Params,
- NamedDecl *Decl);
-
- /// \brief Create an empty function template node.
- static FunctionTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- // Implement isa/cast/dyncast support
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == FunctionTemplate; }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-};
-
-//===----------------------------------------------------------------------===//
-// Kinds of Template Parameters
-//===----------------------------------------------------------------------===//
-
-/// \brief 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 {
- TemplateParmPosition() = delete;
-
-protected:
- TemplateParmPosition(unsigned D, unsigned P)
- : Depth(D), Position(P)
- { }
-
- // FIXME: These probably don't need to be ints. int:5 for depth, int:8 for
- // position? Maybe?
- unsigned Depth;
- unsigned Position;
-
-public:
- /// Get the nesting depth of the template parameter.
- unsigned getDepth() const { return Depth; }
- void setDepth(unsigned D) { Depth = D; }
-
- /// Get the position of the template parameter within its parameter list.
- unsigned getPosition() const { return Position; }
- void setPosition(unsigned P) { Position = P; }
-
- /// Get the index of the template parameter within its parameter list.
- unsigned getIndex() const { return Position; }
-};
-
-/// \brief Declaration of a template type parameter.
-///
-/// For example, "T" in
-/// \code
-/// template<typename T> class vector;
-/// \endcode
-class TemplateTypeParmDecl : public TypeDecl {
- /// \brief Whether this template type parameter was declaration with
- /// the 'typename' keyword.
- ///
- /// If false, it was declared with the 'class' keyword.
- bool Typename : 1;
-
- /// \brief The default template argument, if any.
- typedef DefaultArgStorage<TemplateTypeParmDecl, TypeSourceInfo *>
- DefArgStorage;
- DefArgStorage DefaultArgument;
-
- TemplateTypeParmDecl(DeclContext *DC, SourceLocation KeyLoc,
- SourceLocation IdLoc, IdentifierInfo *Id,
- bool Typename)
- : TypeDecl(TemplateTypeParm, DC, IdLoc, Id, KeyLoc), Typename(Typename),
- DefaultArgument() { }
-
- /// Sema creates these on the stack during auto type deduction.
- friend class Sema;
-
-public:
- static TemplateTypeParmDecl *Create(const ASTContext &C, DeclContext *DC,
- SourceLocation KeyLoc,
- SourceLocation NameLoc,
- unsigned D, unsigned P,
- IdentifierInfo *Id, bool Typename,
- bool ParameterPack);
- static TemplateTypeParmDecl *CreateDeserialized(const ASTContext &C,
- unsigned ID);
-
- /// \brief Whether this template type parameter was declared with
- /// the 'typename' keyword.
- ///
- /// If not, it was declared with the 'class' keyword.
- bool wasDeclaredWithTypename() const { return Typename; }
-
- const DefArgStorage &getDefaultArgStorage() const { return DefaultArgument; }
-
- /// \brief Determine whether this template parameter has a default
- /// argument.
- bool hasDefaultArgument() const { return DefaultArgument.isSet(); }
-
- /// \brief Retrieve the default argument, if any.
- QualType getDefaultArgument() const {
- return DefaultArgument.get()->getType();
- }
-
- /// \brief Retrieves the default argument's source information, if any.
- TypeSourceInfo *getDefaultArgumentInfo() const {
- return DefaultArgument.get();
- }
-
- /// \brief Retrieves the location of the default argument declaration.
- SourceLocation getDefaultArgumentLoc() const;
-
- /// \brief Determines whether the default argument was inherited
- /// from a previous declaration of this template.
- bool defaultArgumentWasInherited() const {
- return DefaultArgument.isInherited();
- }
-
- /// \brief Set the default argument for this template parameter.
- void setDefaultArgument(TypeSourceInfo *DefArg) {
- DefaultArgument.set(DefArg);
- }
- /// \brief Set that this default argument was inherited from another
- /// parameter.
- void setInheritedDefaultArgument(const ASTContext &C,
- TemplateTypeParmDecl *Prev) {
- DefaultArgument.setInherited(C, Prev);
- }
-
- /// \brief Removes the default argument of this template parameter.
- void removeDefaultArgument() {
- DefaultArgument.clear();
- }
-
- /// \brief Set whether this template type parameter was declared with
- /// the 'typename' or 'class' keyword.
- void setDeclaredWithTypename(bool withTypename) { Typename = withTypename; }
-
- /// \brief Retrieve the depth of the template parameter.
- unsigned getDepth() const;
-
- /// \brief Retrieve the index of the template parameter.
- unsigned getIndex() const;
-
- /// \brief Returns whether this is a parameter pack.
- bool isParameterPack() const;
-
- SourceRange getSourceRange() const override LLVM_READONLY;
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == TemplateTypeParm; }
-};
-
-/// 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 *>> {
- /// \brief The default template argument, if any, and whether or not
- /// it was inherited.
- typedef DefaultArgStorage<NonTypeTemplateParmDecl, Expr*> DefArgStorage;
- DefArgStorage DefaultArgument;
-
- // FIXME: Collapse this into TemplateParamPosition; or, just move depth/index
- // down here to save memory.
-
- /// \brief Whether this non-type template parameter is a parameter pack.
- bool ParameterPack;
-
- /// \brief Whether this non-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;
-
- /// \brief The number of types in an expanded parameter pack.
- unsigned NumExpandedTypes;
-
- size_t numTrailingObjects(
- OverloadToken<std::pair<QualType, TypeSourceInfo *>>) const {
- return NumExpandedTypes;
- }
-
- NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation StartLoc,
- SourceLocation IdLoc, unsigned D, unsigned P,
- IdentifierInfo *Id, QualType T,
- bool ParameterPack, TypeSourceInfo *TInfo)
- : DeclaratorDecl(NonTypeTemplateParm, DC, IdLoc, Id, T, TInfo, StartLoc),
- TemplateParmPosition(D, P), ParameterPack(ParameterPack),
- ExpandedParameterPack(false), NumExpandedTypes(0)
- { }
-
- NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation StartLoc,
- SourceLocation IdLoc, unsigned D, unsigned P,
- IdentifierInfo *Id, QualType T,
- TypeSourceInfo *TInfo,
- const QualType *ExpandedTypes,
- unsigned NumExpandedTypes,
- TypeSourceInfo **ExpandedTInfos);
-
- friend class ASTDeclReader;
- friend TrailingObjects;
-
-public:
- static NonTypeTemplateParmDecl *
- Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
- SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id,
- QualType T, bool ParameterPack, TypeSourceInfo *TInfo);
-
- static NonTypeTemplateParmDecl *
- Create(const ASTContext &C, DeclContext *DC, SourceLocation StartLoc,
- SourceLocation IdLoc, unsigned D, unsigned P, IdentifierInfo *Id,
- QualType T, TypeSourceInfo *TInfo,
- const QualType *ExpandedTypes, unsigned NumExpandedTypes,
- TypeSourceInfo **ExpandedTInfos);
-
- static NonTypeTemplateParmDecl *CreateDeserialized(ASTContext &C,
- unsigned ID);
- static NonTypeTemplateParmDecl *CreateDeserialized(ASTContext &C,
- unsigned ID,
- unsigned NumExpandedTypes);
-
- using TemplateParmPosition::getDepth;
- using TemplateParmPosition::setDepth;
- using TemplateParmPosition::getPosition;
- using TemplateParmPosition::setPosition;
- using TemplateParmPosition::getIndex;
-
- SourceRange getSourceRange() const override LLVM_READONLY;
-
- const DefArgStorage &getDefaultArgStorage() const { return DefaultArgument; }
-
- /// \brief Determine whether this template parameter has a default
- /// argument.
- bool hasDefaultArgument() const { return DefaultArgument.isSet(); }
-
- /// \brief Retrieve the default argument, if any.
- Expr *getDefaultArgument() const { return DefaultArgument.get(); }
-
- /// \brief Retrieve the location of the default argument, if any.
- SourceLocation getDefaultArgumentLoc() const;
-
- /// \brief Determines whether the default argument was inherited
- /// from a previous declaration of this template.
- bool defaultArgumentWasInherited() const {
- return DefaultArgument.isInherited();
- }
-
- /// \brief Set the default argument for this template parameter, and
- /// whether that default argument was inherited from another
- /// declaration.
- void setDefaultArgument(Expr *DefArg) { DefaultArgument.set(DefArg); }
- void setInheritedDefaultArgument(const ASTContext &C,
- NonTypeTemplateParmDecl *Parm) {
- DefaultArgument.setInherited(C, Parm);
- }
-
- /// \brief Removes the default argument of this template parameter.
- void removeDefaultArgument() { DefaultArgument.clear(); }
-
- /// \brief Whether this parameter is a non-type template parameter pack.
- ///
- /// If the parameter is a parameter pack, the type may be a
- /// \c PackExpansionType. In the following example, the \c Dims parameter
- /// is a parameter pack (whose type is 'unsigned').
- ///
- /// \code
- /// template<typename T, unsigned ...Dims> struct multi_array;
- /// \endcode
- bool isParameterPack() const { return ParameterPack; }
-
- /// \brief Whether this parameter pack is a pack expansion.
- ///
- /// A non-type template parameter pack is a pack expansion if its type
- /// contains an unexpanded parameter pack. In this case, we will have
- /// built a PackExpansionType wrapping the type.
- bool isPackExpansion() const {
- return ParameterPack && getType()->getAs<PackExpansionType>();
- }
-
- /// \brief Whether this parameter is a non-type template parameter pack
- /// that has a known list of different types at different positions.
- ///
- /// A parameter pack is an expanded parameter pack when the original
- /// parameter pack's type was itself a pack expansion, and that expansion
- /// has already been expanded. For example, given:
- ///
- /// \code
- /// template<typename ...Types>
- /// struct X {
- /// template<Types ...Values>
- /// struct Y { /* ... */ };
- /// };
- /// \endcode
- ///
- /// The parameter pack \c Values has a \c PackExpansionType as its type,
- /// which expands \c Types. When \c Types is supplied with template arguments
- /// by instantiating \c X, the instantiation of \c Values becomes an
- /// expanded parameter pack. For example, instantiating
- /// \c X<int, unsigned int> results in \c Values being an expanded parameter
- /// pack with expansion types \c int and \c unsigned int.
- ///
- /// The \c getExpansionType() and \c getExpansionTypeSourceInfo() functions
- /// return the expansion types.
- bool isExpandedParameterPack() const { return ExpandedParameterPack; }
-
- /// \brief Retrieves the number of expansion types in an expanded parameter
- /// pack.
- unsigned getNumExpansionTypes() const {
- assert(ExpandedParameterPack && "Not an expansion parameter pack");
- return NumExpandedTypes;
- }
-
- /// \brief Retrieve a particular expansion type within an expanded parameter
- /// pack.
- QualType getExpansionType(unsigned I) const {
- assert(I < NumExpandedTypes && "Out-of-range expansion type index");
- auto TypesAndInfos =
- getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
- return TypesAndInfos[I].first;
- }
-
- /// \brief Retrieve a particular expansion type source info within an
- /// expanded parameter pack.
- TypeSourceInfo *getExpansionTypeSourceInfo(unsigned I) const {
- assert(I < NumExpandedTypes && "Out-of-range expansion type index");
- auto TypesAndInfos =
- getTrailingObjects<std::pair<QualType, TypeSourceInfo *>>();
- return TypesAndInfos[I].second;
- }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == NonTypeTemplateParm; }
-};
-
-/// 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 *> {
- void anchor() override;
-
- /// \brief The default template argument, if any.
- typedef DefaultArgStorage<TemplateTemplateParmDecl, TemplateArgumentLoc *>
- DefArgStorage;
- DefArgStorage DefaultArgument;
-
- /// \brief Whether this parameter is a parameter pack.
- bool ParameterPack;
-
- /// \brief Whether this template template parameter is an "expanded"
- /// parameter pack, meaning that it is a pack expansion and we
- /// already know the set of template parameters that expansion expands to.
- bool ExpandedParameterPack;
-
- /// \brief The number of parameters in an expanded parameter pack.
- unsigned NumExpandedParams;
-
- TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L,
- unsigned D, unsigned P, bool ParameterPack,
- IdentifierInfo *Id, TemplateParameterList *Params)
- : TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
- TemplateParmPosition(D, P), ParameterPack(ParameterPack),
- ExpandedParameterPack(false), NumExpandedParams(0)
- { }
-
- TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L,
- unsigned D, unsigned P,
- IdentifierInfo *Id, TemplateParameterList *Params,
- unsigned NumExpansions,
- TemplateParameterList * const *Expansions);
-
-public:
- static TemplateTemplateParmDecl *Create(const ASTContext &C, DeclContext *DC,
- SourceLocation L, unsigned D,
- unsigned P, bool ParameterPack,
- IdentifierInfo *Id,
- TemplateParameterList *Params);
- static TemplateTemplateParmDecl *Create(const ASTContext &C, DeclContext *DC,
- SourceLocation L, unsigned D,
- unsigned P,
- IdentifierInfo *Id,
- TemplateParameterList *Params,
- ArrayRef<TemplateParameterList *> Expansions);
-
- static TemplateTemplateParmDecl *CreateDeserialized(ASTContext &C,
- unsigned ID);
- static TemplateTemplateParmDecl *CreateDeserialized(ASTContext &C,
- unsigned ID,
- unsigned NumExpansions);
-
- using TemplateParmPosition::getDepth;
- using TemplateParmPosition::getPosition;
- using TemplateParmPosition::getIndex;
-
- /// \brief Whether this template template parameter is a template
- /// parameter pack.
- ///
- /// \code
- /// template<template <class T> ...MetaFunctions> struct Apply;
- /// \endcode
- bool isParameterPack() const { return ParameterPack; }
-
- /// \brief Whether this parameter pack is a pack expansion.
- ///
- /// A template template parameter pack is a pack expansion if its template
- /// parameter list contains an unexpanded parameter pack.
- bool isPackExpansion() const {
- return ParameterPack &&
- getTemplateParameters()->containsUnexpandedParameterPack();
- }
-
- /// \brief Whether this parameter is a template template parameter pack that
- /// has a known list of different template parameter lists at different
- /// positions.
- ///
- /// A parameter pack is an expanded parameter pack when the original parameter
- /// pack's template parameter list was itself a pack expansion, and that
- /// expansion has already been expanded. For exampe, given:
- ///
- /// \code
- /// template<typename...Types> struct Outer {
- /// template<template<Types> class...Templates> struct Inner;
- /// };
- /// \endcode
- ///
- /// The parameter pack \c Templates is a pack expansion, which expands the
- /// pack \c Types. When \c Types is supplied with template arguments by
- /// instantiating \c Outer, the instantiation of \c Templates is an expanded
- /// parameter pack.
- bool isExpandedParameterPack() const { return ExpandedParameterPack; }
-
- /// \brief Retrieves the number of expansion template parameters in
- /// an expanded parameter pack.
- unsigned getNumExpansionTemplateParameters() const {
- assert(ExpandedParameterPack && "Not an expansion parameter pack");
- return NumExpandedParams;
- }
-
- /// \brief Retrieve a particular expansion type within an expanded parameter
- /// pack.
- TemplateParameterList *getExpansionTemplateParameters(unsigned I) const {
- assert(I < NumExpandedParams && "Out-of-range expansion type index");
- return getTrailingObjects<TemplateParameterList *>()[I];
- }
-
- const DefArgStorage &getDefaultArgStorage() const { return DefaultArgument; }
-
- /// \brief Determine whether this template parameter has a default
- /// argument.
- bool hasDefaultArgument() const { return DefaultArgument.isSet(); }
-
- /// \brief Retrieve the default argument, if any.
- const TemplateArgumentLoc &getDefaultArgument() const {
- static const TemplateArgumentLoc None;
- return DefaultArgument.isSet() ? *DefaultArgument.get() : None;
- }
-
- /// \brief Retrieve the location of the default argument, if any.
- SourceLocation getDefaultArgumentLoc() const;
-
- /// \brief Determines whether the default argument was inherited
- /// from a previous declaration of this template.
- bool defaultArgumentWasInherited() const {
- return DefaultArgument.isInherited();
- }
-
- /// \brief Set the default argument for this template parameter, and
- /// whether that default argument was inherited from another
- /// declaration.
- void setDefaultArgument(const ASTContext &C,
- const TemplateArgumentLoc &DefArg);
- void setInheritedDefaultArgument(const ASTContext &C,
- TemplateTemplateParmDecl *Prev) {
- DefaultArgument.setInherited(C, Prev);
- }
-
- /// \brief Removes the default argument of this template parameter.
- void removeDefaultArgument() { DefaultArgument.clear(); }
-
- SourceRange getSourceRange() const override LLVM_READONLY {
- SourceLocation End = getLocation();
- if (hasDefaultArgument() && !defaultArgumentWasInherited())
- End = getDefaultArgument().getSourceRange().getEnd();
- return SourceRange(getTemplateParameters()->getTemplateLoc(), End);
- }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == TemplateTemplateParm; }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
- friend TrailingObjects;
-};
-
-/// \brief Represents the builtin template declaration which is used to
-/// implement __make_integer_seq. It serves no real purpose beyond existing as
-/// a place to hold template parameters.
-class BuiltinTemplateDecl : public TemplateDecl {
- void anchor() override;
-
- BuiltinTemplateDecl(const ASTContext &C, DeclContext *DC,
- DeclarationName Name, BuiltinTemplateKind BTK);
-
- BuiltinTemplateKind BTK;
-
-public:
- // Implement isa/cast/dyncast support
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == BuiltinTemplate; }
-
- static BuiltinTemplateDecl *Create(const ASTContext &C, DeclContext *DC,
- DeclarationName Name,
- BuiltinTemplateKind BTK) {
- return new (C, DC) BuiltinTemplateDecl(C, DC, Name, BTK);
- }
-
- SourceRange getSourceRange() const override LLVM_READONLY {
- return SourceRange();
- }
-
- BuiltinTemplateKind getBuiltinTemplateKind() const { return BTK; }
-};
-
-/// \brief 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 {
-
- /// \brief Structure that stores information about a class template
- /// specialization that was instantiated from a class template partial
- /// specialization.
- struct SpecializedPartialSpecialization {
- /// \brief The class template partial specialization from which this
- /// class template specialization was instantiated.
- ClassTemplatePartialSpecializationDecl *PartialSpecialization;
-
- /// \brief The template argument list deduced for the class template
- /// partial specialization itself.
- const TemplateArgumentList *TemplateArgs;
- };
-
- /// \brief The template that this specialization specializes
- llvm::PointerUnion<ClassTemplateDecl *, SpecializedPartialSpecialization *>
- SpecializedTemplate;
-
- /// \brief Further info for explicit template specialization/instantiation.
- struct ExplicitSpecializationInfo {
- /// \brief The type-as-written.
- TypeSourceInfo *TypeAsWritten;
- /// \brief The location of the extern keyword.
- SourceLocation ExternLoc;
- /// \brief The location of the template keyword.
- SourceLocation TemplateKeywordLoc;
-
- ExplicitSpecializationInfo()
- : TypeAsWritten(nullptr), ExternLoc(), TemplateKeywordLoc() {}
- };
-
- /// \brief Further info for explicit template specialization/instantiation.
- /// Does not apply to implicit specializations.
- ExplicitSpecializationInfo *ExplicitInfo;
-
- /// \brief The template arguments used to describe this specialization.
- const TemplateArgumentList *TemplateArgs;
-
- /// \brief The point where this template was instantiated (if any)
- SourceLocation PointOfInstantiation;
-
- /// \brief The kind of specialization this declaration refers to.
- /// Really a value of type TemplateSpecializationKind.
- unsigned SpecializationKind : 3;
-
-protected:
- ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
- DeclContext *DC, SourceLocation StartLoc,
- SourceLocation IdLoc,
- ClassTemplateDecl *SpecializedTemplate,
- const TemplateArgument *Args,
- unsigned NumArgs,
- ClassTemplateSpecializationDecl *PrevDecl);
-
- explicit ClassTemplateSpecializationDecl(ASTContext &C, Kind DK);
-
-public:
- static ClassTemplateSpecializationDecl *
- Create(ASTContext &Context, TagKind TK, DeclContext *DC,
- SourceLocation StartLoc, SourceLocation IdLoc,
- ClassTemplateDecl *SpecializedTemplate,
- const TemplateArgument *Args,
- unsigned NumArgs,
- ClassTemplateSpecializationDecl *PrevDecl);
- static ClassTemplateSpecializationDecl *
- CreateDeserialized(ASTContext &C, unsigned ID);
-
- void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy,
- bool Qualified) const override;
-
- // FIXME: This is broken. CXXRecordDecl::getMostRecentDecl() returns a
- // different "most recent" declaration from this function for the same
- // declaration, because we don't override getMostRecentDeclImpl(). But
- // it's not clear that we should override that, because the most recent
- // declaration as a CXXRecordDecl sometimes is the injected-class-name.
- ClassTemplateSpecializationDecl *getMostRecentDecl() {
- CXXRecordDecl *Recent = static_cast<CXXRecordDecl *>(
- this)->getMostRecentDecl();
- while (!isa<ClassTemplateSpecializationDecl>(Recent)) {
- // FIXME: Does injected class name need to be in the redeclarations chain?
- assert(Recent->isInjectedClassName() && Recent->getPreviousDecl());
- Recent = Recent->getPreviousDecl();
- }
- return cast<ClassTemplateSpecializationDecl>(Recent);
- }
-
- /// \brief Retrieve the template that this specialization specializes.
- ClassTemplateDecl *getSpecializedTemplate() const;
-
- /// \brief Retrieve the template arguments of the class template
- /// specialization.
- const TemplateArgumentList &getTemplateArgs() const {
- return *TemplateArgs;
- }
-
- /// \brief Determine the kind of specialization that this
- /// declaration represents.
- TemplateSpecializationKind getSpecializationKind() const {
- return static_cast<TemplateSpecializationKind>(SpecializationKind);
- }
-
- bool isExplicitSpecialization() const {
- return getSpecializationKind() == TSK_ExplicitSpecialization;
- }
-
- /// \brief True if this declaration is an explicit specialization,
- /// explicit instantiation declaration, or explicit instantiation
- /// definition.
- bool isExplicitInstantiationOrSpecialization() const {
- return isTemplateExplicitInstantiationOrSpecialization(
- getTemplateSpecializationKind());
- }
-
- void setSpecializationKind(TemplateSpecializationKind TSK) {
- SpecializationKind = TSK;
- }
-
- /// \brief Get the point of instantiation (if any), or null if none.
- SourceLocation getPointOfInstantiation() const {
- return PointOfInstantiation;
- }
-
- void setPointOfInstantiation(SourceLocation Loc) {
- assert(Loc.isValid() && "point of instantiation must be valid!");
- PointOfInstantiation = Loc;
- }
-
- /// \brief If this class template specialization is an instantiation of
- /// a template (rather than an explicit specialization), return the
- /// class template or class template partial specialization from which it
- /// was instantiated.
- llvm::PointerUnion<ClassTemplateDecl *,
- ClassTemplatePartialSpecializationDecl *>
- getInstantiatedFrom() const {
- if (!isTemplateInstantiation(getSpecializationKind()))
- return llvm::PointerUnion<ClassTemplateDecl *,
- ClassTemplatePartialSpecializationDecl *>();
-
- return getSpecializedTemplateOrPartial();
- }
-
- /// \brief Retrieve the class template or class template partial
- /// specialization which was specialized by this.
- llvm::PointerUnion<ClassTemplateDecl *,
- ClassTemplatePartialSpecializationDecl *>
- getSpecializedTemplateOrPartial() const {
- if (SpecializedPartialSpecialization *PartialSpec
- = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
- return PartialSpec->PartialSpecialization;
-
- return SpecializedTemplate.get<ClassTemplateDecl*>();
- }
-
- /// \brief Retrieve the set of template arguments that should be used
- /// to instantiate members of the class template or class template partial
- /// specialization from which this class template specialization was
- /// instantiated.
- ///
- /// \returns For a class template specialization instantiated from the primary
- /// template, this function will return the same template arguments as
- /// getTemplateArgs(). For a class template specialization instantiated from
- /// a class template partial specialization, this function will return the
- /// deduced template arguments for the class template partial specialization
- /// itself.
- const TemplateArgumentList &getTemplateInstantiationArgs() const {
- if (SpecializedPartialSpecialization *PartialSpec
- = SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization*>())
- return *PartialSpec->TemplateArgs;
-
- return getTemplateArgs();
- }
-
- /// \brief Note that this class template specialization is actually an
- /// instantiation of the given class template partial specialization whose
- /// template arguments have been deduced.
- void setInstantiationOf(ClassTemplatePartialSpecializationDecl *PartialSpec,
- const TemplateArgumentList *TemplateArgs) {
- assert(!SpecializedTemplate.is<SpecializedPartialSpecialization*>() &&
- "Already set to a class template partial specialization!");
- SpecializedPartialSpecialization *PS
- = new (getASTContext()) SpecializedPartialSpecialization();
- PS->PartialSpecialization = PartialSpec;
- PS->TemplateArgs = TemplateArgs;
- SpecializedTemplate = PS;
- }
-
- /// \brief Note that this class template specialization is an instantiation
- /// of the given class template.
- void setInstantiationOf(ClassTemplateDecl *TemplDecl) {
- assert(!SpecializedTemplate.is<SpecializedPartialSpecialization*>() &&
- "Previously set to a class template partial specialization!");
- SpecializedTemplate = TemplDecl;
- }
-
- /// \brief Sets the type of this specialization as it was written by
- /// the user. This will be a class template specialization type.
- void setTypeAsWritten(TypeSourceInfo *T) {
- if (!ExplicitInfo)
- ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
- ExplicitInfo->TypeAsWritten = T;
- }
- /// \brief Gets the type of this specialization as it was written by
- /// the user, if it was so written.
- TypeSourceInfo *getTypeAsWritten() const {
- return ExplicitInfo ? ExplicitInfo->TypeAsWritten : nullptr;
- }
-
- /// \brief Gets the location of the extern keyword, if present.
- SourceLocation getExternLoc() const {
- return ExplicitInfo ? ExplicitInfo->ExternLoc : SourceLocation();
- }
- /// \brief Sets the location of the extern keyword.
- void setExternLoc(SourceLocation Loc) {
- if (!ExplicitInfo)
- ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
- ExplicitInfo->ExternLoc = Loc;
- }
-
- /// \brief Sets the location of the template keyword.
- void setTemplateKeywordLoc(SourceLocation Loc) {
- if (!ExplicitInfo)
- ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
- ExplicitInfo->TemplateKeywordLoc = Loc;
- }
- /// \brief Gets the location of the template keyword, if present.
- SourceLocation getTemplateKeywordLoc() const {
- 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) {
- ID.AddInteger(TemplateArgs.size());
- for (unsigned Arg = 0; Arg != TemplateArgs.size(); ++Arg)
- TemplateArgs[Arg].Profile(ID, Context);
- }
-
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) {
- return K >= firstClassTemplateSpecialization &&
- K <= lastClassTemplateSpecialization;
- }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-};
-
-class ClassTemplatePartialSpecializationDecl
- : public ClassTemplateSpecializationDecl {
- void anchor() override;
-
- /// \brief The list of template parameters
- TemplateParameterList* TemplateParams;
-
- /// \brief The source info for the template arguments as written.
- /// FIXME: redundant with TypeAsWritten?
- const ASTTemplateArgumentListInfo *ArgsAsWritten;
-
- /// \brief The class template partial specialization from which this
- /// class template partial specialization was instantiated.
- ///
- /// The boolean value will be true to indicate that this class template
- /// partial specialization was specialized at this level.
- llvm::PointerIntPair<ClassTemplatePartialSpecializationDecl *, 1, bool>
- InstantiatedFromMember;
-
- ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
- DeclContext *DC,
- SourceLocation StartLoc,
- SourceLocation IdLoc,
- TemplateParameterList *Params,
- ClassTemplateDecl *SpecializedTemplate,
- const TemplateArgument *Args,
- unsigned NumArgs,
- const ASTTemplateArgumentListInfo *ArgsAsWritten,
- ClassTemplatePartialSpecializationDecl *PrevDecl);
-
- ClassTemplatePartialSpecializationDecl(ASTContext &C)
- : ClassTemplateSpecializationDecl(C, ClassTemplatePartialSpecialization),
- TemplateParams(nullptr), ArgsAsWritten(nullptr),
- InstantiatedFromMember(nullptr, false) {}
-
-public:
- static ClassTemplatePartialSpecializationDecl *
- Create(ASTContext &Context, TagKind TK, DeclContext *DC,
- SourceLocation StartLoc, SourceLocation IdLoc,
- TemplateParameterList *Params,
- ClassTemplateDecl *SpecializedTemplate,
- const TemplateArgument *Args,
- unsigned NumArgs,
- const TemplateArgumentListInfo &ArgInfos,
- QualType CanonInjectedType,
- ClassTemplatePartialSpecializationDecl *PrevDecl);
-
- static ClassTemplatePartialSpecializationDecl *
- CreateDeserialized(ASTContext &C, unsigned ID);
-
- ClassTemplatePartialSpecializationDecl *getMostRecentDecl() {
- return cast<ClassTemplatePartialSpecializationDecl>(
- static_cast<ClassTemplateSpecializationDecl *>(
- this)->getMostRecentDecl());
- }
-
- /// Get the list of template parameters
- TemplateParameterList *getTemplateParameters() const {
- return TemplateParams;
- }
-
- /// Get the template arguments as written.
- const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten() const {
- return ArgsAsWritten;
- }
-
- /// \brief Retrieve the member class template partial specialization from
- /// which this particular class template partial specialization was
- /// instantiated.
- ///
- /// \code
- /// template<typename T>
- /// struct Outer {
- /// template<typename U> struct Inner;
- /// template<typename U> struct Inner<U*> { }; // #1
- /// };
- ///
- /// Outer<float>::Inner<int*> ii;
- /// \endcode
- ///
- /// In this example, the instantiation of \c Outer<float>::Inner<int*> will
- /// end up instantiating the partial specialization
- /// \c Outer<float>::Inner<U*>, which itself was instantiated from the class
- /// template partial specialization \c Outer<T>::Inner<U*>. Given
- /// \c Outer<float>::Inner<U*>, this function would return
- /// \c Outer<T>::Inner<U*>.
- ClassTemplatePartialSpecializationDecl *getInstantiatedFromMember() const {
- const ClassTemplatePartialSpecializationDecl *First =
- cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl());
- return First->InstantiatedFromMember.getPointer();
- }
-
- void setInstantiatedFromMember(
- ClassTemplatePartialSpecializationDecl *PartialSpec) {
- ClassTemplatePartialSpecializationDecl *First =
- cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl());
- First->InstantiatedFromMember.setPointer(PartialSpec);
- }
-
- /// \brief Determines whether this class template partial specialization
- /// template was a specialization of a member partial specialization.
- ///
- /// In the following example, the member template partial specialization
- /// \c X<int>::Inner<T*> is a member specialization.
- ///
- /// \code
- /// template<typename T>
- /// struct X {
- /// template<typename U> struct Inner;
- /// template<typename U> struct Inner<U*>;
- /// };
- ///
- /// template<> template<typename T>
- /// struct X<int>::Inner<T*> { /* ... */ };
- /// \endcode
- bool isMemberSpecialization() {
- ClassTemplatePartialSpecializationDecl *First =
- cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl());
- return First->InstantiatedFromMember.getInt();
- }
-
- /// \brief Note that this member template is a specialization.
- void setMemberSpecialization() {
- ClassTemplatePartialSpecializationDecl *First =
- cast<ClassTemplatePartialSpecializationDecl>(getFirstDecl());
- assert(First->InstantiatedFromMember.getPointer() &&
- "Only member templates can be member template specializations");
- return First->InstantiatedFromMember.setInt(true);
- }
-
- /// Retrieves the injected specialization type for this partial
- /// specialization. This is not the same as the type-decl-type for
- /// this partial specialization, which is an InjectedClassNameType.
- QualType getInjectedSpecializationType() const {
- assert(getTypeForDecl() && "partial specialization has no type set!");
- return cast<InjectedClassNameType>(getTypeForDecl())
- ->getInjectedSpecializationType();
- }
-
- // FIXME: Add Profile support!
-
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) {
- return K == ClassTemplatePartialSpecialization;
- }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-};
-
-/// Declaration of a class template.
-class ClassTemplateDecl : public RedeclarableTemplateDecl {
- static void DeallocateCommon(void *Ptr);
-
-protected:
- /// \brief Data that is common to all of the declarations of a given
- /// class template.
- struct Common : CommonBase {
- Common() : LazySpecializations() { }
-
- /// \brief The class template specializations for this class
- /// template, including explicit specializations and instantiations.
- llvm::FoldingSetVector<ClassTemplateSpecializationDecl> Specializations;
-
- /// \brief The class template partial specializations for this class
- /// template.
- llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>
- PartialSpecializations;
-
- /// \brief The injected-class-name type for this class template.
- QualType InjectedClassNameType;
-
- /// \brief If non-null, points to an array of specializations (including
- /// partial specializations) known only by their external declaration IDs.
- ///
- /// The first value in the array is the number of of specializations/
- /// partial specializations that follow.
- uint32_t *LazySpecializations;
- };
-
- /// \brief Retrieve the set of specializations of this class template.
- llvm::FoldingSetVector<ClassTemplateSpecializationDecl> &
- getSpecializations() const;
-
- /// \brief Retrieve the set of partial specializations of this class
- /// template.
- llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
- getPartialSpecializations();
-
- ClassTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L,
- DeclarationName Name, TemplateParameterList *Params,
- NamedDecl *Decl)
- : RedeclarableTemplateDecl(ClassTemplate, C, DC, L, Name, Params, Decl) {}
-
- CommonBase *newCommon(ASTContext &C) const override;
-
- Common *getCommonPtr() const {
- return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
- }
-
-public:
- /// \brief Load any lazily-loaded specializations from the external source.
- void LoadLazySpecializations() const;
-
- /// \brief Get the underlying class declarations of the template.
- CXXRecordDecl *getTemplatedDecl() const {
- return static_cast<CXXRecordDecl *>(TemplatedDecl);
- }
-
- /// \brief Returns whether this template declaration defines the primary
- /// class pattern.
- bool isThisDeclarationADefinition() const {
- return getTemplatedDecl()->isThisDeclarationADefinition();
- }
-
- /// \brief Create a class template node.
- static ClassTemplateDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation L,
- DeclarationName Name,
- TemplateParameterList *Params,
- NamedDecl *Decl,
- ClassTemplateDecl *PrevDecl);
-
- /// \brief Create an empty class template node.
- static ClassTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- /// \brief Return the specialization with the provided arguments if it exists,
- /// otherwise return the insertion point.
- ClassTemplateSpecializationDecl *
- findSpecialization(ArrayRef<TemplateArgument> Args, void *&InsertPos);
-
- /// \brief Insert the specified specialization knowing that it is not already
- /// in. InsertPos must be obtained from findSpecialization.
- void AddSpecialization(ClassTemplateSpecializationDecl *D, void *InsertPos);
-
- ClassTemplateDecl *getCanonicalDecl() override {
- return cast<ClassTemplateDecl>(
- RedeclarableTemplateDecl::getCanonicalDecl());
- }
- const ClassTemplateDecl *getCanonicalDecl() const {
- return cast<ClassTemplateDecl>(
- RedeclarableTemplateDecl::getCanonicalDecl());
- }
-
- /// \brief Retrieve the previous declaration of this class template, or
- /// NULL if no such declaration exists.
- ClassTemplateDecl *getPreviousDecl() {
- return cast_or_null<ClassTemplateDecl>(
- static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
- }
-
- /// \brief Retrieve the previous declaration of this class template, or
- /// NULL if no such declaration exists.
- const ClassTemplateDecl *getPreviousDecl() const {
- return cast_or_null<ClassTemplateDecl>(
- static_cast<const RedeclarableTemplateDecl *>(
- this)->getPreviousDecl());
- }
-
- ClassTemplateDecl *getMostRecentDecl() {
- return cast<ClassTemplateDecl>(
- static_cast<RedeclarableTemplateDecl *>(this)->getMostRecentDecl());
- }
- const ClassTemplateDecl *getMostRecentDecl() const {
- return const_cast<ClassTemplateDecl*>(this)->getMostRecentDecl();
- }
-
- ClassTemplateDecl *getInstantiatedFromMemberTemplate() const {
- return cast_or_null<ClassTemplateDecl>(
- RedeclarableTemplateDecl::getInstantiatedFromMemberTemplate());
- }
-
- /// \brief Return the partial specialization with the provided arguments if it
- /// exists, otherwise return the insertion point.
- ClassTemplatePartialSpecializationDecl *
- findPartialSpecialization(ArrayRef<TemplateArgument> Args, void *&InsertPos);
-
- /// \brief Insert the specified partial specialization knowing that it is not
- /// already in. InsertPos must be obtained from findPartialSpecialization.
- void AddPartialSpecialization(ClassTemplatePartialSpecializationDecl *D,
- void *InsertPos);
-
- /// \brief Retrieve the partial specializations as an ordered list.
- void getPartialSpecializations(
- SmallVectorImpl<ClassTemplatePartialSpecializationDecl *> &PS);
-
- /// \brief Find a class template partial specialization with the given
- /// type T.
- ///
- /// \param T a dependent type that names a specialization of this class
- /// template.
- ///
- /// \returns the class template partial specialization that exactly matches
- /// the type \p T, or NULL if no such partial specialization exists.
- ClassTemplatePartialSpecializationDecl *findPartialSpecialization(QualType T);
-
- /// \brief Find a class template partial specialization which was instantiated
- /// from the given member partial specialization.
- ///
- /// \param D a member class template partial specialization.
- ///
- /// \returns the class template partial specialization which was instantiated
- /// from the given member partial specialization, or NULL if no such partial
- /// specialization exists.
- ClassTemplatePartialSpecializationDecl *
- findPartialSpecInstantiatedFromMember(
- ClassTemplatePartialSpecializationDecl *D);
-
- /// \brief Retrieve the template specialization type of the
- /// injected-class-name for this class template.
- ///
- /// The injected-class-name for a class template \c X is \c
- /// X<template-args>, where \c template-args is formed from the
- /// template arguments that correspond to the template parameters of
- /// \c X. For example:
- ///
- /// \code
- /// template<typename T, int N>
- /// struct array {
- /// typedef array this_type; // "array" is equivalent to "array<T, N>"
- /// };
- /// \endcode
- QualType getInjectedClassNameSpecialization();
-
- typedef SpecIterator<ClassTemplateSpecializationDecl> spec_iterator;
- typedef llvm::iterator_range<spec_iterator> spec_range;
-
- spec_range specializations() const {
- return spec_range(spec_begin(), spec_end());
- }
-
- spec_iterator spec_begin() const {
- return makeSpecIterator(getSpecializations(), false);
- }
-
- spec_iterator spec_end() const {
- return makeSpecIterator(getSpecializations(), true);
- }
-
- // Implement isa/cast/dyncast support
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == ClassTemplate; }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-};
-
-/// \brief 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 {
- virtual void anchor();
-public:
- typedef llvm::PointerUnion<NamedDecl*,TypeSourceInfo*> FriendUnion;
-
-private:
- // The number of template parameters; always non-zero.
- unsigned NumParams;
-
- // The parameter list.
- TemplateParameterList **Params;
-
- // The declaration that's a friend of this class.
- FriendUnion Friend;
-
- // Location of the 'friend' specifier.
- SourceLocation FriendLoc;
-
-
- FriendTemplateDecl(DeclContext *DC, SourceLocation Loc,
- unsigned NParams,
- TemplateParameterList **Params,
- FriendUnion Friend,
- SourceLocation FriendLoc)
- : Decl(Decl::FriendTemplate, DC, Loc),
- NumParams(NParams),
- Params(Params),
- Friend(Friend),
- FriendLoc(FriendLoc)
- {}
-
- FriendTemplateDecl(EmptyShell Empty)
- : Decl(Decl::FriendTemplate, Empty),
- NumParams(0),
- Params(nullptr)
- {}
-
-public:
- static FriendTemplateDecl *Create(ASTContext &Context,
- DeclContext *DC, SourceLocation Loc,
- unsigned NParams,
- TemplateParameterList **Params,
- FriendUnion Friend,
- SourceLocation FriendLoc);
-
- static FriendTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- /// If this friend declaration names a templated type (or
- /// a dependent member type of a templated type), return that
- /// type; otherwise return null.
- TypeSourceInfo *getFriendType() const {
- return Friend.dyn_cast<TypeSourceInfo*>();
- }
-
- /// If this friend declaration names a templated function (or
- /// a member function of a templated type), return that type;
- /// otherwise return null.
- NamedDecl *getFriendDecl() const {
- return Friend.dyn_cast<NamedDecl*>();
- }
-
- /// \brief Retrieves the location of the 'friend' keyword.
- SourceLocation getFriendLoc() const {
- return FriendLoc;
- }
-
- TemplateParameterList *getTemplateParameterList(unsigned i) const {
- assert(i <= NumParams);
- return Params[i];
- }
-
- unsigned getNumTemplateParameters() const {
- return NumParams;
- }
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == Decl::FriendTemplate; }
-
- friend class ASTDeclReader;
-};
-
-/// \brief Declaration of an alias template.
-///
-/// For example:
-/// \code
-/// template \<typename T> using V = std::map<T*, int, MyCompare<T>>;
-/// \endcode
-class TypeAliasTemplateDecl : public RedeclarableTemplateDecl {
- static void DeallocateCommon(void *Ptr);
-
-protected:
- typedef CommonBase Common;
-
- TypeAliasTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L,
- DeclarationName Name, TemplateParameterList *Params,
- NamedDecl *Decl)
- : RedeclarableTemplateDecl(TypeAliasTemplate, C, DC, L, Name, Params,
- Decl) {}
-
- CommonBase *newCommon(ASTContext &C) const override;
-
- Common *getCommonPtr() {
- return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
- }
-
-public:
- /// Get the underlying function declaration of the template.
- TypeAliasDecl *getTemplatedDecl() const {
- return static_cast<TypeAliasDecl*>(TemplatedDecl);
- }
-
-
- TypeAliasTemplateDecl *getCanonicalDecl() override {
- return cast<TypeAliasTemplateDecl>(
- RedeclarableTemplateDecl::getCanonicalDecl());
- }
- const TypeAliasTemplateDecl *getCanonicalDecl() const {
- return cast<TypeAliasTemplateDecl>(
- RedeclarableTemplateDecl::getCanonicalDecl());
- }
-
- /// \brief Retrieve the previous declaration of this function template, or
- /// NULL if no such declaration exists.
- TypeAliasTemplateDecl *getPreviousDecl() {
- return cast_or_null<TypeAliasTemplateDecl>(
- static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
- }
-
- /// \brief Retrieve the previous declaration of this function template, or
- /// NULL if no such declaration exists.
- const TypeAliasTemplateDecl *getPreviousDecl() const {
- return cast_or_null<TypeAliasTemplateDecl>(
- static_cast<const RedeclarableTemplateDecl *>(
- this)->getPreviousDecl());
- }
-
- TypeAliasTemplateDecl *getInstantiatedFromMemberTemplate() const {
- return cast_or_null<TypeAliasTemplateDecl>(
- RedeclarableTemplateDecl::getInstantiatedFromMemberTemplate());
- }
-
-
- /// \brief Create a function template node.
- static TypeAliasTemplateDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation L,
- DeclarationName Name,
- TemplateParameterList *Params,
- NamedDecl *Decl);
-
- /// \brief Create an empty alias template node.
- static TypeAliasTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- // Implement isa/cast/dyncast support
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == TypeAliasTemplate; }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-};
-
-/// \brief Declaration of a function specialization at template class scope.
-///
-/// This is a non-standard extension needed to support MSVC.
-///
-/// For example:
-/// \code
-/// template <class T>
-/// class A {
-/// template <class U> void foo(U a) { }
-/// template<> void foo(int a) { }
-/// }
-/// \endcode
-///
-/// "template<> foo(int a)" will be saved in Specialization as a normal
-/// CXXMethodDecl. Then during an instantiation of class A, it will be
-/// transformed into an actual function specialization.
-class ClassScopeFunctionSpecializationDecl : public Decl {
- virtual void anchor();
-
- ClassScopeFunctionSpecializationDecl(DeclContext *DC, SourceLocation Loc,
- CXXMethodDecl *FD, bool Args,
- TemplateArgumentListInfo TemplArgs)
- : Decl(Decl::ClassScopeFunctionSpecialization, DC, Loc),
- Specialization(FD), HasExplicitTemplateArgs(Args),
- TemplateArgs(TemplArgs) {}
-
- ClassScopeFunctionSpecializationDecl(EmptyShell Empty)
- : Decl(Decl::ClassScopeFunctionSpecialization, Empty) {}
-
- CXXMethodDecl *Specialization;
- bool HasExplicitTemplateArgs;
- TemplateArgumentListInfo TemplateArgs;
-
-public:
- CXXMethodDecl *getSpecialization() const { return Specialization; }
- bool hasExplicitTemplateArgs() const { return HasExplicitTemplateArgs; }
- const TemplateArgumentListInfo& templateArgs() const { return TemplateArgs; }
-
- static ClassScopeFunctionSpecializationDecl *Create(ASTContext &C,
- DeclContext *DC,
- SourceLocation Loc,
- CXXMethodDecl *FD,
- bool HasExplicitTemplateArgs,
- TemplateArgumentListInfo TemplateArgs) {
- return new (C, DC) ClassScopeFunctionSpecializationDecl(
- DC, Loc, FD, HasExplicitTemplateArgs, TemplateArgs);
- }
-
- static ClassScopeFunctionSpecializationDecl *
- CreateDeserialized(ASTContext &Context, unsigned ID);
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) {
- return K == Decl::ClassScopeFunctionSpecialization;
- }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-};
-
-/// Implementation of inline functions that require the template declarations
-inline AnyFunctionDecl::AnyFunctionDecl(FunctionTemplateDecl *FTD)
- : Function(FTD) { }
-
-/// \brief 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 {
-
- /// \brief Structure that stores information about a variable template
- /// specialization that was instantiated from a variable template partial
- /// specialization.
- struct SpecializedPartialSpecialization {
- /// \brief The variable template partial specialization from which this
- /// variable template specialization was instantiated.
- VarTemplatePartialSpecializationDecl *PartialSpecialization;
-
- /// \brief The template argument list deduced for the variable template
- /// partial specialization itself.
- const TemplateArgumentList *TemplateArgs;
- };
-
- /// \brief The template that this specialization specializes.
- llvm::PointerUnion<VarTemplateDecl *, SpecializedPartialSpecialization *>
- SpecializedTemplate;
-
- /// \brief Further info for explicit template specialization/instantiation.
- struct ExplicitSpecializationInfo {
- /// \brief The type-as-written.
- TypeSourceInfo *TypeAsWritten;
- /// \brief The location of the extern keyword.
- SourceLocation ExternLoc;
- /// \brief The location of the template keyword.
- SourceLocation TemplateKeywordLoc;
-
- ExplicitSpecializationInfo()
- : TypeAsWritten(nullptr), ExternLoc(), TemplateKeywordLoc() {}
- };
-
- /// \brief Further info for explicit template specialization/instantiation.
- /// Does not apply to implicit specializations.
- ExplicitSpecializationInfo *ExplicitInfo;
-
- /// \brief The template arguments used to describe this specialization.
- const TemplateArgumentList *TemplateArgs;
- TemplateArgumentListInfo TemplateArgsInfo;
-
- /// \brief The point where this template was instantiated (if any).
- SourceLocation PointOfInstantiation;
-
- /// \brief The kind of specialization this declaration refers to.
- /// Really a value of type TemplateSpecializationKind.
- unsigned SpecializationKind : 3;
-
-protected:
- VarTemplateSpecializationDecl(Kind DK, ASTContext &Context, DeclContext *DC,
- SourceLocation StartLoc, SourceLocation IdLoc,
- VarTemplateDecl *SpecializedTemplate,
- QualType T, TypeSourceInfo *TInfo,
- StorageClass S, const TemplateArgument *Args,
- unsigned NumArgs);
-
- explicit VarTemplateSpecializationDecl(Kind DK, ASTContext &Context);
-
-public:
- static VarTemplateSpecializationDecl *
- Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
- SourceLocation IdLoc, VarTemplateDecl *SpecializedTemplate, QualType T,
- TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args,
- unsigned NumArgs);
- static VarTemplateSpecializationDecl *CreateDeserialized(ASTContext &C,
- unsigned ID);
-
- void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy,
- bool Qualified) const override;
-
- VarTemplateSpecializationDecl *getMostRecentDecl() {
- VarDecl *Recent = static_cast<VarDecl *>(this)->getMostRecentDecl();
- return cast<VarTemplateSpecializationDecl>(Recent);
- }
-
- /// \brief Retrieve the template that this specialization specializes.
- VarTemplateDecl *getSpecializedTemplate() const;
-
- /// \brief Retrieve the template arguments of the variable template
- /// specialization.
- const TemplateArgumentList &getTemplateArgs() const { return *TemplateArgs; }
-
- // TODO: Always set this when creating the new specialization?
- void setTemplateArgsInfo(const TemplateArgumentListInfo &ArgsInfo);
-
- const TemplateArgumentListInfo &getTemplateArgsInfo() const {
- return TemplateArgsInfo;
- }
-
- /// \brief Determine the kind of specialization that this
- /// declaration represents.
- TemplateSpecializationKind getSpecializationKind() const {
- return static_cast<TemplateSpecializationKind>(SpecializationKind);
- }
-
- bool isExplicitSpecialization() const {
- return getSpecializationKind() == TSK_ExplicitSpecialization;
- }
-
- /// \brief True if this declaration is an explicit specialization,
- /// explicit instantiation declaration, or explicit instantiation
- /// definition.
- bool isExplicitInstantiationOrSpecialization() const {
- return isTemplateExplicitInstantiationOrSpecialization(
- getTemplateSpecializationKind());
- }
-
- void setSpecializationKind(TemplateSpecializationKind TSK) {
- SpecializationKind = TSK;
- }
-
- /// \brief Get the point of instantiation (if any), or null if none.
- SourceLocation getPointOfInstantiation() const {
- return PointOfInstantiation;
- }
-
- void setPointOfInstantiation(SourceLocation Loc) {
- assert(Loc.isValid() && "point of instantiation must be valid!");
- PointOfInstantiation = Loc;
- }
-
- /// \brief If this variable template specialization is an instantiation of
- /// a template (rather than an explicit specialization), return the
- /// variable template or variable template partial specialization from which
- /// it was instantiated.
- llvm::PointerUnion<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>
- getInstantiatedFrom() const {
- if (getSpecializationKind() != TSK_ImplicitInstantiation &&
- getSpecializationKind() != TSK_ExplicitInstantiationDefinition &&
- getSpecializationKind() != TSK_ExplicitInstantiationDeclaration)
- return llvm::PointerUnion<VarTemplateDecl *,
- VarTemplatePartialSpecializationDecl *>();
-
- if (SpecializedPartialSpecialization *PartialSpec =
- SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
- return PartialSpec->PartialSpecialization;
-
- return SpecializedTemplate.get<VarTemplateDecl *>();
- }
-
- /// \brief Retrieve the variable template or variable template partial
- /// specialization which was specialized by this.
- llvm::PointerUnion<VarTemplateDecl *, VarTemplatePartialSpecializationDecl *>
- getSpecializedTemplateOrPartial() const {
- if (SpecializedPartialSpecialization *PartialSpec =
- SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
- return PartialSpec->PartialSpecialization;
-
- return SpecializedTemplate.get<VarTemplateDecl *>();
- }
-
- /// \brief Retrieve the set of template arguments that should be used
- /// to instantiate the initializer of the variable template or variable
- /// template partial specialization from which this variable template
- /// specialization was instantiated.
- ///
- /// \returns For a variable template specialization instantiated from the
- /// primary template, this function will return the same template arguments
- /// as getTemplateArgs(). For a variable template specialization instantiated
- /// from a variable template partial specialization, this function will the
- /// return deduced template arguments for the variable template partial
- /// specialization itself.
- const TemplateArgumentList &getTemplateInstantiationArgs() const {
- if (SpecializedPartialSpecialization *PartialSpec =
- SpecializedTemplate.dyn_cast<SpecializedPartialSpecialization *>())
- return *PartialSpec->TemplateArgs;
-
- return getTemplateArgs();
- }
-
- /// \brief Note that this variable template specialization is actually an
- /// instantiation of the given variable template partial specialization whose
- /// template arguments have been deduced.
- void setInstantiationOf(VarTemplatePartialSpecializationDecl *PartialSpec,
- const TemplateArgumentList *TemplateArgs) {
- assert(!SpecializedTemplate.is<SpecializedPartialSpecialization *>() &&
- "Already set to a variable template partial specialization!");
- SpecializedPartialSpecialization *PS =
- new (getASTContext()) SpecializedPartialSpecialization();
- PS->PartialSpecialization = PartialSpec;
- PS->TemplateArgs = TemplateArgs;
- SpecializedTemplate = PS;
- }
-
- /// \brief Note that this variable template specialization is an instantiation
- /// of the given variable template.
- void setInstantiationOf(VarTemplateDecl *TemplDecl) {
- assert(!SpecializedTemplate.is<SpecializedPartialSpecialization *>() &&
- "Previously set to a variable template partial specialization!");
- SpecializedTemplate = TemplDecl;
- }
-
- /// \brief Sets the type of this specialization as it was written by
- /// the user.
- void setTypeAsWritten(TypeSourceInfo *T) {
- if (!ExplicitInfo)
- ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
- ExplicitInfo->TypeAsWritten = T;
- }
- /// \brief Gets the type of this specialization as it was written by
- /// the user, if it was so written.
- TypeSourceInfo *getTypeAsWritten() const {
- return ExplicitInfo ? ExplicitInfo->TypeAsWritten : nullptr;
- }
-
- /// \brief Gets the location of the extern keyword, if present.
- SourceLocation getExternLoc() const {
- return ExplicitInfo ? ExplicitInfo->ExternLoc : SourceLocation();
- }
- /// \brief Sets the location of the extern keyword.
- void setExternLoc(SourceLocation Loc) {
- if (!ExplicitInfo)
- ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
- ExplicitInfo->ExternLoc = Loc;
- }
-
- /// \brief Sets the location of the template keyword.
- void setTemplateKeywordLoc(SourceLocation Loc) {
- if (!ExplicitInfo)
- ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
- ExplicitInfo->TemplateKeywordLoc = Loc;
- }
- /// \brief Gets the location of the template keyword, if present.
- SourceLocation getTemplateKeywordLoc() const {
- return ExplicitInfo ? ExplicitInfo->TemplateKeywordLoc : SourceLocation();
- }
-
- void Profile(llvm::FoldingSetNodeID &ID) const {
- Profile(ID, TemplateArgs->asArray(), getASTContext());
- }
-
- static void Profile(llvm::FoldingSetNodeID &ID,
- ArrayRef<TemplateArgument> TemplateArgs,
- ASTContext &Context) {
- ID.AddInteger(TemplateArgs.size());
- for (unsigned Arg = 0; Arg != TemplateArgs.size(); ++Arg)
- TemplateArgs[Arg].Profile(ID, Context);
- }
-
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) {
- return K >= firstVarTemplateSpecialization &&
- K <= lastVarTemplateSpecialization;
- }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-};
-
-class VarTemplatePartialSpecializationDecl
- : public VarTemplateSpecializationDecl {
- void anchor() override;
-
- /// \brief The list of template parameters
- TemplateParameterList *TemplateParams;
-
- /// \brief The source info for the template arguments as written.
- /// FIXME: redundant with TypeAsWritten?
- const ASTTemplateArgumentListInfo *ArgsAsWritten;
-
- /// \brief The variable template partial specialization from which this
- /// variable template partial specialization was instantiated.
- ///
- /// The boolean value will be true to indicate that this variable template
- /// partial specialization was specialized at this level.
- llvm::PointerIntPair<VarTemplatePartialSpecializationDecl *, 1, bool>
- InstantiatedFromMember;
-
- VarTemplatePartialSpecializationDecl(
- ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
- SourceLocation IdLoc, TemplateParameterList *Params,
- VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
- StorageClass S, const TemplateArgument *Args, unsigned NumArgs,
- const ASTTemplateArgumentListInfo *ArgInfos);
-
- VarTemplatePartialSpecializationDecl(ASTContext &Context)
- : VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context),
- TemplateParams(nullptr), ArgsAsWritten(nullptr),
- InstantiatedFromMember(nullptr, false) {}
-
-public:
- static VarTemplatePartialSpecializationDecl *
- Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
- SourceLocation IdLoc, TemplateParameterList *Params,
- VarTemplateDecl *SpecializedTemplate, QualType T,
- TypeSourceInfo *TInfo, StorageClass S, const TemplateArgument *Args,
- unsigned NumArgs, const TemplateArgumentListInfo &ArgInfos);
-
- static VarTemplatePartialSpecializationDecl *CreateDeserialized(ASTContext &C,
- unsigned ID);
-
- VarTemplatePartialSpecializationDecl *getMostRecentDecl() {
- return cast<VarTemplatePartialSpecializationDecl>(
- static_cast<VarTemplateSpecializationDecl *>(
- this)->getMostRecentDecl());
- }
-
- /// Get the list of template parameters
- TemplateParameterList *getTemplateParameters() const {
- return TemplateParams;
- }
-
- /// Get the template arguments as written.
- const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten() const {
- return ArgsAsWritten;
- }
-
- /// \brief Retrieve the member variable template partial specialization from
- /// which this particular variable template partial specialization was
- /// instantiated.
- ///
- /// \code
- /// template<typename T>
- /// struct Outer {
- /// template<typename U> U Inner;
- /// template<typename U> U* Inner<U*> = (U*)(0); // #1
- /// };
- ///
- /// template int* Outer<float>::Inner<int*>;
- /// \endcode
- ///
- /// In this example, the instantiation of \c Outer<float>::Inner<int*> will
- /// end up instantiating the partial specialization
- /// \c Outer<float>::Inner<U*>, which itself was instantiated from the
- /// variable template partial specialization \c Outer<T>::Inner<U*>. Given
- /// \c Outer<float>::Inner<U*>, this function would return
- /// \c Outer<T>::Inner<U*>.
- VarTemplatePartialSpecializationDecl *getInstantiatedFromMember() const {
- const VarTemplatePartialSpecializationDecl *First =
- cast<VarTemplatePartialSpecializationDecl>(getFirstDecl());
- return First->InstantiatedFromMember.getPointer();
- }
-
- void
- setInstantiatedFromMember(VarTemplatePartialSpecializationDecl *PartialSpec) {
- VarTemplatePartialSpecializationDecl *First =
- cast<VarTemplatePartialSpecializationDecl>(getFirstDecl());
- First->InstantiatedFromMember.setPointer(PartialSpec);
- }
-
- /// \brief Determines whether this variable template partial specialization
- /// was a specialization of a member partial specialization.
- ///
- /// In the following example, the member template partial specialization
- /// \c X<int>::Inner<T*> is a member specialization.
- ///
- /// \code
- /// template<typename T>
- /// struct X {
- /// template<typename U> U Inner;
- /// template<typename U> U* Inner<U*> = (U*)(0);
- /// };
- ///
- /// template<> template<typename T>
- /// U* X<int>::Inner<T*> = (T*)(0) + 1;
- /// \endcode
- bool isMemberSpecialization() {
- VarTemplatePartialSpecializationDecl *First =
- cast<VarTemplatePartialSpecializationDecl>(getFirstDecl());
- return First->InstantiatedFromMember.getInt();
- }
-
- /// \brief Note that this member template is a specialization.
- void setMemberSpecialization() {
- VarTemplatePartialSpecializationDecl *First =
- cast<VarTemplatePartialSpecializationDecl>(getFirstDecl());
- assert(First->InstantiatedFromMember.getPointer() &&
- "Only member templates can be member template specializations");
- return First->InstantiatedFromMember.setInt(true);
- }
-
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) {
- return K == VarTemplatePartialSpecialization;
- }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-};
-
-/// Declaration of a variable template.
-class VarTemplateDecl : public RedeclarableTemplateDecl {
- static void DeallocateCommon(void *Ptr);
-
-protected:
- /// \brief Data that is common to all of the declarations of a given
- /// variable template.
- struct Common : CommonBase {
- Common() : LazySpecializations() {}
-
- /// \brief The variable template specializations for this variable
- /// template, including explicit specializations and instantiations.
- llvm::FoldingSetVector<VarTemplateSpecializationDecl> Specializations;
-
- /// \brief The variable template partial specializations for this variable
- /// template.
- llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl>
- PartialSpecializations;
-
- /// \brief If non-null, points to an array of specializations (including
- /// partial specializations) known ownly by their external declaration IDs.
- ///
- /// The first value in the array is the number of of specializations/
- /// partial specializations that follow.
- uint32_t *LazySpecializations;
- };
-
- /// \brief Retrieve the set of specializations of this variable template.
- llvm::FoldingSetVector<VarTemplateSpecializationDecl> &
- getSpecializations() const;
-
- /// \brief Retrieve the set of partial specializations of this class
- /// template.
- llvm::FoldingSetVector<VarTemplatePartialSpecializationDecl> &
- getPartialSpecializations();
-
- VarTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L,
- DeclarationName Name, TemplateParameterList *Params,
- NamedDecl *Decl)
- : RedeclarableTemplateDecl(VarTemplate, C, DC, L, Name, Params, Decl) {}
-
- CommonBase *newCommon(ASTContext &C) const override;
-
- Common *getCommonPtr() const {
- return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
- }
-
-public:
- /// \brief Load any lazily-loaded specializations from the external source.
- void LoadLazySpecializations() const;
-
- /// \brief Get the underlying variable declarations of the template.
- VarDecl *getTemplatedDecl() const {
- return static_cast<VarDecl *>(TemplatedDecl);
- }
-
- /// \brief Returns whether this template declaration defines the primary
- /// variable pattern.
- bool isThisDeclarationADefinition() const {
- return getTemplatedDecl()->isThisDeclarationADefinition();
- }
-
- VarTemplateDecl *getDefinition();
-
- /// \brief Create a variable template node.
- static VarTemplateDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation L, DeclarationName Name,
- TemplateParameterList *Params,
- VarDecl *Decl);
-
- /// \brief Create an empty variable template node.
- static VarTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID);
-
- /// \brief Return the specialization with the provided arguments if it exists,
- /// otherwise return the insertion point.
- VarTemplateSpecializationDecl *
- findSpecialization(ArrayRef<TemplateArgument> Args, void *&InsertPos);
-
- /// \brief Insert the specified specialization knowing that it is not already
- /// in. InsertPos must be obtained from findSpecialization.
- void AddSpecialization(VarTemplateSpecializationDecl *D, void *InsertPos);
-
- VarTemplateDecl *getCanonicalDecl() override {
- return cast<VarTemplateDecl>(RedeclarableTemplateDecl::getCanonicalDecl());
- }
- const VarTemplateDecl *getCanonicalDecl() const {
- return cast<VarTemplateDecl>(RedeclarableTemplateDecl::getCanonicalDecl());
- }
-
- /// \brief Retrieve the previous declaration of this variable template, or
- /// NULL if no such declaration exists.
- VarTemplateDecl *getPreviousDecl() {
- return cast_or_null<VarTemplateDecl>(
- static_cast<RedeclarableTemplateDecl *>(this)->getPreviousDecl());
- }
-
- /// \brief Retrieve the previous declaration of this variable template, or
- /// NULL if no such declaration exists.
- const VarTemplateDecl *getPreviousDecl() const {
- return cast_or_null<VarTemplateDecl>(
- static_cast<const RedeclarableTemplateDecl *>(
- this)->getPreviousDecl());
- }
-
- VarTemplateDecl *getMostRecentDecl() {
- return cast<VarTemplateDecl>(
- static_cast<RedeclarableTemplateDecl *>(this)->getMostRecentDecl());
- }
- const VarTemplateDecl *getMostRecentDecl() const {
- return const_cast<VarTemplateDecl *>(this)->getMostRecentDecl();
- }
-
- VarTemplateDecl *getInstantiatedFromMemberTemplate() const {
- return cast_or_null<VarTemplateDecl>(
- RedeclarableTemplateDecl::getInstantiatedFromMemberTemplate());
- }
-
- /// \brief Return the partial specialization with the provided arguments if it
- /// exists, otherwise return the insertion point.
- VarTemplatePartialSpecializationDecl *
- findPartialSpecialization(ArrayRef<TemplateArgument> Args, void *&InsertPos);
-
- /// \brief Insert the specified partial specialization knowing that it is not
- /// already in. InsertPos must be obtained from findPartialSpecialization.
- void AddPartialSpecialization(VarTemplatePartialSpecializationDecl *D,
- void *InsertPos);
-
- /// \brief Retrieve the partial specializations as an ordered list.
- void getPartialSpecializations(
- SmallVectorImpl<VarTemplatePartialSpecializationDecl *> &PS);
-
- /// \brief Find a variable template partial specialization which was
- /// instantiated
- /// from the given member partial specialization.
- ///
- /// \param D a member variable template partial specialization.
- ///
- /// \returns the variable template partial specialization which was
- /// instantiated
- /// from the given member partial specialization, or NULL if no such partial
- /// specialization exists.
- VarTemplatePartialSpecializationDecl *findPartialSpecInstantiatedFromMember(
- VarTemplatePartialSpecializationDecl *D);
-
- typedef SpecIterator<VarTemplateSpecializationDecl> spec_iterator;
- typedef llvm::iterator_range<spec_iterator> spec_range;
-
- spec_range specializations() const {
- return spec_range(spec_begin(), spec_end());
- }
-
- spec_iterator spec_begin() const {
- return makeSpecIterator(getSpecializations(), false);
- }
-
- spec_iterator spec_end() const {
- return makeSpecIterator(getSpecializations(), true);
- }
-
- // Implement isa/cast/dyncast support
- static bool classof(const Decl *D) { return classofKind(D->getKind()); }
- static bool classofKind(Kind K) { return K == VarTemplate; }
-
- friend class ASTDeclReader;
- friend class ASTDeclWriter;
-};
-
-} /* end of namespace clang */
-
-#endif
OpenPOWER on IntegriCloud