preprocessor: Add support for header unit translation
libcpp/ * files.c (struct _cpp_file): Add header_unit field. (_cpp_stack_file): Add header unit support. (cpp_find_header_unit): New. * include/cpplib.h (cpp_find_header_unit): Declare.
This commit is contained in:
parent
db87f19ae3
commit
7ceb899e93
|
@ -111,6 +111,9 @@ struct _cpp_file
|
||||||
|
|
||||||
/* If this file is implicitly preincluded. */
|
/* If this file is implicitly preincluded. */
|
||||||
bool implicit_preinclude : 1;
|
bool implicit_preinclude : 1;
|
||||||
|
|
||||||
|
/* > 0: Known C++ Module header unit, <0: known not. ==0, unknown */
|
||||||
|
int header_unit : 2;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* A singly-linked list for all searches for a given file name, with
|
/* A singly-linked list for all searches for a given file name, with
|
||||||
|
@ -891,9 +894,9 @@ has_unique_contents (cpp_reader *pfile, _cpp_file *file, bool import,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Place the file referenced by FILE into a new buffer on the buffer
|
/* Place the file referenced by FILE into a new buffer on the buffer
|
||||||
stack if possible. IMPORT is true if this stacking attempt is
|
stack if possible. Returns true if a buffer is stacked. Use LOC
|
||||||
because of a #import directive. Returns true if a buffer is
|
for any diagnostics. */
|
||||||
stacked. Use LOC for any diagnostics. */
|
|
||||||
bool
|
bool
|
||||||
_cpp_stack_file (cpp_reader *pfile, _cpp_file *file, include_type type,
|
_cpp_stack_file (cpp_reader *pfile, _cpp_file *file, include_type type,
|
||||||
location_t loc)
|
location_t loc)
|
||||||
|
@ -901,13 +904,46 @@ _cpp_stack_file (cpp_reader *pfile, _cpp_file *file, include_type type,
|
||||||
if (is_known_idempotent_file (pfile, file, type == IT_IMPORT))
|
if (is_known_idempotent_file (pfile, file, type == IT_IMPORT))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
int sysp = 0;
|
||||||
|
char *buf = nullptr;
|
||||||
|
|
||||||
|
/* Check C++ module include translation. */
|
||||||
|
if (!file->header_unit && type < IT_HEADER_HWM
|
||||||
|
/* Do not include translate include-next. */
|
||||||
|
&& type != IT_INCLUDE_NEXT
|
||||||
|
&& pfile->cb.translate_include)
|
||||||
|
buf = (pfile->cb.translate_include
|
||||||
|
(pfile, pfile->line_table, loc, file->path));
|
||||||
|
|
||||||
|
if (buf)
|
||||||
|
{
|
||||||
|
/* We don't increment the line number at the end of a buffer,
|
||||||
|
because we don't usually need that location (we're popping an
|
||||||
|
include file). However in this case we do want to do the
|
||||||
|
increment. So push a writable buffer of two newlines to acheive
|
||||||
|
that. */
|
||||||
|
static uchar newlines[] = "\n\n";
|
||||||
|
cpp_push_buffer (pfile, newlines, 2, true);
|
||||||
|
|
||||||
|
cpp_buffer *buffer
|
||||||
|
= cpp_push_buffer (pfile, reinterpret_cast<unsigned char *> (buf),
|
||||||
|
strlen (buf), true);
|
||||||
|
buffer->to_free = buffer->buf;
|
||||||
|
|
||||||
|
file->header_unit = +1;
|
||||||
|
_cpp_mark_file_once_only (pfile, file);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Not a header unit, and we know it. */
|
||||||
|
file->header_unit = -1;
|
||||||
|
|
||||||
if (!read_file (pfile, file, loc))
|
if (!read_file (pfile, file, loc))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!has_unique_contents (pfile, file, type == IT_IMPORT, loc))
|
if (!has_unique_contents (pfile, file, type == IT_IMPORT, loc))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
int sysp = 0;
|
|
||||||
if (pfile->buffer && file->dir)
|
if (pfile->buffer && file->dir)
|
||||||
sysp = MAX (pfile->buffer->sysp, file->dir->sysp);
|
sysp = MAX (pfile->buffer->sysp, file->dir->sysp);
|
||||||
|
|
||||||
|
@ -934,6 +970,7 @@ _cpp_stack_file (cpp_reader *pfile, _cpp_file *file, include_type type,
|
||||||
/* Initialize controlling macro state. */
|
/* Initialize controlling macro state. */
|
||||||
pfile->mi_valid = true;
|
pfile->mi_valid = true;
|
||||||
pfile->mi_cmacro = 0;
|
pfile->mi_cmacro = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* In the case of a normal #include, we're now at the start of the
|
/* In the case of a normal #include, we're now at the start of the
|
||||||
line *following* the #include. A separate location_t for this
|
line *following* the #include. A separate location_t for this
|
||||||
|
@ -941,11 +978,14 @@ _cpp_stack_file (cpp_reader *pfile, _cpp_file *file, include_type type,
|
||||||
|
|
||||||
This does not apply if we found a PCH file, we're not a regular
|
This does not apply if we found a PCH file, we're not a regular
|
||||||
include, or we ran out of locations. */
|
include, or we ran out of locations. */
|
||||||
if (file->pchname == NULL
|
bool decrement = (file->pchname == NULL
|
||||||
&& type < IT_DIRECTIVE_HWM
|
&& type < IT_DIRECTIVE_HWM
|
||||||
&& pfile->line_table->highest_location != LINE_MAP_MAX_LOCATION - 1)
|
&& (pfile->line_table->highest_location
|
||||||
|
!= LINE_MAP_MAX_LOCATION - 1));
|
||||||
|
if (decrement)
|
||||||
pfile->line_table->highest_location--;
|
pfile->line_table->highest_location--;
|
||||||
|
|
||||||
|
if (file->header_unit <= 0)
|
||||||
/* Add line map and do callbacks. */
|
/* Add line map and do callbacks. */
|
||||||
_cpp_do_file_change (pfile, LC_ENTER, file->path,
|
_cpp_do_file_change (pfile, LC_ENTER, file->path,
|
||||||
/* With preamble injection, start on line zero,
|
/* With preamble injection, start on line zero,
|
||||||
|
@ -954,6 +994,14 @@ _cpp_stack_file (cpp_reader *pfile, _cpp_file *file, include_type type,
|
||||||
starting preprocessed, we expect an initial
|
starting preprocessed, we expect an initial
|
||||||
locating line. */
|
locating line. */
|
||||||
type == IT_PRE_MAIN ? 0 : 1, sysp);
|
type == IT_PRE_MAIN ? 0 : 1, sysp);
|
||||||
|
else if (decrement)
|
||||||
|
{
|
||||||
|
/* Adjust the line back one so we appear on the #include line itself. */
|
||||||
|
const line_map_ordinary *map
|
||||||
|
= LINEMAPS_LAST_ORDINARY_MAP (pfile->line_table);
|
||||||
|
linenum_type line = SOURCE_LINE (map, pfile->line_table->highest_line);
|
||||||
|
linemap_line_start (pfile->line_table, line - 1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1058,6 +1106,33 @@ _cpp_stack_include (cpp_reader *pfile, const char *fname, int angle_brackets,
|
||||||
return _cpp_stack_file (pfile, file, type, loc);
|
return _cpp_stack_file (pfile, file, type, loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* NAME is a header file name, find the path we'll use to open it. */
|
||||||
|
|
||||||
|
const char *
|
||||||
|
cpp_find_header_unit (cpp_reader *pfile, const char *name, bool angle,
|
||||||
|
location_t loc)
|
||||||
|
{
|
||||||
|
cpp_dir *dir = search_path_head (pfile, name, angle, IT_INCLUDE);
|
||||||
|
if (!dir)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
_cpp_file *file = _cpp_find_file (pfile, name, dir, angle,
|
||||||
|
_cpp_FFK_NORMAL, loc);
|
||||||
|
if (!file)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (file->fd > 0)
|
||||||
|
{
|
||||||
|
/* Don't leave it open. */
|
||||||
|
close (file->fd);
|
||||||
|
file->fd = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
file->header_unit = +1;
|
||||||
|
_cpp_mark_file_once_only (pfile, file);
|
||||||
|
return file->path;
|
||||||
|
}
|
||||||
|
|
||||||
/* Could not open FILE. The complication is dependency output. */
|
/* Could not open FILE. The complication is dependency output. */
|
||||||
static void
|
static void
|
||||||
open_file_failed (cpp_reader *pfile, _cpp_file *file, int angle_brackets,
|
open_file_failed (cpp_reader *pfile, _cpp_file *file, int angle_brackets,
|
||||||
|
|
|
@ -983,6 +983,9 @@ extern cpp_callbacks *cpp_get_callbacks (cpp_reader *) ATTRIBUTE_PURE;
|
||||||
extern void cpp_set_callbacks (cpp_reader *, cpp_callbacks *);
|
extern void cpp_set_callbacks (cpp_reader *, cpp_callbacks *);
|
||||||
extern class mkdeps *cpp_get_deps (cpp_reader *) ATTRIBUTE_PURE;
|
extern class mkdeps *cpp_get_deps (cpp_reader *) ATTRIBUTE_PURE;
|
||||||
|
|
||||||
|
extern const char *cpp_find_header_unit (cpp_reader *, const char *file,
|
||||||
|
bool angle_p, location_t);
|
||||||
|
|
||||||
/* This function reads the file, but does not start preprocessing. It
|
/* This function reads the file, but does not start preprocessing. It
|
||||||
returns the name of the original file; this is the same as the
|
returns the name of the original file; this is the same as the
|
||||||
input file, except for preprocessed input. This will generate at
|
input file, except for preprocessed input. This will generate at
|
||||||
|
|
Loading…
Reference in New Issue