| 1 | // gold.h -- general definitions for gold -*- C++ -*- |
| 2 | |
| 3 | #ifndef GOLD_GOLD_H |
| 4 | |
| 5 | #include "config.h" |
| 6 | #include "ansidecl.h" |
| 7 | |
| 8 | #ifdef ENABLE_NLS |
| 9 | # include <libintl.h> |
| 10 | # define _(String) gettext (String) |
| 11 | # ifdef gettext_noop |
| 12 | # define N_(String) gettext_noop (String) |
| 13 | # else |
| 14 | # define N_(String) (String) |
| 15 | # endif |
| 16 | #else |
| 17 | # define gettext(Msgid) (Msgid) |
| 18 | # define dgettext(Domainname, Msgid) (Msgid) |
| 19 | # define dcgettext(Domainname, Msgid, Category) (Msgid) |
| 20 | # define textdomain(Domainname) while (0) /* nothing */ |
| 21 | # define bindtextdomain(Domainname, Dirname) while (0) /* nothing */ |
| 22 | # define _(String) (String) |
| 23 | # define N_(String) (String) |
| 24 | #endif |
| 25 | |
| 26 | // Figure out how to get a hash set and a hash map. |
| 27 | |
| 28 | #if defined(HAVE_TR1_UNORDERED_SET) && defined(HAVE_TR1_UNORDERED_MAP) |
| 29 | |
| 30 | #include <tr1/unordered_set> |
| 31 | #include <tr1/unordered_map> |
| 32 | |
| 33 | // We need a template typedef here. |
| 34 | |
| 35 | #define Unordered_set std::tr1::unordered_set |
| 36 | #define Unordered_map std::tr1::unordered_map |
| 37 | |
| 38 | #elif defined(HAVE_EXT_HASH_MAP) && defined(HAVE_EXT_HASH_SET) |
| 39 | |
| 40 | #include <ext/hash_map> |
| 41 | #include <ext/hash_set> |
| 42 | #include <string> |
| 43 | |
| 44 | #define Unordered_set __gnu_cxx::hash_set |
| 45 | #define Unordered_map __gnu_cxx::hash_map |
| 46 | |
| 47 | namespace __gnu_cxx |
| 48 | { |
| 49 | |
| 50 | template<> |
| 51 | struct hash<std::string> |
| 52 | { |
| 53 | size_t |
| 54 | operator()(std::string s) const |
| 55 | { return __stl_hash_string(s.c_str()); } |
| 56 | }; |
| 57 | |
| 58 | template<typename T> |
| 59 | struct hash<T*> |
| 60 | { |
| 61 | size_t |
| 62 | operator()(T* p) const |
| 63 | { return reinterpret_cast<size_t>(p); } |
| 64 | }; |
| 65 | |
| 66 | } |
| 67 | |
| 68 | #else |
| 69 | |
| 70 | // The fallback is to just use set and map. |
| 71 | |
| 72 | #include <set> |
| 73 | #include <map> |
| 74 | |
| 75 | #define Unordered_set std::set |
| 76 | #define Unordered_map std::map |
| 77 | |
| 78 | #endif |
| 79 | |
| 80 | namespace gold |
| 81 | { |
| 82 | // This is a hack to work around a problem with older versions of g++. |
| 83 | // The problem is that they don't support calling a member template by |
| 84 | // specifying the template parameters. It works to pass in an |
| 85 | // argument for argument dependent lookup. |
| 86 | |
| 87 | // To use this, the member template method declaration should put |
| 88 | // ACCEPT_SIZE or ACCEPT_SIZE_ENDIAN after the last parameter. If the |
| 89 | // method takes no parameters, use ACCEPT_SIZE_ONLY or |
| 90 | // ACCEPT_SIZE_ENDIAN_ONLY. |
| 91 | |
| 92 | // When calling the method, instead of using fn<size>, use fn |
| 93 | // SELECT_SIZE_NAME or SELECT_SIZE_ENDIAN_NAME. And after the last |
| 94 | // argument, put SELECT_SIZE(size) or SELECT_SIZE_ENDIAN(size, |
| 95 | // big_endian). If there is only one argment, use the _ONLY variants. |
| 96 | |
| 97 | #ifdef HAVE_MEMBER_TEMPLATE_SPECIFICATIONS |
| 98 | |
| 99 | #define SELECT_SIZE_NAME(size) <size> |
| 100 | #define SELECT_SIZE(size) |
| 101 | #define SELECT_SIZE_ONLY(size) |
| 102 | #define ACCEPT_SIZE |
| 103 | #define ACCEPT_SIZE_ONLY |
| 104 | #define ACCEPT_SIZE_EXPLICIT(size) |
| 105 | |
| 106 | #define SELECT_SIZE_ENDIAN_NAME(size, big_endian) <size, big_endian> |
| 107 | #define SELECT_SIZE_ENDIAN(size, big_endian) |
| 108 | #define SELECT_SIZE_ENDIAN_ONLY(size, big_endian) |
| 109 | #define ACCEPT_SIZE_ENDIAN |
| 110 | #define ACCEPT_SIZE_ENDIAN_ONLY |
| 111 | #define ACCEPT_SIZE_ENDIAN_EXPLICIT(size, big_endian) |
| 112 | |
| 113 | #else // !defined(HAVE_MEMBER_TEMPLATE_SPECIFICATIONS) |
| 114 | |
| 115 | template<int size> |
| 116 | class Select_size { }; |
| 117 | template<int size, bool big_endian> |
| 118 | class Select_size_endian { }; |
| 119 | |
| 120 | #define SELECT_SIZE_NAME(size) |
| 121 | #define SELECT_SIZE(size) , Select_size<size>() |
| 122 | #define SELECT_SIZE_ONLY(size) Select_size<size>() |
| 123 | #define ACCEPT_SIZE , Select_size<size> |
| 124 | #define ACCEPT_SIZE_ONLY Select_size<size> |
| 125 | #define ACCEPT_SIZE_EXPLICIT(size) , Select_size<size> |
| 126 | |
| 127 | #define SELECT_SIZE_ENDIAN_NAME(size, big_endian) |
| 128 | #define SELECT_SIZE_ENDIAN(size, big_endian) \ |
| 129 | , Select_size_endian<size, big_endian>() |
| 130 | #define SELECT_SIZE_ENDIAN_ONLY(size, big_endian) \ |
| 131 | Select_size_endian<size, big_endian>() |
| 132 | #define ACCEPT_SIZE_ENDIAN , Select_size_endian<size, big_endian> |
| 133 | #define ACCEPT_SIZE_ENDIAN_ONLY Select_size_endian<size, big_endian> |
| 134 | #define ACCEPT_SIZE_ENDIAN_EXPLICIT(size, big_endian) \ |
| 135 | , Select_size_endian<size, big_endian> |
| 136 | |
| 137 | #endif // !defined(HAVE_MEMBER_TEMPLATE_SPECIFICATIONS) |
| 138 | |
| 139 | } // End namespace gold. |
| 140 | |
| 141 | namespace gold |
| 142 | { |
| 143 | |
| 144 | class General_options; |
| 145 | class Command_line; |
| 146 | class Input_argument_list; |
| 147 | class Dirsearch; |
| 148 | class Input_objects; |
| 149 | class Symbol_table; |
| 150 | class Layout; |
| 151 | class Workqueue; |
| 152 | class Output_file; |
| 153 | |
| 154 | // The name of the program as used in error messages. |
| 155 | extern const char* program_name; |
| 156 | |
| 157 | // This function is called to exit the program. Status is true to |
| 158 | // exit success (0) and false to exit failure (1). |
| 159 | extern void |
| 160 | gold_exit(bool status) ATTRIBUTE_NORETURN; |
| 161 | |
| 162 | // This function is called to emit an unexpected error message and a |
| 163 | // newline, and then exit with failure. If PERRNO is true, it reports |
| 164 | // the error in errno. |
| 165 | extern void |
| 166 | gold_fatal(const char* msg, bool perrno) ATTRIBUTE_NORETURN; |
| 167 | |
| 168 | // This is function is called in some cases if we run out of memory. |
| 169 | extern void |
| 170 | gold_nomem() ATTRIBUTE_NORETURN; |
| 171 | |
| 172 | // This macro and function are used in cases which can not arise if |
| 173 | // the code is written correctly. |
| 174 | |
| 175 | #define gold_unreachable() \ |
| 176 | (gold::do_gold_unreachable(__FILE__, __LINE__, __FUNCTION__)) |
| 177 | |
| 178 | extern void do_gold_unreachable(const char*, int, const char*) |
| 179 | ATTRIBUTE_NORETURN; |
| 180 | |
| 181 | // Assertion check. |
| 182 | |
| 183 | #define gold_assert(expr) ((void)(!(expr) ? gold_unreachable(), 0 : 0)) |
| 184 | |
| 185 | // Queue up the first set of tasks. |
| 186 | extern void |
| 187 | queue_initial_tasks(const General_options&, |
| 188 | const Dirsearch&, |
| 189 | const Command_line&, |
| 190 | Workqueue*, |
| 191 | Input_objects*, |
| 192 | Symbol_table*, |
| 193 | Layout*); |
| 194 | |
| 195 | // Queue up the middle set of tasks. |
| 196 | extern void |
| 197 | queue_middle_tasks(const General_options&, |
| 198 | const Input_objects*, |
| 199 | Symbol_table*, |
| 200 | Layout*, |
| 201 | Workqueue*); |
| 202 | |
| 203 | // Queue up the final set of tasks. |
| 204 | extern void |
| 205 | queue_final_tasks(const General_options&, |
| 206 | const Input_objects*, |
| 207 | const Symbol_table*, |
| 208 | const Layout*, |
| 209 | Workqueue*, |
| 210 | Output_file* of); |
| 211 | |
| 212 | } // End namespace gold. |
| 213 | |
| 214 | #endif // !defined(GOLD_GOLD_H) |