From 1900c536cd91bae783e6766d3fc016e75061d17c Mon Sep 17 00:00:00 2001
From: "kenton@google.com"
 <kenton@google.com@630680e5-0e50-0410-840e-4b1c322b438d>
Date: Sat, 1 Aug 2009 00:30:11 +0000
Subject: [PATCH] Fix compile for GCC 3.4.4.

---
 src/google/protobuf/extension_set.h        | 10 ++++++++++
 src/google/protobuf/extension_set_heavy.cc |  9 ++++++---
 2 files changed, 16 insertions(+), 3 deletions(-)

diff --git a/src/google/protobuf/extension_set.h b/src/google/protobuf/extension_set.h
index 8c1d73b878..8c0f12a5c4 100644
--- a/src/google/protobuf/extension_set.h
+++ b/src/google/protobuf/extension_set.h
@@ -61,6 +61,7 @@ namespace protobuf {
   }
   namespace internal {
     class FieldSkipper;                                  // wire_format_lite.h
+    class RepeatedPtrFieldBase;                          // repeated_field.h
   }
   template <typename Element> class RepeatedField;     // repeated_field.h
   template <typename Element> class RepeatedPtrField;  // repeated_field.h
@@ -388,6 +389,15 @@ class LIBPROTOBUF_EXPORT ExtensionSet {
                            const MessageLite* containing_type,
                            FieldSkipper* field_skipper);
 
+  // Hack:  RepeatedPtrFieldBase declares ExtensionSet as a friend.  This
+  //   friendship should automatically extend to ExtensionSet::Extension, but
+  //   unfortunately some older compilers (e.g. GCC 3.4.4) do not implement this
+  //   correctly.  So, we must provide helpers for calling methods of that
+  //   class.
+
+  // Defined in extension_set_heavy.cc.
+  static inline int RepeatedMessage_SpaceUsedExcludingSelf(
+      RepeatedPtrFieldBase* field);
 
   // The Extension struct is small enough to be passed by value, so we use it
   // directly as the value type in the map rather than use pointers.  We use
diff --git a/src/google/protobuf/extension_set_heavy.cc b/src/google/protobuf/extension_set_heavy.cc
index dbe9e33656..8555f6f8bc 100644
--- a/src/google/protobuf/extension_set_heavy.cc
+++ b/src/google/protobuf/extension_set_heavy.cc
@@ -165,6 +165,11 @@ int ExtensionSet::SpaceUsedExcludingSelf() const {
   return total_size;
 }
 
+inline int ExtensionSet::RepeatedMessage_SpaceUsedExcludingSelf(
+    RepeatedPtrFieldBase* field) {
+  return field->SpaceUsedExcludingSelf<GenericTypeHandler<Message> >();
+}
+
 int ExtensionSet::Extension::SpaceUsedExcludingSelf() const {
   int total_size = 0;
   if (is_repeated) {
@@ -191,9 +196,7 @@ int ExtensionSet::Extension::SpaceUsedExcludingSelf() const {
         // RepeatedPtrFieldBase::SpaceUsedExcludingSelf() with a different type
         // handler.
         total_size += sizeof(*repeated_message_value) +
-            repeated_message_value->
-              RepeatedPtrFieldBase::SpaceUsedExcludingSelf<
-                GenericTypeHandler<Message> >();
+            RepeatedMessage_SpaceUsedExcludingSelf(repeated_message_value);
         break;
     }
   } else {