1 /* Preprocess only, using cpplib. 2 Copyright (C) 1995-2022 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 /* Encapsulates state used to convert a stream of tokens into a text 29 file. */ 30 static struct 31 { 32 FILE *outf; /* Stream to write to. */ 33 const cpp_token *prev; /* Previous token. */ 34 const cpp_token *source; /* Source token for spacing. */ 35 unsigned src_line; /* Line number currently being written. */ 36 bool printed; /* True if something output at line. */ 37 bool first_time; /* pp_file_change hasn't been called yet. */ 38 bool prev_was_system_token; /* True if the previous token was a 39 system token.*/ 40 const char *src_file; /* Current source file. */ 41 } print; 42 43 /* Defined and undefined macros being queued for output with -dU at 44 the next newline. */ 45 struct macro_queue 46 { 47 struct macro_queue *next; /* Next macro in the list. */ 48 char *macro; /* The name of the macro if not 49 defined, the full definition if 50 defined. */ 51 }; 52 static macro_queue *define_queue, *undef_queue; 53 54 /* General output routines. */ 55 static void scan_translation_unit (cpp_reader *); 56 static void scan_translation_unit_directives_only (cpp_reader *); 57 static void scan_translation_unit_trad (cpp_reader *); 58 static void account_for_newlines (const unsigned char *, size_t); 59 static int dump_macro (cpp_reader *, cpp_hashnode *, void *); 60 static void dump_queued_macros (cpp_reader *); 61 62 static bool print_line_1 (location_t, const char*, FILE *); 63 static bool print_line (location_t, const char *); 64 static bool maybe_print_line_1 (location_t, FILE *); 65 static bool maybe_print_line (location_t); 66 static bool do_line_change (cpp_reader *, const cpp_token *, 67 location_t, int); 68 69 /* Callback routines for the parser. Most of these are active only 70 in specific modes. */ 71 static void cb_line_change (cpp_reader *, const cpp_token *, int); 72 static void cb_define (cpp_reader *, location_t, cpp_hashnode *); 73 static void cb_undef (cpp_reader *, location_t, cpp_hashnode *); 74 static void cb_used_define (cpp_reader *, location_t, cpp_hashnode *); 75 static void cb_used_undef (cpp_reader *, location_t, cpp_hashnode *); 76 static void cb_include (cpp_reader *, location_t, const unsigned char *, 77 const char *, int, const cpp_token **); 78 static void cb_ident (cpp_reader *, location_t, const cpp_string *); 79 static void cb_def_pragma (cpp_reader *, location_t); 80 static void cb_read_pch (cpp_reader *pfile, const char *name, 81 int fd, const char *orig_name); 82 83 /* Preprocess and output. */ 84 void 85 preprocess_file (cpp_reader *pfile) 86 { 87 /* A successful cpp_read_main_file guarantees that we can call 88 cpp_scan_nooutput or cpp_get_token next. */ 89 if (flag_no_output && pfile->buffer) 90 { 91 /* Scan -included buffers, then the main file. */ 92 while (pfile->buffer->prev) 93 cpp_scan_nooutput (pfile); 94 cpp_scan_nooutput (pfile); 95 } 96 else if (cpp_get_options (pfile)->traditional) 97 scan_translation_unit_trad (pfile); 98 else if (cpp_get_options (pfile)->directives_only 99 && !cpp_get_options (pfile)->preprocessed) 100 scan_translation_unit_directives_only (pfile); 101 else 102 scan_translation_unit (pfile); 103 104 /* -dM command line option. Should this be elsewhere? */ 105 if (flag_dump_macros == 'M') 106 cpp_forall_identifiers (pfile, dump_macro, NULL); 107 108 /* Flush any pending output. */ 109 if (print.printed) 110 putc ('\n', print.outf); 111 } 112 113 /* Set up the callbacks as appropriate. */ 114 void 115 init_pp_output (FILE *out_stream) 116 { 117 cpp_callbacks *cb = cpp_get_callbacks (parse_in); 118 119 if (!flag_no_output) 120 { 121 cb->line_change = cb_line_change; 122 /* Don't emit #pragma or #ident directives if we are processing 123 assembly language; the assembler may choke on them. */ 124 if (cpp_get_options (parse_in)->lang != CLK_ASM) 125 { 126 cb->ident = cb_ident; 127 cb->def_pragma = cb_def_pragma; 128 } 129 } 130 131 if (flag_dump_includes) 132 cb->include = cb_include; 133 134 if (flag_pch_preprocess) 135 { 136 cb->valid_pch = c_common_valid_pch; 137 cb->read_pch = cb_read_pch; 138 } 139 140 if (flag_dump_macros == 'N' || flag_dump_macros == 'D') 141 { 142 cb->define = cb_define; 143 cb->undef = cb_undef; 144 } 145 146 if (flag_dump_macros == 'U') 147 { 148 cb->before_define = dump_queued_macros; 149 cb->used_define = cb_used_define; 150 cb->used_undef = cb_used_undef; 151 } 152 153 cb->has_attribute = c_common_has_attribute; 154 cb->has_builtin = c_common_has_builtin; 155 cb->get_source_date_epoch = cb_get_source_date_epoch; 156 cb->remap_filename = remap_macro_filename; 157 158 /* Initialize the print structure. */ 159 print.src_line = 1; 160 print.printed = false; 161 print.prev = 0; 162 print.outf = out_stream; 163 print.first_time = 1; 164 print.src_file = ""; 165 print.prev_was_system_token = false; 166 } 167 168 // FIXME: Ideally we'd just turn the entirety of the print struct into 169 // an encapsulated streamer ... 170 171 class token_streamer 172 { 173 bool avoid_paste; 174 bool do_line_adjustments; 175 bool in_pragma; 176 bool line_marker_emitted; 177 178 public: 179 token_streamer (cpp_reader *pfile) 180 :avoid_paste (false), 181 do_line_adjustments (cpp_get_options (pfile)->lang != CLK_ASM 182 && !flag_no_line_commands), 183 in_pragma (false), 184 line_marker_emitted (false) 185 { 186 } 187 188 void begin_pragma () 189 { 190 in_pragma = true; 191 } 192 193 void stream (cpp_reader *pfile, const cpp_token *tok, location_t); 194 }; 195 196 void 197 token_streamer::stream (cpp_reader *pfile, const cpp_token *token, 198 location_t loc) 199 { 200 if (token->type == CPP_PADDING) 201 { 202 avoid_paste = true; 203 if (print.source == NULL 204 || (!(print.source->flags & PREV_WHITE) 205 && token->val.source == NULL)) 206 print.source = token->val.source; 207 return; 208 } 209 210 if (token->type == CPP_EOF) 211 return; 212 213 /* Subtle logic to output a space if and only if necessary. */ 214 if (avoid_paste) 215 { 216 unsigned src_line = LOCATION_LINE (loc); 217 218 if (print.source == NULL) 219 print.source = token; 220 221 if (src_line != print.src_line 222 && do_line_adjustments 223 && !in_pragma) 224 { 225 line_marker_emitted = do_line_change (pfile, token, loc, false); 226 putc (' ', print.outf); 227 print.printed = true; 228 } 229 else if (print.source->flags & PREV_WHITE 230 || (print.prev 231 && cpp_avoid_paste (pfile, print.prev, token)) 232 || (print.prev == NULL && token->type == CPP_HASH)) 233 { 234 putc (' ', print.outf); 235 print.printed = true; 236 } 237 } 238 else if (token->flags & PREV_WHITE) 239 { 240 unsigned src_line = LOCATION_LINE (loc); 241 242 if (src_line != print.src_line 243 && do_line_adjustments 244 && !in_pragma) 245 line_marker_emitted = do_line_change (pfile, token, loc, false); 246 putc (' ', print.outf); 247 print.printed = true; 248 } 249 250 avoid_paste = false; 251 print.source = NULL; 252 print.prev = token; 253 if (token->type == CPP_PRAGMA) 254 { 255 const char *space; 256 const char *name; 257 258 line_marker_emitted = maybe_print_line (token->src_loc); 259 fputs ("#pragma ", print.outf); 260 c_pp_lookup_pragma (token->val.pragma, &space, &name); 261 if (space) 262 fprintf (print.outf, "%s %s", space, name); 263 else 264 fprintf (print.outf, "%s", name); 265 print.printed = true; 266 in_pragma = true; 267 } 268 else if (token->type == CPP_PRAGMA_EOL) 269 { 270 maybe_print_line (UNKNOWN_LOCATION); 271 in_pragma = false; 272 } 273 else 274 { 275 if (cpp_get_options (parse_in)->debug) 276 linemap_dump_location (line_table, token->src_loc, print.outf); 277 278 if (do_line_adjustments 279 && !in_pragma 280 && !line_marker_emitted 281 && print.prev_was_system_token != !!in_system_header_at (loc) 282 && !is_location_from_builtin_token (loc)) 283 /* The system-ness of this token is different from the one of 284 the previous token. Let's emit a line change to mark the 285 new system-ness before we emit the token. */ 286 { 287 do_line_change (pfile, token, loc, false); 288 print.prev_was_system_token = !!in_system_header_at (loc); 289 } 290 cpp_output_token (token, print.outf); 291 line_marker_emitted = false; 292 print.printed = true; 293 } 294 295 /* CPP_COMMENT tokens and raw-string literal tokens can have 296 embedded new-line characters. Rather than enumerating all the 297 possible token types just check if token uses val.str union 298 member. */ 299 if (cpp_token_val_index (token) == CPP_TOKEN_FLD_STR) 300 account_for_newlines (token->val.str.text, token->val.str.len); 301 } 302 303 /* Writes out the preprocessed file, handling spacing and paste 304 avoidance issues. */ 305 306 static void 307 scan_translation_unit (cpp_reader *pfile) 308 { 309 token_streamer streamer (pfile); 310 uintptr_t filter = 0; 311 312 if (lang_hooks.preprocess_token) 313 filter = lang_hooks.preprocess_token (pfile, NULL, filter); 314 315 print.source = NULL; 316 for (;;) 317 { 318 location_t spelling_loc; 319 const cpp_token *token 320 = cpp_get_token_with_location (pfile, &spelling_loc); 321 322 streamer.stream (pfile, token, spelling_loc); 323 if (filter) 324 { 325 unsigned flags = lang_hooks.preprocess_token (pfile, token, filter); 326 if (flags & lang_hooks::PT_begin_pragma) 327 streamer.begin_pragma (); 328 } 329 if (token->type == CPP_EOF) 330 break; 331 } 332 333 if (filter) 334 lang_hooks.preprocess_token (pfile, NULL, filter); 335 } 336 337 class do_streamer : public token_streamer 338 { 339 public: 340 uintptr_t filter; 341 342 do_streamer (cpp_reader *pfile, uintptr_t filter) 343 :token_streamer (pfile), filter (filter) 344 { 345 } 346 }; 347 348 static void 349 directives_only_cb (cpp_reader *pfile, CPP_DO_task task, void *data_, ...) 350 { 351 va_list args; 352 va_start (args, data_); 353 354 do_streamer *streamer = reinterpret_cast <do_streamer *> (data_); 355 switch (task) 356 { 357 default: 358 gcc_unreachable (); 359 360 case CPP_DO_print: 361 { 362 print.src_line += va_arg (args, unsigned); 363 364 const void *buf = va_arg (args, const void *); 365 size_t size = va_arg (args, size_t); 366 fwrite (buf, 1, size, print.outf); 367 } 368 break; 369 370 case CPP_DO_location: 371 maybe_print_line (va_arg (args, location_t)); 372 break; 373 374 case CPP_DO_token: 375 { 376 const cpp_token *token = va_arg (args, const cpp_token *); 377 location_t spelling_loc = va_arg (args, location_t); 378 streamer->stream (pfile, token, spelling_loc); 379 if (streamer->filter) 380 { 381 unsigned flags = lang_hooks.preprocess_token 382 (pfile, token, streamer->filter); 383 if (flags & lang_hooks::PT_begin_pragma) 384 streamer->begin_pragma (); 385 } 386 } 387 break; 388 } 389 390 va_end (args); 391 } 392 393 /* Writes out the preprocessed file, handling spacing and paste 394 avoidance issues. */ 395 static void 396 scan_translation_unit_directives_only (cpp_reader *pfile) 397 { 398 uintptr_t filter = 0; 399 if (lang_hooks.preprocess_token) 400 filter = lang_hooks.preprocess_token (pfile, NULL, filter); 401 do_streamer streamer (pfile, filter); 402 cpp_directive_only_process (pfile, &streamer, directives_only_cb); 403 if (streamer.filter) 404 lang_hooks.preprocess_token (pfile, NULL, streamer.filter); 405 } 406 407 /* Adjust print.src_line for newlines embedded in output. */ 408 static void 409 account_for_newlines (const unsigned char *str, size_t len) 410 { 411 while (len--) 412 if (*str++ == '\n') 413 print.src_line++; 414 } 415 416 /* Writes out a traditionally preprocessed file. */ 417 static void 418 scan_translation_unit_trad (cpp_reader *pfile) 419 { 420 while (_cpp_read_logical_line_trad (pfile)) 421 { 422 size_t len = pfile->out.cur - pfile->out.base; 423 maybe_print_line (pfile->out.first_line); 424 fwrite (pfile->out.base, 1, len, print.outf); 425 print.printed = true; 426 if (!CPP_OPTION (pfile, discard_comments)) 427 account_for_newlines (pfile->out.base, len); 428 } 429 } 430 431 /* If the token read on logical line LINE needs to be output on a 432 different line to the current one, output the required newlines or 433 a line marker. If a line marker was emitted, return TRUE otherwise 434 return FALSE. */ 435 436 static bool 437 maybe_print_line_1 (location_t src_loc, FILE *stream) 438 { 439 bool emitted_line_marker = false; 440 unsigned src_line = LOCATION_LINE (src_loc); 441 const char *src_file = LOCATION_FILE (src_loc); 442 443 /* End the previous line of text. */ 444 if (print.printed) 445 { 446 putc ('\n', stream); 447 print.src_line++; 448 print.printed = false; 449 } 450 451 if (!flag_no_line_commands 452 && src_line >= print.src_line 453 && src_line < print.src_line + 8 454 && src_loc != UNKNOWN_LOCATION 455 && strcmp (src_file, print.src_file) == 0) 456 { 457 while (src_line > print.src_line) 458 { 459 putc ('\n', stream); 460 print.src_line++; 461 } 462 } 463 else 464 emitted_line_marker = print_line_1 (src_loc, "", stream); 465 466 return emitted_line_marker; 467 } 468 469 /* If the token read on logical line LINE needs to be output on a 470 different line to the current one, output the required newlines or 471 a line marker. If a line marker was emitted, return TRUE otherwise 472 return FALSE. */ 473 474 static bool 475 maybe_print_line (location_t src_loc) 476 { 477 if (cpp_get_options (parse_in)->debug) 478 linemap_dump_location (line_table, src_loc, 479 print.outf); 480 return maybe_print_line_1 (src_loc, print.outf); 481 } 482 483 /* Output a line marker for logical line LINE. Special flags are "1" 484 or "2" indicating entering or leaving a file. If the line marker 485 was effectively emitted, return TRUE otherwise return FALSE. */ 486 487 static bool 488 print_line_1 (location_t src_loc, const char *special_flags, FILE *stream) 489 { 490 bool emitted_line_marker = false; 491 492 /* End any previous line of text. */ 493 if (print.printed) 494 putc ('\n', stream); 495 print.printed = false; 496 497 if (src_loc != UNKNOWN_LOCATION && !flag_no_line_commands) 498 { 499 const char *file_path = LOCATION_FILE (src_loc); 500 size_t to_file_len = strlen (file_path); 501 unsigned char *to_file_quoted = 502 (unsigned char *) alloca (to_file_len * 4 + 1); 503 504 /* cpp_quote_string does not nul-terminate, so we have to do it 505 ourselves. */ 506 unsigned char *p = cpp_quote_string (to_file_quoted, 507 (const unsigned char *) file_path, 508 to_file_len); 509 *p = '\0'; 510 511 print.src_line = LOCATION_LINE (src_loc); 512 print.src_file = file_path; 513 514 fprintf (stream, "# %u \"%s\"%s", 515 print.src_line, to_file_quoted, special_flags); 516 517 int sysp = in_system_header_at (src_loc); 518 if (sysp == 2) 519 fputs (" 3 4", stream); 520 else if (sysp == 1) 521 fputs (" 3", stream); 522 523 putc ('\n', stream); 524 emitted_line_marker = true; 525 } 526 527 return emitted_line_marker; 528 } 529 530 /* Output a line marker for logical line LINE. Special flags are "1" 531 or "2" indicating entering or leaving a file. Return TRUE if a 532 line marker was effectively emitted, FALSE otherwise. */ 533 534 static bool 535 print_line (location_t src_loc, const char *special_flags) 536 { 537 if (cpp_get_options (parse_in)->debug) 538 linemap_dump_location (line_table, src_loc, 539 print.outf); 540 return print_line_1 (src_loc, special_flags, print.outf); 541 } 542 543 /* Helper function for cb_line_change and scan_translation_unit. 544 Return TRUE if a line marker is emitted, FALSE otherwise. */ 545 static bool 546 do_line_change (cpp_reader *pfile, const cpp_token *token, 547 location_t src_loc, int parsing_args) 548 { 549 bool emitted_line_marker = false; 550 if (define_queue || undef_queue) 551 dump_queued_macros (pfile); 552 553 if (token->type == CPP_EOF || parsing_args) 554 return false; 555 556 emitted_line_marker = maybe_print_line (src_loc); 557 print.prev = 0; 558 print.source = 0; 559 560 /* Supply enough spaces to put this token in its original column, 561 one space per column greater than 2, since scan_translation_unit 562 will provide a space if PREV_WHITE. Don't bother trying to 563 reconstruct tabs; we can't get it right in general, and nothing 564 ought to care. Some things do care; the fault lies with them. */ 565 if (!CPP_OPTION (pfile, traditional)) 566 { 567 int spaces = LOCATION_COLUMN (src_loc) - 2; 568 print.printed = true; 569 570 while (-- spaces >= 0) 571 putc (' ', print.outf); 572 } 573 574 return emitted_line_marker; 575 } 576 577 /* Called when a line of output is started. TOKEN is the first token 578 of the line, and at end of file will be CPP_EOF. */ 579 static void 580 cb_line_change (cpp_reader *pfile, const cpp_token *token, 581 int parsing_args) 582 { 583 do_line_change (pfile, token, token->src_loc, parsing_args); 584 } 585 586 static void 587 cb_ident (cpp_reader *pfile ATTRIBUTE_UNUSED, location_t line, 588 const cpp_string *str) 589 { 590 maybe_print_line (line); 591 fprintf (print.outf, "#ident %s\n", str->text); 592 print.src_line++; 593 } 594 595 static void 596 cb_define (cpp_reader *pfile, location_t line, cpp_hashnode *node) 597 { 598 const line_map_ordinary *map; 599 600 maybe_print_line (line); 601 fputs ("#define ", print.outf); 602 603 /* 'D' is whole definition; 'N' is name only. */ 604 if (flag_dump_macros == 'D') 605 fputs ((const char *) cpp_macro_definition (pfile, node), 606 print.outf); 607 else 608 fputs ((const char *) NODE_NAME (node), print.outf); 609 610 putc ('\n', print.outf); 611 print.printed = false; 612 linemap_resolve_location (line_table, line, 613 LRK_MACRO_DEFINITION_LOCATION, 614 &map); 615 print.src_line++; 616 } 617 618 static void 619 cb_undef (cpp_reader *pfile, location_t line, cpp_hashnode *node) 620 { 621 if (lang_hooks.preprocess_undef) 622 lang_hooks.preprocess_undef (pfile, line, node); 623 maybe_print_line (line); 624 fprintf (print.outf, "#undef %s\n", NODE_NAME (node)); 625 print.src_line++; 626 } 627 628 static void 629 cb_used_define (cpp_reader *pfile, location_t line ATTRIBUTE_UNUSED, 630 cpp_hashnode *node) 631 { 632 if (cpp_user_macro_p (node)) 633 { 634 macro_queue *q; 635 q = XNEW (macro_queue); 636 q->macro = xstrdup ((const char *) cpp_macro_definition (pfile, node)); 637 q->next = define_queue; 638 define_queue = q; 639 } 640 } 641 642 static void 643 cb_used_undef (cpp_reader *pfile ATTRIBUTE_UNUSED, 644 location_t line ATTRIBUTE_UNUSED, 645 cpp_hashnode *node) 646 { 647 macro_queue *q; 648 q = XNEW (macro_queue); 649 q->macro = xstrdup ((const char *) NODE_NAME (node)); 650 q->next = undef_queue; 651 undef_queue = q; 652 } 653 654 static void 655 dump_queued_macros (cpp_reader *pfile ATTRIBUTE_UNUSED) 656 { 657 macro_queue *q; 658 659 /* End the previous line of text. */ 660 if (print.printed) 661 { 662 putc ('\n', print.outf); 663 print.src_line++; 664 print.printed = false; 665 } 666 667 for (q = define_queue; q;) 668 { 669 macro_queue *oq; 670 fputs ("#define ", print.outf); 671 fputs (q->macro, print.outf); 672 putc ('\n', print.outf); 673 print.printed = false; 674 print.src_line++; 675 oq = q; 676 q = q->next; 677 free (oq->macro); 678 free (oq); 679 } 680 define_queue = NULL; 681 for (q = undef_queue; q;) 682 { 683 macro_queue *oq; 684 fprintf (print.outf, "#undef %s\n", q->macro); 685 print.src_line++; 686 oq = q; 687 q = q->next; 688 free (oq->macro); 689 free (oq); 690 } 691 undef_queue = NULL; 692 } 693 694 static void 695 cb_include (cpp_reader *pfile ATTRIBUTE_UNUSED, location_t line, 696 const unsigned char *dir, const char *header, int angle_brackets, 697 const cpp_token **comments) 698 { 699 maybe_print_line (line); 700 if (angle_brackets) 701 fprintf (print.outf, "#%s <%s>", dir, header); 702 else 703 fprintf (print.outf, "#%s \"%s\"", dir, header); 704 705 if (comments != NULL) 706 { 707 while (*comments != NULL) 708 { 709 if ((*comments)->flags & PREV_WHITE) 710 putc (' ', print.outf); 711 cpp_output_token (*comments, print.outf); 712 ++comments; 713 } 714 } 715 716 putc ('\n', print.outf); 717 print.printed = false; 718 print.src_line++; 719 } 720 721 /* Callback called when -fworking-director and -E to emit working 722 directory in cpp output file. */ 723 724 void 725 pp_dir_change (cpp_reader *pfile ATTRIBUTE_UNUSED, const char *dir) 726 { 727 size_t to_file_len = strlen (dir); 728 unsigned char *to_file_quoted = 729 (unsigned char *) alloca (to_file_len * 4 + 1); 730 unsigned char *p; 731 732 /* cpp_quote_string does not nul-terminate, so we have to do it ourselves. */ 733 p = cpp_quote_string (to_file_quoted, (const unsigned char *) dir, to_file_len); 734 *p = '\0'; 735 fprintf (print.outf, "# 1 \"%s//\"\n", to_file_quoted); 736 } 737 738 /* The file name, line number or system header flags have changed, as 739 described in MAP. */ 740 741 void 742 pp_file_change (const line_map_ordinary *map) 743 { 744 const char *flags = ""; 745 746 if (flag_no_line_commands) 747 return; 748 749 if (map != NULL) 750 { 751 input_location = map->start_location; 752 if (print.first_time) 753 { 754 /* Avoid printing foo.i when the main file is foo.c. */ 755 if (!cpp_get_options (parse_in)->preprocessed) 756 print_line (map->start_location, flags); 757 print.first_time = 0; 758 } 759 else 760 { 761 /* Bring current file to correct line when entering a new file. */ 762 if (map->reason == LC_ENTER) 763 { 764 maybe_print_line (linemap_included_from (map)); 765 flags = " 1"; 766 } 767 else if (map->reason == LC_LEAVE) 768 flags = " 2"; 769 print_line (map->start_location, flags); 770 } 771 } 772 } 773 774 /* Copy a #pragma directive to the preprocessed output. */ 775 static void 776 cb_def_pragma (cpp_reader *pfile, location_t line) 777 { 778 maybe_print_line (line); 779 fputs ("#pragma ", print.outf); 780 cpp_output_line (pfile, print.outf); 781 print.printed = false; 782 print.src_line++; 783 } 784 785 /* Dump out the hash table. */ 786 static int 787 dump_macro (cpp_reader *pfile, cpp_hashnode *node, void *v ATTRIBUTE_UNUSED) 788 { 789 if (cpp_user_macro_p (node)) 790 { 791 fputs ("#define ", print.outf); 792 fputs ((const char *) cpp_macro_definition (pfile, node), 793 print.outf); 794 putc ('\n', print.outf); 795 print.printed = false; 796 print.src_line++; 797 } 798 799 return 1; 800 } 801 802 /* Load in the PCH file NAME, open on FD. It was originally searched for 803 by ORIG_NAME. Also, print out a #include command so that the PCH 804 file can be loaded when the preprocessed output is compiled. */ 805 806 static void 807 cb_read_pch (cpp_reader *pfile, const char *name, 808 int fd, const char *orig_name ATTRIBUTE_UNUSED) 809 { 810 c_common_read_pch (pfile, name, fd, orig_name); 811 812 fprintf (print.outf, "#pragma GCC pch_preprocess \"%s\"\n", name); 813 print.src_line++; 814 } 815