};
static loc_spans spans;
+/* Indirection to allow bsearching imports by ordinary location. */
+static vec<module_state *> *ool;
/********************************************************************/
/* Data needed by a module during the process of loading. */
interface and we're importing a partition. */
bool
-loc_spans::maybe_propagate (module_state *import,
- location_t loc = UNKNOWN_LOCATION)
+loc_spans::maybe_propagate (module_state *import, location_t hwm)
{
bool opened = (module_interface_p () && !module_partition_p ()
&& import->is_partition ());
if (opened)
- open (loc);
+ open (hwm);
return opened;
}
first map of the interval. */
void
-loc_spans::open (location_t hwm = UNKNOWN_LOCATION)
+loc_spans::open (location_t hwm)
{
- if (hwm == UNKNOWN_LOCATION)
- hwm = MAP_START_LOCATION (LINEMAPS_LAST_ORDINARY_MAP (line_table));
-
span interval;
interval.ordinary.first = interval.ordinary.second = hwm;
interval.macro.first = interval.macro.second
&& dump ("Opening span %u ordinary:[%u,... macro:...,%u)",
spans->length (), interval.ordinary.first,
interval.macro.second);
+ if (spans->length ())
+ {
+ /* No overlapping! */
+ auto &last = spans->last ();
+ gcc_checking_assert (interval.ordinary.first >= last.ordinary.second);
+ gcc_checking_assert (interval.macro.second <= last.macro.first);
+ }
spans->safe_push (interval);
}
static const module_state *
module_for_ordinary_loc (location_t loc)
{
- unsigned pos = 1;
- unsigned len = modules->length () - pos;
+ unsigned pos = 0;
+ unsigned len = ool->length () - pos;
while (len)
{
unsigned half = len / 2;
- module_state *probe = (*modules)[pos + half];
+ module_state *probe = (*ool)[pos + half];
if (loc < probe->ordinary_locs.first)
len = half;
else if (loc < probe->ordinary_locs.second)
}
}
- return NULL;
+ return nullptr;
}
static const module_state *
for (unsigned ix = loc_spans::SPAN_FIRST; ix != spans.length (); ix++)
{
loc_spans::span &span = spans[ix];
- line_map_ordinary const *omap
- = linemap_check_ordinary (linemap_lookup (line_table,
- span.ordinary.first));
-
- /* We should exactly match up. */
- gcc_checking_assert (MAP_START_LOCATION (omap) == span.ordinary.first);
- line_map_ordinary const *fmap = omap;
- for (; MAP_START_LOCATION (omap) < span.ordinary.second; omap++)
+ if (span.ordinary.first != span.ordinary.second)
{
- /* We should never find a module linemap in an interval. */
- gcc_checking_assert (!MAP_MODULE_P (omap));
+ line_map_ordinary const *omap
+ = linemap_check_ordinary (linemap_lookup (line_table,
+ span.ordinary.first));
- if (max_range < omap->m_range_bits)
- max_range = omap->m_range_bits;
- }
+ /* We should exactly match up. */
+ gcc_checking_assert (MAP_START_LOCATION (omap) == span.ordinary.first);
- unsigned count = omap - fmap;
- info.num_maps.first += count;
+ line_map_ordinary const *fmap = omap;
+ for (; MAP_START_LOCATION (omap) < span.ordinary.second; omap++)
+ {
+ /* We should never find a module linemap in an interval. */
+ gcc_checking_assert (!MAP_MODULE_P (omap));
+
+ if (max_range < omap->m_range_bits)
+ max_range = omap->m_range_bits;
+ }
+
+ info.num_maps.first += omap - fmap;
+ }
if (span.macro.first != span.macro.second)
{
- count = linemap_lookup_macro_index (line_table, span.macro.first) + 1;
- count -= linemap_lookup_macro_index (line_table,
+ /* Iterate over the span's macros, to elide the empty
+ expansions. */
+ unsigned count = 0;
+ for (unsigned macro
+ = linemap_lookup_macro_index (line_table,
span.macro.second - 1);
+ macro < LINEMAPS_MACRO_USED (line_table);
+ macro++)
+ {
+ line_map_macro const *mmap
+ = LINEMAPS_MACRO_MAP_AT (line_table, macro);
+ if (MAP_START_LOCATION (mmap) < span.macro.first)
+ /* Fallen out of the span. */
+ break;
+
+ if (mmap->n_tokens)
+ count++;
+ }
dump (dumper::LOCATION) && dump ("Span:%u %u macro maps", ix, count);
info.num_maps.second += count;
}
line_map_ordinary const *omap
= linemap_check_ordinary (linemap_lookup (line_table,
- span.ordinary.first));
+ span.ordinary.first));
location_t base = MAP_START_LOCATION (omap);
/* Preserve the low MAX_RANGE bits of base by incrementing ORD_OFF. */
location_t start_loc = MAP_START_LOCATION (omap);
unsigned to = start_loc + span.ordinary_delta;
location_t end_loc = MAP_START_LOCATION (omap + 1);
-
- dump () && dump ("Ordinary span:%u [%u,%u):%u->%d(%u)", ix, start_loc,
+
+ dump () && dump ("Ordinary span:%u [%u,%u):%u->%d(%u)",
+ ix, start_loc,
end_loc, end_loc - start_loc,
span.ordinary_delta, to);
/* There should be no change in the low order bits. */
gcc_checking_assert (((start_loc ^ to) & range_mask) == 0);
}
+
/* The ending serialized value. */
ord_off = span.ordinary.second + span.ordinary_delta;
}
- dump () && dump ("Ordinary hwm:%u macro lwm:%u", ord_off, mac_off);
+ dump () && dump ("Ordinary:%u maps hwm:%u macro:%u maps lwm:%u ",
+ info.num_maps.first, ord_off,
+ info.num_maps.second, mac_off);
dump.outdent ();
info.max_range = max_range;
-
+
return info;
}
/* We should never find a module linemap in an interval. */
gcc_checking_assert (!MAP_MODULE_P (omap));
- /* We expect very few filenames, so just an array. */
+ /* We expect very few filenames, so just an array.
+ (Not true when headers are still in play :() */
for (unsigned jx = filenames.length (); jx--;)
{
const char *name = filenames[jx];
if (0 == strcmp (name, fname))
{
/* Reset the linemap's name, because for things like
- preprocessed input we could have multple
+ preprocessed input we could have multiple
instances of the same name, and we'd rather not
percolate that. */
const_cast<line_map_ordinary *> (omap)->to_file = name;
{
loc_spans::span &span = spans[ix];
if (span.macro.first == span.macro.second)
+ /* Empty span. */
continue;
- for (unsigned first
+ for (unsigned macro
= linemap_lookup_macro_index (line_table, span.macro.second - 1);
- first < LINEMAPS_MACRO_USED (line_table);
- first++)
+ macro < LINEMAPS_MACRO_USED (line_table);
+ macro++)
{
line_map_macro const *mmap
- = LINEMAPS_MACRO_MAP_AT (line_table, first);
+ = LINEMAPS_MACRO_MAP_AT (line_table, macro);
location_t start_loc = MAP_START_LOCATION (mmap);
if (start_loc < span.macro.first)
+ /* Fallen out of the span. */
break;
- if (macro_num == info.num_maps.second)
- {
- /* We're ending on an empty macro expansion. The
- preprocessor doesn't prune such things. */
- // FIXME:QOI This is an example of the non-pruning of
- // locations. See write_prepare_maps.
- gcc_checking_assert (!mmap->n_tokens);
- continue;
- }
+
+ if (!mmap->n_tokens)
+ /* Empty expansion. */
+ continue;
sec.u (offset);
sec.u (mmap->n_tokens);
location_t zero = sec.u ();
dump () && dump ("Macro maps:%u zero:%u", num_macros, zero);
- bool propagated = spans.maybe_propagate (this);
+ bool propagated = spans.maybe_propagate (this,
+ line_table->highest_location + 1);
location_t offset = LINEMAPS_MACRO_LOWEST_LOCATION (line_table);
slurp->loc_deltas.second = zero - offset;
return cfg.end (from ());
}
+/* Comparator for ordering the Ordered Ordinary Location array. */
+
+static int
+ool_cmp (const void *a_, const void *b_)
+{
+ auto *a = *static_cast<const module_state *const *> (a_);
+ auto *b = *static_cast<const module_state *const *> (b_);
+ if (a == b)
+ return 0;
+ else if (a->ordinary_locs.first < b->ordinary_locs.second)
+ return -1;
+ else
+ return +1;
+}
+
/* Use ELROND format to record the following sections:
qualified-names : binding value(s)
MOD_SNAME_PFX.README : human readable, strings
/* Determine Strongy Connected Components. */
vec<depset *> sccs = table.connect ();
+ vec_alloc (ool, modules->length ());
+ for (unsigned ix = modules->length (); --ix;)
+ {
+ auto *import = (*modules)[ix];
+ if (import->loadedness > ML_NONE
+ && !(partitions && bitmap_bit_p (partitions, import->mod)))
+ ool->quick_push (import);
+ }
+ ool->qsort (ool_cmp);
+
unsigned crc = 0;
module_state_config config;
location_map_info map_info = write_prepare_maps (&config);
spaces.release ();
sccs.release ();
+ vec_free (ool);
+
/* Human-readable info. */
write_readme (to, reader, config.dialect_str, extensions);
timevar_start (TV_MODULE_MAPPER);
- dump.push (NULL);
+ auto n = dump.push (NULL);
dump () && dump ("Resolving direct import names");
mapper->Cork ();
}
}
- dump.pop (0);
+ dump.pop (n);
timevar_stop (TV_MODULE_MAPPER);
}
if (desired == ML_PREPROCESSOR)
{
- name_pending_imports (reader, false);
+ unsigned n = dump.push (NULL);
- unsigned pre_hwm = 0;
+ dump () && dump ("Reading %s preprocessor state", module);
+ name_pending_imports (reader, false);
/* Preserve the state of the line-map. */
- pre_hwm = LINEMAPS_ORDINARY_USED (line_table);
+ unsigned pre_hwm = LINEMAPS_ORDINARY_USED (line_table);
+
/* We only need to close the span, if we're going to emit a
CMI. But that's a little tricky -- our token scanner
needs to be smarter -- and this isn't much state.
vec_free (pending_imports);
/* Restore the line-map state. */
- linemap_module_restore (line_table, pre_hwm);
- spans.open ();
+ spans.open (linemap_module_restore (line_table, pre_hwm));
/* Now read the preprocessor state of this particular
import. */
- unsigned n = dump.push (module);
if (module->loadedness == ML_CONFIG
&& module->read_preprocessor (true))
module->import_macros ();
- dump.pop (n);
timevar_stop (TV_MODULE_IMPORT);
+
+ dump.pop (n);
}
}
void
preprocessed_module (cpp_reader *reader)
{
+ unsigned n = dump.push (NULL);
+
+ dump () && dump ("Completed phase-4 (tokenization) processing");
+
name_pending_imports (reader, true);
vec_free (pending_imports);
}
}
}
+
+ dump.pop (n);
}
/* VAL is a global tree, add it to the global vec if it is
}
/* A linemap at LWM-1 was interrupted to insert module locations & imports.
- Append a new map, continuing the interrupted one. */
+ Append a new map, continuing the interrupted one. Return the start location
+ of the new map, or 0 if failed (because we ran out of locations. */
-void
+unsigned
linemap_module_restore (line_maps *set, unsigned lwm)
{
- if (lwm && lwm != LINEMAPS_USED (set, false))
+ linemap_assert (lwm);
+
+ 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))))
{
- 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;
+ /* 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;
+
+ return post_map->start_location;
}
+
+ return 0;
}
/* Returns TRUE if the line table set tracks token locations across