Encapsulate template arguments lists in a new class,

TemplateArgumentList. This avoids the need to pass around
pointer/length pairs of template arguments lists, and will eventually
make it easier to introduce member templates and variadic templates.

llvm-svn: 71517
This commit is contained in:
Douglas Gregor 2009-05-11 23:53:27 +00:00
parent 5fb7847fbf
commit d002c7bc58
9 changed files with 177 additions and 143 deletions

View File

@ -554,6 +554,64 @@ public:
} }
}; };
/// \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 not own the pointer.
llvm::PointerIntPair<TemplateArgument *, 1> Arguments;
/// \brief The number of template arguments in this template
/// argument list.
unsigned NumArguments;
public:
TemplateArgumentList(ASTContext &Context,
TemplateArgument *TemplateArgs,
unsigned NumTemplateArgs,
bool CopyArgs);
~TemplateArgumentList();
/// \brief Retrieve the template argument at a given index.
const TemplateArgument &get(unsigned Idx) const {
assert(Idx < NumArguments && "Invalid template argument index");
return getFlatArgumentList()[Idx];
}
/// \brief Retrieve the template argument at a given index.
TemplateArgument &get(unsigned Idx) {
assert(Idx < NumArguments && "Invalid template argument index");
return getFlatArgumentList()[Idx];
}
/// \brief Retrieve the template argument at a given index.
TemplateArgument &operator[](unsigned Idx) { return get(Idx); }
const TemplateArgument &operator[](unsigned Idx) const { return get(Idx); }
/// \brief Retrieve the number of template arguments in this
/// template argument list.
unsigned size() const { return NumArguments; }
/// \brief Retrieve the number of template arguments in the
/// flattened template argument list.
unsigned flat_size() const { return NumArguments; }
/// \brief Retrieve the flattened template argument list.
TemplateArgument *getFlatArgumentList() {
return Arguments.getPointer();
}
const TemplateArgument *getFlatArgumentList() const {
return Arguments.getPointer();
}
};
// \brief Describes the kind of template specialization that a // \brief Describes the kind of template specialization that a
// particular template specialization declaration represents. // particular template specialization declaration represents.
enum TemplateSpecializationKind { enum TemplateSpecializationKind {
@ -589,15 +647,15 @@ class ClassTemplateSpecializationDecl
/// \brief The template that this specialization specializes /// \brief The template that this specialization specializes
ClassTemplateDecl *SpecializedTemplate; ClassTemplateDecl *SpecializedTemplate;
/// \brief The number of template arguments. The actual arguments /// \brief The template arguments used to describe this specialization.
/// are allocated after the ClassTemplateSpecializationDecl object. TemplateArgumentList TemplateArgs;
unsigned NumTemplateArgs : 16;
/// \brief The kind of specialization this declaration refers to. /// \brief The kind of specialization this declaration refers to.
/// Really a value of type TemplateSpecializationKind. /// Really a value of type TemplateSpecializationKind.
unsigned SpecializationKind : 2; unsigned SpecializationKind : 2;
ClassTemplateSpecializationDecl(DeclContext *DC, SourceLocation L, ClassTemplateSpecializationDecl(ASTContext &Context,
DeclContext *DC, SourceLocation L,
ClassTemplateDecl *SpecializedTemplate, ClassTemplateDecl *SpecializedTemplate,
TemplateArgument *TemplateArgs, TemplateArgument *TemplateArgs,
unsigned NumTemplateArgs); unsigned NumTemplateArgs);
@ -614,21 +672,10 @@ public:
return SpecializedTemplate; return SpecializedTemplate;
} }
typedef const TemplateArgument * template_arg_iterator; const TemplateArgumentList &getTemplateArgs() const {
template_arg_iterator template_arg_begin() const { return TemplateArgs;
return reinterpret_cast<template_arg_iterator>(this + 1);
} }
template_arg_iterator template_arg_end() const {
return template_arg_begin() + NumTemplateArgs;
}
const TemplateArgument *getTemplateArgs() const {
return template_arg_begin();
}
unsigned getNumTemplateArgs() const { return NumTemplateArgs; }
/// \brief Determine the kind of specialization that this /// \brief Determine the kind of specialization that this
/// declaration represents. /// declaration represents.
TemplateSpecializationKind getSpecializationKind() const { TemplateSpecializationKind getSpecializationKind() const {
@ -640,7 +687,7 @@ public:
} }
void Profile(llvm::FoldingSetNodeID &ID) const { void Profile(llvm::FoldingSetNodeID &ID) const {
Profile(ID, template_arg_begin(), getNumTemplateArgs()); Profile(ID, TemplateArgs.getFlatArgumentList(), TemplateArgs.flat_size());
} }
/// \brief Sets the type of this specialization as it was written by /// \brief Sets the type of this specialization as it was written by

View File

