Implement explicit instantiations of member classes of class templates, e.g.,
template<typename T>
struct X {
struct Inner;
};
template struct X<int>::Inner;
This change is larger than it looks because it also fixes some
a problem with nested-name-specifiers and tags. We weren't requiring
the DeclContext associated with the scope specifier of a tag to be
complete. Therefore, when looking for something like "struct
X<int>::Inner", we weren't instantiating X<int>.
This, naturally, uncovered a problem with member pointers, where we
were requiring the left-hand side of a member pointer access
expression (e.g., x->*) to be a complete type. However, this is wrong:
the semantics of this expression does not require a complete type (EDG
agrees).
Stuart vouched for me. Blame him.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@71756 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 5914292..e27517e 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -3254,12 +3254,15 @@
goto CreateNewDecl;
}
- // FIXME: RequireCompleteDeclContext(SS)?
+ if (RequireCompleteDeclContext(SS))
+ return DeclPtrTy::make((Decl *)0);
+
DC = computeDeclContext(SS);
SearchDC = DC;
// Look-up name inside 'foo::'.
- PrevDecl = dyn_cast_or_null<TagDecl>(
- LookupQualifiedName(DC, Name, LookupTagName, true).getAsDecl());
+ PrevDecl
+ = dyn_cast_or_null<TagDecl>(
+ LookupQualifiedName(DC, Name, LookupTagName, true).getAsDecl());
// A tag 'foo::bar' must already exist.
if (PrevDecl == 0) {