[cfe-commits] r41571 - in /cfe/trunk: Sema/SemaDecl.cpp clang.xcodeproj/project.pbxproj

Chris Lattner sabre at nondot.org
Wed Aug 29 10:31:48 PDT 2007


Author: lattner
Date: Wed Aug 29 12:31:48 2007
New Revision: 41571

URL: http://llvm.org/viewvc/llvm-project?rev=41571&view=rev
Log:
Implement GCC-compatible layout and typing of enum constants and enum decl.  
A small bit of codegen work is still pending.

Modified:
    cfe/trunk/Sema/SemaDecl.cpp
    cfe/trunk/clang.xcodeproj/project.pbxproj

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

==============================================================================
--- cfe/trunk/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/Sema/SemaDecl.cpp Wed Aug 29 12:31:48 2007
@@ -1053,19 +1053,21 @@
   // Figure out the type that should be used for this enum.
   // FIXME: Support attribute(packed) on enums and -fshort-enums.
   QualType BestType;
+  unsigned BestWidth;
   
   if (NumNegativeBits) {
     // If there is a negative value, figure out the smallest integer type (of 
     // int/long/longlong) that fits.
-    if (NumNegativeBits <= IntWidth && NumPositiveBits < IntWidth)
+    if (NumNegativeBits <= IntWidth && NumPositiveBits < IntWidth) {
       BestType = Context.IntTy;
-    else {
-      unsigned LongWidth = Context.Target.getLongWidth(Enum->getLocation());
-      if (NumNegativeBits <= LongWidth && NumPositiveBits < LongWidth)
+      BestWidth = IntWidth;
+    } else {
+      BestWidth = Context.Target.getLongWidth(Enum->getLocation());
+      if (NumNegativeBits <= BestWidth && NumPositiveBits < BestWidth)
         BestType = Context.LongTy;
       else {
-        unsigned LLWidth = Context.Target.getLongLongWidth(Enum->getLocation());
-        if (NumNegativeBits > LLWidth || NumPositiveBits >= LLWidth)
+        BestWidth = Context.Target.getLongLongWidth(Enum->getLocation());
+        if (NumNegativeBits > BestWidth || NumPositiveBits >= BestWidth)
           Diag(Enum->getLocation(), diag::warn_enum_too_large);
         BestType = Context.LongLongTy;
       }
@@ -1073,19 +1075,70 @@
   } else {
     // If there is no negative value, figure out which of uint, ulong, ulonglong
     // fits.
-    if (NumPositiveBits <= IntWidth)
+    if (NumPositiveBits <= IntWidth) {
       BestType = Context.UnsignedIntTy;
-    else if (NumPositiveBits <=Context.Target.getLongWidth(Enum->getLocation()))
+      BestWidth = IntWidth;
+    } else if (NumPositiveBits <=
+               (BestWidth = Context.Target.getLongWidth(Enum->getLocation())))
       BestType = Context.UnsignedLongTy;
     else {
-      assert(NumPositiveBits <=
-             Context.Target.getLongLongWidth(Enum->getLocation()) &&
+      BestWidth = Context.Target.getLongLongWidth(Enum->getLocation());
+      assert(NumPositiveBits <= BestWidth &&
              "How could an initializer get larger than ULL?");
       BestType = Context.UnsignedLongLongTy;
     }
   }
   
-  // FIXME: Install type in Enum and constant values.
+  // Loop over all of the enumerator constants, changing their types to match
+  // the type of the enum if needed.
+  for (unsigned i = 0; i != NumElements; ++i) {
+    EnumConstantDecl *ECD =
+      cast_or_null<EnumConstantDecl>(static_cast<Decl*>(Elements[i]));
+    if (!ECD) continue;  // Already issued a diagnostic.
+
+    // Standard C says the enumerators have int type, but we allow, as an
+    // extension, the enumerators to be larger than int size.  If each
+    // enumerator value fits in an int, type it as an int, otherwise type it the
+    // same as the enumerator decl itself.  This means that in "enum { X = 1U }"
+    // that X has type 'int', not 'unsigned'.
+    if (ECD->getType() == Context.IntTy)
+      continue;  // Already int type.
+
+    // Determine whether the value fits into an int.
+    llvm::APSInt InitVal = ECD->getInitVal();
+    bool FitsInInt;
+    if (InitVal.isUnsigned() || !InitVal.isNegative())
+      FitsInInt = InitVal.getActiveBits() < IntWidth;
+    else
+      FitsInInt = InitVal.getMinSignedBits() <= IntWidth;
+
+    // If it fits into an integer type, force it.  Otherwise force it to match
+    // the enum decl type.
+    QualType NewTy;
+    unsigned NewWidth;
+    bool NewSign;
+    if (FitsInInt) {
+      NewTy = Context.IntTy;
+      NewWidth = IntWidth;
+      NewSign = true;
+    } else if (ECD->getType() == BestType) {
+      // Already the right type!
+      continue;
+    } else {
+      NewTy = BestType;
+      NewWidth = BestWidth;
+      NewSign = BestType->isSignedIntegerType();
+    }
+
+    // Adjust the APSInt value.
+    InitVal.extOrTrunc(NewWidth);
+    InitVal.setIsSigned(NewSign);
+    ECD->setInitVal(InitVal);
+    
+    // Adjust the Expr initializer and type.
+    ECD->setInitExpr(new ImplicitCastExpr(NewTy, ECD->getInitExpr()));
+    ECD->setType(NewTy);
+  }
   
   Enum->defineElements(EltList, BestType);
 }

Modified: cfe/trunk/clang.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/clang.xcodeproj/project.pbxproj?rev=41571&r1=41570&r2=41571&view=diff

==============================================================================
--- cfe/trunk/clang.xcodeproj/project.pbxproj (original)
+++ cfe/trunk/clang.xcodeproj/project.pbxproj Wed Aug 29 12:31:48 2007
@@ -210,7 +210,7 @@
 		35260CA40C7F75C000D66CE9 /* ExprCXX.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ExprCXX.cpp; path = AST/ExprCXX.cpp; sourceTree = "<group>"; };
 		84D9A8870C1A57E100AC7ABC /* AttributeList.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = AttributeList.cpp; path = Parse/AttributeList.cpp; sourceTree = "<group>"; };
 		84D9A88B0C1A581300AC7ABC /* AttributeList.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AttributeList.h; path = clang/Parse/AttributeList.h; sourceTree = "<group>"; };
-		8DD76F6C0486A84900D96B5E /* clang */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = clang; sourceTree = BUILT_PRODUCTS_DIR; };
+		8DD76F6C0486A84900D96B5E /* clang */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = "compiled.mach-o.executable"; path = clang; sourceTree = BUILT_PRODUCTS_DIR; };
 		DE01DA480B12ADA300AC22CE /* PPCallbacks.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PPCallbacks.h; sourceTree = "<group>"; };
 		DE06756B0C051CFE00EBBFD8 /* ParseExprCXX.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ParseExprCXX.cpp; path = Parse/ParseExprCXX.cpp; sourceTree = "<group>"; };
 		DE06B73D0A8307640050E87E /* LangOptions.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = LangOptions.h; sourceTree = "<group>"; };





More information about the cfe-commits mailing list