@ -235,11 +235,41 @@ TemplateArgument::TemplateArgument(Expr *E) : Kind(Expression) {
StartLoc = E->getSourceRange().getBegin(); StartLoc = E->getSourceRange().getBegin();
} }
//===----------------------------------------------------------------------===//
// TemplateArgumentList Implementation
//===----------------------------------------------------------------------===//
TemplateArgumentList::TemplateArgumentList(ASTContext &Context,
TemplateArgument *TemplateArgs,
unsigned NumTemplateArgs,
bool CopyArgs)
: NumArguments(NumTemplateArgs) {
if (!CopyArgs) {
Arguments.setPointer(TemplateArgs);
Arguments.setInt(1);
return;
}
unsigned Size = sizeof(TemplateArgument) * NumTemplateArgs;
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 != NumTemplateArgs; ++I)
new (Args + I) TemplateArgument(TemplateArgs[I]);
}
TemplateArgumentList::~TemplateArgumentList() {
// FIXME: Deallocate template arguments
}
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// ClassTemplateSpecializationDecl Implementation // ClassTemplateSpecializationDecl Implementation
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
ClassTemplateSpecializationDecl:: ClassTemplateSpecializationDecl::
ClassTemplateSpecializationDecl(DeclContext *DC, SourceLocation L, ClassTemplateSpecializationDecl(ASTContext &Context,
DeclContext *DC, SourceLocation L,
ClassTemplateDecl *SpecializedTemplate, ClassTemplateDecl *SpecializedTemplate,
TemplateArgument *TemplateArgs, TemplateArgument *TemplateArgs,
unsigned NumTemplateArgs) unsigned NumTemplateArgs)
@ -250,10 +280,8 @@ ClassTemplateSpecializationDecl(DeclContext *DC, SourceLocation L,
// class template specializations? // class template specializations?
SpecializedTemplate->getIdentifier()), SpecializedTemplate->getIdentifier()),
SpecializedTemplate(SpecializedTemplate), SpecializedTemplate(SpecializedTemplate),
NumTemplateArgs(NumTemplateArgs), SpecializationKind(TSK_Undeclared) { TemplateArgs(Context, TemplateArgs, NumTemplateArgs, /*CopyArgs=*/true),
TemplateArgument *Arg = reinterpret_cast<TemplateArgument *>(this + 1); SpecializationKind(TSK_Undeclared) {
for (unsigned ArgIdx = 0; ArgIdx < NumTemplateArgs; ++ArgIdx, ++Arg)
new (Arg) TemplateArgument(TemplateArgs[ArgIdx]);
} }
ClassTemplateSpecializationDecl * ClassTemplateSpecializationDecl *
@ -263,13 +291,11 @@ ClassTemplateSpecializationDecl::Create(ASTContext &Context,
TemplateArgument *TemplateArgs, TemplateArgument *TemplateArgs,
unsigned NumTemplateArgs, unsigned NumTemplateArgs,
ClassTemplateSpecializationDecl *PrevDecl) { ClassTemplateSpecializationDecl *PrevDecl) {
unsigned Size = sizeof(ClassTemplateSpecializationDecl) +
sizeof(TemplateArgument) * NumTemplateArgs;
unsigned Align = llvm::AlignOf<ClassTemplateSpecializationDecl>::Alignment;
void *Mem = Context.Allocate(Size, Align);
ClassTemplateSpecializationDecl *Result ClassTemplateSpecializationDecl *Result
= new (Mem) ClassTemplateSpecializationDecl(DC, L, SpecializedTemplate, = new (Context)ClassTemplateSpecializationDecl(Context, DC, L,
TemplateArgs, NumTemplateArgs); SpecializedTemplate,
TemplateArgs,
NumTemplateArgs);
Context.getTypeDeclType(Result, PrevDecl); Context.getTypeDeclType(Result, PrevDecl);
return Result; return Result;
} }

View File

