[cfe-commits] r83550 - in /cfe/trunk: lib/Sema/SemaDecl.cpp test/CXX/temp/temp.spec/temp.expl.spec/p2.cpp
Douglas Gregor
dgregor at apple.com
Thu Oct 8 08:54:21 PDT 2009
Author: dgregor
Date: Thu Oct 8 10:54:21 2009
New Revision: 83550
URL: http://llvm.org/viewvc/llvm-project?rev=83550&view=rev
Log:
Don't complain about out-of-line explicit specializations of member
function and member function templates that are not definitions. Add
more tests to ensure that explicit specializations of member function
templates prevent instantiation.
Modified:
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p2.cpp
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=83550&r1=83549&r2=83550&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Thu Oct 8 10:54:21 2009
@@ -2852,9 +2852,11 @@
if (D.getCXXScopeSpec().isSet() && !NewFD->isInvalidDecl()) {
// An out-of-line member function declaration must also be a
// definition (C++ [dcl.meaning]p1).
- // FIXME: Find a better way to recognize out-of-line specializations!
+ // Note that this is not the case for explicit specializations of
+ // function templates or member functions of class templates, per
+ // C++ [temp.expl.spec]p2.
if (!IsFunctionDefinition && !isFriend &&
- !(TemplateParamLists.size() && !FunctionTemplate)) {
+ NewFD->getTemplateSpecializationKind() != TSK_ExplicitSpecialization) {
Diag(NewFD->getLocation(), diag::err_out_of_line_declaration)
<< D.getCXXScopeSpec().getRange();
NewFD->setInvalidDecl();
Modified: cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p2.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p2.cpp?rev=83550&r1=83549&r2=83550&view=diff
==============================================================================
--- cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p2.cpp (original)
+++ cfe/trunk/test/CXX/temp/temp.spec/temp.expl.spec/p2.cpp Thu Oct 8 10:54:21 2009
@@ -62,7 +62,7 @@
// expected-error{{base specifier}}
template<typename U>
- void ft1(T t, U u);
+ void ft1(T t, U u); // expected-note{{explicitly specialized}}
};
}
@@ -203,14 +203,37 @@
N0::X0<int>::InnerTemplate<long> inner_template2;
N0::X0<int>::InnerTemplate<unsigned long> inner_template3; // expected-note{{instantiation}}
-#if 0
-// FIXME: update the remainder of this test to check for scopes properly.
// -- member function template of a class template
-template<>
-template<>
-void X0<void*>::ft1(void*, const void*) { }
+namespace N0 {
+ template<>
+ template<>
+ void X0<void*>::ft1(void*, const void*) { }
+
+ template<> template<>
+ void X0<void*>::ft1(void *, int);
+
+ template<> template<>
+ void X0<void*>::ft1(void *, unsigned);
+
+ template<> template<>
+ void X0<void*>::ft1(void *, long);
+}
+
+template<> template<>
+void N0::X0<void*>::ft1(void *, unsigned) { } // okay
+
+template<> template<>
+void N0::X0<void*>::ft1(void *, float) { } // expected-error{{function template specialization}}
+
+namespace N1 {
+ template<> template<>
+ void N0::X0<void*>::ft1(void *, long) { } // expected-error{{enclosing}}
+}
+
-void test_func_template(X0<void *> xvp, void *vp, const void *cvp) {
+void test_func_template(N0::X0<void *> xvp, void *vp, const void *cvp,
+ int i, unsigned u) {
xvp.ft1(vp, cvp);
+ xvp.ft1(vp, i);
+ xvp.ft1(vp, u);
}
-#endif
More information about the cfe-commits
mailing list