blob: bbbae7d1b52c4abfba4b2bd4996c62eca943e8b8 [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/developer/debug/zxdb/expr/permissive_input_location.h"
#include "src/developer/debug/zxdb/expr/found_name.h"
#include "src/developer/debug/zxdb/expr/parsed_identifier.h"
#include "src/developer/debug/zxdb/symbols/process_symbols.h"
namespace zxdb {
namespace {
// Returns true if the identifier is a special name that's understood by the symbol system but
// which won't be in the index.
//
// Currently these are PLT breakpoints (called "$plt(foo)" for the function "foo"), and the
// entrypoint (called "$main").
bool IsSpecialSymbolName(const Identifier& ident) {
return ident.components().size() == 1u &&
ident.components()[0].special() != SpecialIdentifier::kNone;
}
} // namespace
std::vector<InputLocation> ExpandPermissiveInputLocationNames(
const FindNameContext& context, const std::vector<InputLocation>& input) {
// Currently all users of this API need the same set of options. This can be moved to a parameter
// of this function if needed.
FindNameOptions opts(FindNameOptions::kNoKinds);
opts.max_results = FindNameOptions::kAllResults;
opts.search_mode = FindNameOptions::kAllNamespaces;
opts.find_functions = true;
opts.find_vars = true;
std::vector<InputLocation> result;
std::vector<FoundName> found; // Keep outside to avoid reallocation.
for (const auto& in : input) {
if (in.type == InputLocation::Type::kName) {
// Needs expansion.
found.clear();
if (IsSpecialSymbolName(in.name)) {
// Pass special names through, don't look in the index because they won't be there.
result.push_back(in);
} else {
FindName(context, opts, ToParsedIdentifier(in.name), &found);
for (const auto& f : found)
result.emplace_back(ToIdentifier(f.GetName()));
}
} else {
// Not a symbolic name, the output is the same as the input.
result.push_back(in);
}
}
return result;
}
// An alternate implementation of this function could get the actual symbol objects from the
// FindName results (function, variable), and then do a symbol lookup on that to get the full
// InputLocation. Basically InputLocation would have another "symbol object" mode that would take
// a RefPtr<Symbol> to look up.
//
// The advantage of that implementation is that it saves the symbol name lookup when we go to the
// ResolveInputLocation() call. Not round-tripping through names also helps remove some potential
// ambiguity about what we're referring to if there are multiple matches.
//
// The disadvantage is that the implementation is more complicated, especially since symbol objects
// don't currently have any ModuleSymbol information associated with them.
//
// TODO(bug 37608) Revisit this design when symbols know their modules. This might make the above
// design more desirable.
std::vector<Location> ResolvePermissiveInputLocations(const ProcessSymbols* process_symbols,
const ResolveOptions& resolve_options,
const FindNameContext& context,
const std::vector<InputLocation>& input) {
std::vector<Location> result;
for (const auto& in : ExpandPermissiveInputLocationNames(context, input)) {
std::vector<Location> inner_result = process_symbols->ResolveInputLocation(in, resolve_options);
result.insert(result.end(), inner_result.begin(), inner_result.end());
}
return result;
}
} // namespace zxdb