@ -1565,11 +1565,12 @@ void TagType::getAsStringInternal(std::string &InnerString,
// arguments. // arguments.
if (ClassTemplateSpecializationDecl *Spec if (ClassTemplateSpecializationDecl *Spec
= dyn_cast<ClassTemplateSpecializationDecl>(getDecl())) { = dyn_cast<ClassTemplateSpecializationDecl>(getDecl())) {
std::string TemplateArgs const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
std::string TemplateArgsStr
= TemplateSpecializationType::PrintTemplateArgumentList( = TemplateSpecializationType::PrintTemplateArgumentList(
Spec->getTemplateArgs(), TemplateArgs.getFlatArgumentList(),
Spec->getNumTemplateArgs()); TemplateArgs.flat_size());
InnerString = TemplateArgs + InnerString; InnerString = TemplateArgsStr + InnerString;
} }
if (Kind) { if (Kind) {
@ -1584,11 +1585,12 @@ void TagType::getAsStringInternal(std::string &InnerString,
MyPart = NS->getNameAsString(); MyPart = NS->getNameAsString();
} else if (ClassTemplateSpecializationDecl *Spec } else if (ClassTemplateSpecializationDecl *Spec
= dyn_cast<ClassTemplateSpecializationDecl>(DC)) { = dyn_cast<ClassTemplateSpecializationDecl>(DC)) {
std::string TemplateArgs const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
std::string TemplateArgsStr
= TemplateSpecializationType::PrintTemplateArgumentList( = TemplateSpecializationType::PrintTemplateArgumentList(
Spec->getTemplateArgs(), TemplateArgs.getFlatArgumentList(),
Spec->getNumTemplateArgs()); TemplateArgs.flat_size());
MyPart = Spec->getIdentifier()->getName() + TemplateArgs; MyPart = Spec->getIdentifier()->getName() + TemplateArgsStr;
} else if (TagDecl *Tag = dyn_cast<TagDecl>(DC)) { } else if (TagDecl *Tag = dyn_cast<TagDecl>(DC)) {
if (TypedefDecl *Typedef = Tag->getTypedefForAnonDecl()) if (TypedefDecl *Typedef = Tag->getTypedefForAnonDecl())
MyPart = Typedef->getIdentifier()->getName(); MyPart = Typedef->getIdentifier()->getName();

View File

@ -65,6 +65,7 @@ namespace clang {
class TypedefDecl; class TypedefDecl;
class TemplateDecl; class TemplateDecl;
class TemplateArgument; class TemplateArgument;
class TemplateArgumentList;
class TemplateParameterList; class TemplateParameterList;
class TemplateTemplateParmDecl; class TemplateTemplateParmDecl;
class ClassTemplateDecl; class ClassTemplateDecl;
@ -1974,7 +1975,7 @@ public:
uintptr_t Entity; uintptr_t Entity;
// \brief If this the instantiation of a default template // \brief If this the instantiation of a default template
// argument, the list of tempalte arguments. // argument, the list of template arguments.
const TemplateArgument *TemplateArgs; const TemplateArgument *TemplateArgs;
/// \brief The number of template arguments in TemplateArgs. /// \brief The number of template arguments in TemplateArgs.
@ -2074,29 +2075,24 @@ public:
void PrintInstantiationStack(); void PrintInstantiationStack();
QualType InstantiateType(QualType T, const TemplateArgument *TemplateArgs, QualType InstantiateType(QualType T, const TemplateArgumentList &TemplateArgs,
unsigned NumTemplateArgs,
SourceLocation Loc, DeclarationName Entity); SourceLocation Loc, DeclarationName Entity);
OwningExprResult InstantiateExpr(Expr *E, OwningExprResult InstantiateExpr(Expr *E,
const TemplateArgument *TemplateArgs, const TemplateArgumentList &TemplateArgs);
unsigned NumTemplateArgs);
Decl *InstantiateDecl(Decl *D, DeclContext *Owner, Decl *InstantiateDecl(Decl *D, DeclContext *Owner,
const TemplateArgument *TemplateArgs, const TemplateArgumentList &TemplateArgs);
unsigned NumTemplateArgs);
bool bool
InstantiateBaseSpecifiers(CXXRecordDecl *Instantiation, InstantiateBaseSpecifiers(CXXRecordDecl *Instantiation,
CXXRecordDecl *Pattern, CXXRecordDecl *Pattern,
const TemplateArgument *TemplateArgs, const TemplateArgumentList &TemplateArgs);
unsigned NumTemplateArgs);
bool bool
InstantiateClass(SourceLocation PointOfInstantiation, InstantiateClass(SourceLocation PointOfInstantiation,
CXXRecordDecl *Instantiation, CXXRecordDecl *Pattern, CXXRecordDecl *Instantiation, CXXRecordDecl *Pattern,
const TemplateArgument *TemplateArgs, const TemplateArgumentList &TemplateArgs);
unsigned NumTemplateArgs);
bool bool
InstantiateClassTemplateSpecialization( InstantiateClassTemplateSpecialization(
@ -2106,13 +2102,11 @@ public:
NestedNameSpecifier * NestedNameSpecifier *
InstantiateNestedNameSpecifier(NestedNameSpecifier *NNS, InstantiateNestedNameSpecifier(NestedNameSpecifier *NNS,
SourceRange Range, SourceRange Range,
const TemplateArgument *TemplateArgs, const TemplateArgumentList &TemplateArgs);
unsigned NumTemplateArgs);
TemplateName TemplateName
InstantiateTemplateName(TemplateName Name, SourceLocation Loc, InstantiateTemplateName(TemplateName Name, SourceLocation Loc,
const TemplateArgument *TemplateArgs, const TemplateArgumentList &TemplateArgs);
unsigned NumTemplateArgs);
// Simple function for cloning expressions. // Simple function for cloning expressions.
template<typename T> template<typename T>

View File

@ -993,7 +993,11 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template,
Template, &Converted[0], Template, &Converted[0],
Converted.size(), Converted.size(),
SourceRange(TemplateLoc, RAngleLoc)); SourceRange(TemplateLoc, RAngleLoc));
ArgType = InstantiateType(ArgType, &Converted[0], Converted.size(),
TemplateArgumentList TemplateArgs(Context, &Converted[0],
Converted.size(),
/*CopyArgs=*/false);
ArgType = InstantiateType(ArgType, TemplateArgs,
TTP->getDefaultArgumentLoc(), TTP->getDefaultArgumentLoc(),
TTP->getDeclName()); TTP->getDeclName());
} }
@ -1061,8 +1065,10 @@ bool Sema::CheckTemplateArgumentList(TemplateDecl *Template,
Converted.size(), Converted.size(),
SourceRange(TemplateLoc, RAngleLoc)); SourceRange(TemplateLoc, RAngleLoc));
NTTPType = InstantiateType(NTTPType, TemplateArgumentList TemplateArgs(Context, &Converted[0],
&Converted[0], Converted.size(), Converted.size(),
/*CopyArgs=*/false);
NTTPType = InstantiateType(NTTPType, TemplateArgs,
NTTP->getLocation(), NTTP->getLocation(),
NTTP->getDeclName()); NTTP->getDeclName());
// If that worked, check the non-type template parameter type // If that worked, check the non-type template parameter type

View File

@ -133,19 +133,17 @@ void Sema::PrintInstantiationStack() {
namespace { namespace {
class VISIBILITY_HIDDEN TemplateTypeInstantiator { class VISIBILITY_HIDDEN TemplateTypeInstantiator {
Sema &SemaRef; Sema &SemaRef;
const TemplateArgument *TemplateArgs; const TemplateArgumentList &TemplateArgs;
unsigned NumTemplateArgs;
SourceLocation Loc; SourceLocation Loc;
DeclarationName Entity; DeclarationName Entity;
public: public:
TemplateTypeInstantiator(Sema &SemaRef, TemplateTypeInstantiator(Sema &SemaRef,
const TemplateArgument *TemplateArgs, const TemplateArgumentList &TemplateArgs,
unsigned NumTemplateArgs,
SourceLocation Loc, SourceLocation Loc,
DeclarationName Entity) DeclarationName Entity)
: SemaRef(SemaRef), TemplateArgs(TemplateArgs), : SemaRef(SemaRef), TemplateArgs(TemplateArgs),
NumTemplateArgs(NumTemplateArgs), Loc(Loc), Entity(Entity) { } Loc(Loc), Entity(Entity) { }
QualType operator()(QualType T) const { return Instantiate(T); } QualType operator()(QualType T) const { return Instantiate(T); }
@ -298,7 +296,7 @@ InstantiateDependentSizedArrayType(const DependentSizedArrayType *T,
// Instantiate the size expression // Instantiate the size expression
Sema::OwningExprResult InstantiatedArraySize = Sema::OwningExprResult InstantiatedArraySize =
SemaRef.InstantiateExpr(ArraySize, TemplateArgs, NumTemplateArgs); SemaRef.InstantiateExpr(ArraySize, TemplateArgs);
if (InstantiatedArraySize.isInvalid()) if (InstantiatedArraySize.isInvalid())
return QualType(); return QualType();
@ -403,7 +401,6 @@ InstantiateTemplateTypeParmType(const TemplateTypeParmType *T,
if (T->getDepth() == 0) { if (T->getDepth() == 0) {
// Replace the template type parameter with its corresponding // Replace the template type parameter with its corresponding
// template argument. // template argument.
assert(T->getIndex() < NumTemplateArgs && "Wrong # of template args");
assert(TemplateArgs[T->getIndex()].getKind() == TemplateArgument::Type && assert(TemplateArgs[T->getIndex()].getKind() == TemplateArgument::Type &&
"Template argument kind mismatch"); "Template argument kind mismatch");
QualType Result = TemplateArgs[T->getIndex()].getAsType(); QualType Result = TemplateArgs[T->getIndex()].getAsType();
@ -443,7 +440,7 @@ InstantiateTemplateSpecializationType(
switch (Arg->getKind()) { switch (Arg->getKind()) {
case TemplateArgument::Type: { case TemplateArgument::Type: {
QualType T = SemaRef.InstantiateType(Arg->getAsType(), QualType T = SemaRef.InstantiateType(Arg->getAsType(),
TemplateArgs, NumTemplateArgs, TemplateArgs,
Arg->getLocation(), Arg->getLocation(),
DeclarationName()); DeclarationName());
if (T.isNull()) if (T.isNull())
@ -461,8 +458,7 @@ InstantiateTemplateSpecializationType(
case TemplateArgument::Expression: case TemplateArgument::Expression:
Sema::OwningExprResult E Sema::OwningExprResult E
= SemaRef.InstantiateExpr(Arg->getAsExpr(), TemplateArgs, = SemaRef.InstantiateExpr(Arg->getAsExpr(), TemplateArgs);
NumTemplateArgs);
if (E.isInvalid()) if (E.isInvalid())
return QualType(); return QualType();
InstantiatedTemplateArgs.push_back(E.takeAs<Expr>()); InstantiatedTemplateArgs.push_back(E.takeAs<Expr>());
@ -475,8 +471,7 @@ InstantiateTemplateSpecializationType(
TemplateName Name = SemaRef.InstantiateTemplateName(T->getTemplateName(), TemplateName Name = SemaRef.InstantiateTemplateName(T->getTemplateName(),
Loc, Loc,
TemplateArgs, TemplateArgs);
NumTemplateArgs);
return SemaRef.CheckTemplateIdType(Name, Loc, SourceLocation(), return SemaRef.CheckTemplateIdType(Name, Loc, SourceLocation(),
&InstantiatedTemplateArgs[0], &InstantiatedTemplateArgs[0],
@ -509,7 +504,7 @@ InstantiateTypenameType(const TypenameType *T, unsigned Quals) const {
NestedNameSpecifier *NNS NestedNameSpecifier *NNS
= SemaRef.InstantiateNestedNameSpecifier(T->getQualifier(), = SemaRef.InstantiateNestedNameSpecifier(T->getQualifier(),
SourceRange(Loc), SourceRange(Loc),
TemplateArgs, NumTemplateArgs); TemplateArgs);
if (!NNS) if (!NNS)
return QualType(); return QualType();
@ -571,9 +566,6 @@ QualType TemplateTypeInstantiator::Instantiate(QualType T) const {
/// \param TemplateArgs the template arguments that will be /// \param TemplateArgs the template arguments that will be
/// substituted for the top-level template parameters within T. /// substituted for the top-level template parameters within T.
/// ///
/// \param NumTemplateArgs the number of template arguments provided
/// by TemplateArgs.
///
/// \param Loc the location in the source code where this substitution /// \param Loc the location in the source code where this substitution
/// is being performed. It will typically be the location of the /// is being performed. It will typically be the location of the
/// declarator (if we're instantiating the type of some declaration) /// declarator (if we're instantiating the type of some declaration)
@ -589,8 +581,7 @@ QualType TemplateTypeInstantiator::Instantiate(QualType T) const {
/// \returns If the instantiation succeeds, the instantiated /// \returns If the instantiation succeeds, the instantiated
/// type. Otherwise, produces diagnostics and returns a NULL type. /// type. Otherwise, produces diagnostics and returns a NULL type.
QualType Sema::InstantiateType(QualType T, QualType Sema::InstantiateType(QualType T,
const TemplateArgument *TemplateArgs, const TemplateArgumentList &TemplateArgs,
unsigned NumTemplateArgs,
SourceLocation Loc, DeclarationName Entity) { SourceLocation Loc, DeclarationName Entity) {
assert(!ActiveTemplateInstantiations.empty() && assert(!ActiveTemplateInstantiations.empty() &&
"Cannot perform an instantiation without some context on the " "Cannot perform an instantiation without some context on the "
@ -600,8 +591,7 @@ QualType Sema::InstantiateType(QualType T,
if (!T->isDependentType()) if (!T->isDependentType())
return T; return T;
TemplateTypeInstantiator Instantiator(*this, TemplateArgs, NumTemplateArgs, TemplateTypeInstantiator Instantiator(*this, TemplateArgs, Loc, Entity);
Loc, Entity);
return Instantiator(T); return Instantiator(T);
} }
@ -614,8 +604,7 @@ QualType Sema::InstantiateType(QualType T,
bool bool
Sema::InstantiateBaseSpecifiers(CXXRecordDecl *Instantiation, Sema::InstantiateBaseSpecifiers(CXXRecordDecl *Instantiation,
CXXRecordDecl *Pattern, CXXRecordDecl *Pattern,
const TemplateArgument *TemplateArgs, const TemplateArgumentList &TemplateArgs) {
unsigned NumTemplateArgs) {
bool Invalid = false; bool Invalid = false;
llvm::SmallVector<CXXBaseSpecifier*, 8> InstantiatedBases; llvm::SmallVector<CXXBaseSpecifier*, 8> InstantiatedBases;
for (ClassTemplateSpecializationDecl::base_class_iterator for (ClassTemplateSpecializationDecl::base_class_iterator
@ -628,7 +617,7 @@ Sema::InstantiateBaseSpecifiers(CXXRecordDecl *Instantiation,
} }
QualType BaseType = InstantiateType(Base->getType(), QualType BaseType = InstantiateType(Base->getType(),
TemplateArgs, NumTemplateArgs, TemplateArgs,
Base->getSourceRange().getBegin(), Base->getSourceRange().getBegin(),
DeclarationName()); DeclarationName());
if (BaseType.isNull()) { if (BaseType.isNull()) {
@ -673,15 +662,11 @@ Sema::InstantiateBaseSpecifiers(CXXRecordDecl *Instantiation,
/// \param TemplateArgs The template arguments to be substituted into /// \param TemplateArgs The template arguments to be substituted into
/// the pattern. /// the pattern.
/// ///
/// \param NumTemplateArgs The number of templates arguments in
/// TemplateArgs.
///
/// \returns true if an error occurred, false otherwise. /// \returns true if an error occurred, false otherwise.
bool bool
Sema::InstantiateClass(SourceLocation PointOfInstantiation, Sema::InstantiateClass(SourceLocation PointOfInstantiation,
CXXRecordDecl *Instantiation, CXXRecordDecl *Pattern, CXXRecordDecl *Instantiation, CXXRecordDecl *Pattern,
const TemplateArgument *TemplateArgs, const TemplateArgumentList &TemplateArgs) {
unsigned NumTemplateArgs) {
bool Invalid = false; bool Invalid = false;
CXXRecordDecl *PatternDef CXXRecordDecl *PatternDef
@ -715,16 +700,14 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation,
Instantiation->startDefinition(); Instantiation->startDefinition();
// Instantiate the base class specifiers. // Instantiate the base class specifiers.
if (InstantiateBaseSpecifiers(Instantiation, Pattern, TemplateArgs, if (InstantiateBaseSpecifiers(Instantiation, Pattern, TemplateArgs))
NumTemplateArgs))
Invalid = true; Invalid = true;
llvm::SmallVector<DeclPtrTy, 32> Fields; llvm::SmallVector<DeclPtrTy, 32> Fields;
for (RecordDecl::decl_iterator Member = Pattern->decls_begin(Context), for (RecordDecl::decl_iterator Member = Pattern->decls_begin(Context),
MemberEnd = Pattern->decls_end(Context); MemberEnd = Pattern->decls_end(Context);
Member != MemberEnd; ++Member) { Member != MemberEnd; ++Member) {
Decl *NewMember = InstantiateDecl(*Member, Instantiation, Decl *NewMember = InstantiateDecl(*Member, Instantiation, TemplateArgs);
TemplateArgs, NumTemplateArgs);
if (NewMember) { if (NewMember) {
if (NewMember->isInvalidDecl()) if (NewMember->isInvalidDecl())
Invalid = true; Invalid = true;
@ -783,21 +766,18 @@ Sema::InstantiateClassTemplateSpecialization(
return InstantiateClass(ClassTemplateSpec->getLocation(), return InstantiateClass(ClassTemplateSpec->getLocation(),
ClassTemplateSpec, Pattern, ClassTemplateSpec, Pattern,
ClassTemplateSpec->getTemplateArgs(), ClassTemplateSpec->getTemplateArgs());
ClassTemplateSpec->getNumTemplateArgs());
} }
/// \brief Instantiate a nested-name-specifier. /// \brief Instantiate a nested-name-specifier.
NestedNameSpecifier * NestedNameSpecifier *
Sema::InstantiateNestedNameSpecifier(NestedNameSpecifier *NNS, Sema::InstantiateNestedNameSpecifier(NestedNameSpecifier *NNS,
SourceRange Range, SourceRange Range,
const TemplateArgument *TemplateArgs, const TemplateArgumentList &TemplateArgs) {
unsigned NumTemplateArgs) {
// Instantiate the prefix of this nested name specifier. // Instantiate the prefix of this nested name specifier.
NestedNameSpecifier *Prefix = NNS->getPrefix(); NestedNameSpecifier *Prefix = NNS->getPrefix();
if (Prefix) { if (Prefix) {
Prefix = InstantiateNestedNameSpecifier(Prefix, Range, TemplateArgs, Prefix = InstantiateNestedNameSpecifier(Prefix, Range, TemplateArgs);
NumTemplateArgs);
if (!Prefix) if (!Prefix)
return 0; return 0;
} }
@ -828,8 +808,7 @@ Sema::InstantiateNestedNameSpecifier(NestedNameSpecifier *NNS,
if (!T->isDependentType()) if (!T->isDependentType())
return NNS; return NNS;
T = InstantiateType(T, TemplateArgs, NumTemplateArgs, Range.getBegin(), T = InstantiateType(T, TemplateArgs, Range.getBegin(), DeclarationName());
DeclarationName());
if (T.isNull()) if (T.isNull())
return 0; return 0;
@ -852,14 +831,12 @@ Sema::InstantiateNestedNameSpecifier(NestedNameSpecifier *NNS,
TemplateName TemplateName
Sema::InstantiateTemplateName(TemplateName Name, SourceLocation Loc, Sema::InstantiateTemplateName(TemplateName Name, SourceLocation Loc,
const TemplateArgument *TemplateArgs, const TemplateArgumentList &TemplateArgs) {
unsigned NumTemplateArgs) {
if (TemplateTemplateParmDecl *TTP if (TemplateTemplateParmDecl *TTP
= dyn_cast_or_null<TemplateTemplateParmDecl>( = dyn_cast_or_null<TemplateTemplateParmDecl>(
Name.getAsTemplateDecl())) { Name.getAsTemplateDecl())) {
assert(TTP->getDepth() == 0 && assert(TTP->getDepth() == 0 &&
"Cannot reduce depth of a template template parameter"); "Cannot reduce depth of a template template parameter");
assert(TTP->getPosition() < NumTemplateArgs && "Wrong # of template args");
assert(TemplateArgs[TTP->getPosition()].getAsDecl() && assert(TemplateArgs[TTP->getPosition()].getAsDecl() &&
"Wrong kind of template template argument"); "Wrong kind of template template argument");
ClassTemplateDecl *ClassTemplate ClassTemplateDecl *ClassTemplate
@ -870,7 +847,7 @@ Sema::InstantiateTemplateName(TemplateName Name, SourceLocation Loc,
NestedNameSpecifier *NNS NestedNameSpecifier *NNS
= InstantiateNestedNameSpecifier(QTN->getQualifier(), = InstantiateNestedNameSpecifier(QTN->getQualifier(),
/*FIXME=*/SourceRange(Loc), /*FIXME=*/SourceRange(Loc),
TemplateArgs, NumTemplateArgs); TemplateArgs);
if (NNS) if (NNS)
return Context.getQualifiedTemplateName(NNS, return Context.getQualifiedTemplateName(NNS,
QTN->hasTemplateKeyword(), QTN->hasTemplateKeyword(),
@ -882,7 +859,7 @@ Sema::InstantiateTemplateName(TemplateName Name, SourceLocation Loc,
NestedNameSpecifier *NNS NestedNameSpecifier *NNS
= InstantiateNestedNameSpecifier(DTN->getQualifier(), = InstantiateNestedNameSpecifier(DTN->getQualifier(),
/*FIXME=*/SourceRange(Loc), /*FIXME=*/SourceRange(Loc),
TemplateArgs, NumTemplateArgs); TemplateArgs);
if (!NNS) // FIXME: Not the best recovery strategy. if (!NNS) // FIXME: Not the best recovery strategy.
return Name; return Name;

View File

@ -23,17 +23,14 @@ namespace {
: public DeclVisitor<TemplateDeclInstantiator, Decl *> { : public DeclVisitor<TemplateDeclInstantiator, Decl *> {
Sema &SemaRef; Sema &SemaRef;
DeclContext *Owner; DeclContext *Owner;
const TemplateArgument *TemplateArgs; const TemplateArgumentList &TemplateArgs;
unsigned NumTemplateArgs;
public: public:
typedef Sema::OwningExprResult OwningExprResult; typedef Sema::OwningExprResult OwningExprResult;
TemplateDeclInstantiator(Sema &SemaRef, DeclContext *Owner, TemplateDeclInstantiator(Sema &SemaRef, DeclContext *Owner,
const TemplateArgument *TemplateArgs, const TemplateArgumentList &TemplateArgs)
unsigned NumTemplateArgs) : SemaRef(SemaRef), Owner(Owner), TemplateArgs(TemplateArgs) { }
: SemaRef(SemaRef), Owner(Owner), TemplateArgs(TemplateArgs),
NumTemplateArgs(NumTemplateArgs) { }
// FIXME: Once we get closer to completion, replace these // FIXME: Once we get closer to completion, replace these
// manually-written declarations with automatically-generated ones // manually-written declarations with automatically-generated ones
@ -83,8 +80,7 @@ Decl *TemplateDeclInstantiator::VisitTypedefDecl(TypedefDecl *D) {
bool Invalid = false; bool Invalid = false;
QualType T = D->getUnderlyingType(); QualType T = D->getUnderlyingType();
if (T->isDependentType()) { if (T->isDependentType()) {
T = SemaRef.InstantiateType(T, TemplateArgs, NumTemplateArgs, T = SemaRef.InstantiateType(T, TemplateArgs, D->getLocation(),
D->getLocation(),
D->getDeclName()); D->getDeclName());
if (T.isNull()) { if (T.isNull()) {
Invalid = true; Invalid = true;
@ -106,7 +102,6 @@ Decl *TemplateDeclInstantiator::VisitTypedefDecl(TypedefDecl *D) {
Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) { Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) {
// Instantiate the type of the declaration // Instantiate the type of the declaration
QualType T = SemaRef.InstantiateType(D->getType(), TemplateArgs, QualType T = SemaRef.InstantiateType(D->getType(), TemplateArgs,
NumTemplateArgs,
D->getTypeSpecStartLoc(), D->getTypeSpecStartLoc(),
D->getDeclName()); D->getDeclName());
if (T.isNull()) if (T.isNull())
@ -129,7 +124,7 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) {
if (D->getInit()) { if (D->getInit()) {
OwningExprResult Init OwningExprResult Init
= SemaRef.InstantiateExpr(D->getInit(), TemplateArgs, NumTemplateArgs); = SemaRef.InstantiateExpr(D->getInit(), TemplateArgs);
if (Init.isInvalid()) if (Init.isInvalid())
Var->setInvalidDecl(); Var->setInvalidDecl();
else else
@ -144,8 +139,7 @@ Decl *TemplateDeclInstantiator::VisitFieldDecl(FieldDecl *D) {
bool Invalid = false; bool Invalid = false;
QualType T = D->getType(); QualType T = D->getType();
if (T->isDependentType()) { if (T->isDependentType()) {
T = SemaRef.InstantiateType(T, TemplateArgs, NumTemplateArgs, T = SemaRef.InstantiateType(T, TemplateArgs, D->getLocation(),
D->getLocation(),
D->getDeclName()); D->getDeclName());
if (!T.isNull() && T->isFunctionType()) { if (!T.isNull() && T->isFunctionType()) {
// C++ [temp.arg.type]p3: // C++ [temp.arg.type]p3:
@ -166,7 +160,7 @@ Decl *TemplateDeclInstantiator::VisitFieldDecl(FieldDecl *D) {
BitWidth = 0; BitWidth = 0;
else if (BitWidth) { else if (BitWidth) {
OwningExprResult InstantiatedBitWidth OwningExprResult InstantiatedBitWidth
= SemaRef.InstantiateExpr(BitWidth, TemplateArgs, NumTemplateArgs); = SemaRef.InstantiateExpr(BitWidth, TemplateArgs);
if (InstantiatedBitWidth.isInvalid()) { if (InstantiatedBitWidth.isInvalid()) {
Invalid = true; Invalid = true;
BitWidth = 0; BitWidth = 0;
@ -195,7 +189,7 @@ Decl *TemplateDeclInstantiator::VisitStaticAssertDecl(StaticAssertDecl *D) {
Expr *AssertExpr = D->getAssertExpr(); Expr *AssertExpr = D->getAssertExpr();
OwningExprResult InstantiatedAssertExpr OwningExprResult InstantiatedAssertExpr
= SemaRef.InstantiateExpr(AssertExpr, TemplateArgs, NumTemplateArgs); = SemaRef.InstantiateExpr(AssertExpr, TemplateArgs);
if (InstantiatedAssertExpr.isInvalid()) if (InstantiatedAssertExpr.isInvalid())
return 0; return 0;
@ -224,8 +218,7 @@ Decl *TemplateDeclInstantiator::VisitEnumDecl(EnumDecl *D) {
// The specified value for the enumerator. // The specified value for the enumerator.
OwningExprResult Value = SemaRef.Owned((Expr *)0); OwningExprResult Value = SemaRef.Owned((Expr *)0);
if (Expr *UninstValue = EC->getInitExpr()) if (Expr *UninstValue = EC->getInitExpr())
Value = SemaRef.InstantiateExpr(UninstValue, Value = SemaRef.InstantiateExpr(UninstValue, TemplateArgs);
TemplateArgs, NumTemplateArgs);
// Drop the initial value and continue. // Drop the initial value and continue.
bool isInvalid = false; bool isInvalid = false;
@ -425,8 +418,7 @@ Decl *TemplateDeclInstantiator::VisitCXXConversionDecl(CXXConversionDecl *D) {
ParmVarDecl *TemplateDeclInstantiator::VisitParmVarDecl(ParmVarDecl *D) { ParmVarDecl *TemplateDeclInstantiator::VisitParmVarDecl(ParmVarDecl *D) {
QualType OrigT = SemaRef.InstantiateType(D->getOriginalType(), TemplateArgs, QualType OrigT = SemaRef.InstantiateType(D->getOriginalType(), TemplateArgs,
NumTemplateArgs, D->getLocation(), D->getLocation(), D->getDeclName());
D->getDeclName());
if (OrigT.isNull()) if (OrigT.isNull())
return 0; return 0;
@ -469,10 +461,8 @@ TemplateDeclInstantiator::VisitOriginalParmVarDecl(OriginalParmVarDecl *D) {
} }
Decl *Sema::InstantiateDecl(Decl *D, DeclContext *Owner, Decl *Sema::InstantiateDecl(Decl *D, DeclContext *Owner,
const TemplateArgument *TemplateArgs, const TemplateArgumentList &TemplateArgs) {
unsigned NumTemplateArgs) { TemplateDeclInstantiator Instantiator(*this, Owner, TemplateArgs);
TemplateDeclInstantiator Instantiator(*this, Owner, TemplateArgs,
NumTemplateArgs);
return Instantiator.Visit(D); return Instantiator.Visit(D);
} }
@ -491,8 +481,7 @@ TemplateDeclInstantiator::InstantiateFunctionType(FunctionDecl *D,
bool InvalidDecl = false; bool InvalidDecl = false;
// Instantiate the function parameters // Instantiate the function parameters
TemplateDeclInstantiator ParamInstantiator(SemaRef, 0, TemplateDeclInstantiator ParamInstantiator(SemaRef, 0, TemplateArgs);
TemplateArgs, NumTemplateArgs);
llvm::SmallVector<QualType, 16> ParamTys; llvm::SmallVector<QualType, 16> ParamTys;
for (FunctionDecl::param_iterator P = D->param_begin(), for (FunctionDecl::param_iterator P = D->param_begin(),
PEnd = D->param_end(); PEnd = D->param_end();
@ -524,8 +513,7 @@ TemplateDeclInstantiator::InstantiateFunctionType(FunctionDecl *D,
const FunctionProtoType *Proto = D->getType()->getAsFunctionProtoType(); const FunctionProtoType *Proto = D->getType()->getAsFunctionProtoType();
assert(Proto && "Missing prototype?"); assert(Proto && "Missing prototype?");
QualType ResultType QualType ResultType
= SemaRef.InstantiateType(Proto->getResultType(), = SemaRef.InstantiateType(Proto->getResultType(), TemplateArgs,
TemplateArgs, NumTemplateArgs,
D->getLocation(), D->getDeclName()); D->getLocation(), D->getDeclName());
if (ResultType.isNull()) if (ResultType.isNull())
return QualType(); return QualType();

View File

@ -24,17 +24,14 @@ namespace {
class VISIBILITY_HIDDEN TemplateExprInstantiator class VISIBILITY_HIDDEN TemplateExprInstantiator
: public StmtVisitor<TemplateExprInstantiator, Sema::OwningExprResult> { : public StmtVisitor<TemplateExprInstantiator, Sema::OwningExprResult> {
Sema &SemaRef; Sema &SemaRef;
const TemplateArgument *TemplateArgs; const TemplateArgumentList &TemplateArgs;
unsigned NumTemplateArgs;
public: public:
typedef Sema::OwningExprResult OwningExprResult; typedef Sema::OwningExprResult OwningExprResult;
TemplateExprInstantiator(Sema &SemaRef, TemplateExprInstantiator(Sema &SemaRef,
const TemplateArgument *TemplateArgs, const TemplateArgumentList &TemplateArgs)
unsigned NumTemplateArgs) : SemaRef(SemaRef), TemplateArgs(TemplateArgs) { }
: SemaRef(SemaRef), TemplateArgs(TemplateArgs),
NumTemplateArgs(NumTemplateArgs) { }
// FIXME: Once we get closer to completion, replace these // FIXME: Once we get closer to completion, replace these
// manually-written declarations with automatically-generated ones // manually-written declarations with automatically-generated ones
@ -294,7 +291,7 @@ TemplateExprInstantiator::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) {
if (E->isArgumentType()) { if (E->isArgumentType()) {
QualType T = E->getArgumentType(); QualType T = E->getArgumentType();
if (T->isDependentType()) { if (T->isDependentType()) {
T = SemaRef.InstantiateType(T, TemplateArgs, NumTemplateArgs, T = SemaRef.InstantiateType(T, TemplateArgs,
/*FIXME*/E->getOperatorLoc(), /*FIXME*/E->getOperatorLoc(),
&SemaRef.PP.getIdentifierTable().get("sizeof")); &SemaRef.PP.getIdentifierTable().get("sizeof"));
if (T.isNull()) if (T.isNull())
@ -324,7 +321,7 @@ TemplateExprInstantiator::VisitUnresolvedDeclRefExpr(UnresolvedDeclRefExpr *E) {
NestedNameSpecifier *NNS NestedNameSpecifier *NNS
= SemaRef.InstantiateNestedNameSpecifier(E->getQualifier(), = SemaRef.InstantiateNestedNameSpecifier(E->getQualifier(),
E->getQualifierRange(), E->getQualifierRange(),
TemplateArgs, NumTemplateArgs); TemplateArgs);
if (!NNS) if (!NNS)
return SemaRef.ExprError(); return SemaRef.ExprError();
@ -348,7 +345,7 @@ TemplateExprInstantiator::VisitCXXTemporaryObjectExpr(
CXXTemporaryObjectExpr *E) { CXXTemporaryObjectExpr *E) {
QualType T = E->getType(); QualType T = E->getType();
if (T->isDependentType()) { if (T->isDependentType()) {
T = SemaRef.InstantiateType(T, TemplateArgs, NumTemplateArgs, T = SemaRef.InstantiateType(T, TemplateArgs,
E->getTypeBeginLoc(), DeclarationName()); E->getTypeBeginLoc(), DeclarationName());
if (T.isNull()) if (T.isNull())
return SemaRef.ExprError(); return SemaRef.ExprError();
@ -413,8 +410,7 @@ Sema::OwningExprResult TemplateExprInstantiator::VisitImplicitCastExpr(
} }
Sema::OwningExprResult Sema::OwningExprResult
Sema::InstantiateExpr(Expr *E, const TemplateArgument *TemplateArgs, Sema::InstantiateExpr(Expr *E, const TemplateArgumentList &TemplateArgs) {
unsigned NumTemplateArgs) { TemplateExprInstantiator Instantiator(*this, TemplateArgs);
TemplateExprInstantiator Instantiator(*this, TemplateArgs, NumTemplateArgs);
return Instantiator.Visit(E); return Instantiator.Visit(E);
} }

View File

@ -1115,9 +1115,7 @@ bool Sema::RequireCompleteType(SourceLocation Loc, QualType T, unsigned diag,
Parent && !Spec; Parent = Parent->getParent()) Parent && !Spec; Parent = Parent->getParent())
Spec = dyn_cast<ClassTemplateSpecializationDecl>(Parent); Spec = dyn_cast<ClassTemplateSpecializationDecl>(Parent);
assert(Spec && "Not a member of a class template specialization?"); assert(Spec && "Not a member of a class template specialization?");
return InstantiateClass(Loc, Rec, Pattern, return InstantiateClass(Loc, Rec, Pattern, Spec->getTemplateArgs());
Spec->getTemplateArgs(),
Spec->getNumTemplateArgs());
} }
} }
} }