/* Part of CPP library.
- Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007,
- 2008, 2009, 2010 Free Software Foundation, Inc.
+ Copyright (C) 1997-2018 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
|| (((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_INCREMENT_LINE(PFILE, COLS_HINT) do { \
const struct line_maps *line_table = PFILE->line_table; \
- const struct line_map *map = &line_table->maps[line_table->used-1]; \
+ 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)
#define BUFF_LIMIT(BUFF) ((BUFF)->limit)
/* #include types. */
-enum include_type {IT_INCLUDE, IT_INCLUDE_NEXT, IT_IMPORT, IT_CMDLINE};
+enum include_type {IT_INCLUDE, IT_INCLUDE_NEXT, IT_IMPORT, IT_CMDLINE, IT_DEFAULT};
union utoken
{
#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. */
+ source_location *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. */
+ source_location *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
{
When the context is popped, the buffer is released. */
_cpp_buff *buff;
- /* For a macro context, the macro node, otherwise NULL. */
- cpp_hashnode *macro;
+ /* 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;
- /* True if utoken element is token, else ptoken. */
- bool direct_p;
+ /* This determines the type of tokens held by this context. */
+ enum context_tokens_kind tokens_kind;
};
struct lexer_state
all directives apart from #define. */
unsigned char save_comments;
- /* Nonzero if lexing __VA_ARGS__ is valid. */
+ /* Nonzero if lexing __VA_ARGS__ and __VA_OPT__ are valid. */
unsigned char va_args_ok;
/* Nonzero if lexing poisoned identifiers is valid. */
/* Nonzero when parsing arguments to a function-like macro. */
unsigned char parsing_args;
+ /* Nonzero if in a __has_include__ or __has_include_next__ statement. */
+ unsigned char in__has_include__;
+
/* Nonzero if prevent_expansion is true only because output is
being discarded. */
unsigned char discarding_output;
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 */
+ cpp_hashnode *n__has_include__; /* __has_include__ operator */
+ cpp_hashnode *n__has_include_next__; /* __has_include_next__ operator */
};
typedef struct _cpp_line_note _cpp_line_note;
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. */
macro invocation. */
source_location invocation_location;
- /* True if this call to cpp_get_token should consider setting
- invocation_location. */
- bool set_invocation_location;
+ /* This is the node representing the macro being expanded at
+ top-level. The value of this data member is valid iff
+ 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 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;
/* Search paths for include files. */
struct cpp_dir *quote_include; /* "" */
const unsigned char *date;
const unsigned char *time;
+ /* Externally set timestamp to replace current date and time useful for
+ reproducibility. It should be initialized to -2 (not yet set) and
+ set to -1 to disable it or to a non-negative value to enable it. */
+ time_t source_date_epoch;
+
/* EOF token, and a token forcing paste avoidance. */
cpp_token avoid_paste;
cpp_token eof;
/* List of saved macros by push_macro. */
struct def_pragma_macro *pushed_macros;
+
+ /* If non-null, the lexer will use this location for the next token
+ instead of getting a location from the linemap. */
+ source_location *forced_token_location_p;
};
/* Character classes. Based on the more primitive macros in safe-ctype.h.
extern void _cpp_pop_context (cpp_reader *);
extern void _cpp_push_text_context (cpp_reader *, cpp_hashnode *,
const unsigned char *, size_t);
-extern bool _cpp_save_parameter (cpp_reader *, cpp_macro *, cpp_hashnode *);
+extern bool _cpp_save_parameter (cpp_reader *, cpp_macro *, cpp_hashnode *,
+ cpp_hashnode *);
extern bool _cpp_arguments_ok (cpp_reader *, cpp_macro *, const cpp_hashnode *,
unsigned int);
extern const unsigned char *_cpp_builtin_macro_text (cpp_reader *,
- cpp_hashnode *);
+ cpp_hashnode *,
+ source_location = 0);
extern int _cpp_warn_if_unused_macro (cpp_reader *, cpp_hashnode *, void *);
extern void _cpp_push_token_context (cpp_reader *, cpp_hashnode *,
const cpp_token *, unsigned int);
extern void _cpp_backup_tokens_direct (cpp_reader *, unsigned int);
/* In identifiers.c */
-extern void _cpp_init_hashtable (cpp_reader *, hash_table *);
+extern void _cpp_init_hashtable (cpp_reader *, cpp_hash_table *);
extern void _cpp_destroy_hashtable (cpp_reader *);
/* In files.c */
typedef struct _cpp_file _cpp_file;
extern _cpp_file *_cpp_find_file (cpp_reader *, const char *, cpp_dir *,
- bool, int);
+ bool, int, bool, source_location);
extern bool _cpp_find_failed (_cpp_file *);
extern void _cpp_mark_file_once_only (cpp_reader *, struct _cpp_file *);
extern void _cpp_fake_include (cpp_reader *, const char *);
-extern bool _cpp_stack_file (cpp_reader *, _cpp_file*, bool);
+extern bool _cpp_stack_file (cpp_reader *, _cpp_file*, bool,
+ source_location);
extern bool _cpp_stack_include (cpp_reader *, const char *, int,
- enum include_type);
+ enum include_type, source_location);
extern int _cpp_compare_file_date (cpp_reader *, const char *, int);
extern void _cpp_report_missing_guards (cpp_reader *);
extern void _cpp_init_files (cpp_reader *);
extern void _cpp_cleanup_files (cpp_reader *);
-extern void _cpp_pop_file_buffer (cpp_reader *, struct _cpp_file *);
+extern void _cpp_pop_file_buffer (cpp_reader *, struct _cpp_file *,
+ const unsigned char *);
extern bool _cpp_save_file_entries (cpp_reader *pfile, FILE *f);
extern bool _cpp_read_file_entries (cpp_reader *, FILE *);
+extern const char *_cpp_get_file_name (_cpp_file *);
extern struct stat *_cpp_get_file_stat (_cpp_file *);
+extern bool _cpp_has_header (cpp_reader *, const char *, int,
+ enum include_type);
/* In expr.c */
extern bool _cpp_parse_expr (cpp_reader *, bool);
extern cpp_token *_cpp_temp_token (cpp_reader *);
extern const cpp_token *_cpp_lex_token (cpp_reader *);
extern cpp_token *_cpp_lex_direct (cpp_reader *);
+extern unsigned char *_cpp_spell_ident_ucns (unsigned char *, cpp_hashnode *);
extern int _cpp_equiv_tokens (const cpp_token *, const cpp_token *);
extern void _cpp_init_tokenrun (tokenrun *, unsigned int);
extern cpp_hashnode *_cpp_lex_identifier (cpp_reader *, const char *);
+extern int _cpp_remaining_tokens_num_in_context (cpp_context *);
+extern void _cpp_init_lexer (void);
/* In init.c. */
extern void _cpp_maybe_push_include_file (cpp_reader *);
extern void _cpp_define_builtin (cpp_reader *, const char *);
extern char ** _cpp_save_pragma_names (cpp_reader *);
extern void _cpp_restore_pragma_names (cpp_reader *, char **);
-extern int _cpp_do__Pragma (cpp_reader *);
+extern int _cpp_do__Pragma (cpp_reader *, source_location);
extern void _cpp_init_directives (cpp_reader *);
extern void _cpp_init_internal_pragmas (cpp_reader *);
extern void _cpp_do_file_change (cpp_reader *, enum lc_reason, const char *,
linenum_type, unsigned int);
extern void _cpp_pop_buffer (cpp_reader *);
+extern char *_cpp_bracket_include (cpp_reader *);
/* In directives.c */
struct _cpp_dir_only_callbacks
{
/* Called to print a block of lines. */
void (*print_lines) (int, const void *, size_t);
- void (*maybe_print_line) (source_location);
+ bool (*maybe_print_line) (source_location);
};
extern void _cpp_preprocess_dir_only (cpp_reader *,
const struct _cpp_dir_only_callbacks *);
/* In traditional.c. */
-extern bool _cpp_scan_out_logical_line (cpp_reader *, cpp_macro *);
+extern bool _cpp_scan_out_logical_line (cpp_reader *, cpp_macro *, bool);
extern bool _cpp_read_logical_line_trad (cpp_reader *);
extern void _cpp_overlay_buffer (cpp_reader *pfile, const unsigned char *,
size_t);
struct normalize_state
{
- /* The previous character. */
+ /* The previous starter character. */
cppchar_t previous;
- /* The combining class of the previous character. */
+ /* The combining class of the previous character (whether or not a
+ starter). */
unsigned char prev_class;
/* The lowest normalization level so far. */
enum cpp_normalize_level level;
#define INITIAL_NORMALIZE_STATE { 0, 0, normalized_KC }
#define NORMALIZE_STATE_RESULT(st) ((st)->level)
-/* We saw a character that matches ISIDNUM(), update a
+/* We saw a character C that matches ISIDNUM(), update a
normalize_state appropriately. */
-#define NORMALIZE_STATE_UPDATE_IDNUM(st) \
- ((st)->previous = 0, (st)->prev_class = 0)
-
-extern cppchar_t _cpp_valid_ucn (cpp_reader *, const unsigned char **,
- const unsigned char *, int,
- struct normalize_state *state);
+#define NORMALIZE_STATE_UPDATE_IDNUM(st, c) \
+ ((st)->previous = (c), (st)->prev_class = 0)
+
+extern bool _cpp_valid_ucn (cpp_reader *, const unsigned char **,
+ const unsigned char *, int,
+ struct normalize_state *state,
+ cppchar_t *,
+ source_range *char_range,
+ cpp_string_location_reader *loc_reader);
extern void _cpp_destroy_iconv (cpp_reader *);
extern unsigned char *_cpp_convert_input (cpp_reader *, const char *,
unsigned char *, size_t, size_t,
static inline int ustrncmp (const unsigned char *, const unsigned char *,
size_t);
static inline size_t ustrlen (const unsigned char *);
-static inline unsigned char *uxstrdup (const unsigned char *);
-static inline unsigned char *ustrchr (const unsigned char *, int);
+static inline const unsigned char *uxstrdup (const unsigned char *);
+static inline const unsigned char *ustrchr (const unsigned char *, int);
static inline int ufputs (const unsigned char *, FILE *);
/* Use a const char for the second parameter since it is usually a literal. */
return strlen ((const char *)s1);
}
-static inline unsigned char *
+static inline const unsigned char *
uxstrdup (const unsigned char *s1)
{
- return (unsigned char *) xstrdup ((const char *)s1);
+ return (const unsigned char *) xstrdup ((const char *)s1);
}
-static inline unsigned char *
+static inline const unsigned char *
ustrchr (const unsigned char *s1, int c)
{
- return (unsigned char *) strchr ((const char *)s1, c);
+ return (const unsigned char *) strchr ((const char *)s1, c);
}
static inline int
return fputs ((const char *)s, f);
}
+ /* In line-map.c. */
+
+/* Create a macro map. A macro map encodes source locations of tokens
+ that are part of a macro replacement-list, at a macro expansion
+ point. See the extensive comments of struct line_map and struct
+ line_map_macro, in line-map.h.
+
+ This map shall be created when the macro is expanded. The map
+ encodes the source location of the expansion point of the macro as
+ well as the "original" source location of each token that is part
+ of the macro replacement-list. If a macro is defined but never
+ expanded, it has no macro map. SET is the set of maps the macro
+ map should be part of. MACRO_NODE is the macro which the new macro
+ map should encode source locations for. EXPANSION is the location
+ of the expansion point of MACRO. For function-like macros
+ invocations, it's best to make it point to the closing parenthesis
+ of the macro, rather than the the location of the first character
+ of the macro. NUM_TOKENS is the number of tokens that are part of
+ the replacement-list of MACRO. */
+const line_map_macro *linemap_enter_macro (struct line_maps *,
+ struct cpp_hashnode*,
+ source_location,
+ unsigned int);
+
+/* Create and return a virtual location for a token that is part of a
+ macro expansion-list at a macro expansion point. See the comment
+ inside struct line_map_macro to see what an expansion-list exactly
+ is.
+
+ A call to this function must come after a call to
+ linemap_enter_macro.
+
+ MAP is the map into which the source location is created. TOKEN_NO
+ is the index of the token in the macro replacement-list, starting
+ at number 0.
+
+ ORIG_LOC is the location of the token outside of this macro
+ expansion. If the token comes originally from the macro
+ definition, it is the locus in the macro definition; otherwise it
+ is a location in the context of the caller of this macro expansion
+ (which is a virtual location or a source location if the caller is
+ itself a macro expansion or not).
+
+ MACRO_DEFINITION_LOC is the location in the macro definition,
+ either of the token itself or of a macro parameter that it
+ replaces. */
+source_location linemap_add_macro_token (const line_map_macro *,
+ unsigned int,
+ source_location,
+ source_location);
+
+/* Return the source line number corresponding to source location
+ LOCATION. SET is the line map set LOCATION comes from. If
+ LOCATION is the location of token that is part of the
+ expansion-list of a macro expansion return the line number of the
+ macro expansion point. */
+int linemap_get_expansion_line (struct line_maps *,
+ source_location);
+
+/* Return the path of the file corresponding to source code location
+ LOCATION.
+
+ If LOCATION is the location of a token that is part of the
+ replacement-list of a macro expansion return the file path of the
+ macro expansion point.
+
+ SET is the line map set LOCATION comes from. */
+const char* linemap_get_expansion_filename (struct line_maps *,
+ source_location);
+
#ifdef __cplusplus
}
#endif