]>
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 | |
63973df3 | 18 | Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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" |
afb03408 | 25 | #include "cpphash.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); |
a1c18b4a MS |
54 | static void cb_define (cpp_reader *, fileline, cpp_hashnode *); |
55 | static void cb_undef (cpp_reader *, fileline, cpp_hashnode *); | |
56 | static void cb_include (cpp_reader *, fileline, const unsigned char *, | |
2f6e4e97 | 57 | const char *, int); |
a1c18b4a MS |
58 | static void cb_ident (cpp_reader *, fileline, const cpp_string *); |
59 | static void cb_def_pragma (cpp_reader *, fileline); | |
93c80368 | 60 | |
aaf93206 NB |
61 | /* Preprocess and output. */ |
62 | void | |
2f6e4e97 | 63 | preprocess_file (cpp_reader *pfile) |
7f2935c7 | 64 | { |
9d10c9a9 NB |
65 | /* A successful cpp_read_main_file guarantees that we can call |
66 | cpp_scan_nooutput or cpp_get_token next. */ | |
67 | if (flag_no_output) | |
6de8f7fc | 68 | { |
9d10c9a9 NB |
69 | /* Scan -included buffers, then the main file. */ |
70 | while (pfile->buffer->prev) | |
71 | cpp_scan_nooutput (pfile); | |
72 | cpp_scan_nooutput (pfile); | |
6de8f7fc | 73 | } |
9d10c9a9 NB |
74 | else if (cpp_get_options (pfile)->traditional) |
75 | scan_translation_unit_trad (pfile); | |
76 | else | |
77 | scan_translation_unit (pfile); | |
78 | ||
79 | /* -dM command line option. Should this be elsewhere? */ | |
80 | if (flag_dump_macros == 'M') | |
81 | cpp_forall_identifiers (pfile, dump_macro, NULL); | |
6de8f7fc NB |
82 | |
83 | /* Flush any pending output. */ | |
63973df3 NB |
84 | if (print.printed) |
85 | putc ('\n', print.outf); | |
6de8f7fc NB |
86 | } |
87 | ||
620ef26c | 88 | /* Set up the callbacks as appropriate. */ |
9d10c9a9 | 89 | void |
2f6e4e97 | 90 | init_pp_output (FILE *out_stream) |
cf44ea52 | 91 | { |
9d10c9a9 NB |
92 | cpp_callbacks *cb = cpp_get_callbacks (parse_in); |
93 | ||
63973df3 | 94 | if (!flag_no_output) |
cf44ea52 | 95 | { |
f0581dc7 | 96 | cb->line_change = cb_line_change; |
c7544dd8 ZW |
97 | /* Don't emit #pragma or #ident directives if we are processing |
98 | assembly language; the assembler may choke on them. */ | |
9d10c9a9 | 99 | if (cpp_get_options (parse_in)->lang != CLK_ASM) |
c7544dd8 ZW |
100 | { |
101 | cb->ident = cb_ident; | |
102 | cb->def_pragma = cb_def_pragma; | |
103 | } | |
cf44ea52 NB |
104 | } |
105 | ||
63973df3 | 106 | if (flag_dump_includes) |
620ef26c | 107 | cb->include = cb_include; |
cf44ea52 | 108 | |
63973df3 | 109 | if (flag_dump_macros == 'N' || flag_dump_macros == 'D') |
cf44ea52 | 110 | { |
620ef26c NB |
111 | cb->define = cb_define; |
112 | cb->undef = cb_undef; | |
cf44ea52 | 113 | } |
9d10c9a9 | 114 | |
12f9df4e | 115 | /* Initialize the print structure. Setting print.src_line to -1 here is |
9d10c9a9 NB |
116 | a trick to guarantee that the first token of the file will cause |
117 | a linemarker to be output by maybe_print_line. */ | |
12f9df4e | 118 | print.src_line = -1; |
9d10c9a9 NB |
119 | print.printed = 0; |
120 | print.prev = 0; | |
9d10c9a9 | 121 | print.outf = out_stream; |
22234f56 | 122 | print.first_time = 1; |
cf44ea52 NB |
123 | } |
124 | ||
644eddaa NB |
125 | /* Writes out the preprocessed file, handling spacing and paste |
126 | avoidance issues. */ | |
93c80368 | 127 | static void |
2f6e4e97 | 128 | scan_translation_unit (cpp_reader *pfile) |
93c80368 | 129 | { |
4ed5bcfb | 130 | bool avoid_paste = false; |
58fea6af | 131 | |
63973df3 | 132 | print.source = NULL; |
4ed5bcfb | 133 | for (;;) |
93c80368 | 134 | { |
4ed5bcfb NB |
135 | const cpp_token *token = cpp_get_token (pfile); |
136 | ||
137 | if (token->type == CPP_PADDING) | |
138 | { | |
139 | avoid_paste = true; | |
63973df3 NB |
140 | if (print.source == NULL |
141 | || (!(print.source->flags & PREV_WHITE) | |
0c34509f | 142 | && token->val.source == NULL)) |
63973df3 | 143 | print.source = token->val.source; |
4ed5bcfb NB |
144 | continue; |
145 | } | |
93c80368 | 146 | |
ef6e958a NB |
147 | if (token->type == CPP_EOF) |
148 | break; | |
93c80368 | 149 | |
4ed5bcfb NB |
150 | /* Subtle logic to output a space if and only if necessary. */ |
151 | if (avoid_paste) | |
152 | { | |
63973df3 NB |
153 | if (print.source == NULL) |
154 | print.source = token; | |
155 | if (print.source->flags & PREV_WHITE | |
156 | || (print.prev | |
157 | && cpp_avoid_paste (pfile, print.prev, token)) | |
158 | || (print.prev == NULL && token->type == CPP_HASH)) | |
159 | putc (' ', print.outf); | |
4ed5bcfb NB |
160 | } |
161 | else if (token->flags & PREV_WHITE) | |
63973df3 | 162 | putc (' ', print.outf); |
ef6e958a | 163 | |
4ed5bcfb | 164 | avoid_paste = false; |
63973df3 NB |
165 | print.source = NULL; |
166 | print.prev = token; | |
167 | cpp_output_token (token, print.outf); | |
4ed5bcfb | 168 | |
d4e6133f | 169 | if (token->type == CPP_COMMENT) |
63973df3 | 170 | account_for_newlines (token->val.str.text, token->val.str.len); |
93c80368 | 171 | } |
93c80368 NB |
172 | } |
173 | ||
12f9df4e | 174 | /* Adjust print.src_line for newlines embedded in output. */ |
dfbf62ec | 175 | static void |
43839642 | 176 | account_for_newlines (const unsigned char *str, size_t len) |
dfbf62ec | 177 | { |
b66377c1 NB |
178 | while (len--) |
179 | if (*str++ == '\n') | |
12f9df4e | 180 | print.src_line++; |
dfbf62ec NB |
181 | } |
182 | ||
1a76916c | 183 | /* Writes out a traditionally preprocessed file. */ |
afb03408 | 184 | static void |
2f6e4e97 | 185 | scan_translation_unit_trad (cpp_reader *pfile) |
afb03408 | 186 | { |
38800fe8 | 187 | while (_cpp_read_logical_line_trad (pfile)) |
afb03408 | 188 | { |
38800fe8 | 189 | size_t len = pfile->out.cur - pfile->out.base; |
12f9df4e | 190 | maybe_print_line (pfile->out.first_line); |
63973df3 NB |
191 | fwrite (pfile->out.base, 1, len, print.outf); |
192 | print.printed = 1; | |
b66377c1 | 193 | if (!CPP_OPTION (pfile, discard_comments)) |
63973df3 | 194 | account_for_newlines (pfile->out.base, len); |
afb03408 | 195 | } |
afb03408 NB |
196 | } |
197 | ||
67821e3a NB |
198 | /* If the token read on logical line LINE needs to be output on a |
199 | different line to the current one, output the required newlines or | |
200 | a line marker, and return 1. Otherwise return 0. */ | |
58fea6af | 201 | static void |
12f9df4e | 202 | maybe_print_line (source_location src_loc) |
93c80368 | 203 | { |
12f9df4e PB |
204 | const struct line_map *map = linemap_lookup (&line_table, src_loc); |
205 | int src_line = SOURCE_LINE (map, src_loc); | |
67821e3a | 206 | /* End the previous line of text. */ |
63973df3 | 207 | if (print.printed) |
93c80368 | 208 | { |
63973df3 | 209 | putc ('\n', print.outf); |
12f9df4e | 210 | print.src_line++; |
63973df3 | 211 | print.printed = 0; |
93c80368 NB |
212 | } |
213 | ||
12f9df4e | 214 | if (src_line >= print.src_line && src_line < print.src_line + 8) |
3cab4133 | 215 | { |
12f9df4e | 216 | while (src_line > print.src_line) |
93c80368 | 217 | { |
63973df3 | 218 | putc ('\n', print.outf); |
12f9df4e | 219 | print.src_line++; |
93c80368 NB |
220 | } |
221 | } | |
222 | else | |
12f9df4e | 223 | print_line (src_loc, ""); |
93c80368 NB |
224 | } |
225 | ||
47d89cf3 NB |
226 | /* Output a line marker for logical line LINE. Special flags are "1" |
227 | or "2" indicating entering or leaving a file. */ | |
93c80368 | 228 | static void |
12f9df4e | 229 | print_line (source_location src_loc, const char *special_flags) |
93c80368 NB |
230 | { |
231 | /* End any previous line of text. */ | |
63973df3 NB |
232 | if (print.printed) |
233 | putc ('\n', print.outf); | |
234 | print.printed = 0; | |
93c80368 | 235 | |
63973df3 | 236 | if (!flag_no_line_commands) |
47d89cf3 | 237 | { |
12f9df4e PB |
238 | const struct line_map *map = linemap_lookup (&line_table, src_loc); |
239 | ||
dcc229e5 ZW |
240 | size_t to_file_len = strlen (map->to_file); |
241 | unsigned char *to_file_quoted = alloca (to_file_len * 4 + 1); | |
242 | unsigned char *p; | |
df383483 | 243 | |
12f9df4e PB |
244 | print.src_line = SOURCE_LINE (map, src_loc); |
245 | ||
dcc229e5 ZW |
246 | /* cpp_quote_string does not nul-terminate, so we have to do it |
247 | ourselves. */ | |
248 | p = cpp_quote_string (to_file_quoted, | |
249 | (unsigned char *)map->to_file, to_file_len); | |
250 | *p = '\0'; | |
12f9df4e | 251 | fprintf (print.outf, "# %u \"%s\"%s", print.src_line, |
a3737481 | 252 | to_file_quoted, special_flags); |
47d89cf3 NB |
253 | |
254 | if (map->sysp == 2) | |
63973df3 | 255 | fputs (" 3 4", print.outf); |
47d89cf3 | 256 | else if (map->sysp == 1) |
63973df3 | 257 | fputs (" 3", print.outf); |
47d89cf3 | 258 | |
63973df3 | 259 | putc ('\n', print.outf); |
47d89cf3 | 260 | } |
93c80368 NB |
261 | } |
262 | ||
97293897 | 263 | /* Called when a line of output is started. TOKEN is the first token |
d15a58c0 | 264 | of the line, and at end of file will be CPP_EOF. */ |
97293897 | 265 | static void |
b2734c68 | 266 | cb_line_change (cpp_reader *pfile, const cpp_token *token, |
7b9a5a66 | 267 | int parsing_args) |
97293897 | 268 | { |
12f9df4e PB |
269 | source_location src_loc = token->src_loc; |
270 | ||
7b9a5a66 | 271 | if (token->type == CPP_EOF || parsing_args) |
97293897 NB |
272 | return; |
273 | ||
12f9df4e | 274 | maybe_print_line (src_loc); |
63973df3 NB |
275 | print.prev = 0; |
276 | print.source = 0; | |
97293897 NB |
277 | |
278 | /* Supply enough spaces to put this token in its original column, | |
279 | one space per column greater than 2, since scan_translation_unit | |
280 | will provide a space if PREV_WHITE. Don't bother trying to | |
281 | reconstruct tabs; we can't get it right in general, and nothing | |
282 | ought to care. Some things do care; the fault lies with them. */ | |
278c4662 | 283 | if (!CPP_OPTION (pfile, traditional)) |
97293897 | 284 | { |
12f9df4e PB |
285 | const struct line_map *map = linemap_lookup (&line_table, src_loc); |
286 | int spaces = SOURCE_COLUMN (map, src_loc) - 2; | |
63973df3 | 287 | print.printed = 1; |
97293897 | 288 | |
12f9df4e PB |
289 | while (-- spaces >= 0) |
290 | putc (' ', print.outf); | |
97293897 NB |
291 | } |
292 | } | |
93c80368 NB |
293 | |
294 | static void | |
a1c18b4a | 295 | cb_ident (cpp_reader *pfile ATTRIBUTE_UNUSED, fileline line, |
2f6e4e97 | 296 | const cpp_string *str) |
58fea6af | 297 | { |
12f9df4e | 298 | maybe_print_line (line); |
63973df3 | 299 | fprintf (print.outf, "#ident \"%s\"\n", str->text); |
12f9df4e | 300 | print.src_line++; |
58fea6af ZW |
301 | } |
302 | ||
303 | static void | |
a1c18b4a | 304 | cb_define (cpp_reader *pfile, fileline line, cpp_hashnode *node) |
58fea6af | 305 | { |
12f9df4e | 306 | maybe_print_line (line); |
63973df3 | 307 | fputs ("#define ", print.outf); |
93c80368 | 308 | |
63973df3 NB |
309 | /* 'D' is whole definition; 'N' is name only. */ |
310 | if (flag_dump_macros == 'D') | |
a3737481 | 311 | fputs ((const char *) cpp_macro_definition (pfile, node), |
63973df3 | 312 | print.outf); |
7096171b | 313 | else |
63973df3 | 314 | fputs ((const char *) NODE_NAME (node), print.outf); |
93c80368 | 315 | |
63973df3 | 316 | putc ('\n', print.outf); |
12f9df4e | 317 | print.src_line++; |
58fea6af ZW |
318 | } |
319 | ||
320 | static void | |
12f9df4e | 321 | cb_undef (cpp_reader *pfile ATTRIBUTE_UNUSED, source_location line, |
2f6e4e97 | 322 | cpp_hashnode *node) |
58fea6af | 323 | { |
12f9df4e | 324 | maybe_print_line (line); |
63973df3 | 325 | fprintf (print.outf, "#undef %s\n", NODE_NAME (node)); |
12f9df4e | 326 | print.src_line++; |
58fea6af ZW |
327 | } |
328 | ||
329 | static void | |
12f9df4e | 330 | cb_include (cpp_reader *pfile ATTRIBUTE_UNUSED, source_location line, |
2f6e4e97 | 331 | const unsigned char *dir, const char *header, int angle_brackets) |
58fea6af | 332 | { |
12f9df4e | 333 | maybe_print_line (line); |
74eb4b3e NB |
334 | if (angle_brackets) |
335 | fprintf (print.outf, "#%s <%s>\n", dir, header); | |
336 | else | |
337 | fprintf (print.outf, "#%s \"%s\"\n", dir, header); | |
12f9df4e | 338 | print.src_line++; |
58fea6af ZW |
339 | } |
340 | ||
8e9ea4d7 | 341 | /* Callback called when -fworking-director and -E to emit working |
fb0840fc | 342 | directory in cpp output file. */ |
8e9ea4d7 PB |
343 | |
344 | void | |
345 | pp_dir_change (cpp_reader *pfile ATTRIBUTE_UNUSED, const char *dir) | |
346 | { | |
347 | size_t to_file_len = strlen (dir); | |
348 | unsigned char *to_file_quoted = alloca (to_file_len * 4 + 1); | |
349 | unsigned char *p; | |
350 | ||
9ac97460 | 351 | /* cpp_quote_string does not nul-terminate, so we have to do it ourselves. */ |
8e9ea4d7 PB |
352 | p = cpp_quote_string (to_file_quoted, (unsigned char *) dir, to_file_len); |
353 | *p = '\0'; | |
354 | fprintf (print.outf, "# 1 \"%s//\"\n", to_file_quoted); | |
355 | } | |
356 | ||
42dcba34 | 357 | /* The file name, line number or system header flags have changed, as |
12f9df4e | 358 | described in MAP. */ |
42dcba34 | 359 | |
23345bbb | 360 | void |
2f6e4e97 | 361 | pp_file_change (const struct line_map *map) |
58fea6af | 362 | { |
d7bc7a98 | 363 | const char *flags = ""; |
58fea6af | 364 | |
23345bbb NB |
365 | if (flag_no_line_commands || flag_no_output) |
366 | return; | |
367 | ||
f4b2bde7 | 368 | if (map != NULL) |
d7bc7a98 | 369 | { |
22234f56 | 370 | if (print.first_time) |
f4b2bde7 PB |
371 | { |
372 | /* Avoid printing foo.i when the main file is foo.c. */ | |
373 | if (!cpp_get_options (parse_in)->preprocessed) | |
12f9df4e | 374 | print_line (map->start_location, flags); |
22234f56 | 375 | print.first_time = 0; |
f4b2bde7 PB |
376 | } |
377 | else | |
378 | { | |
379 | /* Bring current file to correct line when entering a new file. */ | |
380 | if (map->reason == LC_ENTER) | |
12f9df4e PB |
381 | { |
382 | const struct line_map *from = INCLUDED_FROM (&line_table, map); | |
383 | maybe_print_line (LAST_SOURCE_LINE_LOCATION (from)); | |
384 | } | |
f4b2bde7 PB |
385 | if (map->reason == LC_ENTER) |
386 | flags = " 1"; | |
387 | else if (map->reason == LC_LEAVE) | |
388 | flags = " 2"; | |
12f9df4e | 389 | print_line (map->start_location, flags); |
f4b2bde7 | 390 | } |
ad2a084d | 391 | } |
9ec7291f ZW |
392 | } |
393 | ||
bb74c963 | 394 | /* Copy a #pragma directive to the preprocessed output. */ |
58fea6af | 395 | static void |
a1c18b4a | 396 | cb_def_pragma (cpp_reader *pfile, fileline line) |
58fea6af | 397 | { |
12f9df4e | 398 | maybe_print_line (line); |
63973df3 NB |
399 | fputs ("#pragma ", print.outf); |
400 | cpp_output_line (pfile, print.outf); | |
12f9df4e | 401 | print.src_line++; |
58fea6af ZW |
402 | } |
403 | ||
58fea6af ZW |
404 | /* Dump out the hash table. */ |
405 | static int | |
2f6e4e97 | 406 | dump_macro (cpp_reader *pfile, cpp_hashnode *node, void *v ATTRIBUTE_UNUSED) |
58fea6af | 407 | { |
93c80368 | 408 | if (node->type == NT_MACRO && !(node->flags & NODE_BUILTIN)) |
58fea6af | 409 | { |
63973df3 | 410 | fputs ("#define ", print.outf); |
a3737481 | 411 | fputs ((const char *) cpp_macro_definition (pfile, node), |
63973df3 NB |
412 | print.outf); |
413 | putc ('\n', print.outf); | |
12f9df4e | 414 | print.src_line++; |
58fea6af ZW |
415 | } |
416 | ||
417 | return 1; | |
418 | } |