c-lex.c (map): Make const.

* c-lex.c (map): Make const.
	(cb_file_change): Update for callback passing a line map.
	Don't assume we have a previous map.  Remove sanity check
	about popping too many files.
	* cpperror.c (print_location): Make map const.
	* cppfiles.c (stack_include_file): Update; line maps now hold sysp.
	(cpp_make_system_header): Similarly.
	(search_from): Similarly.
	(_cpp_execute_include): Don't remember where we came from.
	* cpphash.h (struct cpp_buffer): Remove return_to_line, sysp.
	(struct cpp_reader): Make map const.
	(CPP_IN_SYSTEM_HEADER, _cpp_do_file_change): Update.
	* cpplib.c (do_line): Update; line maps now hold sysp.
	(cpp_push_buffer): Similarly.
	(_cpp_do_file_change): Similarly; callback with map instead.
	(cpp_get_line_maps): Constify return value.
	(_cpp_pop_buffer): Update.
	* cpplib.h (struct cpp_file_change): Remove.
	(struct cpp_callbacks): Update.
	(cpp_get_line_maps): Constify return value.
	* cppmacro.c (_cpp_create_definition): Update.
	* cppmain.c (struct printer): Constify map.
	(maybe_print_line): Similarly.
	(print_line): Similarly.  Deduce flags 1 and 2 here.
	(cb_file_change): Update.
	* line-map.c (free_line_maps): Warn regardless.
	(add_line_map): Return pointer to const.  When passed NULL to_file
	with LC_LEAVE, use the obvious values for the return point so the
	caller doesn't have to figure them out.
	(lookup_line): Return pointer to const.
	(print_containing_files): Take pointer to const.
	* line-map.h (struct line_map): New members reason, sysp.
	(add_line_map): Return pointer to const.
	(lookup_line): Similarly.
	(print_containing_files): Take pointer to const.

From-SVN: r44789
This commit is contained in:
Neil Booth 2001-08-11 07:33:39 +00:00
parent 16568b922e
commit 47d89cf3e6
10 changed files with 163 additions and 163 deletions

View file

