When we see a reference to a struct, class, or union like "struct X"
that is neither a definition nor a forward declaration and where X has
not yet been declared as a tag, introduce a declaration
into the appropriate scope (which is likely *not* to be the current
scope). The rules for the placement of the declaration differ slightly
in C and C++, so we implement both and test the various corner
cases. This implementation isn't 100% correct due to some lingering
issues with the function prototype scope (for a function parameter
list) not being the same scope as the scope of the function
definition. Testcase is FIXME'd; this probably isn't an important issue.
Addresses <rdar://problem/6484805>.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@62014 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index 219295f..ac1a4be 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -526,7 +526,7 @@
// constructor declaration. We're done with the decl-specifiers
// and will treat this token as an identifier.
if (getLang().CPlusPlus &&
- CurScope->isCXXClassScope() &&
+ CurScope->isClassScope() &&
Actions.isCurrentClassName(*Tok.getIdentifierInfo(), CurScope) &&
NextToken().getKind() == tok::l_paren)
goto DoneWithDeclSpec;
@@ -948,7 +948,7 @@
unsigned TagType, DeclTy *TagDecl) {
SourceLocation LBraceLoc = ConsumeBrace();
- ParseScope StructScope(this, Scope::DeclScope);
+ ParseScope StructScope(this, Scope::ClassScope|Scope::DeclScope);
Actions.ActOnTagStartDefinition(CurScope, TagDecl);
// Empty structs are an extension in C (C99 6.7.2.1p7), but are allowed in
@@ -1875,7 +1875,7 @@
// Enter function-declaration scope, limiting any declarators to the
// function prototype scope, including parameter declarators.
- ParseScope PrototypeScope(this, Scope::FnScope|Scope::DeclScope);
+ ParseScope PrototypeScope(this, Scope::FunctionPrototypeScope|Scope::DeclScope);
bool IsVariadic = false;
while (1) {