[llvm-commits] [llvm] r170036 - in /llvm/trunk: include/llvm/Support/YAMLTraits.h lib/Support/YAMLTraits.cpp
Michael Spencer
bigcheesegs at gmail.com
Fri Dec 14 16:17:59 PST 2012
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.
- 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