[Lldb-commits] [lldb] [LLDB][NativePDB] Complete array member types in AST builder (PR #156370)
via lldb-commits
lldb-commits at lists.llvm.org
Tue Sep 2 09:09:52 PDT 2025
https://github.com/Nerixyz updated https://github.com/llvm/llvm-project/pull/156370
>From 967d3453e997ed25c3548898d69a40d079d307b1 Mon Sep 17 00:00:00 2001
From: Nerixyz <nerixdev at outlook.de>
Date: Mon, 1 Sep 2025 21:02:33 +0200
Subject: [PATCH 1/4] [LLDB] Complete constant array member types in class
members
---
.../TypeSystem/Clang/TypeSystemClang.cpp | 15 ++-
.../NativePDB/Inputs/incomplete-tag-type.cpp | 5 +
.../NativePDB/incomplete-tag-type.cpp | 45 --------
.../NativePDB/incomplete-tag-type.test | 109 ++++++++++++++++++
4 files changed, 126 insertions(+), 48 deletions(-)
delete mode 100644 lldb/test/Shell/SymbolFile/NativePDB/incomplete-tag-type.cpp
create mode 100644 lldb/test/Shell/SymbolFile/NativePDB/incomplete-tag-type.test
diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
index 39aacdb58e694..038677f68b991 100644
--- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
+++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
@@ -9577,12 +9577,21 @@ TypeSystemClang::DeclContextGetTypeSystemClang(const CompilerDeclContext &dc) {
}
void TypeSystemClang::RequireCompleteType(CompilerType type) {
+ if (!type)
+ return;
+
+ clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type));
+ if (qual_type.isNull())
+ return;
+
// Technically, enums can be incomplete too, but we don't handle those as they
// are emitted even under -flimit-debug-info.
- if (!TypeSystemClang::IsCXXClassType(type))
- return;
+ bool is_constant_array = qual_type->isConstantArrayType();
+ bool is_cxx_record = qual_type->getAsCXXRecordDecl() != nullptr;
+ if (is_constant_array || is_cxx_record)
+ type.GetCompleteType();
- if (type.GetCompleteType())
+ if (!is_cxx_record)
return;
// No complete definition in this module. Mark the class as complete to
diff --git a/lldb/test/Shell/SymbolFile/NativePDB/Inputs/incomplete-tag-type.cpp b/lldb/test/Shell/SymbolFile/NativePDB/Inputs/incomplete-tag-type.cpp
index c930338905445..d08f49d1014ba 100644
--- a/lldb/test/Shell/SymbolFile/NativePDB/Inputs/incomplete-tag-type.cpp
+++ b/lldb/test/Shell/SymbolFile/NativePDB/Inputs/incomplete-tag-type.cpp
@@ -13,3 +13,8 @@ struct E {
E();
};
E::E() = default;
+
+struct I {
+ I();
+};
+I::I() = default;
diff --git a/lldb/test/Shell/SymbolFile/NativePDB/incomplete-tag-type.cpp b/lldb/test/Shell/SymbolFile/NativePDB/incomplete-tag-type.cpp
deleted file mode 100644
index 7bc7e618667f7..0000000000000
--- a/lldb/test/Shell/SymbolFile/NativePDB/incomplete-tag-type.cpp
+++ /dev/null
@@ -1,45 +0,0 @@
-// clang-format off
-// REQUIRES: lld, x86
-
-// RUN: %clang_cl --target=x86_64-windows-msvc -c /Fo%t1.obj -- %p/Inputs/incomplete-tag-type.cpp
-// RUN: %clang_cl --target=x86_64-windows-msvc /O1 /Z7 -c /Fo%t2.obj -- %s
-// RUN: lld-link /debug:full /nodefaultlib /entry:main %t1.obj %t2.obj /out:%t.exe /pdb:%t.pdb
-// RUN: %lldb -f %t.exe -o \
-// RUN: "settings set interpreter.stop-command-source-on-error false" \
-// RUN: -o "expression b" -o "expression d" -o "expression static_e_ref" -o "exit" 2>&1 | FileCheck %s
-
-// CHECK: (lldb) expression b
-// CHECK: (B) $0 = {}
-// CHECK: (lldb) expression d
-// CHECK: (D) $1 = {}
-// CHECK: (lldb) expression static_e_ref
-// CHECK: error:{{.*}}incomplete type 'E' where a complete type is required
-
-// Complete base class.
-struct A { int x; A(); };
-struct B : A {};
-B b;
-
-// Complete data member.
-struct C {
- C();
-};
-
-struct D {
- C c;
-};
-D d;
-
-// Incomplete static data member should return error.
-struct E {
- E();
-};
-
-struct F {
- static E static_e;
-};
-
-E F::static_e = E();
-E& static_e_ref = F::static_e;
-
-int main(){}
diff --git a/lldb/test/Shell/SymbolFile/NativePDB/incomplete-tag-type.test b/lldb/test/Shell/SymbolFile/NativePDB/incomplete-tag-type.test
new file mode 100644
index 0000000000000..f30866ccdd6f0
--- /dev/null
+++ b/lldb/test/Shell/SymbolFile/NativePDB/incomplete-tag-type.test
@@ -0,0 +1,109 @@
+# REQUIRES: lld, x86
+
+# RUN: split-file %s %t
+
+# RUN: %clang_cl --target=x86_64-windows-msvc -c /Fo%t1.obj -- %p/Inputs/incomplete-tag-type.cpp
+# RUN: %clang_cl --target=x86_64-windows-msvc /O1 /Z7 -c /Fo%t2.obj -- %t/main.cpp
+# RUN: lld-link /debug:full /nodefaultlib /entry:main %t1.obj %t2.obj /out:%t.exe /pdb:%t.pdb
+
+# RUN: %lldb -f %t.exe -s %t/target-var.input 2>&1 | FileCheck %s --check-prefix=TARGET-VAR
+# RUN: %lldb -f %t.exe -s %t/expr.input 2>&1 | FileCheck %s --check-prefix=EXPR
+
+#--- main.cpp
+
+// Complete base class.
+struct A { int x; A(); };
+struct B : A {};
+B b;
+
+// Complete data member.
+struct C {
+ C();
+};
+
+struct D {
+ C c;
+};
+D d;
+
+// Incomplete static data member should return error.
+struct E {
+ E();
+};
+
+struct F {
+ static E static_e;
+};
+
+E F::static_e = E();
+E& static_e_ref = F::static_e;
+
+struct G {
+ int foo = 1;
+};
+struct H {
+ G g[2];
+};
+H h;
+
+struct I {
+ I();
+};
+struct J {
+ I i[2];
+};
+J j;
+
+
+int main(){}
+
+#--- target-var.input
+
+target variable b
+target variable d
+target variable h
+target variable j
+target variable static_e_ref
+exit
+
+#--- expr.input
+
+settings set interpreter.stop-command-source-on-error false
+expression b
+expression d
+expression h
+expression j
+expression static_e_ref
+exit
+
+# TARGET-VAR: (lldb) target variable b
+# TARGET-VAR-NEXT: (B) b = (A = <incomplete type>)
+# TARGET-VAR-NEXT: (lldb) target variable d
+# TARGET-VAR-NEXT: (D) d = {}
+# TARGET-VAR-NEXT: (lldb) target variable h
+# TARGET-VAR-NEXT: (H) h = {
+# TARGET-VAR-NEXT: g = {
+# TARGET-VAR-NEXT: [0] = (foo = 1)
+# TARGET-VAR-NEXT: [1] = (foo = 1)
+# TARGET-VAR-NEXT: }
+# TARGET-VAR-NEXT: }
+# TARGET-VAR-NEXT: (lldb) target variable j
+# TARGET-VAR-NEXT: (J) j = {}
+# TARGET-VAR-NEXT: (lldb) target variable static_e_ref
+# TARGET-VAR-NEXT: (E &) static_e_ref = 0x{{.*}} <incomplete type "E">
+
+# EXPR: (lldb) expression b
+# EXPR-NEXT: (B) $0 = {}
+# EXPR-NEXT: (lldb) expression d
+# EXPR-NEXT: (D) $1 = {}
+# EXPR-NEXT: (lldb) expression h
+# EXPR-NEXT: (H) $2 = {
+# EXPR-NEXT: g = {
+# EXPR-NEXT: [0] = (foo = 1)
+# EXPR-NEXT: [1] = (foo = 1)
+# EXPR-NEXT: }
+# EXPR-NEXT: }
+# EXPR-NEXT: (lldb) expression j
+# EXPR-NEXT: (J) $3 = {}
+# EXPR-NEXT: (lldb) expression static_e_ref
+# EXPR: error:{{.*}}incomplete type 'E' where a complete type is required
>From 4a08289d9b435e08cd8a7fac1ab9fcbbfdaa88f4 Mon Sep 17 00:00:00 2001
From: Nerixyz <nerixdev at outlook.de>
Date: Mon, 1 Sep 2025 21:54:49 +0200
Subject: [PATCH 2/4] fix: return if complete
---
lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
index 038677f68b991..218ea74bc74c2 100644
--- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
+++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
@@ -9589,7 +9589,8 @@ void TypeSystemClang::RequireCompleteType(CompilerType type) {
bool is_constant_array = qual_type->isConstantArrayType();
bool is_cxx_record = qual_type->getAsCXXRecordDecl() != nullptr;
if (is_constant_array || is_cxx_record)
- type.GetCompleteType();
+ if (type.GetCompleteType())
+ return;
if (!is_cxx_record)
return;
>From d978d598006163b1c5738fa0d17d60be7508fd75 Mon Sep 17 00:00:00 2001
From: Nerixyz <nerixdev at outlook.de>
Date: Tue, 2 Sep 2025 16:05:49 +0200
Subject: [PATCH 3/4] fix: require element type when creating array type
---
.../SymbolFile/NativePDB/PdbAstBuilder.cpp | 1 +
.../Plugins/TypeSystem/Clang/TypeSystemClang.cpp | 16 +++-------------
2 files changed, 4 insertions(+), 13 deletions(-)
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
index 709281cb32709..933c4361d93da 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
@@ -1169,6 +1169,7 @@ clang::QualType PdbAstBuilder::CreateEnumType(PdbTypeSymId id,
clang::QualType PdbAstBuilder::CreateArrayType(const ArrayRecord &ar) {
clang::QualType element_type = GetOrCreateType(ar.ElementType);
+ TypeSystemClang::RequireCompleteType(ToCompilerType(element_type));
SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>(
m_clang.GetSymbolFile()->GetBackingSymbolFile());
diff --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
index 218ea74bc74c2..39aacdb58e694 100644
--- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
+++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
@@ -9577,22 +9577,12 @@ TypeSystemClang::DeclContextGetTypeSystemClang(const CompilerDeclContext &dc) {
}
void TypeSystemClang::RequireCompleteType(CompilerType type) {
- if (!type)
- return;
-
- clang::QualType qual_type(ClangUtil::GetCanonicalQualType(type));
- if (qual_type.isNull())
- return;
-
// Technically, enums can be incomplete too, but we don't handle those as they
// are emitted even under -flimit-debug-info.
- bool is_constant_array = qual_type->isConstantArrayType();
- bool is_cxx_record = qual_type->getAsCXXRecordDecl() != nullptr;
- if (is_constant_array || is_cxx_record)
- if (type.GetCompleteType())
- return;
+ if (!TypeSystemClang::IsCXXClassType(type))
+ return;
- if (!is_cxx_record)
+ if (type.GetCompleteType())
return;
// No complete definition in this module. Mark the class as complete to
>From 28ee7f4f45e0cc656e9a6814db734e330af01e83 Mon Sep 17 00:00:00 2001
From: Nerixyz <nerixdev at outlook.de>
Date: Tue, 2 Sep 2025 18:09:11 +0200
Subject: [PATCH 4/4] fix: remove unused type
---
.../SymbolFile/NativePDB/Inputs/incomplete-tag-type.cpp | 5 -----
1 file changed, 5 deletions(-)
diff --git a/lldb/test/Shell/SymbolFile/NativePDB/Inputs/incomplete-tag-type.cpp b/lldb/test/Shell/SymbolFile/NativePDB/Inputs/incomplete-tag-type.cpp
index d08f49d1014ba..c930338905445 100644
--- a/lldb/test/Shell/SymbolFile/NativePDB/Inputs/incomplete-tag-type.cpp
+++ b/lldb/test/Shell/SymbolFile/NativePDB/Inputs/incomplete-tag-type.cpp
@@ -13,8 +13,3 @@ struct E {
E();
};
E::E() = default;
-
-struct I {
- I();
-};
-I::I() = default;
More information about the lldb-commits
mailing list