https://github.com/Nerixyz updated https://github.com/llvm/llvm-project/pull/149876
>From fa3c96b19ba174904036b031015a073cfd759c76 Mon Sep 17 00:00:00 2001 From: Nerixyz <nerix...@outlook.de> Date: Mon, 21 Jul 2025 20:32:58 +0200 Subject: [PATCH 1/3] [LLDB][NativePDB] Allow type lookup in namespaces --- .../NativePDB/SymbolFileNativePDB.cpp | 58 ++++++++- .../NativePDB/SymbolFileNativePDB.h | 4 + lldb/source/Symbol/Type.cpp | 8 +- .../Inputs/namespace-access.lldbinit | 18 +++ .../SymbolFile/NativePDB/namespace-access.cpp | 114 ++++++++++++++++++ 5 files changed, 196 insertions(+), 6 deletions(-) create mode 100644 lldb/test/Shell/SymbolFile/NativePDB/Inputs/namespace-access.lldbinit create mode 100644 lldb/test/Shell/SymbolFile/NativePDB/namespace-access.cpp diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp index 20d8c1acf9c42..5141632649dd5 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp +++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp @@ -1630,6 +1630,53 @@ size_t SymbolFileNativePDB::ParseSymbolArrayInScope( return count; } +void SymbolFileNativePDB::CacheTypeNames() { + if (!m_type_base_names.IsEmpty()) + return; + + LazyRandomTypeCollection &types = m_index->tpi().typeCollection(); + for (auto ti = types.getFirst(); ti; ti = types.getNext(*ti)) { + CVType cvt = types.getType(*ti); + llvm::StringRef name; + // We are only interested in records, unions, and enums. + // We aren't interested in forward references as we'll visit the actual + // type later anyway. + switch (cvt.kind()) { + case LF_STRUCTURE: + case LF_CLASS: { + ClassRecord cr; + llvm::cantFail(TypeDeserializer::deserializeAs<ClassRecord>(cvt, cr)); + if (cr.isForwardRef()) + continue; + name = cr.Name; + } break; + case LF_UNION: { + UnionRecord ur; + llvm::cantFail(TypeDeserializer::deserializeAs<UnionRecord>(cvt, ur)); + if (ur.isForwardRef()) + continue; + name = ur.Name; + } break; + case LF_ENUM: { + EnumRecord er; + llvm::cantFail(TypeDeserializer::deserializeAs<EnumRecord>(cvt, er)); + if (er.isForwardRef()) + continue; + name = er.Name; + } break; + default: + continue; + } + if (name.empty()) + continue; + + auto base_name = MSVCUndecoratedNameParser::DropScope(name); + m_type_base_names.Append(ConstString(base_name), ti->getIndex()); + } + + m_type_base_names.Sort(); +} + void SymbolFileNativePDB::DumpClangAST(Stream &s, llvm::StringRef filter) { auto ts_or_err = GetTypeSystemForLanguage(eLanguageTypeC_plus_plus); if (!ts_or_err) @@ -1720,11 +1767,14 @@ 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()); + // We can't query for the basename or full name because the type might reside + // in an anonymous namespace. Cache the basenames first. + CacheTypeNames(); + std::vector<uint32_t> matches; + m_type_base_names.GetValues(query.GetTypeBasename(), matches); - for (TypeIndex type_idx : matches) { - TypeSP type_sp = GetOrCreateType(type_idx); + for (uint32_t match_idx : matches) { + TypeSP type_sp = GetOrCreateType(TypeIndex(match_idx)); if (!type_sp) continue; diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h index 9891313f11d0b..457b301c4a486 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h +++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h @@ -258,6 +258,8 @@ class SymbolFileNativePDB : public SymbolFileCommon { void ParseInlineSite(PdbCompilandSymId inline_site_id, Address func_addr); + void CacheTypeNames(); + llvm::BumpPtrAllocator m_allocator; lldb::addr_t m_obj_load_address = 0; @@ -278,6 +280,8 @@ class SymbolFileNativePDB : public SymbolFileCommon { llvm::DenseMap<lldb::user_id_t, std::shared_ptr<InlineSite>> m_inline_sites; llvm::DenseMap<llvm::codeview::TypeIndex, llvm::codeview::TypeIndex> m_parent_types; + + lldb_private::UniqueCStringMap<uint32_t> m_type_base_names; }; } // namespace npdb diff --git a/lldb/source/Symbol/Type.cpp b/lldb/source/Symbol/Type.cpp index 0a886e56100a1..ddb22d611140b 100644 --- a/lldb/source/Symbol/Type.cpp +++ b/lldb/source/Symbol/Type.cpp @@ -134,7 +134,9 @@ bool TypeQuery::ContextMatches( if (ctx == ctx_end) return false; // Pattern too long. - if (ctx->kind == CompilerContextKind::Namespace && ctx->name.IsEmpty()) { + if ((ctx->kind & CompilerContextKind::Namespace) == + CompilerContextKind::Namespace && + ctx->name.IsEmpty()) { // We're matching an anonymous namespace. These are optional, so we check // if the pattern expects an anonymous namespace. if (pat->name.IsEmpty() && (pat->kind & CompilerContextKind::Namespace) == @@ -164,7 +166,9 @@ bool TypeQuery::ContextMatches( auto should_skip = [this](const CompilerContext &ctx) { if (ctx.kind == CompilerContextKind::Module) return GetIgnoreModules(); - if (ctx.kind == CompilerContextKind::Namespace && ctx.name.IsEmpty()) + if ((ctx.kind & CompilerContextKind::Namespace) == + CompilerContextKind::Namespace && + ctx.name.IsEmpty()) return !GetStrictNamespaces(); return false; }; diff --git a/lldb/test/Shell/SymbolFile/NativePDB/Inputs/namespace-access.lldbinit b/lldb/test/Shell/SymbolFile/NativePDB/Inputs/namespace-access.lldbinit new file mode 100644 index 0000000000000..e61ed2e2f453e --- /dev/null +++ b/lldb/test/Shell/SymbolFile/NativePDB/Inputs/namespace-access.lldbinit @@ -0,0 +1,18 @@ +b main +r + +type lookup S +type lookup ::S +type lookup Outer::S +type lookup Outer::Inner1::S +type lookup Inner1::S +type lookup Outer::Inner1::Inner2::S +type lookup Inner2::S +type lookup Outer::Inner2::S +type lookup Outer::A +type lookup A +type lookup ::A +expr sizeof(S) +expr sizeof(A) + +quit diff --git a/lldb/test/Shell/SymbolFile/NativePDB/namespace-access.cpp b/lldb/test/Shell/SymbolFile/NativePDB/namespace-access.cpp new file mode 100644 index 0000000000000..e171d189347d9 --- /dev/null +++ b/lldb/test/Shell/SymbolFile/NativePDB/namespace-access.cpp @@ -0,0 +1,114 @@ +// clang-format off +// REQUIRES: target-windows + +// Test namespace lookup. +// RUN: %build --nodefaultlib -o %t.exe -- %s +// RUN: %lldb -f %t.exe -s \ +// RUN: %p/Inputs/namespace-access.lldbinit 2>&1 | FileCheck %s + +struct S { + char a[1]; +}; + +namespace Outer { + + struct S { + char a[2]; + }; + + namespace Inner1 { + struct S { + char a[3]; + }; + + namespace Inner2 { + struct S { + char a[4]; + }; + } // namespace Inner2 + } // namespace Inner1 + + namespace Inner2 { + struct S { + char a[5]; + }; + } // namespace Inner2 + + namespace { + struct A { + char a[6]; + }; + } // namespace + +} // namespace Outer + +namespace { + struct A { + char a[7]; + }; +} // namespace + +int main(int argc, char **argv) { + S s; + Outer::S os; + Outer::Inner1::S oi1s; + Outer::Inner1::Inner2::S oi1i2s; + Outer::Inner2::S oi2s; + A a1; + Outer::A a2; + return sizeof(s) + sizeof(os) + sizeof(oi1s) + sizeof(oi1i2s) + sizeof(oi2s) + sizeof(a1) + sizeof(a2); +} + + + +// CHECK: (lldb) type lookup S +// CHECK: struct S { +// CHECK: struct S { +// CHECK: struct S { +// CHECK: struct S { +// CHECK: struct S { +// CHECK: } +// CHECK-NEXT: (lldb) type lookup ::S +// CHECK-NEXT: struct S { +// CHECK-NEXT: char a[1]; +// CHECK-NEXT: } +// CHECK-NEXT: (lldb) type lookup Outer::S +// CHECK-NEXT: struct S { +// CHECK-NEXT: char a[2]; +// CHECK-NEXT: } +// CHECK-NEXT: (lldb) type lookup Outer::Inner1::S +// CHECK-NEXT: struct S { +// CHECK-NEXT: char a[3]; +// CHECK-NEXT: } +// CHECK-NEXT: (lldb) type lookup Inner1::S +// CHECK-NEXT: struct S { +// CHECK-NEXT: char a[3]; +// CHECK-NEXT: } +// CHECK-NEXT: (lldb) type lookup Outer::Inner1::Inner2::S +// CHECK-NEXT: struct S { +// CHECK-NEXT: char a[4]; +// CHECK-NEXT: } +// CHECK-NEXT: (lldb) type lookup Inner2::S +// CHECK-NEXT: struct S { +// CHECK: struct S { +// CHECK: } +// CHECK-NEXT: (lldb) type lookup Outer::Inner2::S +// CHECK-NEXT: struct S { +// CHECK-NEXT: char a[5]; +// CHECK-NEXT: } +// CHECK-NEXT: (lldb) type lookup Outer::A +// CHECK-NEXT: struct A { +// CHECK-NEXT: char a[6]; +// CHECK-NEXT: } +// CHECK-NEXT: (lldb) type lookup A +// CHECK-NEXT: struct A { +// CHECK: struct A { +// CHECK: } +// CHECK-NEXT: (lldb) type lookup ::A +// CHECK-NEXT: struct A { +// CHECK-NEXT: char a[7]; +// CHECK-NEXT: } +// CHECK-NEXT: (lldb) expr sizeof(S) +// CHECK-NEXT: (__size_t) $0 = 1 +// CHECK-NEXT: (lldb) expr sizeof(A) +// CHECK-NEXT: (__size_t) $1 = 7 >From 288b5f7ddbca800509434f945495d972252f43a5 Mon Sep 17 00:00:00 2001 From: Nerixyz <nerix...@outlook.de> Date: Tue, 22 Jul 2025 14:35:34 +0200 Subject: [PATCH 2/3] refactor: move basename discovery to `BuildParentMap` --- .../NativePDB/SymbolFileNativePDB.cpp | 61 +++---------------- .../NativePDB/SymbolFileNativePDB.h | 2 - 2 files changed, 10 insertions(+), 53 deletions(-) diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp index 5141632649dd5..cae4c510a0e5f 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp +++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp @@ -1630,53 +1630,6 @@ size_t SymbolFileNativePDB::ParseSymbolArrayInScope( return count; } -void SymbolFileNativePDB::CacheTypeNames() { - if (!m_type_base_names.IsEmpty()) - return; - - LazyRandomTypeCollection &types = m_index->tpi().typeCollection(); - for (auto ti = types.getFirst(); ti; ti = types.getNext(*ti)) { - CVType cvt = types.getType(*ti); - llvm::StringRef name; - // We are only interested in records, unions, and enums. - // We aren't interested in forward references as we'll visit the actual - // type later anyway. - switch (cvt.kind()) { - case LF_STRUCTURE: - case LF_CLASS: { - ClassRecord cr; - llvm::cantFail(TypeDeserializer::deserializeAs<ClassRecord>(cvt, cr)); - if (cr.isForwardRef()) - continue; - name = cr.Name; - } break; - case LF_UNION: { - UnionRecord ur; - llvm::cantFail(TypeDeserializer::deserializeAs<UnionRecord>(cvt, ur)); - if (ur.isForwardRef()) - continue; - name = ur.Name; - } break; - case LF_ENUM: { - EnumRecord er; - llvm::cantFail(TypeDeserializer::deserializeAs<EnumRecord>(cvt, er)); - if (er.isForwardRef()) - continue; - name = er.Name; - } break; - default: - continue; - } - if (name.empty()) - continue; - - auto base_name = MSVCUndecoratedNameParser::DropScope(name); - m_type_base_names.Append(ConstString(base_name), ti->getIndex()); - } - - m_type_base_names.Sort(); -} - void SymbolFileNativePDB::DumpClangAST(Stream &s, llvm::StringRef filter) { auto ts_or_err = GetTypeSystemForLanguage(eLanguageTypeC_plus_plus); if (!ts_or_err) @@ -1767,9 +1720,9 @@ void SymbolFileNativePDB::FindTypes(const lldb_private::TypeQuery &query, std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); - // We can't query for the basename or full name because the type might reside - // in an anonymous namespace. Cache the basenames first. - CacheTypeNames(); + // 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); @@ -2253,9 +2206,13 @@ void SymbolFileNativePDB::BuildParentMap() { RecordIndices &indices = record_indices[tag.asTag().getUniqueName()]; 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; @@ -2341,6 +2298,8 @@ void SymbolFileNativePDB::BuildParentMap() { TypeIndex fwd = full_to_forward[full]; m_parent_types[fwd] = m_parent_types[full]; } + + m_type_base_names.Sort(); } std::optional<PdbCompilandSymId> diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h index 457b301c4a486..02e56484d7525 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h +++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h @@ -258,8 +258,6 @@ class SymbolFileNativePDB : public SymbolFileCommon { void ParseInlineSite(PdbCompilandSymId inline_site_id, Address func_addr); - void CacheTypeNames(); - llvm::BumpPtrAllocator m_allocator; lldb::addr_t m_obj_load_address = 0; >From 1d99fe1e67e822ca2f81ead485bd5fbec88bfd61 Mon Sep 17 00:00:00 2001 From: Nerixyz <nerix...@outlook.de> Date: Tue, 22 Jul 2025 14:36:19 +0200 Subject: [PATCH 3/3] refactor: convert test to use split-file --- .../Inputs/namespace-access.lldbinit | 18 --- .../SymbolFile/NativePDB/namespace-access.cpp | 114 --------------- .../NativePDB/namespace-access.test | 135 ++++++++++++++++++ 3 files changed, 135 insertions(+), 132 deletions(-) delete mode 100644 lldb/test/Shell/SymbolFile/NativePDB/Inputs/namespace-access.lldbinit delete mode 100644 lldb/test/Shell/SymbolFile/NativePDB/namespace-access.cpp create mode 100644 lldb/test/Shell/SymbolFile/NativePDB/namespace-access.test diff --git a/lldb/test/Shell/SymbolFile/NativePDB/Inputs/namespace-access.lldbinit b/lldb/test/Shell/SymbolFile/NativePDB/Inputs/namespace-access.lldbinit deleted file mode 100644 index e61ed2e2f453e..0000000000000 --- a/lldb/test/Shell/SymbolFile/NativePDB/Inputs/namespace-access.lldbinit +++ /dev/null @@ -1,18 +0,0 @@ -b main -r - -type lookup S -type lookup ::S -type lookup Outer::S -type lookup Outer::Inner1::S -type lookup Inner1::S -type lookup Outer::Inner1::Inner2::S -type lookup Inner2::S -type lookup Outer::Inner2::S -type lookup Outer::A -type lookup A -type lookup ::A -expr sizeof(S) -expr sizeof(A) - -quit diff --git a/lldb/test/Shell/SymbolFile/NativePDB/namespace-access.cpp b/lldb/test/Shell/SymbolFile/NativePDB/namespace-access.cpp deleted file mode 100644 index e171d189347d9..0000000000000 --- a/lldb/test/Shell/SymbolFile/NativePDB/namespace-access.cpp +++ /dev/null @@ -1,114 +0,0 @@ -// clang-format off -// REQUIRES: target-windows - -// Test namespace lookup. -// RUN: %build --nodefaultlib -o %t.exe -- %s -// RUN: %lldb -f %t.exe -s \ -// RUN: %p/Inputs/namespace-access.lldbinit 2>&1 | FileCheck %s - -struct S { - char a[1]; -}; - -namespace Outer { - - struct S { - char a[2]; - }; - - namespace Inner1 { - struct S { - char a[3]; - }; - - namespace Inner2 { - struct S { - char a[4]; - }; - } // namespace Inner2 - } // namespace Inner1 - - namespace Inner2 { - struct S { - char a[5]; - }; - } // namespace Inner2 - - namespace { - struct A { - char a[6]; - }; - } // namespace - -} // namespace Outer - -namespace { - struct A { - char a[7]; - }; -} // namespace - -int main(int argc, char **argv) { - S s; - Outer::S os; - Outer::Inner1::S oi1s; - Outer::Inner1::Inner2::S oi1i2s; - Outer::Inner2::S oi2s; - A a1; - Outer::A a2; - return sizeof(s) + sizeof(os) + sizeof(oi1s) + sizeof(oi1i2s) + sizeof(oi2s) + sizeof(a1) + sizeof(a2); -} - - - -// CHECK: (lldb) type lookup S -// CHECK: struct S { -// CHECK: struct S { -// CHECK: struct S { -// CHECK: struct S { -// CHECK: struct S { -// CHECK: } -// CHECK-NEXT: (lldb) type lookup ::S -// CHECK-NEXT: struct S { -// CHECK-NEXT: char a[1]; -// CHECK-NEXT: } -// CHECK-NEXT: (lldb) type lookup Outer::S -// CHECK-NEXT: struct S { -// CHECK-NEXT: char a[2]; -// CHECK-NEXT: } -// CHECK-NEXT: (lldb) type lookup Outer::Inner1::S -// CHECK-NEXT: struct S { -// CHECK-NEXT: char a[3]; -// CHECK-NEXT: } -// CHECK-NEXT: (lldb) type lookup Inner1::S -// CHECK-NEXT: struct S { -// CHECK-NEXT: char a[3]; -// CHECK-NEXT: } -// CHECK-NEXT: (lldb) type lookup Outer::Inner1::Inner2::S -// CHECK-NEXT: struct S { -// CHECK-NEXT: char a[4]; -// CHECK-NEXT: } -// CHECK-NEXT: (lldb) type lookup Inner2::S -// CHECK-NEXT: struct S { -// CHECK: struct S { -// CHECK: } -// CHECK-NEXT: (lldb) type lookup Outer::Inner2::S -// CHECK-NEXT: struct S { -// CHECK-NEXT: char a[5]; -// CHECK-NEXT: } -// CHECK-NEXT: (lldb) type lookup Outer::A -// CHECK-NEXT: struct A { -// CHECK-NEXT: char a[6]; -// CHECK-NEXT: } -// CHECK-NEXT: (lldb) type lookup A -// CHECK-NEXT: struct A { -// CHECK: struct A { -// CHECK: } -// CHECK-NEXT: (lldb) type lookup ::A -// CHECK-NEXT: struct A { -// CHECK-NEXT: char a[7]; -// CHECK-NEXT: } -// CHECK-NEXT: (lldb) expr sizeof(S) -// CHECK-NEXT: (__size_t) $0 = 1 -// CHECK-NEXT: (lldb) expr sizeof(A) -// CHECK-NEXT: (__size_t) $1 = 7 diff --git a/lldb/test/Shell/SymbolFile/NativePDB/namespace-access.test b/lldb/test/Shell/SymbolFile/NativePDB/namespace-access.test new file mode 100644 index 0000000000000..f6c1ccf22fa18 --- /dev/null +++ b/lldb/test/Shell/SymbolFile/NativePDB/namespace-access.test @@ -0,0 +1,135 @@ +# REQUIRES: target-windows + +# Test namespace lookup. +# RUN: split-file %s %t +# RUN: %build --nodefaultlib -o %t.exe -- %t/main.cpp +# RUN: %lldb -f %t.exe -s \ +# RUN: %t/commands.input 2>&1 | FileCheck %s + +#--- main.cpp + +struct S { + char a[1]; +}; + +namespace Outer { + + struct S { + char a[2]; + }; + + namespace Inner1 { + struct S { + char a[3]; + }; + + namespace Inner2 { + struct S { + char a[4]; + }; + } // namespace Inner2 + } // namespace Inner1 + + namespace Inner2 { + struct S { + char a[5]; + }; + } // namespace Inner2 + + namespace { + struct A { + char a[6]; + }; + } // namespace + +} // namespace Outer + +namespace { + struct A { + char a[7]; + }; +} // namespace + +int main(int argc, char **argv) { + S s; + Outer::S os; + Outer::Inner1::S oi1s; + Outer::Inner1::Inner2::S oi1i2s; + Outer::Inner2::S oi2s; + A a1; + Outer::A a2; + return sizeof(s) + sizeof(os) + sizeof(oi1s) + sizeof(oi1i2s) + sizeof(oi2s) + sizeof(a1) + sizeof(a2); +} + +#--- commands.input + +b main +r + +type lookup S +type lookup ::S +type lookup Outer::S +type lookup Outer::Inner1::S +type lookup Inner1::S +type lookup Outer::Inner1::Inner2::S +type lookup Inner2::S +type lookup Outer::Inner2::S +type lookup Outer::A +type lookup A +type lookup ::A +expr sizeof(S) +expr sizeof(A) + +quit + +# CHECK: (lldb) type lookup S +# CHECK: struct S { +# CHECK: struct S { +# CHECK: struct S { +# CHECK: struct S { +# CHECK: struct S { +# CHECK: } +# CHECK-NEXT: (lldb) type lookup ::S +# CHECK-NEXT: struct S { +# CHECK-NEXT: char a[1]; +# CHECK-NEXT: } +# CHECK-NEXT: (lldb) type lookup Outer::S +# CHECK-NEXT: struct S { +# CHECK-NEXT: char a[2]; +# CHECK-NEXT: } +# CHECK-NEXT: (lldb) type lookup Outer::Inner1::S +# CHECK-NEXT: struct S { +# CHECK-NEXT: char a[3]; +# CHECK-NEXT: } +# CHECK-NEXT: (lldb) type lookup Inner1::S +# CHECK-NEXT: struct S { +# CHECK-NEXT: char a[3]; +# CHECK-NEXT: } +# CHECK-NEXT: (lldb) type lookup Outer::Inner1::Inner2::S +# CHECK-NEXT: struct S { +# CHECK-NEXT: char a[4]; +# CHECK-NEXT: } +# CHECK-NEXT: (lldb) type lookup Inner2::S +# CHECK-NEXT: struct S { +# CHECK: struct S { +# CHECK: } +# CHECK-NEXT: (lldb) type lookup Outer::Inner2::S +# CHECK-NEXT: struct S { +# CHECK-NEXT: char a[5]; +# CHECK-NEXT: } +# CHECK-NEXT: (lldb) type lookup Outer::A +# CHECK-NEXT: struct A { +# CHECK-NEXT: char a[6]; +# CHECK-NEXT: } +# CHECK-NEXT: (lldb) type lookup A +# CHECK-NEXT: struct A { +# CHECK: struct A { +# CHECK: } +# CHECK-NEXT: (lldb) type lookup ::A +# CHECK-NEXT: struct A { +# CHECK-NEXT: char a[7]; +# CHECK-NEXT: } +# CHECK-NEXT: (lldb) expr sizeof(S) +# CHECK-NEXT: (__size_t) $0 = 1 +# CHECK-NEXT: (lldb) expr sizeof(A) +# CHECK-NEXT: (__size_t) $1 = 7 _______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits