From a2a32c20434807e9966e3f48375f9419134d1b55 Mon Sep 17 00:00:00 2001 From: "kenton@google.com" Date: Fri, 14 Nov 2008 17:29:32 +0000 Subject: Support HP C++ on Tru64. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Patch (mostly) by Vincent Choinière . --- CONTRIBUTORS.txt | 2 ++ README.txt | 10 +++++- src/google/protobuf/compiler/cpp/cpp_unittest.cc | 5 +-- src/google/protobuf/descriptor.cc | 18 +++++++--- src/google/protobuf/descriptor_unittest.cc | 4 +-- src/google/protobuf/io/zero_copy_stream_impl.cc | 2 ++ src/google/protobuf/message.h | 7 ++++ src/google/protobuf/repeated_field.cc | 9 ++++- src/google/protobuf/repeated_field.h | 29 ++++++++++++++-- src/google/protobuf/stubs/common.h | 6 +++- src/google/protobuf/stubs/strutil.cc | 9 +++-- src/google/protobuf/stubs/strutil.h | 4 +++ src/google/protobuf/text_format_unittest.cc | 6 ++-- src/gtest/gtest.cc | 43 ++++++++++-------------- src/gtest/internal/gtest-internal.h | 12 +++---- src/gtest/internal/gtest-port.h | 6 ++-- 16 files changed, 120 insertions(+), 52 deletions(-) diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index 21c83c66..454d99ba 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -49,3 +49,5 @@ Non-Google patch contributors: text format. Brian Atkinson * Added @Override annotation to generated Java code where appropriate. + Vincent Choinière + * Tru64 support. diff --git a/README.txt b/README.txt index 8e9dd067..8b7c8531 100644 --- a/README.txt +++ b/README.txt @@ -21,7 +21,7 @@ Proceed at your own risk. For advanced usage information on configure and make, see INSTALL.txt. -** Hint on insall location ** +** Hint on install location ** By default, the package will be installed to /usr/local. However, on many platforms, /usr/local/lib is not part of LD_LIBRARY_PATH. @@ -43,6 +43,14 @@ For advanced usage information on configure and make, see INSTALL.txt. See src/solaris/libstdc++.la for more info on this bug. +** Note for HP C++ Tru64 users ** + + To compile invoke configure as follows: + + ./configure CXXFLAGS="-O -std ansi -ieee -D__USE_STD_IOSTREAM" + + Also, you will need to use gmake instead of make. + C++ Installation - Windows ========================== diff --git a/src/google/protobuf/compiler/cpp/cpp_unittest.cc b/src/google/protobuf/compiler/cpp/cpp_unittest.cc index 1807b595..ce7d0c88 100644 --- a/src/google/protobuf/compiler/cpp/cpp_unittest.cc +++ b/src/google/protobuf/compiler/cpp/cpp_unittest.cc @@ -67,7 +67,8 @@ namespace protobuf { namespace compiler { namespace cpp { -namespace { +// Can't use an anonymous namespace here due to brokenness of Tru64 compiler. +namespace cpp_unittest { class MockErrorCollector : public MultiFileErrorCollector { @@ -854,7 +855,7 @@ TEST_F(GeneratedServiceTest, NotImplemented) { EXPECT_TRUE(controller.called_); } -} // namespace +} // namespace cpp_unittest } // namespace cpp } // namespace compiler diff --git a/src/google/protobuf/descriptor.cc b/src/google/protobuf/descriptor.cc index b843a06b..882b104b 100644 --- a/src/google/protobuf/descriptor.cc +++ b/src/google/protobuf/descriptor.cc @@ -1175,8 +1175,13 @@ void Descriptor::CopyTo(DescriptorProto* proto) const { void FieldDescriptor::CopyTo(FieldDescriptorProto* proto) const { proto->set_name(name()); proto->set_number(number()); - proto->set_label(static_cast(label())); - proto->set_type(static_cast(type())); + + // Some compilers do not allow static_cast directly between two enum types, + // so we must cast to int first. + proto->set_label(static_cast( + implicit_cast(label()))); + proto->set_type(static_cast( + implicit_cast(type()))); if (is_extension()) { proto->set_extendee("."); @@ -2487,10 +2492,15 @@ void DescriptorBuilder::BuildFieldOrExtension(const FieldDescriptorProto& proto, result->full_name_ = full_name; result->file_ = file_; result->number_ = proto.number(); - result->type_ = static_cast(proto.type()); - result->label_ = static_cast(proto.label()); result->is_extension_ = is_extension; + // Some compilers do not allow static_cast directly between two enum types, + // so we must cast to int first. + result->type_ = static_cast( + implicit_cast(proto.type())); + result->label_ = static_cast( + implicit_cast(proto.label())); + // Some of these may be filled in when cross-linking. result->containing_type_ = NULL; result->extension_scope_ = NULL; diff --git a/src/google/protobuf/descriptor_unittest.cc b/src/google/protobuf/descriptor_unittest.cc index c919b80d..b7dac69a 100644 --- a/src/google/protobuf/descriptor_unittest.cc +++ b/src/google/protobuf/descriptor_unittest.cc @@ -53,7 +53,7 @@ namespace google { namespace protobuf { -namespace { +namespace GOOGLE_ANONYMOUS_NAMESPACE{ // Some helpers to make assembling descriptors faster. DescriptorProto* AddMessage(FileDescriptorProto* file, const string& name) { @@ -1323,7 +1323,7 @@ class MiscTest : public testing::Test { DescriptorProto* message = AddMessage(&file_proto, "TestMessage"); FieldDescriptorProto* field = AddField(message, "foo", 1, FieldDescriptorProto::LABEL_OPTIONAL, - static_cast(type)); + static_cast(static_cast(type))); if (type == FieldDescriptor::TYPE_MESSAGE || type == FieldDescriptor::TYPE_GROUP) { diff --git a/src/google/protobuf/io/zero_copy_stream_impl.cc b/src/google/protobuf/io/zero_copy_stream_impl.cc index 10071054..04d573e1 100644 --- a/src/google/protobuf/io/zero_copy_stream_impl.cc +++ b/src/google/protobuf/io/zero_copy_stream_impl.cc @@ -42,6 +42,8 @@ #endif #include #include +#include + #include #include #include diff --git a/src/google/protobuf/message.h b/src/google/protobuf/message.h index 65419365..cd25faa2 100644 --- a/src/google/protobuf/message.h +++ b/src/google/protobuf/message.h @@ -110,7 +110,14 @@ #include #include + +#ifdef __DECCXX +// HP C++'s iosfwd doesn't work. +#include +#else #include +#endif + #include namespace google { diff --git a/src/google/protobuf/repeated_field.cc b/src/google/protobuf/repeated_field.cc index ca0033cb..2d5cb0a4 100644 --- a/src/google/protobuf/repeated_field.cc +++ b/src/google/protobuf/repeated_field.cc @@ -36,6 +36,12 @@ namespace google { namespace protobuf { + +// HP C++ on Tru64 can't handle the stuff below being defined out-of-line, so +// on that platform everything is defined in repeated_field.h. On other +// platforms, we want these to be out-of-line to avoid code bloat. +#if !defined(__DECCXX) || !defined(__osf__) + namespace internal { GenericRepeatedField::~GenericRepeatedField() {} @@ -50,6 +56,7 @@ void RepeatedPtrField::Clear() { current_size_ = 0; } -} // namespace protobuf +#endif // !defined(__DECCXX) || !defined(__osf__) +} // namespace protobuf } // namespace google diff --git a/src/google/protobuf/repeated_field.h b/src/google/protobuf/repeated_field.h index c81d27ef..203aa9bf 100644 --- a/src/google/protobuf/repeated_field.h +++ b/src/google/protobuf/repeated_field.h @@ -69,7 +69,12 @@ namespace internal { class LIBPROTOBUF_EXPORT GenericRepeatedField { public: inline GenericRepeatedField() {} +#if defined(__DECCXX) && defined(__osf__) + // HP C++ on Tru64 has trouble when this is not defined inline. + virtual ~GenericRepeatedField() {} +#else virtual ~GenericRepeatedField(); +#endif private: // We only want GeneratedMessageReflection to see and use these, so we @@ -516,9 +521,20 @@ void RepeatedPtrField::Clear() { current_size_ = 0; } +#if defined(__DECCXX) && defined(__osf__) +// HP C++ on Tru64 has trouble when this is not defined inline. +template <> +inline void RepeatedPtrField::Clear() { + for (int i = 0; i < current_size_; i++) { + elements_[i]->clear(); + } + current_size_ = 0; +} +#else // Specialization defined in repeated_field.cc. template <> void LIBPROTOBUF_EXPORT RepeatedPtrField::Clear(); +#endif template void RepeatedPtrField::MergeFrom(const RepeatedPtrField& other) { @@ -698,9 +714,16 @@ class RepeatedPtrIterator typename internal::remove_pointer::type>::type> { public: typedef RepeatedPtrIterator iterator; - typedef typename iterator::reference reference; - typedef typename iterator::pointer pointer; - typedef typename iterator::difference_type difference_type; + typedef std::iterator< + std::random_access_iterator_tag, + typename internal::remove_pointer< + typename internal::remove_pointer::type>::type> superclass; + + // Let the compiler know that these are type names, so we don't have to + // write "typename" in front of them everywhere. + typedef typename superclass::reference reference; + typedef typename superclass::pointer pointer; + typedef typename superclass::difference_type difference_type; RepeatedPtrIterator() : it_(NULL) {} explicit RepeatedPtrIterator(const It& it) : it_(it) {} diff --git a/src/google/protobuf/stubs/common.h b/src/google/protobuf/stubs/common.h index 05c15d1b..858d97fa 100644 --- a/src/google/protobuf/stubs/common.h +++ b/src/google/protobuf/stubs/common.h @@ -40,7 +40,11 @@ #include #include #include -#ifndef _MSC_VER +#if defined(__osf__) +// Tru64 lacks stdint.h, but has inttypes.h which defines a superset of +// what stdint.h would define. +#include +#elif !defined(_MSC_VER) #include #endif diff --git a/src/google/protobuf/stubs/strutil.cc b/src/google/protobuf/stubs/strutil.cc index d3407faf..bc417344 100644 --- a/src/google/protobuf/stubs/strutil.cc +++ b/src/google/protobuf/stubs/strutil.cc @@ -58,17 +58,22 @@ inline bool IsNaN(double value) { return value != value; } +// These are defined as macros on some platforms. #undef them so that we can +// redefine them. +#undef isxdigit +#undef isprint + // The definitions of these in ctype.h change based on locale. Since our // string manipulation is all in relation to the protocol buffer and C++ // languages, we always want to use the C locale. So, we re-define these // exactly as we want them. -static bool isxdigit(char c) { +inline bool isxdigit(char c) { return ('0' <= c && c <= '9') || ('a' <= c && c <= 'f') || ('A' <= c && c <= 'F'); } -static bool isprint(char c) { +inline bool isprint(char c) { return c >= 0x20 && c <= 0x7E; } diff --git a/src/google/protobuf/stubs/strutil.h b/src/google/protobuf/stubs/strutil.h index 984c17e8..7f6bd96f 100644 --- a/src/google/protobuf/stubs/strutil.h +++ b/src/google/protobuf/stubs/strutil.h @@ -42,6 +42,10 @@ namespace protobuf { #ifdef _MSC_VER #define strtoll _strtoi64 #define strtoull _strtoui64 +#elif defined(__DECCXX) && defined(__osf__) +// HP C++ on Tru64 does not have strtoll, but strtol is already 64-bit. +#define strtoll strtol +#define strtoull strtoul #endif // ---------------------------------------------------------------------- diff --git a/src/google/protobuf/text_format_unittest.cc b/src/google/protobuf/text_format_unittest.cc index 97a4fb03..7610c384 100644 --- a/src/google/protobuf/text_format_unittest.cc +++ b/src/google/protobuf/text_format_unittest.cc @@ -52,7 +52,9 @@ namespace google { namespace protobuf { -namespace { + +// Can't use an anonymous namespace here due to brokenness of Tru64 compiler. +namespace text_format_unittest { inline bool IsNaN(double value) { // NaN is never equal to anything, even itself. @@ -778,7 +780,7 @@ TEST_F(TextFormatMessageSetTest, Deserialize) { EXPECT_EQ(2, descriptors.size()); } -} // namespace +} // namespace text_format_unittest } // namespace protobuf } // namespace google diff --git a/src/gtest/gtest.cc b/src/gtest/gtest.cc index 1eee3922..09a0815a 100644 --- a/src/gtest/gtest.cc +++ b/src/gtest/gtest.cc @@ -112,6 +112,21 @@ namespace testing { +// Calling ForEach(internal::Delete) doesn't work on HP C++ / Tru64. So, +// we must define a separate non-template function for each type. +static void DeleteTestCase(TestCase *x) +{ + delete x; +} +static void DeleteEnvironment(Environment *x) +{ + delete x; +} +static void DeleteTestInfo(TestInfo *x) +{ + delete x; +} + // Constants. // A test that matches this pattern is disabled and not run. @@ -799,28 +814,6 @@ String FormatForFailureMessage(char ch) { ch_as_uint, ch_as_uint); } -// For a wchar_t value, we print it as a C++ wchar_t literal and as an -// unsigned integer (both in decimal and in hexidecimal). -String FormatForFailureMessage(wchar_t wchar) { - // The C++ standard doesn't specify the exact size of the wchar_t - // type. It just says that it shall have the same size as another - // integral type, called its underlying type. - // - // Therefore, in order to print a wchar_t value in the numeric form, - // we first convert it to the largest integral type (UInt64) and - // then print the converted value. - // - // We use streaming to print the value as "%llu" doesn't work - // correctly with MSVC 7.1. - const UInt64 wchar_as_uint64 = wchar; - Message msg; - // A String object cannot contain '\0', so we print "\\0" when wchar is - // L'\0'. - msg << "L'" << (wchar ? ToUtf8String(wchar).c_str() : "\\0") << "' (" - << wchar_as_uint64 << ", 0x" << ::std::setbase(16) - << wchar_as_uint64 << ")"; - return msg.GetString(); -} } // namespace internal @@ -2059,7 +2052,7 @@ TestCase::TestCase(const char* name, // Destructor of TestCase. TestCase::~TestCase() { // Deletes every Test in the collection. - test_info_list_->ForEach(internal::Delete); + test_info_list_->ForEach(DeleteTestInfo); // Then deletes the Test collection. delete test_info_list_; @@ -3039,10 +3032,10 @@ UnitTestImpl::UnitTestImpl(UnitTest* parent) UnitTestImpl::~UnitTestImpl() { // Deletes every TestCase. - test_cases_.ForEach(internal::Delete); + test_cases_.ForEach(DeleteTestCase); // Deletes every Environment. - environments_.ForEach(internal::Delete); + environments_.ForEach(DeleteEnvironment); // Deletes the current test result printer. delete result_printer_; diff --git a/src/gtest/internal/gtest-internal.h b/src/gtest/internal/gtest-internal.h index 2be1b4ac..883981f6 100644 --- a/src/gtest/internal/gtest-internal.h +++ b/src/gtest/internal/gtest-internal.h @@ -210,12 +210,13 @@ String StreamableToString(const T& streamable); // Formats a value to be used in a failure message. -#ifdef __SYMBIAN32__ +#if defined (__SYMBIAN32__) || (defined (__DECCXX) && defined(__osf__)) -// These are needed as the Nokia Symbian Compiler cannot decide between -// const T& and const T* in a function template. The Nokia compiler _can_ -// decide between class template specializations for T and T*, so a -// tr1::type_traits-like is_pointer works, and we can overload on that. +// These are needed as the Nokia Symbian Compiler and HP C++ on Tru64 +// cannot decide between const T& and const T* in a function template. +// These compliers _can_ decide between class template specializations +// for T and T*, so a tr1::type_traits-like is_pointer works, and we +// can overload on that. // This overload makes sure that all pointers (including // those to char or wchar_t) are printed as raw pointers. @@ -255,7 +256,6 @@ inline String FormatForFailureMessage(T* pointer) { // These overloaded versions handle narrow and wide characters. String FormatForFailureMessage(char ch); -String FormatForFailureMessage(wchar_t wchar); // When this operand is a const char* or char*, and the other operand // is a ::std::string or ::string, we print this operand as a C string diff --git a/src/gtest/internal/gtest-port.h b/src/gtest/internal/gtest-port.h index 36d5a149..9d65ec83 100644 --- a/src/gtest/internal/gtest-port.h +++ b/src/gtest/internal/gtest-port.h @@ -223,10 +223,10 @@ // struct Foo { // Foo() { ... } // } GTEST_ATTRIBUTE_UNUSED; -#if defined(GTEST_OS_WINDOWS) || (defined(GTEST_OS_LINUX) && defined(SWIG)) -#define GTEST_ATTRIBUTE_UNUSED -#else +#ifdef __GNUC__ #define GTEST_ATTRIBUTE_UNUSED __attribute__ ((unused)) +#else +#define GTEST_ATTRIBUTE_UNUSED #endif // GTEST_OS_WINDOWS || (GTEST_OS_LINUX && SWIG) // A macro to disallow the evil copy constructor and operator= functions -- cgit v1.2.3