| 1 | /* Various declarations for language-independent pretty-print subroutines. |
|---|---|
| 2 | Copyright (C) 2002-2025 Free Software Foundation, Inc. |
| 3 | Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net> |
| 4 | |
| 5 | This file is part of GCC. |
| 6 | |
| 7 | GCC is free software; you can redistribute it and/or modify it under |
| 8 | the terms of the GNU General Public License as published by the Free |
| 9 | Software Foundation; either version 3, or (at your option) any later |
| 10 | version. |
| 11 | |
| 12 | GCC is distributed in the hope that it will be useful, but WITHOUT ANY |
| 13 | WARRANTY; without even the implied warranty of MERCHANTABILITY or |
| 14 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
| 15 | for more details. |
| 16 | |
| 17 | You should have received a copy of the GNU General Public License |
| 18 | along with GCC; see the file COPYING3. If not see |
| 19 | <http://www.gnu.org/licenses/>. */ |
| 20 | |
| 21 | #ifndef GCC_PRETTY_PRINT_H |
| 22 | #define GCC_PRETTY_PRINT_H |
| 23 | |
| 24 | #include "obstack.h" |
| 25 | #include "rich-location.h" |
| 26 | #include "diagnostic-url.h" |
| 27 | |
| 28 | /* Maximum number of format string arguments. */ |
| 29 | #define PP_NL_ARGMAX 30 |
| 30 | |
| 31 | /* The type of a text to be formatted according a format specification |
| 32 | along with a list of things. */ |
| 33 | struct text_info |
| 34 | { |
| 35 | text_info () = default; |
| 36 | text_info (const char *format_spec, |
| 37 | va_list *args_ptr, |
| 38 | int err_no, |
| 39 | void **data = nullptr, |
| 40 | rich_location *rich_loc = nullptr) |
| 41 | : m_format_spec (format_spec), |
| 42 | m_args_ptr (args_ptr), |
| 43 | m_err_no (err_no), |
| 44 | m_data (data), |
| 45 | m_richloc (rich_loc) |
| 46 | { |
| 47 | } |
| 48 | |
| 49 | void set_location (unsigned int idx, location_t loc, |
| 50 | enum range_display_kind range_display_kind); |
| 51 | location_t get_location (unsigned int index_of_location) const; |
| 52 | |
| 53 | const char *m_format_spec; |
| 54 | va_list *m_args_ptr; |
| 55 | int m_err_no; /* for %m */ |
| 56 | void **m_data; |
| 57 | rich_location *m_richloc; |
| 58 | }; |
| 59 | |
| 60 | /* How often diagnostics are prefixed by their locations: |
| 61 | o DIAGNOSTICS_SHOW_PREFIX_NEVER: never - not yet supported; |
| 62 | o DIAGNOSTICS_SHOW_PREFIX_ONCE: emit only once; |
| 63 | o DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE: emit each time a physical |
| 64 | line is started. */ |
| 65 | enum diagnostic_prefixing_rule_t |
| 66 | { |
| 67 | DIAGNOSTICS_SHOW_PREFIX_ONCE = 0x0, |
| 68 | DIAGNOSTICS_SHOW_PREFIX_NEVER = 0x1, |
| 69 | DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE = 0x2 |
| 70 | }; |
| 71 | |
| 72 | class pp_formatted_chunks; |
| 73 | class output_buffer; |
| 74 | class pp_token_list; |
| 75 | class urlifier; |
| 76 | |
| 77 | namespace pp_markup { |
| 78 | class context; |
| 79 | } // namespace pp_markup |
| 80 | |
| 81 | /* The output buffer datatype. This is best seen as an abstract datatype |
| 82 | whose fields should not be accessed directly by clients. */ |
| 83 | class output_buffer |
| 84 | { |
| 85 | public: |
| 86 | output_buffer (); |
| 87 | output_buffer (const output_buffer &) = delete; |
| 88 | output_buffer (output_buffer &&) = delete; |
| 89 | ~output_buffer (); |
| 90 | output_buffer & operator= (const output_buffer &) = delete; |
| 91 | output_buffer & operator= (output_buffer &&) = delete; |
| 92 | |
| 93 | pp_formatted_chunks *push_formatted_chunks (); |
| 94 | void pop_formatted_chunks (); |
| 95 | |
| 96 | void dump (FILE *out, int indent) const; |
| 97 | void DEBUG_FUNCTION dump () const { dump (stderr, indent: 0); } |
| 98 | |
| 99 | /* Obstack where the text is built up. */ |
| 100 | struct obstack m_formatted_obstack; |
| 101 | |
| 102 | /* Obstack containing a chunked representation of the format |
| 103 | specification plus arguments. */ |
| 104 | struct obstack m_chunk_obstack; |
| 105 | |
| 106 | /* Currently active obstack: one of the above two. This is used so |
| 107 | that the text formatters don't need to know which phase we're in. */ |
| 108 | struct obstack *m_obstack; |
| 109 | |
| 110 | /* Topmost element in a stack of arrays of formatted chunks. |
| 111 | These come from the chunk_obstack. */ |
| 112 | pp_formatted_chunks *m_cur_formatted_chunks; |
| 113 | |
| 114 | /* Where to output formatted text. */ |
| 115 | FILE *m_stream; |
| 116 | |
| 117 | /* The amount of characters output so far. */ |
| 118 | int m_line_length; |
| 119 | |
| 120 | /* This must be large enough to hold any printed integer or |
| 121 | floating-point value. */ |
| 122 | char m_digit_buffer[128]; |
| 123 | |
| 124 | /* Nonzero means that text should be flushed when |
| 125 | appropriate. Otherwise, text is buffered until either |
| 126 | pp_really_flush or pp_clear_output_area are called. */ |
| 127 | bool m_flush_p; |
| 128 | }; |
| 129 | |
| 130 | /* Finishes constructing a NULL-terminated character string representing |
| 131 | the buffered text. */ |
| 132 | inline const char * |
| 133 | output_buffer_formatted_text (output_buffer *buff) |
| 134 | { |
| 135 | obstack_1grow (buff->m_obstack, '\0'); |
| 136 | return (const char *) obstack_base (buff->m_obstack); |
| 137 | } |
| 138 | |
| 139 | /* Append to the output buffer a string specified by its |
| 140 | STARTing character and LENGTH. */ |
| 141 | inline void |
| 142 | output_buffer_append_r (output_buffer *buff, const char *start, int length) |
| 143 | { |
| 144 | gcc_checking_assert (start); |
| 145 | obstack_grow (buff->m_obstack, start, length); |
| 146 | for (int i = 0; i < length; i++) |
| 147 | if (start[i] == '\n') |
| 148 | buff->m_line_length = 0; |
| 149 | else |
| 150 | buff->m_line_length++; |
| 151 | } |
| 152 | |
| 153 | /* Return a pointer to the last character emitted in the |
| 154 | output_buffer. A NULL pointer means no character available. */ |
| 155 | inline const char * |
| 156 | output_buffer_last_position_in_text (const output_buffer *buff) |
| 157 | { |
| 158 | const char *p = NULL; |
| 159 | struct obstack *text = buff->m_obstack; |
| 160 | |
| 161 | if (obstack_base (text) != obstack_next_free (text)) |
| 162 | p = ((const char *) obstack_next_free (text)) - 1; |
| 163 | return p; |
| 164 | } |
| 165 | |
| 166 | |
| 167 | /* The type of pretty-printer flags passed to clients. */ |
| 168 | typedef unsigned int pp_flags; |
| 169 | |
| 170 | enum pp_padding |
| 171 | { |
| 172 | pp_none, pp_before, pp_after |
| 173 | }; |
| 174 | |
| 175 | /* Structure for switching in and out of verbatim mode in a convenient |
| 176 | manner. */ |
| 177 | struct pp_wrapping_mode_t |
| 178 | { |
| 179 | /* Current prefixing rule. */ |
| 180 | diagnostic_prefixing_rule_t rule; |
| 181 | |
| 182 | /* The ideal upper bound of number of characters per line, as suggested |
| 183 | by front-end. */ |
| 184 | int line_cutoff; |
| 185 | }; |
| 186 | |
| 187 | /* The type of a hook that formats client-specific data onto a pretty_printer. |
| 188 | A client-supplied formatter returns true if everything goes well, |
| 189 | otherwise it returns false. */ |
| 190 | typedef bool (*printer_fn) (pretty_printer *, text_info *, const char *, |
| 191 | int, bool, bool, bool, bool *, pp_token_list &); |
| 192 | |
| 193 | /* Base class for an optional client-supplied object for doing additional |
| 194 | processing between stages 2 and 3 of formatted printing. */ |
| 195 | class format_postprocessor |
| 196 | { |
| 197 | public: |
| 198 | virtual ~format_postprocessor () {} |
| 199 | virtual std::unique_ptr<format_postprocessor> clone() const = 0; |
| 200 | virtual void handle (pretty_printer *) = 0; |
| 201 | }; |
| 202 | |
| 203 | /* Abstract base class for writing formatted tokens to the pretty_printer's |
| 204 | text buffer, allowing for output formats and dumpfiles to override |
| 205 | how different kinds of tokens are handled. */ |
| 206 | |
| 207 | class token_printer |
| 208 | { |
| 209 | public: |
| 210 | virtual ~token_printer () {} |
| 211 | virtual void print_tokens (pretty_printer *pp, |
| 212 | const pp_token_list &tokens) = 0; |
| 213 | }; |
| 214 | |
| 215 | inline bool & pp_needs_newline (pretty_printer *pp); |
| 216 | |
| 217 | /* True if PRETTY-PRINTER is in line-wrapping mode. */ |
| 218 | #define pp_is_wrapping_line(PP) (pp_line_cutoff (PP) > 0) |
| 219 | |
| 220 | inline output_buffer *&pp_buffer (pretty_printer *pp); |
| 221 | inline output_buffer *pp_buffer (const pretty_printer *pp); |
| 222 | inline const char *pp_get_prefix (const pretty_printer *pp); |
| 223 | extern char *pp_take_prefix (pretty_printer *); |
| 224 | extern void pp_destroy_prefix (pretty_printer *); |
| 225 | inline int &pp_line_cutoff (pretty_printer *pp); |
| 226 | inline diagnostic_prefixing_rule_t &pp_prefixing_rule (pretty_printer *pp); |
| 227 | inline pp_wrapping_mode_t &pp_wrapping_mode (pretty_printer *pp); |
| 228 | inline int & pp_indentation (pretty_printer *pp); |
| 229 | inline bool & pp_translate_identifiers (pretty_printer *pp); |
| 230 | inline bool & pp_show_color (pretty_printer *pp); |
| 231 | inline printer_fn &pp_format_decoder (pretty_printer *pp); |
| 232 | inline format_postprocessor *pp_format_postprocessor (pretty_printer *pp); |
| 233 | inline bool & pp_show_highlight_colors (pretty_printer *pp); |
| 234 | |
| 235 | class urlifier; |
| 236 | |
| 237 | /* The data structure that contains the bare minimum required to do |
| 238 | proper pretty-printing. Clients may derive from this structure |
| 239 | and add additional fields they need. */ |
| 240 | class pretty_printer |
| 241 | { |
| 242 | public: |
| 243 | friend inline output_buffer *&pp_buffer (pretty_printer *pp); |
| 244 | friend inline output_buffer *pp_buffer (const pretty_printer *pp); |
| 245 | friend inline const char *pp_get_prefix (const pretty_printer *pp); |
| 246 | friend char *pp_take_prefix (pretty_printer *); |
| 247 | friend void pp_destroy_prefix (pretty_printer *); |
| 248 | friend inline int &pp_line_cutoff (pretty_printer *pp); |
| 249 | friend inline diagnostic_prefixing_rule_t & |
| 250 | pp_prefixing_rule (pretty_printer *pp); |
| 251 | friend inline const diagnostic_prefixing_rule_t & |
| 252 | pp_prefixing_rule (const pretty_printer *pp); |
| 253 | friend inline pp_wrapping_mode_t &pp_wrapping_mode (pretty_printer *pp); |
| 254 | friend bool & pp_needs_newline (pretty_printer *pp); |
| 255 | friend int & pp_indentation (pretty_printer *pp); |
| 256 | friend bool & pp_translate_identifiers (pretty_printer *pp); |
| 257 | friend bool & pp_show_color (pretty_printer *pp); |
| 258 | friend printer_fn &pp_format_decoder (pretty_printer *pp); |
| 259 | friend format_postprocessor * pp_format_postprocessor (pretty_printer *pp); |
| 260 | friend bool & pp_show_highlight_colors (pretty_printer *pp); |
| 261 | |
| 262 | friend void pp_output_formatted_text (pretty_printer *, |
| 263 | const urlifier *); |
| 264 | |
| 265 | /* Default construct a pretty printer with specified |
| 266 | maximum line length cut off limit. */ |
| 267 | explicit pretty_printer (int = 0); |
| 268 | explicit pretty_printer (const pretty_printer &other); |
| 269 | |
| 270 | virtual ~pretty_printer (); |
| 271 | |
| 272 | virtual std::unique_ptr<pretty_printer> clone () const; |
| 273 | |
| 274 | void set_output_stream (FILE *outfile) |
| 275 | { |
| 276 | m_buffer->m_stream = outfile; |
| 277 | } |
| 278 | |
| 279 | void set_token_printer (token_printer* tp) |
| 280 | { |
| 281 | m_token_printer = tp; // borrowed |
| 282 | } |
| 283 | |
| 284 | void set_prefix (char *prefix); |
| 285 | |
| 286 | void emit_prefix (); |
| 287 | |
| 288 | void format (text_info &text); |
| 289 | |
| 290 | void maybe_space (); |
| 291 | |
| 292 | bool supports_urls_p () const { return m_url_format != URL_FORMAT_NONE; } |
| 293 | diagnostic_url_format get_url_format () const { return m_url_format; } |
| 294 | void set_url_format (diagnostic_url_format url_format) |
| 295 | { |
| 296 | m_url_format = url_format; |
| 297 | } |
| 298 | |
| 299 | void begin_url (const char *url); |
| 300 | void end_url (); |
| 301 | |
| 302 | /* Switch into verbatim mode and return the old mode. */ |
| 303 | pp_wrapping_mode_t |
| 304 | set_verbatim_wrapping () |
| 305 | { |
| 306 | const pp_wrapping_mode_t oldmode = pp_wrapping_mode (pp: this); |
| 307 | pp_line_cutoff (pp: this) = 0; |
| 308 | pp_prefixing_rule (pp: this) = DIAGNOSTICS_SHOW_PREFIX_NEVER; |
| 309 | return oldmode; |
| 310 | } |
| 311 | |
| 312 | void set_padding (pp_padding padding) { m_padding = padding; } |
| 313 | pp_padding get_padding () const { return m_padding; } |
| 314 | |
| 315 | void clear_state (); |
| 316 | void set_real_maximum_length (); |
| 317 | int remaining_character_count_for_line (); |
| 318 | |
| 319 | void set_format_postprocessor (std::unique_ptr<format_postprocessor> p) |
| 320 | { |
| 321 | m_format_postprocessor = std::move (p); |
| 322 | } |
| 323 | |
| 324 | void dump (FILE *out, int indent) const; |
| 325 | void DEBUG_FUNCTION dump () const { dump (stderr, indent: 0); } |
| 326 | |
| 327 | private: |
| 328 | /* Where we print external representation of ENTITY. */ |
| 329 | output_buffer *m_buffer; |
| 330 | |
| 331 | /* The prefix for each new line. If non-NULL, this is "owned" by the |
| 332 | pretty_printer, and will eventually be free-ed. */ |
| 333 | char *m_prefix; |
| 334 | |
| 335 | /* Where to put whitespace around the entity being formatted. */ |
| 336 | pp_padding m_padding; |
| 337 | |
| 338 | /* The real upper bound of number of characters per line, taking into |
| 339 | account the case of a very very looong prefix. */ |
| 340 | int m_maximum_length; |
| 341 | |
| 342 | /* Indentation count. */ |
| 343 | int m_indent_skip; |
| 344 | |
| 345 | /* Current wrapping mode. */ |
| 346 | pp_wrapping_mode_t m_wrapping; |
| 347 | |
| 348 | /* If non-NULL, this function formats a TEXT into the BUFFER. When called, |
| 349 | TEXT->format_spec points to a format code. FORMAT_DECODER should call |
| 350 | pp_string (and related functions) to add data to the BUFFER. |
| 351 | FORMAT_DECODER can read arguments from *TEXT->args_pts using VA_ARG. |
| 352 | If the BUFFER needs additional characters from the format string, it |
| 353 | should advance the TEXT->format_spec as it goes. When FORMAT_DECODER |
| 354 | returns, TEXT->format_spec should point to the last character processed. |
| 355 | The QUOTE and FORMATTED_TOKEN_LIST are passed in, to allow for |
| 356 | deferring-handling of format codes (e.g. %H and %I in |
| 357 | the C++ frontend). */ |
| 358 | printer_fn m_format_decoder; |
| 359 | |
| 360 | /* If non-NULL, this is called by pp_format once after all format codes |
| 361 | have been processed, to allow for client-specific postprocessing. |
| 362 | This is used by the C++ frontend for handling the %H and %I |
| 363 | format codes (which interract with each other). */ |
| 364 | std::unique_ptr<format_postprocessor> m_format_postprocessor; |
| 365 | |
| 366 | /* This is used by pp_output_formatted_text after it has converted all |
| 367 | formatted chunks into a single list of tokens. |
| 368 | Can be nullptr. |
| 369 | Borrowed from the output format or from dump_pretty_printer. */ |
| 370 | token_printer *m_token_printer; |
| 371 | |
| 372 | /* Nonzero if current PREFIX was emitted at least once. */ |
| 373 | bool m_emitted_prefix; |
| 374 | |
| 375 | /* Nonzero means one should emit a newline before outputting anything. */ |
| 376 | bool m_need_newline; |
| 377 | |
| 378 | /* Nonzero means identifiers are translated to the locale character |
| 379 | set on output. */ |
| 380 | bool m_translate_identifiers; |
| 381 | |
| 382 | /* Nonzero means that text should be colorized. */ |
| 383 | bool m_show_color; |
| 384 | |
| 385 | /* True means that pertinent sections within the text should be |
| 386 | highlighted with color. */ |
| 387 | bool m_show_highlight_colors; |
| 388 | |
| 389 | /* Whether URLs should be emitted, and which terminator to use. */ |
| 390 | diagnostic_url_format m_url_format; |
| 391 | |
| 392 | /* If true, then we've had a begin_url (nullptr), and so the |
| 393 | next end_url should be a no-op. */ |
| 394 | bool m_skipping_null_url; |
| 395 | }; |
| 396 | |
| 397 | inline output_buffer *& |
| 398 | pp_buffer (pretty_printer *pp) |
| 399 | { |
| 400 | return pp->m_buffer; |
| 401 | } |
| 402 | |
| 403 | inline output_buffer * |
| 404 | pp_buffer (const pretty_printer *pp) |
| 405 | { |
| 406 | return pp->m_buffer; |
| 407 | } |
| 408 | |
| 409 | inline const char * |
| 410 | pp_get_prefix (const pretty_printer *pp) |
| 411 | { |
| 412 | return pp->m_prefix; |
| 413 | } |
| 414 | |
| 415 | /* TRUE if a newline character needs to be added before further |
| 416 | formatting. */ |
| 417 | inline bool & |
| 418 | pp_needs_newline (pretty_printer *pp) |
| 419 | { |
| 420 | return pp->m_need_newline; |
| 421 | } |
| 422 | |
| 423 | /* The amount of whitespace to be emitted when starting a new line. */ |
| 424 | inline int & |
| 425 | pp_indentation (pretty_printer *pp) |
| 426 | { |
| 427 | return pp->m_indent_skip; |
| 428 | } |
| 429 | |
| 430 | /* True if identifiers are translated to the locale character set on |
| 431 | output. */ |
| 432 | inline bool & |
| 433 | pp_translate_identifiers (pretty_printer *pp) |
| 434 | { |
| 435 | return pp->m_translate_identifiers; |
| 436 | } |
| 437 | |
| 438 | /* True if colors should be shown. */ |
| 439 | inline bool & |
| 440 | pp_show_color (pretty_printer *pp) |
| 441 | { |
| 442 | return pp->m_show_color; |
| 443 | } |
| 444 | |
| 445 | inline printer_fn & |
| 446 | pp_format_decoder (pretty_printer *pp) |
| 447 | { |
| 448 | return pp->m_format_decoder; |
| 449 | } |
| 450 | |
| 451 | inline format_postprocessor * |
| 452 | pp_format_postprocessor (pretty_printer *pp) |
| 453 | { |
| 454 | return pp->m_format_postprocessor.get (); |
| 455 | } |
| 456 | |
| 457 | inline bool & |
| 458 | pp_show_highlight_colors (pretty_printer *pp) |
| 459 | { |
| 460 | return pp->m_show_highlight_colors; |
| 461 | } |
| 462 | |
| 463 | /* Maximum characters per line in automatic line wrapping mode. |
| 464 | Zero means don't wrap lines. */ |
| 465 | inline int & |
| 466 | pp_line_cutoff (pretty_printer *pp) |
| 467 | { |
| 468 | return pp->m_wrapping.line_cutoff; |
| 469 | } |
| 470 | |
| 471 | /* Prefixing rule used in formatting a diagnostic message. */ |
| 472 | inline diagnostic_prefixing_rule_t & |
| 473 | pp_prefixing_rule (pretty_printer *pp) |
| 474 | { |
| 475 | return pp->m_wrapping.rule; |
| 476 | } |
| 477 | inline const diagnostic_prefixing_rule_t & |
| 478 | pp_prefixing_rule (const pretty_printer *pp) |
| 479 | { |
| 480 | return pp->m_wrapping.rule; |
| 481 | } |
| 482 | |
| 483 | /* Get or set the wrapping mode as a single entity. */ |
| 484 | inline pp_wrapping_mode_t & |
| 485 | pp_wrapping_mode (pretty_printer *pp) |
| 486 | { |
| 487 | return pp->m_wrapping; |
| 488 | } |
| 489 | |
| 490 | #define pp_space(PP) pp_character (PP, ' ') |
| 491 | #define pp_left_paren(PP) pp_character (PP, '(') |
| 492 | #define pp_right_paren(PP) pp_character (PP, ')') |
| 493 | #define pp_left_bracket(PP) pp_character (PP, '[') |
| 494 | #define pp_right_bracket(PP) pp_character (PP, ']') |
| 495 | #define pp_left_brace(PP) pp_character (PP, '{') |
| 496 | #define pp_right_brace(PP) pp_character (PP, '}') |
| 497 | #define pp_semicolon(PP) pp_character (PP, ';') |
| 498 | #define pp_comma(PP) pp_character (PP, ',') |
| 499 | #define pp_dot(PP) pp_character (PP, '.') |
| 500 | #define pp_colon(PP) pp_character (PP, ':') |
| 501 | #define pp_colon_colon(PP) pp_string (PP, "::") |
| 502 | #define pp_arrow(PP) pp_string (PP, "->") |
| 503 | #define pp_equal(PP) pp_character (PP, '=') |
| 504 | #define pp_question(PP) pp_character (PP, '?') |
| 505 | #define pp_bar(PP) pp_character (PP, '|') |
| 506 | #define pp_bar_bar(PP) pp_string (PP, "||") |
| 507 | #define pp_carret(PP) pp_character (PP, '^') |
| 508 | #define pp_ampersand(PP) pp_character (PP, '&') |
| 509 | #define pp_ampersand_ampersand(PP) pp_string (PP, "&&") |
| 510 | #define pp_less(PP) pp_character (PP, '<') |
| 511 | #define pp_less_equal(PP) pp_string (PP, "<=") |
| 512 | #define pp_greater(PP) pp_character (PP, '>') |
| 513 | #define pp_greater_equal(PP) pp_string (PP, ">=") |
| 514 | #define pp_plus(PP) pp_character (PP, '+') |
| 515 | #define pp_minus(PP) pp_character (PP, '-') |
| 516 | #define pp_star(PP) pp_character (PP, '*') |
| 517 | #define pp_slash(PP) pp_character (PP, '/') |
| 518 | #define pp_modulo(PP) pp_character (PP, '%') |
| 519 | #define pp_exclamation(PP) pp_character (PP, '!') |
| 520 | #define pp_complement(PP) pp_character (PP, '~') |
| 521 | #define pp_quote(PP) pp_character (PP, '\'') |
| 522 | #define pp_backquote(PP) pp_character (PP, '`') |
| 523 | #define pp_doublequote(PP) pp_character (PP, '"') |
| 524 | #define pp_underscore(PP) pp_character (PP, '_') |
| 525 | #define pp_maybe_newline_and_indent(PP, N) \ |
| 526 | if (pp_needs_newline (PP)) pp_newline_and_indent (PP, N) |
| 527 | #define pp_scalar(PP, FORMAT, SCALAR) \ |
| 528 | do \ |
| 529 | { \ |
| 530 | sprintf (pp_buffer (PP)->m_digit_buffer, FORMAT, SCALAR); \ |
| 531 | pp_string (PP, pp_buffer (PP)->m_digit_buffer); \ |
| 532 | } \ |
| 533 | while (0) |
| 534 | #define pp_decimal_int(PP, I) pp_scalar (PP, "%d", I) |
| 535 | #define pp_unsigned_wide_integer(PP, I) \ |
| 536 | pp_scalar (PP, HOST_WIDE_INT_PRINT_UNSIGNED, (unsigned HOST_WIDE_INT) I) |
| 537 | #define pp_vrange(PP, R) \ |
| 538 | do \ |
| 539 | { \ |
| 540 | vrange_printer vrange_pp (PP); \ |
| 541 | (R)->accept (vrange_pp); \ |
| 542 | } \ |
| 543 | while (0) |
| 544 | #define pp_double(PP, F) pp_scalar (PP, "%f", F) |
| 545 | #define pp_pointer(PP, P) pp_scalar (PP, "%p", P) |
| 546 | |
| 547 | #define pp_identifier(PP, ID) pp_string (PP, (pp_translate_identifiers (PP) \ |
| 548 | ? identifier_to_locale (ID) \ |
| 549 | : (ID))) |
| 550 | |
| 551 | |
| 552 | extern void pp_set_line_maximum_length (pretty_printer *, int); |
| 553 | inline void pp_set_prefix (pretty_printer *pp, char *prefix) |
| 554 | { |
| 555 | pp->set_prefix (prefix); |
| 556 | } |
| 557 | extern void pp_clear_output_area (pretty_printer *); |
| 558 | extern const char *pp_formatted_text (pretty_printer *); |
| 559 | extern const char *pp_last_position_in_text (const pretty_printer *); |
| 560 | inline void pp_emit_prefix (pretty_printer *pp) |
| 561 | { |
| 562 | pp->emit_prefix (); |
| 563 | } |
| 564 | extern void pp_append_text (pretty_printer *, const char *, const char *); |
| 565 | extern void pp_newline_and_flush (pretty_printer *); |
| 566 | extern void pp_newline_and_indent (pretty_printer *, int); |
| 567 | extern void pp_separate_with (pretty_printer *, char); |
| 568 | |
| 569 | /* If we haven't already defined a front-end-specific diagnostics |
| 570 | style, use the generic one. */ |
| 571 | #ifdef GCC_DIAG_STYLE |
| 572 | #define GCC_PPDIAG_STYLE GCC_DIAG_STYLE |
| 573 | #else |
| 574 | #define GCC_PPDIAG_STYLE __gcc_diag__ |
| 575 | #endif |
| 576 | |
| 577 | /* This header may be included before diagnostics-core.h, hence the duplicate |
| 578 | definitions to allow for GCC-specific formats. */ |
| 579 | #if GCC_VERSION >= 3005 |
| 580 | #define ATTRIBUTE_GCC_PPDIAG(m, n) __attribute__ ((__format__ (GCC_PPDIAG_STYLE, m ,n))) ATTRIBUTE_NONNULL(m) |
| 581 | #else |
| 582 | #define ATTRIBUTE_GCC_PPDIAG(m, n) ATTRIBUTE_NONNULL(m) |
| 583 | #endif |
| 584 | extern void pp_printf (pretty_printer *, const char *, ...) |
| 585 | ATTRIBUTE_GCC_PPDIAG(2,3); |
| 586 | |
| 587 | extern void pp_printf_n (pretty_printer *, unsigned HOST_WIDE_INT n, |
| 588 | const char *, const char *, ...) |
| 589 | ATTRIBUTE_GCC_PPDIAG(3,5) |
| 590 | ATTRIBUTE_GCC_PPDIAG(4,5); |
| 591 | |
| 592 | extern void pp_verbatim (pretty_printer *, const char *, ...) |
| 593 | ATTRIBUTE_GCC_PPDIAG(2,3); |
| 594 | extern void pp_flush (pretty_printer *); |
| 595 | extern void pp_really_flush (pretty_printer *); |
| 596 | inline void pp_format (pretty_printer *pp, text_info *text) |
| 597 | { |
| 598 | gcc_assert (text); |
| 599 | pp->format (text&: *text); |
| 600 | } |
| 601 | extern void pp_output_formatted_text (pretty_printer *, |
| 602 | const urlifier * = nullptr); |
| 603 | extern void pp_format_verbatim (pretty_printer *, text_info *); |
| 604 | |
| 605 | extern void pp_indent (pretty_printer *); |
| 606 | extern void pp_newline (pretty_printer *); |
| 607 | extern void pp_character (pretty_printer *, int); |
| 608 | extern void pp_string (pretty_printer *, const char *); |
| 609 | extern void pp_string_n (pretty_printer *, const char *, size_t); |
| 610 | extern void pp_unicode_character (pretty_printer *, unsigned); |
| 611 | |
| 612 | extern void pp_write_text_to_stream (pretty_printer *); |
| 613 | extern void pp_write_text_as_dot_label_to_stream (pretty_printer *, bool); |
| 614 | extern void pp_write_text_as_html_like_dot_to_stream (pretty_printer *pp); |
| 615 | |
| 616 | inline void pp_maybe_space (pretty_printer *pp) |
| 617 | { |
| 618 | pp->maybe_space (); |
| 619 | } |
| 620 | |
| 621 | extern void pp_begin_quote (pretty_printer *, bool); |
| 622 | extern void pp_end_quote (pretty_printer *, bool); |
| 623 | |
| 624 | inline void |
| 625 | pp_begin_url (pretty_printer *pp, const char *url) |
| 626 | { |
| 627 | pp->begin_url (url); |
| 628 | } |
| 629 | |
| 630 | inline void |
| 631 | pp_end_url (pretty_printer *pp) |
| 632 | { |
| 633 | pp->end_url (); |
| 634 | } |
| 635 | |
| 636 | /* Switch into verbatim mode and return the old mode. */ |
| 637 | inline pp_wrapping_mode_t |
| 638 | pp_set_verbatim_wrapping (pretty_printer *pp) |
| 639 | { |
| 640 | return pp->set_verbatim_wrapping (); |
| 641 | } |
| 642 | |
| 643 | extern const char *identifier_to_locale (const char *); |
| 644 | extern void *(*identifier_to_locale_alloc) (size_t); |
| 645 | extern void (*identifier_to_locale_free) (void *); |
| 646 | |
| 647 | /* Print I to PP in decimal. */ |
| 648 | |
| 649 | inline void |
| 650 | pp_wide_integer (pretty_printer *pp, HOST_WIDE_INT i) |
| 651 | { |
| 652 | pp_scalar (pp, HOST_WIDE_INT_PRINT_DEC, i); |
| 653 | } |
| 654 | |
| 655 | inline void |
| 656 | pp_wide_int (pretty_printer *pp, const wide_int_ref &w, signop sgn) |
| 657 | { |
| 658 | unsigned int len; |
| 659 | print_dec_buf_size (wi: w, sgn, len: &len); |
| 660 | if (UNLIKELY (len > sizeof (pp_buffer (pp)->m_digit_buffer))) |
| 661 | pp_wide_int_large (pp, w, sgn); |
| 662 | else |
| 663 | { |
| 664 | print_dec (wi: w, buf: pp_buffer (pp)->m_digit_buffer, sgn); |
| 665 | pp_string (pp, pp_buffer (pp)->m_digit_buffer); |
| 666 | } |
| 667 | } |
| 668 | |
| 669 | template<unsigned int N, typename T> |
| 670 | void pp_wide_integer (pretty_printer *pp, const poly_int<N, T> &); |
| 671 | |
| 672 | #endif /* GCC_PRETTY_PRINT_H */ |
| 673 |
Definitions
- text_info
- text_info
- text_info
- diagnostic_prefixing_rule_t
- output_buffer
- output_buffer
- output_buffer
- operator=
- operator=
- dump
- output_buffer_formatted_text
- output_buffer_append_r
- output_buffer_last_position_in_text
- pp_padding
- pp_wrapping_mode_t
- format_postprocessor
- ~format_postprocessor
- token_printer
- ~token_printer
- pretty_printer
- set_output_stream
- set_token_printer
- supports_urls_p
- get_url_format
- set_url_format
- set_verbatim_wrapping
- set_padding
- get_padding
- set_format_postprocessor
- dump
- pp_buffer
- pp_buffer
- pp_get_prefix
- pp_needs_newline
- pp_indentation
- pp_translate_identifiers
- pp_show_color
- pp_format_decoder
- pp_format_postprocessor
- pp_show_highlight_colors
- pp_line_cutoff
- pp_prefixing_rule
- pp_prefixing_rule
- pp_wrapping_mode
- pp_set_prefix
- pp_emit_prefix
- pp_format
- pp_maybe_space
- pp_begin_url
- pp_end_url
- pp_set_verbatim_wrapping
- pp_wide_integer
Improve your Profiling and Debugging skills
Find out more
