[cfe-commits] r84216 - in /cfe/trunk: lib/Sema/SemaTemplate.cpp test/SemaTemplate/extern-templates.cpp test/SemaTemplate/variadic-class-template-2.cpp
Douglas Gregor
dgregor at apple.com
Thu Oct 15 15:53:22 PDT 2009
Author: dgregor
Date: Thu Oct 15 17:53:21 2009
New Revision: 84216
URL: http://llvm.org/viewvc/llvm-project?rev=84216&view=rev
Log:
Make the remaining explicit-instantiation semantic action use
CheckSpecializationInstantiationRedecl to check for
redeclarations/instantiations. Also fixes a longstanding issue where
our explicit-instantiation location information wasn't as good as it
could have been.
Modified:
cfe/trunk/lib/Sema/SemaTemplate.cpp
cfe/trunk/test/SemaTemplate/extern-templates.cpp
cfe/trunk/test/SemaTemplate/variadic-class-template-2.cpp
Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=84216&r1=84215&r2=84216&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Thu Oct 15 17:53:21 2009
@@ -3630,54 +3630,18 @@
ClassTemplateSpecializationDecl *Specialization = 0;
- bool SpecializationRequiresInstantiation = true;
if (PrevDecl) {
- if (PrevDecl->getSpecializationKind()
- == TSK_ExplicitInstantiationDefinition) {
- // This particular specialization has already been declared or
- // instantiated. We cannot explicitly instantiate it.
- Diag(TemplateNameLoc, diag::err_explicit_instantiation_duplicate)
- << Context.getTypeDeclType(PrevDecl);
- Diag(PrevDecl->getLocation(),
- diag::note_previous_explicit_instantiation);
+ bool SuppressNew = false;
+ if (CheckSpecializationInstantiationRedecl(*this, TemplateNameLoc, TSK,
+ PrevDecl,
+ PrevDecl->getSpecializationKind(),
+ PrevDecl->getPointOfInstantiation(),
+ SuppressNew))
return DeclPtrTy::make(PrevDecl);
- }
- if (PrevDecl->getSpecializationKind() == TSK_ExplicitSpecialization) {
- // C++ DR 259, C++0x [temp.explicit]p4:
- // For a given set of template parameters, if an explicit
- // instantiation of a template appears after a declaration of
- // an explicit specialization for that template, the explicit
- // instantiation has no effect.
- if (!getLangOptions().CPlusPlus0x) {
- Diag(TemplateNameLoc,
- diag::ext_explicit_instantiation_after_specialization)
- << Context.getTypeDeclType(PrevDecl);
- Diag(PrevDecl->getLocation(),
- diag::note_previous_template_specialization);
- }
-
- // Create a new class template specialization declaration node
- // for this explicit specialization. This node is only used to
- // record the existence of this explicit instantiation for
- // accurate reproduction of the source code; we don't actually
- // use it for anything, since it is semantically irrelevant.
- Specialization
- = ClassTemplateSpecializationDecl::Create(Context,
- ClassTemplate->getDeclContext(),
- TemplateNameLoc,
- ClassTemplate,
- Converted, 0);
- Specialization->setLexicalDeclContext(CurContext);
- CurContext->addDecl(Specialization);
+ if (SuppressNew)
return DeclPtrTy::make(PrevDecl);
- }
-
- // If we have already (implicitly) instantiated this
- // specialization, there is less work to do.
- if (PrevDecl->getSpecializationKind() == TSK_ImplicitInstantiation)
- SpecializationRequiresInstantiation = false;
-
+
if (PrevDecl->getSpecializationKind() == TSK_ImplicitInstantiation ||
PrevDecl->getSpecializationKind() == TSK_Undeclared) {
// Since the only prior class template specialization with these
@@ -3688,7 +3652,7 @@
Specialization->setLocation(TemplateNameLoc);
PrevDecl = 0;
}
- }
+ }
if (!Specialization) {
// Create a new class template specialization declaration node for
@@ -3741,11 +3705,13 @@
//
// This check comes when we actually try to perform the
// instantiation.
- if (SpecializationRequiresInstantiation)
+ ClassTemplateSpecializationDecl *Def
+ = cast_or_null<ClassTemplateSpecializationDecl>(
+ Specialization->getDefinition(Context));
+ if (!Def)
InstantiateClassTemplateSpecialization(Specialization, TSK);
else // Instantiate the members of this class template specialization.
- InstantiateClassTemplateSpecializationMembers(TemplateLoc, Specialization,
- TSK);
+ InstantiateClassTemplateSpecializationMembers(TemplateNameLoc, Def, TSK);
return DeclPtrTy::make(Specialization);
}
@@ -3836,7 +3802,9 @@
return TagD;
}
- if (!Record->getDefinition(Context)) {
+ CXXRecordDecl *RecordDef
+ = cast_or_null<CXXRecordDecl>(Record->getDefinition(Context));
+ if (!RecordDef) {
// C++ [temp.explicit]p3:
// A definition of a member class of a class template shall be in scope
// at the point of an explicit instantiation of the member class.
@@ -3848,12 +3816,12 @@
Diag(Pattern->getLocation(), diag::note_forward_declaration)
<< Pattern;
return true;
- } else if (InstantiateClass(TemplateLoc, Record, Def,
+ } else if (InstantiateClass(NameLoc, Record, Def,
getTemplateInstantiationArgs(Record),
TSK))
return true;
} else // Instantiate all of the members of the class.
- InstantiateClassMembers(TemplateLoc, Record,
+ InstantiateClassMembers(NameLoc, RecordDef,
getTemplateInstantiationArgs(Record), TSK);
// FIXME: We don't have any representation for explicit instantiations of
Modified: cfe/trunk/test/SemaTemplate/extern-templates.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/extern-templates.cpp?rev=84216&r1=84215&r2=84216&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/extern-templates.cpp (original)
+++ cfe/trunk/test/SemaTemplate/extern-templates.cpp Thu Oct 15 17:53:21 2009
@@ -29,16 +29,14 @@
xii.g(0);
}
-// FIXME: we would like the notes to point to the explicit instantiation at the
-// bottom.
-extern template class X0<long*>; // expected-note 2{{instantiation}}
+extern template class X0<long*>;
void test_longptr(X0<long*> xl, X0<long*>::Inner xli) {
xl.f(0);
xli.g(0);
}
-template class X0<long*>;
+template class X0<long*>; // expected-note 2{{instantiation}}
template<typename T>
class X1 {
Modified: cfe/trunk/test/SemaTemplate/variadic-class-template-2.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/variadic-class-template-2.cpp?rev=84216&r1=84215&r2=84216&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/variadic-class-template-2.cpp (original)
+++ cfe/trunk/test/SemaTemplate/variadic-class-template-2.cpp Thu Oct 15 17:53:21 2009
@@ -14,6 +14,6 @@
template <typename = int, typename ...> struct TS3 {}; // expected-note{{template parameter is declared here}}
template struct TS3<>; // expected-note{{previous explicit instantiation is here}}
-template struct TS3<int>; // expected-error{{duplicate explicit instantiation of 'TS3<>'}}
+template struct TS3<int>; // expected-error{{duplicate explicit instantiation of 'TS3}}
template struct TS3<int, int>;
template struct TS3<10>; // expected-error{{template argument for template type parameter must be a type}}
More information about the cfe-commits
mailing list