Patch for enum sizes

Well, a start, anyway. Enough to prevent clang asserting when
switching on an enumerated type, at least.

No idea if this is a sensible approach or not. Feel free to flame :wink:

I think the code dealing with finding the minimum and maximum enum
constants is really ugly, but I can't see a better way to do it with
the current APSInt API. Anyone have ideas?

-Keith

enum-sizing.diff (4.26 KB)

Seems reasonable: I applied it with changes, here are some comments:

+ enum EnumTypePolicy {
+ AlwaysInt,
+ ShortestType
+ };

This should be documented as a whole and each element should be as well. I wrote:

   /// EnumTypePolicy - This enum value contains a list of the various policies
   /// that a target can have about how enums are converted to integer types.
   enum EnumTypePolicy {
     AlwaysInt, // 'int' or 'unsigned'
     ShortestType // -fshort-enums
   };

+ /// integerTypeCompatibleWithEnumType - returns the integer type compatible
+ /// with the given enum type.
+ QualType integerTypeCompatibleWithEnum(EnumDecl *ED, SourceLocation L);

I renamed this to: getEnumDeclIntegerType and made it const. Also, it doesn't need the source location node, because:

+/// integerTypeCompatibleWithEnumType - returns the integer type compatible
+/// with the given enum type.
+QualType ASTContext::integerTypeCompatibleWithEnum(EnumDecl *ED, SourceLocation L) {
+ Decl *D = ED->getFirstElement();
+ EnumConstantDecl *C = cast<EnumConstantDecl>(D);
...

By the time this is called, all enum constants have to have the same type (which is the integer type we want). I replaced this with:

QualType ASTContext::getEnumDeclIntegerType(EnumDecl *ED) const {
   if (EnumConstantDecl *C = ED->getEnumConstantList())
     return C->getType();

   // If the enum list is empty, it is typed as if it contained a single zero
   // element [C++ dcl.enum] and is illegal in C (as an extension, we treat it
   // the same as C++ does).
   switch (Target.getEnumTypePolicy(ED->getLocation())) {
   default: assert(0 && "Unknown enum layout policy");
   case TargetInfo::AlwaysInt: return UnsignedIntTy; // 0 -> unsigned
   case TargetInfo::ShortestType: return UnsignedCharTy; // 0 -> unsigned char
   }
}

I will work on making enum layout follow the GCC conventions next and fix some TODO's in the relevant handling code.

Thanks Keith!

-Chris