Branch data Line data Source code
1 : : /* Preprocess only, using cpplib.
2 : : Copyright (C) 1995-2025 Free Software Foundation, Inc.
3 : : Written by Per Bothner, 1994-95.
4 : :
5 : : This program is free software; you can redistribute it and/or modify it
6 : : under the terms of the GNU General Public License as published by the
7 : : Free Software Foundation; either version 3, or (at your option) any
8 : : later version.
9 : :
10 : : This program is distributed in the hope that it will be useful,
11 : : but WITHOUT ANY WARRANTY; without even the implied warranty of
12 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 : : GNU General Public License for more details.
14 : :
15 : : You should have received a copy of the GNU General Public License
16 : : along with this program; see the file COPYING3. If not see
17 : : <http://www.gnu.org/licenses/>. */
18 : :
19 : : #include "config.h"
20 : : #include "system.h"
21 : : #include "coretypes.h"
22 : : #include "c-common.h" /* For flags. */
23 : : #include "../libcpp/internal.h"
24 : : #include "langhooks.h"
25 : : #include "c-pragma.h" /* For parse_in. */
26 : : #include "file-prefix-map.h" /* remap_macro_filename() */
27 : :
28 : : class token_streamer;
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. */
35 : : const cpp_token *prev; /* Previous token. */
36 : : const cpp_token *source; /* Source token for spacing. */
37 : : unsigned src_line; /* Line number currently being written. */
38 : : bool printed; /* True if something output at line. */
39 : : bool first_time; /* pp_file_change hasn't been called yet. */
40 : : bool prev_was_system_token; /* True if the previous token was a
41 : : system token.*/
42 : : const char *src_file; /* Current source file. */
43 : : token_streamer *streamer; /* Instance of class token_streamer using this
44 : : object. */
45 : : } print;
46 : :
47 : : /* Defined and undefined macros being queued for output with -dU at
48 : : the next newline. */
49 : : struct macro_queue
50 : : {
51 : : struct macro_queue *next; /* Next macro in the list. */
52 : : char *macro; /* The name of the macro if not
53 : : defined, the full definition if
54 : : defined. */
55 : : };
56 : : static macro_queue *define_queue, *undef_queue;
57 : :
58 : : /* General output routines. */
59 : : static void scan_translation_unit (cpp_reader *);
60 : : static void scan_translation_unit_directives_only (cpp_reader *);
61 : : static void scan_translation_unit_trad (cpp_reader *);
62 : : static void account_for_newlines (const unsigned char *, size_t);
63 : : static int dump_macro (cpp_reader *, cpp_hashnode *, void *);
64 : : static void dump_queued_macros (cpp_reader *);
65 : :
66 : : static bool print_line_1 (location_t, const char*, FILE *);
67 : : static bool print_line (location_t, const char *);
68 : : static bool maybe_print_line_1 (location_t, FILE *);
69 : : static bool maybe_print_line (location_t);
70 : : static bool do_line_change (cpp_reader *, const cpp_token *,
71 : : location_t, int);
72 : :
73 : : /* Callback routines for the parser. Most of these are active only
74 : : in specific modes. */
75 : : static void cb_line_change (cpp_reader *, const cpp_token *, int);
76 : : static void cb_define (cpp_reader *, location_t, cpp_hashnode *);
77 : : static void cb_undef (cpp_reader *, location_t, cpp_hashnode *);
78 : : static void cb_used_define (cpp_reader *, location_t, cpp_hashnode *);
79 : : static void cb_used_undef (cpp_reader *, location_t, cpp_hashnode *);
80 : : static void cb_include (cpp_reader *, location_t, const unsigned char *,
81 : : const char *, int, const cpp_token **);
82 : : static void cb_ident (cpp_reader *, location_t, const cpp_string *);
83 : : static void cb_def_pragma (cpp_reader *, location_t);
84 : : static void cb_read_pch (cpp_reader *pfile, const char *name,
85 : : int fd, const char *orig_name);
86 : :
87 : : /* Preprocess and output. */
88 : : void
89 : 6049 : preprocess_file (cpp_reader *pfile)
90 : : {
91 : : /* A successful cpp_read_main_file guarantees that we can call
92 : : cpp_scan_nooutput or cpp_get_token next. */
93 : 6049 : if (flag_no_output && pfile->buffer)
94 : : {
95 : 104 : if (flag_modules)
96 : : {
97 : : /* For macros from imported headers we need directives_only_cb. */
98 : 12 : scan_translation_unit_directives_only (pfile);
99 : : }
100 : : else
101 : : {
102 : : /* Scan -included buffers, then the main file. */
103 : 179 : while (pfile->buffer->prev)
104 : 87 : cpp_scan_nooutput (pfile);
105 : 92 : cpp_scan_nooutput (pfile);
106 : : }
107 : : }
108 : 5945 : else if (cpp_get_options (pfile)->traditional)
109 : 2349 : scan_translation_unit_trad (pfile);
110 : 3596 : else if (cpp_get_options (pfile)->directives_only
111 : 68 : && !cpp_get_options (pfile)->preprocessed)
112 : 60 : scan_translation_unit_directives_only (pfile);
113 : : else
114 : 3536 : scan_translation_unit (pfile);
115 : :
116 : : /* -dM command line option. Should this be elsewhere? */
117 : 5875 : if (flag_dump_macros == 'M')
118 : 80 : cpp_forall_identifiers (pfile, dump_macro, NULL);
119 : :
120 : : /* Flush any pending output. */
121 : 5875 : if (print.printed)
122 : 4184 : putc ('\n', print.outf);
123 : 5875 : }
124 : :
125 : : /* Don't emit #pragma or #ident directives if we are processing
126 : : assembly language; the assembler may choke on them. */
127 : : static bool
128 : 99373 : should_output_pragmas ()
129 : : {
130 : 99373 : return cpp_get_options (parse_in)->lang != CLK_ASM;
131 : : }
132 : :
133 : : /* Set up the callbacks as appropriate. */
134 : : void
135 : 6054 : init_pp_output (FILE *out_stream)
136 : : {
137 : 6054 : cpp_callbacks *cb = cpp_get_callbacks (parse_in);
138 : :
139 : 6054 : if (!flag_no_output)
140 : : {
141 : 5950 : cb->line_change = cb_line_change;
142 : 5950 : if (should_output_pragmas ())
143 : : {
144 : 4971 : cb->ident = cb_ident;
145 : 4971 : cb->def_pragma = cb_def_pragma;
146 : : }
147 : : }
148 : :
149 : 6054 : if (flag_dump_includes)
150 : 1 : cb->include = cb_include;
151 : :
152 : 6054 : if (flag_pch_preprocess)
153 : : {
154 : 463 : cb->valid_pch = c_common_valid_pch;
155 : 463 : cb->read_pch = cb_read_pch;
156 : : }
157 : :
158 : 6054 : if (flag_dump_macros == 'N' || flag_dump_macros == 'D')
159 : : {
160 : 172 : cb->define = cb_define;
161 : 172 : cb->undef = cb_undef;
162 : : }
163 : :
164 : 6054 : if (flag_dump_macros == 'U')
165 : : {
166 : 23 : cb->before_define = dump_queued_macros;
167 : 23 : cb->used_define = cb_used_define;
168 : 23 : cb->used_undef = cb_used_undef;
169 : : }
170 : :
171 : 6054 : cb->has_attribute = c_common_has_attribute;
172 : 6054 : cb->has_builtin = c_common_has_builtin;
173 : 6054 : cb->has_feature = c_common_has_feature;
174 : 6054 : cb->get_source_date_epoch = cb_get_source_date_epoch;
175 : 6054 : cb->get_suggestion = cb_get_suggestion;
176 : 6054 : cb->remap_filename = remap_macro_filename;
177 : :
178 : : /* Initialize the print structure. */
179 : 6054 : print.src_line = 1;
180 : 6054 : print.printed = false;
181 : 6054 : print.prev = 0;
182 : 6054 : print.outf = out_stream;
183 : 6054 : print.first_time = 1;
184 : 6054 : print.src_file = "";
185 : 6054 : print.prev_was_system_token = false;
186 : 6054 : print.streamer = nullptr;
187 : 6054 : }
188 : :
189 : : // FIXME: Ideally we'd just turn the entirety of the print struct into
190 : : // an encapsulated streamer ...
191 : :
192 : : class token_streamer
193 : : {
194 : : bool avoid_paste;
195 : : bool do_line_adjustments;
196 : : bool in_pragma;
197 : :
198 : : public:
199 : 3608 : token_streamer (cpp_reader *pfile)
200 : 3608 : :avoid_paste (false),
201 : 7216 : do_line_adjustments (cpp_get_options (pfile)->lang != CLK_ASM
202 : 3608 : && !flag_no_line_commands),
203 : 3608 : in_pragma (false)
204 : : {
205 : 3608 : gcc_assert (!print.streamer);
206 : 3608 : print.streamer = this;
207 : 3608 : }
208 : :
209 : 156 : void begin_pragma ()
210 : : {
211 : 156 : in_pragma = true;
212 : 156 : }
213 : :
214 : : void stream (cpp_reader *pfile, const cpp_token *tok, location_t);
215 : : };
216 : :
217 : : void
218 : 29560903 : token_streamer::stream (cpp_reader *pfile, const cpp_token *token,
219 : : location_t loc)
220 : : {
221 : : /* Keep input_location up to date, since it is needed for processing early
222 : : pragmas such as #pragma GCC diagnostic. */
223 : 29560903 : input_location = loc;
224 : :
225 : 29560903 : if (token->type == CPP_PADDING)
226 : : {
227 : 2072278 : avoid_paste = true;
228 : 2072278 : if (print.source == NULL
229 : 302117 : || (!(print.source->flags & PREV_WHITE)
230 : 86711 : && token->val.source == NULL))
231 : 1792938 : print.source = token->val.source;
232 : 2072278 : return;
233 : : }
234 : :
235 : 27488625 : if (token->type == CPP_EOF)
236 : : return;
237 : :
238 : : /* Keep track when we move into and out of system locations. */
239 : 27485263 : const bool is_system_token = in_system_header_at (loc);
240 : 27485263 : const bool system_state_changed
241 : 27485263 : = (is_system_token != print.prev_was_system_token);
242 : 27485263 : print.prev_was_system_token = is_system_token;
243 : :
244 : : /* Subtle logic to output a space if and only if necessary. */
245 : 27485263 : bool line_marker_emitted = false;
246 : 27485263 : if (avoid_paste)
247 : : {
248 : 1295007 : unsigned src_line = LOCATION_LINE (loc);
249 : :
250 : 1295007 : if (print.source == NULL)
251 : 557119 : print.source = token;
252 : :
253 : 1295007 : if (src_line != print.src_line
254 : 4711 : && do_line_adjustments
255 : 4673 : && !in_pragma)
256 : : {
257 : 4656 : line_marker_emitted = do_line_change (pfile, token, loc, false);
258 : 4656 : putc (' ', print.outf);
259 : 4656 : print.printed = true;
260 : : }
261 : 1290351 : else if (print.source->flags & PREV_WHITE
262 : 459406 : || (print.prev
263 : 393445 : && cpp_avoid_paste (pfile, print.prev, token))
264 : 1747780 : || (print.prev == NULL && token->type == CPP_HASH))
265 : : {
266 : 832939 : putc (' ', print.outf);
267 : 832939 : print.printed = true;
268 : : }
269 : : }
270 : 26190256 : else if (token->flags & PREV_WHITE && token->type != CPP_PRAGMA)
271 : : {
272 : 11266534 : unsigned src_line = LOCATION_LINE (loc);
273 : :
274 : 11266534 : if (src_line != print.src_line
275 : 7237 : && do_line_adjustments
276 : 527 : && !in_pragma)
277 : 401 : line_marker_emitted = do_line_change (pfile, token, loc, false);
278 : 11266534 : putc (' ', print.outf);
279 : 11266534 : print.printed = true;
280 : : }
281 : :
282 : 27485263 : avoid_paste = false;
283 : 27485263 : print.source = NULL;
284 : 27485263 : print.prev = token;
285 : 27485263 : if (token->type == CPP_PRAGMA)
286 : : {
287 : 28085 : in_pragma = true;
288 : 28085 : if (should_output_pragmas ())
289 : : {
290 : 28085 : const char *space;
291 : 28085 : const char *name;
292 : :
293 : 28085 : line_marker_emitted = maybe_print_line (token->src_loc);
294 : 28085 : fputs ("#pragma ", print.outf);
295 : 28085 : c_pp_lookup_pragma (token->val.pragma, &space, &name);
296 : 28085 : if (space)
297 : 28067 : fprintf (print.outf, "%s %s", space, name);
298 : : else
299 : 18 : fprintf (print.outf, "%s", name);
300 : 28085 : print.printed = true;
301 : : }
302 : 28085 : if (token->val.pragma >= PRAGMA_FIRST_EXTERNAL)
303 : 27991 : c_pp_invoke_early_pragma_handler (token->val.pragma);
304 : : }
305 : 27457178 : else if (token->type == CPP_PRAGMA_EOL)
306 : : {
307 : 28241 : if (should_output_pragmas ())
308 : 28241 : maybe_print_line (UNKNOWN_LOCATION);
309 : 28241 : in_pragma = false;
310 : : }
311 : 27428937 : else if (token->type == CPP_EMBED)
312 : : {
313 : 130 : char buf[76 + 6];
314 : 130 : maybe_print_line (token->src_loc);
315 : 130 : gcc_checking_assert (token->val.str.len != 0);
316 : 130 : fputs ("#embed \".\" __gnu__::__base64__(", print.outf);
317 : 130 : if (token->val.str.len > 30)
318 : : {
319 : 130 : fputs (" \\\n", print.outf);
320 : 130 : print.src_line++;
321 : : }
322 : 130 : buf[0] = '"';
323 : 130 : memcpy (buf + 1 + 76, "\" \\\n", 5);
324 : 130 : unsigned int j = 1;
325 : 130 : static const char base64_enc[] =
326 : : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
327 : 130 : for (unsigned i = 0; ; i += 3)
328 : : {
329 : 196824 : unsigned char a = token->val.str.text[i];
330 : 196824 : unsigned char b = 0, c = 0;
331 : 196824 : unsigned int n = token->val.str.len - i;
332 : 196824 : if (n > 1)
333 : 196778 : b = token->val.str.text[i + 1];
334 : 196778 : if (n > 2)
335 : 196738 : c = token->val.str.text[i + 2];
336 : 196824 : unsigned long v = ((((unsigned long) a) << 16)
337 : 196824 : | (((unsigned long) b) << 8)
338 : 196824 : | c);
339 : 196824 : buf[j++] = base64_enc[(v >> 18) & 63];
340 : 196824 : buf[j++] = base64_enc[(v >> 12) & 63];
341 : 196824 : buf[j++] = base64_enc[(v >> 6) & 63];
342 : 196824 : buf[j++] = base64_enc[v & 63];
343 : 196824 : if (j == 76 + 1 || n <= 3)
344 : : {
345 : 10438 : if (n < 3)
346 : : {
347 : 86 : buf[j - 1] = '=';
348 : 86 : if (n == 1)
349 : 46 : buf[j - 2] = '=';
350 : : }
351 : 10438 : if (n <= 3)
352 : 130 : memcpy (buf + j, "\")", 3);
353 : : else
354 : 10308 : print.src_line++;
355 : 10438 : fputs (buf, print.outf);
356 : 10438 : j = 1;
357 : 10438 : if (n <= 3)
358 : : break;
359 : : }
360 : 196694 : }
361 : 130 : print.printed = true;
362 : 130 : maybe_print_line (token->src_loc);
363 : 130 : return;
364 : : }
365 : : else
366 : : {
367 : 27428807 : if (cpp_get_options (parse_in)->debug)
368 : 3 : linemap_dump_location (line_table, token->src_loc, print.outf);
369 : :
370 : 27428807 : if (do_line_adjustments
371 : 26956153 : && !in_pragma
372 : 26919056 : && !line_marker_emitted
373 : 26919056 : && system_state_changed
374 : 27440388 : && !is_location_from_builtin_token (loc))
375 : : /* The system-ness of this token is different from the one of
376 : : the previous token. Let's emit a line change to mark the
377 : : new system-ness before we emit the token. */
378 : : {
379 : 11578 : line_marker_emitted = do_line_change (pfile, token, loc, false);
380 : : }
381 : 27428807 : if (!in_pragma || should_output_pragmas ())
382 : : {
383 : 27428807 : cpp_output_token (token, print.outf);
384 : 27428807 : print.printed = true;
385 : : }
386 : : }
387 : :
388 : : /* CPP_COMMENT tokens and raw-string literal tokens can have
389 : : embedded new-line characters. Rather than enumerating all the
390 : : possible token types just check if token uses val.str union
391 : : member. */
392 : 27485133 : if (cpp_token_val_index (token) == CPP_TOKEN_FLD_STR)
393 : 575469 : account_for_newlines (token->val.str.text, token->val.str.len);
394 : : }
395 : :
396 : : /* Writes out the preprocessed file, handling spacing and paste
397 : : avoidance issues. */
398 : :
399 : : static void
400 : 3536 : scan_translation_unit (cpp_reader *pfile)
401 : : {
402 : 3536 : token_streamer streamer (pfile);
403 : 3536 : uintptr_t filter = 0;
404 : :
405 : 3536 : if (lang_hooks.preprocess_token)
406 : 1215 : filter = lang_hooks.preprocess_token (pfile, NULL, filter);
407 : :
408 : 3536 : print.source = NULL;
409 : 58988826 : for (;;)
410 : : {
411 : 29496181 : location_t spelling_loc;
412 : 29496181 : const cpp_token *token
413 : 29496181 : = cpp_get_token_with_location (pfile, &spelling_loc);
414 : :
415 : 29496007 : streamer.stream (pfile, token, spelling_loc);
416 : 29496007 : if (filter)
417 : : {
418 : 739030 : unsigned flags = lang_hooks.preprocess_token (pfile, token, filter);
419 : 739030 : if (flags & lang_hooks::PT_begin_pragma)
420 : 132 : streamer.begin_pragma ();
421 : : }
422 : 29496007 : if (token->type == CPP_EOF)
423 : : break;
424 : 29492645 : }
425 : :
426 : 3362 : if (filter)
427 : 93 : lang_hooks.preprocess_token (pfile, NULL, filter);
428 : 3362 : }
429 : :
430 : : class do_streamer : public token_streamer
431 : : {
432 : : public:
433 : : uintptr_t filter;
434 : :
435 : 72 : do_streamer (cpp_reader *pfile, uintptr_t filter)
436 : 144 : :token_streamer (pfile), filter (filter)
437 : : {
438 : : }
439 : : };
440 : :
441 : : static void
442 : 3816 : directives_only_cb (cpp_reader *pfile, CPP_DO_task task, void *data_, ...)
443 : : {
444 : 3816 : va_list args;
445 : 3816 : va_start (args, data_);
446 : :
447 : 3816 : do_streamer *streamer = reinterpret_cast <do_streamer *> (data_);
448 : 3816 : switch (task)
449 : : {
450 : 0 : default:
451 : 0 : gcc_unreachable ();
452 : :
453 : 822 : case CPP_DO_print:
454 : 822 : if (!flag_no_output)
455 : : {
456 : 729 : print.src_line += va_arg (args, unsigned);
457 : :
458 : 729 : const void *buf = va_arg (args, const void *);
459 : 729 : size_t size = va_arg (args, size_t);
460 : 729 : fwrite (buf, 1, size, print.outf);
461 : : }
462 : : break;
463 : :
464 : 1604 : case CPP_DO_location:
465 : 1604 : if (!flag_no_output)
466 : 1406 : maybe_print_line (va_arg (args, location_t));
467 : : break;
468 : :
469 : 1390 : case CPP_DO_token:
470 : 1390 : {
471 : 1390 : const cpp_token *token = va_arg (args, const cpp_token *);
472 : 1390 : unsigned flags = 0;
473 : 1390 : if (streamer->filter)
474 : 165 : flags = lang_hooks.preprocess_token (pfile, token, streamer->filter);
475 : 1390 : if (!flag_no_output)
476 : : {
477 : 1339 : location_t spelling_loc = va_arg (args, location_t);
478 : 1339 : streamer->stream (pfile, token, spelling_loc);
479 : 1339 : if (flags & lang_hooks::PT_begin_pragma)
480 : 24 : streamer->begin_pragma ();
481 : : }
482 : : }
483 : : break;
484 : : }
485 : :
486 : 3816 : va_end (args);
487 : 3816 : }
488 : :
489 : : /* Writes out the preprocessed file, handling spacing and paste
490 : : avoidance issues. */
491 : : static void
492 : 72 : scan_translation_unit_directives_only (cpp_reader *pfile)
493 : : {
494 : 72 : uintptr_t filter = 0;
495 : 72 : if (lang_hooks.preprocess_token)
496 : 56 : filter = lang_hooks.preprocess_token (pfile, NULL, filter);
497 : 72 : do_streamer streamer (pfile, filter);
498 : 72 : cpp_directive_only_process (pfile, &streamer, directives_only_cb);
499 : 72 : if (streamer.filter)
500 : 18 : lang_hooks.preprocess_token (pfile, NULL, streamer.filter);
501 : 72 : }
502 : :
503 : : /* Adjust print.src_line for newlines embedded in output. For example, if a raw
504 : : string literal contains newlines, then we need to increment our notion of the
505 : : current line to keep in sync and avoid outputting a line marker
506 : : unnecessarily. If a raw string literal containing newlines is the result of
507 : : macro expansion, then we have the opposite problem, where the token takes up
508 : : more lines in the output than it did in the input, and hence a line marker is
509 : : needed to restore the correct state for subsequent lines. In this case,
510 : : incrementing print.src_line still does the job, because it will cause us to
511 : : emit the line marker the next time a token is streamed. */
512 : : static void
513 : 575644 : account_for_newlines (const unsigned char *str, size_t len)
514 : : {
515 : 2778323 : while (len--)
516 : 2202679 : if (*str++ == '\n')
517 : 654 : print.src_line++;
518 : 575644 : }
519 : :
520 : : /* Writes out a traditionally preprocessed file. */
521 : : static void
522 : 2349 : scan_translation_unit_trad (cpp_reader *pfile)
523 : : {
524 : 451204 : while (_cpp_read_logical_line_trad (pfile))
525 : : {
526 : 446506 : size_t len = pfile->out.cur - pfile->out.base;
527 : 446506 : maybe_print_line (pfile->out.first_line);
528 : 446506 : fwrite (pfile->out.base, 1, len, print.outf);
529 : 446506 : print.printed = true;
530 : 446506 : if (!CPP_OPTION (pfile, discard_comments))
531 : 175 : account_for_newlines (pfile->out.base, len);
532 : : }
533 : 2349 : }
534 : :
535 : : /* If the token read on logical line LINE needs to be output on a
536 : : different line to the current one, output the required newlines or
537 : : a line marker. If a line marker was emitted, return TRUE otherwise
538 : : return FALSE. */
539 : :
540 : : static bool
541 : 4861465 : maybe_print_line_1 (location_t src_loc, FILE *stream)
542 : : {
543 : 4861465 : bool emitted_line_marker = false;
544 : 4861465 : unsigned src_line = LOCATION_LINE (src_loc);
545 : 4861465 : const char *src_file = LOCATION_FILE (src_loc);
546 : :
547 : : /* End the previous line of text. */
548 : 4861465 : if (print.printed)
549 : : {
550 : 4574420 : putc ('\n', stream);
551 : 4574420 : print.src_line++;
552 : 4574420 : print.printed = false;
553 : : }
554 : :
555 : 4861465 : if (!flag_no_line_commands
556 : 4849837 : && src_line >= print.src_line
557 : 4736994 : && src_line < print.src_line + 8
558 : 4598316 : && src_loc != UNKNOWN_LOCATION
559 : 4598314 : && strcmp (src_file, print.src_file) == 0)
560 : : {
561 : 6126764 : while (src_line > print.src_line)
562 : : {
563 : 1528450 : putc ('\n', stream);
564 : 1528450 : print.src_line++;
565 : : }
566 : : }
567 : : else
568 : 263151 : emitted_line_marker = print_line_1 (src_loc, "", stream);
569 : :
570 : 4861465 : return emitted_line_marker;
571 : : }
572 : :
573 : : /* If the token read on logical line LINE needs to be output on a
574 : : different line to the current one, output the required newlines or
575 : : a line marker. If a line marker was emitted, return TRUE otherwise
576 : : return FALSE. */
577 : :
578 : : static bool
579 : 4861465 : maybe_print_line (location_t src_loc)
580 : : {
581 : 4861465 : if (cpp_get_options (parse_in)->debug)
582 : 2 : linemap_dump_location (line_table, src_loc,
583 : : print.outf);
584 : 4861465 : return maybe_print_line_1 (src_loc, print.outf);
585 : : }
586 : :
587 : : /* Output a line marker for logical line LINE. Special flags are "1"
588 : : or "2" indicating entering or leaving a file. If the line marker
589 : : was effectively emitted, return TRUE otherwise return FALSE. */
590 : :
591 : : static bool
592 : 390414 : print_line_1 (location_t src_loc, const char *special_flags, FILE *stream)
593 : : {
594 : 390414 : bool emitted_line_marker = false;
595 : :
596 : : /* End any previous line of text. */
597 : 390414 : if (print.printed)
598 : 19109 : putc ('\n', stream);
599 : 390414 : print.printed = false;
600 : :
601 : 390414 : if (src_loc != UNKNOWN_LOCATION && !flag_no_line_commands)
602 : : {
603 : 350545 : const char *file_path = LOCATION_FILE (src_loc);
604 : 350545 : size_t to_file_len = strlen (file_path);
605 : 350545 : unsigned char *to_file_quoted =
606 : 350545 : (unsigned char *) alloca (to_file_len * 4 + 1);
607 : :
608 : : /* cpp_quote_string does not nul-terminate, so we have to do it
609 : : ourselves. */
610 : 350545 : unsigned char *p = cpp_quote_string (to_file_quoted,
611 : : (const unsigned char *) file_path,
612 : : to_file_len);
613 : 350545 : *p = '\0';
614 : :
615 : 350545 : print.src_line = LOCATION_LINE (src_loc);
616 : 350545 : print.src_file = file_path;
617 : :
618 : 350545 : fprintf (stream, "# %u \"%s\"%s",
619 : : print.src_line, to_file_quoted, special_flags);
620 : :
621 : 350545 : int sysp = in_system_header_at (src_loc);
622 : 350545 : if (sysp == 2)
623 : 141479 : fputs (" 3 4", stream);
624 : 209066 : else if (sysp == 1)
625 : 712 : fputs (" 3", stream);
626 : :
627 : 350545 : putc ('\n', stream);
628 : 350545 : emitted_line_marker = true;
629 : : }
630 : :
631 : 390414 : return emitted_line_marker;
632 : : }
633 : :
634 : : /* Output a line marker for logical line LINE. Special flags are "1"
635 : : or "2" indicating entering or leaving a file. Return TRUE if a
636 : : line marker was effectively emitted, FALSE otherwise. */
637 : :
638 : : static bool
639 : 127263 : print_line (location_t src_loc, const char *special_flags)
640 : : {
641 : 127263 : if (cpp_get_options (parse_in)->debug)
642 : 6 : linemap_dump_location (line_table, src_loc,
643 : : print.outf);
644 : 127263 : return print_line_1 (src_loc, special_flags, print.outf);
645 : : }
646 : :
647 : : /* Helper function for cb_line_change and scan_translation_unit.
648 : : Return TRUE if a line marker is emitted, FALSE otherwise. */
649 : : static bool
650 : 4170480 : do_line_change (cpp_reader *pfile, const cpp_token *token,
651 : : location_t src_loc, int parsing_args)
652 : : {
653 : 4170480 : bool emitted_line_marker = false;
654 : 4170480 : if (define_queue || undef_queue)
655 : 21 : dump_queued_macros (pfile);
656 : :
657 : 4170480 : if (token->type == CPP_EOF || parsing_args)
658 : : return false;
659 : :
660 : 4150305 : emitted_line_marker = maybe_print_line (src_loc);
661 : 4150305 : print.prev = 0;
662 : 4150305 : print.source = 0;
663 : :
664 : : /* Supply enough spaces to put this token in its original column,
665 : : one space per column greater than 2, since scan_translation_unit
666 : : will provide a space if PREV_WHITE. Don't bother trying to
667 : : reconstruct tabs; we can't get it right in general, and nothing
668 : : ought to care. Some things do care; the fault lies with them.
669 : :
670 : : Also do not output the spaces if this is a CPP_PRAGMA token. In this
671 : : case, libcpp has provided the location of the first token after #pragma,
672 : : so we would start at the wrong column. */
673 : 4150305 : if (!CPP_OPTION (pfile, traditional) && token->type != CPP_PRAGMA)
674 : : {
675 : 4122338 : int spaces = LOCATION_COLUMN (src_loc) - 2;
676 : 4122338 : print.printed = true;
677 : :
678 : 15735664 : while (-- spaces >= 0)
679 : 11613326 : putc (' ', print.outf);
680 : : }
681 : :
682 : : return emitted_line_marker;
683 : : }
684 : :
685 : : /* Called when a line of output is started. TOKEN is the first token
686 : : of the line, and at end of file will be CPP_EOF. */
687 : : static void
688 : 4153845 : cb_line_change (cpp_reader *pfile, const cpp_token *token,
689 : : int parsing_args)
690 : : {
691 : 4153845 : do_line_change (pfile, token, token->src_loc, parsing_args);
692 : 4153845 : }
693 : :
694 : : static void
695 : 2 : cb_ident (cpp_reader *pfile ATTRIBUTE_UNUSED, location_t line,
696 : : const cpp_string *str)
697 : : {
698 : 2 : maybe_print_line (line);
699 : 2 : fprintf (print.outf, "#ident %s\n", str->text);
700 : 2 : print.src_line++;
701 : 2 : }
702 : :
703 : : static void
704 : 145205 : cb_define (cpp_reader *pfile, location_t line, cpp_hashnode *node)
705 : : {
706 : 145205 : const line_map_ordinary *map;
707 : :
708 : 145205 : maybe_print_line (line);
709 : 145205 : fputs ("#define ", print.outf);
710 : :
711 : : /* 'D' is whole definition; 'N' is name only. */
712 : 145205 : if (flag_dump_macros == 'D')
713 : 39359 : fputs ((const char *) cpp_macro_definition (pfile, node),
714 : : print.outf);
715 : : else
716 : 105846 : fputs ((const char *) NODE_NAME (node), print.outf);
717 : :
718 : 145205 : putc ('\n', print.outf);
719 : 145205 : print.printed = false;
720 : 145205 : linemap_resolve_location (line_table, line,
721 : : LRK_MACRO_DEFINITION_LOCATION,
722 : : &map);
723 : 145205 : print.src_line++;
724 : 145205 : }
725 : :
726 : : static void
727 : 5463 : cb_undef (cpp_reader *pfile, location_t line, cpp_hashnode *node)
728 : : {
729 : 5463 : if (lang_hooks.preprocess_undef)
730 : 0 : lang_hooks.preprocess_undef (pfile, line, node);
731 : 5463 : maybe_print_line (line);
732 : 5463 : fprintf (print.outf, "#undef %s\n", NODE_NAME (node));
733 : 5463 : print.src_line++;
734 : 5463 : }
735 : :
736 : : static void
737 : 22 : cb_used_define (cpp_reader *pfile, location_t line ATTRIBUTE_UNUSED,
738 : : cpp_hashnode *node)
739 : : {
740 : 22 : if (cpp_user_macro_p (node))
741 : : {
742 : 21 : macro_queue *q;
743 : 21 : q = XNEW (macro_queue);
744 : 21 : q->macro = xstrdup ((const char *) cpp_macro_definition (pfile, node));
745 : 21 : q->next = define_queue;
746 : 21 : define_queue = q;
747 : : }
748 : 22 : }
749 : :
750 : : static void
751 : 11 : cb_used_undef (cpp_reader *pfile ATTRIBUTE_UNUSED,
752 : : location_t line ATTRIBUTE_UNUSED,
753 : : cpp_hashnode *node)
754 : : {
755 : 11 : macro_queue *q;
756 : 11 : q = XNEW (macro_queue);
757 : 11 : q->macro = xstrdup ((const char *) NODE_NAME (node));
758 : 11 : q->next = undef_queue;
759 : 11 : undef_queue = q;
760 : 11 : }
761 : :
762 : : static void
763 : 9294 : dump_queued_macros (cpp_reader *pfile ATTRIBUTE_UNUSED)
764 : : {
765 : 9294 : macro_queue *q;
766 : :
767 : : /* End the previous line of text. */
768 : 9294 : if (print.printed)
769 : : {
770 : 12 : putc ('\n', print.outf);
771 : 12 : print.src_line++;
772 : 12 : print.printed = false;
773 : : }
774 : :
775 : 9315 : for (q = define_queue; q;)
776 : : {
777 : 21 : macro_queue *oq;
778 : 21 : fputs ("#define ", print.outf);
779 : 21 : fputs (q->macro, print.outf);
780 : 21 : putc ('\n', print.outf);
781 : 21 : print.printed = false;
782 : 21 : print.src_line++;
783 : 21 : oq = q;
784 : 21 : q = q->next;
785 : 21 : free (oq->macro);
786 : 21 : free (oq);
787 : : }
788 : 9294 : define_queue = NULL;
789 : 9305 : for (q = undef_queue; q;)
790 : : {
791 : 11 : macro_queue *oq;
792 : 11 : fprintf (print.outf, "#undef %s\n", q->macro);
793 : 11 : print.src_line++;
794 : 11 : oq = q;
795 : 11 : q = q->next;
796 : 11 : free (oq->macro);
797 : 11 : free (oq);
798 : : }
799 : 9294 : undef_queue = NULL;
800 : 9294 : }
801 : :
802 : : static void
803 : 1 : cb_include (cpp_reader *pfile ATTRIBUTE_UNUSED, location_t line,
804 : : const unsigned char *dir, const char *header, int angle_brackets,
805 : : const cpp_token **comments)
806 : : {
807 : 1 : maybe_print_line (line);
808 : 1 : if (angle_brackets)
809 : 0 : fprintf (print.outf, "#%s <%s>", dir, header);
810 : : else
811 : 1 : fprintf (print.outf, "#%s \"%s\"", dir, header);
812 : :
813 : 1 : if (comments != NULL)
814 : : {
815 : 2 : while (*comments != NULL)
816 : : {
817 : 1 : if ((*comments)->flags & PREV_WHITE)
818 : 1 : putc (' ', print.outf);
819 : 1 : cpp_output_token (*comments, print.outf);
820 : 1 : ++comments;
821 : : }
822 : : }
823 : :
824 : 1 : putc ('\n', print.outf);
825 : 1 : print.printed = false;
826 : 1 : print.src_line++;
827 : 1 : }
828 : :
829 : : /* Callback called when -fworking-director and -E to emit working
830 : : directory in cpp output file. */
831 : :
832 : : void
833 : 2046 : pp_dir_change (cpp_reader *pfile ATTRIBUTE_UNUSED, const char *dir)
834 : : {
835 : 2046 : size_t to_file_len = strlen (dir);
836 : 2046 : unsigned char *to_file_quoted =
837 : 2046 : (unsigned char *) alloca (to_file_len * 4 + 1);
838 : 2046 : unsigned char *p;
839 : :
840 : : /* cpp_quote_string does not nul-terminate, so we have to do it ourselves. */
841 : 2046 : p = cpp_quote_string (to_file_quoted, (const unsigned char *) dir, to_file_len);
842 : 2046 : *p = '\0';
843 : 2046 : fprintf (print.outf, "# 1 \"%s//\"\n", to_file_quoted);
844 : 2046 : }
845 : :
846 : : /* The file name, line number or system header flags have changed, as
847 : : described in MAP. */
848 : :
849 : : void
850 : 138179 : pp_file_change (const line_map_ordinary *map)
851 : : {
852 : 138179 : const char *flags = "";
853 : :
854 : 138179 : if (flag_no_line_commands)
855 : : return;
856 : :
857 : 132996 : if (map != NULL)
858 : : {
859 : 127273 : input_location = map->start_location;
860 : 127273 : if (print.first_time)
861 : : {
862 : : /* Avoid printing foo.i when the main file is foo.c. */
863 : 5907 : if (!cpp_get_options (parse_in)->preprocessed)
864 : 5897 : print_line (map->start_location, flags);
865 : 5907 : print.first_time = 0;
866 : : }
867 : : else
868 : : {
869 : : /* Bring current file to correct line when entering a new file. */
870 : 121366 : if (map->reason == LC_ENTER)
871 : : {
872 : 51794 : maybe_print_line (linemap_included_from (map));
873 : 51794 : flags = " 1";
874 : : }
875 : 69572 : else if (map->reason == LC_LEAVE)
876 : 51790 : flags = " 2";
877 : 121366 : print_line (map->start_location, flags);
878 : : }
879 : : }
880 : : }
881 : :
882 : : /* Copy a #pragma directive to the preprocessed output. */
883 : : static void
884 : 4197 : cb_def_pragma (cpp_reader *pfile, location_t line)
885 : : {
886 : 4197 : maybe_print_line (line);
887 : 4197 : fputs ("#pragma ", print.outf);
888 : 4197 : cpp_output_line (pfile, print.outf);
889 : 4197 : print.printed = false;
890 : 4197 : print.src_line++;
891 : 4197 : }
892 : :
893 : : /* Stream a token as if we had seen it directly ourselves; needed
894 : : in case a token was lexed externally, e.g. while processing a
895 : : pragma. */
896 : : void
897 : 63557 : c_pp_stream_token (cpp_reader *pfile, const cpp_token *tok, location_t loc)
898 : : {
899 : 63557 : gcc_assert (print.streamer);
900 : 63557 : print.streamer->stream (pfile, tok, loc);
901 : 63557 : }
902 : :
903 : : /* Dump out the hash table. */
904 : : static int
905 : 331989 : dump_macro (cpp_reader *pfile, cpp_hashnode *node, void *v ATTRIBUTE_UNUSED)
906 : : {
907 : 331989 : if (cpp_user_macro_p (node))
908 : : {
909 : 54244 : fputs ("#define ", print.outf);
910 : 54244 : fputs ((const char *) cpp_macro_definition (pfile, node),
911 : : print.outf);
912 : 54244 : putc ('\n', print.outf);
913 : 54244 : print.printed = false;
914 : 54244 : print.src_line++;
915 : : }
916 : :
917 : 331989 : return 1;
918 : : }
919 : :
920 : : /* Load in the PCH file NAME, open on FD. It was originally searched for
921 : : by ORIG_NAME. Also, print out a #include command so that the PCH
922 : : file can be loaded when the preprocessed output is compiled. */
923 : :
924 : : static void
925 : 24 : cb_read_pch (cpp_reader *pfile, const char *name,
926 : : int fd, const char *orig_name ATTRIBUTE_UNUSED)
927 : : {
928 : 24 : c_common_read_pch (pfile, name, fd, orig_name);
929 : :
930 : 24 : fprintf (print.outf, "#pragma GCC pch_preprocess \"%s\"\n", name);
931 : 24 : print.src_line++;
932 : :
933 : : /* The process of reading the PCH has destroyed the frontend parser,
934 : : so ask the frontend to reinitialize it, in case we need it to
935 : : process any #pragma directives encountered while preprocessing. */
936 : 24 : c_init_preprocess ();
937 : 24 : }
|