Clean up HAVE_MEMBER_TEMPLATE_SPECIFICATIONS somewhat.
authorIan Lance Taylor <iant@google.com>
Fri, 29 Sep 2006 22:34:01 +0000 (22:34 +0000)
committerIan Lance Taylor <iant@google.com>
Fri, 29 Sep 2006 22:34:01 +0000 (22:34 +0000)
gold/gold.h
gold/object.h
gold/output.cc
gold/output.h
gold/resolve.cc
gold/symtab.cc
gold/symtab.h

index cb17ae765635abba7077911e0239f71f57515956..9ddf2f792a1ef52a83c5fdec111b4fea427dca95 100644 (file)
@@ -77,6 +77,62 @@ struct hash<T*>
 
 #endif
 
+namespace gold
+{
+// This is a hack to work around a problem with older versions of g++.
+// The problem is that they don't support calling a member template by
+// specifying the template parameters.  It works to pass in an
+// argument for argument dependent lookup.
+
+// To use this, the member template method declaration should put
+// ACCEPT_SIZE or ACCEPT_SIZE_ENDIAN after the last parameter.  If the
+// method takes no parameters, use ACCEPT_SIZE_ONLY or
+// ACCEPT_SIZE_ENDIAN_ONLY.
+
+// When calling the method, instead of using fn<size>, use fn
+// SELECT_SIZE_NAME or SELECT_SIZE_ENDIAN_NAME.  And after the last
+// argument, put SELECT_SIZE(size) or SELECT_SIZE_ENDIAN(size,
+// big_endian).  If there is only one argment, use the _ONLY variants.
+
+#ifdef HAVE_MEMBER_TEMPLATE_SPECIFICATIONS
+
+#define SELECT_SIZE_NAME <size>
+#define SELECT_SIZE(size)
+#define SELECT_SIZE_ONLY(size)
+#define ACCEPT_SIZE
+#define ACCEPT_SIZE_ONLY
+
+#define SELECT_SIZE_ENDIAN_NAME <size, big_endian>
+#define SELECT_SIZE_ENDIAN(size, big_endian)
+#define SELECT_SIZE_ENDIAN_ONLY(size, big_endian)
+#define ACCEPT_SIZE_ENDIAN
+#define ACCEPT_SIZE_ENDIAN_ONLY
+
+#else // !defined(HAVE_MEMBER_TEMPLATE_SPECIFICATIONS)
+
+template<int size>
+class Select_size { };
+template<int size, bool big_endian>
+class Select_size_endian { };
+
+#define SELECT_SIZE_NAME
+#define SELECT_SIZE(size) , Select_size<size>()
+#define SELECT_SIZE_ONLY(size) Select_size<size>()
+#define ACCEPT_SIZE , Select_size<size>
+#define ACCEPT_SIZE_ONLY Select_size<size>
+
+#define SELECT_SIZE_ENDIAN_NAME
+#define SELECT_SIZE_ENDIAN(size, big_endian) \
+  , Select_size_endian<size, big_endian>()
+#define SELECT_SIZE_ENDIAN_ONLY(size, big_endian) \
+  Select_size_endian<size, big_endian>()
+#define ACCEPT_SIZE_ENDIAN , Select_size_endian<size, big_endian>
+#define ACCEPT_SIZE_ENDIAN_ONLY Select_size_endian<size, big_endian>
+
+#endif // !defined(HAVE_MEMBER_TEMPLATE_SPECIFICATIONS)
+
+} // End namespace gold.
+
 namespace gold
 {
 
index 198e0153016ef4fd4bd0d4c75d846763812c3933..cea0f06a8f7123a4d3cd9a0538b9638862782953 100644 (file)
@@ -85,14 +85,12 @@ class Object
   is_locked() const
   { return this->input_file_->file().is_locked(); }
 
-#ifdef HAVE_MEMBER_TEMPLATE_SPECIFICATIONS
   // Return the sized target structure associated with this object.
   // This is like the target method but it returns a pointer of
   // appropriate checked type.
   template<int size, bool big_endian>
   Sized_target<size, big_endian>*
-  sized_target();
-#endif
+  sized_target(ACCEPT_SIZE_ENDIAN_ONLY);
 
   // Read the symbol and relocation information.
   Read_symbols_data
@@ -232,22 +230,18 @@ class Object
   std::vector<Map_to_output> map_to_output_;
 };
 
-#ifdef HAVE_MEMBER_TEMPLATE_SPECIFICATIONS
-
 // Implement sized_target inline for efficiency.  This approach breaks
 // static type checking, but is made safe using asserts.
 
 template<int size, bool big_endian>
 inline Sized_target<size, big_endian>*
