]>
Commit | Line | Data |
---|---|---|
aaf93206 | 1 | /* Preprocess only, using cpplib. |
0ea5865c | 2 | Copyright (C) 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 |
d6d52dd6 | 3 | Free Software Foundation, Inc. |
7f2935c7 PB |
4 | Written by Per Bothner, 1994-95. |
5 | ||
6 | This program is free software; you can redistribute it and/or modify it | |
7 | under the terms of the GNU General Public License as published by the | |
8 | Free Software Foundation; either version 2, or (at your option) any | |
9 | later version. | |
10 | ||
11 | This program is distributed in the hope that it will be useful, | |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | GNU General Public License for more details. | |
15 | ||
16 | You should have received a copy of the GNU General Public License | |
17 | along with this program; if not, write to the Free Software | |
366ccddb | 18 | Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ |
7f2935c7 | 19 | |
84ee6fd4 | 20 | #include "config.h" |
b04cd507 | 21 | #include "system.h" |
4977bab6 ZW |
22 | #include "coretypes.h" |
23 | #include "tm.h" | |
b04cd507 | 24 | #include "cpplib.h" |
4f4e53dd | 25 | #include "../libcpp/internal.h" |
63973df3 | 26 | #include "tree.h" |
9d10c9a9 NB |
27 | #include "c-common.h" /* For flags. */ |
28 | #include "c-pragma.h" /* For parse_in. */ | |
63973df3 NB |
29 | |
30 | /* Encapsulates state used to convert a stream of tokens into a text | |
31 | file. */ | |
32 | static struct | |
33 | { | |
34 | FILE *outf; /* Stream to write to. */ | |
63973df3 NB |
35 | const cpp_token *prev; /* Previous token. */ |
36 | const cpp_token *source; /* Source token for spacing. */ | |
12f9df4e | 37 | int src_line; /* Line number currently being written. */ |
63973df3 | 38 | unsigned char printed; /* Nonzero if something output at line. */ |
a1105617 | 39 | bool first_time; /* pp_file_change hasn't been called yet. */ |
63973df3 | 40 | } print; |
7f2935c7 | 41 | |
93c80368 | 42 | /* General output routines. */ |
2f6e4e97 AJ |
43 | static void scan_translation_unit (cpp_reader *); |
44 | static void scan_translation_unit_trad (cpp_reader *); | |
43839642 | 45 | static void account_for_newlines (const unsigned char *, size_t); |
2f6e4e97 | 46 | static int dump_macro (cpp_reader *, cpp_hashnode *, void *); |
93c80368 | 47 | |
12f9df4e PB |
48 | static void print_line (source_location, const char *); |
49 | static void maybe_print_line (source_location); | |
93c80368 | 50 | |
58fea6af ZW |
51 | /* Callback routines for the parser. Most of these are active only |
52 | in specific modes. */ | |
2f6e4e97 | 53 | static void cb_line_change (cpp_reader *, const cpp_token *, int); |
a281759f PB |
54 | static void cb_define (cpp_reader *, source_location, cpp_hashnode *); |
55 | static void cb_undef (cpp_reader *, source_location, cpp_hashnode *); | |
56 | static void cb_include (cpp_reader *, source_location, const unsigned char *, | |
cbc43ae0 | 57 | const char *, int, const cpp_token **); |
a281759f PB |
58 | static void cb_ident (cpp_reader *, source_location, const cpp_string *); |
59 | static void cb_def_pragma (cpp_reader *, source_location); | |
c0d578e6 GK |
60 | static void cb_read_pch (cpp_reader *pfile, const char *name, |
61 | int fd, const char *orig_name); | |
93c80368 | 62 | |
aaf93206 NB |
63 | /* Preprocess and output. */ |
64 | void | |
2f6e4e97 | 65 | preprocess_file (cpp_reader *pfile) |
7f2935c7 | 66 | { |
9d10c9a9 NB |
67 | /* A successful cpp_read_main_file guarantees that we can call |
68 | cpp_scan_nooutput or cpp_get_token next. */ | |
69 | if (flag_no_output) | |
6de8f7fc | 70 | { |
9d10c9a9 NB |
71 | /* Scan -included buffers, then the main file. */ |
72 | while (pfile->buffer->prev) | |
73 | cpp_scan_nooutput (pfile); | |
74 | cpp_scan_nooutput (pfile); | |
6de8f7fc | 75 | } |
9d10c9a9 NB |
76 | else if (cpp_get_options (pfile)->traditional) |
77 | scan_translation_unit_trad (pfile); | |
78 | else | |
79 | scan_translation_unit (pfile); | |
80 | ||
81 | /* -dM command line option. Should this be elsewhere? */ | |
82 | if (flag_dump_macros == 'M') | |
83 | cpp_forall_identifiers (pfile, dump_macro, NULL); | |
6de8f7fc NB |
84 | |
85 | /* Flush any pending output. */ | |
63973df3 NB |
86 | if (print.printed) |
87 | putc ('\n', print.outf); | |
6de8f7fc NB |
88 | } |
89 | ||
620ef26c | 90 | /* Set up the callbacks as appropriate. */ |
9d10c9a9 | 91 | void |
2f6e4e97 | 92 | init_pp_output (FILE *out_stream) |
cf44ea52 | 93 | { |
9d10c9a9 NB |
94 | cpp_callbacks *cb = cpp_get_callbacks (parse_in); |
95 | ||
63973df3 | 96 | if (!flag_no_output) |
cf44ea52 | 97 | { |
f0581dc7 | 98 | cb->line_change = cb_line_change; |
c7544dd8 ZW |
99 | /* Don't emit #pragma or #ident directives if we are processing |
100 | assembly language; the assembler may choke on them. */ | |
9d10c9a9 | 101 | if (cpp_get_options (parse_in)->lang != CLK_ASM) |
c7544dd8 ZW |
102 | { |
103 | cb->ident = cb_ident; | |
104 | cb->def_pragma = cb_def_pragma; | |
105 | } | |
cf44ea52 NB |
106 | } |
107 | ||
63973df3 | 108 | if (flag_dump_includes) |
620ef26c | 109 | cb->include = cb_include; |
cf44ea52 | 110 | |
c0d578e6 GK |
111 | if (flag_pch_preprocess) |
112 | { | |
113 | cb->valid_pch = c_common_valid_pch; | |
114 | cb->read_pch = cb_read_pch; | |
115 | } | |
116 | ||
63973df3 | 117 | if (flag_dump_macros == 'N' || flag_dump_macros == 'D') |
cf44ea52 | 118 | { |
620ef26c NB |
119 | cb->define = cb_define; |
120 | cb->undef = cb_undef; | |
cf44ea52 | 121 | } |
9d10c9a9 | 122 | |
12f9df4e | 123 | /* Initialize the print structure. Setting print.src_line to -1 here is |
9d10c9a9 NB |
124 | a trick to guarantee that the first token of the file will cause |
125 | a linemarker to be output by maybe_print_line. */ | |
12f9df4e | 126 | print.src_line = -1; |
9d10c9a9 NB |
127 | print.printed = 0; |
128 | print.prev = 0; | |
9d10c9a9 | 129 | print.outf = out_stream; |
22234f56 | 130 | print.first_time = 1; |
cf44ea52 NB |
131 | } |
132 | ||
644eddaa NB |
133 | /* Writes out the preprocessed file, handling spacing and paste |
134 | avoidance issues. */ | |
93c80368 | 135 | static void |
2f6e4e97 | 136 | scan_translation_unit (cpp_reader *pfile) |
93c80368 | 137 | { |
4ed5bcfb | 138 | bool avoid_paste = false; |
58fea6af | 139 | |
63973df3 | 140 | print.source = NULL; |
4ed5bcfb | 141 | for (;;) |
93c80368 | 142 | { |
4ed5bcfb NB |
143 | const cpp_token *token = cpp_get_token (pfile); |
144 | ||
145 | if (token->type == CPP_PADDING) | |
146 | { | |
147 | avoid_paste = true; | |
63973df3 NB |
148 | if (print.source == NULL |
149 | || (!(print.source->flags & PREV_WHITE) | |
0c34509f | 150 | && token->val.source == NULL)) |
63973df3 | 151 | print.source = token->val.source; |
4ed5bcfb NB |
152 | continue; |
153 | } | |
93c80368 | 154 | |
ef6e958a NB |
155 | if (token->type == CPP_EOF) |
156 | break; | |
93c80368 | 157 | |
4ed5bcfb NB |
158 | /* Subtle logic to output a space if and only if necessary. */ |
159 | if (avoid_paste) | |
160 | { | |
63973df3 NB |
161 | if (print.source == NULL) |
162 | print.source = token; | |
163 | if (print.source->flags & PREV_WHITE | |
164 | || (print.prev | |
165 | && cpp_avoid_paste (pfile, print.prev, token)) | |
166 | || (print.prev == NULL && token->type == CPP_HASH)) | |
167 | putc (' ', print.outf); | |
4ed5bcfb NB |
168 | } |
169 | else if (token->flags & PREV_WHITE) | |
63973df3 | 170 | putc (' ', print.outf); |
ef6e958a | 171 | |
4ed5bcfb | 172 | avoid_paste = false; |
63973df3 NB |
173 | print.source = NULL; |
174 | print.prev = token; | |
175 | cpp_output_token (token, print.outf); | |
4ed5bcfb | 176 | |
d4e6133f | 177 | if (token->type == CPP_COMMENT) |
63973df3 | 178 | account_for_newlines (token->val.str.text, token->val.str.len); |
93c80368 | 179 | } |
93c80368 NB |
180 | } |
181 | ||
12f9df4e | 182 | /* Adjust print.src_line for newlines embedded in output. */ |
dfbf62ec | 183 | static void |
43839642 | 184 | account_for_newlines (const unsigned char *str, size_t len) |
dfbf62ec | 185 | { |
b66377c1 NB |
186 | while (len--) |
187 | if (*str++ == '\n') | |
12f9df4e | 188 | print.src_line++; |
dfbf62ec NB |
189 | } |
190 | ||
1a76916c | 191 | /* Writes out a traditionally preprocessed file. */ |
afb03408 | 192 | static void |
2f6e4e97 | 193 | scan_translation_unit_trad (cpp_reader *pfile) |
afb03408 | 194 | { |
38800fe8 | 195 | while (_cpp_read_logical_line_trad (pfile)) |
afb03408 | 196 | { |
38800fe8 | 197 | size_t len = pfile->out.cur - pfile->out.base; |
12f9df4e | 198 | maybe_print_line (pfile->out.first_line); |
63973df3 NB |
199 | fwrite (pfile->out.base, 1, len, print.outf); |
200 | print.printed = 1; | |
b66377c1 | 201 | if (!CPP_OPTION (pfile, discard_comments)) |
63973df3 | 202 | account_for_newlines (pfile->out.base, len); |
afb03408 | 203 | } |
afb03408 NB |
204 | } |
205 | ||
67821e3a NB |
206 | /* If the token read on logical line LINE needs to be output on a |
207 | different line to the current one, output the required newlines or | |
208 | a line marker, and return 1. Otherwise return 0. */ | |
58fea6af | 209 | static void |
12f9df4e | 210 | maybe_print_line (source_location src_loc) |
93c80368 | 211 | { |
12f9df4e PB |
212 | const struct line_map *map = linemap_lookup (&line_table, src_loc); |
213 | int src_line = SOURCE_LINE (map, src_loc); | |
67821e3a | 214 | /* End the previous line of text. */ |
63973df3 | 215 | if (print.printed) |
93c80368 | 216 | { |
63973df3 | 217 | putc ('\n', print.outf); |
12f9df4e | 218 | print.src_line++; |
63973df3 | 219 | print.printed = 0; |
93c80368 NB |
220 | } |
221 | ||
12f9df4e | 222 | if (src_line >= print.src_line && src_line < print.src_line + 8) |
3cab4133 | 223 | { |
12f9df4e | 224 | while (src_line > print.src_line) |
93c80368 | 225 | { |
63973df3 | 226 | putc ('\n', print.outf); |
12f9df4e | 227 | print.src_line++; |
93c80368 NB |
228 | } |
229 | } | |
230 | else | |
12f9df4e | 231 | print_line (src_loc, ""); |
93c80368 NB |
232 | } |
233 | ||
47d89cf3 NB |
234 | /* Output a line marker for logical line LINE. Special flags are "1" |
235 | or "2" indicating entering or leaving a file. */ | |
93c80368 | 236 | static void |
12f9df4e | 237 | print_line (source_location src_loc, const char *special_flags) |
93c80368 NB |
238 | { |
239 | /* End any previous line of text. */ | |
63973df3 NB |
240 | if (print.printed) |
241 | putc ('\n', print.outf); | |
242 | print.printed = 0; | |
93c80368 | 243 | |
63973df3 | 244 | if (!flag_no_line_commands) |
47d89cf3 | 245 | { |
12f9df4e PB |
246 | const struct line_map *map = linemap_lookup (&line_table, src_loc); |
247 | ||
dcc229e5 | 248 | size_t to_file_len = strlen (map->to_file); |
cceb1885 GDR |
249 | unsigned char *to_file_quoted = |
250 | (unsigned char *) alloca (to_file_len * 4 + 1); | |
dcc229e5 | 251 | unsigned char *p; |
df383483 | 252 | |
12f9df4e PB |
253 | print.src_line = SOURCE_LINE (map, src_loc); |
254 | ||
dcc229e5 ZW |
255 | /* cpp_quote_string does not nul-terminate, so we have to do it |
256 | ourselves. */ | |
257 | p = cpp_quote_string (to_file_quoted, | |
5f754896 | 258 | (const unsigned char *) map->to_file, to_file_len); |
dcc229e5 | 259 | *p = '\0'; |
d2c979ef PB |
260 | fprintf (print.outf, "# %u \"%s\"%s", |
261 | print.src_line == 0 ? 1 : print.src_line, | |
a3737481 | 262 | to_file_quoted, special_flags); |
47d89cf3 NB |
263 | |
264 | if (map->sysp == 2) | |
63973df3 | 265 | fputs (" 3 4", print.outf); |
47d89cf3 | 266 | else if (map->sysp == 1) |
63973df3 | 267 | fputs (" 3", print.outf); |
47d89cf3 | 268 | |
63973df3 | 269 | putc ('\n', print.outf); |
47d89cf3 | 270 | } |
93c80368 NB |
271 | } |
272 | ||
97293897 | 273 | /* Called when a line of output is started. TOKEN is the first token |
d15a58c0 | 274 | of the line, and at end of file will be CPP_EOF. */ |
97293897 | 275 | static void |
b2734c68 | 276 | cb_line_change (cpp_reader *pfile, const cpp_token *token, |
7b9a5a66 | 277 | int parsing_args) |
97293897 | 278 | { |
12f9df4e PB |
279 | source_location src_loc = token->src_loc; |
280 | ||
7b9a5a66 | 281 | if (token->type == CPP_EOF || parsing_args) |
97293897 NB |
282 | return; |
283 | ||
12f9df4e | 284 | maybe_print_line (src_loc); |
63973df3 NB |
285 | print.prev = 0; |
286 | print.source = 0; | |
97293897 NB |
287 | |
288 | /* Supply enough spaces to put this token in its original column, | |
289 | one space per column greater than 2, since scan_translation_unit | |
290 | will provide a space if PREV_WHITE. Don't bother trying to | |
291 | reconstruct tabs; we can't get it right in general, and nothing | |
292 | ought to care. Some things do care; the fault lies with them. */ | |
278c4662 | 293 | if (!CPP_OPTION (pfile, traditional)) |
97293897 | 294 | { |
12f9df4e PB |
295 | const struct line_map *map = linemap_lookup (&line_table, src_loc); |
296 | int spaces = SOURCE_COLUMN (map, src_loc) - 2; | |
63973df3 | 297 | print.printed = 1; |
97293897 | 298 | |
12f9df4e PB |
299 | while (-- spaces >= 0) |
300 | putc (' ', print.outf); | |
97293897 NB |
301 | } |
302 | } | |
93c80368 NB |
303 | |
304 | static void | |
a281759f | 305 | cb_ident (cpp_reader *pfile ATTRIBUTE_UNUSED, source_location line, |
2f6e4e97 | 306 | const cpp_string *str) |
58fea6af | 307 | { |
12f9df4e | 308 | maybe_print_line (line); |
14788775 | 309 | fprintf (print.outf, "#ident %s\n", str->text); |
12f9df4e | 310 | print.src_line++; |
58fea6af ZW |
311 | } |
312 | ||
313 | static void | |
a281759f | 314 | cb_define (cpp_reader *pfile, source_location line, cpp_hashnode *node) |
58fea6af | 315 | { |
12f9df4e | 316 | maybe_print_line (line); |
63973df3 | 317 | fputs ("#define ", print.outf); |
93c80368 | 318 | |
63973df3 NB |
319 | /* 'D' is whole definition; 'N' is name only. */ |
320 | if (flag_dump_macros == 'D') | |
a3737481 | 321 | fputs ((const char *) cpp_macro_definition (pfile, node), |
63973df3 | 322 | print.outf); |
7096171b | 323 | else |
63973df3 | 324 | fputs ((const char *) NODE_NAME (node), print.outf); |
93c80368 | 325 | |
63973df3 | 326 | putc ('\n', print.outf); |
112598f4 PB |
327 | if (linemap_lookup (&line_table, line)->to_line != 0) |
328 | print.src_line++; | |
58fea6af ZW |
329 | } |
330 | ||
331 | static void | |
12f9df4e | 332 | cb_undef (cpp_reader *pfile ATTRIBUTE_UNUSED, source_location line, |
2f6e4e97 | 333 | cpp_hashnode *node) |
58fea6af | 334 | { |
12f9df4e | 335 | maybe_print_line (line); |
63973df3 | 336 | fprintf (print.outf, "#undef %s\n", NODE_NAME (node)); |
12f9df4e | 337 | print.src_line++; |
58fea6af ZW |
338 | } |
339 | ||
340 | static void | |
12f9df4e | 341 | cb_include (cpp_reader *pfile ATTRIBUTE_UNUSED, source_location line, |
cbc43ae0 ILT |
342 | const unsigned char *dir, const char *header, int angle_brackets, |
343 | const cpp_token **comments) | |
58fea6af | 344 | { |
12f9df4e | 345 | maybe_print_line (line); |
74eb4b3e | 346 | if (angle_brackets) |
cbc43ae0 | 347 | fprintf (print.outf, "#%s <%s>", dir, header); |
74eb4b3e | 348 | else |
cbc43ae0 ILT |
349 | fprintf (print.outf, "#%s \"%s\"", dir, header); |
350 | ||
351 | if (comments != NULL) | |
352 | { | |
353 | while (*comments != NULL) | |
354 | { | |
355 | if ((*comments)->flags & PREV_WHITE) | |
356 | putc (' ', print.outf); | |
357 | cpp_output_token (*comments, print.outf); | |
358 | ++comments; | |
359 | } | |
360 | } | |
361 | ||
362 | putc ('\n', print.outf); | |
12f9df4e | 363 | print.src_line++; |
58fea6af ZW |
364 | } |
365 | ||
8e9ea4d7 | 366 | /* Callback called when -fworking-director and -E to emit working |
fb0840fc | 367 | directory in cpp output file. */ |
8e9ea4d7 PB |
368 | |
369 | void | |
370 | pp_dir_change (cpp_reader *pfile ATTRIBUTE_UNUSED, const char *dir) | |
371 | { | |
372 | size_t to_file_len = strlen (dir); | |
cceb1885 GDR |
373 | unsigned char *to_file_quoted = |
374 | (unsigned char *) alloca (to_file_len * 4 + 1); | |
8e9ea4d7 PB |
375 | unsigned char *p; |
376 | ||
9ac97460 | 377 | /* cpp_quote_string does not nul-terminate, so we have to do it ourselves. */ |
5f754896 | 378 | p = cpp_quote_string (to_file_quoted, (const unsigned char *) dir, to_file_len); |
8e9ea4d7 PB |
379 | *p = '\0'; |
380 | fprintf (print.outf, "# 1 \"%s//\"\n", to_file_quoted); | |
381 | } | |
382 | ||
42dcba34 | 383 | /* The file name, line number or system header flags have changed, as |
12f9df4e | 384 | described in MAP. */ |
42dcba34 | 385 | |
23345bbb | 386 | void |
2f6e4e97 | 387 | pp_file_change (const struct line_map *map) |
58fea6af | 388 | { |
d7bc7a98 | 389 | const char *flags = ""; |
58fea6af | 390 | |
f9c65623 | 391 | if (flag_no_line_commands) |
23345bbb NB |
392 | return; |
393 | ||
f4b2bde7 | 394 | if (map != NULL) |
d7bc7a98 | 395 | { |
22234f56 | 396 | if (print.first_time) |
f4b2bde7 PB |
397 | { |
398 | /* Avoid printing foo.i when the main file is foo.c. */ | |
399 | if (!cpp_get_options (parse_in)->preprocessed) | |
12f9df4e | 400 | print_line (map->start_location, flags); |
22234f56 | 401 | print.first_time = 0; |
f4b2bde7 PB |
402 | } |
403 | else | |
404 | { | |
405 | /* Bring current file to correct line when entering a new file. */ | |
406 | if (map->reason == LC_ENTER) | |
12f9df4e PB |
407 | { |
408 | const struct line_map *from = INCLUDED_FROM (&line_table, map); | |
409 | maybe_print_line (LAST_SOURCE_LINE_LOCATION (from)); | |
410 | } | |
f4b2bde7 PB |
411 | if (map->reason == LC_ENTER) |
412 | flags = " 1"; | |
413 | else if (map->reason == LC_LEAVE) | |
414 | flags = " 2"; | |
12f9df4e | 415 | print_line (map->start_location, flags); |
f4b2bde7 | 416 | } |
ad2a084d | 417 | } |
9ec7291f ZW |
418 | } |
419 | ||
bb74c963 | 420 | /* Copy a #pragma directive to the preprocessed output. */ |
58fea6af | 421 | static void |
a281759f | 422 | cb_def_pragma (cpp_reader *pfile, source_location line) |
58fea6af | 423 | { |
12f9df4e | 424 | maybe_print_line (line); |
63973df3 NB |
425 | fputs ("#pragma ", print.outf); |
426 | cpp_output_line (pfile, print.outf); | |
12f9df4e | 427 | print.src_line++; |
58fea6af ZW |
428 | } |
429 | ||
58fea6af ZW |
430 | /* Dump out the hash table. */ |
431 | static int | |
2f6e4e97 | 432 | dump_macro (cpp_reader *pfile, cpp_hashnode *node, void *v ATTRIBUTE_UNUSED) |
58fea6af | 433 | { |
93c80368 | 434 | if (node->type == NT_MACRO && !(node->flags & NODE_BUILTIN)) |
58fea6af | 435 | { |
63973df3 | 436 | fputs ("#define ", print.outf); |
a3737481 | 437 | fputs ((const char *) cpp_macro_definition (pfile, node), |
63973df3 NB |
438 | print.outf); |
439 | putc ('\n', print.outf); | |
12f9df4e | 440 | print.src_line++; |
58fea6af ZW |
441 | } |
442 | ||
443 | return 1; | |
444 | } | |
c0d578e6 GK |
445 | |
446 | /* Load in the PCH file NAME, open on FD. It was originally searched for | |
447 | by ORIG_NAME. Also, print out a #include command so that the PCH | |
448 | file can be loaded when the preprocessed output is compiled. */ | |
449 | ||
450 | static void | |
451 | cb_read_pch (cpp_reader *pfile, const char *name, | |
452 | int fd, const char *orig_name ATTRIBUTE_UNUSED) | |
453 | { | |
454 | c_common_read_pch (pfile, name, fd, orig_name); | |
c22cacf3 | 455 | |
c0d578e6 GK |
456 | fprintf (print.outf, "#pragma GCC pch_preprocess \"%s\"\n", name); |
457 | print.src_line++; | |
458 | } |