[prev in list] [next in list] [prev in thread] [next in thread] 

List:       cfe-commits
Subject:    Re: [PATCH] D11194: Instantiate function declarations in instantiated functions.
From:       Serge Pavlov <sepavloff () gmail ! com>
Date:       2015-07-16 17:38:00
Message-ID: 6cba14e2c4384705d4636009b7139c47 () localhost ! localdomain
[Download RAW message or body]

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


["D11194.29921.patch" (text/x-patch)]

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


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic