src/developer/debug/zxdb/symbols/module_symbols_impl.cc
void ModuleSymbolsImpl::ResolveLineInputLocationForFile(const SymbolContext& symbol_context,
                                                        const std::string& canonical_file,
                                                        int line_number,
                                                        const ResolveOptions& options,
                                                        std::vector<Location>* output) const {
  const std::vector<unsigned>* units = index_.FindFileUnitIndices(canonical_file);
  if (!units)
    return;

  std::vector<LineMatch> matches;
  for (unsigned index : *units) {
    llvm::DWARFUnit* unit = context_->getUnitAtIndex(index);
    LineTableImpl line_table(context_.get(), unit);

    // Complication 1 above: find all matches for this line in the unit.
    std::vector<LineMatch> unit_matches =
        GetAllLineTableMatchesInUnit(line_table, canonical_file, line_number);

    matches.insert(matches.end(), unit_matches.begin(), unit_matches.end());
  }

  if (matches.empty())
    return;

  // Complications 2 & 3 above: Get all instances of the best match only with a max of one per
  // function. The best match is the one with the lowest line number (found matches should all be
  // bigger than the input line, so this will be the closest).
  for (const LineMatch& match : GetBestLineMatches(matches)) {
    uint64_t abs_addr = symbol_context.RelativeToAbsolute(match.address);
    if (options.symbolize)
      output->push_back(LocationForAddress(symbol_context, abs_addr, options, nullptr));
    else
      output->push_back(Location(Location::State::kAddress, abs_addr));
  }
}
// To a first approximation we just look up the line in the line table for each compilation unit
// that references the file. Complications:
//
// 1. The line might not be an exact match (the user can specify a blank line or something optimized
//    out). In this case, find the next valid line.
//
// 2. The above step can find many different locations. Maybe some code from the file in question is
//    inlined into the compilation unit, but not the function with the line in it. Or different
//    template instantiations can mean that a line of code is in some instantiations but don't apply
//    to others.
//
//    To solve this duplication problem, get the resolved line of each of the addresses found above
//    and find the best one. Keep only those locations matching the best one (there can still be
//    multiple).
//
// 3. Inlining and templates can mean there can be multiple matches of the exact same line. Only
//    keep the first match per function or inlined function to catch the case where a line is spread
//    across multiple line table entries.
To a first approximation we just look up the line in the line table for each compilation unit
that references the file. Complications.

1. The line might not be an exact match (the user can specify a blank line or something optimized
out). In this case, find the next valid line.

2. The above step can find many different locations. Maybe some code from the file in question is
inlined into the compilation unit, but not the function with the line in it. Or different
template instantiations can mean that a line of code is in some instantiations but don't apply
to others.

To solve this duplication problem, get the resolved line of each of the addresses found above
and find the best one. Keep only those locations matching the best one (there can still be
multiple).

3. Inlining and templates can mean there can be multiple matches of the exact same line. Only
keep the first match per function or inlined function to catch the case where a line is spread
across multiple line table entries.
To a first approximation we just look up the line in the line table for each compilation unit that references the file . Complications . 1 . The line might not be an exact match ( the user can specify a blank line or something optimized out ) . In this case find the next valid line . 2 . The above step can find many different locations . Maybe some code from the file in question is inlined into the compilation unit but not the function with the line in it . Or different template instantiations can mean that a line of code is in some instantiations but don ' t apply to others . To solve this duplication problem get the resolved line of each of the addresses found above and find the best one . Keep only those locations matching the best one ( there can still be multiple ) . 3 . Inlining and templates can mean there can be multiple matches of the exact same line . Only keep the first match per function or inlined function to catch the case where a line is spread across multiple line table entries .
void ModuleSymbolsImpl::ResolveLineInputLocationForFile(const SymbolContext& symbol_context,
                                                        const std::string& canonical_file,
                                                        int line_number,
                                                        const ResolveOptions& options,
                                                        std::vector<Location>* output) const {
  const std::vector<unsigned>* units = index_.FindFileUnitIndices(canonical_file);
  if (!units)
    return;
  std::vector<LineMatch> matches;
  for (unsigned index : *units) {
    llvm::DWARFUnit* unit = context_->getUnitAtIndex(index);
    LineTableImpl line_table(context_.get(), unit);
    std::vector<LineMatch> unit_matches =
        GetAllLineTableMatchesInUnit(line_table, canonical_file, line_number);
    matches.insert(matches.end(), unit_matches.begin(), unit_matches.end());
  }
  if (matches.empty())
    return;
  for (const LineMatch& match : GetBestLineMatches(matches)) {
    uint64_t abs_addr = symbol_context.RelativeToAbsolute(match.address);
    if (options.symbolize)
      output->push_back(LocationForAddress(symbol_context, abs_addr, options, nullptr));
    else
      output->push_back(Location(Location::State::kAddress, abs_addr));
  }
}
void ModuleSymbolsImpl :: ResolveLineInputLocationForFile ( const SymbolContext & symbol_context , const std :: string & canonical_file , int line_number , const ResolveOptions & options , std :: vector < Location > * output ) const { const std :: vector < unsigned > * units = index_ . FindFileUnitIndices ( canonical_file ) ; if ( ! units ) return ; std :: vector < LineMatch > matches ; for ( unsigned index : * units ) { llvm :: DWARFUnit * unit = context_ -> getUnitAtIndex ( index ) ; LineTableImpl line_table ( context_ . get ( ) , unit ) ; std :: vector < LineMatch > unit_matches = GetAllLineTableMatchesInUnit ( line_table , canonical_file , line_number ) ; matches . insert ( matches . end ( ) , unit_matches . begin ( ) , unit_matches . end ( ) ) ; } if ( matches . empty ( ) ) return ; for ( const LineMatch & match : GetBestLineMatches ( matches ) ) { uint64_t abs_addr = symbol_context . RelativeToAbsolute ( match . address ) ; if ( options . symbolize ) output -> push_back ( LocationForAddress ( symbol_context , abs_addr , options , nullptr ) ) ; else output -> push_back ( Location ( Location :: State :: kAddress , abs_addr ) ) ; } }
To a first approximation we just look up the line in the line table for each compilation unit
that references the file.
To a first approximation we just look up the line in the line table for each compilation unit that references the file .
// Complication 1 above: find all matches for this line in the unit. // Complications 2 & 3 above: Get all instances of the best match only with a max of one per // function. The best match is the one with the lowest line number (found matches should all be // bigger than the input line, so this will be the closest).