From 5482377ddc6d4104399a7e2e49518a6e893dca65 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Fri, 29 Sep 2006 22:34:01 +0000 Subject: [PATCH] Clean up HAVE_MEMBER_TEMPLATE_SPECIFICATIONS somewhat. --- gold/gold.h | 56 +++++++++++++++++++++++++++++++++++++++++ gold/object.h | 17 +++---------- gold/output.cc | 26 ++++++++++--------- gold/output.h | 5 ++-- gold/resolve.cc | 10 ++------ gold/symtab.cc | 66 +++++++++---------------------------------------- gold/symtab.h | 18 +++++--------- 7 files changed, 96 insertions(+), 102 deletions(-) diff --git a/gold/gold.h b/gold/gold.h index cb17ae76563..9ddf2f792a1 100644 --- a/gold/gold.h +++ b/gold/gold.h @@ -77,6 +77,62 @@ struct hash #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, 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 +#define SELECT_SIZE(size) +#define SELECT_SIZE_ONLY(size) +#define ACCEPT_SIZE +#define ACCEPT_SIZE_ONLY + +#define SELECT_SIZE_ENDIAN_NAME +#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 +class Select_size { }; +template +class Select_size_endian { }; + +#define SELECT_SIZE_NAME +#define SELECT_SIZE(size) , Select_size() +#define SELECT_SIZE_ONLY(size) Select_size() +#define ACCEPT_SIZE , Select_size +#define ACCEPT_SIZE_ONLY Select_size + +#define SELECT_SIZE_ENDIAN_NAME +#define SELECT_SIZE_ENDIAN(size, big_endian) \ + , Select_size_endian() +#define SELECT_SIZE_ENDIAN_ONLY(size, big_endian) \ + Select_size_endian() +#define ACCEPT_SIZE_ENDIAN , Select_size_endian +#define ACCEPT_SIZE_ENDIAN_ONLY Select_size_endian + +#endif // !defined(HAVE_MEMBER_TEMPLATE_SPECIFICATIONS) + +} // End namespace gold. + namespace gold { diff --git a/gold/object.h b/gold/object.h index 198e0153016..cea0f06a8f7 100644 --- a/gold/object.h +++ b/gold/object.h @@ -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 Sized_target* - 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_; }; -#ifdef HAVE_MEMBER_TEMPLATE_SPECIFICATIONS - // Implement sized_target inline for efficiency. This approach breaks // static type checking, but is made safe using asserts. template inline Sized_target* -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*>(this->target_); } -#endif - // A regular object file. This is size and endian specific. template @@ -288,11 +282,8 @@ class Sized_object : public Object Sized_target* sized_target() { -#ifdef HAVE_MEMBER_TEMPLATE_SPECIFICATIONS - return this->Object::sized_target(); -#else - return static_cast*>(this->target()); -#endif + return this->Object::sized_target SELECT_SIZE_ENDIAN_NAME ( + SELECT_SIZE_ENDIAN_ONLY(size, big_endian)); } private: diff --git a/gold/output.cc b/gold/output.cc index ababd8c289f..82e2ca5d421 100644 --- a/gold/output.cc +++ b/gold/output.cc @@ -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(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* ssym; - ssym = this->symtab_->get_sized_symbol(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* ophdr) const template unsigned char* Output_segment::write_section_headers(const Stringpool* secnamepool, - unsigned char* v) const -{ - v = this->write_section_headers_list(secnamepool, - &this->output_data_, - v); - v = this->write_section_headers_list(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 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::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(*p); + const Output_section* ps = static_cast(*p); elfcpp::Shdr_write oshdr(v); ps->write_header(secnamepool, &oshdr); v += shdr_size; diff --git a/gold/output.h b/gold/output.h index c6f2c785cb9..368e4ba4387 100644 --- a/gold/output.h +++ b/gold/output.h @@ -481,7 +481,8 @@ class Output_segment // Write the section headers of associated sections into V. template 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 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_; diff --git a/gold/resolve.cc b/gold/resolve.cc index 669fbaf232e..98e93f0737b 100644 --- a/gold/resolve.cc +++ b/gold/resolve.cc @@ -53,14 +53,8 @@ Symbol_table::resolve(Sized_symbol* to, if (object->target()->has_resolve()) { Sized_target* sized_target; -#ifdef HAVE_MEMBER_TEMPLATE_SPECIFICATIONS - sized_target = object->sized_target(); -#else - Target* target = object->target(); - assert(target->get_size() == size); - assert(target->is_big_endian() ? big_endian : !big_endian); - sized_target = static_cast*>(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; } diff --git a/gold/symtab.cc b/gold/symtab.cc index cc77b37e3df..2251ea76c7d 100644 --- a/gold/symtab.cc +++ b/gold/symtab.cc @@ -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 void -Symbol_table::resolve(Sized_symbol* to, const Sized_symbol* from) +Symbol_table::resolve(Sized_symbol* to, const Sized_symbol* from + ACCEPT_SIZE_ENDIAN) { unsigned char buf[elfcpp::Elf_sizes::sym_size]; elfcpp::Sym_write esym(buf); @@ -150,40 +149,6 @@ Symbol_table::resolve(Sized_symbol* to, const Sized_symbol* from) Symbol_table::resolve(to, esym.sym(), from->object()); } -#else - -template -void -Symbol_table::resolve(Sized_symbol* to, const Sized_symbol* from, - bool big_endian) -{ - unsigned char buf[elfcpp::Elf_sizes::sym_size]; - if (big_endian) - { - elfcpp::Sym_write 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 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* object, if (!ins.second) { // We already have an entry for NAME/VERSION. -#ifdef HAVE_MEMBER_TEMPLATE_SPECIFICATIONS - ret = this->get_sized_symbol(ins.first->second); -#else - assert(size == this->get_size()); - ret = static_cast*>(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* object, // This is the unfortunate case where we already have // entries for both NAME/VERSION and NAME/NULL. const Sized_symbol* sym2; -#ifdef HAVE_MEMBER_TEMPLATE_SPECIFICATIONS - sym2 = this->get_sized_symbol(insdef.first->second); - Symbol_table::resolve(ret, sym2); -#else - sym2 = static_cast*>(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* 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(insdef.first->second); -#else - ret = static_cast*>(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; } diff --git a/gold/symtab.h b/gold/symtab.h index 51bb269c527..23d54e4d58e 100644 --- a/gold/symtab.h +++ b/gold/symtab.h @@ -236,11 +236,11 @@ class Symbol_table // Return the sized version of a symbol in this table. template Sized_symbol* - get_sized_symbol(Symbol*) const; + get_sized_symbol(Symbol* ACCEPT_SIZE) const; template const Sized_symbol* - 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& sym, Object*); -#ifdef HAVE_MEMBER_TEMPLATE_SPECIFICATIONS template static void - resolve(Sized_symbol* to, const Sized_symbol* from); -#else - template - static void - resolve(Sized_symbol* to, const Sized_symbol* from, - bool big_endian); -#endif + resolve(Sized_symbol* to, const Sized_symbol* from + ACCEPT_SIZE_ENDIAN); // Finalize symbols specialized for size. template @@ -345,7 +339,7 @@ class Symbol_table template Sized_symbol* -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*>(sym); @@ -353,7 +347,7 @@ Symbol_table::get_sized_symbol(Symbol* sym) const template const Sized_symbol* -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*>(sym); -- 2.30.2