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.h402
1 files changed, 232 insertions, 170 deletions
diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h
index b532668..176c6ba 100644
--- a/include/clang/AST/DeclTemplate.h
+++ b/include/clang/AST/DeclTemplate.h
@@ -53,7 +53,7 @@ class TemplateParameterList {
SourceLocation RAngleLoc);
public:
- static TemplateParameterList *Create(ASTContext &C,
+ static TemplateParameterList *Create(const ASTContext &C,
SourceLocation TemplateLoc,
SourceLocation LAngleLoc,
NamedDecl **Params,
@@ -85,7 +85,7 @@ public:
return begin()[Idx];
}
- /// \btief Returns the minimum number of arguments needed to form a
+ /// \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.
@@ -107,101 +107,57 @@ public:
}
};
-/// \brief A helper class for making template argument lists.
-class TemplateArgumentListBuilder {
- TemplateArgument *StructuredArgs;
- unsigned MaxStructuredArgs;
- unsigned NumStructuredArgs;
-
- llvm::SmallVector<TemplateArgument, 4> FlatArgs;
- unsigned MaxFlatArgs;
- unsigned NumFlatArgs;
-
- bool AddingToPack;
- unsigned PackBeginIndex;
-
-public:
- TemplateArgumentListBuilder(const TemplateParameterList *Parameters,
- unsigned NumTemplateArgs)
- : StructuredArgs(0), MaxStructuredArgs(Parameters->size()),
- NumStructuredArgs(0), FlatArgs(0),
- MaxFlatArgs(std::max(MaxStructuredArgs, NumTemplateArgs)), NumFlatArgs(0),
- AddingToPack(false), PackBeginIndex(0) { }
-
- void Append(const TemplateArgument &Arg);
- void BeginPack();
- void EndPack();
-
- unsigned flatSize() const { return FlatArgs.size(); }
- const TemplateArgument *getFlatArguments() const { return FlatArgs.data(); }
-
- unsigned structuredSize() const {
- // If we don't have any structured args, just reuse the flat size.
- if (!StructuredArgs)
- return flatSize();
-
- return NumStructuredArgs;
- }
- const TemplateArgument *getStructuredArguments() const {
- // If we don't have any structured args, just reuse the flat args.
- if (!StructuredArgs)
- return getFlatArguments();
-
- return StructuredArgs;
- }
-};
-
/// \brief A template argument list.
-///
-/// FIXME: In the future, this class will be extended to support
-/// variadic templates and member templates, which will make some of
-/// the function names below make more sense.
class TemplateArgumentList {
/// \brief The template argument list.
///
/// The integer value will be non-zero to indicate that this
/// template argument list does own the pointer.
- llvm::PointerIntPair<const TemplateArgument *, 1> FlatArguments;
+ llvm::PointerIntPair<const TemplateArgument *, 1> Arguments;
/// \brief The number of template arguments in this template
/// argument list.
- unsigned NumFlatArguments;
-
- llvm::PointerIntPair<const TemplateArgument *, 1> StructuredArguments;
- unsigned NumStructuredArguments;
+ unsigned NumArguments;
TemplateArgumentList(const TemplateArgumentList &Other); // DO NOT IMPL
void operator=(const TemplateArgumentList &Other); // DO NOT IMPL
+
+ TemplateArgumentList(const TemplateArgument *Args, unsigned NumArgs,
+ bool Owned)
+ : Arguments(Args, Owned), NumArguments(NumArgs) { }
+
public:
- /// TemplateArgumentList - If this constructor is passed "true" for 'TakeArgs'
- /// it copies them into a locally new[]'d array. If passed "false", then it
- /// just references the array passed in. This is only safe if the builder
- /// outlives it, but saves a copy.
- TemplateArgumentList(ASTContext &Context,
- TemplateArgumentListBuilder &Builder,
- bool TakeArgs);
-
- /// TemplateArgumentList - It copies the template arguments into a locally
- /// new[]'d array.
- TemplateArgumentList(ASTContext &Context,
- const TemplateArgument *Args, unsigned NumArgs);
-
- /// Produces a shallow copy of the given template argument list. This
- /// 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);
-
- TemplateArgumentList() : NumFlatArguments(0), NumStructuredArguments(0) { }
-
- /// \brief Copies the template arguments into a locally new[]'d array.
- void init(ASTContext &Context,
- const TemplateArgument *Args, unsigned NumArgs);
+ /// \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, false), 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(), false), NumArguments(Other->size()) { }
/// \brief Retrieve the template argument at a given index.
const TemplateArgument &get(unsigned Idx) const {
- assert(Idx < NumFlatArguments && "Invalid template argument index");
- return getFlatArgumentList()[Idx];
+ assert(Idx < NumArguments && "Invalid template argument index");
+ return data()[Idx];
}
/// \brief Retrieve the template argument at a given index.
@@ -209,15 +165,11 @@ public:
/// \brief Retrieve the number of template arguments in this
/// template argument list.
- unsigned size() const { return NumFlatArguments; }
-
- /// \brief Retrieve the number of template arguments in the
- /// flattened template argument list.
- unsigned flat_size() const { return NumFlatArguments; }
+ unsigned size() const { return NumArguments; }
- /// \brief Retrieve the flattened template argument list.
- const TemplateArgument *getFlatArgumentList() const {
- return FlatArguments.getPointer();
+ /// \brief Retrieve a pointer to the template argument list.
+ const TemplateArgument *data() const {
+ return Arguments.getPointer();
}
};
@@ -292,7 +244,31 @@ public:
/// 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 TemplateArgumentListInfo *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) {
+ return new (C) FunctionTemplateSpecializationInfo(FD, Template, TSK,
+ TemplateArgs,
+ TemplateArgsAsWritten,
+ POI);
+ }
+
/// \brief The function template specialization that this structure
/// describes.
FunctionDecl *Function;
@@ -345,8 +321,8 @@ public:
}
void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, TemplateArguments->getFlatArgumentList(),
- TemplateArguments->flat_size(),
+ Profile(ID, TemplateArguments->data(),
+ TemplateArguments->size(),
Function->getASTContext());
}
@@ -441,11 +417,6 @@ class DependentFunctionTemplateSpecializationInfo {
return reinterpret_cast<FunctionTemplateDecl*const*>(this+1);
}
- const TemplateArgumentLoc *getTemplateArgs() const {
- return reinterpret_cast<const TemplateArgumentLoc*>(
- &getTemplates()[getNumTemplates()]);
- }
-
public:
DependentFunctionTemplateSpecializationInfo(
const UnresolvedSetImpl &Templates,
@@ -463,6 +434,12 @@ public:
return getTemplates()[I];
}
+ /// \brief Returns the explicit template arguments that were given.
+ const TemplateArgumentLoc *getTemplateArgs() const {
+ return reinterpret_cast<const TemplateArgumentLoc*>(
+ &getTemplates()[getNumTemplates()]);
+ }
+
/// \brief Returns the number of explicit template arguments that were given.
unsigned getNumTemplateArgs() const {
return d.NumArgs;
@@ -584,7 +561,7 @@ protected:
/// for the common pointer.
CommonBase *getCommonPtr();
- virtual CommonBase *newCommon() = 0;
+ virtual CommonBase *newCommon(ASTContext &C) = 0;
// Construct a template decl with name, parameters, and templated element.
RedeclarableTemplateDecl(Kind DK, DeclContext *DC, SourceLocation L,
@@ -789,19 +766,13 @@ protected:
TemplateParameterList *Params, NamedDecl *Decl)
: RedeclarableTemplateDecl(FunctionTemplate, DC, L, Name, Params, Decl) { }
- CommonBase *newCommon();
+ CommonBase *newCommon(ASTContext &C);
Common *getCommonPtr() {
return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
}
- friend void FunctionDecl::setFunctionTemplateSpecialization(
- FunctionTemplateDecl *Template,
- const TemplateArgumentList *TemplateArgs,
- void *InsertPos,
- TemplateSpecializationKind TSK,
- const TemplateArgumentListInfo *TemplateArgsAsWritten,
- SourceLocation PointOfInstantiation);
+ friend class FunctionDecl;
/// \brief Retrieve the set of function template specializations of this
/// function template.
@@ -940,15 +911,15 @@ class TemplateTypeParmDecl : public TypeDecl {
bool Typename, QualType Type, bool ParameterPack)
: TypeDecl(TemplateTypeParm, DC, L, Id), Typename(Typename),
InheritedDefault(false), ParameterPack(ParameterPack), DefaultArgument() {
- TypeForDecl = Type.getTypePtr();
+ TypeForDecl = Type.getTypePtrOrNull();
}
public:
- static TemplateTypeParmDecl *Create(ASTContext &C, DeclContext *DC,
+ static TemplateTypeParmDecl *Create(const ASTContext &C, DeclContext *DC,
SourceLocation L, unsigned D, unsigned P,
IdentifierInfo *Id, bool Typename,
bool ParameterPack);
- static TemplateTypeParmDecl *Create(ASTContext &C, EmptyShell Empty);
+ static TemplateTypeParmDecl *Create(const ASTContext &C, EmptyShell Empty);
/// \brief Whether this template type parameter was declared with
/// the 'typename' keyword. If not, it was declared with the 'class'
@@ -1014,22 +985,54 @@ public:
/// template<int Size> class array { };
/// @endcode
class NonTypeTemplateParmDecl
- : public VarDecl, protected TemplateParmPosition {
+ : public DeclaratorDecl, protected TemplateParmPosition {
/// \brief The default template argument, if any, and whether or not
/// it was inherited.
llvm::PointerIntPair<Expr*, 1, bool> DefaultArgumentAndInherited;
+ // 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;
+
NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation L, unsigned D,
unsigned P, IdentifierInfo *Id, QualType T,
- TypeSourceInfo *TInfo)
- : VarDecl(NonTypeTemplateParm, DC, L, Id, T, TInfo, SC_None, SC_None),
- TemplateParmPosition(D, P), DefaultArgumentAndInherited(0, false)
+ bool ParameterPack, TypeSourceInfo *TInfo)
+ : DeclaratorDecl(NonTypeTemplateParm, DC, L, Id, T, TInfo),
+ TemplateParmPosition(D, P), DefaultArgumentAndInherited(0, false),
+ ParameterPack(ParameterPack), ExpandedParameterPack(false),
+ NumExpandedTypes(0)
{ }
+ NonTypeTemplateParmDecl(DeclContext *DC, SourceLocation L, unsigned D,
+ unsigned P, IdentifierInfo *Id, QualType T,
+ TypeSourceInfo *TInfo,
+ const QualType *ExpandedTypes,
+ unsigned NumExpandedTypes,
+ TypeSourceInfo **ExpandedTInfos);
+
+ friend class ASTDeclReader;
+
public:
static NonTypeTemplateParmDecl *
- Create(ASTContext &C, DeclContext *DC, SourceLocation L, unsigned D,
- unsigned P, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo);
+ Create(const ASTContext &C, DeclContext *DC, SourceLocation L, unsigned D,
+ unsigned P, IdentifierInfo *Id, QualType T, bool ParameterPack,
+ TypeSourceInfo *TInfo);
+
+ static NonTypeTemplateParmDecl *
+ Create(const ASTContext &C, DeclContext *DC, SourceLocation L, unsigned D,
+ unsigned P, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo,
+ const QualType *ExpandedTypes, unsigned NumExpandedTypes,
+ TypeSourceInfo **ExpandedTInfos);
using TemplateParmPosition::getDepth;
using TemplateParmPosition::setDepth;
@@ -1037,6 +1040,9 @@ public:
using TemplateParmPosition::setPosition;
using TemplateParmPosition::getIndex;
+ SourceLocation getInnerLocStart() const;
+ SourceRange getSourceRange() const;
+
/// \brief Determine whether this template parameter has a default
/// argument.
bool hasDefaultArgument() const {
@@ -1071,6 +1077,65 @@ public:
DefaultArgumentAndInherited.setInt(false);
}
+ /// \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 is a non-type template parameter pack
+ /// that has 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");
+ void * const *TypesAndInfos = reinterpret_cast<void * const*>(this + 1);
+ return QualType::getFromOpaquePtr(TypesAndInfos[2*I]);
+ }
+
+ /// \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");
+ void * const *TypesAndInfos = reinterpret_cast<void * const*>(this + 1);
+ return static_cast<TypeSourceInfo *>(TypesAndInfos[2*I+1]);
+ }
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classof(const NonTypeTemplateParmDecl *D) { return true; }
@@ -1092,24 +1157,36 @@ class TemplateTemplateParmDecl
/// Whether or not the default argument was inherited.
bool DefaultArgumentWasInherited;
+ /// \brief Whether this parameter is a parameter pack.
+ bool ParameterPack;
+
TemplateTemplateParmDecl(DeclContext *DC, SourceLocation L,
- unsigned D, unsigned P,
+ unsigned D, unsigned P, bool ParameterPack,
IdentifierInfo *Id, TemplateParameterList *Params)
: TemplateDecl(TemplateTemplateParm, DC, L, Id, Params),
TemplateParmPosition(D, P), DefaultArgument(),
- DefaultArgumentWasInherited(false)
+ DefaultArgumentWasInherited(false), ParameterPack(ParameterPack)
{ }
public:
- static TemplateTemplateParmDecl *Create(ASTContext &C, DeclContext *DC,
+ static TemplateTemplateParmDecl *Create(const ASTContext &C, DeclContext *DC,
SourceLocation L, unsigned D,
- unsigned P, IdentifierInfo *Id,
+ unsigned P, bool ParameterPack,
+ IdentifierInfo *Id,
TemplateParameterList *Params);
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 Determine whether this template parameter has a default
/// argument.
bool hasDefaultArgument() const {
@@ -1211,7 +1288,7 @@ class ClassTemplateSpecializationDecl
ExplicitSpecializationInfo *ExplicitInfo;
/// \brief The template arguments used to describe this specialization.
- TemplateArgumentList TemplateArgs;
+ TemplateArgumentList *TemplateArgs;
/// \brief The point where this template was instantiated (if any)
SourceLocation PointOfInstantiation;
@@ -1224,7 +1301,8 @@ protected:
ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
DeclContext *DC, SourceLocation L,
ClassTemplateDecl *SpecializedTemplate,
- TemplateArgumentListBuilder &Builder,
+ const TemplateArgument *Args,
+ unsigned NumArgs,
ClassTemplateSpecializationDecl *PrevDecl);
explicit ClassTemplateSpecializationDecl(Kind DK);
@@ -1233,7 +1311,8 @@ public:
static ClassTemplateSpecializationDecl *
Create(ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation L,
ClassTemplateDecl *SpecializedTemplate,
- TemplateArgumentListBuilder &Builder,
+ const TemplateArgument *Args,
+ unsigned NumArgs,
ClassTemplateSpecializationDecl *PrevDecl);
static ClassTemplateSpecializationDecl *
Create(ASTContext &Context, EmptyShell Empty);
@@ -1259,15 +1338,7 @@ public:
/// \brief Retrieve the template arguments of the class template
/// specialization.
const TemplateArgumentList &getTemplateArgs() const {
- return TemplateArgs;
- }
-
- /// \brief Initialize the template arguments of the class template
- /// specialization.
- void initTemplateArgs(TemplateArgument *Args, unsigned NumArgs) {
- assert(TemplateArgs.flat_size() == 0 &&
- "Template arguments already initialized!");
- TemplateArgs.init(getASTContext(), Args, NumArgs);
+ return *TemplateArgs;
}
/// \brief Determine the kind of specialization that this
@@ -1357,18 +1428,6 @@ public:
SpecializedTemplate = PS;
}
- /// \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,
- TemplateArgument *TemplateArgs,
- unsigned NumTemplateArgs) {
- ASTContext &Ctx = getASTContext();
- setInstantiationOf(PartialSpec,
- new (Ctx) TemplateArgumentList(Ctx, TemplateArgs,
- NumTemplateArgs));
- }
-
/// \brief Note that this class template specialization is an instantiation
/// of the given class template.
void setInstantiationOf(ClassTemplateDecl *TemplDecl) {
@@ -1415,8 +1474,7 @@ public:
SourceLocation getInnerLocStart() const { return getTemplateKeywordLoc(); }
void Profile(llvm::FoldingSetNodeID &ID) const {
- Profile(ID, TemplateArgs.getFlatArgumentList(), TemplateArgs.flat_size(),
- getASTContext());
+ Profile(ID, TemplateArgs->data(), TemplateArgs->size(), getASTContext());
}
static void
@@ -1440,6 +1498,9 @@ public:
static bool classof(const ClassTemplatePartialSpecializationDecl *) {
return true;
}
+
+ friend class ASTDeclReader;
+ friend class ASTDeclWriter;
};
class ClassTemplatePartialSpecializationDecl
@@ -1469,15 +1530,16 @@ class ClassTemplatePartialSpecializationDecl
DeclContext *DC, SourceLocation L,
TemplateParameterList *Params,
ClassTemplateDecl *SpecializedTemplate,
- TemplateArgumentListBuilder &Builder,
+ const TemplateArgument *Args,
+ unsigned NumArgs,
TemplateArgumentLoc *ArgInfos,
unsigned NumArgInfos,
ClassTemplatePartialSpecializationDecl *PrevDecl,
unsigned SequenceNumber)
: ClassTemplateSpecializationDecl(Context,
ClassTemplatePartialSpecialization,
- TK, DC, L, SpecializedTemplate, Builder,
- PrevDecl),
+ TK, DC, L, SpecializedTemplate,
+ Args, NumArgs, PrevDecl),
TemplateParams(Params), ArgsAsWritten(ArgInfos),
NumArgsAsWritten(NumArgInfos), SequenceNumber(SequenceNumber),
InstantiatedFromMember(0, false) { }
@@ -1493,7 +1555,8 @@ public:
Create(ASTContext &Context, TagKind TK,DeclContext *DC, SourceLocation L,
TemplateParameterList *Params,
ClassTemplateDecl *SpecializedTemplate,
- TemplateArgumentListBuilder &Builder,
+ const TemplateArgument *Args,
+ unsigned NumArgs,
const TemplateArgumentListInfo &ArgInfos,
QualType CanonInjectedType,
ClassTemplatePartialSpecializationDecl *PrevDecl,
@@ -1512,18 +1575,11 @@ public:
return TemplateParams;
}
- void initTemplateParameters(TemplateParameterList *Params) {
- assert(TemplateParams == 0 && "TemplateParams already set");
- TemplateParams = Params;
- }
-
/// Get the template arguments as written.
TemplateArgumentLoc *getTemplateArgsAsWritten() const {
return ArgsAsWritten;
}
- void initTemplateArgsAsWritten(const TemplateArgumentListInfo &ArgInfos);
-
/// Get the number of template arguments as written.
unsigned getNumTemplateArgsAsWritten() const {
return NumArgsAsWritten;
@@ -1532,8 +1588,7 @@ public:
/// \brief Get the sequence number for this class template partial
/// specialization.
unsigned getSequenceNumber() const { return SequenceNumber; }
- void setSequenceNumber(unsigned N) { SequenceNumber = N; }
-
+
/// \brief Retrieve the member class template partial specialization from
/// which this particular class template partial specialization was
/// instantiated.
@@ -1617,6 +1672,9 @@ public:
static bool classof(const ClassTemplatePartialSpecializationDecl *) {
return true;
}
+
+ friend class ASTDeclReader;
+ friend class ASTDeclWriter;
};
/// Declaration of a class template.
@@ -1630,6 +1688,8 @@ 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::FoldingSet<ClassTemplateSpecializationDecl> Specializations;
@@ -1641,25 +1701,31 @@ protected:
/// \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 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 Load any lazily-loaded specializations from the external source.
+ void LoadLazySpecializations();
+
/// \brief Retrieve the set of specializations of this class template.
- llvm::FoldingSet<ClassTemplateSpecializationDecl> &getSpecializations() {
- return getCommonPtr()->Specializations;
- }
+ llvm::FoldingSet<ClassTemplateSpecializationDecl> &getSpecializations();
/// \brief Retrieve the set of partial specializations of this class
/// template.
llvm::FoldingSet<ClassTemplatePartialSpecializationDecl> &
- getPartialSpecializations() {
- return getCommonPtr()->PartialSpecializations;
- }
+ getPartialSpecializations();
ClassTemplateDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
TemplateParameterList *Params, NamedDecl *Decl)
: RedeclarableTemplateDecl(ClassTemplate, DC, L, Name, Params, Decl) { }
- CommonBase *newCommon();
+ CommonBase *newCommon(ASTContext &C);
Common *getCommonPtr() {
return static_cast<Common *>(RedeclarableTemplateDecl::getCommonPtr());
@@ -1693,9 +1759,7 @@ public:
/// \brief Insert the specified specialization knowing that it is not already
/// in. InsertPos must be obtained from findSpecialization.
- void AddSpecialization(ClassTemplateSpecializationDecl *D, void *InsertPos) {
- getSpecializations().InsertNode(D, InsertPos);
- }
+ void AddSpecialization(ClassTemplateSpecializationDecl *D, void *InsertPos);
ClassTemplateDecl *getCanonicalDecl() {
return redeclarable_base::getCanonicalDecl();
@@ -1729,9 +1793,7 @@ public:
/// \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) {
- getPartialSpecializations().InsertNode(D, InsertPos);
- }
+ void *InsertPos);
/// \brief Return the next partial specialization sequence number.
unsigned getNextPartialSpecSequenceNumber() {
OpenPOWER on IntegriCloud