From Craig Silverstein: Add -O option.
[external/binutils.git] / gold / options.h
1 // options.h -- handle command line options for gold  -*- C++ -*-
2
3 // Command_line
4 //   Holds everything we get from the command line.
5 // General_options (from Command_line::options())
6 //   Options which are not position dependent.
7 // Input_argument (from Command_line::inputs())
8 //   The list of input files, including -l options.
9 // Position_dependent_options (from Input_argument::options())
10 //   Position dependent options which apply to this argument.
11
12 #ifndef GOLD_OPTIONS_H
13 #define GOLD_OPTIONS_H
14
15 #include <cstdlib>
16 #include <list>
17 #include <string>
18 #include <vector>
19
20 namespace gold
21 {
22
23 class Command_line;
24 class Input_file_group;
25
26 namespace options {
27
28 class Command_line_options;
29 struct One_option;
30
31 } // End namespace gold::options.
32
33 // The position independent options which apply to the whole link.
34 // There are a lot of them.
35
36 class General_options
37 {
38  public:
39   General_options();
40
41   // -E: export dynamic symbols.
42   bool
43   export_dynamic() const
44   { return this->export_dynamic_; }
45
46   // -I: dynamic linker name.
47   const char*
48   dynamic_linker() const
49   { return this->dynamic_linker_; }
50
51   // -L: Library search path.
52   typedef std::vector<const char*> Dir_list;
53
54   const Dir_list&
55   search_path() const
56   { return this->search_path_; }
57
58   // -O: optimization level (0: don't try to optimize output size).
59   int
60   optimization_level() const
61   { return this->optimization_level_; }
62
63   // -o: Output file name.
64   const char*
65   output_file_name() const
66   { return this->output_file_name_; }
67
68   // -r: Whether we are doing a relocatable link.
69   bool
70   is_relocatable() const
71   { return this->is_relocatable_; }
72
73   // --eh-frame-hdr: Whether to generate an exception frame header.
74   bool
75   create_eh_frame_hdr() const
76   { return this->create_eh_frame_hdr_; }
77
78   // --rpath: The runtime search path.
79   const Dir_list&
80   rpath() const
81   { return this->rpath_; }
82
83   // --rpath-link: The link time search patch for shared libraries.
84   const Dir_list&
85   rpath_link() const
86   { return this->rpath_link_; }
87
88   // --shared: Whether generating a shared object.
89   bool
90   is_shared() const
91   { return this->is_shared_; }
92
93   // --static: Whether doing a static link.
94   bool
95   is_static() const
96   { return this->is_static_; }
97
98  private:
99   // Don't copy this structure.
100   General_options(const General_options&);
101   General_options& operator=(const General_options&);
102
103   friend class Command_line;
104   friend class options::Command_line_options;
105
106   void
107   set_export_dynamic()
108   { this->export_dynamic_ = true; }
109
110   void
111   set_dynamic_linker(const char* arg)
112   { this->dynamic_linker_ = arg; }
113
114   void
115   add_to_search_path(const char* arg)
116   { this->search_path_.push_back(arg); }
117
118   void
119   set_optimization_level(const char* arg)
120   { this->optimization_level_ = atoi(arg); }
121
122   void
123   set_output_file_name(const char* arg)
124   { this->output_file_name_ = arg; }
125
126   void
127   set_relocatable()
128   { this->is_relocatable_ = true; }
129
130   void
131   set_create_eh_frame_hdr()
132   { this->create_eh_frame_hdr_ = true; }
133
134   void
135   add_to_rpath(const char* arg)
136   { this->rpath_.push_back(arg); }
137
138   void
139   add_to_rpath_link(const char* arg)
140   { this->rpath_link_.push_back(arg); }
141
142   void
143   set_shared()
144   { this->is_shared_ = true; }
145
146   void
147   set_static()
148   { this->is_static_ = true; }
149
150   void
151   ignore(const char*)
152   { }
153
154   bool export_dynamic_;
155   const char* dynamic_linker_;
156   Dir_list search_path_;
157   int optimization_level_;
158   const char* output_file_name_;
159   bool is_relocatable_;
160   bool create_eh_frame_hdr_;
161   Dir_list rpath_;
162   Dir_list rpath_link_;
163   bool is_shared_;
164   bool is_static_;
165 };
166
167 // The current state of the position dependent options.
168
169 class Position_dependent_options
170 {
171  public:
172   Position_dependent_options();
173
174   // -Bstatic: Whether we are searching for a static archive rather
175   // than a shared object.
176   bool
177   do_static_search() const
178   { return this->do_static_search_; }
179
180   // --as-needed: Whether to add a DT_NEEDED argument only if the
181   // dynamic object is used.
182   bool
183   as_needed() const
184   { return this->as_needed_; }
185
186   // --whole-archive: Whether to include the entire contents of an
187   // --archive.
188   bool
189   include_whole_archive() const
190   { return this->include_whole_archive_; }
191
192   void
193   set_static_search()
194   { this->do_static_search_ = true; }
195
196   void
197   set_dynamic_search()
198   { this->do_static_search_ = false; }
199
200   void
201   set_as_needed()
202   { this->as_needed_ = true; }
203
204   void
205   clear_as_needed()
206   { this->as_needed_ = false; }
207
208   void
209   set_whole_archive()
210   { this->include_whole_archive_ = true; }
211
212   void
213   clear_whole_archive()
214   { this->include_whole_archive_ = false; }
215
216  private:
217   bool do_static_search_;
218   bool as_needed_;
219   bool include_whole_archive_;
220 };
221
222 // A single file or library argument from the command line.
223
224 class Input_file_argument
225 {
226  public:
227   Input_file_argument()
228     : name_(), is_lib_(false), options_()
229   { }
230
231   Input_file_argument(const char* name, bool is_lib,
232                       const Position_dependent_options& options)
233     : name_(name), is_lib_(is_lib), options_(options)
234   { }
235
236   const char*
237   name() const
238   { return this->name_.c_str(); }
239
240   const Position_dependent_options&
241   options() const
242   { return this->options_; }
243
244   bool
245   is_lib() const
246   { return this->is_lib_; }
247
248  private:
249   // We use std::string, not const char*, here for convenience when
250   // using script files, so that we do not have to preserve the string
251   // in that case.
252   std::string name_;
253   bool is_lib_;
254   Position_dependent_options options_;
255 };
256
257 // A file or library, or a group, from the command line.
258
259 class Input_argument
260 {
261  public:
262   // Create a file or library argument.
263   explicit Input_argument(Input_file_argument file)
264     : is_file_(true), file_(file), group_(NULL)
265   { }
266
267   // Create a group argument.
268   explicit Input_argument(Input_file_group* group)
269     : is_file_(false), group_(group)
270   { }
271
272   // Return whether this is a file.
273   bool
274   is_file() const
275   { return this->is_file_; }
276
277   // Return whether this is a group.
278   bool
279   is_group() const
280   { return !this->is_file_; }
281
282   // Return the information about the file.
283   const Input_file_argument&
284   file() const
285   {
286     gold_assert(this->is_file_);
287     return this->file_;
288   }
289
290   // Return the information about the group.
291   const Input_file_group*
292   group() const
293   {
294     gold_assert(!this->is_file_);
295     return this->group_;
296   }
297
298   Input_file_group*
299   group()
300   {
301     gold_assert(!this->is_file_);
302     return this->group_;
303   }
304
305  private:
306   bool is_file_;
307   Input_file_argument file_;
308   Input_file_group* group_;
309 };
310
311 // A group from the command line.  This is a set of arguments within
312 // --start-group ... --end-group.
313
314 class Input_file_group
315 {
316  public:
317   typedef std::vector<Input_argument> Files;
318   typedef Files::const_iterator const_iterator;
319
320   Input_file_group()
321     : files_()
322   { }
323
324   // Add a file to the end of the group.
325   void
326   add_file(const Input_file_argument& arg)
327   { this->files_.push_back(Input_argument(arg)); }
328
329   // Iterators to iterate over the group contents.
330
331   const_iterator
332   begin() const
333   { return this->files_.begin(); }
334
335   const_iterator
336   end() const
337   { return this->files_.end(); }
338
339  private:
340   Files files_;
341 };
342
343 // A list of files from the command line or a script.
344
345 class Input_arguments
346 {
347  public:
348   typedef std::vector<Input_argument> Input_argument_list;
349   typedef Input_argument_list::const_iterator const_iterator;
350
351   Input_arguments()
352     : input_argument_list_(), in_group_(false)
353   { }
354
355   // Add a file.
356   void
357   add_file(const Input_file_argument& arg);
358
359   // Start a group (the --start-group option).
360   void
361   start_group();
362
363   // End a group (the --end-group option).
364   void
365   end_group();
366
367   // Return whether we are currently in a group.
368   bool
369   in_group() const
370   { return this->in_group_; }
371
372   // Iterators to iterate over the list of input files.
373
374   const_iterator
375   begin() const
376   { return this->input_argument_list_.begin(); }
377
378   const_iterator
379   end() const
380   { return this->input_argument_list_.end(); }
381
382   // Return whether the list is empty.
383   bool
384   empty() const
385   { return this->input_argument_list_.empty(); }
386
387  private:
388   Input_argument_list input_argument_list_;
389   bool in_group_;
390 };
391
392 // All the information read from the command line.
393
394 class Command_line
395 {
396  public:
397   typedef Input_arguments::const_iterator const_iterator;
398
399   Command_line();
400
401   // Process the command line options.  This will exit with an
402   // appropriate error message if an unrecognized option is seen.
403   void
404   process(int argc, char** argv);
405
406   // Handle a -l option.
407   int
408   process_l_option(int, char**, char*);
409
410   // Handle a --start-group option.
411   void
412   start_group(const char* arg);
413
414   // Handle a --end-group option.
415   void
416   end_group(const char* arg);
417
418   // Get the general options.
419   const General_options&
420   options() const
421   { return this->options_; }
422
423   // Iterators to iterate over the list of input files.
424
425   const_iterator
426   begin() const
427   { return this->inputs_.begin(); }
428
429   const_iterator
430   end() const
431   { return this->inputs_.end(); }
432
433  private:
434   Command_line(const Command_line&);
435   Command_line& operator=(const Command_line&);
436
437   // Report usage error.
438   void
439   usage() ATTRIBUTE_NORETURN;
440   void
441   usage(const char* msg, const char* opt) ATTRIBUTE_NORETURN;
442   void
443   usage(const char* msg, char opt) ATTRIBUTE_NORETURN;
444
445   // Apply a command line option.
446   void
447   apply_option(const gold::options::One_option&, const char*);
448
449   // Add a file.
450   void
451   add_file(const char* name, bool is_lib);
452
453   General_options options_;
454   Position_dependent_options position_options_;
455   Input_arguments inputs_;
456 };
457
458 } // End namespace gold.
459
460 #endif // !defined(GOLD_OPTIONS_H)