summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema
diff options
context:
space:
mode:
authorChandler Carruth <chandlerc@gmail.com>2010-08-25 08:27:02 +0000
committerChandler Carruth <chandlerc@gmail.com>2010-08-25 08:27:02 +0000
commitcfe41db403840e4b929db3e92f938f3da01bd772 (patch)
tree91378e92b5e607f9a378ae8dda4167349bc84078 /clang/lib/Sema
parent6b1533a1a95ad558827a2691b06c499ccf0c2932 (diff)
downloadbcm5719-llvm-cfe41db403840e4b929db3e92f938f3da01bd772.tar.gz
bcm5719-llvm-cfe41db403840e4b929db3e92f938f3da01bd772.zip
Support explicit instantiation of function templates and members of class
templates when only the declaration is in scope. This requires deferring the instantiation to be lazy, and ensuring the definition is required for that translation unit. We re-use the existing pending instantiation queue, previously only used to track implicit instantiations which were required to be lazy. Fixes PR7979. A subsequent change will rename *PendingImplicitInstantiations to *PendingInstatiations for clarity given its broader role. llvm-svn: 112037
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r--clang/lib/Sema/SemaTemplate.cpp6
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiateDecl.cpp32
2 files changed, 26 insertions, 12 deletions
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 8826b7f370f..e7c506810d6 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -5071,8 +5071,7 @@ Sema::DeclResult Sema::ActOnExplicitInstantiation(Scope *S,
// Instantiate static data member.
Prev->setTemplateSpecializationKind(TSK, D.getIdentifierLoc());
if (TSK == TSK_ExplicitInstantiationDefinition)
- InstantiateStaticDataMemberDefinition(D.getIdentifierLoc(), Prev, false,
- /*DefinitionRequired=*/true);
+ InstantiateStaticDataMemberDefinition(D.getIdentifierLoc(), Prev);
// FIXME: Create an ExplicitInstantiation node?
return (Decl*) 0;
@@ -5179,8 +5178,7 @@ Sema::DeclResult Sema::ActOnExplicitInstantiation(Scope *S,
Specialization->setTemplateSpecializationKind(TSK, D.getIdentifierLoc());
if (TSK == TSK_ExplicitInstantiationDefinition)
- InstantiateFunctionDefinition(D.getIdentifierLoc(), Specialization,
- false, /*DefinitionRequired=*/true);
+ InstantiateFunctionDefinition(D.getIdentifierLoc(), Specialization);
// C++0x [temp.explicit]p2:
// If the explicit instantiation is for a member function, a member class
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 39d7f234099..dd82114f2b0 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -2040,8 +2040,12 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
Diag(PatternDecl->getLocation(),
diag::note_explicit_instantiation_here);
Function->setInvalidDecl();
+ } else if (Function->getTemplateSpecializationKind()
+ == TSK_ExplicitInstantiationDefinition) {
+ PendingImplicitInstantiations.push_back(
+ std::make_pair(Function, PointOfInstantiation));
}
-
+
return;
}
@@ -2176,8 +2180,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) {
+ PendingImplicitInstantiations.push_back(
+ std::make_pair(Var, PointOfInstantiation));
+ }
+
return;
}
@@ -2714,8 +2722,10 @@ void Sema::PerformPendingImplicitInstantiations(bool LocalOnly) {
Function->getLocation(), *this,
Context.getSourceManager(),
"instantiating function definition");
-
- InstantiateFunctionDefinition(/*FIXME:*/Inst.second, Function, true);
+ bool DefinitionRequired = Function->getTemplateSpecializationKind() ==
+ TSK_ExplicitInstantiationDefinition;
+ InstantiateFunctionDefinition(/*FIXME:*/Inst.second, Function, true,
+ DefinitionRequired);
continue;
}
@@ -2734,9 +2744,12 @@ 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;
}
@@ -2746,7 +2759,10 @@ void Sema::PerformPendingImplicitInstantiations(bool LocalOnly) {
"instantiating static data member "
"definition");
- InstantiateStaticDataMemberDefinition(/*FIXME:*/Inst.second, Var, true);
+ bool DefinitionRequired = Var->getTemplateSpecializationKind() ==
+ TSK_ExplicitInstantiationDefinition;
+ InstantiateStaticDataMemberDefinition(/*FIXME:*/Inst.second, Var, true,
+ DefinitionRequired);
}
}
OpenPOWER on IntegriCloud