Explicitly request unsigned enum types when desired
authorReid Kleckner <reid@kleckner.net>
Mon, 23 Sep 2013 23:26:57 +0000 (23:26 +0000)
committerReid Kleckner <reid@kleckner.net>
Mon, 23 Sep 2013 23:26:57 +0000 (23:26 +0000)
The underlying type of all plain enums in MSVC is 'int', even if the
enumerator contains large 32-bit unsigned values or values greater than
UINT_MAX.  The only way to get a large or unsigned enum type is to
request it explicitly with the C++11 strong enum types feature.

However, since LLVM isn't C++11 yet, I had to add a conditional
LLVM_ENUM_INT_TYPE to Compiler.h to control its usage.

The motivating true positive for this change is compiling PointerIntPair
with MSVC for win64.  The PointerIntMask value is supposed to be pointer
sized value of all ones with some low zeros.  Instead, it's truncated to
32-bits!  We are only saved later because it is sign extended back in
the AND with int64_t, and we happen to want all ones.

This silences lots of -Wmicrosoft warnings during a clang self-host
targeting Windows.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191241 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/ADT/PointerIntPair.h
include/llvm/IR/Attributes.h
include/llvm/IR/InlineAsm.h
include/llvm/MC/MCSectionMachO.h
include/llvm/MC/MachineLocation.h
include/llvm/Object/ObjectFile.h
include/llvm/Support/COFF.h
include/llvm/Support/Compiler.h
include/llvm/Support/Dwarf.h
include/llvm/Support/ELF.h
include/llvm/Support/MachO.h

index 0299a83c4411cff24b314ffa432234c74405075a..0cfd470003af79fc4af7de573cd4ed2f082f40c9 100644 (file)
@@ -14,6 +14,7 @@
 #ifndef LLVM_ADT_POINTERINTPAIR_H
 #define LLVM_ADT_POINTERINTPAIR_H
 
+#include "llvm/Support/Compiler.h"
 #include "llvm/Support/PointerLikeTypeTraits.h"
 #include <cassert>
 
