summaryrefslogtreecommitdiff
path: root/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp')
-rw-r--r--lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp85
1 files changed, 73 insertions, 12 deletions
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
index 20d8c1acf9c4..7af53e16ce9d 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
@@ -1720,18 +1720,22 @@ void SymbolFileNativePDB::FindTypes(const lldb_private::TypeQuery &query,
std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
- std::vector<TypeIndex> matches =
- m_index->tpi().findRecordsByName(query.GetTypeBasename().GetStringRef());
-
- for (TypeIndex type_idx : matches) {
- TypeSP type_sp = GetOrCreateType(type_idx);
- if (!type_sp)
+ // We can't query for the full name because the type might reside
+ // in an anonymous namespace. Search for the basename in our map and check the
+ // matching types afterwards.
+ std::vector<uint32_t> matches;
+ m_type_base_names.GetValues(query.GetTypeBasename(), matches);
+
+ for (uint32_t match_idx : matches) {
+ std::vector context = GetContextForType(TypeIndex(match_idx));
+ if (context.empty())
continue;
- // We resolved a type. Get the fully qualified name to ensure it matches.
- ConstString name = type_sp->GetQualifiedName();
- TypeQuery type_match(name.GetStringRef(), TypeQueryOptions::e_exact_match);
- if (query.ContextMatches(type_match.GetContextRef())) {
+ if (query.ContextMatches(context)) {
+ TypeSP type_sp = GetOrCreateType(TypeIndex(match_idx));
+ if (!type_sp)
+ continue;
+
results.InsertUnique(type_sp);
if (results.Done(query))
return;
@@ -2201,11 +2205,15 @@ void SymbolFileNativePDB::BuildParentMap() {
CVTagRecord tag = CVTagRecord::create(type);
RecordIndices &indices = record_indices[tag.asTag().getUniqueName()];
- if (tag.asTag().isForwardRef())
+ if (tag.asTag().isForwardRef()) {
indices.forward = *ti;
- else
+ } else {
indices.full = *ti;
+ auto base_name = MSVCUndecoratedNameParser::DropScope(tag.name());
+ m_type_base_names.Append(ConstString(base_name), ti->getIndex());
+ }
+
if (indices.full != TypeIndex::None() &&
indices.forward != TypeIndex::None()) {
forward_to_full[indices.forward] = indices.full;
@@ -2261,6 +2269,10 @@ void SymbolFileNativePDB::BuildParentMap() {
llvm::consumeError(std::move(error));
}
+ // After calling Append(), the type-name map needs to be sorted again to be
+ // able to look up a type by its name.
+ m_type_base_names.Sort();
+
// Now that we know the forward -> full mapping of all type indices, we can
// re-write all the indices. At the end of this process, we want a mapping
// consisting of fwd -> full and full -> full for all child -> parent indices.
@@ -2353,3 +2365,52 @@ SymbolFileNativePDB::GetParentType(llvm::codeview::TypeIndex ti) {
return std::nullopt;
return parent_iter->second;
}
+
+std::vector<CompilerContext>
+SymbolFileNativePDB::GetContextForType(TypeIndex ti) {
+ CVType type = m_index->tpi().getType(ti);
+ if (!IsTagRecord(type))
+ return {};
+
+ CVTagRecord tag = CVTagRecord::create(type);
+
+ std::optional<Type::ParsedName> parsed_name =
+ Type::GetTypeScopeAndBasename(tag.name());
+ if (!parsed_name)
+ return {{tag.contextKind(), ConstString(tag.name())}};
+
+ std::vector<CompilerContext> ctx;
+ // assume everything is a namespace at first
+ for (llvm::StringRef scope : parsed_name->scope) {
+ ctx.emplace_back(CompilerContextKind::Namespace, ConstString(scope));
+ }
+ // we know the kind of our own type
+ ctx.emplace_back(tag.contextKind(), ConstString(parsed_name->basename));
+
+ // try to find the kind of parents
+ for (auto &el : llvm::reverse(llvm::drop_end(ctx))) {
+ std::optional<TypeIndex> parent = GetParentType(ti);
+ if (!parent)
+ break;
+
+ ti = *parent;
+ type = m_index->tpi().getType(ti);
+ switch (type.kind()) {
+ case LF_CLASS:
+ case LF_STRUCTURE:
+ case LF_INTERFACE:
+ el.kind = CompilerContextKind::ClassOrStruct;
+ continue;
+ case LF_UNION:
+ el.kind = CompilerContextKind::Union;
+ continue;
+ case LF_ENUM:
+ el.kind = CompilerContextKind::Enum;
+ continue;
+ default:
+ break;
+ }
+ break;
+ }
+ return ctx;
+}