@ -58,7 +58,7 @@ Boston, MA 02111-1307, USA. */
static const char *cpp_filename;
/* The current line map. */
static struct line_map *map;
static const struct line_map *map;
/* We may keep statistics about how long which files took to compile. */
static int header_time, body_time;
@ -91,7 +91,7 @@ static void update_header_times PARAMS ((const char *));
static int dump_one_header PARAMS ((splay_tree_node, void *));
static void cb_ident PARAMS ((cpp_reader *, unsigned int,
const cpp_string *));
static void cb_file_change PARAMS ((cpp_reader *, const cpp_file_change *));
static void cb_file_change PARAMS ((cpp_reader *, const struct line_map *));
static void cb_def_pragma PARAMS ((cpp_reader *, unsigned int));
static void cb_define PARAMS ((cpp_reader *, unsigned int,
cpp_hashnode *));
@ -244,28 +244,28 @@ cb_ident (pfile, line, str)
}
static void
cb_file_change (pfile, fc)
cb_file_change (pfile, new_map)
cpp_reader *pfile ATTRIBUTE_UNUSED;
const cpp_file_change *fc;
const struct line_map *new_map;
{
unsigned int from_line = SOURCE_LINE (fc->map - 1, fc->line - 1);
unsigned int to_line = SOURCE_LINE (new_map, new_map->to_line);
if (fc->reason == LC_ENTER)
if (new_map->reason == LC_ENTER)
{
/* Don't stack the main buffer on the input stack;
we already did in compile_file. */
if (MAIN_FILE_P (fc->map))
main_input_filename = fc->map->to_file;
if (map == NULL)
main_input_filename = new_map->to_file;
else
{
lineno = from_line;
push_srcloc (fc->map->to_file, 1);
lineno = SOURCE_LINE (new_map - 1, new_map->from_line - 1);
push_srcloc (new_map->to_file, 1);
input_file_stack->indent_level = indent_level;
(*debug_hooks->start_source_file) (lineno, fc->map->to_file);
(*debug_hooks->start_source_file) (lineno, new_map->to_file);
#ifndef NO_IMPLICIT_EXTERN_C
if (c_header_level)
++c_header_level;
else if (fc->externc)
else if (new_map->sysp == 2)
{
c_header_level = 1;
++pending_lang_change;
@ -273,41 +273,36 @@ cb_file_change (pfile, fc)
#endif
}
}
else if (fc->reason == LC_LEAVE)
else if (new_map->reason == LC_LEAVE)
{
/* Popping out of a file. */
if (input_file_stack->next)
{
#ifndef NO_IMPLICIT_EXTERN_C
if (c_header_level && --c_header_level == 0)
{
if (fc->externc)
warning ("badly nested C headers from preprocessor");
--pending_lang_change;
}
if (c_header_level && --c_header_level == 0)
{
if (new_map->sysp == 2)
warning ("badly nested C headers from preprocessor");
--pending_lang_change;
}
#endif
#if 0
if (indent_level != input_file_stack->indent_level)
{
warning_with_file_and_line
(input_filename, lineno,
"This file contains more '%c's than '%c's.",
indent_level > input_file_stack->indent_level ? '{' : '}',
indent_level > input_file_stack->indent_level ? '}' : '{');
}
#endif
pop_srcloc ();
(*debug_hooks->end_source_file) (from_line);
if (indent_level != input_file_stack->indent_level)
{
warning_with_file_and_line
(input_filename, lineno,
"This file contains more '%c's than '%c's.",
indent_level > input_file_stack->indent_level ? '{' : '}',
indent_level > input_file_stack->indent_level ? '}' : '{');
}
else
error ("leaving more files than we entered");
#endif
pop_srcloc ();
(*debug_hooks->end_source_file) (to_line);
}
update_header_times (fc->map->to_file);
map = fc->map;
in_system_header = fc->sysp != 0;
input_filename = map->to_file;
lineno = SOURCE_LINE (map, fc->line);
update_header_times (new_map->to_file);
in_system_header = new_map->sysp != 0;
input_filename = new_map->to_file;
lineno = to_line;
map = new_map;
/* Hook for C++. */
extract_interface_info ();

View file

@ -61,7 +61,7 @@ print_location (pfile, filename, pos)
line = 0;
else
{
struct line_map *map;
const struct line_map *map;
if (type == BUF_PRAGMA)
buffer = buffer->prev;

View file

@ -290,7 +290,7 @@ stack_include_file (pfile, inc)
/* We'll try removing deps_sysp after the release of 3.0. */
deps_sysp = pfile->system_include_depth != 0;
sysp = MAX ((pfile->buffer ? pfile->buffer->sysp : 0),
sysp = MAX ((pfile->map ? pfile->map->sysp : 0),
(inc->foundhere ? inc->foundhere->sysp : 0));
/* For -M, add the file to the dependencies on its first inclusion. */
@ -329,7 +329,6 @@ stack_include_file (pfile, inc)
fp = cpp_push_buffer (pfile, inc->buffer, len, BUF_FILE, inc->name, 0);
fp->inc = inc;
fp->inc->refcnt++;
fp->sysp = sysp;
/* Initialise controlling macro state. */
pfile->mi_valid = true;
@ -337,7 +336,7 @@ stack_include_file (pfile, inc)
pfile->include_depth++;
/* Generate the call back. */
_cpp_do_file_change (pfile, LC_ENTER, 1);
_cpp_do_file_change (pfile, LC_ENTER, fp->nominal_fname, 1, sysp);
}
/* Read the file referenced by INC into the file cache.
@ -576,9 +575,8 @@ cpp_make_system_header (pfile, syshdr, externc)
/* 1 = system header, 2 = system header to be treated as C. */
if (syshdr)
flags = 1 + (externc != 0);
pfile->buffer->sysp = flags;
_cpp_do_file_change (pfile, LC_RENAME,
SOURCE_LINE (pfile->map, pfile->line));
_cpp_do_file_change (pfile, LC_RENAME, pfile->map->to_file,
SOURCE_LINE (pfile->map, pfile->line), flags);
}
/* Report on all files that might benefit from a multiple include guard.
@ -678,7 +676,6 @@ _cpp_execute_include (pfile, header, type)
if (header->type == CPP_HEADER_NAME)
pfile->system_include_depth++;
pfile->buffer->return_to_line = SOURCE_LINE (pfile->map, pfile->line);
stack_include_file (pfile, inc);
if (type == IT_IMPORT)
@ -808,7 +805,7 @@ search_from (pfile, type)
buffer->dir.len = dlen;
buffer->dir.next = CPP_OPTION (pfile, quote_include);
buffer->dir.sysp = buffer->sysp;
buffer->dir.sysp = pfile->map->sysp;
}
return &buffer->dir;

View file

@ -66,7 +66,7 @@ struct cpp_chunk
typedef struct cpp_pool cpp_pool;
struct cpp_pool
{
struct cpp_chunk *cur, *locked;
struct cpp_chunk *cur, *locked, *first;
unsigned char *pos; /* Current position. */
unsigned int align;
unsigned int locks;
@ -190,11 +190,6 @@ struct cpp_buffer
/* Token column position adjustment owing to tabs in whitespace. */
unsigned int col_adjust;
/* The line of the buffer that we return to after a #include.
Strictly this is redundant, since it can be calculated from the
line maps, but it is clearest to save it here. */
unsigned int return_to_line;
/* Contains PREV_WHITE and/or AVOID_LPASTE. */
unsigned char saved_flags;
@ -213,9 +208,6 @@ struct cpp_buffer
buffers. */
unsigned char from_stage3;
/* 1 = system header file, 2 = C system header file used for C++. */
unsigned char sysp;
/* Nonzero means that the directory to start searching for ""
include files has been calculated and stored in "dir" below. */
unsigned char search_cached;
@ -247,7 +239,7 @@ struct cpp_reader
/* Source line tracking. */
struct line_maps line_maps;
struct line_map *map;
const struct line_map *map;
unsigned int line;
/* The position of the last lexed token and last lexed directive. */
@ -376,8 +368,7 @@ extern unsigned char _cpp_trigraph_map[UCHAR_MAX + 1];
/* Macros. */
#define CPP_PRINT_DEPS(PFILE) CPP_OPTION (PFILE, print_deps)
#define CPP_IN_SYSTEM_HEADER(PFILE) \
(CPP_BUFFER (PFILE) && CPP_BUFFER (PFILE)->sysp)
#define CPP_IN_SYSTEM_HEADER(PFILE) (pfile->map && pfile->map->sysp)
#define CPP_PEDANTIC(PF) CPP_OPTION (PF, pedantic)
#define CPP_WTRADITIONAL(PF) CPP_OPTION (PF, warn_traditional)
@ -439,7 +430,8 @@ extern void _cpp_do__Pragma PARAMS ((cpp_reader *));
extern void _cpp_init_directives PARAMS ((cpp_reader *));
extern void _cpp_init_internal_pragmas PARAMS ((cpp_reader *));
extern void _cpp_do_file_change PARAMS ((cpp_reader *, enum lc_reason,
unsigned int));
const char *,
unsigned int, unsigned int));
extern void _cpp_pop_buffer PARAMS ((cpp_reader *));
/* Utility routines and macros. */

View file

@ -713,7 +713,7 @@ do_line (pfile)
cpp_buffer *buffer = pfile->buffer;
enum lc_reason reason = LC_RENAME;
unsigned long new_lineno;
unsigned int cap;
unsigned int cap, sysp = pfile->map->sysp;
cpp_token token;
/* C99 raised the minimum limit on #line numbers. */
@ -741,9 +741,10 @@ do_line (pfile)
/* Only accept flags for the # 55 form. */
if (pfile->state.line_extension)
{
int flag = 0, sysp = 0;
int flag;
flag = read_flag (pfile, flag);
sysp = 0;
flag = read_flag (pfile, 0);
if (flag == 1)
{
reason = LC_ENTER;
@ -763,7 +764,6 @@ do_line (pfile)
if (flag == 4)
sysp = 2;
}
buffer->sysp = sysp;
}
check_eol (pfile);
}
@ -775,34 +775,27 @@ do_line (pfile)
}
end_directive (pfile, 1);
_cpp_do_file_change (pfile, reason, new_lineno);
_cpp_do_file_change (pfile, reason, (const char *) buffer->nominal_fname,
new_lineno, sysp);
}
/* Arrange the file_change callback. pfile->line has changed to
FILE_LINE of the current buffer, for reason REASON. */
FILE_LINE of TO_FILE, for reason REASON. SYSP is 1 for a system
header, 2 for a sytem header that needs to be extern "C" protected,
and zero otherwise. */
void
_cpp_do_file_change (pfile, reason, file_line)
_cpp_do_file_change (pfile, reason, to_file, file_line, sysp)
cpp_reader *pfile;
enum lc_reason reason;
const char *to_file;
unsigned int file_line;
unsigned int sysp;
{
cpp_buffer *buffer = pfile->buffer;
pfile->map = add_line_map (&pfile->line_maps, reason,
pfile->line, buffer->nominal_fname, file_line);
pfile->map = add_line_map (&pfile->line_maps, reason, sysp,
pfile->line, to_file, file_line);
if (pfile->cb.file_change)
{
cpp_file_change fc;
fc.map = pfile->map;
fc.line = pfile->line;
fc.reason = reason;
fc.sysp = buffer->sysp;
fc.externc = CPP_OPTION (pfile, cplusplus) && buffer->sysp == 2;
(*pfile->cb.file_change) (pfile, &fc);
}
(*pfile->cb.file_change) (pfile, pfile->map);
}
/*
@ -908,7 +901,8 @@ cpp_register_pragma (pfile, space, name, handler)
}
found:
new = xnew (struct pragma_entry);
new = (struct pragma_entry *)
_cpp_pool_alloc (&pfile->macro_pool, sizeof (struct pragma_entry));
new->name = name;
new->len = strlen (name);
new->isnspace = 0;
@ -936,7 +930,8 @@ cpp_register_pragma_space (pfile, space)
p = p->next;
}
new = xnew (struct pragma_entry);
new = (struct pragma_entry *)
_cpp_pool_alloc (&pfile->macro_pool, sizeof (struct pragma_entry));
new->name = space;
new->len = len;
new->isnspace = 1;
@ -1722,7 +1717,7 @@ cpp_get_callbacks (pfile)
}
/* The line map set. */
struct line_maps *
const struct line_maps *
cpp_get_line_maps (pfile)
cpp_reader *pfile;
{
@ -1764,7 +1759,6 @@ cpp_push_buffer (pfile, buffer, len, type, filename, return_at_eof)
new->line_base = new->buf = new->cur = buffer;
new->rlimit = buffer + len;
new->sysp = 0;
/* No read ahead or extra char initially. */
new->read_ahead = EOF;
@ -1813,7 +1807,7 @@ _cpp_pop_buffer (pfile)
{
/* Callbacks are not generated for popping the main file. */
if (buffer->prev)
_cpp_do_file_change (pfile, LC_LEAVE, buffer->prev->return_to_line);
_cpp_do_file_change (pfile, LC_LEAVE, 0, 0, 0);
_cpp_pop_file_buffer (pfile, buffer);
}

View file

@ -387,20 +387,10 @@ struct cpp_options
unsigned char help_only;
};
typedef struct cpp_file_change cpp_file_change;
struct cpp_file_change
{
struct line_map *map; /* Line map, valid until next callback. */
unsigned int line; /* Logical line number of next line. */
enum lc_reason reason; /* Reason for change. */
unsigned char sysp; /* Nonzero if system header. */
unsigned char externc; /* Nonzero if wrapper needed. */
};
/* Call backs. */
struct cpp_callbacks
{
void (*file_change) PARAMS ((cpp_reader *, const cpp_file_change *));
void (*file_change) PARAMS ((cpp_reader *, const struct line_map *));
void (*include) PARAMS ((cpp_reader *, unsigned int,
const unsigned char *, const cpp_token *));
void (*define) PARAMS ((cpp_reader *, unsigned int, cpp_hashnode *));
@ -501,7 +491,7 @@ extern int cpp_destroy PARAMS ((cpp_reader *));
through the pointer returned from cpp_get_callbacks, or set them
with cpp_set_callbacks. */
extern cpp_options *cpp_get_options PARAMS ((cpp_reader *));
extern struct line_maps *cpp_get_line_maps PARAMS ((cpp_reader *));
extern const struct line_maps *cpp_get_line_maps PARAMS ((cpp_reader *));
extern cpp_callbacks *cpp_get_callbacks PARAMS ((cpp_reader *));
extern void cpp_set_callbacks PARAMS ((cpp_reader *, cpp_callbacks *));

View file

@ -1466,7 +1466,7 @@ _cpp_create_definition (pfile, node)
&& macro->expansion[0].val.node == node);
/* To suppress some diagnostics. */
macro->syshdr = pfile->buffer->sysp != 0;
macro->syshdr = pfile->map->sysp != 0;
/* Commit the memory. */
POOL_COMMIT (&pfile->macro_pool, macro->count * sizeof (cpp_token));

