/* Part of CPP library. Copyright (C) 1997-2026 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify itunder the terms of the GNU General Public License as published by theFree Software Foundation; either version 3, or (at your option) anylater version. This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details. You should have received a copy of the GNU General Public Licensealong with this program; see the file COPYING3. If not see<http://www.gnu.org/licenses/>. */ /* This header defines all the internal data structures and functions that need to be visible across files. It should not be used outside cpplib. */ #ifndef LIBCPP_INTERNAL_H#define LIBCPP_INTERNAL_H #include "symtab.h"#include "cpplib.h"#include "rich-location.h" #if HAVE_ICONV#include <iconv.h>#else#define HAVE_ICONV 0typedef int iconv_t; /* dummy */#endif #ifdef __cplusplusextern "C" {#endif struct directive; /* Deliberately incomplete. */struct pending_option;struct op;struct _cpp_strbuf; typedef bool (*convert_f) (iconv_t, const unsigned char *, size_t, struct _cpp_strbuf *);struct cset_converter{ convert_f func; iconv_t cd; int width; const char* from; const char* to;}; #define BITS_PER_CPPCHAR_T (CHAR_BIT * sizeof (cppchar_t)) /* Test if a sign is valid within a preprocessing number. */#define VALID_SIGN(c, prevc) \ (((c) == '+' || (c) == '-') && \ ((prevc) == 'e' || (prevc) == 'E' \ || (((prevc) == 'p' || (prevc) == 'P') \ && CPP_OPTION (pfile, extended_numbers)))) #define DIGIT_SEP(c) ((c) == '\'' && CPP_OPTION (pfile, digit_separators)) #define CPP_OPTION(PFILE, OPTION) ((PFILE)->opts.OPTION)#define CPP_BUFFER(PFILE) ((PFILE)->buffer)#define CPP_BUF_COLUMN(BUF, CUR) ((CUR) - (BUF)->line_base)#define CPP_BUF_COL(BUF) CPP_BUF_COLUMN(BUF, (BUF)->cur) #define CPP_INCREMENT_LINE(PFILE, COLS_HINT) do { \ const class line_maps *line_table = PFILE->line_table; \ const struct line_map_ordinary *map = \ LINEMAPS_LAST_ORDINARY_MAP (line_table); \ linenum_type line = SOURCE_LINE (map, line_table->highest_line); \ linemap_line_start (PFILE->line_table, line + 1, COLS_HINT); \ } while (0) /* Host alignment handling. */struct dummy{ char c; union { double d; int *p; location_t l; } u;}; #define DEFAULT_ALIGNMENT offsetof (struct dummy, u)#define CPP_ALIGN2(size, align) (((size) + ((align) - 1)) & ~((align) - 1))#define CPP_ALIGN(size) CPP_ALIGN2 (size, DEFAULT_ALIGNMENT) #define _cpp_mark_macro_used(NODE) \ (cpp_user_macro_p (NODE) ? (NODE)->value.macro->used = 1 : 0) /* A generic memory buffer, and operations on it. */typedef struct _cpp_buff _cpp_buff;struct _cpp_buff{ struct _cpp_buff *next; unsigned char *base, *cur, *limit;}; extern _cpp_buff *_cpp_get_buff (cpp_reader *, size_t);extern void _cpp_release_buff (cpp_reader *, _cpp_buff *);extern void _cpp_extend_buff (cpp_reader *, _cpp_buff **, size_t);extern _cpp_buff *_cpp_append_extend_buff (cpp_reader *, _cpp_buff *, size_t);extern void _cpp_free_buff (_cpp_buff *);extern unsigned char *_cpp_aligned_alloc (cpp_reader *, size_t);extern unsigned char *_cpp_unaligned_alloc (cpp_reader *, size_t); #define BUFF_ROOM(BUFF) (size_t) ((BUFF)->limit - (BUFF)->cur)#define BUFF_FRONT(BUFF) ((BUFF)->cur)#define BUFF_LIMIT(BUFF) ((BUFF)->limit) /* #include types. */enum include_type { /* Directive-based including mechanisms. */ IT_INCLUDE, /* #include */ IT_INCLUDE_NEXT, /* #include_next */ IT_IMPORT, /* #import */ IT_EMBED, /* #embed */ /* Non-directive including mechanisms. */ IT_CMDLINE, /* -include */ IT_DEFAULT, /* forced header */ IT_MAIN, /* main, start on line 1 */ IT_PRE_MAIN, /* main, but there will be a preamble before line 1 */ IT_DIRECTIVE_HWM = IT_IMPORT + 1, /* Directives below this. */ IT_HEADER_HWM = IT_DEFAULT + 1 /* Header files below this. */ }; union utoken{ const cpp_token *token; const cpp_token **ptoken;}; /* A "run" of tokens; part of a chain of runs. */typedef struct tokenrun tokenrun;struct tokenrun{ tokenrun *next, *prev; cpp_token *base, *limit;}; /* Accessor macros for struct cpp_context. */#define FIRST(c) ((c)->u.iso.first)#define LAST(c) ((c)->u.iso.last)#define CUR(c) ((c)->u.trad.cur)#define RLIMIT(c) ((c)->u.trad.rlimit) /* This describes some additional data that is added to the macro token context of type cpp_context, when -ftrack-macro-expansion is on. */typedef struct{ /* The node of the macro we are referring to. */ cpp_hashnode *macro_node; /* This buffer contains an array of virtual locations. The virtual location at index 0 is the virtual location of the token at index 0 in the current instance of cpp_context; similarly for all the other virtual locations. */ location_t *virt_locs; /* This is a pointer to the current virtual location. This is used to iterate over the virtual locations while we iterate over the tokens they belong to. */ location_t *cur_virt_loc;} macro_context; /* The kind of tokens carried by a cpp_context. */enum context_tokens_kind { /* This is the value of cpp_context::tokens_kind if u.iso.first contains an instance of cpp_token **. */ TOKENS_KIND_INDIRECT, /* This is the value of cpp_context::tokens_kind if u.iso.first contains an instance of cpp_token *. */ TOKENS_KIND_DIRECT, /* This is the value of cpp_context::tokens_kind when the token context contains tokens resulting from macro expansion. In that case struct cpp_context::macro points to an instance of struct macro_context. This is used only when the -ftrack-macro-expansion flag is on. */ TOKENS_KIND_EXTENDED}; typedef struct cpp_context cpp_context;struct cpp_context{ /* Doubly-linked list. */ cpp_context *next, *prev; union { /* For ISO macro expansion. Contexts other than the base context are contiguous tokens. e.g. macro expansions, expanded argument tokens. */ struct { union utoken first; union utoken last; } iso; /* For traditional macro expansion. */ struct { const unsigned char *cur; const unsigned char *rlimit; } trad; } u; /* If non-NULL, a buffer used for storage related to this context. When the context is popped, the buffer is released. */ _cpp_buff *buff; /* If tokens_kind is TOKEN_KIND_EXTENDED, then (as we thus are in a macro context) this is a pointer to an instance of macro_context. Otherwise if tokens_kind is *not* TOKEN_KIND_EXTENDED, then, if we are in a macro context, this is a pointer to an instance of cpp_hashnode, representing the name of the macro this context is for. If we are not in a macro context, then this is just NULL. Note that when tokens_kind is TOKEN_KIND_EXTENDED, the memory used by the instance of macro_context pointed to by this member is de-allocated upon de-allocation of the instance of struct cpp_context. */ union { macro_context *mc; cpp_hashnode *macro; } c; /* This determines the type of tokens held by this context. */ enum context_tokens_kind tokens_kind;}; struct lexer_state{ /* 1 if we're handling a directive. 2 if it's an include-like directive. */ unsigned char in_directive; /* Nonzero if in a directive that will handle padding tokens itself. #include needs this to avoid problems with computed include and spacing between tokens. */ unsigned char directive_wants_padding; /* True if we are skipping a failed conditional group. */ unsigned char skipping; /* Nonzero if in a directive that takes angle-bracketed headers. */ unsigned char angled_headers; /* Nonzero if in a #if or #elif directive. */ unsigned char in_expression; /* Nonzero to save comments. Turned off if discard_comments, and in all directives apart from #define. */ unsigned char save_comments; /* Nonzero if lexing __VA_ARGS__ and __VA_OPT__ are valid. */ unsigned char va_args_ok; /* Nonzero if lexing poisoned identifiers is valid. */ unsigned char poisoned_ok; /* Nonzero to prevent macro expansion. */ unsigned char prevent_expansion; /* Nonzero when parsing arguments to a function-like macro. */ unsigned char parsing_args; /* Nonzero if prevent_expansion is true only because output is being discarded. */ unsigned char discarding_output; /* Nonzero to skip evaluating part of an expression. */ unsigned int skip_eval; /* Nonzero if CPP_COMMA is valid in expression in C++. */ unsigned int comma_ok; /* Nonzero when tokenizing a deferred pragma. */ unsigned char in_deferred_pragma; /* Count to token that is a header-name. */ unsigned char directive_file_token; /* Nonzero if the deferred pragma being handled allows macro expansion. */ unsigned char pragma_allow_expansion; /* Nonzero if _Pragma should not be interpreted. */ unsigned char ignore__Pragma;}; /* Special nodes - identifiers with predefined significance. */struct spec_nodes{ cpp_hashnode *n_defined; /* defined operator */ cpp_hashnode *n_true; /* C++ keyword true */ cpp_hashnode *n_false; /* C++ keyword false */ cpp_hashnode *n__VA_ARGS__; /* C99 vararg macros */ cpp_hashnode *n__VA_OPT__; /* C++ vararg macros */ enum {M_EXPORT, M_MODULE, M_IMPORT, M__IMPORT, M_HWM}; /* C++20 modules, only set when module_directives is in effect. incoming variants [0], outgoing ones [1] */ cpp_hashnode *n_modules[M_HWM][2];}; typedef struct _cpp_line_note _cpp_line_note;struct _cpp_line_note{ /* Location in the clean line the note refers to. */ const unsigned char *pos; /* Type of note. The 9 'from' trigraph characters represent those trigraphs, '\\' an escaped newline, ' ' an escaped newline with intervening space, 'W' trailing whitespace, 'L', 'S' and 'T' for leading whitespace issues, 0 represents a note that has already been handled, and anything else is invalid. */ unsigned int type;}; /* Tail padding required by search_line_fast alternatives. */#ifdef HAVE_SSSE3#define CPP_BUFFER_PADDING 64#else#define CPP_BUFFER_PADDING 16#endif /* Represents the contents of a file cpplib has read in. */struct cpp_buffer{ const unsigned char *cur; /* Current location. */ const unsigned char *line_base; /* Start of current physical line. */ const unsigned char *next_line; /* Start of to-be-cleaned logical line. */ const unsigned char *buf; /* Entire character buffer. */ const unsigned char *rlimit; /* Writable byte at end of file. */ const unsigned char *to_free; /* Pointer that should be freed when popping the buffer. */ _cpp_line_note *notes; /* Array of notes. */ unsigned int cur_note; /* Next note to process. */ unsigned int notes_used; /* Number of notes. */ unsigned int notes_cap; /* Size of allocated array. */ struct cpp_buffer *prev; /* Pointer into the file table; non-NULL if this is a file buffer. Used for include_next and to record control macros. */ struct _cpp_file *file; /* Saved value of __TIMESTAMP__ macro - date and time of last modification of the assotiated file. */ const unsigned char *timestamp; /* Value of if_stack at start of this file. Used to prohibit unmatched #endif (etc) in an include file. */ struct if_stack *if_stack; /* True if we need to get the next clean line. */ bool need_line : 1; /* True if we have already warned about C++ comments in this file. The warning happens only for C89 extended mode with -pedantic on, or for -Wtraditional, and only once per file (otherwise it would be far too noisy). */ bool warned_cplusplus_comments : 1; /* True if we don't process trigraphs and escaped newlines. True for preprocessed input, command line directives, and _Pragma buffers. */ bool from_stage3 : 1; /* At EOF, a buffer is automatically popped. If RETURN_AT_EOF is true, a CPP_EOF token is then returned. Otherwise, the next token from the enclosing buffer is returned. */ bool return_at_eof : 1; /* One for a system header, two for a C system header file that therefore needs to be extern "C" protected in C++, and zero otherwise. */ unsigned char sysp; /* The directory of the this buffer's file. Its NAME member is not allocated, so we don't need to worry about freeing it. */ struct cpp_dir dir; /* Descriptor for converting from the input character set to the source character set. */ struct cset_converter input_cset_desc;}; /* The list of saved macros by push_macro pragma. */struct def_pragma_macro { /* Chain element to previous saved macro. */ struct def_pragma_macro *next; /* Name of the macro. */ char *name; /* The stored macro content. */ unsigned char *definition; /* Definition line number. */ location_t line; /* If macro defined in system header. */ unsigned int syshdr : 1; /* Nonzero if it has been expanded or had its existence tested. */ unsigned int used : 1; /* Mark if we save an undefined macro. */ unsigned int is_undef : 1; /* Nonzero if it was a builtin macro. */ unsigned int is_builtin : 1;}; /* A cpp_reader encapsulates the "state" of a pre-processor run. Applying cpp_get_token repeatedly yields a stream of pre-processor tokens. Usually, there is only one cpp_reader object active. */struct cpp_reader{ /* Top of buffer stack. */ cpp_buffer *buffer; /* Overlaid buffer (can be different after processing #include). */ cpp_buffer *overlaid_buffer; /* Lexer state. */ struct lexer_state state; /* Source line tracking. */ class line_maps *line_table; /* The line of the '#' of the current directive. */ location_t directive_line; /* Memory buffers. */ _cpp_buff *a_buff; /* Aligned permanent storage. */ _cpp_buff *u_buff; /* Unaligned permanent storage. */ _cpp_buff *free_buffs; /* Free buffer chain. */ /* Context stack. */ struct cpp_context base_context; struct cpp_context *context; /* If in_directive, the directive if known. */ const struct directive *directive; /* Token generated while handling a directive, if any. */ cpp_token directive_result; /* When expanding a macro at top-level, this is the location of the macro invocation. */ location_t invocation_location; /* This is the node representing the macro being expanded at top-level. The value of this data member is valid iff cpp_in_macro_expansion_p() returns TRUE. */ cpp_hashnode *top_most_macro_node; /* Nonzero if we are about to expand a macro. Note that if we are really expanding a macro, the function macro_of_context returns the macro being expanded and this flag is set to false. Client code should use the function cpp_in_macro_expansion_p to know if we are either about to expand a macro, or are actually expanding one. */ bool about_to_expand_macro_p; /* True if the preprocessor should diagnose CPP_DOT or CPP_COLON tokens as the first ones coming from macro expansion. */ bool diagnose_dot_colon_from_macro_p; /* Search paths for include files. */ struct cpp_dir *quote_include; /* "" */ struct cpp_dir *bracket_include; /* <> */ struct cpp_dir no_search_path; /* No path. */ struct cpp_dir *embed_include; /* #embed <> */ /* Chain of all hashed _cpp_file instances. */ struct _cpp_file *all_files; struct _cpp_file *main_file; /* File and directory hash table. */ struct htab *file_hash; struct htab *dir_hash; struct file_hash_entry_pool *file_hash_entries; /* Negative path lookup hash table. */ struct htab *nonexistent_file_hash; struct obstack nonexistent_file_ob; /* Nonzero means don't look for #include "foo" the source-file directory. */Lines 1–500 of 1044. Load more
/* Part of CPP library. Copyright (C) 1997-2026 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; see the file COPYING3. If not see <http://www.gnu.org/licenses/>. */ /* This header defines all the internal data structures and functions that need to be visible across files. It should not be used outside cpplib. */ #ifndef LIBCPP_INTERNAL_H #define LIBCPP_INTERNAL_H #include "symtab.h" #include "cpplib.h" #include "rich-location.h" #if HAVE_ICONV #include <iconv.h> #else #define HAVE_ICONV 0 typedef int iconv_t; /* dummy */ #endif #ifdef __cplusplus extern "C" { #endif struct directive; /* Deliberately incomplete. */ struct pending_option; struct op; struct _cpp_strbuf; typedef bool (*convert_f) (iconv_t, const unsigned char *, size_t, struct _cpp_strbuf *); struct cset_converter { convert_f func; iconv_t cd; int width; const char* from; const char* to; }; #define BITS_PER_CPPCHAR_T (CHAR_BIT * sizeof (cppchar_t)) /* Test if a sign is valid within a preprocessing number. */ #define VALID_SIGN(c, prevc) \ (((c) == '+' || (c) == '-') && \ ((prevc) == 'e' || (prevc) == 'E' \ || (((prevc) == 'p' || (prevc) == 'P') \ && CPP_OPTION (pfile, extended_numbers)))) #define DIGIT_SEP(c) ((c) == '\'' && CPP_OPTION (pfile, digit_separators)) #define CPP_OPTION(PFILE, OPTION) ((PFILE)->opts.OPTION) #define CPP_BUFFER(PFILE) ((PFILE)->buffer) #define CPP_BUF_COLUMN(BUF, CUR) ((CUR) - (BUF)->line_base) #define CPP_BUF_COL(BUF) CPP_BUF_COLUMN(BUF, (BUF)->cur) #define CPP_INCREMENT_LINE(PFILE, COLS_HINT) do { \ const class line_maps *line_table = PFILE->line_table; \ const struct line_map_ordinary *map = \ LINEMAPS_LAST_ORDINARY_MAP (line_table); \ linenum_type line = SOURCE_LINE (map, line_table->highest_line); \ linemap_line_start (PFILE->line_table, line + 1, COLS_HINT); \ } while (0) /* Host alignment handling. */ struct dummy { char c; union { double d; int *p; location_t l; } u; }; #define DEFAULT_ALIGNMENT offsetof (struct dummy, u) #define CPP_ALIGN2(size, align) (((size) + ((align) - 1)) & ~((align) - 1)) #define CPP_ALIGN(size) CPP_ALIGN2 (size, DEFAULT_ALIGNMENT) #define _cpp_mark_macro_used(NODE) \ (cpp_user_macro_p (NODE) ? (NODE)->value.macro->used = 1 : 0) /* A generic memory buffer, and operations on it. */ typedef struct _cpp_buff _cpp_buff; struct _cpp_buff { struct _cpp_buff *next; unsigned char *base, *cur, *limit; }; extern _cpp_buff *_cpp_get_buff (cpp_reader *, size_t); extern void _cpp_release_buff (cpp_reader *, _cpp_buff *); extern void _cpp_extend_buff (cpp_reader *, _cpp_buff **, size_t); extern _cpp_buff *_cpp_append_extend_buff (cpp_reader *, _cpp_buff *, size_t); extern void _cpp_free_buff (_cpp_buff *); extern unsigned char *_cpp_aligned_alloc (cpp_reader *, size_t); extern unsigned char *_cpp_unaligned_alloc (cpp_reader *, size_t); #define BUFF_ROOM(BUFF) (size_t) ((BUFF)->limit - (BUFF)->cur) #define BUFF_FRONT(BUFF) ((BUFF)->cur) #define BUFF_LIMIT(BUFF) ((BUFF)->limit) /* #include types. */ enum include_type { /* Directive-based including mechanisms. */ IT_INCLUDE, /* #include */ IT_INCLUDE_NEXT, /* #include_next */ IT_IMPORT, /* #import */ IT_EMBED, /* #embed */ /* Non-directive including mechanisms. */ IT_CMDLINE, /* -include */ IT_DEFAULT, /* forced header */ IT_MAIN, /* main, start on line 1 */ IT_PRE_MAIN, /* main, but there will be a preamble before line 1 */ IT_DIRECTIVE_HWM = IT_IMPORT + 1, /* Directives below this. */ IT_HEADER_HWM = IT_DEFAULT + 1 /* Header files below this. */ }; union utoken { const cpp_token *token; const cpp_token **ptoken; }; /* A "run" of tokens; part of a chain of runs. */ typedef struct tokenrun tokenrun; struct tokenrun { tokenrun *next, *prev; cpp_token *base, *limit; }; /* Accessor macros for struct cpp_context. */ #define FIRST(c) ((c)->u.iso.first) #define LAST(c) ((c)->u.iso.last) #define CUR(c) ((c)->u.trad.cur) #define RLIMIT(c) ((c)->u.trad.rlimit) /* This describes some additional data that is added to the macro token context of type cpp_context, when -ftrack-macro-expansion is on. */ typedef struct { /* The node of the macro we are referring to. */ cpp_hashnode *macro_node; /* This buffer contains an array of virtual locations. The virtual location at index 0 is the virtual location of the token at index 0 in the current instance of cpp_context; similarly for all the other virtual locations. */ location_t *virt_locs; /* This is a pointer to the current virtual location. This is used to iterate over the virtual locations while we iterate over the tokens they belong to. */ location_t *cur_virt_loc; } macro_context; /* The kind of tokens carried by a cpp_context. */ enum context_tokens_kind { /* This is the value of cpp_context::tokens_kind if u.iso.first contains an instance of cpp_token **. */ TOKENS_KIND_INDIRECT, /* This is the value of cpp_context::tokens_kind if u.iso.first contains an instance of cpp_token *. */ TOKENS_KIND_DIRECT, /* This is the value of cpp_context::tokens_kind when the token context contains tokens resulting from macro expansion. In that case struct cpp_context::macro points to an instance of struct macro_context. This is used only when the -ftrack-macro-expansion flag is on. */ TOKENS_KIND_EXTENDED }; typedef struct cpp_context cpp_context; struct cpp_context { /* Doubly-linked list. */ cpp_context *next, *prev; union { /* For ISO macro expansion. Contexts other than the base context are contiguous tokens. e.g. macro expansions, expanded argument tokens. */ struct { union utoken first; union utoken last; } iso; /* For traditional macro expansion. */ struct { const unsigned char *cur; const unsigned char *rlimit; } trad; } u; /* If non-NULL, a buffer used for storage related to this context. When the context is popped, the buffer is released. */ _cpp_buff *buff; /* If tokens_kind is TOKEN_KIND_EXTENDED, then (as we thus are in a macro context) this is a pointer to an instance of macro_context. Otherwise if tokens_kind is *not* TOKEN_KIND_EXTENDED, then, if we are in a macro context, this is a pointer to an instance of cpp_hashnode, representing the name of the macro this context is for. If we are not in a macro context, then this is just NULL. Note that when tokens_kind is TOKEN_KIND_EXTENDED, the memory used by the instance of macro_context pointed to by this member is de-allocated upon de-allocation of the instance of struct cpp_context. */ union { macro_context *mc; cpp_hashnode *macro; } c; /* This determines the type of tokens held by this context. */ enum context_tokens_kind tokens_kind; }; struct lexer_state { /* 1 if we're handling a directive. 2 if it's an include-like directive. */ unsigned char in_directive; /* Nonzero if in a directive that will handle padding tokens itself. #include needs this to avoid problems with computed include and spacing between tokens. */ unsigned char directive_wants_padding; /* True if we are skipping a failed conditional group. */ unsigned char skipping; /* Nonzero if in a directive that takes angle-bracketed headers. */ unsigned char angled_headers; /* Nonzero if in a #if or #elif directive. */ unsigned char in_expression; /* Nonzero to save comments. Turned off if discard_comments, and in all directives apart from #define. */ unsigned char save_comments; /* Nonzero if lexing __VA_ARGS__ and __VA_OPT__ are valid. */ unsigned char va_args_ok; /* Nonzero if lexing poisoned identifiers is valid. */ unsigned char poisoned_ok; /* Nonzero to prevent macro expansion. */ unsigned char prevent_expansion; /* Nonzero when parsing arguments to a function-like macro. */ unsigned char parsing_args; /* Nonzero if prevent_expansion is true only because output is being discarded. */ unsigned char discarding_output; /* Nonzero to skip evaluating part of an expression. */ unsigned int skip_eval; /* Nonzero if CPP_COMMA is valid in expression in C++. */ unsigned int comma_ok; /* Nonzero when tokenizing a deferred pragma. */ unsigned char in_deferred_pragma; /* Count to token that is a header-name. */ unsigned char directive_file_token; /* Nonzero if the deferred pragma being handled allows macro expansion. */ unsigned char pragma_allow_expansion; /* Nonzero if _Pragma should not be interpreted. */ unsigned char ignore__Pragma; }; /* Special nodes - identifiers with predefined significance. */ struct spec_nodes { cpp_hashnode *n_defined; /* defined operator */ cpp_hashnode *n_true; /* C++ keyword true */ cpp_hashnode *n_false; /* C++ keyword false */ cpp_hashnode *n__VA_ARGS__; /* C99 vararg macros */ cpp_hashnode *n__VA_OPT__; /* C++ vararg macros */ enum {M_EXPORT, M_MODULE, M_IMPORT, M__IMPORT, M_HWM}; /* C++20 modules, only set when module_directives is in effect. incoming variants [0], outgoing ones [1] */ cpp_hashnode *n_modules[M_HWM][2]; }; typedef struct _cpp_line_note _cpp_line_note; struct _cpp_line_note { /* Location in the clean line the note refers to. */ const unsigned char *pos; /* Type of note. The 9 'from' trigraph characters represent those trigraphs, '\\' an escaped newline, ' ' an escaped newline with intervening space, 'W' trailing whitespace, 'L', 'S' and 'T' for leading whitespace issues, 0 represents a note that has already been handled, and anything else is invalid. */ unsigned int type; }; /* Tail padding required by search_line_fast alternatives. */ #ifdef HAVE_SSSE3 #define CPP_BUFFER_PADDING 64 #else #define CPP_BUFFER_PADDING 16 #endif /* Represents the contents of a file cpplib has read in. */ struct cpp_buffer { const unsigned char *cur; /* Current location. */ const unsigned char *line_base; /* Start of current physical line. */ const unsigned char *next_line; /* Start of to-be-cleaned logical line. */ const unsigned char *buf; /* Entire character buffer. */ const unsigned char *rlimit; /* Writable byte at end of file. */ const unsigned char *to_free; /* Pointer that should be freed when popping the buffer. */ _cpp_line_note *notes; /* Array of notes. */ unsigned int cur_note; /* Next note to process. */ unsigned int notes_used; /* Number of notes. */ unsigned int notes_cap; /* Size of allocated array. */ struct cpp_buffer *prev; /* Pointer into the file table; non-NULL if this is a file buffer. Used for include_next and to record control macros. */ struct _cpp_file *file; /* Saved value of __TIMESTAMP__ macro - date and time of last modification of the assotiated file. */ const unsigned char *timestamp; /* Value of if_stack at start of this file. Used to prohibit unmatched #endif (etc) in an include file. */ struct if_stack *if_stack; /* True if we need to get the next clean line. */ bool need_line : 1; /* True if we have already warned about C++ comments in this file. The warning happens only for C89 extended mode with -pedantic on, or for -Wtraditional, and only once per file (otherwise it would be far too noisy). */ bool warned_cplusplus_comments : 1; /* True if we don't process trigraphs and escaped newlines. True for preprocessed input, command line directives, and _Pragma buffers. */ bool from_stage3 : 1; /* At EOF, a buffer is automatically popped. If RETURN_AT_EOF is true, a CPP_EOF token is then returned. Otherwise, the next token from the enclosing buffer is returned. */ bool return_at_eof : 1; /* One for a system header, two for a C system header file that therefore needs to be extern "C" protected in C++, and zero otherwise. */ unsigned char sysp; /* The directory of the this buffer's file. Its NAME member is not allocated, so we don't need to worry about freeing it. */ struct cpp_dir dir; /* Descriptor for converting from the input character set to the source character set. */ struct cset_converter input_cset_desc; }; /* The list of saved macros by push_macro pragma. */ struct def_pragma_macro { /* Chain element to previous saved macro. */ struct def_pragma_macro *next; /* Name of the macro. */ char *name; /* The stored macro content. */ unsigned char *definition; /* Definition line number. */ location_t line; /* If macro defined in system header. */ unsigned int syshdr : 1; /* Nonzero if it has been expanded or had its existence tested. */ unsigned int used : 1; /* Mark if we save an undefined macro. */ unsigned int is_undef : 1; /* Nonzero if it was a builtin macro. */ unsigned int is_builtin : 1; }; /* A cpp_reader encapsulates the "state" of a pre-processor run. Applying cpp_get_token repeatedly yields a stream of pre-processor tokens. Usually, there is only one cpp_reader object active. */ struct cpp_reader { /* Top of buffer stack. */ cpp_buffer *buffer; /* Overlaid buffer (can be different after processing #include). */ cpp_buffer *overlaid_buffer; /* Lexer state. */ struct lexer_state state; /* Source line tracking. */ class line_maps *line_table; /* The line of the '#' of the current directive. */ location_t directive_line; /* Memory buffers. */ _cpp_buff *a_buff; /* Aligned permanent storage. */ _cpp_buff *u_buff; /* Unaligned permanent storage. */ _cpp_buff *free_buffs; /* Free buffer chain. */ /* Context stack. */ struct cpp_context base_context; struct cpp_context *context; /* If in_directive, the directive if known. */ const struct directive *directive; /* Token generated while handling a directive, if any. */ cpp_token directive_result; /* When expanding a macro at top-level, this is the location of the macro invocation. */ location_t invocation_location; /* This is the node representing the macro being expanded at top-level. The value of this data member is valid iff cpp_in_macro_expansion_p() returns TRUE. */ cpp_hashnode *top_most_macro_node; /* Nonzero if we are about to expand a macro. Note that if we are really expanding a macro, the function macro_of_context returns the macro being expanded and this flag is set to false. Client code should use the function cpp_in_macro_expansion_p to know if we are either about to expand a macro, or are actually expanding one. */ bool about_to_expand_macro_p; /* True if the preprocessor should diagnose CPP_DOT or CPP_COLON tokens as the first ones coming from macro expansion. */ bool diagnose_dot_colon_from_macro_p; /* Search paths for include files. */ struct cpp_dir *quote_include; /* "" */ struct cpp_dir *bracket_include; /* <> */ struct cpp_dir no_search_path; /* No path. */ struct cpp_dir *embed_include; /* #embed <> */ /* Chain of all hashed _cpp_file instances. */ struct _cpp_file *all_files; struct _cpp_file *main_file; /* File and directory hash table. */ struct htab *file_hash; struct htab *dir_hash; struct file_hash_entry_pool *file_hash_entries; /* Negative path lookup hash table. */ struct htab *nonexistent_file_hash; struct obstack nonexistent_file_ob; /* Nonzero means don't look for #include "foo" the source-file directory. */