[PATCH] Instantiate incomplete class used in template method.

Serge Pavlov sepavloff at gmail.com
Mon Apr 13 11:02:16 PDT 2015


Simplified patch.


http://reviews.llvm.org/D8281

Files:
  lib/Sema/SemaTemplateInstantiate.cpp
  lib/Sema/SemaTemplateInstantiateDecl.cpp
  test/SemaTemplate/instantiate-local-class.cpp

Index: lib/Sema/SemaTemplateInstantiate.cpp
===================================================================
--- lib/Sema/SemaTemplateInstantiate.cpp
+++ lib/Sema/SemaTemplateInstantiate.cpp
@@ -2796,6 +2796,11 @@
       isa<TemplateTemplateParmDecl>(D))
     return nullptr;
 
+  // If the declaration we are looking for is an incomplete or forward type
+  // declaration, we may not have a chance to instantiate it.
+  if (const TagDecl *TD = dyn_cast<TagDecl>(D))
+    return nullptr;
+
   // If we didn't find the decl, then we either have a sema bug, or we have a
   // forward reference to a label declaration.  Return null to indicate that
   // we have an uninstantiated label.
Index: lib/Sema/SemaTemplateInstantiateDecl.cpp
===================================================================
--- lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -4409,6 +4409,14 @@
     if (D->isInvalidDecl())
       return nullptr;
 
+    // If the declaration we are looking for is an incomplete or forward type
+    // declaration, we may not have a chance to instantiate it.
+    if (const TagDecl *TD = dyn_cast<TagDecl>(D)) {
+      Decl *Inst = SubstDecl(D, CurContext, TemplateArgs);
+      CurrentInstantiationScope->InstantiatedLocal(D, Inst);
+      return cast<TypeDecl>(Inst);
+    }
+
     // If we didn't find the decl, then we must have a label decl that hasn't
     // been found yet.  Lazily instantiate it and return it now.
     assert(isa<LabelDecl>(D));
Index: test/SemaTemplate/instantiate-local-class.cpp
===================================================================
--- test/SemaTemplate/instantiate-local-class.cpp
+++ test/SemaTemplate/instantiate-local-class.cpp
@@ -194,3 +194,22 @@
   void f() { F<int>(); }
 };
 }
+
+namespace PR18653 {
+  template <class T> void f();
+  template <class T> struct str {
+    void m() {
+      f<class newclass>();
+    }
+  };
+  template struct str<int>;
+
+  template<typename T> void f() { void g(struct x); }
+  template void f<int>();
+
+  template<typename T> void f2() {
+    void g2(struct x2);
+    struct x2 {};
+  }
+  template void f2<int>();
+}

EMAIL PREFERENCES
  http://reviews.llvm.org/settings/panel/emailpreferences/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D8281.23685.patch
Type: text/x-patch
Size: 2166 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20150413/4757c34a/attachment.bin>


More information about the cfe-commits mailing list