bool SourceManager::sameSourceId(const SourceLocation &a, const SourceLocation &b) { if (!a.isSet() && !b.isSet()) return true; size_t loc_a, loc_b; if (!findLocation(a, &loc_a) || !findLocation(b, &loc_b)) return false; return loc_a == loc_b; }
bool SourceManager::areLocationsInsertedOnSameLine(const SourceLocation &aLocA, const SourceLocation &aLocB) { SourceLocation a = normalize(aLocA); SourceLocation b = normalize(aLocB); // This can occur with builtin tokens. if (!a.isSet() && !b.isSet()) return true; size_t loc_a, loc_b; if (!findLocation(a, &loc_a) || !findLocation(b, &loc_b)) return false; if (loc_a != loc_b) return false; unsigned line_a = getLine(locations_[loc_a], a); unsigned line_b = getLine(locations_[loc_b], b); return line_a && line_b && line_a == line_b; }
void SourceManager::getTokenHistory(const SourceLocation &aLoc, TokenHistory *history) { SourceLocation loc = aLoc; while (loc.isSet()) { size_t loc_index; if (!findLocation(loc, &loc_index)) return; const LREntry &range = locations_[loc_index]; if (loc.isInMacro()) { history->macros.append(FullMacroRef(range.getMacro(), loc.offset() - range.id)); } else { history->files.append(fullSourceRef(range, loc)); } loc = range.getParent(); } }
bool SourceManager::findLocation(const SourceLocation &loc, size_t *aIndex) { if (!loc.isSet()) return false; if (last_lookup_ < locations_.length() && locations_[last_lookup_].owns(loc)) { *aIndex = last_lookup_; return true; } // We should not allocate ids >= the next id. assert(loc.offset() < next_source_id_); // Binary search. size_t lower = 0; size_t upper = locations_.length(); while (lower < upper) { size_t index = (lower + upper) / 2; LREntry &range = locations_[index]; if (loc.offset() < range.id) { upper = index; } else if (loc.offset() > range.id + range.length() + 1) { // Note +1 for the terminal offset. lower = index + 1; } else { assert(range.owns(loc)); // Update cache. last_lookup_ = index; *aIndex = index; return true; } } // What happened? assert(false); return false; }