aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/AST/DeclTemplate.h74
-rw-r--r--lib/AST/Decl.cpp2
-rw-r--r--lib/AST/DeclTemplate.cpp63
3 files changed, 123 insertions, 16 deletions
diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h
index 552b8ee5b3..ed4d54a1dd 100644
--- a/include/clang/AST/DeclTemplate.h
+++ b/include/clang/AST/DeclTemplate.h
@@ -183,20 +183,26 @@ public:
/// TemplateArgumentList - It copies the template arguments into a locally
/// new[]'d array.
TemplateArgumentList(ASTContext &Context,
- unsigned NumArgs, const TemplateArgument *Args);
+ 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) { }
+
/// Used to release the memory associated with a TemplateArgumentList
/// object. FIXME: This is currently not called anywhere, but the
/// memory will still be freed when using a BumpPtrAllocator.
void Destroy(ASTContext &C);
~TemplateArgumentList();
+
+ /// \brief Copies the template arguments into a locally new[]'d array.
+ void init(ASTContext &Context,
+ const TemplateArgument *Args, unsigned NumArgs);
/// \brief Retrieve the template argument at a given index.
const TemplateArgument &get(unsigned Idx) const {
@@ -962,6 +968,8 @@ protected:
TemplateArgumentListBuilder &Builder,
ClassTemplateSpecializationDecl *PrevDecl);
+ explicit ClassTemplateSpecializationDecl(Kind DK);
+
public:
static ClassTemplateSpecializationDecl *
Create(ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation L,
@@ -969,6 +977,8 @@ public:
TemplateArgumentListBuilder &Builder,
ClassTemplateSpecializationDecl *PrevDecl);
+ static ClassTemplateSpecializationDecl *CreateEmpty(ASTContext &Context);
+
virtual void Destroy(ASTContext& C);
virtual void getNameForDiagnostic(std::string &S,
@@ -984,6 +994,14 @@ public:
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);
+ }
+
/// \brief Determine the kind of specialization that this
/// declaration represents.
TemplateSpecializationKind getSpecializationKind() const {
@@ -1024,6 +1042,19 @@ public:
SpecializedTemplate.get<ClassTemplateDecl*>());
}
+ /// \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 const_cast<ClassTemplateDecl*>(
+ 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
@@ -1048,6 +1079,8 @@ public:
/// template arguments have been deduced.
void setInstantiationOf(ClassTemplatePartialSpecializationDecl *PartialSpec,
TemplateArgumentList *TemplateArgs) {
+ assert(!SpecializedTemplate.is<SpecializedPartialSpecialization*>() &&
+ "Already set to a class template partial specialization!");
SpecializedPartialSpecialization *PS
= new (getASTContext()) SpecializedPartialSpecialization();
PS->PartialSpecialization = PartialSpec;
@@ -1055,6 +1088,26 @@ 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) {
+ 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) {
@@ -1154,6 +1207,12 @@ class ClassTemplatePartialSpecializationDecl
TemplateParams(Params), ArgsAsWritten(ArgInfos),
NumArgsAsWritten(NumArgInfos), SequenceNumber(SequenceNumber),
InstantiatedFromMember(0, false) { }
+
+ ClassTemplatePartialSpecializationDecl()
+ : ClassTemplateSpecializationDecl(ClassTemplatePartialSpecialization),
+ TemplateParams(0), ArgsAsWritten(0),
+ NumArgsAsWritten(0), SequenceNumber(0),
+ InstantiatedFromMember(0, false) { }
public:
static ClassTemplatePartialSpecializationDecl *
@@ -1166,16 +1225,26 @@ public:
ClassTemplatePartialSpecializationDecl *PrevDecl,
unsigned SequenceNumber);
+ static ClassTemplatePartialSpecializationDecl *
+ CreateEmpty(ASTContext &Context);
+
/// Get the list of template parameters
TemplateParameterList *getTemplateParameters() const {
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;
@@ -1184,6 +1253,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
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 5fc6fb0481..267c19f5dc 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -1394,7 +1394,7 @@ FunctionDecl::setFunctionTemplateSpecialization(FunctionTemplateDecl *Template,
SourceLocation RAngleLoc) {
ASTContext &Ctx = getASTContext();
TemplateArgumentList *TemplArgs
- = new (Ctx) TemplateArgumentList(Ctx, NumTemplateArgs, TemplateArgs);
+ = new (Ctx) TemplateArgumentList(Ctx, TemplateArgs, NumTemplateArgs);
TemplateArgumentListInfo *TemplArgsInfo
= new (Ctx) TemplateArgumentListInfo(LAngleLoc, RAngleLoc);
for (unsigned i=0; i != NumTemplateArgsAsWritten; ++i)
diff --git a/lib/AST/DeclTemplate.cpp b/lib/AST/DeclTemplate.cpp
index 3ac32bc80b..ca19d1ff03 100644
--- a/lib/AST/DeclTemplate.cpp
+++ b/lib/AST/DeclTemplate.cpp
@@ -392,19 +392,9 @@ TemplateArgumentList::TemplateArgumentList(ASTContext &Context,
}
TemplateArgumentList::TemplateArgumentList(ASTContext &Context,
- unsigned NumArgs,
- const TemplateArgument *Args)
- : NumFlatArguments(NumArgs),
- NumStructuredArguments(NumArgs) {
-
- TemplateArgument *NewArgs = new (Context) TemplateArgument[NumArgs];
- std::copy(Args, Args+NumArgs, NewArgs);
- FlatArguments.setPointer(NewArgs);
- FlatArguments.setInt(1); // Owns the pointer.
-
- // Just reuse the flat arguments array.
- StructuredArguments.setPointer(NewArgs);
- StructuredArguments.setInt(0); // Doesn't own the pointer.
+ const TemplateArgument *Args,
+ unsigned NumArgs) {
+ init(Context, Args, NumArgs);
}
/// Produces a shallow copy of the given template argument list. This
@@ -417,6 +407,23 @@ TemplateArgumentList::TemplateArgumentList(const TemplateArgumentList *Other)
StructuredArguments(Other->StructuredArguments.getPointer(), false),
NumStructuredArguments(Other->NumStructuredArguments) { }
+void TemplateArgumentList::init(ASTContext &Context,
+ const TemplateArgument *Args,
+ unsigned NumArgs) {
+assert(NumFlatArguments == 0 && NumStructuredArguments == 0 &&
+ "Already initialized!");
+
+NumFlatArguments = NumStructuredArguments = NumArgs;
+TemplateArgument *NewArgs = new (Context) TemplateArgument[NumArgs];
+std::copy(Args, Args+NumArgs, NewArgs);
+FlatArguments.setPointer(NewArgs);
+FlatArguments.setInt(1); // Owns the pointer.
+
+// Just reuse the flat arguments array.
+StructuredArguments.setPointer(NewArgs);
+StructuredArguments.setInt(0); // Doesn't own the pointer.
+}
+
void TemplateArgumentList::Destroy(ASTContext &C) {
if (FlatArguments.getInt())
C.Deallocate((void*)FlatArguments.getPointer());
@@ -444,6 +451,12 @@ ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
SpecializationKind(TSK_Undeclared) {
}
+ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(Kind DK)
+ : CXXRecordDecl(DK, TTK_Struct, 0, SourceLocation(), 0, 0),
+ ExplicitInfo(0),
+ SpecializationKind(TSK_Undeclared) {
+}
+
ClassTemplateSpecializationDecl *
ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK,
DeclContext *DC, SourceLocation L,
@@ -461,6 +474,12 @@ ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK,
return Result;
}
+ClassTemplateSpecializationDecl *
+ClassTemplateSpecializationDecl::CreateEmpty(ASTContext &Context) {
+ return
+ new (Context)ClassTemplateSpecializationDecl(ClassTemplateSpecialization);
+}
+
void ClassTemplateSpecializationDecl::Destroy(ASTContext &C) {
delete ExplicitInfo;
@@ -524,6 +543,24 @@ Create(ASTContext &Context, TagKind TK,DeclContext *DC, SourceLocation L,
return Result;
}
+ClassTemplatePartialSpecializationDecl *
+ClassTemplatePartialSpecializationDecl::CreateEmpty(ASTContext &Context) {
+ return new (Context)ClassTemplatePartialSpecializationDecl();
+}
+
+void ClassTemplatePartialSpecializationDecl::
+initTemplateArgsAsWritten(const TemplateArgumentListInfo &ArgInfos) {
+ assert(ArgsAsWritten == 0 && "ArgsAsWritten already set");
+ unsigned N = ArgInfos.size();
+ TemplateArgumentLoc *ClonedArgs
+ = new (getASTContext()) TemplateArgumentLoc[N];
+ for (unsigned I = 0; I != N; ++I)
+ ClonedArgs[I] = ArgInfos[I];
+
+ ArgsAsWritten = ClonedArgs;
+ NumArgsAsWritten = N;
+}
+
//===----------------------------------------------------------------------===//
// FriendTemplateDecl Implementation
//===----------------------------------------------------------------------===//