[cfe-commits] r39357 - in /cfe/cfe/trunk: AST/ASTContext.cpp AST/Sema.h AST/SemaDecl.cpp Driver/X86Builtins.def Sema/Sema.h Sema/SemaDecl.cpp include/clang/AST/Decl.h include/clang/AST/Type.h

snaroff at cs.uiuc.edu snaroff at cs.uiuc.edu
Wed Jul 11 09:43:33 PDT 2007


Author: snaroff
Date: Wed Jul 11 11:43:33 2007
New Revision: 39357

URL: http://llvm.org/viewvc/llvm-project?rev=39357&view=rev
Log:
Bug #:
Submitted by:
Reviewed by:
carbon.h looking good! Only 1 warning left...no parse errors!

This fixes 3 bugs...
- A couple tricky bugs with type canonicalization. Nested typedef's  weren't being
handled properly. For example, the following didn't work:

typdef int __darwin_pid_t;
typedef __darwin_pid_t pid_t;

int getpgid(pid_t);
int getpgid(int);

- The storage class wasn't being preserved. As a result, Sema was complaining
about the  following:

extern char *foo;
char *foo;

- various built-ins weren't registered...resulting in spurious warnings.

Modified:
    cfe/cfe/trunk/AST/ASTContext.cpp
    cfe/cfe/trunk/AST/Sema.h
    cfe/cfe/trunk/AST/SemaDecl.cpp
    cfe/cfe/trunk/Driver/X86Builtins.def
    cfe/cfe/trunk/Sema/Sema.h
    cfe/cfe/trunk/Sema/SemaDecl.cpp
    cfe/cfe/trunk/include/clang/AST/Decl.h
    cfe/cfe/trunk/include/clang/AST/Type.h

Modified: cfe/cfe/trunk/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/AST/ASTContext.cpp?rev=39357&r1=39356&r2=39357&view=diff

==============================================================================
--- cfe/cfe/trunk/AST/ASTContext.cpp (original)
+++ cfe/cfe/trunk/AST/ASTContext.cpp Wed Jul 11 11:43:33 2007
@@ -15,6 +15,7 @@
 #include "clang/AST/Decl.h"
 #include "clang/Lex/Preprocessor.h"
 #include "llvm/ADT/SmallVector.h"
+
 using namespace llvm;
 using namespace clang;
 
@@ -268,7 +269,7 @@
   if (Decl->TypeForDecl) return Decl->TypeForDecl;
   
   // FIXME: does this lose qualifiers from the typedef??
-  Type *Canonical = Decl->getUnderlyingType().getTypePtr();
+  Type *Canonical = Decl->getUnderlyingType().getCanonicalType().getTypePtr();
   Types.push_back(Decl->TypeForDecl = new TypedefType(Decl, Canonical));
   return Types.back();
 }

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

==============================================================================
--- cfe/cfe/trunk/AST/Sema.h (original)
+++ cfe/cfe/trunk/AST/Sema.h Wed Jul 11 11:43:33 2007
@@ -98,7 +98,7 @@
   TypedefDecl *MergeTypeDefDecl(TypedefDecl *New, Decl *Old);
   FunctionDecl *MergeFunctionDecl(FunctionDecl *New, Decl *Old);
   VarDecl *MergeVarDecl(VarDecl *New, Decl *Old);
-  
+
   /// More parsing and symbol table subroutines...
   VarDecl *ParseParamDeclarator(DeclaratorChunk &FI, unsigned ArgNo,
                                 Scope *FnBodyScope);

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

==============================================================================
--- cfe/cfe/trunk/AST/SemaDecl.cpp (original)
+++ cfe/cfe/trunk/AST/SemaDecl.cpp Wed Jul 11 11:43:33 2007
@@ -96,7 +96,6 @@
       Context.Target.DiagnoseNonPortability(IdLoc,
                                             diag::port_target_builtin_use);
     }
-    
     // If this is a builtin on this (or all) targets, create the decl.
     if (unsigned BuiltinID = II->getBuiltinID())
       return LazilyCreateBuiltin(II, BuiltinID, S);
@@ -172,7 +171,8 @@
   // This is not right, but it's a start.  If 'Old' is a function prototype with
   // the same type as 'New', silently allow this.  FIXME: We should link up decl
   // objects here.
-  if (Old->getBody() == 0 && Old->getType() == New->getType()) {
+  if (Old->getBody() == 0 && 
+      Old->getCanonicalType() == New->getCanonicalType()) {
     return New;
   }
   
@@ -197,12 +197,17 @@
     Diag(OldD->getLocation(), diag::err_previous_definition);
     return New;
   }
-  
-  // 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);
+  // Verify the types match.
+  if (Old->getCanonicalType() != New->getCanonicalType()) {
+    Diag(New->getLocation(), diag::err_redefinition, New->getName());
+    Diag(Old->getLocation(), diag::err_previous_definition);
+    return New;
+  }
+  // We've verified the types match, now check if Old is "extern".
+  if (Old->getStorageClass() != ObjectDecl::Extern) {
+    Diag(New->getLocation(), diag::err_redefinition, New->getName());
+    Diag(Old->getLocation(), diag::err_previous_definition);
+  }
   return New;
 }
 
