[cfe-commits] r39275 - in /cfe/cfe/trunk: AST/SemaDecl.cpp Sema/SemaDecl.cpp include/clang/Basic/DiagnosticKinds.def

sabre at cs.uiuc.edu sabre at cs.uiuc.edu
Wed Jul 11 09:42:20 PDT 2007


Author: sabre
Date: Wed Jul 11 11:42:19 2007
New Revision: 39275

URL: http://llvm.org/viewvc/llvm-project?rev=39275&view=rev
Log:
Diagnose mixing of tags.  For example, for:

struct blah * P;
union blah *P2;

we now emit:

t.c:2:1: error: redefinition of 'blah' with tag that does not match previous use
union blah *P2;
^
t.c:1:8: error: previous use is here
struct blah * P;
       ^

Modified:
    cfe/cfe/trunk/AST/SemaDecl.cpp
    cfe/cfe/trunk/Sema/SemaDecl.cpp
    cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def

Modified: cfe/cfe/trunk/AST/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/SemaDecl.cpp?rev=39275&r1=39274&r2=39275&view=diff

==============================================================================
--- cfe/cfe/trunk/AST/SemaDecl.cpp (original)
+++ cfe/cfe/trunk/AST/SemaDecl.cpp Wed Jul 11 11:42:19 2007
@@ -273,6 +273,14 @@
   // If this is a use of an existing tag, it must have a name.
   assert((isUse || Name != 0) && "Nameless record must have a name!");
   
+  Decl::Kind Kind = isUnion ? Decl::Union : Decl::Struct;
+  
+  // If there is an identifier, use the location of the identifier as the
+  // location of the decl, otherwise use the location of the struct/union
+  // keyword.
+  SourceLocation Loc = NameLoc.isValid() ? NameLoc : KWLoc;
+  
+  
   // If this is a named struct, check to see if there was a previous forward
   // declaration or definition.
   if (Decl *PrevDecl = LookupScopedDecl(Name, Decl::IDNS_Tag)) {
@@ -281,7 +289,12 @@
     // the same scope (so that the definition/declaration completes or
     // rementions the tag), reuse the decl.
     if (isUse || S->isDeclScope(PrevDecl)) {
-      
+      // Make sure that this wasn't declared as an enum and now used as a struct
+      // or something similar.
+      if (PrevDecl->getKind() != Kind) {
+        Diag(KWLoc, diag::err_redefinition_with_wrong_tag, Name->getName());
+        Diag(PrevDecl->getLocation(), diag::err_previous_use);
+      }
       
     }
     
@@ -291,13 +304,8 @@
     
   }
   
-  // If there is an identifier, use the location of the identifier as the
-  // location of the decl, otherwise use the location of the struct/union
-  // keyword.
-  SourceLocation Loc = NameLoc.isValid() ? NameLoc : KWLoc;
-  
   // Otherwise, if this is the first time we've seen this tag, create the decl.
-  Decl *New = new RecordDecl(isUnion ? Decl::Union : Decl::Struct, Loc, Name);
+  Decl *New = new RecordDecl(Kind, Loc, Name);
   
   // If this has an identifier, add it to the scope stack.
   if (Name) {

Modified: cfe/cfe/trunk/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Sema/SemaDecl.cpp?rev=39275&r1=39274&r2=39275&view=diff

==============================================================================
--- cfe/cfe/trunk/Sema/SemaDecl.cpp (original)
+++ cfe/cfe/trunk/Sema/SemaDecl.cpp Wed Jul 11 11:42:19 2007
@@ -273,6 +273,14 @@
   // If this is a use of an existing tag, it must have a name.
   assert((isUse || Name != 0) && "Nameless record must have a name!");
   
+  Decl::Kind Kind = isUnion ? Decl::Union : Decl::Struct;
+  
+  // If there is an identifier, use the location of the identifier as the
+  // location of the decl, otherwise use the location of the struct/union
+  // keyword.
+  SourceLocation Loc = NameLoc.isValid() ? NameLoc : KWLoc;
+  
+  
   // If this is a named struct, check to see if there was a previous forward
   // declaration or definition.
   if (Decl *PrevDecl = LookupScopedDecl(Name, Decl::IDNS_Tag)) {
@@ -281,7 +289,12 @@
     // the same scope (so that the definition/declaration completes or
     // rementions the tag), reuse the decl.
     if (isUse || S->isDeclScope(PrevDecl)) {
-      
+      // Make sure that this wasn't declared as an enum and now used as a struct
+      // or something similar.
+      if (PrevDecl->getKind() != Kind) {
+        Diag(KWLoc, diag::err_redefinition_with_wrong_tag, Name->getName());
+        Diag(PrevDecl->getLocation(), diag::err_previous_use);
+      }
       
     }
     
@@ -291,13 +304,8 @@
     
   }
   
-  // If there is an identifier, use the location of the identifier as the
-  // location of the decl, otherwise use the location of the struct/union
-  // keyword.
-  SourceLocation Loc = NameLoc.isValid() ? NameLoc : KWLoc;
-  
   // Otherwise, if this is the first time we've seen this tag, create the decl.
-  Decl *New = new RecordDecl(isUnion ? Decl::Union : Decl::Struct, Loc, Name);
+  Decl *New = new RecordDecl(Kind, Loc, Name);
   
   // If this has an identifier, add it to the scope stack.
   if (Name) {

Modified: cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=39275&r1=39274&r2=39275&view=diff

==============================================================================
--- cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/cfe/trunk/include/clang/Basic/DiagnosticKinds.def Wed Jul 11 11:42:19 2007
@@ -415,14 +415,19 @@
 DIAG(err_param_not_declared, ERROR,
      "parameter '%s' was not declared")
 
+DIAG(err_previous_definition, ERROR,
+     "previous definition is here")
+DIAG(err_previous_use, ERROR,
+     "previous use is here")
+
 DIAG(err_unexpected_typedef, ERROR,
      "unexpected type name '%s': expected expression")
 DIAG(err_undeclared_var_use, ERROR,
      "use of undeclared identifier '%s'")
 DIAG(err_redefinition, ERROR,
      "redefinition of '%s'")
-DIAG(err_previous_definition, ERROR,
-     "previous definition is here")
+DIAG(err_redefinition_with_wrong_tag, ERROR,
+     "redefinition of '%s' with tag that does not match previous use")
 
 DIAG(warn_implicit_function_decl, WARNING,
      "implicit declaration of function '%s'")





More information about the cfe-commits mailing list