Initial implementation of anonymous unions (and, as a GNU extension,
structures and classes) in C++. Covers name lookup and the synthesis
and member access for the unnamed objects/fields associated with
anonymous unions.

Some C++ semantic checks are still missing (anonymous unions can't
have function members, static data members, etc.), and there is no
support for anonymous structs or unions in C.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@61840 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index bfe0272..bfe8a18 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -290,7 +290,7 @@
 }
 
 //===----------------------------------------------------------------------===//
-// TagdDecl Implementation
+// TagDecl Implementation
 //===----------------------------------------------------------------------===//
 
 TagDecl* TagDecl::getDefinition(ASTContext& C) const {
@@ -308,6 +308,7 @@
   : TagDecl(DK, TK, DC, L, Id, 0), DeclContext(DK) {
   
   HasFlexibleArrayMember = false;
+  AnonymousStructOrUnion = false;
   assert(classof(static_cast<Decl*>(this)) && "Invalid Kind!");
 }
 
diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp
index faaa104..cf612c2 100644
--- a/lib/AST/DeclBase.cpp
+++ b/lib/AST/DeclBase.cpp
@@ -412,7 +412,7 @@
   else if (DeclKind == Decl::LinkageSpec)
     return true;
   else if (DeclKind == Decl::Record || DeclKind == Decl::CXXRecord)
-    return false; // FIXME: need to know about anonymous unions/structs
+    return cast<RecordDecl>(this)->isAnonymousStructOrUnion();
   else if (DeclKind == Decl::Namespace)
     return false; // FIXME: Check for C++0x inline namespaces
 
diff --git a/lib/AST/DeclSerialization.cpp b/lib/AST/DeclSerialization.cpp
index 0a29813..38af462 100644
--- a/lib/AST/DeclSerialization.cpp
+++ b/lib/AST/DeclSerialization.cpp
@@ -618,6 +618,7 @@
   ScopedDecl::EmitInRec(S);
   S.EmitBool(isDefinition());
   S.EmitBool(hasFlexibleArrayMember());
+  S.EmitBool(isAnonymousStructOrUnion());
   ScopedDecl::EmitOutRec(S);
 }
 
@@ -630,6 +631,7 @@
   decl->ScopedDecl::ReadInRec(D, C);
   decl->setDefinition(D.ReadBool());
   decl->setHasFlexibleArrayMember(D.ReadBool());
+  decl->setAnonymousStructOrUnion(D.ReadBool());
   decl->ScopedDecl::ReadOutRec(D, C);
     
   return decl;