aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libcpp/include/line-map.h51
-rw-r--r--libcpp/internal.h24
-rw-r--r--libcpp/line-map.c116
3 files changed, 150 insertions, 41 deletions
diff --git a/libcpp/include/line-map.h b/libcpp/include/line-map.h
index 44008be..50b2e4f 100644
--- a/libcpp/include/line-map.h
+++ b/libcpp/include/line-map.h
@@ -72,6 +72,7 @@ enum lc_reason
LC_RENAME, /* Other reason for name change. */
LC_RENAME_VERBATIM, /* Likewise, but "" != stdin. */
LC_ENTER_MACRO, /* Begin macro expansion. */
+ LC_MODULE, /* A (C++) Module. */
/* FIXME: add support for stringize and paste. */
LC_HWM /* High Water Mark. */
};
@@ -439,7 +440,8 @@ struct GTY((tag ("1"))) line_map_ordinary : public line_map {
/* Location from whence this line map was included. For regular
#includes, this location will be the last location of a map. For
- outermost file, this is 0. */
+ outermost file, this is 0. For modules it could be anywhere
+ within a map. */
location_t included_from;
/* Size is 20 or 24 bytes, no padding */
@@ -662,6 +664,15 @@ ORDINARY_MAP_IN_SYSTEM_HEADER_P (const line_map_ordinary *ord_map)
return ord_map->sysp;
}
+/* TRUE if this line map is for a module (not a source file). */
+
+inline bool
+MAP_MODULE_P (const line_map *map)
+{
+ return (MAP_ORDINARY_P (map)
+ && linemap_check_ordinary (map)->reason == LC_MODULE);
+}
+
/* Get the filename of ordinary map MAP. */
inline const char *
@@ -1076,6 +1087,9 @@ extern void linemap_check_files_exited (class line_maps *);
extern location_t linemap_line_start
(class line_maps *set, linenum_type to_line, unsigned int max_column_hint);
+/* Allocate a raw block of line maps, zero initialized. */
+extern line_map *line_map_new_raw (line_maps *, bool, unsigned);
+
/* Add a mapping of logical source line to physical source file and
line number. This function creates an "ordinary map", which is a
map that records locations of tokens that are not part of macro
@@ -1093,6 +1107,39 @@ extern const line_map *linemap_add
(class line_maps *, enum lc_reason, unsigned int sysp,
const char *to_file, linenum_type to_line);
+/* 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 (line_maps *, cpp_hashnode *,
+ location_t, unsigned int);
+
+/* Create a source location for a module. The creator must either do
+ this after the TU is tokenized, or deal with saving and restoring
+ map state. */
+
+extern location_t linemap_module_loc
+ (line_maps *, location_t from, const char *name);
+extern void linemap_module_reparent
+ (line_maps *, location_t loc, location_t new_parent);
+
+/* Restore the linemap state such that the map at LWM-1 continues. */
+extern void linemap_module_restore
+ (line_maps *, unsigned lwm);
+
/* Given a logical source location, returns the map which the
corresponding (source file, line, column) triplet can be deduced
from. Since the set is built chronologically, the logical lines are
@@ -1102,6 +1149,8 @@ extern const line_map *linemap_add
extern const line_map *linemap_lookup
(const line_maps *, location_t);
+unsigned linemap_lookup_macro_index (const line_maps *, location_t);
+
/* Returns TRUE if the line table set tracks token locations across
macro expansion, FALSE otherwise. */
bool linemap_tracks_macro_expansion_locs_p (class line_maps *);
diff --git a/libcpp/internal.h b/libcpp/internal.h
index d7780e4..3f5bafb 100644
--- a/libcpp/internal.h
+++ b/libcpp/internal.h
@@ -868,29 +868,7 @@ 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 line_map_macro *linemap_enter_macro (class line_maps *,
- struct cpp_hashnode*,
- location_t,
- unsigned int);
+/* In line-map.c. */
/* 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
diff --git a/libcpp/line-map.c b/libcpp/line-map.c
index 5a74174..bbb6963 100644
--- a/libcpp/line-map.c
+++ b/libcpp/line-map.c
@@ -378,23 +378,21 @@ linemap_check_files_exited (line_maps *set)
ORDINARY_MAP_FILE_NAME (map));
}
-/* Create a new line map in the line map set SET, and return it.
- REASON is the reason of creating the map. It determines the type
- of map created (ordinary or macro map). Note that ordinary maps and
- macro maps are allocated in different memory location. */
+/* Create NUM zero-initialized maps of type MACRO_P. */
-static struct line_map *
-new_linemap (line_maps *set, location_t start_location)
+line_map *
+line_map_new_raw (line_maps *set, bool macro_p, unsigned num)
{
- bool macro_p = start_location >= LINE_MAP_MAX_LOCATION;
unsigned num_maps_allocated = LINEMAPS_ALLOCATED (set, macro_p);
unsigned num_maps_used = LINEMAPS_USED (set, macro_p);
-
- if (num_maps_used == num_maps_allocated)
+
+ if (num > num_maps_allocated - num_maps_used)
{
/* We need more space! */
if (!num_maps_allocated)
num_maps_allocated = 128;
+ if (num_maps_allocated < num_maps_used + num)
+ num_maps_allocated = num_maps_used + num;
num_maps_allocated *= 2;
size_t size_of_a_map;
@@ -436,13 +434,39 @@ new_linemap (line_maps *set, location_t start_location)
line_map *result = (macro_p ? (line_map *)&set->info_macro.maps[num_maps_used]
: (line_map *)&set->info_ordinary.maps[num_maps_used]);
- LINEMAPS_USED (set, macro_p)++;
+ LINEMAPS_USED (set, macro_p) += num;
+
+ return result;
+}
+
+/* Create a new line map in the line map set SET, and return it.
+ REASON is the reason of creating the map. It determines the type
+ of map created (ordinary or macro map). Note that ordinary maps and
+ macro maps are allocated in different memory location. */
+
+static struct line_map *
+new_linemap (line_maps *set, location_t start_location)
+{
+ line_map *result = line_map_new_raw (set,
+ start_location >= LINE_MAP_MAX_LOCATION,
+ 1);
result->start_location = start_location;
return result;
}
+/* Return the location of the last source line within an ordinary
+ map. */
+inline location_t
+LAST_SOURCE_LINE_LOCATION (const line_map_ordinary *map)
+{
+ return (((map[1].start_location - 1
+ - map->start_location)
+ & ~((1 << map->m_column_and_range_bits) - 1))
+ + map->start_location);
+}
+
/* Add a mapping of logical source line to physical source file and
line number.
@@ -570,6 +594,56 @@ linemap_add (line_maps *set, enum lc_reason reason,
return map;
}
+/* Create a location for a module NAME imported at FROM. */
+
+location_t
+linemap_module_loc (line_maps *set, location_t from, const char *name)
+{
+ const line_map_ordinary *map
+ = linemap_check_ordinary (linemap_add (set, LC_MODULE, false, name, 0));
+ const_cast <line_map_ordinary *> (map)->included_from = from;
+
+ location_t loc = linemap_line_start (set, 0, 0);
+
+ return loc;
+}
+
+/* The linemap containing LOC is being reparented to be
+ imported/included from ADOPTOR. This can happen when an
+ indirectly imported module is then directly imported, or when
+ partitions are involved. */
+
+void
+linemap_module_reparent (line_maps *set, location_t loc, location_t adoptor)
+{
+ const line_map_ordinary *map = linemap_ordinary_map_lookup (set, loc);
+ const_cast<line_map_ordinary *> (map)->included_from = adoptor;
+}
+
+/* A linemap at LWM-1 was interrupted to insert module locations & imports.
+ Append a new map, continuing the interrupted one. */
+
+void
+linemap_module_restore (line_maps *set, unsigned lwm)
+{
+ if (lwm && lwm != LINEMAPS_USED (set, false))
+ {
+ const line_map_ordinary *pre_map
+ = linemap_check_ordinary (LINEMAPS_MAP_AT (set, false, lwm - 1));
+ unsigned src_line = SOURCE_LINE (pre_map,
+ LAST_SOURCE_LINE_LOCATION (pre_map));
+ location_t inc_at = pre_map->included_from;
+ if (const line_map_ordinary *post_map
+ = (linemap_check_ordinary
+ (linemap_add (set, LC_RENAME_VERBATIM,
+ ORDINARY_MAP_IN_SYSTEM_HEADER_P (pre_map),
+ ORDINARY_MAP_FILE_NAME (pre_map), src_line))))
+ /* linemap_add will think we were included from the same as
+ the preceeding map. */
+ const_cast <line_map_ordinary *> (post_map)->included_from = inc_at;
+ }
+}
+
/* Returns TRUE if the line table set tracks token locations across
macro expansion, FALSE otherwise. */
@@ -1003,14 +1077,25 @@ linemap_macro_map_lookup (const line_maps *set, location_t line)
if (set == NULL)
return NULL;
+ unsigned ix = linemap_lookup_macro_index (set, line);
+ const struct line_map_macro *result = LINEMAPS_MACRO_MAP_AT (set, ix);
+ linemap_assert (MAP_START_LOCATION (result) <= line);
+
+ return result;
+}
+
+unsigned
+linemap_lookup_macro_index (const line_maps *set, location_t line)
+{
unsigned mn = LINEMAPS_MACRO_CACHE (set);
unsigned mx = LINEMAPS_MACRO_USED (set);
const struct line_map_macro *cached = LINEMAPS_MACRO_MAP_AT (set, mn);
if (line >= MAP_START_LOCATION (cached))
{
- if (mn == 0 || line < MAP_START_LOCATION (&cached[-1]))
- return cached;
+ if (line < (MAP_START_LOCATION (cached)
+ + MACRO_MAP_NUM_MACRO_TOKENS (cached)))
+ return mn;
mx = mn - 1;
mn = 0;
}
@@ -1025,10 +1110,7 @@ linemap_macro_map_lookup (const line_maps *set, location_t line)
}
LINEMAPS_MACRO_CACHE (set) = mx;
- const struct line_map_macro *result = LINEMAPS_MACRO_MAP_AT (set, mx);
- linemap_assert (MAP_START_LOCATION (result) <= line);
-
- return result;
+ return mx;
}
/* Return TRUE if MAP encodes locations coming from a macro
@@ -1747,7 +1829,7 @@ linemap_dump (FILE *stream, class line_maps *set, unsigned ix, bool is_macro)
{
const char *const lc_reasons_v[LC_HWM]
= { "LC_ENTER", "LC_LEAVE", "LC_RENAME", "LC_RENAME_VERBATIM",
- "LC_ENTER_MACRO" };
+ "LC_ENTER_MACRO", "LC_MODULE" };
const line_map *map;
unsigned reason;