@@ -254,8 +259,19 @@
   } else {
     TypeRef R = GetTypeForDeclarator(D, S);
     if (R.isNull()) return 0;
-    VarDecl *NewVD = new VarDecl(D.getIdentifierLoc(), II, R);
 
+    ObjectDecl::StorageClass S;
+    switch (D.getDeclSpec().getStorageClassSpec()) {
+      default: assert(0 && "Unknown storage class!");
+      case 0: S = ObjectDecl::None;
+      case DeclSpec::SCS_extern:   S = ObjectDecl::Extern; break;
+      case DeclSpec::SCS_static:   S = ObjectDecl::Static; break;
+      // The following 2 should never be seen in this context.
+      case DeclSpec::SCS_auto:     S = ObjectDecl::Auto; break;
+      case DeclSpec::SCS_register: S = ObjectDecl::Register; break;
+    }
+    VarDecl *NewVD = new VarDecl(D.getIdentifierLoc(), II, R, S);
+    
     // Merge the decl with the existing one if appropriate.
     if (PrevDecl) {
       NewVD = MergeVarDecl(NewVD, PrevDecl);
@@ -294,9 +310,11 @@
     
   }
   
+  // FIXME: Handle storage class (auto, register). No declarator?
   VarDecl *New = new VarDecl(PI.IdentLoc, II, 
-                             TypeRef::getFromOpaquePtr(PI.TypeInfo));
-  
+                             TypeRef::getFromOpaquePtr(PI.TypeInfo), 
+                             ObjectDecl::None);
+
   // If this has an identifier, add it to the scope stack.
   if (II) {
     New->setNext(II->getFETokenInfo<Decl>());

Modified: cfe/cfe/trunk/Driver/X86Builtins.def
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/Driver/X86Builtins.def?rev=39357&r1=39356&r2=39357&view=diff

==============================================================================
--- cfe/cfe/trunk/Driver/X86Builtins.def (original)
+++ cfe/cfe/trunk/Driver/X86Builtins.def Wed Jul 11 11:43:33 2007
@@ -361,6 +361,14 @@
 BUILTIN(__builtin_ia32_mfence, "v", "")
 BUILTIN(__builtin_ia32_loaddqu, "v", "")
 BUILTIN(__builtin_ia32_storedqu, "v", "")
+BUILTIN(__builtin_ia32_psllwi, "v", "")
+BUILTIN(__builtin_ia32_pslldi, "v", "")
+BUILTIN(__builtin_ia32_psllqi, "v", "")
+BUILTIN(__builtin_ia32_psrawi, "v", "")
+BUILTIN(__builtin_ia32_psradi, "v", "")
+BUILTIN(__builtin_ia32_psrlwi, "v", "")
+BUILTIN(__builtin_ia32_psrldi, "v", "")
+BUILTIN(__builtin_ia32_psrlqi, "v", "")
 BUILTIN(__builtin_ia32_pmuludq, "v", "")
 BUILTIN(__builtin_ia32_pmuludq128, "v", "")
 BUILTIN(__builtin_ia32_psllw128, "v", "")

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

==============================================================================
--- cfe/cfe/trunk/Sema/Sema.h (original)
+++ cfe/cfe/trunk/Sema/Sema.h Wed Jul 11 11:43:33 2007
@@ -98,7 +98,7 @@
   TypedefDecl *MergeTypeDefDecl(TypedefDecl *New, Decl *Old);
   FunctionDecl *MergeFunctionDecl(FunctionDecl *New, Decl *Old);
   VarDecl *MergeVarDecl(VarDecl *New, Decl *Old);
-  
+
   /// More parsing and symbol table subroutines...
   VarDecl *ParseParamDeclarator(DeclaratorChunk &FI, unsigned ArgNo,
                                 Scope *FnBodyScope);

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

==============================================================================
--- cfe/cfe/trunk/Sema/SemaDecl.cpp (original)
+++ cfe/cfe/trunk/Sema/SemaDecl.cpp Wed Jul 11 11:43:33 2007
@@ -96,7 +96,6 @@
       Context.Target.DiagnoseNonPortability(IdLoc,
                                             diag::port_target_builtin_use);
     }
-    
     // If this is a builtin on this (or all) targets, create the decl.
     if (unsigned BuiltinID = II->getBuiltinID())
       return LazilyCreateBuiltin(II, BuiltinID, S);
@@ -172,7 +171,8 @@
   // This is not right, but it's a start.  If 'Old' is a function prototype with
   // the same type as 'New', silently allow this.  FIXME: We should link up decl
   // objects here.
-  if (Old->getBody() == 0 && Old->getType() == New->getType()) {
+  if (Old->getBody() == 0 && 
+      Old->getCanonicalType() == New->getCanonicalType()) {
     return New;
   }
   
@@ -197,12 +197,17 @@
     Diag(OldD->getLocation(), diag::err_previous_definition);
     return New;
   }
