Clean up HAVE_MEMBER_TEMPLATE_SPECIFICATIONS somewhat.
This commit is contained in:
parent
61ba1cf936
commit
5482377ddc
56
gold/gold.h
56
gold/gold.h
@ -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
|
||||
{
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
unsigned char* v
|
||||
ACCEPT_SIZE_ENDIAN) 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);
|
||||
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;
|
||||
|
@ -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_;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user