[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