]> granicus.if.org Git - clang/commitdiff
Allow type definitions inside anonymous struct/union in Microsoft mode.
authorFrancois Pichet <pichet2000@gmail.com>
Wed, 8 Sep 2010 11:32:25 +0000 (11:32 +0000)
committerFrancois Pichet <pichet2000@gmail.com>
Wed, 8 Sep 2010 11:32:25 +0000 (11:32 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@113354 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticGroups.td
include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaDecl.cpp
test/SemaCXX/MicrosoftExtensions.cpp

index dade38e4e346081bbb3ac0ac17cef030eb39fcf2..fa7c5cfc91e7c3d2f4f0803d807b860665399787 100644 (file)
@@ -227,3 +227,6 @@ def NonGCC : DiagGroup<"non-gcc",
 
 // A warning group for warnings about GCC extensions.
 def GNU : DiagGroup<"gnu", [GNUDesignator, VLA]>;
+
+// A warning group for warnings about Microsoft extensions.
+def Microsoft : DiagGroup<"microsoft">;
index 7ec98a69f39c827a0cd915e84f680aba8e9ad3ac..438d0fc1f8ca14ea70fac2f7803921f584c68632 100644 (file)
@@ -2850,6 +2850,9 @@ def err_anonymous_struct_member_redecl : Error<
   "member of anonymous struct redeclares %0">;
 def err_anonymous_record_with_type : Error<
   "types cannot be declared in an anonymous %select{struct|union}0">;
+def ext_anonymous_record_with_type : Extension<
+  "types declared in an anonymous %select{struct|union}0 are a Microsoft extension">,
+  InGroup<Microsoft>;
 def err_anonymous_record_with_function : Error<
   "functions cannot be declared in an anonymous %select{struct|union}0">;
 def err_anonymous_record_with_static : Error<
index 2b42fb60fbb17ed7cebbe657bfb5732a66ab498a..dbc758f1f2a97ce95cfb106d5d03e84555ba1222 100644 (file)
@@ -1898,10 +1898,16 @@ Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS,
       } else if (RecordDecl *MemRecord = dyn_cast<RecordDecl>(*Mem)) {
         if (!MemRecord->isAnonymousStructOrUnion() &&
             MemRecord->getDeclName()) {
-          // This is a nested type declaration.
-          Diag(MemRecord->getLocation(), diag::err_anonymous_record_with_type)
-            << (int)Record->isUnion();
-          Invalid = true;
+          // Visual C++ allows type definition in anonymous struct or union.
+          if (getLangOptions().Microsoft)
+            Diag(MemRecord->getLocation(), diag::ext_anonymous_record_with_type)
+              << (int)Record->isUnion();
+          else {
+            // This is a nested type declaration.
+            Diag(MemRecord->getLocation(), diag::err_anonymous_record_with_type)
+              << (int)Record->isUnion();
+            Invalid = true;
+          }
         }
       } else if (isa<AccessSpecDecl>(*Mem)) {
         // Any access specifier is fine.
@@ -1915,9 +1921,17 @@ Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS,
           DK = diag::err_anonymous_record_with_function;
         else if (isa<VarDecl>(*Mem))
           DK = diag::err_anonymous_record_with_static;
-        Diag((*Mem)->getLocation(), DK)
+        
+        // Visual C++ allows type definition in anonymous struct or union.
+        if (getLangOptions().Microsoft &&
+            DK == diag::err_anonymous_record_with_type)
+          Diag((*Mem)->getLocation(), diag::ext_anonymous_record_with_type)
             << (int)Record->isUnion();
+        else {
+          Diag((*Mem)->getLocation(), DK)
+              << (int)Record->isUnion();
           Invalid = true;
+        }
       }
     }
   }
index fb3107f44e979ea40b85c24a2a9de9fae68a33ed..93650a53f443b0c549a6edc0548c36eebf36dff5 100644 (file)
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -fsyntax-only -verify -fms-extensions -fexceptions
+// RUN: %clang_cc1 %s -fsyntax-only -Wmicrosoft -verify -fms-extensions -fexceptions
 
 
 // ::type_info is predeclared with forward class declartion
@@ -30,6 +30,48 @@ struct Derived : Base {
   virtual void f3();
 };
 
+
+// MSVC allows type definition in anonymous union and struct
+struct A
+{
+  union 
+  {
+    int a;
+    struct B  // expected-warning {{types declared in an anonymous union are a Microsoft extension}}
+    { 
+      int c;
+    } d;
+
+    union C   // expected-warning {{types declared in an anonymous union are a Microsoft extension}}
+    {
+      int e;
+      int ee;
+    } f;
+
+    typedef int D;  // expected-warning {{types declared in an anonymous union are a Microsoft extension}}
+    struct F;  // expected-warning {{types declared in an anonymous union are a Microsoft extension}}
+  };
+
+  struct
+  {
+    int a2;
+
+    struct B2  // expected-warning {{types declared in an anonymous struct are a Microsoft extension}}
+    {
+      int c2;
+    } d2;
+    
+       union C2  // expected-warning {{types declared in an anonymous struct are a Microsoft extension}}
+    {
+      int e2;
+      int ee2;
+    } f2;
+
+    typedef int D2;  // expected-warning {{types declared in an anonymous struct are a Microsoft extension}}
+    struct F2;  // expected-warning {{types declared in an anonymous struct are a Microsoft extension}}
+  };
+};
+
 // __stdcall handling
 struct M {
     int __stdcall addP();