-Object::sized_target()
+Object::sized_target(ACCEPT_SIZE_ENDIAN_ONLY)
 {
   assert(this->target_->get_size() == size);
   assert(this->target_->is_big_endian() ? big_endian : !big_endian);
   return static_cast<Sized_target<size, big_endian>*>(this->target_);
 }
 
-#endif
-
 // A regular object file.  This is size and endian specific.
 
 template<int size, bool big_endian>
@@ -288,11 +282,8 @@ class Sized_object : public Object
   Sized_target<size, big_endian>*
   sized_target()
   {
-#ifdef HAVE_MEMBER_TEMPLATE_SPECIFICATIONS
-    return this->Object::sized_target<size, big_endian>();
-#else
-    return static_cast<Sized_target<size, big_endian>*>(this->target());
-#endif
+    return this->Object::sized_target SELECT_SIZE_ENDIAN_NAME (
+      SELECT_SIZE_ENDIAN_ONLY(size, big_endian));
   }
 
  private:
index ababd8c289fcf29284468042a03fc6b4c621998f..82e2ca5d421d3d0609164d25930758ebb5cbf833 100644 (file)
@@ -140,7 +140,8 @@ Output_section_headers::do_sized_write(Output_file* of)
   for (Layout::Segment_list::const_iterator p = this->segment_list_.begin();
        p != this->segment_list_.end();
        ++p)
-    v = (*p)->write_section_headers<size, big_endian>(this->secnamepool_, v);
+    v = (*p)->write_section_headers SELECT_SIZE_ENDIAN_NAME (
+      this->secnamepool_, v SELECT_SIZE_ENDIAN(size, big_endian));
   for (Layout::Section_list::const_iterator p = this->section_list_.begin();
        p != this->section_list_.end();
        ++p)
@@ -324,7 +325,8 @@ Output_file_header::do_sized_write(Output_file* of)
   else
     {
       Sized_symbol<size>* ssym;
-      ssym = this->symtab_->get_sized_symbol<size>(sym);
+      ssym = this->symtab_->get_sized_symbol SELECT_SIZE_NAME (
+        sym SELECT_SIZE(size));
       v = ssym->value();
     }
   oehdr.put_e_entry(v);
@@ -715,14 +717,13 @@ Output_segment::write_header(elfcpp::Phdr_write<size, big_endian>* ophdr) const
 template<int size, bool big_endian>
 unsigned char*
 Output_segment::write_section_headers(const Stringpool* secnamepool,
-                                     unsigned char* v) const
-{
-  v = this->write_section_headers_list<size, big_endian>(secnamepool,
-                                                        &this->output_data_,
-                                                        v);
-  v = this->write_section_headers_list<size, big_endian>(secnamepool,
-                                                        &this->output_bss_,
-                                                        v);
+                                     unsigned char* v
+                                      ACCEPT_SIZE_ENDIAN) const
+{
+  v = this->write_section_headers_list SELECT_SIZE_ENDIAN_NAME (
+    secnamepool, &this->output_data_, v SELECT_SIZE_ENDIAN(size, big_endian));
+  v = this->write_section_headers_list SELECT_SIZE_ENDIAN_NAME (
+    secnamepool, &this->output_bss_, v SELECT_SIZE_ENDIAN(size, big_endian));
   return v;
 }
 
