[cfe-commits] r39322 - in /cfe/cfe/trunk: AST/Sema.h AST/SemaDecl.cpp Sema/Sema.h Sema/SemaDecl.cpp

sabre at cs.uiuc.edu sabre at cs.uiuc.edu
Wed Jul 11 09:43:05 PDT 2007


Author: sabre
Date: Wed Jul 11 11:43:04 2007
New Revision: 39322

URL: http://llvm.org/viewvc/llvm-project?rev=39322&view=rev
Log:
Refactor conflict handling code, no functionality change.

Modified:
    cfe/cfe/trunk/AST/Sema.h
    cfe/cfe/trunk/AST/SemaDecl.cpp
    cfe/cfe/trunk/Sema/Sema.h
    cfe/cfe/trunk/Sema/SemaDecl.cpp

Modified: cfe/cfe/trunk/AST/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/Sema.h?rev=39322&r1=39321&r2=39322&view=diff

==============================================================================
--- cfe/cfe/trunk/AST/Sema.h (original)
+++ cfe/cfe/trunk/AST/Sema.h Wed Jul 11 11:43:04 2007
@@ -25,9 +25,10 @@
   class Preprocessor;
   class Decl;
   class VarDecl;
+  class TypedefDecl;
+  class FunctionDecl;
   class TypeRef;
   class LangOptions;
-  class FunctionDecl;
   class DeclaratorChunk;
   
 /// Sema - This implements semantic analysis and AST building for C.
@@ -74,8 +75,11 @@
   virtual DeclTy *ParseFunctionDefBody(DeclTy *Decl, StmtTy *Body);
   virtual void PopScope(SourceLocation Loc, Scope *S);
   
-  Decl *ParseTypedefDecl(Scope *S, Declarator &D);
-  
+  TypedefDecl *ParseTypedefDecl(Scope *S, Declarator &D);
+  TypedefDecl *MergeTypeDefDecl(TypedefDecl *New, Decl *Old);
+  FunctionDecl *MergeFunctionDecl(FunctionDecl *New, Decl *Old);
+  VarDecl *MergeVarDecl(VarDecl *New, Decl *Old);
+
   /// ParsedFreeStandingDeclSpec - This method is invoked when a declspec with
   /// no declarator (e.g. "struct foo;") is parsed.
   virtual DeclTy *ParsedFreeStandingDeclSpec(Scope *S, DeclSpec &DS);  

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

==============================================================================
--- cfe/cfe/trunk/AST/SemaDecl.cpp (original)
+++ cfe/cfe/trunk/AST/SemaDecl.cpp Wed Jul 11 11:43:04 2007
@@ -74,10 +74,6 @@
   // TODO: emit error on 'typedef int;'
   // if (!DS.isMissingDeclaratorOk()) Diag(...);
   
-  // TODO: Register 'struct foo;' with the type system as an opaque struct.
-  
-  // TODO: Check that we don't already have 'union foo;' or something else
-  // that conflicts.
   return 0;
 }
 
@@ -95,34 +91,90 @@
   return 0;
 }
 
