diff options
author | Tom Tromey <tromey@redhat.com> | 2011-10-17 11:58:56 +0200 |
---|---|---|
committer | Dodji Seketeli <dodji@gcc.gnu.org> | 2011-10-17 11:58:56 +0200 |
commit | 46427374e1ffdcb2781d99abc63ebd3ab7af6110 (patch) | |
tree | 202b8180f693619f1878beec9e49e08c0fe4ddd3 /libcpp/internal.h | |
parent | 2be4314f3d92e4c8d39561a1a90a0a8b2888dfd2 (diff) | |
download | gcc-46427374e1ffdcb2781d99abc63ebd3ab7af6110.zip gcc-46427374e1ffdcb2781d99abc63ebd3ab7af6110.tar.gz gcc-46427374e1ffdcb2781d99abc63ebd3ab7af6110.tar.bz2 |
Linemap infrastructure for virtual locations
This is the first instalment of a set which goal is to track locations
of tokens across macro expansions. Tom Tromey did the original work
and attached the patch to PR preprocessor/7263. This opus is a
derivative of that original work.
This patch modifies the linemap module of libcpp to add virtual
locations support.
A virtual location is a mapped location that can resolve to several
different physical locations. It can always resolve to the spelling
location of a token. For tokens resulting from macro expansion it can
resolve to:
- either the location of the expansion point of the macro.
- or the location of the token in the definition of the
macro
- or, if the token is an argument of a function-like macro,
the location of the use of the matching macro parameter in
the definition of the macro
The patch creates a new type of line map called a macro map. For every
single macro expansion, there is a macro map that generates a virtual
location for every single resulting token of the expansion.
The good old type of line map we all know is now called an ordinary
map. That one still encodes spelling locations as it has always had.
As a result linemap_lookup as been extended to return a macro map when
given a virtual location resulting from a macro expansion. The layout
of structs line_map has changed to support this new type of map. So
did the layout of struct line_maps. Accessor macros have been
introduced to avoid messing with the implementation details of these
datastructures directly. This helped already as we have been testing
different ways of arranging these datastructure. Having to constantly
adjust client code that is too tied with the internals of line_map and
line_maps would have been even more painful.
Of course, many new public functions have been added to the linemap
module to handle the resolution of virtual locations.
This patch introduces the infrastructure but no part of the compiler
uses virtual locations yet.
However the client code of the linemap data structures has been
adjusted as per the changes. E.g, it's not anymore reliable for a
client code to manipulate struct line_map directly if it just wants to
deal with spelling locations, because struct line_map can now
represent a macro map as well. In that case, it's better to use the
convenient API to resolve the initial (possibly virtual) location to a
spelling location (or to an ordinary map) and use that.
This is the reason why the patch adjusts the Java, Ada and Fortran
front ends.
Also, note that virtual locations are not supposed to be ordered for
relations '<' and '>' anymore. To test if a virtual location appears
"before" another one, one has to use a new operator exposed by the
line map interface. The patch updates the only spot (in the
diagnostics module) I have found that was making the assumption that
locations were ordered for these relations. This is the only change
that introduces a use of the new line map API in this patch, so I am
adding a regression test for it only.
From-SVN: r180081
Diffstat (limited to 'libcpp/internal.h')
-rw-r--r-- | libcpp/internal.h | 73 |
1 files changed, 72 insertions, 1 deletions
diff --git a/libcpp/internal.h b/libcpp/internal.h index 6c423f0..65bfa1d 100644 --- a/libcpp/internal.h +++ b/libcpp/internal.h @@ -67,7 +67,8 @@ struct cset_converter #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 *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) @@ -739,6 +740,76 @@ ufputs (const unsigned char *s, FILE *f) 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 struct line_map *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 struct line_map *, + 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 |