]> granicus.if.org Git - clang/commitdiff
In C++, allow a declaration of an enum to follow a definition of that
authorDouglas Gregor <dgregor@apple.com>
Tue, 22 Jun 2010 14:26:35 +0000 (14:26 +0000)
committerDouglas Gregor <dgregor@apple.com>
Tue, 22 Jun 2010 14:26:35 +0000 (14:26 +0000)
enum as a GNU extension.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@106540 91177308-0d34-0410-b5e6-96231b3b80d8

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

index 5665cf0c87b0fc8c67fbd97a17af05cd3b73981b..e5c16fbe4386191b84419d8e66f79b4efe8954fa 100644 (file)
@@ -1722,6 +1722,9 @@ def ext_forward_ref_enum : Extension<
   "ISO C forbids forward references to 'enum' types">;
 def err_forward_ref_enum : Error<
   "ISO C++ forbids forward references to 'enum' types">;
+def ext_forward_ref_enum_def : Extension<
+  "redeclaration of already-defined enum %0 is a GNU extension">, InGroup<GNU>;
+  
 def err_redefinition_of_enumerator : Error<"redefinition of enumerator %0">;
 def err_duplicate_member : Error<"duplicate member %0">;
 def err_misplaced_ivar : Error<
index 4a7c877fd98782a3c9d6f4c2748a27c06297e767..ebfb9810d6608a3f6658255ac29962d3b1426ca5 100644 (file)
@@ -5401,10 +5401,17 @@ CreateNewDecl:
     New = EnumDecl::Create(Context, SearchDC, Loc, Name, KWLoc,
                            cast_or_null<EnumDecl>(PrevDecl));
     // If this is an undefined enum, warn.
-    if (TUK != TUK_Definition && !Invalid)  {
-      unsigned DK = getLangOptions().CPlusPlus? diag::err_forward_ref_enum
-                                              : diag::ext_forward_ref_enum;
-      Diag(Loc, DK);
+    if (TUK != TUK_Definition && !Invalid) {
+      TagDecl *Def;
+      if (PrevDecl && (Def = cast<EnumDecl>(PrevDecl)->getDefinition())) {
+        Diag(Loc, diag::ext_forward_ref_enum_def)
+          << New;
+        Diag(Def->getLocation(), diag::note_previous_definition);
+      } else {
+        Diag(Loc, 
+             getLangOptions().CPlusPlus? diag::err_forward_ref_enum
+                                       : diag::ext_forward_ref_enum);
+      }
     }
   } else {
     // struct/union/class
index bfb5784dd161f06ad5c5b07361d7e37a1796cc37..3a66617e0d191bc4f487cd5848f4d12c37994de2 100644 (file)
@@ -1,9 +1,11 @@
 // RUN: %clang_cc1 -fsyntax-only -pedantic -std=c++98 -verify -triple x86_64-apple-darwin %s
-enum E {
+enum E { // expected-note{{previous definition is here}}
   Val1,
   Val2
 };
 
+enum E; // expected-warning{{redeclaration of already-defined enum 'E' is a GNU extension}}
+
 int& enumerator_type(int);
 float& enumerator_type(E);