+/// MergeTypeDefDecl - We just parsed a typedef 'New' which has the same name
+/// and scope as a previous declaration 'Old'.  Figure out how to resolve this
+/// situation, merging decls or emitting diagnostics as appropriate.
+///
+TypedefDecl *Sema::MergeTypeDefDecl(TypedefDecl *New, Decl *Old) {
+  // TODO: CHECK FOR CONFLICTS, multiple decls with same name in one scope.
+  // TODO: This is totally simplistic.  It should handle merging functions
+  // together etc, merging extern int X; int X; ...
+  Diag(New->getLocation(), diag::err_redefinition, New->getName());
+  Diag(Old->getLocation(), diag::err_previous_definition);
+  return New;
+}
+
+/// MergeFunctionDecl - We just parsed a function 'New' which has the same name
+/// and scope as a previous declaration 'Old'.  Figure out how to resolve this
+/// situation, merging decls or emitting diagnostics as appropriate.
+///
+FunctionDecl *Sema::MergeFunctionDecl(FunctionDecl *New, Decl *Old) {
+  // TODO: CHECK FOR CONFLICTS, multiple decls with same name in one scope.
+  // TODO: This is totally simplistic.  It should handle merging functions
+  // together etc, merging extern int X; int X; ...
+  Diag(New->getLocation(), diag::err_redefinition, New->getName());
+  Diag(Old->getLocation(), diag::err_previous_definition);
+  return New;
+}
+
+/// MergeVarDecl - We just parsed a variable 'New' which has the same name
+/// and scope as a previous declaration 'Old'.  Figure out how to resolve this
+/// situation, merging decls or emitting diagnostics as appropriate.
+///
+VarDecl *Sema::MergeVarDecl(VarDecl *New, Decl *Old) {
+  // TODO: CHECK FOR CONFLICTS, multiple decls with same name in one scope.
+  // TODO: This is totally simplistic.  It should handle merging functions
+  // together etc, merging extern int X; int X; ...
+  Diag(New->getLocation(), diag::err_redefinition, New->getName());
+  Diag(Old->getLocation(), diag::err_previous_definition);
+  return New;
+}
+
 
 Action::DeclTy *
 Sema::ParseDeclarator(Scope *S, Declarator &D, ExprTy *Init, 
                       DeclTy *LastInGroup) {
   IdentifierInfo *II = D.getIdentifier();
   
-  if (Decl *PrevDecl = LookupScopedDecl(II, Decl::IDNS_Ordinary)) {
-    // TODO: CHECK FOR CONFLICTS, multiple decls with same name in one scope.
-    if (S->isDeclScope(PrevDecl)) {
-      // TODO: This is totally simplistic.  It should handle merging functions
-      // together etc, merging extern int X; int X; ...
-      Diag(D.getIdentifierLoc(), diag::err_redefinition, II->getName());
-      Diag(PrevDecl->getLocation(), diag::err_previous_definition);
-    }
-  }
-  
+  // See if this is a redefinition of a variable in the same scope.
+  Decl *PrevDecl = LookupScopedDecl(II, Decl::IDNS_Ordinary);
+  if (!S->isDeclScope(PrevDecl))
+    PrevDecl = 0;   // If in outer scope, it isn't the same thing.
+
   Decl *New;
   if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef) {
-    New = ParseTypedefDecl(S, D);
-    if (!New) return 0;
+    TypedefDecl *NewTD = ParseTypedefDecl(S, D);
+    if (!NewTD) return 0;
+    
+    // Merge the decl with the existing one if appropriate.
+    if (PrevDecl) {
+      NewTD = MergeTypeDefDecl(NewTD, PrevDecl);
+      if (NewTD == 0) return 0;
+    }
+    New = NewTD;
   } else if (D.isFunctionDeclarator()) {
     TypeRef R = GetTypeForDeclarator(D, S);
     if (R.isNull()) return 0;
-    New = new FunctionDecl(D.getIdentifierLoc(), II, R);
+    
+    FunctionDecl *NewFD = new FunctionDecl(D.getIdentifierLoc(), II, R);
+    
+    // Merge the decl with the existing one if appropriate.
+    if (PrevDecl) {
+      NewFD = MergeFunctionDecl(NewFD, PrevDecl);
+      if (NewFD == 0) return 0;
+    }
+    New = NewFD;
   } else {
     TypeRef R = GetTypeForDeclarator(D, S);
     if (R.isNull()) return 0;
-    New = new VarDecl(D.getIdentifierLoc(), II, R);
+    VarDecl *NewVD = new VarDecl(D.getIdentifierLoc(), II, R);
+
+    // Merge the decl with the existing one if appropriate.
+    if (PrevDecl) {
+      NewVD = MergeVarDecl(NewVD, PrevDecl);
+      if (NewVD == 0) return 0;
+    }
+    New = NewVD;
   }
   
   
