diff --git a/include/llvm/Support/YAMLTraits.h b/include/llvm/Support/YAMLTraits.h index 80580620ea8..4487eae2482 100644 --- a/include/llvm/Support/YAMLTraits.h +++ b/include/llvm/Support/YAMLTraits.h @@ -227,10 +227,9 @@ public: }; -// Test if SequenceTraits is defined on type T -// and SequenceTraits::flow is *not* defined. +// Test if SequenceTraits is defined on type T. template -struct has_SequenceTraits +struct has_SequenceMethodTraits { typedef size_t (*Signature_size)(class IO&, T&); @@ -240,41 +239,57 @@ struct has_SequenceTraits template static double test(...); - template static - char flowtest( char[sizeof(&U::flow)] ) ; +public: + static bool const value = (sizeof(test >(0)) == 1); +}; - template - static double flowtest(...); + +// has_FlowTraits 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 ::value> +class has_FlowTraits +{ +public: + static const bool value = false; +}; + +// 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 +struct has_FlowTraits +{ + struct Fallback { bool flow; }; + struct Derived : T, Fallback { }; + + template + static char (&f(SameType*))[1]; + + template + static char (&f(...))[2]; public: - static bool const value = (sizeof(test >(0)) == 1) - && (sizeof(flowtest(0)) != 1); + static bool const value = sizeof(f(0)) == 2; }; + +// Test if SequenceTraits is defined on type T +// and SequenceTraits::flow is *not* defined. +template +struct has_SequenceTraits : public llvm::integral_constant::value + && !has_FlowTraits::value > { }; + + // Test if SequenceTraits is defined on type T // and SequenceTraits::flow is defined. -template -struct has_FlowSequenceTraits -{ - typedef size_t (*Signature_size)(class IO&, T&); +template +struct has_FlowSequenceTraits : public llvm::integral_constant::value + && has_FlowTraits::value > { }; - template - static char test(SameType*); - - template - static double test(...); - - template static - char flowtest( char[sizeof(&U::flow)] ) ; - - template - static double flowtest(...); - -public: - static bool const value = (sizeof(test >(0)) == 1) - && (sizeof(flowtest(0)) == 1); -}; // Test if DocumentListTraits is defined on type T