/* If LOC is the virtual location of a token coming from the expansion of a macro M and if its spelling location is reserved (e.g, a location for a built-in token), then this function unwinds (using linemap_unwind_toward_expansion) the location until a location that is not reserved and is not in a system header is reached. In other words, this unwinds the reserved location until a location that is in real source code is reached. Otherwise, if the spelling location for LOC is not reserved or if LOC doesn't come from the expansion of a macro, the function returns LOC as is and *MAP is not touched. *MAP is set to the map of the returned location if the later is different from LOC. */ source_location linemap_unwind_to_first_non_reserved_loc (struct line_maps *set, source_location loc, const struct line_map **map) { source_location resolved_loc; const struct line_map *map0 = NULL, *map1 = NULL; map0 = linemap_lookup (set, loc); if (!linemap_macro_expansion_map_p (map0)) return loc; resolved_loc = linemap_resolve_location (set, loc, LRK_SPELLING_LOCATION, &map1); if (resolved_loc >= RESERVED_LOCATION_COUNT && !LINEMAP_SYSP (map1)) return loc; while (linemap_macro_expansion_map_p (map0) && (resolved_loc < RESERVED_LOCATION_COUNT || LINEMAP_SYSP (map1))) { loc = linemap_unwind_toward_expansion (set, loc, &map0); resolved_loc = linemap_resolve_location (set, loc, LRK_SPELLING_LOCATION, &map1); } if (map != NULL) *map = map0; return loc; }
int linemap_location_in_system_header_p (struct line_maps *set, source_location location) { const struct line_map *map = NULL; location = linemap_resolve_location (set, location, LRK_SPELLING_LOCATION, &map); if (location < RESERVED_LOCATION_COUNT) return false; return LINEMAP_SYSP (map); }
void linemap_dump_location (struct line_maps *set, source_location loc, FILE *stream) { const struct line_map *map; source_location location; const char *path = "", *from = ""; int l = -1, c = -1, s = -1, e = -1; if (loc == 0) return; location = linemap_resolve_location (set, loc, LRK_MACRO_DEFINITION_LOCATION, &map); if (map == NULL) /* Only reserved locations can be tolerated in this case. */ linemap_assert (location < RESERVED_LOCATION_COUNT); else { path = LINEMAP_FILE (map); l = SOURCE_LINE (map, location); c = SOURCE_COLUMN (map, location); s = LINEMAP_SYSP (map) != 0; e = location != loc; if (e) from = "N/A"; else from = (INCLUDED_FROM (set, map)) ? LINEMAP_FILE (INCLUDED_FROM (set, map)) : "<NULL>"; } /* P: path, L: line, C: column, S: in-system-header, M: map address, E: macro expansion?, LOC: original location, R: resolved location */ fprintf (stream, "{P:%s;F:%s;L:%d;C:%d;S:%d;M:%p;E:%d,LOC:%d,R:%d}", path, from, l, c, s, (void*)map, e, loc, location); }
expanded_location linemap_expand_location (struct line_maps *set, const struct line_map *map, source_location loc) { expanded_location xloc; memset (&xloc, 0, sizeof (xloc)); if (loc < RESERVED_LOCATION_COUNT) /* The location for this token wasn't generated from a line map. It was probably a location for a builtin token, chosen by some client code. Let's not try to expand the location in that case. */; else if (map == NULL) /* We shouldn't be getting a NULL map with a location that is not reserved by the client code. */ abort (); else { /* MAP must be an ordinary map and LOC must be non-virtual, encoded into this map, obviously; the accessors used on MAP below ensure it is ordinary. Let's just assert the non-virtualness of LOC here. */ if (linemap_location_from_macro_expansion_p (set, loc)) abort (); xloc.file = LINEMAP_FILE (map); xloc.line = SOURCE_LINE (map, loc); xloc.column = SOURCE_COLUMN (map, loc); xloc.sysp = LINEMAP_SYSP (map) != 0; } return xloc; }
int linemap_location_in_system_header_p (struct line_maps *set, source_location location) { const struct line_map *map = NULL; if (location < RESERVED_LOCATION_COUNT) return false; /* Let's look at where the token for LOCATION comes from. */ while (true) { map = linemap_lookup (set, location); if (map != NULL) { if (!linemap_macro_expansion_map_p (map)) /* It's a normal token. */ return LINEMAP_SYSP (map); else { /* It's a token resulting from a macro expansion. */ source_location loc = linemap_macro_map_loc_unwind_toward_spelling (map, location); if (loc < RESERVED_LOCATION_COUNT) /* This token might come from a built-in macro. Let's look at where that macro got expanded. */ location = linemap_macro_map_loc_to_exp_point (map, location); else location = loc; } } else break; } return false; }