@@ -259,7 +311,7 @@
 }
 
 
-Decl *Sema::ParseTypedefDecl(Scope *S, Declarator &D) {
+TypedefDecl *Sema::ParseTypedefDecl(Scope *S, Declarator &D) {
   assert(D.getIdentifier() && "Wrong callback for declspec withotu declarator");
   
   TypeRef T = GetTypeForDeclarator(D, S);

Modified: cfe/cfe/trunk/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Sema/Sema.h?rev=39322&r1=39321&r2=39322&view=diff

==============================================================================
--- cfe/cfe/trunk/Sema/Sema.h (original)
+++ cfe/cfe/trunk/Sema/Sema.h Wed Jul 11 11:43:04 2007
@@ -25,9 +25,10 @@
   class Preprocessor;
   class Decl;
   class VarDecl;
+  class TypedefDecl;
+  class FunctionDecl;
   class TypeRef;
   class LangOptions;
-  class FunctionDecl;
   class DeclaratorChunk;
   
 /// Sema - This implements semantic analysis and AST building for C.
@@ -74,8 +75,11 @@
   virtual DeclTy *ParseFunctionDefBody(DeclTy *Decl, StmtTy *Body);
   virtual void PopScope(SourceLocation Loc, Scope *S);
   
-  Decl *ParseTypedefDecl(Scope *S, Declarator &D);
-  
+  TypedefDecl *ParseTypedefDecl(Scope *S, Declarator &D);
+  TypedefDecl *MergeTypeDefDecl(TypedefDecl *New, Decl *Old);
+  FunctionDecl *MergeFunctionDecl(FunctionDecl *New, Decl *Old);
+  VarDecl *MergeVarDecl(VarDecl *New, Decl *Old);
+
   /// ParsedFreeStandingDeclSpec - This method is invoked when a declspec with
   /// no declarator (e.g. "struct foo;") is parsed.
   virtual DeclTy *ParsedFreeStandingDeclSpec(Scope *S, DeclSpec &DS);  

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

==============================================================================
--- cfe/cfe/trunk/Sema/SemaDecl.cpp (original)
+++ cfe/cfe/trunk/Sema/SemaDecl.cpp Wed Jul 11 11:43:04 2007
@@ -74,10 +74,6 @@
   // TODO: emit error on 'typedef int;'
   // if (!DS.isMissingDeclaratorOk()) Diag(...);
   
-  // TODO: Register 'struct foo;' with the type system as an opaque struct.
-  
-  // TODO: Check that we don't already have 'union foo;' or something else
-  // that conflicts.
   return 0;
 }
 
@@ -95,34 +91,90 @@
   return 0;
 }
 
