[llvm-commits] [llvm] r170036 - in /llvm/trunk: include/llvm/Support/YAMLTraits.h lib/Support/YAMLTraits.cpp

Benjamin Kramer benny.kra at gmail.com
Sat Dec 15 01:44:09 PST 2012


On 15.12.2012, at 01:17, Michael Spencer <bigcheesegs at gmail.com> wrote:

> On Thu, Dec 13, 2012 at 3:04 PM, Nick Kledzik <kledzik at apple.com> wrote:
>> My trait stuff that I committed yesterday builds with clang and Visual Studio, but was failing with gcc-4.x on various *nix platforms.  To unblock the build  bots, I used #if 0 to conditionalize away the failing test cases in unittests/Support/YAMLIOTest.cpp.
>> 
>> I reconfigured llvm to build with an old llvm-gcc-4.2 compiler I have, and saw many compilation errors with YAMLIOTest.cpp.  I used some different SFINAE techniques and now have trait testing that works with gcc-4.2 and clang.
>> 
>> Ben and Michael, could you try putting in this new include/llvm/Support/YAMLTraits.h, enabling the tests in unittests/Support/YAMLIOTest.cpp, and build SupportTests with your compiler to verify these traits work?  Thanks!
>> 
>> 
>> 
>> 
>> -Nick
> 
> Works on recent clang and MSVC 2012 Update 1.

Also compiles with GCC 4.2, 4.4 and 4.8.

- Ben

> 
> - Michael Spencer
> 
>> 
>> 
>> Index: include/llvm/Support/YAMLTraits.h
>> ===================================================================
>> --- include/llvm/Support/YAMLTraits.h   (revision 170156)
>> +++ include/llvm/Support/YAMLTraits.h   (working copy)
>> @@ -227,10 +227,9 @@
>> };
>> 
>> 
>> -// Test if SequenceTraits<T> is defined on type T
>> -// and SequenceTraits<T>::flow is *not* defined.
>> +// Test if SequenceTraits<T> is defined on type T.
>> template <class T>
>> -struct has_SequenceTraits
>> +struct has_SequenceMethodTraits
>> {
>>   typedef size_t (*Signature_size)(class IO&, T&);
>> 
>> @@ -240,43 +239,59 @@
>>   template <typename U>
>>   static double test(...);
>> 
>> -  template <typename U> static
>> -  char flowtest( char[sizeof(&U::flow)] ) ;
>> +public:
>> +  static bool const value =  (sizeof(test<SequenceTraits<T> >(0)) == 1);
>> +};
>> 
>> -  template <typename U>
>> -  static double flowtest(...);
>> 
>> +// has_FlowTraits<int> will cause an error with some compilers because
>> +// it subclasses int.  Using this wrapper only instantiates the
>> +// real has_FlowTraits only if the template type is a class.
>> +template <typename T, bool Enabled = llvm::is_class<T>::value>
>> +class has_FlowTraits
>> +{
>> public:
>> -  static bool const value =  (sizeof(test<SequenceTraits<T> >(0)) == 1)
>> -                          && (sizeof(flowtest<T>(0)) != 1);
>> +   static const bool value = false;
>> };
>> 
>> -
>> -// Test if SequenceTraits<T> is defined on type T
>> -// and SequenceTraits<T>::flow is defined.
>> +// Some older gcc compilers don't support straight forward tests
>> +// for members, so test for ambiguity cause by the base and derived
>> +// classes both defining the member.
>> template <class T>
>> -struct has_FlowSequenceTraits
>> +struct has_FlowTraits<T, true>
>> {
>> -  typedef size_t (*Signature_size)(class IO&, T&);
>> +  struct Fallback { bool flow; };
>> +  struct Derived : T, Fallback { };
>> 
>> -  template <typename U>
>> -  static char test(SameType<Signature_size, &U::size>*);
>> +  template<typename C>
>> +  static char (&f(SameType<bool Fallback::*, &C::flow>*))[1];
>> 
>> -  template <typename U>
>> -  static double test(...);
>> +  template<typename C>
>> +  static char (&f(...))[2];
>> 
>> -  template <typename U> static
>> -  char flowtest( char[sizeof(&U::flow)] ) ;
>> -
>> -  template <typename U>
>> -  static double flowtest(...);
>> -
>> public:
>> -  static bool const value =  (sizeof(test<SequenceTraits<T> >(0)) == 1)
>> -                          && (sizeof(flowtest<T>(0)) == 1);
>> +  static bool const value = sizeof(f<Derived>(0)) == 2;
>> };
>> 
>> 
>> +
>> +// Test if SequenceTraits<T> is defined on type T
>> +// and SequenceTraits<T>::flow is *not* defined.
>> +template<typename T>
>> +struct has_SequenceTraits : public  llvm::integral_constant<bool,
>> +                                         has_SequenceMethodTraits<T>::value
>> +                                      && !has_FlowTraits<T>::value > { };
>> +
>> +
>> +// Test if SequenceTraits<T> is defined on type T
>> +// and SequenceTraits<T>::flow is defined.
>> +template<typename T>
>> +struct has_FlowSequenceTraits : public llvm::integral_constant<bool,
>> +                                         has_SequenceMethodTraits<T>::value
>> +                                      && has_FlowTraits<T>::value > { };
>> +
>> +
>> +
>> // Test if DocumentListTraits<T> is defined on type T
>> template <class T>
>> struct has_DocumentListTraits
>> 
>> 





More information about the llvm-commits mailing list