summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaTemplate.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-10-08 15:14:33 +0000
committerDouglas Gregor <dgregor@apple.com>2009-10-08 15:14:33 +0000
commitbbe8f466211771b1a96b1eede898f9380b14dd6f (patch)
treef122ca444fc6ea0ecb3f895eacb214c3a342bff4 /clang/lib/Sema/SemaTemplate.cpp
parent86d142a80113e9e1d11996f7d5bd9baecfd5a69f (diff)
downloadbcm5719-llvm-bbe8f466211771b1a96b1eede898f9380b14dd6f.tar.gz
bcm5719-llvm-bbe8f466211771b1a96b1eede898f9380b14dd6f.zip
Improve checking for specializations of member classes of class
templates, and keep track of how those member classes were instantiated or specialized. Make sure that we don't try to instantiate an explicitly-specialized member class of a class template, when that explicit specialization was a declaration rather than a definition. llvm-svn: 83547
Diffstat (limited to 'clang/lib/Sema/SemaTemplate.cpp')
-rw-r--r--clang/lib/Sema/SemaTemplate.cpp41
1 files changed, 31 insertions, 10 deletions
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 5c6ec0004af..219d73146ea 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -2360,15 +2360,13 @@ static TemplateSpecializationKind getTemplateSpecializationKind(NamedDecl *D) {
if (!D)
return TSK_Undeclared;
- if (ClassTemplateSpecializationDecl *CTS
- = dyn_cast<ClassTemplateSpecializationDecl>(D))
- return CTS->getSpecializationKind();
+ if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(D))
+ return Record->getTemplateSpecializationKind();
if (FunctionDecl *Function = dyn_cast<FunctionDecl>(D))
return Function->getTemplateSpecializationKind();
if (VarDecl *Var = dyn_cast<VarDecl>(D))
return Var->getTemplateSpecializationKind();
- // FIXME: member classes of class templates!
return TSK_Undeclared;
}
@@ -3192,23 +3190,46 @@ Sema::CheckMemberSpecialization(NamedDecl *Member, NamedDecl *&PrevDecl) {
// FIXME: Check for specialization-after-instantiation errors and such.
// Note that this is an explicit instantiation of a member.
+ // the original declaration to note that it is an explicit specialization
+ // (if it was previously an implicit instantiation). This latter step
+ // makes bookkeeping easier.
if (isa<FunctionDecl>(Member)) {
- // FIXME: We're also setting the original instantiation we found to be
- // an explicit specialization, although I'd rather not have to do this.
- cast<FunctionDecl>(Instantiation)->setTemplateSpecializationKind(
- TSK_ExplicitSpecialization);
+ FunctionDecl *InstantiationFunction = cast<FunctionDecl>(Instantiation);
+ if (InstantiationFunction->getTemplateSpecializationKind() ==
+ TSK_ImplicitInstantiation) {
+ InstantiationFunction->setTemplateSpecializationKind(
+ TSK_ExplicitSpecialization);
+ InstantiationFunction->setLocation(Member->getLocation());
+ }
+
cast<FunctionDecl>(Member)->setInstantiationOfMemberFunction(
cast<CXXMethodDecl>(InstantiatedFrom),
TSK_ExplicitSpecialization);
} else if (isa<VarDecl>(Member)) {
+ VarDecl *InstantiationVar = cast<VarDecl>(Instantiation);
+ if (InstantiationVar->getTemplateSpecializationKind() ==
+ TSK_ImplicitInstantiation) {
+ InstantiationVar->setTemplateSpecializationKind(
+ TSK_ExplicitSpecialization);
+ InstantiationVar->setLocation(Member->getLocation());
+ }
+
Context.setInstantiatedFromStaticDataMember(cast<VarDecl>(Member),
cast<VarDecl>(InstantiatedFrom),
TSK_ExplicitSpecialization);
} else {
assert(isa<CXXRecordDecl>(Member) && "Only member classes remain");
- // FIXME: Record TSK_ExplicitSpecialization.
+ CXXRecordDecl *InstantiationClass = cast<CXXRecordDecl>(Instantiation);
+ if (InstantiationClass->getTemplateSpecializationKind() ==
+ TSK_ImplicitInstantiation) {
+ InstantiationClass->setTemplateSpecializationKind(
+ TSK_ExplicitSpecialization);
+ InstantiationClass->setLocation(Member->getLocation());
+ }
+
cast<CXXRecordDecl>(Member)->setInstantiationOfMemberClass(
- cast<CXXRecordDecl>(InstantiatedFrom));
+ cast<CXXRecordDecl>(InstantiatedFrom),
+ TSK_ExplicitSpecialization);
}
// Save the caller the trouble of having to figure out which declaration
OpenPOWER on IntegriCloud