forked from OSchip/llvm-project
Check in a new template argument list builder that should work better for variadic templates.
llvm-svn: 73937
This commit is contained in:
parent
e2170edfbb
commit
5947ddfb55
|
@ -469,10 +469,6 @@ public:
|
|||
/// occur in a non-dependent, canonical template argument list.
|
||||
TemplateArgument(Expr *E);
|
||||
|
||||
/// \brief Construct a template argument pack.
|
||||
TemplateArgument(SourceLocation Loc, TemplateArgument *Args,
|
||||
unsigned NumArgs, bool CopyArgs);
|
||||
|
||||
/// \brief Copy constructor for a template argument.
|
||||
TemplateArgument(const TemplateArgument &Other) : Kind(Other.Kind) {
|
||||
if (Kind == Integral) {
|
||||
|
@ -587,6 +583,9 @@ public:
|
|||
/// \brief Retrieve the location where the template argument starts.
|
||||
SourceLocation getLocation() const { return StartLoc; }
|
||||
|
||||
/// \brief Construct a template argument pack.
|
||||
void setArgumentPack(TemplateArgument *Args, unsigned NumArgs, bool CopyArgs);
|
||||
|
||||
/// \brief Used to insert TemplateArguments into FoldingSets.
|
||||
void Profile(llvm::FoldingSetNodeID &ID) const {
|
||||
ID.AddInteger(Kind);
|
||||
|
@ -622,47 +621,51 @@ public:
|
|||
|
||||
/// \brief A helper class for making template argument lists.
|
||||
class TemplateArgumentListBuilder {
|
||||
/// FlatArgs - contains the template arguments in flat form.
|
||||
llvm::SmallVector<TemplateArgument, 16> FlatArgs;
|
||||
TemplateArgument *StructuredArgs;
|
||||
unsigned MaxStructuredArgs;
|
||||
unsigned NumStructuredArgs;
|
||||
|
||||
llvm::SmallVector<TemplateArgument, 16> StructuredArgs;
|
||||
|
||||
ASTContext &Context;
|
||||
TemplateArgument *FlatArgs;
|
||||
unsigned MaxFlatArgs;
|
||||
unsigned NumFlatArgs;
|
||||
|
||||
bool AddingToPack;
|
||||
unsigned PackBeginIndex;
|
||||
|
||||
/// isAddingFromParameterPack - Returns whether we're adding arguments from
|
||||
/// a parameter pack.
|
||||
bool isAddingFromParameterPack() const {
|
||||
return PackBeginIndex != std::numeric_limits<unsigned>::max();
|
||||
}
|
||||
|
||||
public:
|
||||
TemplateArgumentListBuilder(ASTContext &Context) : Context(Context),
|
||||
PackBeginIndex(std::numeric_limits<unsigned>::max()) { }
|
||||
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) { }
|
||||
|
||||
size_t structuredSize() const {
|
||||
assert(!isAddingFromParameterPack() &&
|
||||
"Size is not valid when adding from a parameter pack");
|
||||
void Append(const TemplateArgument& Arg);
|
||||
void BeginPack();
|
||||
void EndPack();
|
||||
|
||||
return StructuredArgs.size();
|
||||
void ReleaseArgs();
|
||||
|
||||
unsigned flatSize() const {
|
||||
return NumFlatArgs;
|
||||
}
|
||||
const TemplateArgument *getFlatArguments() const {
|
||||
return FlatArgs;
|
||||
}
|
||||
|
||||
size_t flatSize() const { return FlatArgs.size(); }
|
||||
unsigned structuredSize() const {
|
||||
// If we don't have any structured args, just reuse the flat size.
|
||||
if (!StructuredArgs)
|
||||
return flatSize();
|
||||
|
||||
void push_back(const TemplateArgument& Arg);
|
||||
|
||||
/// BeginParameterPack - Start adding arguments from a parameter pack.
|
||||
void BeginParameterPack();
|
||||
|
||||
/// EndParameterPack - Finish adding arguments from a parameter pack.
|
||||
void EndParameterPack();
|
||||
|
||||
const TemplateArgument *getFlatArgumentList() const {
|
||||
return FlatArgs.data();
|
||||
return NumStructuredArgs;
|
||||
}
|
||||
TemplateArgument *getFlatArgumentList() {
|
||||
return FlatArgs.data();
|
||||
const TemplateArgument *getStructuredArguments() const {
|
||||
// If we don't have any structured args, just reuse the flat args.
|
||||
if (!StructuredArgs)
|
||||
return getFlatArguments();
|
||||
|
||||
return StructuredArgs;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -676,22 +679,25 @@ class TemplateArgumentList {
|
|||
///
|
||||
/// The integer value will be non-zero to indicate that this
|
||||
/// template argument list does not own the pointer.
|
||||
llvm::PointerIntPair<TemplateArgument *, 1> Arguments;
|
||||
llvm::PointerIntPair<const TemplateArgument *, 1> FlatArguments;
|
||||
|
||||
/// \brief The number of template arguments in this template
|
||||
/// argument list.
|
||||
unsigned NumArguments;
|
||||
unsigned NumFlatArguments;
|
||||
|
||||
llvm::PointerIntPair<const TemplateArgument *, 1> StructuredArguments;
|
||||
unsigned NumStructuredArguments;
|
||||
|
||||
public:
|
||||
TemplateArgumentList(ASTContext &Context,
|
||||
TemplateArgumentListBuilder &Builder,
|
||||
bool CopyArgs, bool FlattenArgs);
|
||||
bool TakeArgs);
|
||||
|
||||
~TemplateArgumentList();
|
||||
|
||||
/// \brief Retrieve the template argument at a given index.
|
||||
const TemplateArgument &get(unsigned Idx) const {
|
||||
assert(Idx < NumArguments && "Invalid template argument index");
|
||||
assert(Idx < NumFlatArguments && "Invalid template argument index");
|
||||
return getFlatArgumentList()[Idx];
|
||||
}
|
||||
|
||||
|
@ -700,15 +706,15 @@ public:
|
|||
|
||||
/// \brief Retrieve the number of template arguments in this
|
||||
/// template argument list.
|
||||
unsigned size() const { return NumArguments; }
|
||||
unsigned size() const { return NumFlatArguments; }
|
||||
|
||||
/// \brief Retrieve the number of template arguments in the
|
||||
/// flattened template argument list.
|
||||
unsigned flat_size() const { return NumArguments; }
|
||||
unsigned flat_size() const { return NumFlatArguments; }
|
||||
|
||||
/// \brief Retrieve the flattened template argument list.
|
||||
const TemplateArgument *getFlatArgumentList() const {
|
||||
return Arguments.getPointer();
|
||||
return FlatArguments.getPointer();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -239,9 +239,11 @@ TemplateArgument::TemplateArgument(Expr *E) : Kind(Expression) {
|
|||
}
|
||||
|
||||
/// \brief Construct a template argument pack.
|
||||
TemplateArgument::TemplateArgument(SourceLocation Loc, TemplateArgument *args,
|
||||
unsigned NumArgs, bool CopyArgs)
|
||||
: Kind(Pack) {
|
||||
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) {
|
||||
|
@ -250,14 +252,15 @@ TemplateArgument::TemplateArgument(SourceLocation Loc, TemplateArgument *args,
|
|||
}
|
||||
|
||||
Args.Args = new TemplateArgument[NumArgs];
|
||||
for (unsigned I = 0; I != NumArgs; ++I)
|
||||
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:
|
||||
|
@ -265,28 +268,55 @@ void TemplateArgumentListBuilder::push_back(const TemplateArgument& Arg) {
|
|||
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 (!isAddingFromParameterPack())
|
||||
StructuredArgs.push_back(Arg);
|
||||
if (!FlatArgs)
|
||||
FlatArgs = new TemplateArgument[MaxFlatArgs];
|
||||
|
||||
FlatArgs[NumFlatArgs++] = Arg;
|
||||
}
|
||||
|
||||
void TemplateArgumentListBuilder::BeginParameterPack() {
|
||||
assert(!isAddingFromParameterPack() && "Already adding to parameter pack!");
|
||||
void TemplateArgumentListBuilder::BeginPack() {
|
||||
assert(!AddingToPack && "Already adding to pack!");
|
||||
assert(!StructuredArgs && "Argument list already contains a pack!");
|
||||
|
||||
PackBeginIndex = FlatArgs.size();
|
||||
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!");
|
||||
|
||||
unsigned NumArgs = FlatArgs.size() - PackBeginIndex;
|
||||
TemplateArgument *Args = NumArgs ? &FlatArgs[PackBeginIndex] : 0;
|
||||
AddingToPack = false;
|
||||
|
||||
StructuredArgs.push_back(TemplateArgument(SourceLocation(), Args, NumArgs,
|
||||
/*CopyArgs=*/false));
|
||||
StructuredArgs = new TemplateArgument[MaxStructuredArgs];
|
||||
|
||||
PackBeginIndex = std::numeric_limits<unsigned>::max();
|
||||
// First copy the flat entries over to the list (if any)
|
||||
for (unsigned I = 0; I != PackBeginIndex; ++I) {
|
||||
NumStructuredArgs++;
|
||||
StructuredArgs[I] = FlatArgs[I];
|
||||
}
|
||||
|
||||
// Next, set the pack.
|
||||
TemplateArgument *PackArgs = 0;
|
||||
unsigned NumPackArgs = NumFlatArgs - PackBeginIndex;
|
||||
if (NumPackArgs)
|
||||
PackArgs = &FlatArgs[PackBeginIndex];
|
||||
|
||||
StructuredArgs[NumStructuredArgs++].setArgumentPack(PackArgs, NumPackArgs,
|
||||
/*CopyArgs=*/false);
|
||||
}
|
||||
|
||||
void TemplateArgumentListBuilder::ReleaseArgs() {
|
||||
FlatArgs = 0;
|
||||
NumFlatArgs = 0;
|
||||
MaxFlatArgs = 0;
|
||||
StructuredArgs = 0;
|
||||
NumStructuredArgs = 0;
|
||||
MaxStructuredArgs = 0;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -294,24 +324,18 @@ void TemplateArgumentListBuilder::EndParameterPack() {
|
|||
//===----------------------------------------------------------------------===//
|
||||
TemplateArgumentList::TemplateArgumentList(ASTContext &Context,
|
||||
TemplateArgumentListBuilder &Builder,
|
||||
bool CopyArgs, bool FlattenArgs)
|
||||
: NumArguments(Builder.flatSize()) {
|
||||
if (!CopyArgs) {
|
||||
Arguments.setPointer(Builder.getFlatArgumentList());
|
||||
Arguments.setInt(1);
|
||||
bool TakeArgs)
|
||||
: FlatArguments(Builder.getFlatArguments(), TakeArgs),
|
||||
NumFlatArguments(Builder.flatSize()),
|
||||
StructuredArguments(Builder.getStructuredArguments(), TakeArgs),
|
||||
NumStructuredArguments(Builder.structuredSize()) {
|
||||
|
||||
if (!TakeArgs)
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
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 (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) {
|
||||
}
|
||||
|
||||
|
|
|
@ -847,13 +847,14 @@ QualType Sema::CheckTemplateIdType(TemplateName Name,
|
|||
|
||||
// Check that the template argument list is well-formed for this
|
||||
// template.
|
||||
TemplateArgumentListBuilder ConvertedTemplateArgs(Context);
|
||||
TemplateArgumentListBuilder Converted(Template->getTemplateParameters(),
|
||||
NumTemplateArgs);
|
||||
if (CheckTemplateArgumentList(Template, TemplateLoc, LAngleLoc,
|
||||
TemplateArgs, NumTemplateArgs, RAngleLoc,
|
||||
ConvertedTemplateArgs))
|
||||
Converted))
|
||||
return QualType();
|
||||
|
||||
assert((ConvertedTemplateArgs.structuredSize() ==
|
||||
assert((Converted.structuredSize() ==
|
||||
Template->getTemplateParameters()->size()) &&
|
||||
"Converted template argument list is too short!");
|
||||
|
||||
|
@ -871,16 +872,16 @@ QualType Sema::CheckTemplateIdType(TemplateName Name,
|
|||
// template<typename T, typename U = T> struct A;
|
||||
TemplateName CanonName = Context.getCanonicalTemplateName(Name);
|
||||
CanonType = Context.getTemplateSpecializationType(CanonName,
|
||||
ConvertedTemplateArgs.getFlatArgumentList(),
|
||||
ConvertedTemplateArgs.flatSize());
|
||||
Converted.getFlatArguments(),
|
||||
Converted.flatSize());
|
||||
} else if (ClassTemplateDecl *ClassTemplate
|
||||
= dyn_cast<ClassTemplateDecl>(Template)) {
|
||||
// Find the class template specialization declaration that
|
||||
// corresponds to these arguments.
|
||||
llvm::FoldingSetNodeID ID;
|
||||
ClassTemplateSpecializationDecl::Profile(ID,
|
||||
ConvertedTemplateArgs.getFlatArgumentList(),
|
||||
ConvertedTemplateArgs.flatSize());
|
||||
Converted.getFlatArguments(),
|
||||
Converted.flatSize());
|
||||
void *InsertPos = 0;
|
||||
ClassTemplateSpecializationDecl *Decl
|
||||
= ClassTemplate->getSpecializations().FindNodeOrInsertPos(ID, InsertPos);
|
||||
|
@ -892,7 +893,7 @@ QualType Sema::CheckTemplateIdType(TemplateName Name,
|
|||
ClassTemplate->getDeclContext(),
|
||||
TemplateLoc,
|
||||
ClassTemplate,
|
||||
ConvertedTemplateArgs, 0);
|
||||
Converted, 0);
|
||||
ClassTemplate->getSpecializations().InsertNode(Decl, InsertPos);
|
||||
Decl->setLexicalDeclContext(CurContext);
|
||||
}
|
||||
|
@ -1003,7 +1004,7 @@ bool Sema::CheckTemplateTypeArgument(TemplateTypeParmDecl *Param,
|
|||
return true;
|
||||
|
||||
// Add the converted template type argument.
|
||||
Converted.push_back(
|
||||
Converted.Append(
|
||||
TemplateArgument(Arg.getLocation(),
|
||||
Context.getCanonicalType(Arg.getAsType())));
|
||||
return false;
|
||||
|
@ -1061,9 +1062,9 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template,
|
|||
// parameter.
|
||||
if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*Param)) {
|
||||
if (TTP->isParameterPack()) {
|
||||
// We have an empty parameter pack.
|
||||
Converted.BeginParameterPack();
|
||||
Converted.EndParameterPack();
|
||||
// We have an empty argument pack.
|
||||
Converted.BeginPack();
|
||||
Converted.EndPack();
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1076,13 +1077,12 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template,
|
|||
// on the previously-computed template arguments.
|
||||
if (ArgType->isDependentType()) {
|
||||
InstantiatingTemplate Inst(*this, TemplateLoc,
|
||||
Template, Converted.getFlatArgumentList(),
|
||||
Template, Converted.getFlatArguments(),
|
||||
Converted.flatSize(),
|
||||
SourceRange(TemplateLoc, RAngleLoc));
|
||||
|
||||
TemplateArgumentList TemplateArgs(Context, Converted,
|
||||
/*CopyArgs=*/false,
|
||||
/*FlattenArgs=*/false);
|
||||
/*TakeArgs=*/false);
|
||||
ArgType = InstantiateType(ArgType, TemplateArgs,
|
||||
TTP->getDefaultArgumentLoc(),
|
||||
TTP->getDeclName());
|
||||
|
@ -1098,13 +1098,12 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template,
|
|||
break;
|
||||
|
||||
InstantiatingTemplate Inst(*this, TemplateLoc,
|
||||
Template, Converted.getFlatArgumentList(),
|
||||
Template, Converted.getFlatArguments(),
|
||||
Converted.flatSize(),
|
||||
SourceRange(TemplateLoc, RAngleLoc));
|
||||
|
||||
TemplateArgumentList TemplateArgs(Context, Converted,
|
||||
/*CopyArgs=*/false,
|
||||
/*FlattenArgs=*/false);
|
||||
/*TakeArgs=*/false);
|
||||
|
||||
Sema::OwningExprResult E = InstantiateExpr(NTTP->getDefaultArgument(),
|
||||
TemplateArgs);
|
||||
|
@ -1130,14 +1129,14 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template,
|
|||
|
||||
if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*Param)) {
|
||||
if (TTP->isParameterPack()) {
|
||||
Converted.BeginParameterPack();
|
||||
Converted.BeginPack();
|
||||
// Check all the remaining arguments (if any).
|
||||
for (; ArgIdx < NumArgs; ++ArgIdx) {
|
||||
if (CheckTemplateTypeArgument(TTP, TemplateArgs[ArgIdx], Converted))
|
||||
Invalid = true;
|
||||
}
|
||||
|
||||
Converted.EndParameterPack();
|
||||
Converted.EndPack();
|
||||
} else {
|
||||
if (CheckTemplateTypeArgument(TTP, Arg, Converted))
|
||||
Invalid = true;
|
||||
|
@ -1152,13 +1151,12 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template,
|
|||
if (NTTPType->isDependentType()) {
|
||||
// Instantiate the type of the non-type template parameter.
|
||||
InstantiatingTemplate Inst(*this, TemplateLoc,
|
||||
Template, Converted.getFlatArgumentList(),
|
||||
Template, Converted.getFlatArguments(),
|
||||
Converted.flatSize(),
|
||||
SourceRange(TemplateLoc, RAngleLoc));
|
||||
|
||||
TemplateArgumentList TemplateArgs(Context, Converted,
|
||||
/*CopyArgs=*/false,
|
||||
/*FlattenArgs=*/false);
|
||||
/*TakeArgs=*/false);
|
||||
NTTPType = InstantiateType(NTTPType, TemplateArgs,
|
||||
NTTP->getLocation(),
|
||||
NTTP->getDeclName());
|
||||
|
@ -1167,7 +1165,6 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template,
|
|||
if (!NTTPType.isNull())
|
||||
NTTPType = CheckNonTypeTemplateParameterType(NTTPType,
|
||||
NTTP->getLocation());
|
||||
|
||||
if (NTTPType.isNull()) {
|
||||
Invalid = true;
|
||||
break;
|
||||
|
@ -1185,7 +1182,7 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template,
|
|||
if (CheckTemplateArgument(NTTP, NTTPType, E, Result))
|
||||
Invalid = true;
|
||||
else
|
||||
Converted.push_back(Result);
|
||||
Converted.Append(Result);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1193,7 +1190,7 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template,
|
|||
case TemplateArgument::Integral:
|
||||
// We've already checked this template argument, so just copy
|
||||
// it to the list of converted arguments.
|
||||
Converted.push_back(Arg);
|
||||
Converted.Append(Arg);
|
||||
break;
|
||||
|
||||
case TemplateArgument::Type:
|
||||
|
@ -1240,7 +1237,7 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template,
|
|||
// Add the converted template argument.
|
||||
Decl *D
|
||||
= Context.getCanonicalDecl(cast<DeclRefExpr>(ArgExpr)->getDecl());
|
||||
Converted.push_back(TemplateArgument(Arg.getLocation(), D));
|
||||
Converted.Append(TemplateArgument(Arg.getLocation(), D));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -1257,7 +1254,7 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template,
|
|||
case TemplateArgument::Declaration:
|
||||
// We've already checked this template argument, so just copy
|
||||
// it to the list of converted arguments.
|
||||
Converted.push_back(Arg);
|
||||
Converted.Append(Arg);
|
||||
break;
|
||||
|
||||
case TemplateArgument::Integral:
|
||||
|
@ -2102,7 +2099,7 @@ bool Sema::CheckClassTemplatePartialSpecializationArgs(
|
|||
// accommodate variadic templates.
|
||||
MirrorsPrimaryTemplate = true;
|
||||
|
||||
const TemplateArgument *ArgList = TemplateArgs.getFlatArgumentList();
|
||||
const TemplateArgument *ArgList = TemplateArgs.getFlatArguments();
|
||||
|
||||
for (unsigned I = 0, N = TemplateParams->size(); I != N; ++I) {
|
||||
// Determine whether the template argument list of the partial
|
||||
|
@ -2298,13 +2295,14 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TagKind TK,
|
|||
|
||||
// Check that the template argument list is well-formed for this
|
||||
// template.
|
||||
TemplateArgumentListBuilder ConvertedTemplateArgs(Context);
|
||||
TemplateArgumentListBuilder Converted(ClassTemplate->getTemplateParameters(),
|
||||
TemplateArgs.size());
|
||||
if (CheckTemplateArgumentList(ClassTemplate, TemplateNameLoc, LAngleLoc,
|
||||
TemplateArgs.data(), TemplateArgs.size(),
|
||||
RAngleLoc, ConvertedTemplateArgs))
|
||||
RAngleLoc, Converted))
|
||||
return true;
|
||||
|
||||
assert((ConvertedTemplateArgs.structuredSize() ==
|
||||
assert((Converted.structuredSize() ==
|
||||
ClassTemplate->getTemplateParameters()->size()) &&
|
||||
"Converted template argument list is too short!");
|
||||
|
||||
|
@ -2315,8 +2313,7 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TagKind TK,
|
|||
bool MirrorsPrimaryTemplate;
|
||||
if (CheckClassTemplatePartialSpecializationArgs(
|
||||
ClassTemplate->getTemplateParameters(),
|
||||
ConvertedTemplateArgs,
|
||||
MirrorsPrimaryTemplate))
|
||||
Converted, MirrorsPrimaryTemplate))
|
||||
return true;
|
||||
|
||||
if (MirrorsPrimaryTemplate) {
|
||||
|
@ -2338,13 +2335,13 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TagKind TK,
|
|||
|
||||
// FIXME: Template parameter list matters, too
|
||||
ClassTemplatePartialSpecializationDecl::Profile(ID,
|
||||
ConvertedTemplateArgs.getFlatArgumentList(),
|
||||
ConvertedTemplateArgs.flatSize());
|
||||
Converted.getFlatArguments(),
|
||||
Converted.flatSize());
|
||||
}
|
||||
else
|
||||
ClassTemplateSpecializationDecl::Profile(ID,
|
||||
ConvertedTemplateArgs.getFlatArgumentList(),
|
||||
ConvertedTemplateArgs.flatSize());
|
||||
Converted.getFlatArguments(),
|
||||
Converted.flatSize());
|
||||
void *InsertPos = 0;
|
||||
ClassTemplateSpecializationDecl *PrevDecl = 0;
|
||||
|
||||
|
@ -2387,7 +2384,7 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TagKind TK,
|
|||
TemplateNameLoc,
|
||||
TemplateParams,
|
||||
ClassTemplate,
|
||||
ConvertedTemplateArgs,
|
||||
Converted,
|
||||
PrevPartial);
|
||||
|
||||
if (PrevPartial) {
|
||||
|
@ -2437,7 +2434,7 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TagKind TK,
|
|||
ClassTemplate->getDeclContext(),
|
||||
TemplateNameLoc,
|
||||
ClassTemplate,
|
||||
ConvertedTemplateArgs,
|
||||
Converted,
|
||||
PrevDecl);
|
||||
|
||||
if (PrevDecl) {
|
||||
|
@ -2559,13 +2556,14 @@ Sema::ActOnExplicitInstantiation(Scope *S, SourceLocation TemplateLoc,
|
|||
|
||||
// Check that the template argument list is well-formed for this
|
||||
// template.
|
||||
TemplateArgumentListBuilder ConvertedTemplateArgs(Context);
|
||||
TemplateArgumentListBuilder Converted(ClassTemplate->getTemplateParameters(),
|
||||
TemplateArgs.size());
|
||||
if (CheckTemplateArgumentList(ClassTemplate, TemplateNameLoc, LAngleLoc,
|
||||
TemplateArgs.data(), TemplateArgs.size(),
|
||||
RAngleLoc, ConvertedTemplateArgs))
|
||||
RAngleLoc, Converted))
|
||||
return true;
|
||||
|
||||
assert((ConvertedTemplateArgs.structuredSize() ==
|
||||
assert((Converted.structuredSize() ==
|
||||
ClassTemplate->getTemplateParameters()->size()) &&
|
||||
"Converted template argument list is too short!");
|
||||
|
||||
|
@ -2573,8 +2571,8 @@ Sema::ActOnExplicitInstantiation(Scope *S, SourceLocation TemplateLoc,
|
|||
// corresponds to these arguments.
|
||||
llvm::FoldingSetNodeID ID;
|
||||
ClassTemplateSpecializationDecl::Profile(ID,
|
||||
ConvertedTemplateArgs.getFlatArgumentList(),
|
||||
ConvertedTemplateArgs.flatSize());
|
||||
Converted.getFlatArguments(),
|
||||
Converted.flatSize());
|
||||
void *InsertPos = 0;
|
||||
ClassTemplateSpecializationDecl *PrevDecl
|
||||
= ClassTemplate->getSpecializations().FindNodeOrInsertPos(ID, InsertPos);
|
||||
|
@ -2617,7 +2615,7 @@ Sema::ActOnExplicitInstantiation(Scope *S, SourceLocation TemplateLoc,
|
|||
ClassTemplate->getDeclContext(),
|
||||
TemplateNameLoc,
|
||||
ClassTemplate,
|
||||
ConvertedTemplateArgs, 0);
|
||||
Converted, 0);
|
||||
Specialization->setLexicalDeclContext(CurContext);
|
||||
CurContext->addDecl(Context, Specialization);
|
||||
return DeclPtrTy::make(Specialization);
|
||||
|
@ -2643,7 +2641,7 @@ Sema::ActOnExplicitInstantiation(Scope *S, SourceLocation TemplateLoc,
|
|||
ClassTemplate->getDeclContext(),
|
||||
TemplateNameLoc,
|
||||
ClassTemplate,
|
||||
ConvertedTemplateArgs, 0);
|
||||
Converted, 0);
|
||||
|
||||
ClassTemplate->getSpecializations().InsertNode(Specialization,
|
||||
InsertPos);
|
||||
|
|
|
@ -654,7 +654,8 @@ Sema::DeduceTemplateArguments(ClassTemplatePartialSpecializationDecl *Partial,
|
|||
// C++ [temp.deduct.type]p2:
|
||||
// [...] or if any template argument remains neither deduced nor
|
||||
// explicitly specified, template argument deduction fails.
|
||||
TemplateArgumentListBuilder Builder(Context);
|
||||
TemplateArgumentListBuilder Builder(Partial->getTemplateParameters(),
|
||||
Deduced.size());
|
||||
for (unsigned I = 0, N = Deduced.size(); I != N; ++I) {
|
||||
if (Deduced[I].isNull()) {
|
||||
Decl *Param
|
||||
|
@ -669,13 +670,12 @@ Sema::DeduceTemplateArguments(ClassTemplatePartialSpecializationDecl *Partial,
|
|||
return TDK_Incomplete;
|
||||
}
|
||||
|
||||
Builder.push_back(Deduced[I]);
|
||||
Builder.Append(Deduced[I]);
|
||||
}
|
||||
|
||||
// Form the template argument list from the deduced template arguments.
|
||||
TemplateArgumentList *DeducedArgumentList
|
||||
= new (Context) TemplateArgumentList(Context, Builder, /*CopyArgs=*/true,
|
||||
/*FlattenArgs=*/true);
|
||||
= new (Context) TemplateArgumentList(Context, Builder, /*TakeArgs=*/true);
|
||||
Info.reset(DeducedArgumentList);
|
||||
|
||||
// Substitute the deduced template arguments into the template
|
||||
|
|
Loading…
Reference in New Issue