aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaTemplateInstantiateDecl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Sema/SemaTemplateInstantiateDecl.cpp')
-rw-r--r--lib/Sema/SemaTemplateInstantiateDecl.cpp397
1 files changed, 200 insertions, 197 deletions
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 2fd35285324e..1c7869fecd86 100644
--- a/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -9,8 +9,10 @@
// This file implements C++ template instantiation for declarations.
//
//===----------------------------------------------------------------------===/
-#include "Sema.h"
-#include "Lookup.h"
+#include "clang/Sema/SemaInternal.h"
+#include "clang/Sema/Lookup.h"
+#include "clang/Sema/PrettyDeclStackTrace.h"
+#include "clang/Sema/Template.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclTemplate.h"
@@ -19,7 +21,6 @@
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/TypeLoc.h"
-#include "clang/Basic/PrettyStackTrace.h"
#include "clang/Lex/Preprocessor.h"
using namespace clang;
@@ -31,11 +32,7 @@ namespace {
DeclContext *Owner;
const MultiLevelTemplateArgumentList &TemplateArgs;
- void InstantiateAttrs(Decl *Tmpl, Decl *New);
-
public:
- typedef Sema::OwningExprResult OwningExprResult;
-
TemplateDeclInstantiator(Sema &SemaRef, DeclContext *Owner,
const MultiLevelTemplateArgumentList &TemplateArgs)
: SemaRef(SemaRef), Owner(Owner), TemplateArgs(TemplateArgs) { }
@@ -87,10 +84,6 @@ namespace {
return 0;
}
- const LangOptions &getLangOptions() {
- return SemaRef.getLangOptions();
- }
-
// Helper functions for instantiating methods.
TypeSourceInfo *SubstFunctionType(FunctionDecl *D,
llvm::SmallVectorImpl<ParmVarDecl *> &Params);
@@ -144,28 +137,38 @@ bool TemplateDeclInstantiator::SubstQualifier(const TagDecl *OldDecl,
}
// FIXME: Is this still too simple?
-void TemplateDeclInstantiator::InstantiateAttrs(Decl *Tmpl, Decl *New) {
- for (const Attr *TmplAttr = Tmpl->getAttrs(); TmplAttr;
- TmplAttr = TmplAttr->getNext()) {
+void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs,
+ Decl *Tmpl, Decl *New) {
+ for (AttrVec::const_iterator i = Tmpl->attr_begin(), e = Tmpl->attr_end();
+ i != e; ++i) {
+ const Attr *TmplAttr = *i;
// FIXME: This should be generalized to more than just the AlignedAttr.
if (const AlignedAttr *Aligned = dyn_cast<AlignedAttr>(TmplAttr)) {
- if (Aligned->isDependent()) {
+ if (Aligned->isAlignmentDependent()) {
// The alignment expression is not potentially evaluated.
- EnterExpressionEvaluationContext Unevaluated(SemaRef,
- Action::Unevaluated);
-
- OwningExprResult Result = SemaRef.SubstExpr(Aligned->getAlignmentExpr(),
- TemplateArgs);
- if (!Result.isInvalid())
- // FIXME: Is this the correct source location?
- SemaRef.AddAlignedAttr(Aligned->getAlignmentExpr()->getExprLoc(),
- New, Result.takeAs<Expr>());
+ EnterExpressionEvaluationContext Unevaluated(*this,
+ Sema::Unevaluated);
+
+ if (Aligned->isAlignmentExpr()) {
+ ExprResult Result = SubstExpr(Aligned->getAlignmentExpr(),
+ TemplateArgs);
+ if (!Result.isInvalid())
+ AddAlignedAttr(Aligned->getLocation(), New, Result.takeAs<Expr>());
+ }
+ else {
+ TypeSourceInfo *Result = SubstType(Aligned->getAlignmentType(),
+ TemplateArgs,
+ Aligned->getLocation(),
+ DeclarationName());
+ if (Result)
+ AddAlignedAttr(Aligned->getLocation(), New, Result);
+ }
continue;
}
}
// FIXME: Is cloning correct for all attributes?
- Attr *NewAttr = TmplAttr->clone(SemaRef.Context);
+ Attr *NewAttr = TmplAttr->clone(Context);
New->addAttr(NewAttr);
}
}
@@ -234,7 +237,7 @@ Decl *TemplateDeclInstantiator::VisitTypedefDecl(TypedefDecl *D) {
Typedef->setPreviousDeclaration(cast<TypedefDecl>(InstPrev));
}
- InstantiateAttrs(D, Typedef);
+ SemaRef.InstantiateAttrs(TemplateArgs, D, Typedef);
Typedef->setAccess(D->getAccess());
Owner->addDecl(Typedef);
@@ -249,14 +252,14 @@ static bool InstantiateInitializationArguments(Sema &SemaRef,
Expr **Args, unsigned NumArgs,
const MultiLevelTemplateArgumentList &TemplateArgs,
llvm::SmallVectorImpl<SourceLocation> &FakeCommaLocs,
- ASTOwningVector<&ActionBase::DeleteExpr> &InitArgs) {
+ ASTOwningVector<Expr*> &InitArgs) {
for (unsigned I = 0; I != NumArgs; ++I) {
// When we hit the first defaulted argument, break out of the loop:
// we don't pass those default arguments on.
if (Args[I]->isDefaultArgument())
break;
- Sema::OwningExprResult Arg = SemaRef.SubstExpr(Args[I], TemplateArgs);
+ ExprResult Arg = SemaRef.SubstExpr(Args[I], TemplateArgs);
if (Arg.isInvalid())
return true;
@@ -288,7 +291,7 @@ static bool InstantiateInitializer(Sema &S, Expr *Init,
const MultiLevelTemplateArgumentList &TemplateArgs,
SourceLocation &LParenLoc,
llvm::SmallVector<SourceLocation, 4> &CommaLocs,
- ASTOwningVector<&ActionBase::DeleteExpr> &NewArgs,
+ ASTOwningVector<Expr*> &NewArgs,
SourceLocation &RParenLoc) {
NewArgs.clear();
LParenLoc = SourceLocation();
@@ -331,7 +334,7 @@ static bool InstantiateInitializer(Sema &S, Expr *Init,
}
}
- Sema::OwningExprResult Result = S.SubstExpr(Init, TemplateArgs);
+ ExprResult Result = S.SubstExpr(Init, TemplateArgs);
if (Result.isInvalid())
return true;
@@ -363,7 +366,6 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) {
D->getStorageClassAsWritten());
Var->setThreadSpecified(D->isThreadSpecified());
Var->setCXXDirectInitializer(D->hasCXXDirectInitializer());
- Var->setDeclaredInCondition(D->isDeclaredInCondition());
// Substitute the nested name specifier, if any.
if (SubstQualifier(D, Var))
@@ -399,7 +401,7 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) {
if (Owner->isFunctionOrMethod())
SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Var);
}
- InstantiateAttrs(D, Var);
+ SemaRef.InstantiateAttrs(TemplateArgs, D, Var);
// Link instantiations of static data members back to the template from
// which they were instantiated.
@@ -418,25 +420,23 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) {
// Instantiate the initializer.
SourceLocation LParenLoc, RParenLoc;
llvm::SmallVector<SourceLocation, 4> CommaLocs;
- ASTOwningVector<&ActionBase::DeleteExpr> InitArgs(SemaRef);
+ ASTOwningVector<Expr*> InitArgs(SemaRef);
if (!InstantiateInitializer(SemaRef, D->getInit(), TemplateArgs, LParenLoc,
CommaLocs, InitArgs, RParenLoc)) {
// Attach the initializer to the declaration.
if (D->hasCXXDirectInitializer()) {
// Add the direct initializer to the declaration.
- SemaRef.AddCXXDirectInitializerToDecl(Sema::DeclPtrTy::make(Var),
+ SemaRef.AddCXXDirectInitializerToDecl(Var,
LParenLoc,
move_arg(InitArgs),
CommaLocs.data(),
RParenLoc);
} else if (InitArgs.size() == 1) {
- Expr *Init = (Expr*)(InitArgs.take()[0]);
- SemaRef.AddInitializerToDecl(Sema::DeclPtrTy::make(Var),
- SemaRef.Owned(Init),
- false);
+ Expr *Init = InitArgs.take()[0];
+ SemaRef.AddInitializerToDecl(Var, Init, false);
} else {
assert(InitArgs.size() == 0);
- SemaRef.ActOnUninitializedDecl(Sema::DeclPtrTy::make(Var), false);
+ SemaRef.ActOnUninitializedDecl(Var, false);
}
} else {
// FIXME: Not too happy about invalidating the declaration
@@ -446,12 +446,12 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) {
SemaRef.PopExpressionEvaluationContext();
} else if (!Var->isStaticDataMember() || Var->isOutOfLine())
- SemaRef.ActOnUninitializedDecl(Sema::DeclPtrTy::make(Var), false);
+ SemaRef.ActOnUninitializedDecl(Var, false);
// Diagnose unused local variables.
if (!Var->isInvalidDecl() && Owner->isFunctionOrMethod() && !Var->isUsed())
SemaRef.DiagnoseUnusedDecl(Var);
-
+
return Var;
}
@@ -493,9 +493,9 @@ Decl *TemplateDeclInstantiator::VisitFieldDecl(FieldDecl *D) {
BitWidth = 0;
else if (BitWidth) {
// The bit-width expression is not potentially evaluated.
- EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
+ EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated);
- OwningExprResult InstantiatedBitWidth
+ ExprResult InstantiatedBitWidth
= SemaRef.SubstExpr(BitWidth, TemplateArgs);
if (InstantiatedBitWidth.isInvalid()) {
Invalid = true;
@@ -518,7 +518,7 @@ Decl *TemplateDeclInstantiator::VisitFieldDecl(FieldDecl *D) {
return 0;
}
- InstantiateAttrs(D, Field);
+ SemaRef.InstantiateAttrs(TemplateArgs, D, Field);
if (Invalid)
Field->setInvalidDecl();
@@ -529,7 +529,7 @@ Decl *TemplateDeclInstantiator::VisitFieldDecl(FieldDecl *D) {
}
if (CXXRecordDecl *Parent= dyn_cast<CXXRecordDecl>(Field->getDeclContext())) {
if (Parent->isAnonymousStructOrUnion() &&
- Parent->getLookupContext()->isFunctionOrMethod())
+ Parent->getRedeclContext()->isFunctionOrMethod())
SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Field);
}
@@ -581,20 +581,18 @@ Decl *TemplateDeclInstantiator::VisitStaticAssertDecl(StaticAssertDecl *D) {
Expr *AssertExpr = D->getAssertExpr();
// The expression in a static assertion is not potentially evaluated.
- EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
+ EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated);
- OwningExprResult InstantiatedAssertExpr
+ ExprResult InstantiatedAssertExpr
= SemaRef.SubstExpr(AssertExpr, TemplateArgs);
if (InstantiatedAssertExpr.isInvalid())
return 0;
- OwningExprResult Message(SemaRef, D->getMessage());
+ ExprResult Message(D->getMessage());
D->getMessage()->Retain();
- Decl *StaticAssert
- = SemaRef.ActOnStaticAssertDeclaration(D->getLocation(),
- move(InstantiatedAssertExpr),
- move(Message)).getAs<Decl>();
- return StaticAssert;
+ return SemaRef.ActOnStaticAssertDeclaration(D->getLocation(),
+ InstantiatedAssertExpr.get(),
+ Message.get());
}
Decl *TemplateDeclInstantiator::VisitEnumDecl(EnumDecl *D) {
@@ -611,18 +609,18 @@ Decl *TemplateDeclInstantiator::VisitEnumDecl(EnumDecl *D) {
if (D->getDeclContext()->isFunctionOrMethod())
SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Enum);
- llvm::SmallVector<Sema::DeclPtrTy, 4> Enumerators;
+ llvm::SmallVector<Decl*, 4> Enumerators;
EnumConstantDecl *LastEnumConst = 0;
for (EnumDecl::enumerator_iterator EC = D->enumerator_begin(),
ECEnd = D->enumerator_end();
EC != ECEnd; ++EC) {
// The specified value for the enumerator.
- OwningExprResult Value = SemaRef.Owned((Expr *)0);
+ ExprResult Value = SemaRef.Owned((Expr *)0);
if (Expr *UninstValue = EC->getInitExpr()) {
// The enumerator's value expression is not potentially evaluated.
EnterExpressionEvaluationContext Unevaluated(SemaRef,
- Action::Unevaluated);
+ Sema::Unevaluated);
Value = SemaRef.SubstExpr(UninstValue, TemplateArgs);
}
@@ -637,7 +635,7 @@ Decl *TemplateDeclInstantiator::VisitEnumDecl(EnumDecl *D) {
EnumConstantDecl *EnumConst
= SemaRef.CheckEnumConstant(Enum, LastEnumConst,
EC->getLocation(), EC->getIdentifier(),
- move(Value));
+ Value.get());
if (isInvalid) {
if (EnumConst)
@@ -648,7 +646,7 @@ Decl *TemplateDeclInstantiator::VisitEnumDecl(EnumDecl *D) {
if (EnumConst) {
EnumConst->setAccess(Enum->getAccess());
Enum->addDecl(EnumConst);
- Enumerators.push_back(Sema::DeclPtrTy::make(EnumConst));
+ Enumerators.push_back(EnumConst);
LastEnumConst = EnumConst;
if (D->getDeclContext()->isFunctionOrMethod()) {
@@ -662,8 +660,8 @@ Decl *TemplateDeclInstantiator::VisitEnumDecl(EnumDecl *D) {
// FIXME: Fixup LBraceLoc and RBraceLoc
// FIXME: Empty Scope and AttributeList (required to handle attribute packed).
SemaRef.ActOnEnumBody(Enum->getLocation(), SourceLocation(), SourceLocation(),
- Sema::DeclPtrTy::make(Enum),
- &Enumerators[0], Enumerators.size(),
+ Enum,
+ Enumerators.data(), Enumerators.size(),
0, 0);
return Enum;
@@ -679,7 +677,7 @@ Decl *TemplateDeclInstantiator::VisitClassTemplateDecl(ClassTemplateDecl *D) {
// Create a local instantiation scope for this class template, which
// will contain the instantiations of the template parameters.
- Sema::LocalInstantiationScope Scope(SemaRef);
+ LocalInstantiationScope Scope(SemaRef);
TemplateParameterList *TempParams = D->getTemplateParameters();
TemplateParameterList *InstParams = SubstTemplateParams(TempParams);
if (!InstParams)
@@ -857,16 +855,7 @@ TemplateDeclInstantiator::VisitClassTemplatePartialSpecializationDecl(
if (!InstClassTemplate)
return 0;
- Decl *DCanon = D->getCanonicalDecl();
- for (llvm::FoldingSet<ClassTemplatePartialSpecializationDecl>::iterator
- P = InstClassTemplate->getPartialSpecializations().begin(),
- PEnd = InstClassTemplate->getPartialSpecializations().end();
- P != PEnd; ++P) {
- if (P->getInstantiatedFromMember()->getCanonicalDecl() == DCanon)
- return &*P;
- }
-
- return 0;
+ return InstClassTemplate->findPartialSpecInstantiatedFromMember(D);
}
Decl *
@@ -875,7 +864,7 @@ TemplateDeclInstantiator::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
// will contain the instantiations of the template parameters and then get
// merged with the local instantiation scope for the function template
// itself.
- Sema::LocalInstantiationScope Scope(SemaRef);
+ LocalInstantiationScope Scope(SemaRef);
TemplateParameterList *TempParams = D->getTemplateParameters();
TemplateParameterList *InstParams = SubstTemplateParams(TempParams);
@@ -957,7 +946,7 @@ Decl *TemplateDeclInstantiator::VisitCXXRecordDecl(CXXRecordDecl *D) {
// Make sure that anonymous structs and unions are recorded.
if (D->isAnonymousStructOrUnion()) {
Record->setAnonymousStructOrUnion(true);
- if (Record->getDeclContext()->getLookupContext()->isFunctionOrMethod())
+ if (Record->getDeclContext()->getRedeclContext()->isFunctionOrMethod())
SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Record);
}
@@ -977,20 +966,16 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,
FunctionTemplateDecl *FunctionTemplate = D->getDescribedFunctionTemplate();
void *InsertPos = 0;
if (FunctionTemplate && !TemplateParams) {
- llvm::FoldingSetNodeID ID;
std::pair<const TemplateArgument *, unsigned> Innermost
= TemplateArgs.getInnermost();
- FunctionTemplateSpecializationInfo::Profile(ID, Innermost.first,
- Innermost.second,
- SemaRef.Context);
- FunctionTemplateSpecializationInfo *Info
- = FunctionTemplate->getSpecializations().FindNodeOrInsertPos(ID,
- InsertPos);
+ FunctionDecl *SpecFunc
+ = FunctionTemplate->findSpecialization(Innermost.first, Innermost.second,
+ InsertPos);
// If we already have a function template specialization, return it.
- if (Info)
- return Info->Function;
+ if (SpecFunc)
+ return SpecFunc;
}
bool isFriend;
@@ -1003,7 +988,7 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,
Owner->isFunctionOrMethod() ||
!(isa<Decl>(Owner) &&
cast<Decl>(Owner)->isDefinedOutsideFunctionOrMethod());
- Sema::LocalInstantiationScope Scope(SemaRef, MergeWithParentScope);
+ LocalInstantiationScope Scope(SemaRef, MergeWithParentScope);
llvm::SmallVector<ParmVarDecl *, 4> Params;
TypeSourceInfo *TInfo = D->getTypeSourceInfo();
@@ -1181,7 +1166,9 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,
PrincipalDecl->setObjectOfFriendDecl(PrevDecl != 0);
DC->makeDeclVisibleInContext(PrincipalDecl, /*Recoverable=*/ false);
-
+
+ bool queuedInstantiation = false;
+
if (!SemaRef.getLangOptions().CPlusPlus0x &&
D->isThisDeclarationADefinition()) {
// Check for a function body.
@@ -1198,21 +1185,36 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,
else for (FunctionDecl::redecl_iterator R = Function->redecls_begin(),
REnd = Function->redecls_end();
R != REnd; ++R) {
- if (*R != Function &&
- ((*R)->getFriendObjectKind() != Decl::FOK_None)) {
+ if (*R == Function)
+ continue;
+ switch (R->getFriendObjectKind()) {
+ case Decl::FOK_None:
+ if (!queuedInstantiation && R->isUsed(false)) {
+ if (MemberSpecializationInfo *MSInfo
+ = Function->getMemberSpecializationInfo()) {
+ if (MSInfo->getPointOfInstantiation().isInvalid()) {
+ SourceLocation Loc = R->getLocation(); // FIXME
+ MSInfo->setPointOfInstantiation(Loc);
+ SemaRef.PendingLocalImplicitInstantiations.push_back(
+ std::make_pair(Function, Loc));
+ queuedInstantiation = true;
+ }
+ }
+ }
+ break;
+ default:
if (const FunctionDecl *RPattern
- = (*R)->getTemplateInstantiationPattern())
+ = R->getTemplateInstantiationPattern())
if (RPattern->hasBody(RPattern)) {
SemaRef.Diag(Function->getLocation(), diag::err_redefinition)
<< Function->getDeclName();
- SemaRef.Diag((*R)->getLocation(), diag::note_previous_definition);
+ SemaRef.Diag(R->getLocation(), diag::note_previous_definition);
Function->setInvalidDecl();
break;
}
}
}
}
-
}
if (Function->isOverloadedOperator() && !DC->isRecord() &&
@@ -1231,20 +1233,16 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,
// We are creating a function template specialization from a function
// template. Check whether there is already a function template
// specialization for this particular set of template arguments.
- llvm::FoldingSetNodeID ID;
std::pair<const TemplateArgument *, unsigned> Innermost
= TemplateArgs.getInnermost();
- FunctionTemplateSpecializationInfo::Profile(ID, Innermost.first,
- Innermost.second,
- SemaRef.Context);
- FunctionTemplateSpecializationInfo *Info
- = FunctionTemplate->getSpecializations().FindNodeOrInsertPos(ID,
- InsertPos);
+ FunctionDecl *SpecFunc
+ = FunctionTemplate->findSpecialization(Innermost.first, Innermost.second,
+ InsertPos);
// If we already have a function template specialization, return it.
- if (Info)
- return Info->Function;
+ if (SpecFunc)
+ return SpecFunc;
}
bool isFriend;
@@ -1256,7 +1254,7 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,
bool MergeWithParentScope = (TemplateParams != 0) ||
!(isa<Decl>(Owner) &&
cast<Decl>(Owner)->isDefinedOutsideFunctionOrMethod());
- Sema::LocalInstantiationScope Scope(SemaRef, MergeWithParentScope);
+ LocalInstantiationScope Scope(SemaRef, MergeWithParentScope);
llvm::SmallVector<ParmVarDecl *, 4> Params;
TypeSourceInfo *TInfo = D->getTypeSourceInfo();
@@ -1313,39 +1311,27 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,
CXXRecordDecl *Record = cast<CXXRecordDecl>(DC);
CXXMethodDecl *Method = 0;
- DeclarationName Name = D->getDeclName();
+ DeclarationNameInfo NameInfo
+ = SemaRef.SubstDeclarationNameInfo(D->getNameInfo(), TemplateArgs);
if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(D)) {
- QualType ClassTy = SemaRef.Context.getTypeDeclType(Record);
- Name = SemaRef.Context.DeclarationNames.getCXXConstructorName(
- SemaRef.Context.getCanonicalType(ClassTy));
Method = CXXConstructorDecl::Create(SemaRef.Context, Record,
- Constructor->getLocation(),
- Name, T, TInfo,
+ NameInfo, T, TInfo,
Constructor->isExplicit(),
Constructor->isInlineSpecified(),
false);
} else if (CXXDestructorDecl *Destructor = dyn_cast<CXXDestructorDecl>(D)) {
- QualType ClassTy = SemaRef.Context.getTypeDeclType(Record);
- Name = SemaRef.Context.DeclarationNames.getCXXDestructorName(
- SemaRef.Context.getCanonicalType(ClassTy));
Method = CXXDestructorDecl::Create(SemaRef.Context, Record,
- Destructor->getLocation(), Name,
- T, Destructor->isInlineSpecified(),
+ NameInfo, T,
+ Destructor->isInlineSpecified(),
false);
} else if (CXXConversionDecl *Conversion = dyn_cast<CXXConversionDecl>(D)) {
- CanQualType ConvTy
- = SemaRef.Context.getCanonicalType(
- T->getAs<FunctionType>()->getResultType());
- Name = SemaRef.Context.DeclarationNames.getCXXConversionFunctionName(
- ConvTy);
Method = CXXConversionDecl::Create(SemaRef.Context, Record,
- Conversion->getLocation(), Name,
- T, TInfo,
+ NameInfo, T, TInfo,
Conversion->isInlineSpecified(),
Conversion->isExplicit());
} else {
- Method = CXXMethodDecl::Create(SemaRef.Context, Record, D->getLocation(),
- D->getDeclName(), T, TInfo,
+ Method = CXXMethodDecl::Create(SemaRef.Context, Record,
+ NameInfo, T, TInfo,
D->isStatic(),
D->getStorageClassAsWritten(),
D->isInlineSpecified());
@@ -1409,8 +1395,8 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,
if (InitMethodInstantiation(Method, D))
Method->setInvalidDecl();
- LookupResult Previous(SemaRef, Name, SourceLocation(),
- Sema::LookupOrdinaryName, Sema::ForRedeclaration);
+ LookupResult Previous(SemaRef, NameInfo, Sema::LookupOrdinaryName,
+ Sema::ForRedeclaration);
if (!FunctionTemplate || TemplateParams || isFriend) {
SemaRef.LookupQualifiedName(Previous, Record);
@@ -1446,7 +1432,7 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,
else
Owner->addDecl(DeclToAdd);
}
-
+
return Method;
}
@@ -1475,8 +1461,8 @@ Decl *TemplateDeclInstantiator::VisitTemplateTypeParmDecl(
TemplateTypeParmDecl *Inst =
TemplateTypeParmDecl::Create(SemaRef.Context, Owner, D->getLocation(),
- TTPT->getDepth() - 1, TTPT->getIndex(),
- TTPT->getName(),
+ TTPT->getDepth() - TemplateArgs.getNumLevels(),
+ TTPT->getIndex(),TTPT->getName(),
D->wasDeclaredWithTypename(),
D->isParameterPack());
@@ -1517,8 +1503,9 @@ Decl *TemplateDeclInstantiator::VisitNonTypeTemplateParmDecl(
NonTypeTemplateParmDecl *Param
= NonTypeTemplateParmDecl::Create(SemaRef.Context, Owner, D->getLocation(),
- D->getDepth() - 1, D->getPosition(),
- D->getIdentifier(), T, DI);
+ D->getDepth() - TemplateArgs.getNumLevels(),
+ D->getPosition(), D->getIdentifier(), T,
+ DI);
if (Invalid)
Param->setInvalidDecl();
@@ -1539,7 +1526,7 @@ TemplateDeclInstantiator::VisitTemplateTemplateParmDecl(
{
// Perform the actual substitution of template parameters within a new,
// local instantiation scope.
- Sema::LocalInstantiationScope Scope(SemaRef);
+ LocalInstantiationScope Scope(SemaRef);
InstParams = SubstTemplateParams(TempParams);
if (!InstParams)
return NULL;
@@ -1548,8 +1535,9 @@ TemplateDeclInstantiator::VisitTemplateTemplateParmDecl(
// Build the template template parameter.
TemplateTemplateParmDecl *Param
= TemplateTemplateParmDecl::Create(SemaRef.Context, Owner, D->getLocation(),
- D->getDepth() - 1, D->getPosition(),
- D->getIdentifier(), InstParams);
+ D->getDepth() - TemplateArgs.getNumLevels(),
+ D->getPosition(), D->getIdentifier(),
+ InstParams);
Param->setDefaultArgument(D->getDefaultArgument(), false);
// Introduce this template parameter's instantiation into the instantiation
@@ -1575,22 +1563,22 @@ Decl *TemplateDeclInstantiator::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
Decl *TemplateDeclInstantiator::VisitUsingDecl(UsingDecl *D) {
// The nested name specifier is non-dependent, so no transformation
- // is required.
+ // is required. The same holds for the name info.
+ DeclarationNameInfo NameInfo = D->getNameInfo();
// We only need to do redeclaration lookups if we're in a class
// scope (in fact, it's not really even possible in non-class
// scopes).
bool CheckRedeclaration = Owner->isRecord();
- LookupResult Prev(SemaRef, D->getDeclName(), D->getLocation(),
- Sema::LookupUsingDeclName, Sema::ForRedeclaration);
+ LookupResult Prev(SemaRef, NameInfo, Sema::LookupUsingDeclName,
+ Sema::ForRedeclaration);
UsingDecl *NewUD = UsingDecl::Create(SemaRef.Context, Owner,
- D->getLocation(),
D->getNestedNameRange(),
D->getUsingLocation(),
D->getTargetNestedNameDecl(),
- D->getDeclName(),
+ NameInfo,
D->isTypeName());
CXXScopeSpec SS;
@@ -1666,10 +1654,12 @@ Decl * TemplateDeclInstantiator
SS.setRange(D->getTargetNestedNameRange());
SS.setScopeRep(NNS);
+ // Since NameInfo refers to a typename, it cannot be a C++ special name.
+ // Hence, no tranformation is required for it.
+ DeclarationNameInfo NameInfo(D->getDeclName(), D->getLocation());
NamedDecl *UD =
SemaRef.BuildUsingDeclaration(/*Scope*/ 0, D->getAccess(),
- D->getUsingLoc(), SS, D->getLocation(),
- D->getDeclName(), 0,
+ D->getUsingLoc(), SS, NameInfo, 0,
/*instantiation*/ true,
/*typename*/ true, D->getTypenameLoc());
if (UD)
@@ -1691,10 +1681,12 @@ Decl * TemplateDeclInstantiator
SS.setRange(D->getTargetNestedNameRange());
SS.setScopeRep(NNS);
+ DeclarationNameInfo NameInfo
+ = SemaRef.SubstDeclarationNameInfo(D->getNameInfo(), TemplateArgs);
+
NamedDecl *UD =
SemaRef.BuildUsingDeclaration(/*Scope*/ 0, D->getAccess(),
- D->getUsingLoc(), SS, D->getLocation(),
- D->getDeclName(), 0,
+ D->getUsingLoc(), SS, NameInfo, 0,
/*instantiation*/ true,
/*typename*/ false, SourceLocation());
if (UD)
@@ -1735,13 +1727,8 @@ TemplateDeclInstantiator::SubstTemplateParams(TemplateParameterList *L) {
}
// Clean up if we had an error.
- if (Invalid) {
- for (ParamVector::iterator PI = Params.begin(), PE = Params.end();
- PI != PE; ++PI)
- if (*PI)
- (*PI)->Destroy(SemaRef.Context);
+ if (Invalid)
return NULL;
- }
TemplateParameterList *InstL
= TemplateParameterList::Create(SemaRef.Context, L->getTemplateLoc(),
@@ -1767,7 +1754,7 @@ TemplateDeclInstantiator::InstantiateClassTemplatePartialSpecialization(
// Create a local instantiation scope for this class template partial
// specialization, which will contain the instantiations of the template
// parameters.
- Sema::LocalInstantiationScope Scope(SemaRef);
+ LocalInstantiationScope Scope(SemaRef);
// Substitute into the template parameters of the class template partial
// specialization.
@@ -1804,15 +1791,10 @@ TemplateDeclInstantiator::InstantiateClassTemplatePartialSpecialization(
// Figure out where to insert this class template partial specialization
// in the member template's set of class template partial specializations.
- llvm::FoldingSetNodeID ID;
- ClassTemplatePartialSpecializationDecl::Profile(ID,
- Converted.getFlatArguments(),
- Converted.flatSize(),
- SemaRef.Context);
void *InsertPos = 0;
ClassTemplateSpecializationDecl *PrevDecl
- = ClassTemplate->getPartialSpecializations().FindNodeOrInsertPos(ID,
- InsertPos);
+ = ClassTemplate->findPartialSpecialization(Converted.getFlatArguments(),
+ Converted.flatSize(), InsertPos);
// Build the canonical type that describes the converted template
// arguments of the class template partial specialization.
@@ -1871,7 +1853,7 @@ TemplateDeclInstantiator::InstantiateClassTemplatePartialSpecialization(
InstTemplateArgs,
CanonType,
0,
- ClassTemplate->getPartialSpecializations().size());
+ ClassTemplate->getNextPartialSpecSequenceNumber());
// Substitute the nested name specifier, if any.
if (SubstQualifier(PartialSpec, InstPartialSpec))
return 0;
@@ -1881,8 +1863,7 @@ TemplateDeclInstantiator::InstantiateClassTemplatePartialSpecialization(
// Add this partial specialization to the set of class template partial
// specializations.
- ClassTemplate->getPartialSpecializations().InsertNode(InstPartialSpec,
- InsertPos);
+ ClassTemplate->AddPartialSpecialization(InstPartialSpec, InsertPos);
return false;
}
@@ -2003,7 +1984,7 @@ TemplateDeclInstantiator::InitFunctionInstantiation(FunctionDecl *New,
Proto->getExtInfo()));
}
- InstantiateAttrs(Tmpl, New);
+ SemaRef.InstantiateAttrs(TemplateArgs, Tmpl, New);
return false;
}
@@ -2078,8 +2059,12 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
Diag(PatternDecl->getLocation(),
diag::note_explicit_instantiation_here);
Function->setInvalidDecl();
+ } else if (Function->getTemplateSpecializationKind()
+ == TSK_ExplicitInstantiationDefinition) {
+ PendingInstantiations.push_back(
+ std::make_pair(Function, PointOfInstantiation));
}
-
+
return;
}
@@ -2099,13 +2084,13 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
// If we're performing recursive template instantiation, create our own
// queue of pending implicit instantiations that we will instantiate later,
// while we're still within our own instantiation context.
- std::deque<PendingImplicitInstantiation> SavedPendingImplicitInstantiations;
+ std::deque<PendingImplicitInstantiation> SavedPendingInstantiations;
if (Recursive)
- PendingImplicitInstantiations.swap(SavedPendingImplicitInstantiations);
+ PendingInstantiations.swap(SavedPendingInstantiations);
EnterExpressionEvaluationContext EvalContext(*this,
- Action::PotentiallyEvaluated);
- ActOnStartOfFunctionDef(0, DeclPtrTy::make(Function));
+ Sema::PotentiallyEvaluated);
+ ActOnStartOfFunctionDef(0, Function);
// Introduce a new scope where local variable instantiations will be
// recorded, unless we're actually a member function within a local
@@ -2118,10 +2103,14 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
LocalInstantiationScope Scope(*this, MergeWithParentScope);
// Introduce the instantiated function parameters into the local
- // instantiation scope.
- for (unsigned I = 0, N = PatternDecl->getNumParams(); I != N; ++I)
- Scope.InstantiatedLocal(PatternDecl->getParamDecl(I),
- Function->getParamDecl(I));
+ // instantiation scope, and set the parameter names to those used
+ // in the template.
+ for (unsigned I = 0, N = PatternDecl->getNumParams(); I != N; ++I) {
+ const ParmVarDecl *PatternParam = PatternDecl->getParamDecl(I);
+ ParmVarDecl *FunctionParam = Function->getParamDecl(I);
+ FunctionParam->setDeclName(PatternParam->getDeclName());
+ Scope.InstantiatedLocal(PatternParam, FunctionParam);
+ }
// Enter the scope of this instantiation. We don't use
// PushDeclContext because we don't have a scope.
@@ -2139,12 +2128,12 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
}
// Instantiate the function body.
- OwningStmtResult Body = SubstStmt(Pattern, TemplateArgs);
+ StmtResult Body = SubstStmt(Pattern, TemplateArgs);
if (Body.isInvalid())
Function->setInvalidDecl();
- ActOnFinishFunctionBody(DeclPtrTy::make(Function), move(Body),
+ ActOnFinishFunctionBody(Function, Body.get(),
/*IsInstantiation=*/true);
PerformDependentDiagnostics(PatternDecl, TemplateArgs);
@@ -2156,16 +2145,16 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
// This class may have local implicit instantiations that need to be
// instantiation within this scope.
- PerformPendingImplicitInstantiations(/*LocalOnly=*/true);
+ PerformPendingInstantiations(/*LocalOnly=*/true);
Scope.Exit();
if (Recursive) {
// Instantiate any pending implicit instantiations found during the
// instantiation of this template.
- PerformPendingImplicitInstantiations();
+ PerformPendingInstantiations();
// Restore the set of pending implicit instantiations.
- PendingImplicitInstantiations.swap(SavedPendingImplicitInstantiations);
+ PendingInstantiations.swap(SavedPendingInstantiations);
}
}
@@ -2210,8 +2199,12 @@ void Sema::InstantiateStaticDataMemberDefinition(
diag::err_explicit_instantiation_undefined_member)
<< 2 << Var->getDeclName() << Var->getDeclContext();
Diag(Def->getLocation(), diag::note_explicit_instantiation_here);
- }
-
+ } else if (Var->getTemplateSpecializationKind()
+ == TSK_ExplicitInstantiationDefinition) {
+ PendingInstantiations.push_back(
+ std::make_pair(Var, PointOfInstantiation));
+ }
+
return;
}
@@ -2234,9 +2227,9 @@ void Sema::InstantiateStaticDataMemberDefinition(
// If we're performing recursive template instantiation, create our own
// queue of pending implicit instantiations that we will instantiate later,
// while we're still within our own instantiation context.
- std::deque<PendingImplicitInstantiation> SavedPendingImplicitInstantiations;
+ std::deque<PendingImplicitInstantiation> SavedPendingInstantiations;
if (Recursive)
- PendingImplicitInstantiations.swap(SavedPendingImplicitInstantiations);
+ PendingInstantiations.swap(SavedPendingInstantiations);
// Enter the scope of this instantiation. We don't use
// PushDeclContext because we don't have a scope.
@@ -2260,10 +2253,10 @@ void Sema::InstantiateStaticDataMemberDefinition(
if (Recursive) {
// Instantiate any pending implicit instantiations found during the
// instantiation of this template.
- PerformPendingImplicitInstantiations();
+ PerformPendingInstantiations();
// Restore the set of pending implicit instantiations.
- PendingImplicitInstantiations.swap(SavedPendingImplicitInstantiations);
+ PendingInstantiations.swap(SavedPendingInstantiations);
}
}
@@ -2281,8 +2274,13 @@ Sema::InstantiateMemInitializers(CXXConstructorDecl *New,
Inits != InitsEnd; ++Inits) {
CXXBaseOrMemberInitializer *Init = *Inits;
+ // Only instantiate written initializers, let Sema re-construct implicit
+ // ones.
+ if (!Init->isWritten())
+ continue;
+
SourceLocation LParenLoc, RParenLoc;
- ASTOwningVector<&ActionBase::DeleteExpr> NewArgs(*this);
+ ASTOwningVector<Expr*> NewArgs(*this);
llvm::SmallVector<SourceLocation, 4> CommaLocs;
// Instantiate the initializer.
@@ -2341,7 +2339,7 @@ Sema::InstantiateMemInitializers(CXXConstructorDecl *New,
}
// Assign all the initializers to the new constructor.
- ActOnMemInitializers(DeclPtrTy::make(New),
+ ActOnMemInitializers(New,
/*FIXME: ColonLoc */
SourceLocation(),
NewInits.data(), NewInits.size(),
@@ -2588,7 +2586,7 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D,
DeclContext *ParentDC = D->getDeclContext();
if (isa<ParmVarDecl>(D) || isa<NonTypeTemplateParmDecl>(D) ||
isa<TemplateTypeParmDecl>(D) || isa<TemplateTemplateParmDecl>(D) ||
- ParentDC->isFunctionOrMethod()) {
+ (ParentDC->isFunctionOrMethod() && ParentDC->isDependentContext())) {
// D is a local of some kind. Look into the map of local
// declarations to their instantiations.
return cast<NamedDecl>(CurrentInstantiationScope->getInstantiationOf(D));
@@ -2729,14 +2727,14 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D,
/// \brief Performs template instantiation for all implicit template
/// instantiations we have seen until this point.
-void Sema::PerformPendingImplicitInstantiations(bool LocalOnly) {
+void Sema::PerformPendingInstantiations(bool LocalOnly) {
while (!PendingLocalImplicitInstantiations.empty() ||
- (!LocalOnly && !PendingImplicitInstantiations.empty())) {
+ (!LocalOnly && !PendingInstantiations.empty())) {
PendingImplicitInstantiation Inst;
if (PendingLocalImplicitInstantiations.empty()) {
- Inst = PendingImplicitInstantiations.front();
- PendingImplicitInstantiations.pop_front();
+ Inst = PendingInstantiations.front();
+ PendingInstantiations.pop_front();
} else {
Inst = PendingLocalImplicitInstantiations.front();
PendingLocalImplicitInstantiations.pop_front();
@@ -2744,12 +2742,12 @@ void Sema::PerformPendingImplicitInstantiations(bool LocalOnly) {
// Instantiate function definitions
if (FunctionDecl *Function = dyn_cast<FunctionDecl>(Inst.first)) {
- PrettyStackTraceActionsDecl CrashInfo(DeclPtrTy::make(Function),
- Function->getLocation(), *this,
- Context.getSourceManager(),
- "instantiating function definition");
-
- InstantiateFunctionDefinition(/*FIXME:*/Inst.second, Function, true);
+ PrettyDeclStackTraceEntry CrashInfo(*this, Function, SourceLocation(),
+ "instantiating function definition");
+ bool DefinitionRequired = Function->getTemplateSpecializationKind() ==
+ TSK_ExplicitInstantiationDefinition;
+ InstantiateFunctionDefinition(/*FIXME:*/Inst.second, Function, true,
+ DefinitionRequired);
continue;
}
@@ -2768,20 +2766,24 @@ void Sema::PerformPendingImplicitInstantiations(bool LocalOnly) {
case TSK_Undeclared:
assert(false && "Cannot instantitiate an undeclared specialization.");
case TSK_ExplicitInstantiationDeclaration:
- case TSK_ExplicitInstantiationDefinition:
case TSK_ExplicitSpecialization:
- continue; // No longer need implicit instantiation.
+ continue; // No longer need to instantiate this type.
+ case TSK_ExplicitInstantiationDefinition:
+ // We only need an instantiation if the pending instantiation *is* the
+ // explicit instantiation.
+ if (Var != Var->getMostRecentDeclaration()) continue;
case TSK_ImplicitInstantiation:
break;
}
- PrettyStackTraceActionsDecl CrashInfo(DeclPtrTy::make(Var),
- Var->getLocation(), *this,
- Context.getSourceManager(),
- "instantiating static data member "
- "definition");
+ PrettyDeclStackTraceEntry CrashInfo(*this, Var, Var->getLocation(),
+ "instantiating static data member "
+ "definition");
- InstantiateStaticDataMemberDefinition(/*FIXME:*/Inst.second, Var, true);
+ bool DefinitionRequired = Var->getTemplateSpecializationKind() ==
+ TSK_ExplicitInstantiationDefinition;
+ InstantiateStaticDataMemberDefinition(/*FIXME:*/Inst.second, Var, true,
+ DefinitionRequired);
}
}
@@ -2798,3 +2800,4 @@ void Sema::PerformDependentDiagnostics(const DeclContext *Pattern,
}
}
}
+