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) {