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