sepavloff updated this revision to Diff 29921. sepavloff added a comment. Address reviewer's comments.
http://reviews.llvm.org/D11194 Files: lib/Sema/SemaTemplateInstantiate.cpp lib/Sema/SemaTemplateInstantiateDecl.cpp test/SemaTemplate/default-arguments.cpp test/SemaTemplate/instantiate-exception-spec-cxx11.cpp Index: test/SemaTemplate/instantiate-exception-spec-cxx11.cpp =================================================================== --- test/SemaTemplate/instantiate-exception-spec-cxx11.cpp +++ test/SemaTemplate/instantiate-exception-spec-cxx11.cpp @@ -178,3 +178,11 @@ } } + +namespace NondefDecls { + template<typename T> void f1() { + int g1(int) noexcept(T::error); // expected-error{{type 'int' cannot be used prior to '::' because it has no members}} + } + template void f1<int>(); // expected-note{{in instantiation of function template specialization 'NondefDecls::f1<int>' requested here}} +} + Index: test/SemaTemplate/default-arguments.cpp =================================================================== --- test/SemaTemplate/default-arguments.cpp +++ test/SemaTemplate/default-arguments.cpp @@ -159,3 +159,10 @@ int g() { X<int>::f(0); } // expected-note {{in instantiation of template class 'DR1635::X<int>' requested here}} } + +namespace NondefDecls { + template<typename T> void f1() { + int g1(int defarg = T::error); // expected-error{{type 'int' cannot be used prior to '::' because it has no members}} + } + template void f1<int>(); // expected-note{{in instantiation of function template specialization 'NondefDecls::f1<int>' requested here}} +} Index: lib/Sema/SemaTemplateInstantiateDecl.cpp =================================================================== --- lib/Sema/SemaTemplateInstantiateDecl.cpp +++ lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -3250,6 +3250,9 @@ if (CXXRecordDecl *Cls = dyn_cast<CXXRecordDecl>(Tmpl->getDeclContext())) { if (Cls->isLocalClass()) RequireInstantiation = true; + } else if (Tmpl->getLexicalDeclContext()->isFunctionOrMethod()) { + // This is a non-defining declaration of a file scope function. + RequireInstantiation = true; } if (SemaRef.getLangOpts().CPlusPlus11 && EPI.ExceptionSpec.Type != EST_None && Index: lib/Sema/SemaTemplateInstantiate.cpp =================================================================== --- lib/Sema/SemaTemplateInstantiate.cpp +++ lib/Sema/SemaTemplateInstantiate.cpp @@ -1691,6 +1691,16 @@ ExprResult NewArg = SubstExpr(Arg, TemplateArgs); if (NewArg.isUsable()) NewParm->setDefaultArg(NewArg.get()); + } else if (OwningFunc->getLexicalDeclContext()->isFunctionOrMethod()) { + // This is a function declaration within a function definition, as in: + // template<class T> void f() { + // void g(int x = T::v); + // } + Sema::ContextRAII SavedContext(*this, OwningFunc); + LocalInstantiationScope Local(*this); + ExprResult NewArg = SubstExpr(Arg, TemplateArgs); + if (NewArg.isUsable()) + NewParm->setDefaultArg(NewArg.get()); } else { // FIXME: if we non-lazily instantiated non-dependent default args for // non-dependent parameter types we could remove a bunch of duplicate
Index: test/SemaTemplate/instantiate-exception-spec-cxx11.cpp =================================================================== --- test/SemaTemplate/instantiate-exception-spec-cxx11.cpp +++ test/SemaTemplate/instantiate-exception-spec-cxx11.cpp @@ -178,3 +178,11 @@ } } + +namespace NondefDecls { + template<typename T> void f1() { + int g1(int) noexcept(T::error); // expected-error{{type 'int' cannot be used prior to '::' because it has no members}} + } + template void f1<int>(); // expected-note{{in instantiation of function template specialization 'NondefDecls::f1<int>' requested here}} +} + Index: test/SemaTemplate/default-arguments.cpp =================================================================== --- test/SemaTemplate/default-arguments.cpp +++ test/SemaTemplate/default-arguments.cpp @@ -159,3 +159,10 @@ int g() { X<int>::f(0); } // expected-note {{in instantiation of template class 'DR1635::X<int>' requested here}} } + +namespace NondefDecls { + template<typename T> void f1() { + int g1(int defarg = T::error); // expected-error{{type 'int' cannot be used prior to '::' because it has no members}} + } + template void f1<int>(); // expected-note{{in instantiation of function template specialization 'NondefDecls::f1<int>' requested here}} +} Index: lib/Sema/SemaTemplateInstantiateDecl.cpp =================================================================== --- lib/Sema/SemaTemplateInstantiateDecl.cpp +++ lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -3250,6 +3250,9 @@ if (CXXRecordDecl *Cls = dyn_cast<CXXRecordDecl>(Tmpl->getDeclContext())) { if (Cls->isLocalClass()) RequireInstantiation = true; + } else if (Tmpl->getLexicalDeclContext()->isFunctionOrMethod()) { + // This is a non-defining declaration of a file scope function. + RequireInstantiation = true; } if (SemaRef.getLangOpts().CPlusPlus11 && EPI.ExceptionSpec.Type != EST_None && Index: lib/Sema/SemaTemplateInstantiate.cpp =================================================================== --- lib/Sema/SemaTemplateInstantiate.cpp +++ lib/Sema/SemaTemplateInstantiate.cpp @@ -1691,6 +1691,16 @@ ExprResult NewArg = SubstExpr(Arg, TemplateArgs); if (NewArg.isUsable()) NewParm->setDefaultArg(NewArg.get()); + } else if (OwningFunc->getLexicalDeclContext()->isFunctionOrMethod()) { + // This is a function declaration within a function definition, as in: + // template<class T> void f() { + // void g(int x = T::v); + // } + Sema::ContextRAII SavedContext(*this, OwningFunc); + LocalInstantiationScope Local(*this); + ExprResult NewArg = SubstExpr(Arg, TemplateArgs); + if (NewArg.isUsable()) + NewParm->setDefaultArg(NewArg.get()); } else { // FIXME: if we non-lazily instantiated non-dependent default args for // non-dependent parameter types we could remove a bunch of duplicate
_______________________________________________ cfe-commits mailing list cfe-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits