Recognition of empty structures and unions is moved to semantic stage

Differential Revision: http://llvm-reviews.chandlerc.com/D586


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@183609 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 7be376e..e6a8946 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -11235,6 +11235,41 @@
 
     if (Record->hasAttrs())
       CheckAlignasUnderalignment(Record);
+
+    // Check if the structure/union declaration is a language extension.
+    if (!getLangOpts().CPlusPlus) {
+      bool ZeroSize = true;
+      bool UnnamedOnly = true;
+      unsigned UnnamedCnt = 0;
+      for (RecordDecl::field_iterator I = Record->field_begin(),
+                                      E = Record->field_end(); UnnamedOnly && I != E; ++I) {
+        if (I->isUnnamedBitfield()) {
+          UnnamedCnt++;
+          if (I->getBitWidthValue(Context) > 0)
+            ZeroSize = false;
+        } else {
+          UnnamedOnly = ZeroSize = false;
+        }
+      }
+
+      // Empty structs are an extension in C (C99 6.7.2.1p7), but are allowed in
+      // C++.
+      if (ZeroSize) {
+        if (UnnamedCnt == 0)
+          Diag(RecLoc, diag::warn_empty_struct_union_compat) << Record->isUnion();
+        else
+          Diag(RecLoc, diag::warn_zero_size_struct_union_compat) << Record->isUnion();
+      }
+
+      // Structs without named members are extension in C (C99 6.7.2.1p7), but
+      // are accepted by GCC.
+      if (UnnamedOnly) {
+        if (UnnamedCnt == 0)
+          Diag(RecLoc, diag::ext_empty_struct_union) << Record->isUnion();
+        else
+          Diag(RecLoc, diag::ext_no_named_members_in_struct_union) << Record->isUnion();
+      }
+    }
   } else {
     ObjCIvarDecl **ClsFields =
       reinterpret_cast<ObjCIvarDecl**>(RecFields.data());