-  
-  // 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);
+  // Verify the types match.
+  if (Old->getCanonicalType() != New->getCanonicalType()) {
+    Diag(New->getLocation(), diag::err_redefinition, New->getName());
+    Diag(Old->getLocation(), diag::err_previous_definition);
+    return New;
+  }
+  // We've verified the types match, now check if Old is "extern".
+  if (Old->getStorageClass() != ObjectDecl::Extern) {
+    Diag(New->getLocation(), diag::err_redefinition, New->getName());
+    Diag(Old->getLocation(), diag::err_previous_definition);
+  }
   return New;
 }
 
@@ -254,8 +259,19 @@
   } else {
     TypeRef R = GetTypeForDeclarator(D, S);
     if (R.isNull()) return 0;
-    VarDecl *NewVD = new VarDecl(D.getIdentifierLoc(), II, R);
 
+    ObjectDecl::StorageClass S;
+    switch (D.getDeclSpec().getStorageClassSpec()) {
+      default: assert(0 && "Unknown storage class!");
+      case 0: S = ObjectDecl::None;
+      case DeclSpec::SCS_extern:   S = ObjectDecl::Extern; break;
+      case DeclSpec::SCS_static:   S = ObjectDecl::Static; break;
+      // The following 2 should never be seen in this context.
+      case DeclSpec::SCS_auto:     S = ObjectDecl::Auto; break;
+      case DeclSpec::SCS_register: S = ObjectDecl::Register; break;
+    }
+    VarDecl *NewVD = new VarDecl(D.getIdentifierLoc(), II, R, S);
+    
     // Merge the decl with the existing one if appropriate.
     if (PrevDecl) {
       NewVD = MergeVarDecl(NewVD, PrevDecl);
@@ -294,9 +310,11 @@
     
   }
   
+  // FIXME: Handle storage class (auto, register). No declarator?
   VarDecl *New = new VarDecl(PI.IdentLoc, II, 
-                             TypeRef::getFromOpaquePtr(PI.TypeInfo));
-  
+                             TypeRef::getFromOpaquePtr(PI.TypeInfo), 
+                             ObjectDecl::None);
+
   // If this has an identifier, add it to the scope stack.
   if (II) {
     New->setNext(II->getFETokenInfo<Decl>());

Modified: cfe/cfe/trunk/include/clang/AST/Decl.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/AST/Decl.h?rev=39357&r1=39356&r2=39357&view=diff

==============================================================================
--- cfe/cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/cfe/trunk/include/clang/AST/Decl.h Wed Jul 11 11:43:33 2007
@@ -95,14 +95,21 @@
 
 /// ObjectDecl - Represents a declaration of a value.
 class ObjectDecl : public Decl {
+public:
+  enum StorageClass {
+    None, Extern, Static, Auto, Register
+  };
+private:
   TypeRef DeclType;
+  StorageClass SClass;
 protected:
-  ObjectDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, TypeRef T)
-    : Decl(DK, L, Id), DeclType(T) {}
+  ObjectDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, TypeRef T,
+             StorageClass S = None): Decl(DK, L, Id), DeclType(T), SClass(S) {}
 public:
-
   TypeRef getType() const { return DeclType; }
-
+  TypeRef getCanonicalType() const { return DeclType.getCanonicalType(); }
+  StorageClass getStorageClass() const { return SClass; }
+  
   // Implement isa/cast/dyncast/etc.
   static bool classof(const Decl *D) {
     return D->getKind() == Variable || D->getKind() == Function;
@@ -115,8 +122,8 @@
 class VarDecl : public ObjectDecl {
   // TODO: Initializer.
 public:
-  VarDecl(SourceLocation L, IdentifierInfo *Id, TypeRef T)
-    : ObjectDecl(Variable, L, Id, T) {}
+  VarDecl(SourceLocation L, IdentifierInfo *Id, TypeRef T, StorageClass S)
+    : ObjectDecl(Variable, L, Id, T, S) {}
   
   // Implement isa/cast/dyncast/etc.
   static bool classof(const Decl *D) { return D->getKind() == Variable; }

Modified: cfe/cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/cfe/trunk/include/clang/AST/Type.h?rev=39357&r1=39356&r2=39357&view=diff

==============================================================================
--- cfe/cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/cfe/trunk/include/clang/AST/Type.h Wed Jul 11 11:43:33 2007
@@ -302,7 +302,7 @@
   static bool classof(const ArrayType *) { return true; }
 };
 
-/// FunctionType - C99 6.7.5.3 - Array Declarators.  This is the common base
+/// FunctionType - C99 6.7.5.3 - Function Declarators.  This is the common base
 /// class of FunctionTypeNoProto and FunctionTypeProto.
 ///
 class FunctionType : public Type {
@@ -396,7 +396,9 @@
 
 class TypedefType : public Type {
   TypedefDecl *Decl;
-  TypedefType(TypedefDecl *D, Type *can) : Type(TypeName, can), Decl(D) {}
+  TypedefType(TypedefDecl *D, Type *can) : Type(TypeName, can), Decl(D) {
+    assert(!isa<TypedefType>(can) && "Invalid canonoical type");
+  }
   friend class ASTContext;  // ASTContext creates these.
 public:
   





More information about the cfe-commits mailing list