summaryrefslogtreecommitdiffstats
path: root/lib/AST/DeclTemplate.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/AST/DeclTemplate.cpp')
-rw-r--r--lib/AST/DeclTemplate.cpp126
1 files changed, 75 insertions, 51 deletions
diff --git a/lib/AST/DeclTemplate.cpp b/lib/AST/DeclTemplate.cpp
index 23c2637..165672d 100644
--- a/lib/AST/DeclTemplate.cpp
+++ b/lib/AST/DeclTemplate.cpp
@@ -239,79 +239,103 @@ TemplateArgument::TemplateArgument(Expr *E) : Kind(Expression) {
}
/// \brief Construct a template argument pack.
-TemplateArgument::TemplateArgument(SourceLocation Loc, TemplateArgument *args,
- unsigned NumArgs, bool CopyArgs)
- : Kind(Pack) {
- Args.NumArgs = NumArgs;
- Args.CopyArgs = CopyArgs;
- if (!Args.CopyArgs) {
- Args.Args = args;
- return;
- }
-
- Args.Args = new TemplateArgument[NumArgs];
- for (unsigned I = 0; I != NumArgs; ++I)
- Args.Args[I] = args[I];
+void TemplateArgument::setArgumentPack(TemplateArgument *args, unsigned NumArgs,
+ bool CopyArgs) {
+ assert(isNull() && "Must call setArgumentPack on a null argument");
+
+ Kind = Pack;
+ Args.NumArgs = NumArgs;
+ Args.CopyArgs = CopyArgs;
+ if (!Args.CopyArgs) {
+ Args.Args = args;
+ return;
+ }
+
+ Args.Args = new TemplateArgument[NumArgs];
+ for (unsigned I = 0; I != Args.NumArgs; ++I)
+ Args.Args[I] = args[I];
}
//===----------------------------------------------------------------------===//
// TemplateArgumentListBuilder Implementation
//===----------------------------------------------------------------------===//
-void TemplateArgumentListBuilder::push_back(const TemplateArgument& Arg) {
+
+void TemplateArgumentListBuilder::Append(const TemplateArgument& Arg) {
switch (Arg.getKind()) {
- default: break;
- case TemplateArgument::Type:
- assert(Arg.getAsType()->isCanonical() && "Type must be canonical!");
- break;
+ default: break;
+ case TemplateArgument::Type:
+ assert(Arg.getAsType()->isCanonical() && "Type must be canonical!");
+ break;
}
- FlatArgs.push_back(Arg);
+ assert(NumFlatArgs < MaxFlatArgs && "Argument list builder is full!");
+ assert(!StructuredArgs &&
+ "Can't append arguments when an argument pack has been added!");
+
+ if (!FlatArgs)
+ FlatArgs = new TemplateArgument[MaxFlatArgs];
- if (!isAddingFromParameterPack())
- StructuredArgs.push_back(Arg);
+ FlatArgs[NumFlatArgs++] = Arg;
}
-void TemplateArgumentListBuilder::BeginParameterPack() {
- assert(!isAddingFromParameterPack() && "Already adding to parameter pack!");
-
- PackBeginIndex = FlatArgs.size();
+void TemplateArgumentListBuilder::BeginPack() {
+ assert(!AddingToPack && "Already adding to pack!");
+ assert(!StructuredArgs && "Argument list already contains a pack!");
+
+ AddingToPack = true;
+ PackBeginIndex = NumFlatArgs;
}
-void TemplateArgumentListBuilder::EndParameterPack() {
- assert(isAddingFromParameterPack() && "Not adding to parameter pack!");
+void TemplateArgumentListBuilder::EndPack() {
+ assert(AddingToPack && "Not adding to pack!");
+ assert(!StructuredArgs && "Argument list already contains a pack!");
+
+ AddingToPack = false;
- unsigned NumArgs = FlatArgs.size() - PackBeginIndex;
- TemplateArgument *Args = NumArgs ? &FlatArgs[PackBeginIndex] : 0;
+ StructuredArgs = new TemplateArgument[MaxStructuredArgs];
+
+ // First copy the flat entries over to the list (if any)
+ for (unsigned I = 0; I != PackBeginIndex; ++I) {
+ NumStructuredArgs++;
+ StructuredArgs[I] = FlatArgs[I];
+ }
- StructuredArgs.push_back(TemplateArgument(SourceLocation(), Args, NumArgs,
- /*CopyArgs=*/false));
+ // Next, set the pack.
+ TemplateArgument *PackArgs = 0;
+ unsigned NumPackArgs = NumFlatArgs - PackBeginIndex;
+ if (NumPackArgs)
+ PackArgs = &FlatArgs[PackBeginIndex];
- PackBeginIndex = std::numeric_limits<unsigned>::max();
-}
+ StructuredArgs[NumStructuredArgs++].setArgumentPack(PackArgs, NumPackArgs,
+ /*CopyArgs=*/false);
+}
+
+void TemplateArgumentListBuilder::ReleaseArgs() {
+ FlatArgs = 0;
+ NumFlatArgs = 0;
+ MaxFlatArgs = 0;
+ StructuredArgs = 0;
+ NumStructuredArgs = 0;
+ MaxStructuredArgs = 0;
+}
//===----------------------------------------------------------------------===//
// TemplateArgumentList Implementation
//===----------------------------------------------------------------------===//
TemplateArgumentList::TemplateArgumentList(ASTContext &Context,
TemplateArgumentListBuilder &Builder,
- bool CopyArgs, bool FlattenArgs)
- : NumArguments(Builder.flatSize()) {
- if (!CopyArgs) {
- Arguments.setPointer(Builder.getFlatArgumentList());
- Arguments.setInt(1);
- return;
- }
-
+ bool TakeArgs)
+ : FlatArguments(Builder.getFlatArguments(), TakeArgs),
+ NumFlatArguments(Builder.flatSize()),
+ StructuredArguments(Builder.getStructuredArguments(), TakeArgs),
+ NumStructuredArguments(Builder.structuredSize()) {
- unsigned Size = sizeof(TemplateArgument) * Builder.flatSize();
- unsigned Align = llvm::AlignOf<TemplateArgument>::Alignment;
- void *Mem = Context.Allocate(Size, Align);
- Arguments.setPointer((TemplateArgument *)Mem);
- Arguments.setInt(0);
-
- TemplateArgument *Args = (TemplateArgument *)Mem;
- for (unsigned I = 0; I != NumArguments; ++I)
- new (Args + I) TemplateArgument(Builder.getFlatArgumentList()[I]);
+ if (!TakeArgs)
+ return;
+
+ if (Builder.getStructuredArguments() == Builder.getFlatArguments())
+ StructuredArguments.setInt(0);
+ Builder.ReleaseArgs();
}
TemplateArgumentList::~TemplateArgumentList() {
@@ -333,7 +357,7 @@ ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK,
// class template specializations?
SpecializedTemplate->getIdentifier()),
SpecializedTemplate(SpecializedTemplate),
- TemplateArgs(Context, Builder, /*CopyArgs=*/true, /*FlattenArgs=*/true),
+ TemplateArgs(Context, Builder, /*TakeArgs=*/true),
SpecializationKind(TSK_Undeclared) {
}
OpenPOWER on IntegriCloud