Commit a2a32c20 authored by kenton@google.com's avatar kenton@google.com

Support HP C++ on Tru64.

Patch (mostly) by Vincent Choinière <Choiniere.Vincent@hydro.qc.ca>.
parent 8da400ed
......@@ -49,3 +49,5 @@ Non-Google patch contributors:
text format.
Brian Atkinson <nairb774@gmail.com>
* Added @Override annotation to generated Java code where appropriate.
Vincent Choinire <Choiniere.Vincent@hydro.qc.ca>
* Tru64 support.
......@@ -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
==========================
......
......@@ -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
......
......@@ -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<FieldDescriptorProto::Label>(label()));
proto->set_type(static_cast<FieldDescriptorProto::Type>(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<FieldDescriptorProto::Label>(
implicit_cast<int>(label())));
proto->set_type(static_cast<FieldDescriptorProto::Type>(
implicit_cast<int>(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<FieldDescriptor::Type>(proto.type());
result->label_ = static_cast<FieldDescriptor::Label>(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<FieldDescriptor::Type>(
implicit_cast<int>(proto.type()));
result->label_ = static_cast<FieldDescriptor::Label>(
implicit_cast<int>(proto.label()));
// Some of these may be filled in when cross-linking.
result->containing_type_ = NULL;
result->extension_scope_ = NULL;
......
......@@ -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<FieldDescriptorProto::Type>(type));
static_cast<FieldDescriptorProto::Type>(static_cast<int>(type)));
if (type == FieldDescriptor::TYPE_MESSAGE ||
type == FieldDescriptor::TYPE_GROUP) {
......
......@@ -42,6 +42,8 @@
#endif
#include <errno.h>
#include <iostream>
#include <algorithm>
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/stl_util-inl.h>
......
......@@ -110,7 +110,14 @@
#include <vector>
#include <string>
#ifdef __DECCXX
// HP C++'s iosfwd doesn't work.
#include <iostream>
#else
#include <iosfwd>
#endif
#include <google/protobuf/stubs/common.h>
namespace google {
......
......@@ -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<string>::Clear() {
current_size_ = 0;
}
} // namespace protobuf
#endif // !defined(__DECCXX) || !defined(__osf__)
} // namespace protobuf
} // namespace google
......@@ -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<Element>::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<string>::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<string>::Clear();
#endif
template <typename Element>
void RepeatedPtrField<Element>::MergeFrom(const RepeatedPtrField& other) {
......@@ -698,9 +714,16 @@ class RepeatedPtrIterator
typename internal::remove_pointer<It>::type>::type> {
public:
typedef RepeatedPtrIterator<It> 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<It>::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) {}
......
......@@ -40,7 +40,11 @@
#include <cstddef>
#include <string>
#include <string.h>
#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 <inttypes.h>
#elif !defined(_MSC_VER)
#include <stdint.h>
#endif
......
......@@ -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;
}
......
......@@ -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
// ----------------------------------------------------------------------
......
......@@ -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
......@@ -112,6 +112,21 @@
namespace testing {
// Calling ForEach(internal::Delete<T>) 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<TestInfo>);
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<TestCase>);
test_cases_.ForEach(DeleteTestCase);
// Deletes every Environment.
environments_.ForEach(internal::Delete<Environment>);
environments_.ForEach(DeleteEnvironment);
// Deletes the current test result printer.
delete result_printer_;
......
......@@ -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
......
......@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment