summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/tools/clang/lib/Sema/SemaTemplateInstantiate.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Sema/SemaTemplateInstantiate.cpp')
-rw-r--r--contrib/llvm/tools/clang/lib/Sema/SemaTemplateInstantiate.cpp295
1 files changed, 197 insertions, 98 deletions
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaTemplateInstantiate.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaTemplateInstantiate.cpp
index 7ef04e9..8904f37 100644
--- a/contrib/llvm/tools/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/contrib/llvm/tools/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -14,6 +14,7 @@
#include "TreeTransform.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.h"
+#include "clang/AST/ASTLambda.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/Expr.h"
#include "clang/Basic/LangOptions.h"
@@ -61,7 +62,24 @@ Sema::getTemplateInstantiationArgs(NamedDecl *D,
DeclContext *Ctx = dyn_cast<DeclContext>(D);
if (!Ctx) {
Ctx = D->getDeclContext();
-
+
+ // Add template arguments from a variable template instantiation.
+ if (VarTemplateSpecializationDecl *Spec =
+ dyn_cast<VarTemplateSpecializationDecl>(D)) {
+ // We're done when we hit an explicit specialization.
+ if (Spec->getSpecializationKind() == TSK_ExplicitSpecialization &&
+ !isa<VarTemplatePartialSpecializationDecl>(Spec))
+ return Result;
+
+ Result.addOuterTemplateArguments(&Spec->getTemplateInstantiationArgs());
+
+ // If this variable template specialization was instantiated from a
+ // specialized member that is a variable template, we're done.
+ assert(Spec->getSpecializedTemplate() && "No variable template?");
+ if (Spec->getSpecializedTemplate()->isMemberSpecialization())
+ return Result;
+ }
+
// If we have a template template parameter with translation unit context,
// then we're performing substitution into a default template argument of
// this template template parameter before we've constructed the template
@@ -72,7 +90,7 @@ Sema::getTemplateInstantiationArgs(NamedDecl *D,
if (TemplateTemplateParmDecl *TTP
= dyn_cast<TemplateTemplateParmDecl>(D)) {
for (unsigned I = 0, N = TTP->getDepth() + 1; I != N; ++I)
- Result.addOuterTemplateArguments(0, 0);
+ Result.addOuterTemplateArguments(None);
return Result;
}
}
@@ -113,12 +131,15 @@ Sema::getTemplateInstantiationArgs(NamedDecl *D,
assert(Function->getPrimaryTemplate() && "No function template?");
if (Function->getPrimaryTemplate()->isMemberSpecialization())
break;
+
+ // If this function is a generic lambda specialization, we are done.
+ if (isGenericLambdaCallOperatorSpecialization(Function))
+ break;
+
} else if (FunctionTemplateDecl *FunTmpl
= Function->getDescribedFunctionTemplate()) {
// Add the "injected" template arguments.
- std::pair<const TemplateArgument *, unsigned>
- Injected = FunTmpl->getInjectedTemplateArgs();
- Result.addOuterTemplateArguments(Injected.first, Injected.second);
+ Result.addOuterTemplateArguments(FunTmpl->getInjectedTemplateArgs());
}
// If this is a friend declaration and it declares an entity at
@@ -135,9 +156,10 @@ Sema::getTemplateInstantiationArgs(NamedDecl *D,
} else if (CXXRecordDecl *Rec = dyn_cast<CXXRecordDecl>(Ctx)) {
if (ClassTemplateDecl *ClassTemplate = Rec->getDescribedClassTemplate()) {
QualType T = ClassTemplate->getInjectedClassNameSpecialization();
- const TemplateSpecializationType *TST
- = cast<TemplateSpecializationType>(Context.getCanonicalType(T));
- Result.addOuterTemplateArguments(TST->getArgs(), TST->getNumArgs());
+ const TemplateSpecializationType *TST =
+ cast<TemplateSpecializationType>(Context.getCanonicalType(T));
+ Result.addOuterTemplateArguments(
+ llvm::makeArrayRef(TST->getArgs(), TST->getNumArgs()));
if (ClassTemplate->isMemberSpecialization())
break;
}
@@ -293,6 +315,29 @@ InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
}
}
+Sema::InstantiatingTemplate::InstantiatingTemplate(
+ Sema &SemaRef, SourceLocation PointOfInstantiation,
+ VarTemplatePartialSpecializationDecl *PartialSpec,
+ ArrayRef<TemplateArgument> TemplateArgs,
+ sema::TemplateDeductionInfo &DeductionInfo, SourceRange InstantiationRange)
+ : SemaRef(SemaRef), SavedInNonInstantiationSFINAEContext(
+ SemaRef.InNonInstantiationSFINAEContext) {
+ Invalid = CheckInstantiationDepth(PointOfInstantiation, InstantiationRange);
+ if (!Invalid) {
+ ActiveTemplateInstantiation Inst;
+ Inst.Kind =
+ ActiveTemplateInstantiation::DeducedTemplateArgumentSubstitution;
+ Inst.PointOfInstantiation = PointOfInstantiation;
+ Inst.Entity = PartialSpec;
+ Inst.TemplateArgs = TemplateArgs.data();
+ Inst.NumTemplateArgs = TemplateArgs.size();
+ Inst.DeductionInfo = &DeductionInfo;
+ Inst.InstantiationRange = InstantiationRange;
+ SemaRef.InNonInstantiationSFINAEContext = false;
+ SemaRef.ActiveTemplateInstantiations.push_back(Inst);
+ }
+}
+
Sema::InstantiatingTemplate::
InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
ParmVarDecl *Param,
@@ -399,6 +444,18 @@ void Sema::InstantiatingTemplate::Clear() {
}
SemaRef.InNonInstantiationSFINAEContext
= SavedInNonInstantiationSFINAEContext;
+
+ // Name lookup no longer looks in this template's defining module.
+ assert(SemaRef.ActiveTemplateInstantiations.size() >=
+ SemaRef.ActiveTemplateInstantiationLookupModules.size() &&
+ "forgot to remove a lookup module for a template instantiation");
+ if (SemaRef.ActiveTemplateInstantiations.size() ==
+ SemaRef.ActiveTemplateInstantiationLookupModules.size()) {
+ if (Module *M = SemaRef.ActiveTemplateInstantiationLookupModules.back())
+ SemaRef.LookupModulesCache.erase(M);
+ SemaRef.ActiveTemplateInstantiationLookupModules.pop_back();
+ }
+
SemaRef.ActiveTemplateInstantiations.pop_back();
Invalid = true;
}
@@ -436,7 +493,7 @@ void Sema::PrintInstantiationStack() {
// FIXME: In all of these cases, we need to show the template arguments
unsigned InstantiationIdx = 0;
- for (SmallVector<ActiveTemplateInstantiation, 16>::reverse_iterator
+ for (SmallVectorImpl<ActiveTemplateInstantiation>::reverse_iterator
Active = ActiveTemplateInstantiations.rbegin(),
ActiveEnd = ActiveTemplateInstantiations.rend();
Active != ActiveEnd;
@@ -473,7 +530,9 @@ void Sema::PrintInstantiationStack() {
<< Active->InstantiationRange;
} else if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
Diags.Report(Active->PointOfInstantiation,
- diag::note_template_static_data_member_def_here)
+ VD->isStaticDataMember()?
+ diag::note_template_static_data_member_def_here
+ : diag::note_template_variable_def_here)
<< VD
<< Active->InstantiationRange;
} else if (EnumDecl *ED = dyn_cast<EnumDecl>(D)) {
@@ -616,7 +675,7 @@ Optional<TemplateDeductionInfo *> Sema::isSFINAEContext() const {
if (InNonInstantiationSFINAEContext)
return Optional<TemplateDeductionInfo *>(0);
- for (SmallVector<ActiveTemplateInstantiation, 16>::const_reverse_iterator
+ for (SmallVectorImpl<ActiveTemplateInstantiation>::const_reverse_iterator
Active = ActiveTemplateInstantiations.rbegin(),
ActiveEnd = ActiveTemplateInstantiations.rend();
Active != ActiveEnd;
@@ -708,9 +767,8 @@ namespace {
bool TryExpandParameterPacks(SourceLocation EllipsisLoc,
SourceRange PatternRange,
- llvm::ArrayRef<UnexpandedParameterPack> Unexpanded,
- bool &ShouldExpand,
- bool &RetainExpansion,
+ ArrayRef<UnexpandedParameterPack> Unexpanded,
+ bool &ShouldExpand, bool &RetainExpansion,
Optional<unsigned> &NumExpansions) {
return getSema().CheckParameterPacksForExpansion(EllipsisLoc,
PatternRange, Unexpanded,
@@ -859,13 +917,38 @@ namespace {
}
ExprResult TransformLambdaScope(LambdaExpr *E,
- CXXMethodDecl *CallOperator) {
- CallOperator->setInstantiationOfMemberFunction(E->getCallOperator(),
- TSK_ImplicitInstantiation);
- return TreeTransform<TemplateInstantiator>::
- TransformLambdaScope(E, CallOperator);
+ CXXMethodDecl *NewCallOperator,
+ ArrayRef<InitCaptureInfoTy> InitCaptureExprsAndTypes) {
+ CXXMethodDecl *const OldCallOperator = E->getCallOperator();
+ // In the generic lambda case, we set the NewTemplate to be considered
+ // an "instantiation" of the OldTemplate.
+ if (FunctionTemplateDecl *const NewCallOperatorTemplate =
+ NewCallOperator->getDescribedFunctionTemplate()) {
+
+ FunctionTemplateDecl *const OldCallOperatorTemplate =
+ OldCallOperator->getDescribedFunctionTemplate();
+ NewCallOperatorTemplate->setInstantiatedFromMemberTemplate(
+ OldCallOperatorTemplate);
+ // Mark the NewCallOperatorTemplate a specialization.
+ NewCallOperatorTemplate->setMemberSpecialization();
+ } else
+ // For a non-generic lambda we set the NewCallOperator to
+ // be an instantiation of the OldCallOperator.
+ NewCallOperator->setInstantiationOfMemberFunction(OldCallOperator,
+ TSK_ImplicitInstantiation);
+
+ return inherited::TransformLambdaScope(E, NewCallOperator,
+ InitCaptureExprsAndTypes);
+ }
+ TemplateParameterList *TransformTemplateParameterList(
+ TemplateParameterList *OrigTPL) {
+ if (!OrigTPL || !OrigTPL->size()) return OrigTPL;
+
+ DeclContext *Owner = OrigTPL->getParam(0)->getDeclContext();
+ TemplateDeclInstantiator DeclInstantiator(getSema(),
+ /* DeclContext *Owner */ Owner, TemplateArgs);
+ return DeclInstantiator.SubstTemplateParams(OrigTPL);
}
-
private:
ExprResult transformNonTypeTemplateParmRef(NonTypeTemplateParmDecl *parm,
SourceLocation loc,
@@ -884,6 +967,16 @@ bool TemplateInstantiator::AlreadyTransformed(QualType T) {
return true;
}
+static TemplateArgument
+getPackSubstitutedTemplateArgument(Sema &S, TemplateArgument Arg) {
+ assert(S.ArgumentPackSubstitutionIndex >= 0);
+ assert(S.ArgumentPackSubstitutionIndex < (int)Arg.pack_size());
+ Arg = Arg.pack_begin()[S.ArgumentPackSubstitutionIndex];
+ if (Arg.isPackExpansion())
+ Arg = Arg.getPackExpansionPattern();
+ return Arg;
+}
+
Decl *TemplateInstantiator::TransformDecl(SourceLocation Loc, Decl *D) {
if (!D)
return 0;
@@ -903,10 +996,7 @@ Decl *TemplateInstantiator::TransformDecl(SourceLocation Loc, Decl *D) {
if (TTP->isParameterPack()) {
assert(Arg.getKind() == TemplateArgument::Pack &&
"Missing argument pack");
-
- assert(getSema().ArgumentPackSubstitutionIndex >= 0);
- assert(getSema().ArgumentPackSubstitutionIndex < (int)Arg.pack_size());
- Arg = Arg.pack_begin()[getSema().ArgumentPackSubstitutionIndex];
+ Arg = getPackSubstitutedTemplateArgument(getSema(), Arg);
}
TemplateName Template = Arg.getAsTemplate();
@@ -951,8 +1041,7 @@ TemplateInstantiator::TransformFirstQualifierInScope(NamedDecl *D,
if (getSema().ArgumentPackSubstitutionIndex == -1)
return 0;
- assert(getSema().ArgumentPackSubstitutionIndex < (int)Arg.pack_size());
- Arg = Arg.pack_begin()[getSema().ArgumentPackSubstitutionIndex];
+ Arg = getPackSubstitutedTemplateArgument(getSema(), Arg);
}
QualType T = Arg.getAsType();
@@ -1054,9 +1143,8 @@ TemplateName TemplateInstantiator::TransformTemplateName(CXXScopeSpec &SS,
// keep the entire argument pack.
return getSema().Context.getSubstTemplateTemplateParmPack(TTP, Arg);
}
-
- assert(getSema().ArgumentPackSubstitutionIndex < (int)Arg.pack_size());
- Arg = Arg.pack_begin()[getSema().ArgumentPackSubstitutionIndex];
+
+ Arg = getPackSubstitutedTemplateArgument(getSema(), Arg);
}
TemplateName Template = Arg.getAsTemplate();
@@ -1078,11 +1166,9 @@ TemplateName TemplateInstantiator::TransformTemplateName(CXXScopeSpec &SS,
if (getSema().ArgumentPackSubstitutionIndex == -1)
return Name;
- const TemplateArgument &ArgPack = SubstPack->getArgumentPack();
- assert(getSema().ArgumentPackSubstitutionIndex < (int)ArgPack.pack_size() &&
- "Pack substitution index out-of-range");
- return ArgPack.pack_begin()[getSema().ArgumentPackSubstitutionIndex]
- .getAsTemplate();
+ TemplateArgument Arg = SubstPack->getArgumentPack();
+ Arg = getPackSubstitutedTemplateArgument(getSema(), Arg);
+ return Arg.getAsTemplate();
}
return inherited::TransformTemplateName(SS, Name, NameLoc, ObjectType,
@@ -1094,25 +1180,7 @@ TemplateInstantiator::TransformPredefinedExpr(PredefinedExpr *E) {
if (!E->isTypeDependent())
return SemaRef.Owned(E);
- FunctionDecl *currentDecl = getSema().getCurFunctionDecl();
- assert(currentDecl && "Must have current function declaration when "
- "instantiating.");
-
- PredefinedExpr::IdentType IT = E->getIdentType();
-
- unsigned Length = PredefinedExpr::ComputeName(IT, currentDecl).length();
-
- llvm::APInt LengthI(32, Length + 1);
- QualType ResTy;
- if (IT == PredefinedExpr::LFunction)
- ResTy = getSema().Context.WCharTy.withConst();
- else
- ResTy = getSema().Context.CharTy.withConst();
- ResTy = getSema().Context.getConstantArrayType(ResTy, LengthI,
- ArrayType::Normal, 0);
- PredefinedExpr *PE =
- new (getSema().Context) PredefinedExpr(E->getLocation(), ResTy, IT);
- return getSema().Owned(PE);
+ return getSema().BuildPredefinedExpr(E->getLocation(), E->getIdentType());
}
ExprResult
@@ -1147,8 +1215,7 @@ TemplateInstantiator::TransformTemplateParmRefExpr(DeclRefExpr *E,
Arg);
}
- assert(getSema().ArgumentPackSubstitutionIndex < (int)Arg.pack_size());
- Arg = Arg.pack_begin()[getSema().ArgumentPackSubstitutionIndex];
+ Arg = getPackSubstitutedTemplateArgument(getSema(), Arg);
}
return transformNonTypeTemplateParmRef(NTTP, E->getLocation(), Arg);
@@ -1161,14 +1228,6 @@ ExprResult TemplateInstantiator::transformNonTypeTemplateParmRef(
ExprResult result;
QualType type;
- // If the argument is a pack expansion, the parameter must actually be a
- // parameter pack, and we should substitute the pattern itself, producing
- // an expression which contains an unexpanded parameter pack.
- if (arg.isPackExpansion()) {
- assert(parm->isParameterPack() && "pack expansion for non-pack");
- arg = arg.getPackExpansionPattern();
- }
-
// The template argument itself might be an expression, in which
// case we just return that expression.
if (arg.getKind() == TemplateArgument::Expression) {
@@ -1234,12 +1293,9 @@ TemplateInstantiator::TransformSubstNonTypeTemplateParmPackExpr(
// We aren't expanding the parameter pack, so just return ourselves.
return getSema().Owned(E);
}
-
- const TemplateArgument &ArgPack = E->getArgumentPack();
- unsigned Index = (unsigned)getSema().ArgumentPackSubstitutionIndex;
- assert(Index < ArgPack.pack_size() && "Substitution index out-of-range");
-
- const TemplateArgument &Arg = ArgPack.pack_begin()[Index];
+
+ TemplateArgument Arg = E->getArgumentPack();
+ Arg = getPackSubstitutedTemplateArgument(getSema(), Arg);
return transformNonTypeTemplateParmRef(E->getParameterPack(),
E->getParameterPackLocation(),
Arg);
@@ -1410,8 +1466,7 @@ TemplateInstantiator::TransformTemplateTypeParmType(TypeLocBuilder &TLB,
return Result;
}
- assert(getSema().ArgumentPackSubstitutionIndex < (int)Arg.pack_size());
- Arg = Arg.pack_begin()[getSema().ArgumentPackSubstitutionIndex];
+ Arg = getPackSubstitutedTemplateArgument(getSema(), Arg);
}
assert(Arg.getKind() == TemplateArgument::Type &&
@@ -1459,12 +1514,11 @@ TemplateInstantiator::TransformSubstTemplateTypeParmPackType(
NewTL.setNameLoc(TL.getNameLoc());
return TL.getType();
}
-
- const TemplateArgument &ArgPack = TL.getTypePtr()->getArgumentPack();
- unsigned Index = (unsigned)getSema().ArgumentPackSubstitutionIndex;
- assert(Index < ArgPack.pack_size() && "Substitution index out-of-range");
-
- QualType Result = ArgPack.pack_begin()[Index].getAsType();
+
+ TemplateArgument Arg = TL.getTypePtr()->getArgumentPack();
+ Arg = getPackSubstitutedTemplateArgument(getSema(), Arg);
+ QualType Result = Arg.getAsType();
+
Result = getSema().Context.getSubstTemplateTypeParmType(
TL.getTypePtr()->getReplacedParameter(),
Result);
@@ -1577,6 +1631,9 @@ static bool NeedsInstantiationAsFunctionType(TypeSourceInfo *T) {
for (unsigned I = 0, E = FP.getNumArgs(); I != E; ++I) {
ParmVarDecl *P = FP.getArg(I);
+ // This must be synthesized from a typedef.
+ if (!P) continue;
+
// The parameter's type as written might be dependent even if the
// decayed type was not dependent.
if (TypeSourceInfo *TSInfo = P->getTypeSourceInfo())
@@ -1755,6 +1812,10 @@ Sema::SubstBaseSpecifiers(CXXRecordDecl *Instantiation,
Base = Pattern->bases_begin(), BaseEnd = Pattern->bases_end();
Base != BaseEnd; ++Base) {
if (!Base->getType()->isDependentType()) {
+ if (const CXXRecordDecl *RD = Base->getType()->getAsCXXRecordDecl()) {
+ if (RD->isInvalidDecl())
+ Instantiation->setInvalidDecl();
+ }
InstantiatedBases.push_back(new (Context) CXXBaseSpecifier(*Base));
continue;
}
@@ -1949,7 +2010,7 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation,
}
InstantiatingTemplate Inst(*this, PointOfInstantiation, Instantiation);
- if (Inst)
+ if (Inst.isInvalid())
return true;
// Enter the scope of this instantiation. We don't use
@@ -2081,6 +2142,14 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation,
E = LateAttrs.end(); I != E; ++I) {
assert(CurrentInstantiationScope == Instantiator.getStartingScope());
CurrentInstantiationScope = I->Scope;
+
+ // Allow 'this' within late-parsed attributes.
+ NamedDecl *ND = dyn_cast<NamedDecl>(I->NewDecl);
+ CXXRecordDecl *ThisContext =
+ dyn_cast_or_null<CXXRecordDecl>(ND->getDeclContext());
+ CXXThisScopeRAII ThisScope(*this, ThisContext, /*TypeQuals*/0,
+ ND && ND->isCXXInstanceMember());
+
Attr *NewAttr =
instantiateTemplateAttribute(I->TmplAttr, Context, *this, TemplateArgs);
I->NewDecl->addAttr(NewAttr);
@@ -2104,13 +2173,25 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation,
// Instantiate any out-of-line class template partial
// specializations now.
- for (TemplateDeclInstantiator::delayed_partial_spec_iterator
+ for (TemplateDeclInstantiator::delayed_partial_spec_iterator
P = Instantiator.delayed_partial_spec_begin(),
PEnd = Instantiator.delayed_partial_spec_end();
P != PEnd; ++P) {
if (!Instantiator.InstantiateClassTemplatePartialSpecialization(
- P->first,
- P->second)) {
+ P->first, P->second)) {
+ Instantiation->setInvalidDecl();
+ break;
+ }
+ }
+
+ // Instantiate any out-of-line variable template partial
+ // specializations now.
+ for (TemplateDeclInstantiator::delayed_var_partial_spec_iterator
+ P = Instantiator.delayed_var_partial_spec_begin(),
+ PEnd = Instantiator.delayed_var_partial_spec_end();
+ P != PEnd; ++P) {
+ if (!Instantiator.InstantiateVarTemplatePartialSpecialization(
+ P->first, P->second)) {
Instantiation->setInvalidDecl();
break;
}
@@ -2166,7 +2247,7 @@ bool Sema::InstantiateEnum(SourceLocation PointOfInstantiation,
}
InstantiatingTemplate Inst(*this, PointOfInstantiation, Instantiation);
- if (Inst)
+ if (Inst.isInvalid())
return true;
// Enter the scope of this instantiation. We don't use
@@ -2198,12 +2279,10 @@ namespace {
};
}
-bool
-Sema::InstantiateClassTemplateSpecialization(
- SourceLocation PointOfInstantiation,
- ClassTemplateSpecializationDecl *ClassTemplateSpec,
- TemplateSpecializationKind TSK,
- bool Complain) {
+bool Sema::InstantiateClassTemplateSpecialization(
+ SourceLocation PointOfInstantiation,
+ ClassTemplateSpecializationDecl *ClassTemplateSpec,
+ TemplateSpecializationKind TSK, bool Complain) {
// Perform the actual instantiation on the canonical declaration.
ClassTemplateSpec = cast<ClassTemplateSpecializationDecl>(
ClassTemplateSpec->getCanonicalDecl());
@@ -2252,15 +2331,18 @@ Sema::InstantiateClassTemplateSpecialization(
SmallVector<MatchResult, 4> Matched;
SmallVector<ClassTemplatePartialSpecializationDecl *, 4> PartialSpecs;
Template->getPartialSpecializations(PartialSpecs);
+ TemplateSpecCandidateSet FailedCandidates(PointOfInstantiation);
for (unsigned I = 0, N = PartialSpecs.size(); I != N; ++I) {
ClassTemplatePartialSpecializationDecl *Partial = PartialSpecs[I];
- TemplateDeductionInfo Info(PointOfInstantiation);
+ TemplateDeductionInfo Info(FailedCandidates.getLocation());
if (TemplateDeductionResult Result
= DeduceTemplateArguments(Partial,
ClassTemplateSpec->getTemplateArgs(),
Info)) {
- // FIXME: Store the failed-deduction information for use in
- // diagnostics, later.
+ // Store the failed-deduction information for use in diagnostics, later.
+ // TODO: Actually use the failed-deduction info?
+ FailedCandidates.addCandidate()
+ .set(Partial, MakeDeductionFailureInfo(Context, Result, Info));
(void)Result;
} else {
Matched.push_back(PartialSpecMatchResult());
@@ -2275,7 +2357,7 @@ Sema::InstantiateClassTemplateSpecialization(
SmallVector<const NamedDecl *, 4> InstantiatedTemplateParameters;
if (Matched.size() >= 1) {
- SmallVector<MatchResult, 4>::iterator Best = Matched.begin();
+ SmallVectorImpl<MatchResult>::iterator Best = Matched.begin();
if (Matched.size() == 1) {
// -- If exactly one matching specialization is found, the
// instantiation is generated from that specialization.
@@ -2288,8 +2370,8 @@ Sema::InstantiateClassTemplateSpecialization(
// specialized than all of the other matching
// specializations, then the use of the class template is
// ambiguous and the program is ill-formed.
- for (SmallVector<MatchResult, 4>::iterator P = Best + 1,
- PEnd = Matched.end();
+ for (SmallVectorImpl<MatchResult>::iterator P = Best + 1,
+ PEnd = Matched.end();
P != PEnd; ++P) {
if (getMoreSpecializedPartialSpecialization(P->Partial, Best->Partial,
PointOfInstantiation)
@@ -2300,8 +2382,8 @@ Sema::InstantiateClassTemplateSpecialization(
// Determine if the best partial specialization is more specialized than
// the others.
bool Ambiguous = false;
- for (SmallVector<MatchResult, 4>::iterator P = Matched.begin(),
- PEnd = Matched.end();
+ for (SmallVectorImpl<MatchResult>::iterator P = Matched.begin(),
+ PEnd = Matched.end();
P != PEnd; ++P) {
if (P != Best &&
getMoreSpecializedPartialSpecialization(P->Partial, Best->Partial,
@@ -2319,8 +2401,8 @@ Sema::InstantiateClassTemplateSpecialization(
<< ClassTemplateSpec;
// Print the matching partial specializations.
- for (SmallVector<MatchResult, 4>::iterator P = Matched.begin(),
- PEnd = Matched.end();
+ for (SmallVectorImpl<MatchResult>::iterator P = Matched.begin(),
+ PEnd = Matched.end();
P != PEnd; ++P)
Diag(P->Partial->getLocation(), diag::note_partial_spec_match)
<< getTemplateArgumentBindingsText(
@@ -2377,6 +2459,11 @@ Sema::InstantiateClassMembers(SourceLocation PointOfInstantiation,
CXXRecordDecl *Instantiation,
const MultiLevelTemplateArgumentList &TemplateArgs,
TemplateSpecializationKind TSK) {
+ assert(
+ (TSK == TSK_ExplicitInstantiationDefinition ||
+ TSK == TSK_ExplicitInstantiationDeclaration ||
+ (TSK == TSK_ImplicitInstantiation && Instantiation->isLocalClass())) &&
+ "Unexpected template specialization kind!");
for (DeclContext::decl_iterator D = Instantiation->decls_begin(),
DEnd = Instantiation->decls_end();
D != DEnd; ++D) {
@@ -2417,9 +2504,15 @@ Sema::InstantiateClassMembers(SourceLocation PointOfInstantiation,
InstantiateFunctionDefinition(PointOfInstantiation, Function);
} else {
Function->setTemplateSpecializationKind(TSK, PointOfInstantiation);
+ if (TSK == TSK_ImplicitInstantiation)
+ PendingLocalImplicitInstantiations.push_back(
+ std::make_pair(Function, PointOfInstantiation));
}
}
} else if (VarDecl *Var = dyn_cast<VarDecl>(*D)) {
+ if (isa<VarTemplateSpecializationDecl>(Var))
+ continue;
+
if (Var->isStaticDataMember()) {
MemberSpecializationInfo *MSInfo = Var->getMemberSpecializationInfo();
assert(MSInfo && "No member specialization information?");
@@ -2689,6 +2782,12 @@ LocalInstantiationScope::findInstantiationOf(const Decl *D) {
break;
}
+ // If we're performing a partial substitution during template argument
+ // deduction, we may not have values for template parameters yet.
+ if (isa<NonTypeTemplateParmDecl>(D) || isa<TemplateTypeParmDecl>(D) ||
+ isa<TemplateTemplateParmDecl>(D))
+ return 0;
+
// If we didn't find the decl, then we either have a sema bug, or we have a
// forward reference to a label declaration. Return null to indicate that
// we have an uninstantiated label.
OpenPOWER on IntegriCloud