[PATCH] D11194: Instantiate function declarations in instantiated functions.
Serge Pavlov
sepavloff at gmail.com
Tue Jul 14 12:52:46 PDT 2015
sepavloff created this revision.
sepavloff added a subscriber: cfe-commits.
If a function declaration is found inside a template function as in:
template<class T> void f() {
void g(int x = T::v) except(T::w);
}
it must be instantiated along with the enclosing template function,
including default arguments and exception specification.
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,10 @@
if (CXXRecordDecl *Cls = dyn_cast<CXXRecordDecl>(Tmpl->getDeclContext())) {
if (Cls->isLocalClass())
RequireInstantiation = true;
+ } else if (Tmpl->getLexicalDeclContext()->isFunctionOrMethod() &&
+ !Tmpl->isThisDeclarationADefinition()) {
+ // 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,17 @@
ExprResult NewArg = SubstExpr(Arg, TemplateArgs);
if (NewArg.isUsable())
NewParm->setDefaultArg(NewArg.get());
+ } else if (OwningFunc->getLexicalDeclContext()->isFunctionOrMethod() &&
+ !OwningFunc->isThisDeclarationADefinition()) {
+ // 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
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D11194.29704.patch
Type: text/x-patch
Size: 3083 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20150714/2605b60e/attachment.bin>
More information about the cfe-commits
mailing list