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 6780 : 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 6780 : if (flag_no_output && pfile->buffer)
94 : {
95 110 : if (flag_modules)
96 : {
97 : /* For macros from imported headers we need directives_only_cb. */
98 18 : 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 6670 : else if (cpp_get_options (pfile)->traditional)
109 2925 : scan_translation_unit_trad (pfile);
110 3745 : 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 3673 : scan_translation_unit (pfile);
115 :
116 : /* -dM command line option. Should this be elsewhere? */
117 6604 : if (flag_dump_macros == 'M')
118 80 : cpp_forall_identifiers (pfile, dump_macro, NULL);
119 :
120 : /* Flush any pending output. */
121 6604 : if (print.printed)
122 4777 : putc ('\n', print.outf);
123 6604 : }
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 120953 : should_output_pragmas ()
129 : {
130 120953 : return cpp_get_options (parse_in)->lang != CLK_ASM;
131 : }
132 :
133 : /* Set up the callbacks as appropriate. */
134 : void
135 6785 : init_pp_output (FILE *out_stream)
136 : {
137 6785 : cpp_callbacks *cb = cpp_get_callbacks (parse_in);
138 :
139 6785 : if (!flag_no_output)
140 : {
141 6675 : cb->line_change = cb_line_change;
142 6675 : if (should_output_pragmas ())
143 : {
144 5696 : cb->ident = cb_ident;
145 5696 : cb->def_pragma = cb_def_pragma;
146 : }
147 : }
148 :
149 6785 : if (flag_dump_includes)
150 1 : cb->include = cb_include;
151 :
152 6785 : if (flag_pch_preprocess)
153 : {
154 470 : cb->valid_pch = c_common_valid_pch;
155 470 : cb->read_pch = cb_read_pch;
156 : }
157 :
158 6785 : if (flag_dump_macros == 'N' || flag_dump_macros == 'D')
159 : {
160 232 : cb->define = cb_define;
161 232 : cb->undef = cb_undef;
162 : }
163 :
164 6785 : 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 6785 : cb->has_attribute = c_common_has_attribute;
172 6785 : cb->has_builtin = c_common_has_builtin;
173 6785 : cb->has_feature = c_common_has_feature;
174 6785 : cb->get_source_date_epoch = cb_get_source_date_epoch;
175 6785 : cb->get_suggestion = cb_get_suggestion;
176 6785 : cb->remap_filename = remap_macro_filename;
177 :
178 : /* Initialize the print structure. */
179 6785 : print.src_line = 1;
180 6785 : print.printed = false;
181 6785 : print.prev = 0;
182 6785 : print.outf = out_stream;
183 6785 : print.first_time = 1;
184 6785 : print.src_file = "";
185 6785 : print.prev_was_system_token = false;
186 6785 : print.streamer = nullptr;
187 6785 : }
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 3763 : token_streamer (cpp_reader *pfile)
200 3763 : :avoid_paste (false),
201 7526 : do_line_adjustments (cpp_get_options (pfile)->lang != CLK_ASM
202 3763 : && !flag_no_line_commands),
203 3763 : in_pragma (false)
204 : {
205 3763 : gcc_assert (!print.streamer);
206 3763 : print.streamer = this;
207 3763 : }
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 36286941 : 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 36286941 : input_location = loc;
224 :
225 36286941 : if (token->type == CPP_PADDING)
226 : {
227 2488526 : avoid_paste = true;
228 2488526 : if (print.source == NULL
229 323094 : || (!(print.source->flags & PREV_WHITE)
230 108188 : && token->val.source == NULL))
231 2195074 : print.source = token->val.source;
232 2488526 : return;
233 : }
234 :
235 33798415 : if (token->type == CPP_EOF)
236 : return;
237 :
238 : /* Keep track when we move into and out of system locations. */
239 33794918 : const bool is_system_token = in_system_header_at (loc);
240 33794918 : const bool system_state_changed
241 33794918 : = (is_system_token != print.prev_was_system_token);
242 33794918 : print.prev_was_system_token = is_system_token;
243 :
244 : /* Subtle logic to output a space if and only if necessary. */
245 33794918 : bool line_marker_emitted = false;
246 33794918 : if (avoid_paste)
247 : {
248 1601927 : unsigned src_line = LOCATION_LINE (loc);
249 :
250 1601927 : if (print.source == NULL)
251 680368 : print.source = token;
252 :
253 1601927 : if (src_line != print.src_line
254 5586 : && do_line_adjustments
255 5548 : && !in_pragma)
256 : {
257 5531 : line_marker_emitted = do_line_change (pfile, token, loc, false);
258 5531 : putc (' ', print.outf);
259 5531 : print.printed = true;
260 : }
261 1596396 : else if (print.source->flags & PREV_WHITE
262 561470 : || (print.prev
263 481869 : && cpp_avoid_paste (pfile, print.prev, token))
264 2155805 : || (print.prev == NULL && token->type == CPP_HASH))
265 : {
266 1037004 : putc (' ', print.outf);
267 1037004 : print.printed = true;
268 : }
269 : }
270 32192991 : else if (token->flags & PREV_WHITE && token->type != CPP_PRAGMA)
271 : {
272 13880636 : unsigned src_line = LOCATION_LINE (loc);
273 :
274 13880636 : if (src_line != print.src_line
275 7365 : && do_line_adjustments
276 507 : && !in_pragma)
277 381 : line_marker_emitted = do_line_change (pfile, token, loc, false);
278 13880636 : putc (' ', print.outf);
279 13880636 : print.printed = true;
280 : }
281 :
282 33794918 : avoid_paste = false;
283 33794918 : print.source = NULL;
284 33794918 : print.prev = token;
285 33794918 : if (token->type == CPP_PRAGMA)
286 : {
287 34153 : in_pragma = true;
288 34153 : if (should_output_pragmas ())
289 : {
290 34153 : const char *space;
291 34153 : const char *name;
292 :
293 34153 : line_marker_emitted = maybe_print_line (token->src_loc);
294 34153 : fputs ("#pragma ", print.outf);
295 34153 : c_pp_lookup_pragma (token->val.pragma, &space, &name);
296 34153 : if (space)
297 34135 : fprintf (print.outf, "%s %s", space, name);
298 : else
299 18 : fprintf (print.outf, "%s", name);
300 34153 : print.printed = true;
301 : }
302 34153 : if (token->val.pragma >= PRAGMA_FIRST_EXTERNAL)
303 34059 : c_pp_invoke_early_pragma_handler (token->val.pragma);
304 : }
305 33760765 : else if (token->type == CPP_PRAGMA_EOL)
306 : {
307 34315 : if (should_output_pragmas ())
308 34315 : maybe_print_line (UNKNOWN_LOCATION);
309 34315 : in_pragma = false;
310 : }
311 33726450 : 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 33726320 : if (cpp_get_options (parse_in)->debug)
368 3 : linemap_dump_location (line_table, token->src_loc, print.outf);
369 :
370 33726320 : if (do_line_adjustments
371 33253003 : && !in_pragma
372 33207193 : && !line_marker_emitted
373 33207193 : && system_state_changed
374 33739817 : && !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 13496 : line_marker_emitted = do_line_change (pfile, token, loc, false);
380 : }
381 33726320 : if (!in_pragma || should_output_pragmas ())
382 : {
383 33726320 : cpp_output_token (token, print.outf);
384 33726320 : 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 33794788 : if (cpp_token_val_index (token) == CPP_TOKEN_FLD_STR)
393 710912 : 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 3673 : scan_translation_unit (cpp_reader *pfile)
401 : {
402 3673 : token_streamer streamer (pfile);
403 3673 : uintptr_t filter = 0;
404 :
405 3673 : if (lang_hooks.preprocess_token)
406 1306 : filter = lang_hooks.preprocess_token (pfile, NULL, filter);
407 :
408 3673 : print.source = NULL;
409 72411183 : for (;;)
410 : {
411 36207428 : location_t spelling_loc;
412 36207428 : const cpp_token *token
413 36207428 : = cpp_get_token_with_location (pfile, &spelling_loc);
414 :
415 36207252 : streamer.stream (pfile, token, spelling_loc);
416 36207252 : if (filter)
417 : {
418 763835 : unsigned flags = lang_hooks.preprocess_token (pfile, token, filter);
419 763835 : if (flags & lang_hooks::PT_begin_pragma)
420 132 : streamer.begin_pragma ();
421 : }
422 36207252 : if (token->type == CPP_EOF)
423 : break;
424 36203755 : }
425 :
426 3497 : if (filter)
427 117 : lang_hooks.preprocess_token (pfile, NULL, filter);
428 3497 : }
429 :
430 : class do_streamer : public token_streamer
431 : {
432 : public:
433 : uintptr_t filter;
434 :
435 90 : do_streamer (cpp_reader *pfile, uintptr_t filter)
436 180 : :token_streamer (pfile), filter (filter)
437 : {
438 : }
439 : };
440 :
441 : static void
442 127764 : directives_only_cb (cpp_reader *pfile, CPP_DO_task task, void *data_, ...)
443 : {
444 127764 : va_list args;
445 127764 : va_start (args, data_);
446 :
447 127764 : do_streamer *streamer = reinterpret_cast <do_streamer *> (data_);
448 127764 : switch (task)
449 : {
450 0 : default:
451 0 : gcc_unreachable ();
452 :
453 32349 : case CPP_DO_print:
454 32349 : if (!flag_no_output)
455 : {
456 32217 : print.src_line += va_arg (args, unsigned);
457 :
458 32217 : const void *buf = va_arg (args, const void *);
459 32217 : size_t size = va_arg (args, size_t);
460 32217 : fwrite (buf, 1, size, print.outf);
461 : }
462 : break;
463 :
464 93908 : case CPP_DO_location:
465 93908 : if (!flag_no_output)
466 93611 : maybe_print_line (va_arg (args, location_t));
467 : break;
468 :
469 1507 : case CPP_DO_token:
470 1507 : {
471 1507 : const cpp_token *token = va_arg (args, const cpp_token *);
472 1507 : unsigned flags = 0;
473 1507 : if (streamer->filter)
474 282 : flags = lang_hooks.preprocess_token (pfile, token, streamer->filter);
475 1507 : 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 127764 : va_end (args);
487 127764 : }
488 :
489 : /* Writes out the preprocessed file, handling spacing and paste
490 : avoidance issues. */
491 : static void
492 90 : scan_translation_unit_directives_only (cpp_reader *pfile)
493 : {
494 90 : uintptr_t filter = 0;
495 90 : if (lang_hooks.preprocess_token)
496 72 : filter = lang_hooks.preprocess_token (pfile, NULL, filter);
497 90 : do_streamer streamer (pfile, filter);
498 90 : cpp_directive_only_process (pfile, &streamer, directives_only_cb);
499 90 : if (streamer.filter)
500 27 : lang_hooks.preprocess_token (pfile, NULL, streamer.filter);
501 90 : }
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 711087 : account_for_newlines (const unsigned char *str, size_t len)
514 : {
515 3639689 : while (len--)
516 2928602 : if (*str++ == '\n')
517 654 : print.src_line++;
518 711087 : }
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 6068834 : maybe_print_line_1 (location_t src_loc, FILE *stream)
542 : {
543 6068834 : bool emitted_line_marker = false;
544 6068834 : unsigned src_line = LOCATION_LINE (src_loc);
545 6068834 : const char *src_file = LOCATION_FILE (src_loc);
546 :
547 : /* End the previous line of text. */
548 6068834 : if (print.printed)
549 : {
550 5551200 : putc ('\n', stream);
551 5551200 : print.src_line++;
552 5551200 : print.printed = false;
553 : }
554 :
555 6068834 : if (!flag_no_line_commands
556 6057038 : && src_line >= print.src_line
557 5906041 : && src_line < print.src_line + 8
558 5729040 : && src_loc != UNKNOWN_LOCATION
559 5729038 : && strcmp (src_file, print.src_file) == 0)
560 : {
561 7787859 : while (src_line > print.src_line)
562 : {
563 2058827 : putc ('\n', stream);
564 2058827 : print.src_line++;
565 : }
566 : }
567 : else
568 339802 : emitted_line_marker = print_line_1 (src_loc, "", stream);
569 :
570 6068834 : 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 6068834 : maybe_print_line (location_t src_loc)
580 : {
581 6068834 : if (cpp_get_options (parse_in)->debug)
582 2 : linemap_dump_location (line_table, src_loc,
583 : print.outf);
584 6068834 : 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 489081 : print_line_1 (location_t src_loc, const char *special_flags, FILE *stream)
593 : {
594 489081 : bool emitted_line_marker = false;
595 :
596 : /* End any previous line of text. */
597 489081 : if (print.printed)
598 23434 : putc ('\n', stream);
599 489081 : print.printed = false;
600 :
601 489081 : if (src_loc != UNKNOWN_LOCATION && !flag_no_line_commands)
602 : {
603 442970 : const char *file_path = LOCATION_FILE (src_loc);
604 442970 : size_t to_file_len = strlen (file_path);
605 442970 : unsigned char *to_file_quoted =
606 442970 : (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 442970 : unsigned char *p = cpp_quote_string (to_file_quoted,
611 : (const unsigned char *) file_path,
612 : to_file_len);
613 442970 : *p = '\0';
614 :
615 442970 : print.src_line = LOCATION_LINE (src_loc);
616 442970 : print.src_file = file_path;
617 :
618 442970 : fprintf (stream, "# %u \"%s\"%s",
619 : print.src_line, to_file_quoted, special_flags);
620 :
621 442970 : int sysp = in_system_header_at (src_loc);
622 442970 : if (sysp == 2)
623 0 : fputs (" 3 4", stream);
624 442970 : else if (sysp == 1)
625 167611 : fputs (" 3", stream);
626 :
627 442970 : putc ('\n', stream);
628 442970 : emitted_line_marker = true;
629 : }
630 :
631 489081 : 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 149279 : print_line (location_t src_loc, const char *special_flags)
640 : {
641 149279 : if (cpp_get_options (parse_in)->debug)
642 6 : linemap_dump_location (line_table, src_loc,
643 : print.outf);
644 149279 : 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 5071596 : do_line_change (cpp_reader *pfile, const cpp_token *token,
651 : location_t src_loc, int parsing_args)
652 : {
653 5071596 : bool emitted_line_marker = false;
654 5071596 : if (define_queue || undef_queue)
655 21 : dump_queued_macros (pfile);
656 :
657 5071596 : if (token->type == CPP_EOF || parsing_args)
658 : return false;
659 :
660 5049029 : emitted_line_marker = maybe_print_line (src_loc);
661 5049029 : print.prev = 0;
662 5049029 : 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 5049029 : if (!CPP_OPTION (pfile, traditional) && token->type != CPP_PRAGMA)
674 : {
675 5014994 : int spaces = LOCATION_COLUMN (src_loc) - 2;
676 5014994 : print.printed = true;
677 :
678 19205658 : while (-- spaces >= 0)
679 14190664 : 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 5052188 : cb_line_change (cpp_reader *pfile, const cpp_token *token,
689 : int parsing_args)
690 : {
691 5052188 : do_line_change (pfile, token, token->src_loc, parsing_args);
692 5052188 : }
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 231660 : cb_define (cpp_reader *pfile, location_t line, cpp_hashnode *node)
705 : {
706 231660 : const line_map_ordinary *map;
707 :
708 231660 : maybe_print_line (line);
709 231660 : fputs ("#define ", print.outf);
710 :
711 : /* 'D' is whole definition; 'N' is name only. */
712 231660 : if (flag_dump_macros == 'D')
713 52866 : fputs ((const char *) cpp_macro_definition (pfile, node),
714 : print.outf);
715 : else
716 178794 : fputs ((const char *) NODE_NAME (node), print.outf);
717 :
718 231660 : putc ('\n', print.outf);
719 231660 : print.printed = false;
720 231660 : linemap_resolve_location (line_table, line,
721 : LRK_MACRO_DEFINITION_LOCATION,
722 : &map);
723 231660 : print.src_line++;
724 231660 : }
725 :
726 : static void
727 30019 : cb_undef (cpp_reader *pfile, location_t line, cpp_hashnode *node)
728 : {
729 30019 : if (lang_hooks.preprocess_undef)
730 0 : lang_hooks.preprocess_undef (pfile, line, node);
731 30019 : maybe_print_line (line);
732 30019 : fprintf (print.outf, "#undef %s\n", NODE_NAME (node));
733 30019 : print.src_line++;
734 30019 : }
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 2252 : pp_dir_change (cpp_reader *pfile ATTRIBUTE_UNUSED, const char *dir)
834 : {
835 2252 : size_t to_file_len = strlen (dir);
836 2252 : unsigned char *to_file_quoted =
837 2252 : (unsigned char *) alloca (to_file_len * 4 + 1);
838 2252 : unsigned char *p;
839 :
840 : /* cpp_quote_string does not nul-terminate, so we have to do it ourselves. */
841 2252 : p = cpp_quote_string (to_file_quoted, (const unsigned char *) dir, to_file_len);
842 2252 : *p = '\0';
843 2252 : fprintf (print.outf, "# 1 \"%s//\"\n", to_file_quoted);
844 2252 : }
845 :
846 : /* The file name, line number or system header flags have changed, as
847 : described in MAP. */
848 :
849 : void
850 160978 : pp_file_change (const line_map_ordinary *map)
851 : {
852 160978 : const char *flags = "";
853 :
854 160978 : if (flag_no_line_commands)
855 : return;
856 :
857 155735 : if (map != NULL)
858 : {
859 149289 : input_location = map->start_location;
860 149289 : if (print.first_time)
861 : {
862 : /* Avoid printing foo.i when the main file is foo.c. */
863 6632 : if (!cpp_get_options (parse_in)->preprocessed)
864 6622 : print_line (map->start_location, flags);
865 6632 : print.first_time = 0;
866 : }
867 : else
868 : {
869 : /* Bring current file to correct line when entering a new file. */
870 142657 : if (map->reason == LC_ENTER)
871 : {
872 61242 : maybe_print_line (linemap_included_from (map));
873 61242 : flags = " 1";
874 : }
875 81415 : else if (map->reason == LC_LEAVE)
876 61238 : flags = " 2";
877 142657 : print_line (map->start_location, flags);
878 : }
879 : }
880 : }
881 :
882 : /* Copy a #pragma directive to the preprocessed output. */
883 : static void
884 5122 : cb_def_pragma (cpp_reader *pfile, location_t line)
885 : {
886 5122 : maybe_print_line (line);
887 5122 : fputs ("#pragma ", print.outf);
888 5122 : cpp_output_line (pfile, print.outf);
889 5122 : print.printed = false;
890 5122 : print.src_line++;
891 5122 : }
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 78326 : c_pp_stream_token (cpp_reader *pfile, const cpp_token *tok, location_t loc)
898 : {
899 78326 : gcc_assert (print.streamer);
900 78326 : print.streamer->stream (pfile, tok, loc);
901 78326 : }
902 :
903 : /* Dump out the hash table. */
904 : static int
905 343536 : dump_macro (cpp_reader *pfile, cpp_hashnode *node, void *v ATTRIBUTE_UNUSED)
906 : {
907 343536 : if (cpp_user_macro_p (node))
908 : {
909 54532 : fputs ("#define ", print.outf);
910 54532 : fputs ((const char *) cpp_macro_definition (pfile, node),
911 : print.outf);
912 54532 : putc ('\n', print.outf);
913 54532 : print.printed = false;
914 54532 : print.src_line++;
915 : }
916 :
917 343536 : 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 : }
|