[PATCH] Instantiate incomplete class used in template method.
Serge Pavlov
sepavloff at gmail.com
Mon Apr 6 12:49:24 PDT 2015
Updated 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,13 @@
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))
+ if (TD->getDefinition() ||
+ (!TD->isThisDeclarationADefinition() && !TD->isFreeStanding()))
+ 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
@@ -4399,6 +4399,21 @@
isa<TemplateTemplateParmDecl>(D))
return D;
+ // 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)) {
+ const TagDecl *DeclToInstantiate = nullptr;
+ if (TagDecl *Def = TD->getDefinition())
+ DeclToInstantiate = Def;
+ else if (!TD->isThisDeclarationADefinition() && !TD->isFreeStanding())
+ DeclToInstantiate = TD;
+ if (DeclToInstantiate) {
+ Decl *Inst = SubstDecl(D, CurContext, TemplateArgs);
+ CurrentInstantiationScope->InstantiatedLocal(D, Inst);
+ return cast<TypeDecl>(Inst);
+ }
+ }
+
if (D->isInvalidDecl())
return nullptr;
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.23288.patch
Type: text/x-patch
Size: 2448 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20150406/87228341/attachment.bin>
More information about the cfe-commits
mailing list