@@ -730,7 +731,8 @@ template<int size, bool big_endian>
 unsigned char*
 Output_segment::write_section_headers_list(const Stringpool* secnamepool,
                                           const Output_data_list* pdl,
-                                          unsigned char* v) const
+                                          unsigned char* v
+                                           ACCEPT_SIZE_ENDIAN) const
 {
   const int shdr_size = elfcpp::Elf_sizes<size>::shdr_size;
   for (Output_data_list::const_iterator p = pdl->begin();
@@ -739,7 +741,7 @@ Output_segment::write_section_headers_list(const Stringpool* secnamepool,
     {
       if ((*p)->is_section())
        {
-         Output_section* ps = static_cast<const Output_section*>(*p);
+         const Output_section* ps = static_cast<const Output_section*>(*p);
          elfcpp::Shdr_write<size, big_endian> oshdr(v);
          ps->write_header(secnamepool, &oshdr);
          v += shdr_size;
index c6f2c785cb936bdcf95a48a39f89881250a7db3b..368e4ba4387ab890bc3093523ed929f521755157 100644 (file)
@@ -481,7 +481,8 @@ class Output_segment
   // Write the section headers of associated sections into V.
   template<int size, bool big_endian>
   unsigned char*
-  write_section_headers(const Stringpool*, unsigned char* v) const;
+  write_section_headers(const Stringpool*,
+                        unsigned char* v ACCEPT_SIZE_ENDIAN) const;
 
  private:
   Output_segment(const Output_segment&);
@@ -501,7 +502,7 @@ class Output_segment
   template<int size, bool big_endian>
   unsigned char*
   write_section_headers_list(const Stringpool*, const Output_data_list*,
-                            unsigned char* v) const;
+                            unsigned char* v ACCEPT_SIZE_ENDIAN) const;
 
   // The list of output data with contents attached to this segment.
   Output_data_list output_data_;
index 669fbaf232ea153d6de4899e07f10a95176b2895..98e93f0737b88b557b41c4121fade8c288a2ca34 100644 (file)
@@ -53,14 +53,8 @@ Symbol_table::resolve(Sized_symbol<size>* to,
   if (object->target()->has_resolve())
     {
       Sized_target<size, big_endian>* sized_target;
-#ifdef HAVE_MEMBER_TEMPLATE_SPECIFICATIONS
-      sized_target = object->sized_target<size, big_endian>();
-#else
-      Target* target = object->target();
-      assert(target->get_size() == size);
-      assert(target->is_big_endian() ? big_endian : !big_endian);
-      sized_target = static_cast<Sized_target<size, big_endian>*>(target);
-#endif
+      sized_target = object->sized_target SELECT_SIZE_ENDIAN_NAME (
+       SELECT_SIZE_ENDIAN_ONLY(size, big_endian));
       sized_target->resolve(to, sym, object);
       return;
     }
index cc77b37e3df5e8cc43d8e620019eaec65bbdde92..2251ea76c7d1f3dc64d1aad428033d712f1064d5 100644 (file)
@@ -133,11 +133,10 @@ Symbol_table::lookup(const char* name, const char* version) const
 // version is the default version.  Because this is unusual, we do
 // this the slow way, by converting back to an ELF symbol.
 
-#ifdef HAVE_MEMBER_TEMPLATE_SPECIFICATIONS
-
 template<int size, bool big_endian>
 void
-Symbol_table::resolve(Sized_symbol<size>* to, const Sized_symbol<size>* from)
+Symbol_table::resolve(Sized_symbol<size>* to, const Sized_symbol<size>* from
+                      ACCEPT_SIZE_ENDIAN)
 {
   unsigned char buf[elfcpp::Elf_sizes<size>::sym_size];
   elfcpp::Sym_write<size, big_endian> esym(buf);
@@ -150,40 +149,6 @@ Symbol_table::resolve(Sized_symbol<size>* to, const Sized_symbol<size>* from)
   Symbol_table::resolve(to, esym.sym(), from->object());
 }
 
-#else
-
-template<int size>
-void
-Symbol_table::resolve(Sized_symbol<size>* to, const Sized_symbol<size>* from,
-                      bool big_endian)
-{
-  unsigned char buf[elfcpp::Elf_sizes<size>::sym_size];
-  if (big_endian)
-    {
-      elfcpp::Sym_write<size, true> esym(buf);
-      // We don't bother to set the st_name field.
-      esym.put_st_value(from->value());
-      esym.put_st_size(from->symsize());
-      esym.put_st_info(from->binding(), from->type());
-      esym.put_st_other(from->visibility(), from->other());
-      esym.put_st_shndx(from->shnum());
-      Symbol_table::resolve(to, esym.sym(), from->object());
-    }
-  else
-    {
-      elfcpp::Sym_write<size, false> esym(buf);
-      // We don't bother to set the st_name field.
-      esym.put_st_value(from->value());
-      esym.put_st_size(from->symsize());
-      esym.put_st_info(from->binding(), from->type());
-      esym.put_st_other(from->visibility(), from->other());
-      esym.put_st_shndx(from->shnum());
-      Symbol_table::resolve(to, esym.sym(), from->object());
-    }
-}
-
-#endif
-
 // Add one symbol from OBJECT to the symbol table.  NAME is symbol
 // name and VERSION is the version; both are canonicalized.  DEF is
 // whether this is the default version.
@@ -236,12 +201,8 @@ Symbol_table::add_from_object(Sized_object<size, big_endian>* object,
   if (!ins.second)
     {
       // We already have an entry for NAME/VERSION.
-#ifdef HAVE_MEMBER_TEMPLATE_SPECIFICATIONS
-      ret = this->get_sized_symbol<size>(ins.first->second);
-#else
-      assert(size == this->get_size());
-      ret = static_cast<Sized_symbol<size>*>(ins.first->second);
-#endif
+      ret = this->get_sized_symbol SELECT_SIZE_NAME (ins.first->second
+                                                     SELECT_SIZE(size));
       assert(ret != NULL);
       Symbol_table::resolve(ret, sym, object);
 
@@ -258,13 +219,11 @@ Symbol_table::add_from_object(Sized_object<size, big_endian>* object,
              // This is the unfortunate case where we already have
              // entries for both NAME/VERSION and NAME/NULL.
              const Sized_symbol<size>* sym2;
-#ifdef HAVE_MEMBER_TEMPLATE_SPECIFICATIONS
-             sym2 = this->get_sized_symbol<size>(insdef.first->second);
-             Symbol_table::resolve<size, big_endian>(ret, sym2);
-#else
-             sym2 = static_cast<Sized_symbol<size>*>(insdef.first->second);
-             Symbol_table::resolve(ret, sym2, big_endian);
-#endif
+             sym2 = this->get_sized_symbol SELECT_SIZE_NAME (
+               insdef.first->second
+                SELECT_SIZE(size));
+             Symbol_table::resolve SELECT_SIZE_ENDIAN_NAME (
+               ret, sym2 SELECT_SIZE_ENDIAN(size, big_endian));
              this->make_forwarder(insdef.first->second, ret);
              insdef.first->second = ret;
            }
@@ -278,11 +237,8 @@ Symbol_table::add_from_object(Sized_object<size, big_endian>* object,
        {
          // We already have an entry for NAME/NULL.  Make
          // NAME/VERSION point to it.
-#ifdef HAVE_MEMBER_TEMPLATE_SPECIFICATIONS
-         ret = this->get_sized_symbol<size>(insdef.first->second);
-#else
-          ret = static_cast<Sized_symbol<size>*>(insdef.first->second);
-#endif
+         ret = this->get_sized_symbol SELECT_SIZE_NAME (insdef.first->second
+                                                         SELECT_SIZE(size));
          Symbol_table::resolve(ret, sym, object);
          ins.first->second = ret;
        }
index 51bb269c527b9d6b2746701267e9d63a9ca3b40d..23d54e4d58efbb975ba25fd7715d793131dd5e6f 100644 (file)
@@ -236,11 +236,11 @@ class Symbol_table
   // Return the sized version of a symbol in this table.
   template<int size>
   Sized_symbol<size>*
-  get_sized_symbol(Symbol*) const;
+  get_sized_symbol(Symbol* ACCEPT_SIZE) const;
 
   template<int size>
   const Sized_symbol<size>*
-  get_sized_symbol(const Symbol*) const;
+  get_sized_symbol(const Symbol* ACCEPT_SIZE) const;
 
   // Finalize the symbol table after we have set the final addresses
   // of all the input sections.  This sets the final symbol values and
@@ -280,16 +280,10 @@ class Symbol_table
          const elfcpp::Sym<size, big_endian>& sym,
          Object*);
 
-#ifdef HAVE_MEMBER_TEMPLATE_SPECIFICATIONS
   template<int size, bool big_endian>
   static void
-  resolve(Sized_symbol<size>* to, const Sized_symbol<size>* from);
-#else
-  template<int size>
-  static void
-  resolve(Sized_symbol<size>* to, const Sized_symbol<size>* from,
-          bool big_endian);
-#endif
+  resolve(Sized_symbol<size>* to, const Sized_symbol<size>* from
+          ACCEPT_SIZE_ENDIAN);
 
   // Finalize symbols specialized for size.
   template<int size>
@@ -345,7 +339,7 @@ class Symbol_table
 
 template<int size>
 Sized_symbol<size>*
-Symbol_table::get_sized_symbol(Symbol* sym) const
+Symbol_table::get_sized_symbol(Symbol* sym ACCEPT_SIZE) const
 {
   assert(size == this->get_size());
   return static_cast<Sized_symbol<size>*>(sym);
@@ -353,7 +347,7 @@ Symbol_table::get_sized_symbol(Symbol* sym) const
 
 template<int size>
 const Sized_symbol<size>*
-Symbol_table::get_sized_symbol(const Symbol* sym) const
+Symbol_table::get_sized_symbol(const Symbol* sym ACCEPT_SIZE) const
 {
   assert(size == this->get_size());
   return static_cast<const Sized_symbol<size>*>(sym);