@@ -40,7 +41,7 @@ template <typename PointerTy, unsigned IntBits, typename IntType=unsigned,
           typename PtrTraits = PointerLikeTypeTraits<PointerTy> >
 class PointerIntPair {
   intptr_t Value;
-  enum {
+  enum LLVM_ENUM_INT_TYPE(uintptr_t) {
     /// PointerBitMask - The bits that come from the pointer.
     PointerBitMask =
       ~(uintptr_t)(((intptr_t)1 << PtrTraits::NumLowBitsAvailable)-1),
index ebee637004b6951299ae34cb127238105b670a08..c23ba0f73c58b2606f570b164c976d57767f2ea3 100644 (file)
@@ -18,6 +18,7 @@
 
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/FoldingSet.h"
+#include "llvm/Support/Compiler.h"
 #include "llvm/Support/PointerLikeTypeTraits.h"
 #include <bitset>
 #include <cassert>
@@ -200,7 +201,7 @@ public:
 /// index `1'.
 class AttributeSet {
 public:
-  enum AttrIndex {
+  enum AttrIndex LLVM_ENUM_INT_TYPE(unsigned) {
     ReturnIndex = 0U,
     FunctionIndex = ~0U
   };
index 33e4ab8522d1bf2fa2b2d7953798e28e2ae191d3..3398a83e365e1344b51b12257678a6c8bc3e09a1 100644 (file)
@@ -197,7 +197,7 @@ public:
   // These are helper methods for dealing with flags in the INLINEASM SDNode
   // in the backend.
   
-  enum {
+  enum LLVM_ENUM_INT_TYPE(uint32_t) {
     // Fixed operands on an INLINEASM SDNode.
     Op_InputChain = 0,
     Op_AsmString = 1,
index b68bd8596801ad3c64a975605771d1504f04484b..d7e88ea561247b66fddb0452ab88e6ccc75246ed 100644 (file)
@@ -41,7 +41,7 @@ public:
 
   /// These are the section type and attributes fields.  A MachO section can
   /// have only one Type, but can have any of the attributes specified.
-  enum {
+  enum LLVM_ENUM_INT_TYPE(uint32_t) {
     // TypeAndAttributes bitmasks.
     SECTION_TYPE       = 0x000000FFU,
     SECTION_ATTRIBUTES = 0xFFFFFF00U,
index 7d9abc3587df33dfb87968edb92413b77069a8f4..b3fbee77021d7c9b249a2d2b68e63eb9ae903226 100644 (file)
@@ -16,6 +16,9 @@
 #ifndef LLVM_MC_MACHINELOCATION_H
 #define LLVM_MC_MACHINELOCATION_H
 
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/DataTypes.h"
+
 namespace llvm {
   class MCSymbol;
 
@@ -25,7 +28,7 @@ private:
   unsigned Register;                    // gcc/gdb register number.
   int Offset;                           // Displacement if not register.
 public:
-  enum {
+  enum LLVM_ENUM_INT_TYPE(uint32_t) {
     // The target register number for an abstract frame pointer. The value is
     // an arbitrary value that doesn't collide with any real target register.
     VirtualFP = ~0U
index f434d63736f65866fb5664c21be6f7da15dd5ecb..6973c6713b52cfb451c637504ec758253b42c58b 100644 (file)
@@ -192,7 +192,7 @@ public:
     ST_Other
   };
 
-  enum Flags {
+  enum Flags LLVM_ENUM_INT_TYPE(unsigned) {
     SF_None            = 0,
     SF_Undefined       = 1U << 0,  // Symbol is defined in another object file
     SF_Global          = 1U << 1,  // Global symbol
index 541d563cef49fd29041e018d40ba7ef35954e23c..9cc3989df043e611bb29ceddff88c8bba50d2339 100644 (file)
@@ -222,7 +222,7 @@ namespace COFF {
     uint32_t Characteristics;
   };
 
-  enum SectionCharacteristics {
+  enum SectionCharacteristics LLVM_ENUM_INT_TYPE(uint32_t) {
     SC_Invalid = 0xffffffff,
 
     IMAGE_SCN_TYPE_NO_PAD            = 0x00000008,
index c32a48546ce2515db78bbed9b935d81e1fac70cd..13920fcc5a89b7105ac01e2ff15f615c314a9d41 100644 (file)
 # define LLVM_STATIC_ASSERT(expr, msg)
 #endif
 
+/// \macro LLVM_ENUM_INT_TYPE
+/// \brief Expands to colon followed by the given integral type on compilers
+/// which support C++11 strong enums.  This can be used to make enums unsigned
+/// with MSVC.
+#if __has_feature(cxx_strong_enums)
+# define LLVM_ENUM_INT_TYPE(intty) : intty
+#elif defined(_MSC_VER) && _MSC_VER >= 1600  // Added in MSVC 2010.
+# define LLVM_ENUM_INT_TYPE(intty) : intty
+#else
+# define LLVM_ENUM_INT_TYPE(intty)
+#endif
+
 #endif
index 70c46db0e97b531f9ddb0278a2857e5160d2fd04..0f3354143849b33c01d9df4555d031727dceb118 100644 (file)
@@ -16,6 +16,7 @@
 #ifndef LLVM_SUPPORT_DWARF_H
 #define LLVM_SUPPORT_DWARF_H
 
+#include "llvm/Support/Compiler.h"
 #include "llvm/Support/DataTypes.h"
 
 namespace llvm {
@@ -23,7 +24,7 @@ namespace llvm {
 //===----------------------------------------------------------------------===//
 // Debug info constants.
 
-enum {
+enum LLVM_ENUM_INT_TYPE(uint32_t) {
   LLVMDebugVersion = (12 << 16),    // Current version of debug information.
   LLVMDebugVersion11 = (11 << 16),  // Constant for version 11.
   LLVMDebugVersion10 = (10 << 16),  // Constant for version 10.
@@ -46,7 +47,7 @@ namespace dwarf {
 // Do not mix the following two enumerations sets.  DW_TAG_invalid changes the
 // enumeration base type.
 
-enum LLVMConstants {
+enum LLVMConstants LLVM_ENUM_INT_TYPE(uint32_t) {
   // llvm mock tags
   DW_TAG_invalid = ~0U, // Tag for invalid results.
 
index 8f92832795b7fabf5af77fc149f6d1393811a130..61d1a0d5cbd92b0b9a3017ba8c9bd0e7bba68155 100644 (file)
@@ -650,7 +650,7 @@ enum {
 };
 
 // ARM Specific e_flags
-enum {
+enum LLVM_ENUM_INT_TYPE(unsigned) {
   EF_ARM_SOFT_FLOAT =     0x00000200U,
   EF_ARM_VFP_FLOAT =      0x00000400U,
   EF_ARM_EABI_UNKNOWN =   0x00000000U,
@@ -800,7 +800,7 @@ enum {
 };
 
 // Mips Specific e_flags
-enum {
+enum LLVM_ENUM_INT_TYPE(unsigned) {
   EF_MIPS_NOREORDER = 0x00000001, // Don't reorder instructions
   EF_MIPS_PIC       = 0x00000002, // Position independent code
   EF_MIPS_CPIC      = 0x00000004, // Call object with Position independent code
@@ -1116,7 +1116,7 @@ enum {
 };
 
 // Section types.
-enum {
+enum LLVM_ENUM_INT_TYPE(unsigned) {
   SHT_NULL          = 0,  // No associated section (inactive entry).
   SHT_PROGBITS      = 1,  // Program-defined contents.
   SHT_SYMTAB        = 2,  // Symbol table.
@@ -1164,7 +1164,7 @@ enum {
 };
 
 // Section flags.
-enum {
+enum LLVM_ENUM_INT_TYPE(unsigned) {
   // Section data should be writable during execution.
   SHF_WRITE = 0x1,
 
@@ -1234,7 +1234,7 @@ enum {
 };
 
 // Section Group Flags
-enum {
+enum LLVM_ENUM_INT_TYPE(unsigned) {
   GRP_COMDAT = 0x1,
   GRP_MASKOS = 0x0ff00000,
   GRP_MASKPROC = 0xf0000000
@@ -1451,7 +1451,7 @@ enum {
 };
 
 // Segment flag bits.
-enum {
+enum LLVM_ENUM_INT_TYPE(unsigned) {
   PF_X        = 1,         // Execute
   PF_W        = 2,         // Write
   PF_R        = 4,         // Read
index 59998ada0204b4f92ec4492c6a736b8d7b0cd393..b2ac6b3b5b67d56fcd2547e49217f2de3b173457 100644 (file)
 #ifndef LLVM_SUPPORT_MACHO_H
 #define LLVM_SUPPORT_MACHO_H
 
+#include "llvm/Support/Compiler.h"
 #include "llvm/Support/DataTypes.h"
 #include "llvm/Support/Host.h"
 
 namespace llvm {
   namespace MachO {
     // Enums from <mach-o/loader.h>
-    enum {
+    enum LLVM_ENUM_INT_TYPE(uint32_t) {
       // Constants for the "magic" field in llvm::MachO::mach_header and
       // llvm::MachO::mach_header_64
       MH_MAGIC    = 0xFEEDFACEu,
@@ -75,12 +76,12 @@ namespace llvm {
       MH_DEAD_STRIPPABLE_DYLIB   = 0x00400000u
     };
 
-    enum {
+    enum LLVM_ENUM_INT_TYPE(uint32_t) {
       // Flags for the "cmd" field in llvm::MachO::load_command
       LC_REQ_DYLD    = 0x80000000u
     };
 
-    enum LoadCommandType {
+    enum LoadCommandType LLVM_ENUM_INT_TYPE(uint32_t) {
       // Constants for the "cmd" field in llvm::MachO::load_command
       LC_SEGMENT              = 0x00000001u,
       LC_SYMTAB               = 0x00000002u,
@@ -130,7 +131,7 @@ namespace llvm {
       LC_LINKER_OPTIONS       = 0x0000002Du
     };
 
-    enum {
+    enum LLVM_ENUM_INT_TYPE(uint32_t) {
       // Constant bits for the "flags" field in llvm::MachO::segment_command
       SG_HIGHVM              = 0x1u,
       SG_FVMLIB              = 0x2u,
@@ -173,7 +174,7 @@ namespace llvm {
       S_THREAD_LOCAL_INIT_FUNCTION_POINTERS = 0x15u
     };
 
-    enum {
+    enum LLVM_ENUM_INT_TYPE(uint32_t) {
       // Constant masks for the "flags[31:24]" field in llvm::MachO::section and
       // llvm::MachO::section_64 (mask "flags" with SECTION_ATTRIBUTES_USR)
       S_ATTR_PURE_INSTRUCTIONS   = 0x80000000u,
@@ -235,9 +236,9 @@ namespace llvm {
     };
 
     enum BindSpecialDylib {
-      BIND_SPECIAL_DYLIB_SELF            =  0u,
-      BIND_SPECIAL_DYLIB_MAIN_EXECUTABLE = -1u,
-      BIND_SPECIAL_DYLIB_FLAT_LOOKUP     = -2u
+      BIND_SPECIAL_DYLIB_SELF            =  0,
+      BIND_SPECIAL_DYLIB_MAIN_EXECUTABLE = -1,
+      BIND_SPECIAL_DYLIB_FLAT_LOOKUP     = -2
     };
 
     enum {
@@ -347,7 +348,7 @@ namespace llvm {
       N_LENG    = 0xFEu
     };
 
-    enum {
+    enum LLVM_ENUM_INT_TYPE(uint32_t) {
       // Constant values for the r_symbolnum field in an
       // llvm::MachO::relocation_info structure when r_extern is 0.
       R_ABS = 0,
@@ -892,7 +893,7 @@ namespace llvm {
     }
 
     // Enums from <mach/machine.h>
-    enum {
+    enum LLVM_ENUM_INT_TYPE(uint32_t) {
       // Capability bits used in the definition of cpu_type.
       CPU_ARCH_MASK  = 0xff000000,   // Mask for architecture bits
       CPU_ARCH_ABI64 = 0x01000000    // 64 bit ABI
@@ -912,13 +913,13 @@ namespace llvm {
       CPU_TYPE_POWERPC64 = CPU_TYPE_POWERPC | CPU_ARCH_ABI64
     };
 
-    enum {
+    enum LLVM_ENUM_INT_TYPE(uint32_t) {
       // Capability bits used in the definition of cpusubtype.
       CPU_SUB_TYPE_MASK  = 0xff000000,   // Mask for architecture bits
       CPU_SUB_TYPE_LIB64 = 0x80000000,   // 64 bit libraries
 
       // Special CPU subtype constants.
-      CPU_SUBTYPE_MULTIPLE = -1
+      CPU_SUBTYPE_MULTIPLE = ~0u
     };
 
     // Constants for the cpusubtype field.