+/// MergeTypeDefDecl - We just parsed a typedef 'New' which has the same name
+/// and scope as a previous declaration 'Old'.  Figure out how to resolve this
+/// situation, merging decls or emitting diagnostics as appropriate.
+///
+TypedefDecl *Sema::MergeTypeDefDecl(TypedefDecl *New, Decl *Old) {
+  // TODO: CHECK FOR CONFLICTS, multiple decls with same name in one scope.
+  // TODO: This is totally simplistic.  It should handle merging functions
+  // together etc, merging extern int X; int X; ...
+  Diag(New->getLocation(), diag::err_redefinition, New->getName());
+  Diag(Old->getLocation(), diag::err_previous_definition);
+  return New;
+}
+
+/// MergeFunctionDecl - We just parsed a function 'New' which has the same name
+/// and scope as a previous declaration 'Old'.  Figure out how to resolve this
+/// situation, merging decls or emitting diagnostics as appropriate.
+///
+FunctionDecl *Sema::MergeFunctionDecl(FunctionDecl *New, Decl *Old) {
+  // TODO: CHECK FOR CONFLICTS, multiple decls with same name in one scope.
+  // TODO: This is totally simplistic.  It should handle merging functions
+  // together etc, merging extern int X; int X; ...
+  Diag(New->getLocation(), diag::err_redefinition, New->getName());
+  Diag(Old->getLocation(), diag::err_previous_definition);
+  return New;
+}
+
+/// MergeVarDecl - We just parsed a variable 'New' which has the same name
+/// and scope as a previous declaration 'Old'.  Figure out how to resolve this
+/// situation, merging decls or emitting diagnostics as appropriate.
+///
+VarDecl *Sema::MergeVarDecl(VarDecl *New, Decl *Old) {
+  // TODO: CHECK FOR CONFLICTS, multiple decls with same name in one scope.
+  // TODO: This is totally simplistic.  It should handle merging functions
+  // together etc, merging extern int X; int X; ...
+  Diag(New->getLocation(), diag::err_redefinition, New->getName());
+  Diag(Old->getLocation(), diag::err_previous_definition);
+  return New;
+}
+
 
 Action::DeclTy *
 Sema::ParseDeclarator(Scope *S, Declarator &D, ExprTy *Init, 
                       DeclTy *LastInGroup) {
   IdentifierInfo *II = D.getIdentifier();
   
-  if (Decl *PrevDecl = LookupScopedDecl(II, Decl::IDNS_Ordinary)) {
-    // TODO: CHECK FOR CONFLICTS, multiple decls with same name in one scope.
-    if (S->isDeclScope(PrevDecl)) {
-      // TODO: This is totally simplistic.  It should handle merging functions
-      // together etc, merging extern int X; int X; ...
-      Diag(D.getIdentifierLoc(), diag::err_redefinition, II->getName());
-      Diag(PrevDecl->getLocation(), diag::err_previous_definition);
-    }
-  }
-  
+  // See if this is a redefinition of a variable in the same scope.
+  Decl *PrevDecl = LookupScopedDecl(II, Decl::IDNS_Ordinary);
+  if (!S->isDeclScope(PrevDecl))
+    PrevDecl = 0;   // If in outer scope, it isn't the same thing.
+
   Decl *New;
   if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef) {
-    New = ParseTypedefDecl(S, D);
-    if (!New) return 0;
+    TypedefDecl *NewTD = ParseTypedefDecl(S, D);
+    if (!NewTD) return 0;
+    
+    // Merge the decl with the existing one if appropriate.
+    if (PrevDecl) {
+      NewTD = MergeTypeDefDecl(NewTD, PrevDecl);
+      if (NewTD == 0) return 0;
+    }
+    New = NewTD;
   } else if (D.isFunctionDeclarator()) {
     TypeRef R = GetTypeForDeclarator(D, S);
     if (R.isNull()) return 0;
-    New = new FunctionDecl(D.getIdentifierLoc(), II, R);
+    
+    FunctionDecl *NewFD = new FunctionDecl(D.getIdentifierLoc(), II, R);
+    
+    // Merge the decl with the existing one if appropriate.
+    if (PrevDecl) {
+      NewFD = MergeFunctionDecl(NewFD, PrevDecl);
+      if (NewFD == 0) return 0;
+    }
+    New = NewFD;
   } else {
     TypeRef R = GetTypeForDeclarator(D, S);
     if (R.isNull()) return 0;
-    New = new VarDecl(D.getIdentifierLoc(), II, R);
+    VarDecl *NewVD = new VarDecl(D.getIdentifierLoc(), II, R);
+
+    // Merge the decl with the existing one if appropriate.
+    if (PrevDecl) {
+      NewVD = MergeVarDecl(NewVD, PrevDecl);
+      if (NewVD == 0) return 0;
+    }
+    New = NewVD;
   }
   
   
@@ -259,7 +311,7 @@
 }
 
 
-Decl *Sema::ParseTypedefDecl(Scope *S, Declarator &D) {
+TypedefDecl *Sema::ParseTypedefDecl(Scope *S, Declarator &D) {
   assert(D.getIdentifier() && "Wrong callback for declspec withotu declarator");
   
   TypeRef T = GetTypeForDeclarator(D, S);





More information about the cfe-commits mailing list