X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FSupport%2FAlignOf.h;h=5268c8d16986801b4f5f3fcf707369d28cf134b0;hb=812af1efba18ceeda296e1bed2e9e59eecd4e9d2;hp=f564fd353d8c7ded57db5fbd03cd8411d1f4fc87;hpb=b042171a213a4aefe5023275fcbed8dab559b222;p=oota-llvm.git diff --git a/include/llvm/Support/AlignOf.h b/include/llvm/Support/AlignOf.h index f564fd353d8..5268c8d1698 100644 --- a/include/llvm/Support/AlignOf.h +++ b/include/llvm/Support/AlignOf.h @@ -17,17 +17,23 @@ #include "llvm/Support/Compiler.h" #include +#include namespace llvm { -template + +namespace detail { + +// For everything other than an abstract class we can calulate alignment by +// building a class with a single character and a member of the given type. +template ::value> struct AlignmentCalcImpl { char x; #if defined(_MSC_VER) // Disables "structure was padded due to __declspec(align())" warnings that are // generated by any class using AlignOf with a manually specified alignment. -// Although the warning is disabled in the LLVM project we need this pragma +// Although the warning is disabled in the LLVM project we need this pragma // as AlignOf.h is a published support header that's available for use -// out-of-tree, and we would like that to ompile cleanly at /W4. +// out-of-tree, and we would like that to compile cleanly at /W4. #pragma warning(suppress : 4324) #endif T t; @@ -35,6 +41,25 @@ private: AlignmentCalcImpl() {} // Never instantiate. }; +// Abstract base class helper, this will have the minimal alignment and size +// for any abstract class. We don't even define its destructor because this +// type should never be used in a way that requires it. +struct AlignmentCalcImplBase { + virtual ~AlignmentCalcImplBase() = 0; +}; + +// When we have an abstract class type, specialize the alignment computation +// engine to create another abstract class that derives from both an empty +// abstract base class and the provided type. This has the same effect as the +// above except that it handles the fact that we can't actually create a member +// of type T. +template +struct AlignmentCalcImpl : AlignmentCalcImplBase, T { + virtual ~AlignmentCalcImpl() = 0; +}; + +} // End detail namespace. + /// AlignOf - A templated class that contains an enum value representing /// the alignment of the template argument. For example, /// AlignOf::Alignment represents the alignment of type "int". The @@ -44,9 +69,20 @@ private: /// compile-time constant (e.g., for template instantiation). template struct AlignOf { - enum { Alignment = - static_cast(sizeof(AlignmentCalcImpl) - sizeof(T)) }; - +#ifndef _MSC_VER + // Avoid warnings from GCC like: + // comparison between 'enum llvm::AlignOf::' and 'enum + // llvm::AlignOf::' [-Wenum-compare] + // by using constexpr instead of enum. + // (except on MSVC, since it doesn't support constexpr yet). + static constexpr unsigned Alignment = static_cast( + sizeof(detail::AlignmentCalcImpl) - sizeof(T)); +#else + enum { + Alignment = static_cast(sizeof(detail::AlignmentCalcImpl) - + sizeof(T)) + }; +#endif enum { Alignment_GreaterEqual_2Bytes = Alignment >= 2 ? 1 : 0 }; enum { Alignment_GreaterEqual_4Bytes = Alignment >= 4 ? 1 : 0 }; enum { Alignment_GreaterEqual_8Bytes = Alignment >= 8 ? 1 : 0 }; @@ -58,6 +94,10 @@ struct AlignOf { enum { Alignment_LessEqual_16Bytes = Alignment <= 16 ? 1 : 0 }; }; +#ifndef _MSC_VER +template constexpr unsigned AlignOf::Alignment; +#endif + /// alignOf - A templated function that returns the minimum alignment of /// of a type. This provides no extra functionality beyond the AlignOf /// class besides some cosmetic cleanliness. Example usage: @@ -198,12 +238,12 @@ union SizerImpl { } // end namespace detail /// \brief This union template exposes a suitably aligned and sized character -/// array member which can hold elements of any of up to four types. +/// array member which can hold elements of any of up to ten types. /// /// These types may be arrays, structs, or any other types. The goal is to /// expose a char array buffer member which can be used as suitable storage for -/// a placement new of any of these types. Support for more than seven types can -/// be added at the cost of more boiler plate. +/// a placement new of any of these types. Support for more than ten types can +/// be added at the cost of more boilerplate. template