Line data Source code
1 : /* Preprocess only, using cpplib.
2 : Copyright (C) 1995-2026 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 6767 : 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 6767 : if (flag_no_output && pfile->buffer)
94 : {
95 107 : if (flag_modules)
96 : {
97 : /* For macros from imported headers we need directives_only_cb. */
98 15 : 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 6660 : else if (cpp_get_options (pfile)->traditional)
109 2925 : scan_translation_unit_trad (pfile);
110 3735 : else if (cpp_get_options (pfile)->directives_only
111 80 : && !cpp_get_options (pfile)->preprocessed)
112 72 : scan_translation_unit_directives_only (pfile);
113 : else
114 3663 : scan_translation_unit (pfile);
115 :
116 : /* -dM command line option. Should this be elsewhere? */
117 6591 : if (flag_dump_macros == 'M')
118 80 : cpp_forall_identifiers (pfile, dump_macro, NULL);
119 :
120 : /* Flush any pending output. */
121 6591 : if (print.printed)
122 4776 : putc ('\n', print.outf);
123 6591 : }
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 118355 : should_output_pragmas ()
129 : {
130 118355 : return cpp_get_options (parse_in)->lang != CLK_ASM;
131 : }
132 :
133 : /* Set up the callbacks as appropriate. */
134 : void
135 6772 : init_pp_output (FILE *out_stream)
136 : {
137 6772 : cpp_callbacks *cb = cpp_get_callbacks (parse_in);
138 :
139 6772 : if (!flag_no_output)
140 : {
141 6665 : cb->line_change = cb_line_change;
142 6665 : if (should_output_pragmas ())
143 : {
144 5685 : cb->ident = cb_ident;
145 5685 : cb->def_pragma = cb_def_pragma;
146 : }
147 : }
148 :
149 6772 : if (flag_dump_includes)
150 1 : cb->include = cb_include;
151 :
152 6772 : if (flag_pch_preprocess)
153 : {
154 468 : cb->valid_pch = c_common_valid_pch;
155 468 : cb->read_pch = cb_read_pch;
156 : }
157 :
158 6772 : if (flag_dump_macros == 'N' || flag_dump_macros == 'D')
159 : {
160 214 : cb->define = cb_define;
161 214 : cb->undef = cb_undef;
162 : }
163 :
164 6772 : 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 6772 : cb->has_attribute = c_common_has_attribute;
172 6772 : cb->has_builtin = c_common_has_builtin;
173 6772 : cb->has_feature = c_common_has_feature;
174 6772 : cb->get_source_date_epoch = cb_get_source_date_epoch;
175 6772 : cb->get_suggestion = cb_get_suggestion;
176 6772 : cb->remap_filename = remap_macro_filename;
177 :
178 : /* Initialize the print structure. */
179 6772 : print.src_line = 1;
180 6772 : print.printed = false;
181 6772 : print.prev = 0;
182 6772 : print.outf = out_stream;
183 6772 : print.first_time = 1;
184 6772 : print.src_file = "";
185 6772 : print.prev_was_system_token = false;
186 6772 : print.streamer = nullptr;
187 6772 : }
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 3750 : token_streamer (cpp_reader *pfile)
200 3750 : :avoid_paste (false),
201 7500 : do_line_adjustments (cpp_get_options (pfile)->lang != CLK_ASM
202 3750 : && !flag_no_line_commands),
203 3750 : in_pragma (false)
204 : {
205 3750 : gcc_assert (!print.streamer);
206 3750 : print.streamer = this;
207 3750 : }
208 :
209 162 : void begin_pragma ()
210 : {
211 162 : in_pragma = true;
212 162 : }
213 :
214 : void stream (cpp_reader *pfile, const cpp_token *tok, location_t);
215 : };
216 :
217 : void
218 35740083 : 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 35740083 : input_location = loc;
224 :
225 35740083 : if (token->type == CPP_PADDING)
226 : {
227 2437823 : avoid_paste = true;
228 2437823 : if (print.source == NULL
229 316813 : || (!(print.source->flags & PREV_WHITE)
230 106465 : && token->val.source == NULL))
231 2149806 : print.source = token->val.source;
232 2437823 : return;
233 : }
234 :
235 33302260 : if (token->type == CPP_EOF)
236 : return;
237 :
238 : /* Keep track when we move into and out of system locations. */
239 33298773 : const bool is_system_token = in_system_header_at (loc);
240 33298773 : const bool system_state_changed
241 33298773 : = (is_system_token != print.prev_was_system_token);
242 33298773 : print.prev_was_system_token = is_system_token;
243 :
244 : /* Subtle logic to output a space if and only if necessary. */
245 33298773 : bool line_marker_emitted = false;
246 33298773 : if (avoid_paste)
247 : {
248 1568037 : unsigned src_line = LOCATION_LINE (loc);
249 :
250 1568037 : if (print.source == NULL)
251 665654 : print.source = token;
252 :
253 1568037 : if (src_line != print.src_line
254 5386 : && do_line_adjustments
255 5348 : && !in_pragma)
256 : {
257 5331 : line_marker_emitted = do_line_change (pfile, token, loc, false);
258 5331 : putc (' ', print.outf);
259 5331 : print.printed = true;
260 : }
261 1562706 : else if (print.source->flags & PREV_WHITE
262 548657 : || (print.prev
263 471504 : && cpp_avoid_paste (pfile, print.prev, token))
264 2109317 : || (print.prev == NULL && token->type == CPP_HASH))
265 : {
266 1016112 : putc (' ', print.outf);
267 1016112 : print.printed = true;
268 : }
269 : }
270 31730736 : else if (token->flags & PREV_WHITE && token->type != CPP_PRAGMA)
271 : {
272 13678538 : unsigned src_line = LOCATION_LINE (loc);
273 :
274 13678538 : if (src_line != print.src_line
275 7331 : && do_line_adjustments
276 507 : && !in_pragma)
277 381 : line_marker_emitted = do_line_change (pfile, token, loc, false);
278 13678538 : putc (' ', print.outf);
279 13678538 : print.printed = true;
280 : }
281 :
282 33298773 : avoid_paste = false;
283 33298773 : print.source = NULL;
284 33298773 : print.prev = token;
285 33298773 : if (token->type == CPP_PRAGMA)
286 : {
287 33384 : in_pragma = true;
288 33384 : if (should_output_pragmas ())
289 : {
290 33384 : const char *space;
291 33384 : const char *name;
292 :
293 33384 : line_marker_emitted = maybe_print_line (token->src_loc);
294 33384 : fputs ("#pragma ", print.outf);
295 33384 : c_pp_lookup_pragma (token->val.pragma, &space, &name);
296 33384 : if (space)
297 33366 : fprintf (print.outf, "%s %s", space, name);
298 : else
299 18 : fprintf (print.outf, "%s", name);
300 33384 : print.printed = true;
301 : }
302 33384 : if (token->val.pragma >= PRAGMA_FIRST_EXTERNAL)
303 33290 : c_pp_invoke_early_pragma_handler (token->val.pragma);
304 : }
305 33265389 : else if (token->type == CPP_PRAGMA_EOL)
306 : {
307 33546 : if (should_output_pragmas ())
308 33546 : maybe_print_line (UNKNOWN_LOCATION);
309 33546 : in_pragma = false;
310 : }
311 33231843 : 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 33231713 : if (cpp_get_options (parse_in)->debug)
368 3 : linemap_dump_location (line_table, token->src_loc, print.outf);
369 :
370 33231713 : if (do_line_adjustments
371 32758527 : && !in_pragma
372 32713767 : && !line_marker_emitted
373 32713767 : && system_state_changed
374 33244872 : && !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 13158 : line_marker_emitted = do_line_change (pfile, token, loc, false);
380 : }
381 33231713 : if (!in_pragma || should_output_pragmas ())
382 : {
383 33231713 : cpp_output_token (token, print.outf);
384 33231713 : 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 33298643 : if (cpp_token_val_index (token) == CPP_TOKEN_FLD_STR)
393 701691 : 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 3663 : scan_translation_unit (cpp_reader *pfile)
401 : {
402 3663 : token_streamer streamer (pfile);
403 3663 : uintptr_t filter = 0;
404 :
405 3663 : if (lang_hooks.preprocess_token)
406 1297 : filter = lang_hooks.preprocess_token (pfile, NULL, filter);
407 :
408 3663 : print.source = NULL;
409 71321115 : for (;;)
410 : {
411 35662389 : location_t spelling_loc;
412 35662389 : const cpp_token *token
413 35662389 : = cpp_get_token_with_location (pfile, &spelling_loc);
414 :
415 35662213 : streamer.stream (pfile, token, spelling_loc);
416 35662213 : if (filter)
417 : {
418 763255 : unsigned flags = lang_hooks.preprocess_token (pfile, token, filter);
419 763255 : if (flags & lang_hooks::PT_begin_pragma)
420 132 : streamer.begin_pragma ();
421 : }
422 35662213 : if (token->type == CPP_EOF)
423 : break;
424 35658726 : }
425 :
426 3487 : if (filter)
427 117 : lang_hooks.preprocess_token (pfile, NULL, filter);
428 3487 : }
429 :
430 : class do_streamer : public token_streamer
431 : {
432 : public:
433 : uintptr_t filter;
434 :
435 87 : do_streamer (cpp_reader *pfile, uintptr_t filter)
436 174 : :token_streamer (pfile), filter (filter)
437 : {
438 : }
439 : };
440 :
441 : static void
442 122365 : directives_only_cb (cpp_reader *pfile, CPP_DO_task task, void *data_, ...)
443 : {
444 122365 : va_list args;
445 122365 : va_start (args, data_);
446 :
447 122365 : do_streamer *streamer = reinterpret_cast <do_streamer *> (data_);
448 122365 : switch (task)
449 : {
450 0 : default:
451 0 : gcc_unreachable ();
452 :
453 31237 : case CPP_DO_print:
454 31237 : if (!flag_no_output)
455 : {
456 31126 : print.src_line += va_arg (args, unsigned);
457 :
458 31126 : const void *buf = va_arg (args, const void *);
459 31126 : size_t size = va_arg (args, size_t);
460 31126 : fwrite (buf, 1, size, print.outf);
461 : }
462 : break;
463 :
464 89633 : case CPP_DO_location:
465 89633 : if (!flag_no_output)
466 89384 : maybe_print_line (va_arg (args, location_t));
467 : break;
468 :
469 1495 : case CPP_DO_token:
470 1495 : {
471 1495 : const cpp_token *token = va_arg (args, const cpp_token *);
472 1495 : unsigned flags = 0;
473 1495 : if (streamer->filter)
474 270 : flags = lang_hooks.preprocess_token (pfile, token, streamer->filter);
475 1495 : if (!flag_no_output)
476 : {
477 1363 : location_t spelling_loc = va_arg (args, location_t);
478 1363 : streamer->stream (pfile, token, spelling_loc);
479 1363 : if (flags & lang_hooks::PT_begin_pragma)
480 30 : streamer->begin_pragma ();
481 : }
482 : }
483 : break;
484 : }
485 :
486 122365 : va_end (args);
487 122365 : }
488 :
489 : /* Writes out the preprocessed file, handling spacing and paste
490 : avoidance issues. */
491 : static void
492 87 : scan_translation_unit_directives_only (cpp_reader *pfile)
493 : {
494 87 : uintptr_t filter = 0;
495 87 : if (lang_hooks.preprocess_token)
496 69 : filter = lang_hooks.preprocess_token (pfile, NULL, filter);
497 87 : do_streamer streamer (pfile, filter);
498 87 : cpp_directive_only_process (pfile, &streamer, directives_only_cb);
499 87 : if (streamer.filter)
500 24 : lang_hooks.preprocess_token (pfile, NULL, streamer.filter);
501 87 : }
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 701866 : account_for_newlines (const unsigned char *str, size_t len)
514 : {
515 3589756 : while (len--)
516 2887890 : if (*str++ == '\n')
517 654 : print.src_line++;
518 701866 : }
519 :
520 : /* Writes out a traditionally preprocessed file. */
521 : static void
522 2925 : scan_translation_unit_trad (cpp_reader *pfile)
523 : {
524 535270 : while (_cpp_read_logical_line_trad (pfile))
525 : {
526 529420 : size_t len = pfile->out.cur - pfile->out.base;
527 529420 : maybe_print_line (pfile->out.first_line);
528 529420 : fwrite (pfile->out.base, 1, len, print.outf);
529 529420 : print.printed = true;
530 529420 : if (!CPP_OPTION (pfile, discard_comments))
531 175 : account_for_newlines (pfile->out.base, len);
532 : }
533 2925 : }
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 5958386 : maybe_print_line_1 (location_t src_loc, FILE *stream)
542 : {
543 5958386 : bool emitted_line_marker = false;
544 5958386 : unsigned src_line = LOCATION_LINE (src_loc);
545 5958386 : const char *src_file = LOCATION_FILE (src_loc);
546 :
547 : /* End the previous line of text. */
548 5958386 : if (print.printed)
549 : {
550 5476974 : putc ('\n', stream);
551 5476974 : print.src_line++;
552 5476974 : print.printed = false;
553 : }
554 :
555 5958386 : if (!flag_no_line_commands
556 5946625 : && src_line >= print.src_line
557 5805420 : && src_line < print.src_line + 8
558 5634487 : && src_loc != UNKNOWN_LOCATION
559 5634485 : && strcmp (src_file, print.src_file) == 0)
560 : {
561 7621406 : while (src_line > print.src_line)
562 : {
563 1986927 : putc ('\n', stream);
564 1986927 : print.src_line++;
565 : }
566 : }
567 : else
568 323907 : emitted_line_marker = print_line_1 (src_loc, "", stream);
569 :
570 5958386 : 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 5958386 : maybe_print_line (location_t src_loc)
580 : {
581 5958386 : if (cpp_get_options (parse_in)->debug)
582 2 : linemap_dump_location (line_table, src_loc,
583 : print.outf);
584 5958386 : 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 469941 : print_line_1 (location_t src_loc, const char *special_flags, FILE *stream)
593 : {
594 469941 : bool emitted_line_marker = false;
595 :
596 : /* End any previous line of text. */
597 469941 : if (print.printed)
598 22775 : putc ('\n', stream);
599 469941 : print.printed = false;
600 :
601 469941 : if (src_loc != UNKNOWN_LOCATION && !flag_no_line_commands)
602 : {
603 424634 : const char *file_path = LOCATION_FILE (src_loc);
604 424634 : size_t to_file_len = strlen (file_path);
605 424634 : unsigned char *to_file_quoted =
606 424634 : (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 424634 : unsigned char *p = cpp_quote_string (to_file_quoted,
611 : (const unsigned char *) file_path,
612 : to_file_len);
613 424634 : *p = '\0';
614 :
615 424634 : print.src_line = LOCATION_LINE (src_loc);
616 424634 : print.src_file = file_path;
617 :
618 424634 : fprintf (stream, "# %u \"%s\"%s",
619 : print.src_line, to_file_quoted, special_flags);
620 :
621 424634 : int sysp = in_system_header_at (src_loc);
622 424634 : if (sysp == 2)
623 0 : fputs (" 3 4", stream);
624 424634 : else if (sysp == 1)
625 162030 : fputs (" 3", stream);
626 :
627 424634 : putc ('\n', stream);
628 424634 : emitted_line_marker = true;
629 : }
630 :
631 469941 : 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 146034 : print_line (location_t src_loc, const char *special_flags)
640 : {
641 146034 : if (cpp_get_options (parse_in)->debug)
642 6 : linemap_dump_location (line_table, src_loc,
643 : print.outf);
644 146034 : 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 4996383 : do_line_change (cpp_reader *pfile, const cpp_token *token,
651 : location_t src_loc, int parsing_args)
652 : {
653 4996383 : bool emitted_line_marker = false;
654 4996383 : if (define_queue || undef_queue)
655 21 : dump_queued_macros (pfile);
656 :
657 4996383 : if (token->type == CPP_EOF || parsing_args)
658 : return false;
659 :
660 4974151 : emitted_line_marker = maybe_print_line (src_loc);
661 4974151 : print.prev = 0;
662 4974151 : 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 4974151 : if (!CPP_OPTION (pfile, traditional) && token->type != CPP_PRAGMA)
674 : {
675 4940885 : int spaces = LOCATION_COLUMN (src_loc) - 2;
676 4940885 : print.printed = true;
677 :
678 18924518 : while (-- spaces >= 0)
679 13983633 : 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 4977513 : cb_line_change (cpp_reader *pfile, const cpp_token *token,
689 : int parsing_args)
690 : {
691 4977513 : do_line_change (pfile, token, token->src_loc, parsing_args);
692 4977513 : }
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 205945 : cb_define (cpp_reader *pfile, location_t line, cpp_hashnode *node)
705 : {
706 205945 : const line_map_ordinary *map;
707 :
708 205945 : maybe_print_line (line);
709 205945 : fputs ("#define ", print.outf);
710 :
711 : /* 'D' is whole definition; 'N' is name only. */
712 205945 : if (flag_dump_macros == 'D')
713 52693 : fputs ((const char *) cpp_macro_definition (pfile, node),
714 : print.outf);
715 : else
716 153252 : fputs ((const char *) NODE_NAME (node), print.outf);
717 :
718 205945 : putc ('\n', print.outf);
719 205945 : print.printed = false;
720 205945 : linemap_resolve_location (line_table, line,
721 : LRK_MACRO_DEFINITION_LOCATION,
722 : &map);
723 205945 : print.src_line++;
724 205945 : }
725 :
726 : static void
727 27647 : cb_undef (cpp_reader *pfile, location_t line, cpp_hashnode *node)
728 : {
729 27647 : if (lang_hooks.preprocess_undef)
730 0 : lang_hooks.preprocess_undef (pfile, line, node);
731 27647 : maybe_print_line (line);
732 27647 : fprintf (print.outf, "#undef %s\n", NODE_NAME (node));
733 27647 : print.src_line++;
734 27647 : }
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 2245 : pp_dir_change (cpp_reader *pfile ATTRIBUTE_UNUSED, const char *dir)
834 : {
835 2245 : size_t to_file_len = strlen (dir);
836 2245 : unsigned char *to_file_quoted =
837 2245 : (unsigned char *) alloca (to_file_len * 4 + 1);
838 2245 : unsigned char *p;
839 :
840 : /* cpp_quote_string does not nul-terminate, so we have to do it ourselves. */
841 2245 : p = cpp_quote_string (to_file_quoted, (const unsigned char *) dir, to_file_len);
842 2245 : *p = '\0';
843 2245 : fprintf (print.outf, "# 1 \"%s//\"\n", to_file_quoted);
844 2245 : }
845 :
846 : /* The file name, line number or system header flags have changed, as
847 : described in MAP. */
848 :
849 : void
850 157702 : pp_file_change (const line_map_ordinary *map)
851 : {
852 157702 : const char *flags = "";
853 :
854 157702 : if (flag_no_line_commands)
855 : return;
856 :
857 152480 : if (map != NULL)
858 : {
859 146044 : input_location = map->start_location;
860 146044 : if (print.first_time)
861 : {
862 : /* Avoid printing foo.i when the main file is foo.c. */
863 6622 : if (!cpp_get_options (parse_in)->preprocessed)
864 6612 : print_line (map->start_location, flags);
865 6622 : print.first_time = 0;
866 : }
867 : else
868 : {
869 : /* Bring current file to correct line when entering a new file. */
870 139422 : if (map->reason == LC_ENTER)
871 : {
872 59640 : maybe_print_line (linemap_included_from (map));
873 59640 : flags = " 1";
874 : }
875 79782 : else if (map->reason == LC_LEAVE)
876 59636 : flags = " 2";
877 139422 : print_line (map->start_location, flags);
878 : }
879 : }
880 : }
881 :
882 : /* Copy a #pragma directive to the preprocessed output. */
883 : static void
884 5006 : cb_def_pragma (cpp_reader *pfile, location_t line)
885 : {
886 5006 : maybe_print_line (line);
887 5006 : fputs ("#pragma ", print.outf);
888 5006 : cpp_output_line (pfile, print.outf);
889 5006 : print.printed = false;
890 5006 : print.src_line++;
891 5006 : }
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 76507 : c_pp_stream_token (cpp_reader *pfile, const cpp_token *tok, location_t loc)
898 : {
899 76507 : gcc_assert (print.streamer);
900 76507 : print.streamer->stream (pfile, tok, loc);
901 76507 : }
902 :
903 : /* Dump out the hash table. */
904 : static int
905 343524 : dump_macro (cpp_reader *pfile, cpp_hashnode *node, void *v ATTRIBUTE_UNUSED)
906 : {
907 343524 : if (cpp_user_macro_p (node))
908 : {
909 54531 : fputs ("#define ", print.outf);
910 54531 : fputs ((const char *) cpp_macro_definition (pfile, node),
911 : print.outf);
912 54531 : putc ('\n', print.outf);
913 54531 : print.printed = false;
914 54531 : print.src_line++;
915 : }
916 :
917 343524 : 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 : }
|