View file

@ -31,8 +31,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
struct printer
{
FILE *outf; /* Stream to write to. */
const char *syshdr_flags; /* System header flags, if any. */
struct line_map *map; /* Logical to physical line mappings. */
const struct line_map *map; /* Logical to physical line mappings. */
unsigned int line; /* Line currently being written. */
unsigned char printed; /* Nonzero if something output at line. */
};
@ -47,9 +46,9 @@ static void scan_translation_unit PARAMS ((cpp_reader *));
static void check_multiline_token PARAMS ((cpp_string *));
static int dump_macro PARAMS ((cpp_reader *, cpp_hashnode *, void *));
static void print_line PARAMS ((struct line_map *, unsigned int,
static void print_line PARAMS ((const struct line_map *, unsigned int,
const char *));
static void maybe_print_line PARAMS ((struct line_map *, unsigned int));
static void maybe_print_line PARAMS ((const struct line_map *, unsigned int));
/* Callback routines for the parser. Most of these are active only
in specific modes. */
@ -59,7 +58,7 @@ static void cb_include PARAMS ((cpp_reader *, unsigned int,
const unsigned char *, const cpp_token *));
static void cb_ident PARAMS ((cpp_reader *, unsigned int,
const cpp_string *));
static void cb_file_change PARAMS ((cpp_reader *, const cpp_file_change *));
static void cb_file_change PARAMS ((cpp_reader *, const struct line_map *));
static void cb_def_pragma PARAMS ((cpp_reader *, unsigned int));
const char *progname; /* Needs to be global. */
@ -285,7 +284,7 @@ check_multiline_token (str)
static void
maybe_print_line (map, line)
struct line_map *map;
const struct line_map *map;
unsigned int line;
{
/* End the previous line of text. */
@ -308,9 +307,11 @@ maybe_print_line (map, line)
print_line (map, line, "");
}
/* Output a line marker for logical line LINE. Special flags are "1"
or "2" indicating entering or leaving a file. */
static void
print_line (map, line, special_flags)
struct line_map *map;
const struct line_map *map;
unsigned int line;
const char *special_flags;
{
@ -321,9 +322,17 @@ print_line (map, line, special_flags)
print.line = line;
if (! options->no_line_commands)
fprintf (print.outf, "# %u \"%s\"%s%s\n",
SOURCE_LINE (map, print.line), map->to_file,
special_flags, print.syshdr_flags);
{
fprintf (print.outf, "# %u \"%s\"%s",
SOURCE_LINE (map, print.line), map->to_file, special_flags);
if (map->sysp == 2)
fputs (" 3 4", print.outf);
else if (map->sysp == 1)
fputs (" 3", print.outf);
putc ('\n', print.outf);
}
}
/* Callbacks. */
@ -382,40 +391,32 @@ cb_include (pfile, line, dir, header)
}
/* The file name, line number or system header flags have changed, as
described in FC. NB: the old print.map must be considered invalid. */
described in MAP. From this point on, the old print.map might be
pointing to freed memory, and so must not be dereferenced. */
static void
cb_file_change (pfile, fc)
cb_file_change (pfile, map)
cpp_reader *pfile ATTRIBUTE_UNUSED;
const cpp_file_change *fc;
const struct line_map *map;
{
bool first_time = print.map == NULL;
/* Bring current file to correct line. We handle the first file
change callback specially, so that a first line of "# 1 "foo.c"
in file foo.i outputs just the foo.c line, and not a foo.i line. */
if (fc->reason == LC_ENTER && !first_time)
maybe_print_line (fc->map - 1, fc->line - 1);
print.map = fc->map;
if (fc->externc)
print.syshdr_flags = " 3 4";
else if (fc->sysp)
print.syshdr_flags = " 3";
else
print.syshdr_flags = "";
if (!first_time)
/* Not first time? */
if (print.map)
{
const char *flags = "";
if (fc->reason == LC_ENTER)
/* Bring current file to correct line when entering a new file. */
if (map->reason == LC_ENTER)
maybe_print_line (map - 1, map->from_line - 1);
if (map->reason == LC_ENTER)
flags = " 1";
else if (fc->reason == LC_LEAVE)
else if (map->reason == LC_LEAVE)
flags = " 2";
print_line (print.map, fc->line, flags);
print_line (map, map->from_line, flags);
}
print.map = map;
}
/* Copy a #pragma directive to the preprocessed output. LINE is the

View file

@ -45,14 +45,15 @@ free_line_maps (set)
{
if (set->maps)
{
#ifdef ENABLE_CHECKING
struct line_map *map;
/* Depending upon whether we are handling preprocessed input or
not, this can be a user error or an ICE. */
for (map = CURRENT_LINE_MAP (set); ! MAIN_FILE_P (map);
map = INCLUDED_FROM (set, map))
fprintf (stderr, "line-map.c: file \"%s\" entered but not left\n",
map->to_file);
#endif
free (set->maps);
}
}
@ -64,10 +65,11 @@ free_line_maps (set)
FROM_LINE should be monotonic increasing across calls to this
function. */
struct line_map *
add_line_map (set, reason, from_line, to_file, to_line)
const struct line_map *
add_line_map (set, reason, sysp, from_line, to_file, to_line)
struct line_maps *set;
enum lc_reason reason;
unsigned int sysp;
unsigned int from_line;
const char *to_file;
unsigned int to_line;
@ -85,9 +87,6 @@ add_line_map (set, reason, from_line, to_file, to_line)
}
map = &set->maps[set->used];
map->from_line = from_line;
map->to_file = to_file;
map->to_line = to_line;
/* If we don't keep our line maps consistent, we can easily
segfault. Don't rely on the client to do it for us. */
@ -95,17 +94,42 @@ add_line_map (set, reason, from_line, to_file, to_line)
reason = LC_ENTER;
else if (reason == LC_LEAVE)
{
if (MAIN_FILE_P (map - 1)
|| strcmp (INCLUDED_FROM (set, map - 1)->to_file, to_file))
struct line_map *from;
bool error;
if (MAIN_FILE_P (map - 1))
{
#ifdef ENABLE_CHECKING
fprintf (stderr, "line-map.c: file \"%s\" left but not entered\n",
to_file);
#endif
error = true;
reason = LC_RENAME;
from = map - 1;
}
else
{
from = INCLUDED_FROM (set, map - 1);
error = to_file && strcmp (from->to_file, to_file);
}
/* Depending upon whether we are handling preprocessed input or
not, this can be a user error or an ICE. */
if (error)
fprintf (stderr, "line-map.c: file \"%s\" left but not entered\n",
to_file);
/* A TO_FILE of NULL is special - we use the natural values. */
if (error || to_file == NULL)
{
to_file = from->to_file;
to_line = LAST_SOURCE_LINE (from) + 1;
sysp = from->sysp;
}
}
map->reason = reason;
map->sysp = sysp;
map->from_line = from_line;
map->to_file = to_file;
map->to_line = to_line;
if (reason == LC_ENTER)
map->included_from = set->used - 1;
else if (reason == LC_RENAME)
@ -122,7 +146,7 @@ add_line_map (set, reason, from_line, to_file, to_line)
chronologically, the logical lines are monotonic increasing, and so
the list is sorted and we can use a binary search. */
struct line_map *
const struct line_map *
lookup_line (set, line)
struct line_maps *set;
unsigned int line;
@ -151,7 +175,7 @@ lookup_line (set, line)
void
print_containing_files (set, map)
struct line_maps *set;
struct line_map *map;
const struct line_map *map;
{
if (MAIN_FILE_P (map) || set->last_listed == map->included_from)
return;

View file

@ -23,17 +23,29 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef GCC_LINE_MAP_H
#define GCC_LINE_MAP_H
/* Reason for adding a line change with add_line_map (). LC_ENTER is
when including a new file, e.g. a #include directive in C.
LC_LEAVE is when reaching a file's end. LC_RENAME is when a file
name or line number changes for neither of the above reasons
(e.g. a #line directive in C). */
enum lc_reason {LC_ENTER = 0, LC_LEAVE, LC_RENAME};
/* The logical line FROM_LINE maps to physical source file TO_FILE at
line TO_LINE, and subsequently one-to-one until the next line_map
structure in the set. INCLUDED_FROM is an index into the set that
gives the line mapping at whose end the current one was included.
File(s) at the bottom of the include stack have this set to -1. */
File(s) at the bottom of the include stack have this set to -1.
REASON is the reason for creation of this line map, SYSP is 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. */
struct line_map
{
const char *to_file;
unsigned int to_line;
unsigned int from_line;
int included_from;
ENUM_BITFIELD (lc_reason) reason : CHAR_BIT;
unsigned char sysp;
};
/* A set of chronological line_map structures. */
@ -49,13 +61,6 @@ struct line_maps
int last_listed;
};
/* Reason for adding a line change with add_line_map (). LC_ENTER is
when including a new file, e.g. a #include directive in C.
LC_LEAVE is when reaching a file's end. LC_RENAME is when a file
name or line number changes for neither of the above reasons
(e.g. a #line directive in C). */
enum lc_reason {LC_ENTER = 0, LC_LEAVE, LC_RENAME};
/* Initialize a line map set. */
extern void init_line_maps
PARAMS ((struct line_maps *));
@ -66,25 +71,27 @@ extern void free_line_maps
/* Add a mapping of logical source line to physical source file and
line number. The text pointed to by TO_FILE must have a lifetime
at least as long as the final call to lookup_line ().
at least as long as the line maps. If reason is LC_LEAVE, and
TO_FILE is NULL, then TO_FILE, TO_LINE and SYSP are given their
natural values considering the file we are returning to.
FROM_LINE should be monotonic increasing across calls to this
function. A call to this function can relocate the previous set of
maps, so any stored line_map pointers should not be used. */
extern struct line_map *add_line_map
PARAMS ((struct line_maps *, enum lc_reason,
extern const struct line_map *add_line_map
PARAMS ((struct line_maps *, enum lc_reason, unsigned int sysp,
unsigned int from_line, const char *to_file, unsigned int to_line));
/* Given a logical line, returns the map from which the corresponding
(source file, line) pair can be deduced. */
extern struct line_map *lookup_line
extern const struct line_map *lookup_line
PARAMS ((struct line_maps *, unsigned int));
/* Print the file names and line numbers of the #include commands
which led to the map MAP, if any, to stderr. Nothing is output if
the most recently listed stack is the same as the current one. */
extern void print_containing_files
PARAMS ((struct line_maps *, struct line_map *));
PARAMS ((struct line_maps *, const struct line_map *));
/* Converts a map and logical line to source line. */
#define SOURCE_LINE(MAP, LINE) ((LINE) + (MAP)->to_line - (MAP)->from_line)