diff options
author | Ian Lance Taylor <iant@google.com> | 2006-09-29 22:34:01 +0000 |
---|---|---|
committer | Ian Lance Taylor <iant@google.com> | 2006-09-29 22:34:01 +0000 |
commit | 5482377ddc6d4104399a7e2e49518a6e893dca65 (patch) | |
tree | 17d8018e5b63b67fee207053404b8479c00f6843 | |
parent | 61ba1cf93601b0a0877a8ade94ba3c674a09f77e (diff) | |
download | fsf-binutils-gdb-5482377ddc6d4104399a7e2e49518a6e893dca65.zip fsf-binutils-gdb-5482377ddc6d4104399a7e2e49518a6e893dca65.tar.gz fsf-binutils-gdb-5482377ddc6d4104399a7e2e49518a6e893dca65.tar.bz2 |
Clean up HAVE_MEMBER_TEMPLATE_SPECIFICATIONS somewhat.
-rw-r--r-- | gold/gold.h | 56 | ||||
-rw-r--r-- | gold/object.h | 17 | ||||
-rw-r--r-- | gold/output.cc | 26 | ||||
-rw-r--r-- | gold/output.h | 5 | ||||
-rw-r--r-- | gold/resolve.cc | 10 | ||||
-rw-r--r-- | gold/symtab.cc | 66 | ||||
-rw-r--r-- | gold/symtab.h | 18 |
7 files changed, 96 insertions, 102 deletions
diff --git a/gold/gold.h b/gold/gold.h index cb17ae7..9ddf2f7 100644 --- a/gold/gold.h +++ b/gold/gold.h @@ -79,6 +79,62 @@ struct hash<T*> 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 +{ class General_options; class Input_objects; diff --git a/gold/object.h b/gold/object.h index 198e015..cea0f06 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<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: diff --git a/gold/output.cc b/gold/output.cc index ababd8c..82e2ca5 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<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; diff --git a/gold/output.h b/gold/output.h index c6f2c78..368e4ba 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<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_; diff --git a/gold/resolve.cc b/gold/resolve.cc index 669fbaf..98e93f0 100644 --- a/gold/resolve.cc +++ b/gold/resolve.cc @@ -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; } diff --git a/gold/symtab.cc b/gold/symtab.cc index cc77b37..2251ea7 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<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; } diff --git a/gold/symtab.h b/gold/symtab.h index 51bb269..23d54e4 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<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); |