cprover
Toggle main menu visibility
Loading...
Searching...
No Matches
gcc_cmdline.cpp
Go to the documentation of this file.
1
/*******************************************************************\
2
3
Module: A special command line object for the gcc-like options
4
5
Author: CM Wintersteiger, 2006
6
7
\*******************************************************************/
8
11
12
#include "
gcc_cmdline.h
"
13
14
#include <
util/invariant.h
>
15
#include <
util/prefix.h
>
16
17
#include <cstring>
18
#include <fstream>
// IWYU pragma: keep
19
#include <iostream>
20
#include <sstream>
// IWYU pragma: keep
21
22
// clang-format off
23
// non-gcc options
24
const
char
*
goto_cc_options_with_separated_argument
[]=
25
{
26
"--verbosity"
,
27
"--function"
,
28
"--native-compiler"
,
29
"--native-linker"
,
30
"--print-rejected-preprocessed-source"
,
31
"--mangle-suffix"
,
32
nullptr
33
};
34
35
// non-gcc options
36
const
char
*
goto_cc_options_without_argument
[]=
37
{
38
"--show-symbol-table"
,
39
"--show-function-table"
,
40
"--ppc-macos"
,
41
"--i386-linux"
,
42
"--i386-win32"
,
43
"--i386-macos"
,
44
"--winx64"
,
45
"--string-abstraction"
,
46
"--no-library"
,
47
"--16"
,
48
"--32"
,
49
"--64"
,
50
"--little-endian"
,
51
"--big-endian"
,
52
"--partial-inlining"
,
53
"--validate-goto-model"
,
54
"-?"
,
55
"--export-file-local-symbols"
,
56
// This is deprecated. Currently prints out a deprecation warning.
57
"--export-function-local-symbols"
,
58
nullptr
59
};
60
61
// separated or concatenated
62
const
char
*
gcc_options_with_argument
[]=
63
{
64
"-o"
,
65
"-x"
,
66
"-B"
,
67
"-iquote"
,
68
"-idirafter"
,
69
"-include"
,
70
"-I"
,
71
"-V"
,
72
"-D"
,
73
"-L"
,
74
"-l"
,
75
"-MT"
,
76
"-MQ"
,
77
"-MF"
,
78
"-U"
,
79
"-u"
,
// goes to linker
80
"-T"
,
// goes to linker
81
nullptr
82
};
83
84
const
char
*
gcc_options_with_separated_argument
[]=
85
{
86
"-aux-info"
,
87
"-arch"
,
// Apple only
88
"--param"
,
// Apple only
89
"-imacros"
,
90
"-iprefix"
,
91
"-iwithprefix"
,
92
"-iwithprefixbefore"
,
93
"-isystem"
,
94
"-isysroot"
,
95
"-imultilib"
,
96
"-imultiarch"
,
97
"-mcpu"
,
98
"-mtune"
,
99
"-march"
,
100
"-Xpreprocessor"
,
101
"-Xassembler"
,
102
"-Xlinker"
,
103
"-b"
,
104
"-std"
,
105
"--std"
,
106
"-print-file-name"
,
107
"-print-prog-name"
,
108
"-specs"
,
109
"--sysroot"
,
110
"--include"
,
// undocumented
111
"-current_version"
,
// on the Mac
112
"-compatibility_version"
,
// on the Mac
113
"-target"
,
114
"--target"
,
115
"-z"
,
116
nullptr
117
};
118
119
const
char
*
gcc_options_with_concatenated_argument
[]=
120
{
121
"-d"
,
122
"-g"
,
123
"-A"
,
124
nullptr
125
};
126
127
const
char
*
gcc_options_without_argument
[]=
128
{
129
"--help"
,
130
"-h"
,
131
"-r"
,
// for ld mimicking
132
"-dylib"
,
// for ld mimicking on MacOS
133
"-c"
,
134
"-S"
,
135
"-E"
,
136
"-combine"
,
137
"-pipe"
,
138
"-pass-exit-codes"
,
139
"-v"
,
140
"-###"
,
141
"-help"
,
142
"-target-help"
,
143
"--version"
,
144
"-ansi"
,
145
"-trigraphs"
,
146
"-no-integrated-cpp"
,
147
"-traditional"
,
148
"-traditional-cpp"
,
149
"-nostdinc++"
,
150
"-gen-decls"
,
151
"-pedantic"
,
152
"-pedantic-errors"
,
153
"-w"
,
154
"-dumpspecs"
,
155
"-dumpmachine"
,
156
"-dumpversion"
,
157
"-g"
,
158
"-gcoff"
,
159
"-gdwarf-2"
,
160
"-ggdb"
,
161
"-gstabs"
,
162
"-gstabs+"
,
163
"-gvms"
,
164
"-gxcoff"
,
165
"-gxcoff+"
,
166
"-p"
,
167
"-pg"
,
168
"-print-libgcc-file-name"
,
169
"-print-multi-directory"
,
170
"-print-multi-lib"
,
171
"-print-search-dirs"
,
172
"-print-sysroot"
,
173
"-print-sysroot-headers-suffix"
,
174
"-Q"
,
175
"-Qn"
,
176
"-Qy"
,
177
"-pthread"
,
178
"-save-temps"
,
179
"-time"
,
180
"-O"
,
181
"-O0"
,
182
"-O1"
,
183
"-O2"
,
184
"-O3"
,
185
"-O6"
,
186
"-Os"
,
187
"-Oz"
,
// Apple only
188
"-C"
,
189
"-E"
,
190
"-H"
,
191
"-M"
,
192
"-MM"
,
193
"-MG"
,
194
"-MP"
,
195
"-MD"
,
196
"-MMD"
,
197
"-mno-unaligned-access"
,
198
"-mthumb"
,
199
"-mthumb-interwork"
,
200
"-nostdinc"
,
201
"-P"
,
202
"-remap"
,
203
"-undef"
,
204
"-nostdinc"
,
205
"-nostartfiles"
,
206
"-nodefaultlibs"
,
207
"-nostdlib"
,
208
"-pie"
,
209
"-rdynamic"
,
210
"-s"
,
211
"-static"
,
212
"-static-libgcc"
,
213
"--static"
,
214
"-shared"
,
215
"--shared"
,
216
"-shared-libgcc"
,
217
"-symbolic"
,
218
"-EB"
,
219
"-EL"
,
220
"-fast"
,
// Apple only
221
"-coverage"
,
222
nullptr
223
};
224
// clang-format on
225
229
bool
gcc_cmdlinet::parse
(
int
argc,
const
char
**argv)
230
{
231
PRECONDITION
(argc > 0);
232
add_arg
(argv[0]);
233
234
argst
current_args;
235
current_args.reserve(argc - 1);
236
237
for
(
int
i=1; i<argc; i++)
238
current_args.push_back(argv[i]);
239
240
bool
result =
parse_arguments
(current_args,
false
);
241
242
parse_specs
();
243
244
return
result;
245
}
246
247
bool
gcc_cmdlinet::parse_arguments
(
248
const
argst
&args_to_parse,
249
bool
in_spec_file)
250
{
251
for
(argst::const_iterator it = args_to_parse.begin();
252
it != args_to_parse.end();
253
++it)
254
{
255
const
std::string &argv_i=*it;
256
257
// options file?
258
if
(
has_prefix
(argv_i,
"@"
))
259
{
260
std::ifstream opts_file(argv_i.substr(1));
261
std::ostringstream all_lines;
262
std::string line;
263
264
while
(std::getline(opts_file, line))
265
all_lines <<
' '
<< line;
266
267
line = all_lines.str();
268
// erase leading whitespace
269
line.erase(0, line.find_first_not_of(
"\t "
));
270
271
if
(!line.empty())
272
parse_specs_line
(line,
false
);
273
274
continue
;
275
}
276
277
// file?
278
if
(argv_i==
"-"
|| !
has_prefix
(argv_i,
"-"
))
279
{
280
if
(!in_spec_file)
281
add_infile_arg
(argv_i);
282
continue
;
283
}
284
285
if
(!in_spec_file)
286
{
287
argst::const_iterator next=it;
288
++next;
289
290
bool
found=
false
;
291
292
if
(
in_list
(argv_i.c_str(),
293
goto_cc_options_without_argument
))
// without argument
294
{
295
set
(argv_i);
296
found=
true
;
297
}
298
299
// separated only, and also allow concatenation with "="
300
for
(
const
char
**o=
goto_cc_options_with_separated_argument
;
301
*o!=
nullptr
&& !found;
302
++o)
303
{
304
if
(argv_i==*o)
// separated
305
{
306
found=
true
;
307
if
(next != args_to_parse.end())
308
{
309
set
(argv_i, *next);
310
++it;
311
}
312
else
313
set
(argv_i,
""
);
314
}
315
// concatenated with "="
316
else
if
(
has_prefix
(argv_i, std::string(*o)+
"="
))
317
{
318
found=
true
;
319
set
(*o, argv_i.substr(strlen(*o)+1));
320
}
321
}
322
323
if
(found)
324
continue
;
325
326
// add to new_argv
327
add_arg
(argv_i);
328
}
329
330
// also store in cmdlinet
331
332
if
(
has_prefix
(argv_i,
"-f"
))
// f-options
333
{
334
set
(argv_i);
335
}
336
else
if
(
has_prefix
(argv_i,
"-W"
))
// W-options
337
{
338
// "Wp,..." is s special case. These are to pass stuff
339
// to the preprocessor.
340
if
(
has_prefix
(argv_i,
"-Wp,"
))
341
{
342
std::string value=argv_i.substr(4);
343
set
(
"-WP,"
, value);
344
}
345
else
346
set
(argv_i);
347
}
348
else
if
(
has_prefix
(argv_i,
"-m"
))
// m-options
349
{
350
// these sometimes come with a value separated by '=', e.g.,
351
// -march=cpu_type
352
std::size_t equal_pos=argv_i.find(
'='
);
353
354
if
(equal_pos==std::string::npos)
355
set
(argv_i);
// no value
356
else
357
set
(argv_i.substr(0, equal_pos), argv_i.substr(equal_pos+1));
358
}
359
// without argument
360
else
if
(
in_list
(argv_i.c_str(),
gcc_options_without_argument
))
361
{
362
set
(argv_i);
363
}
364
else
365
{
366
argst::const_iterator next=it;
367
++next;
368
369
bool
found=
false
;
370
371
// separated only, and also allow concatenation with "="
372
for
(
const
char
**o=
gcc_options_with_separated_argument
;
373
*o!=
nullptr
&& !found;
374
++o)
375
{
376
if
(argv_i==*o)
// separated
377
{
378
found=
true
;
379
if
(next != args_to_parse.end())
380
{
381
set
(argv_i, *next);
382
if
(!in_spec_file)
383
add_arg
(*next);
384
++it;
385
}
386
else
387
set
(argv_i,
""
);
388
}
389
// concatenated with "="
390
else
if
(
has_prefix
(argv_i, std::string(*o)+
"="
))
391
{
392
found=
true
;
393
set
(*o, argv_i.substr(strlen(*o)+1));
394
}
395
}
396
397
// concatenated _or_ separated, e.g., -I
398
for
(
const
char
**o=
gcc_options_with_argument
;
399
*o!=
nullptr
&& !found;
400
++o)
401
{
402
if
(argv_i==*o)
// separated
403
{
404
found=
true
;
405
if
(next != args_to_parse.end())
406
{
407
set
(argv_i, *next);
408
if
(!in_spec_file)
409
add_arg
(*next);
410
++it;
411
}
412
else
413
set
(argv_i,
""
);
414
}
415
else
if
(
has_prefix
(argv_i, *o))
// concatenated
416
{
417
found=
true
;
418
set
(*o, argv_i.substr(strlen(*o)));
419
}
420
}
421
422
// concatenated only
423
for
(
const
char
**o=
gcc_options_with_concatenated_argument
;
424
*o!=
nullptr
&& !found;
425
++o)
426
{
427
if
(
has_prefix
(argv_i, *o))
// concatenated
428
{
429
found=
true
;
430
set
(*o, argv_i.substr(strlen(*o)));
431
}
432
}
433
434
if
(!found)
435
{
436
// unrecognized option
437
std::cerr <<
"Warning: uninterpreted gcc option '"
<< argv_i
438
<<
"'\n"
;
439
}
440
}
441
}
442
443
return
false
;
444
}
445
447
void
gcc_cmdlinet::parse_specs_line
(
const
std::string &line,
bool
in_spec_file)
448
{
449
// initial whitespace has been stripped
450
PRECONDITION
(!line.empty());
451
PRECONDITION
(line[0] !=
' '
&& line[0] !=
'\t'
);
452
453
argst
args_from_specs;
454
455
for
(std::string::size_type arg_start=0, arg_end=0;
456
arg_end!=std::string::npos;
457
arg_start=line.find_first_not_of(
"\t "
, arg_end))
458
{
459
arg_end=line.find_first_of(
"\t "
, arg_start);
460
args_from_specs.push_back(line.substr(arg_start, arg_end - arg_start));
461
}
462
463
parse_arguments
(args_from_specs, in_spec_file);
464
}
465
467
void
gcc_cmdlinet::parse_specs
()
468
{
469
const
std::string &specs_file_name=
get_value
(
"specs"
);
470
if
(specs_file_name.empty())
471
return
;
472
473
std::ifstream specs_file(specs_file_name);
474
std::string line;
475
bool
use_line=
false
;
476
477
while
(std::getline(specs_file, line))
478
{
479
// erase leading whitespace
480
line.erase(0, line.find_first_not_of(
"\t "
));
481
482
if
(line.empty())
483
// blank lines reset the mode
484
use_line=
false
;
485
else
if
(!use_line &&
486
(line==
"*link_libgcc:"
||
487
line==
"*lib:"
||
488
line==
"*libgcc:"
||
489
line==
"*link:"
))
490
use_line=
true
;
491
else
if
(use_line)
492
parse_specs_line
(line,
true
);
493
else
494
{
495
// TODO need message interface
496
// debug() << "Warning: ignoring spec " << line << eom;
497
}
498
}
499
}
cmdlinet::get_value
std::string get_value(char option) const
Definition
cmdline.cpp:48
gcc_cmdlinet::parse_arguments
bool parse_arguments(const argst &args_to_parse, bool in_spec_file)
Definition
gcc_cmdline.cpp:247
gcc_cmdlinet::parse_specs
void parse_specs()
Parse GCC spec files https://gcc.gnu.org/onlinedocs/gcc/Spec-Files.html.
Definition
gcc_cmdline.cpp:467
gcc_cmdlinet::argst
std::vector< std::string > argst
Definition
gcc_cmdline.h:30
gcc_cmdlinet::parse
virtual bool parse(int, const char **)
parses the command line options into a cmdlinet
Definition
gcc_cmdline.cpp:229
gcc_cmdlinet::parse_specs_line
void parse_specs_line(const std::string &line, bool in_spec_file)
Parse GCC spec files https://gcc.gnu.org/onlinedocs/gcc/Spec-Files.html.
Definition
gcc_cmdline.cpp:447
goto_cc_cmdlinet::set
void set(const std::string &opt, const char *value) override
Set option option to value.
Definition
goto_cc_cmdline.h:33
goto_cc_cmdlinet::add_infile_arg
void add_infile_arg(const std::string &arg)
Definition
goto_cc_cmdline.cpp:102
goto_cc_cmdlinet::in_list
static bool in_list(const char *option, const char **list)
Definition
goto_cc_cmdline.cpp:38
goto_cc_cmdlinet::add_arg
void add_arg(const std::string &arg)
Definition
goto_cc_cmdline.h:71
has_prefix
bool has_prefix(const std::string &s, const std::string &prefix)
Definition
converter.cpp:13
gcc_options_with_concatenated_argument
const char * gcc_options_with_concatenated_argument[]
Definition
gcc_cmdline.cpp:119
gcc_options_with_separated_argument
const char * gcc_options_with_separated_argument[]
Definition
gcc_cmdline.cpp:84
goto_cc_options_with_separated_argument
const char * goto_cc_options_with_separated_argument[]
Definition
gcc_cmdline.cpp:24
gcc_options_without_argument
const char * gcc_options_without_argument[]
Definition
gcc_cmdline.cpp:127
goto_cc_options_without_argument
const char * goto_cc_options_without_argument[]
Definition
gcc_cmdline.cpp:36
gcc_options_with_argument
const char * gcc_options_with_argument[]
Definition
gcc_cmdline.cpp:62
gcc_cmdline.h
A special command line object for the gcc-like options.
prefix.h
invariant.h
PRECONDITION
#define PRECONDITION(CONDITION)
Definition
invariant.h:463
goto-cc
gcc_cmdline.cpp
Generated by
1.17.0