<div class="gmail_quote">On 3 February 2011 20:20, Douglas Gregor <span dir="ltr"><<a href="mailto:dgregor@apple.com">dgregor@apple.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
Author: dgregor<br>
Date: Thu Feb 3 22:20:44 2011<br>
New Revision: 124856<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=124856&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=124856&view=rev</a><br>
Log:<br>
Tighten up the semantics of default template arguments, per C++0x<br>
[temp.param]p9 and C++ DR226. Fixes PR8747.<br></blockquote><div><br></div><div>Hi Doug, I suspect this is the wrong PR#?</div><div><br></div><div>Nick</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<br>
Modified:<br>
cfe/trunk/include/clang/Sema/Sema.h<br>
cfe/trunk/lib/Sema/SemaDecl.cpp<br>
cfe/trunk/lib/Sema/SemaTemplate.cpp<br>
cfe/trunk/test/CXX/temp/temp.param/p9-0x.cpp<br>
<br>
Modified: cfe/trunk/include/clang/Sema/Sema.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=124856&r1=124855&r2=124856&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=124856&r1=124855&r2=124856&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Sema/Sema.h (original)<br>
+++ cfe/trunk/include/clang/Sema/Sema.h Thu Feb 3 22:20:44 2011<br>
@@ -2914,7 +2914,8 @@<br>
TPC_ClassTemplate,<br>
TPC_FunctionTemplate,<br>
TPC_ClassTemplateMember,<br>
- TPC_FriendFunctionTemplate<br>
+ TPC_FriendFunctionTemplate,<br>
+ TPC_FriendFunctionTemplateDefinition<br>
};<br>
<br>
bool CheckTemplateParameterList(TemplateParameterList *NewParams,<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=124856&r1=124855&r2=124856&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=124856&r1=124855&r2=124856&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Thu Feb 3 22:20:44 2011<br>
@@ -3967,8 +3967,14 @@<br>
FunctionTemplateDecl *PrevTemplate = FunctionTemplate->getPreviousDeclaration();<br>
CheckTemplateParameterList(FunctionTemplate->getTemplateParameters(),<br>
PrevTemplate? PrevTemplate->getTemplateParameters() : 0,<br>
- D.getDeclSpec().isFriendSpecified()? TPC_FriendFunctionTemplate<br>
- : TPC_FunctionTemplate);<br>
+ D.getDeclSpec().isFriendSpecified()<br>
+ ? (IsFunctionDefinition<br>
+ ? TPC_FriendFunctionTemplateDefinition<br>
+ : TPC_FriendFunctionTemplate)<br>
+ : (D.getCXXScopeSpec().isSet() &&<br>
+ DC && DC->isRecord())<br>
+ ? TPC_ClassTemplateMember<br>
+ : TPC_FunctionTemplate);<br>
}<br>
<br>
if (NewFD->isInvalidDecl()) {<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=124856&r1=124855&r2=124856&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=124856&r1=124855&r2=124856&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Thu Feb 3 22:20:44 2011<br>
@@ -946,7 +946,10 @@<br>
// template declaration.<br>
if (CheckTemplateParameterList(TemplateParams,<br>
PrevClassTemplate? PrevClassTemplate->getTemplateParameters() : 0,<br>
- TPC_ClassTemplate))<br>
+ (SS.isSet() && SemanticContext &&<br>
+ SemanticContext->isRecord())<br>
+ ? TPC_ClassTemplateMember<br>
+ : TPC_ClassTemplate))<br>
Invalid = true;<br>
<br>
if (SS.isSet()) {<br>
@@ -1045,11 +1048,15 @@<br>
return false;<br>
<br>
case Sema::TPC_FunctionTemplate:<br>
+ case Sema::TPC_FriendFunctionTemplateDefinition:<br>
// C++ [temp.param]p9:<br>
// A default template-argument shall not be specified in a<br>
// function template declaration or a function template<br>
// definition [...]<br>
- // (This sentence is not in C++0x, per DR226).<br>
+ // If a friend function template declaration specifies a default<br>
+ // template-argument, that declaration shall be a definition and shall be<br>
+ // the only declaration of the function template in the translation unit.<br>
+ // (C++98/03 doesn't have this wording; see DR226).<br>
if (!S.getLangOptions().CPlusPlus0x)<br>
S.Diag(ParamLoc,<br>
diag::ext_template_parameter_default_in_function_template)<br>
<br>
Modified: cfe/trunk/test/CXX/temp/temp.param/p9-0x.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.param/p9-0x.cpp?rev=124856&r1=124855&r2=124856&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.param/p9-0x.cpp?rev=124856&r1=124855&r2=124856&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/CXX/temp/temp.param/p9-0x.cpp (original)<br>
+++ cfe/trunk/test/CXX/temp/temp.param/p9-0x.cpp Thu Feb 3 22:20:44 2011<br>
@@ -12,3 +12,41 @@<br>
<br>
template<template<class> class ...Templates = vector> // expected-error{{template parameter pack cannot have a default argument}}<br>
struct X2;<br>
+<br>
+struct X3 {<br>
+ template<typename T = int> // expected-error{{default template argument not permitted on a friend template}}<br>
+ friend void f0(X3);<br>
+<br>
+ template<typename T = int><br>
+ friend void f1(X3) {<br>
+ }<br>
+};<br>
+<br>
+namespace PR8747 {<br>
+ // Testcase 1<br>
+ struct A0 { template<typename U> struct B; };<br>
+ template<typename U = int> struct A0::B { }; // expected-error{{cannot add a default template argument to the definition of a member of a class template}}<br>
+<br>
+ // Testcase 2<br>
+ template<typename T> struct A1 { template<typename U> struct B; };<br>
+ template<typename T> template<typename U = int> struct A1<T>::B { }; // expected-error{{cannot add a default template argument to the definition of a member of a class template}}<br>
+<br>
+ // Testcase 3<br>
+ template<typename T><br>
+ struct X2 {<br>
+ void f0();<br>
+ template<typename U> void f1();<br>
+ };<br>
+<br>
+ template<typename T = int> void X2<T>::f0() { } // expected-error{{cannot add a default template argument to the definition of a member of a class template}}<br>
+ template<typename T> template<typename U = int> void X2<T>::f1() { } // expected-error{{cannot add a default template argument to the definition of a member of a class template}}<br>
+<br>
+ namespace Inner {<br>
+ template<typename T> struct X3;<br>
+ template<typename T> void f2();<br>
+ }<br>
+<br>
+ // Okay; not class members.<br>
+ template<typename T = int> struct Inner::X3 { };<br>
+ template<typename T = int> void Inner::f2() {}<br>
+}<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br>