diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp --- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp +++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp @@ -1231,8 +1231,10 @@ clang::QualType PdbAstBuilder::CreateArrayType(const ArrayRecord &ar) { clang::QualType element_type = GetOrCreateType(ar.ElementType); - uint64_t element_count = - ar.Size / GetSizeOfType({ar.ElementType}, m_index.tpi()); + uint64_t element_size = GetSizeOfType({ar.ElementType}, m_index.tpi()); + if (element_size == 0) + return {}; + uint64_t element_count = ar.Size / element_size; CompilerType array_ct = m_clang.CreateArrayType(ToCompilerType(element_type), element_count, false); diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp --- a/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp +++ b/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp @@ -138,8 +138,6 @@ clang::QualType member_type = m_ast_builder.GetOrCreateType(PdbTypeSymId(static_data_member.Type)); - m_ast_builder.CompleteType(member_type); - CompilerType member_ct = m_ast_builder.ToCompilerType(member_type); lldb::AccessType access = @@ -149,7 +147,7 @@ // Static constant members may be a const[expr] declaration. // Query the symbol's value as the variable initializer if valid. - if (member_ct.IsConst()) { + if (member_ct.IsConst() && member_ct.IsCompleteType()) { std::string qual_name = decl->getQualifiedNameAsString(); auto results = diff --git a/lldb/test/Shell/SymbolFile/NativePDB/Inputs/local-variables.lldbinit b/lldb/test/Shell/SymbolFile/NativePDB/Inputs/local-variables.lldbinit --- a/lldb/test/Shell/SymbolFile/NativePDB/Inputs/local-variables.lldbinit +++ b/lldb/test/Shell/SymbolFile/NativePDB/Inputs/local-variables.lldbinit @@ -25,6 +25,8 @@ p Param2 p Local1 p Local2 +p varA.val +p varB.val continue target modules dump ast diff --git a/lldb/test/Shell/SymbolFile/NativePDB/local-variables.cpp b/lldb/test/Shell/SymbolFile/NativePDB/local-variables.cpp --- a/lldb/test/Shell/SymbolFile/NativePDB/local-variables.cpp +++ b/lldb/test/Shell/SymbolFile/NativePDB/local-variables.cpp @@ -5,6 +5,26 @@ // RUN: env LLDB_USE_NATIVE_PDB_READER=1 %lldb -f %t.exe -s \ // RUN: %p/Inputs/local-variables.lldbinit 2>&1 | FileCheck %s +class B; +class A { +public: + static const A constA; + static A a; + static B b; + int val = 1; +}; +class B { +public: + static A a; + int val = 2; +}; +A varA; +B varB; +const A A::constA = varA; +A A::a = varA; +B A::b = varB; +A B::a = varA; + int Function(int Param1, char Param2) { unsigned Local1 = Param1 + 1; char Local2 = Param2 + 1; @@ -15,7 +35,7 @@ int main(int argc, char **argv) { int SomeLocal = argc * 2; - return Function(SomeLocal, 'a'); + return varA.val + varB.val + Function(SomeLocal, 'a'); } // CHECK: (lldb) target create "{{.*}}local-variables.cpp.tmp.exe" @@ -28,13 +48,13 @@ // CHECK-NEXT: Process {{.*}} stopped // CHECK-NEXT: * thread #1, stop reason = breakpoint 1.1 // CHECK-NEXT: frame #0: {{.*}} local-variables.cpp.tmp.exe`main(argc=8, argv={{.*}}) at local-variables.cpp:{{.*}} -// CHECK-NEXT: 14 } -// CHECK-NEXT: 15 -// CHECK-NEXT: 16 int main(int argc, char **argv) { -// CHECK-NEXT: -> 17 int SomeLocal = argc * 2; -// CHECK-NEXT: 18 return Function(SomeLocal, 'a'); -// CHECK-NEXT: 19 } -// CHECK-NEXT: 20 +// CHECK-NEXT: 34 } +// CHECK-NEXT: 35 +// CHECK-NEXT: 36 int main(int argc, char **argv) { +// CHECK-NEXT: -> 37 int SomeLocal = argc * 2; +// CHECK-NEXT: 38 return varA.val + varB.val + Function(SomeLocal, 'a'); +// CHECK-NEXT: 39 } +// CHECK-NEXT: 40 // CHECK: Process {{.*}} launched: '{{.*}}local-variables.cpp.tmp.exe' // CHECK-NEXT: (lldb) p argc @@ -43,12 +63,12 @@ // CHECK-NEXT: Process {{.*}} stopped // CHECK-NEXT: * thread #1, stop reason = step in // CHECK-NEXT: frame #0: {{.*}} local-variables.cpp.tmp.exe`main(argc=8, argv={{.*}}) at local-variables.cpp:{{.*}} -// CHECK-NEXT: 15 -// CHECK-NEXT: 16 int main(int argc, char **argv) { -// CHECK-NEXT: 17 int SomeLocal = argc * 2; -// CHECK-NEXT: -> 18 return Function(SomeLocal, 'a'); -// CHECK-NEXT: 19 } -// CHECK-NEXT: 20 +// CHECK-NEXT: 35 +// CHECK-NEXT: 36 int main(int argc, char **argv) { +// CHECK-NEXT: 37 int SomeLocal = argc * 2; +// CHECK-NEXT: -> 38 return varA.val + varB.val + Function(SomeLocal, 'a'); +// CHECK-NEXT: 39 } +// CHECK-NEXT: 40 // CHECK: (lldb) p SomeLocal // CHECK-NEXT: (int) $1 = 16 @@ -56,13 +76,13 @@ // CHECK-NEXT: Process {{.*}} stopped // CHECK-NEXT: * thread #1, stop reason = step in // CHECK-NEXT: frame #0: {{.*}} local-variables.cpp.tmp.exe`Function(Param1=16, Param2='a') at local-variables.cpp:{{.*}} -// CHECK-NEXT: 6 -// CHECK-NEXT: 7 -// CHECK-NEXT: 8 int Function(int Param1, char Param2) { -// CHECK-NEXT: -> 9 unsigned Local1 = Param1 + 1; -// CHECK-NEXT: 10 char Local2 = Param2 + 1; -// CHECK-NEXT: 11 ++Local1; -// CHECK-NEXT: 12 ++Local2; +// CHECK-NEXT: 26 +// CHECK-NEXT: 27 +// CHECK-NEXT: 28 int Function(int Param1, char Param2) { +// CHECK-NEXT: -> 29 unsigned Local1 = Param1 + 1; +// CHECK-NEXT: 30 char Local2 = Param2 + 1; +// CHECK-NEXT: 31 ++Local1; +// CHECK-NEXT: 32 ++Local2; // CHECK: (lldb) p Param1 // CHECK-NEXT: (int) $2 = 16 @@ -72,13 +92,13 @@ // CHECK-NEXT: Process {{.*}} stopped // CHECK-NEXT: * thread #1, stop reason = step in // CHECK-NEXT: frame #0: {{.*}} local-variables.cpp.tmp.exe`Function(Param1=16, Param2='a') at local-variables.cpp:{{.*}} -// CHECK-NEXT: 7 -// CHECK-NEXT: 8 int Function(int Param1, char Param2) { -// CHECK-NEXT: 9 unsigned Local1 = Param1 + 1; -// CHECK-NEXT: -> 10 char Local2 = Param2 + 1; -// CHECK-NEXT: 11 ++Local1; -// CHECK-NEXT: 12 ++Local2; -// CHECK-NEXT: 13 return Local1; +// CHECK-NEXT: 27 +// CHECK-NEXT: 28 int Function(int Param1, char Param2) { +// CHECK-NEXT: 29 unsigned Local1 = Param1 + 1; +// CHECK-NEXT: -> 30 char Local2 = Param2 + 1; +// CHECK-NEXT: 31 ++Local1; +// CHECK-NEXT: 32 ++Local2; +// CHECK-NEXT: 33 return Local1; // CHECK: (lldb) p Param1 // CHECK-NEXT: (int) $4 = 16 @@ -90,13 +110,13 @@ // CHECK-NEXT: Process {{.*}} stopped // CHECK-NEXT: * thread #1, stop reason = step in // CHECK-NEXT: frame #0: {{.*}} local-variables.cpp.tmp.exe`Function(Param1=16, Param2='a') at local-variables.cpp:{{.*}} -// CHECK-NEXT: 8 int Function(int Param1, char Param2) { -// CHECK-NEXT: 9 unsigned Local1 = Param1 + 1; -// CHECK-NEXT: 10 char Local2 = Param2 + 1; -// CHECK-NEXT: -> 11 ++Local1; -// CHECK-NEXT: 12 ++Local2; -// CHECK-NEXT: 13 return Local1; -// CHECK-NEXT: 14 } +// CHECK-NEXT: 28 int Function(int Param1, char Param2) { +// CHECK-NEXT: 29 unsigned Local1 = Param1 + 1; +// CHECK-NEXT: 30 char Local2 = Param2 + 1; +// CHECK-NEXT: -> 31 ++Local1; +// CHECK-NEXT: 32 ++Local2; +// CHECK-NEXT: 33 return Local1; +// CHECK-NEXT: 34 } // CHECK: (lldb) p Param1 // CHECK-NEXT: (int) $7 = 16 @@ -110,13 +130,13 @@ // CHECK-NEXT: Process {{.*}} stopped // CHECK-NEXT: * thread #1, stop reason = step in // CHECK-NEXT: frame #0: {{.*}} local-variables.cpp.tmp.exe`Function(Param1=16, Param2='a') at local-variables.cpp:{{.*}} -// CHECK-NEXT: 9 unsigned Local1 = Param1 + 1; -// CHECK-NEXT: 10 char Local2 = Param2 + 1; -// CHECK-NEXT: 11 ++Local1; -// CHECK-NEXT: -> 12 ++Local2; -// CHECK-NEXT: 13 return Local1; -// CHECK-NEXT: 14 } -// CHECK-NEXT: 15 +// CHECK-NEXT: 29 unsigned Local1 = Param1 + 1; +// CHECK-NEXT: 30 char Local2 = Param2 + 1; +// CHECK-NEXT: 31 ++Local1; +// CHECK-NEXT: -> 32 ++Local2; +// CHECK-NEXT: 33 return Local1; +// CHECK-NEXT: 34 } +// CHECK-NEXT: 35 // CHECK: (lldb) p Param1 // CHECK-NEXT: (int) $11 = 16 @@ -130,13 +150,13 @@ // CHECK-NEXT: Process {{.*}} stopped // CHECK-NEXT: * thread #1, stop reason = step in // CHECK-NEXT: frame #0: {{.*}} local-variables.cpp.tmp.exe`Function(Param1=16, Param2='a') at local-variables.cpp:{{.*}} -// CHECK-NEXT: 10 char Local2 = Param2 + 1; -// CHECK-NEXT: 11 ++Local1; -// CHECK-NEXT: 12 ++Local2; -// CHECK-NEXT: -> 13 return Local1; -// CHECK-NEXT: 14 } -// CHECK-NEXT: 15 -// CHECK-NEXT: 16 int main(int argc, char **argv) { +// CHECK-NEXT: 30 char Local2 = Param2 + 1; +// CHECK-NEXT: 31 ++Local1; +// CHECK-NEXT: 32 ++Local2; +// CHECK-NEXT: -> 33 return Local1; +// CHECK-NEXT: 34 } +// CHECK-NEXT: 35 +// CHECK-NEXT: 36 int main(int argc, char **argv) { // CHECK: (lldb) p Param1 // CHECK-NEXT: (int) $15 = 16 @@ -146,9 +166,13 @@ // CHECK-NEXT: (unsigned int) $17 = 18 // CHECK-NEXT: (lldb) p Local2 // CHECK-NEXT: (char) $18 = 'c' +// CHECK-NEXT: (lldb) p varA.val +// CHECK-NEXT: (int) $19 = 1 +// CHECK-NEXT: (lldb) p varB.val +// CHECK-NEXT: (int) $20 = 2 // CHECK-NEXT: (lldb) continue // CHECK-NEXT: Process {{.*}} resuming -// CHECK-NEXT: Process {{.*}} exited with status = 18 (0x00000012) +// CHECK-NEXT: Process {{.*}} exited with status = 21 (0x00000015) // CHECK: (lldb) target modules dump ast // CHECK-NEXT: Dumping clang ast for {{.*}} modules. @@ -157,6 +181,6 @@ // CHECK-NEXT: | |-ParmVarDecl {{.*}} argc 'int' // CHECK-NEXT: | `-ParmVarDecl {{.*}} argv 'char **' // CHECK-NEXT: |-FunctionDecl {{.*}} __scrt_common_main_seh 'int ()' static -// CHECK-NEXT: `-FunctionDecl {{.*}} Function 'int (int, char)' +// CHECK-NEXT: |-FunctionDecl {{.*}} Function 'int (int, char)' // CHECK-NEXT: |-ParmVarDecl {{.*}} Param1 'int' // CHECK-NEXT: `-ParmVarDecl {{.*}} Param2 'char'