From 603533a0a4dcfc2ef33051b9ae8237568a19adc4 Mon Sep 17 00:00:00 2001 From: "zhanyong.wan" Date: Sat, 5 Mar 2011 08:04:01 +0000 Subject: Fixes compatibility with Borland C++Builder. Original patch by Josh Kelley. Simplified by Zhanyong Wan. --- include/gtest/gtest-printers.h | 28 ++++++++++++++++++++++------ include/gtest/gtest.h | 4 +++- include/gtest/internal/gtest-internal.h | 5 +++++ include/gtest/internal/gtest-string.h | 2 +- src/gtest.cc | 2 +- test/gtest_unittest.cc | 25 +++++++++++++++++++------ 6 files changed, 51 insertions(+), 15 deletions(-) diff --git a/include/gtest/gtest-printers.h b/include/gtest/gtest-printers.h index 8ed6ec1..cbb809f 100644 --- a/include/gtest/gtest-printers.h +++ b/include/gtest/gtest-printers.h @@ -308,7 +308,10 @@ void DefaultPrintTo(IsNotContainer /* dummy */, } else { // C++ doesn't allow casting from a function pointer to any object // pointer. - if (ImplicitlyConvertible::value) { + // + // IsTrue() silences warnings: "Condition is always true", + // "unreachable code". + if (IsTrue(ImplicitlyConvertible::value)) { // T is not a function type. We just call << to print p, // relying on ADL to pick up user-defined << for their pointer // types, if any. @@ -736,12 +739,25 @@ struct TuplePrefixPrinter<0> { template static void TersePrintPrefixToStrings(const Tuple&, Strings*) {} }; +// We have to specialize the entire TuplePrefixPrinter<> class +// template here, even though the definition of +// TersePrintPrefixToStrings() is the same as the generic version, as +// Borland C++ doesn't support specializing a method. template <> -template -void TuplePrefixPrinter<1>::PrintPrefixTo(const Tuple& t, ::std::ostream* os) { - UniversalPrinter::type>:: - Print(::std::tr1::get<0>(t), os); -} +struct TuplePrefixPrinter<1> { + template + static void PrintPrefixTo(const Tuple& t, ::std::ostream* os) { + UniversalPrinter::type>:: + Print(::std::tr1::get<0>(t), os); + } + + template + static void TersePrintPrefixToStrings(const Tuple& t, Strings* strings) { + ::std::stringstream ss; + UniversalTersePrint(::std::tr1::get<0>(t), &ss); + strings->push_back(ss.str()); + } +}; // Helper function for printing a tuple. T must be instantiated with // a tuple type. diff --git a/include/gtest/gtest.h b/include/gtest/gtest.h index 03ade85..cd01c7b 100644 --- a/include/gtest/gtest.h +++ b/include/gtest/gtest.h @@ -1296,7 +1296,9 @@ namespace internal { template String FormatForComparisonFailureMessage(const T1& value, const T2& /* other_operand */) { - return PrintToString(value); + // C++Builder compiles this incorrectly if the namespace isn't explicitly + // given. + return ::testing::PrintToString(value); } // The helper function for {ASSERT|EXPECT}_EQ. diff --git a/include/gtest/internal/gtest-internal.h b/include/gtest/internal/gtest-internal.h index db098a4..947b162 100644 --- a/include/gtest/internal/gtest-internal.h +++ b/include/gtest/internal/gtest-internal.h @@ -873,6 +873,11 @@ class ImplicitlyConvertible { static const bool value = sizeof(Helper(ImplicitlyConvertible::MakeFrom())) == 1; # pragma warning(pop) // Restores the warning state. +#elif defined(__BORLANDC__) + // C++Builder cannot use member overload resolution during template + // instantiation. The simplest workaround is to use its C++0x type traits + // functions (C++Builder 2009 and above only). + static const bool value = __is_convertible(From, To); #else static const bool value = sizeof(Helper(ImplicitlyConvertible::MakeFrom())) == 1; diff --git a/include/gtest/internal/gtest-string.h b/include/gtest/internal/gtest-string.h index efde52a..dc3a07b 100644 --- a/include/gtest/internal/gtest-string.h +++ b/include/gtest/internal/gtest-string.h @@ -296,7 +296,7 @@ class GTEST_API_ String { private: // Constructs a non-NULL String from the given content. This - // function can only be called when data_ has not been allocated. + // function can only be called when c_str_ has not been allocated. // ConstructNonNull(NULL, 0) results in an empty string (""). // ConstructNonNull(NULL, non_zero) is undefined behavior. void ConstructNonNull(const char* buffer, size_t a_length) { diff --git a/src/gtest.cc b/src/gtest.cc index 9105712..3859d5a 100644 --- a/src/gtest.cc +++ b/src/gtest.cc @@ -4349,7 +4349,7 @@ bool ShouldShard(const char* total_shards_env, // Parses the environment variable var as an Int32. If it is unset, // returns default_val. If it is not an Int32, prints an error // and aborts. -Int32 Int32FromEnvOrDie(const char* const var, Int32 default_val) { +Int32 Int32FromEnvOrDie(const char* var, Int32 default_val) { const char* str_val = posix::GetEnv(var); if (str_val == NULL) { return default_val; diff --git a/test/gtest_unittest.cc b/test/gtest_unittest.cc index e6619d5..46db38d 100644 --- a/test/gtest_unittest.cc +++ b/test/gtest_unittest.cc @@ -1416,8 +1416,8 @@ static int global_var = 0; #define GTEST_USE_UNPROTECTED_COMMA_ global_var++, global_var++ TEST_F(ExpectFatalFailureTest, AcceptsMacroThatExpandsToUnprotectedComma) { -#if !defined(__BORLANDC__) || __BORLANDC__ >= 0x600 - // ICE's in C++Builder 2007. +#ifndef __BORLANDC__ + // ICE's in C++Builder. EXPECT_FATAL_FAILURE({ GTEST_USE_UNPROTECTED_COMMA_; AddFatalFailure(); @@ -3550,8 +3550,8 @@ TEST(AssertionTest, ASSERT_TRUE) { // Tests ASSERT_TRUE(predicate) for predicates returning AssertionResult. TEST(AssertionTest, AssertTrueWithAssertionResult) { ASSERT_TRUE(ResultIsEven(2)); -#if !defined(__BORLANDC__) || __BORLANDC__ >= 0x600 - // ICE's in C++Builder 2007. +#ifndef __BORLANDC__ + // ICE's in C++Builder. EXPECT_FATAL_FAILURE(ASSERT_TRUE(ResultIsEven(3)), "Value of: ResultIsEven(3)\n" " Actual: false (3 is odd)\n" @@ -3576,8 +3576,8 @@ TEST(AssertionTest, ASSERT_FALSE) { // Tests ASSERT_FALSE(predicate) for predicates returning AssertionResult. TEST(AssertionTest, AssertFalseWithAssertionResult) { ASSERT_FALSE(ResultIsEven(3)); -#if !defined(__BORLANDC__) || __BORLANDC__ >= 0x600 - // ICE's in C++Builder 2007. +#ifndef __BORLANDC__ + // ICE's in C++Builder. EXPECT_FATAL_FAILURE(ASSERT_FALSE(ResultIsEven(2)), "Value of: ResultIsEven(2)\n" " Actual: true (2 is even)\n" @@ -3877,10 +3877,16 @@ TEST(AssertionTest, AnonymousEnum) { ASSERT_LE(kCaseA, kCaseB); ASSERT_GT(kCaseB, kCaseA); ASSERT_GE(kCaseA, kCaseA); + +# ifndef __BORLANDC__ + + // ICE's in C++Builder. EXPECT_FATAL_FAILURE(ASSERT_EQ(kCaseA, kCaseB), "Value of: kCaseB"); EXPECT_FATAL_FAILURE(ASSERT_EQ(kCaseA, kCaseC), "Actual: 42"); +# endif + EXPECT_FATAL_FAILURE(ASSERT_EQ(kCaseA, kCaseC), "Which is: -1"); } @@ -4791,10 +4797,13 @@ TEST(ComparisonAssertionTest, AcceptsUnprintableArgs) { // Code tested by EXPECT_FATAL_FAILURE cannot reference local // variables, so we have to write UnprintableChar('x') instead of x. +#ifndef __BORLANDC__ + // ICE's in C++Builder. EXPECT_FATAL_FAILURE(ASSERT_NE(UnprintableChar('x'), UnprintableChar('x')), "1-byte object <78>"); EXPECT_FATAL_FAILURE(ASSERT_LE(UnprintableChar('y'), UnprintableChar('x')), "1-byte object <78>"); +#endif EXPECT_FATAL_FAILURE(ASSERT_LE(UnprintableChar('y'), UnprintableChar('x')), "1-byte object <79>"); EXPECT_FATAL_FAILURE(ASSERT_GE(UnprintableChar('x'), UnprintableChar('y')), @@ -7213,8 +7222,10 @@ TEST(CopyArrayTest, WorksForDegeneratedArrays) { TEST(CopyArrayTest, WorksForOneDimensionalArrays) { const char a[3] = "hi"; int b[3]; +#ifndef __BORLANDC__ // C++Builder cannot compile some array size deductions. CopyArray(a, &b); EXPECT_TRUE(ArrayEq(a, b)); +#endif int c[3]; CopyArray(a, 3, c); @@ -7224,8 +7235,10 @@ TEST(CopyArrayTest, WorksForOneDimensionalArrays) { TEST(CopyArrayTest, WorksForTwoDimensionalArrays) { const int a[2][3] = { { 0, 1, 2 }, { 3, 4, 5 } }; int b[2][3]; +#ifndef __BORLANDC__ // C++Builder cannot compile some array size deductions. CopyArray(a, &b); EXPECT_TRUE(ArrayEq(a, b)); +#endif int c[2][3]; CopyArray(a, 2, c); -- cgit v0.12