[Lldb-commits] [lldb] r349067 - [NativePDB] Add support for local variables.

Zachary Turner via lldb-commits lldb-commits at lists.llvm.org
Thu Dec 13 10:17:51 PST 2018


Author: zturner
Date: Thu Dec 13 10:17:51 2018
New Revision: 349067

URL: http://llvm.org/viewvc/llvm-project?rev=349067&view=rev
Log:
[NativePDB] Add support for local variables.

This patch adds support for parsing and evaluating local variables.
using the native pdb plugin.

Differential Revision: https://reviews.llvm.org/D55575

Added:
    lldb/trunk/lit/SymbolFile/NativePDB/Inputs/local-variables.lldbinit
    lldb/trunk/lit/SymbolFile/NativePDB/local-variables.cpp
Modified:
    lldb/trunk/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp
    lldb/trunk/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.h
    lldb/trunk/source/Plugins/SymbolFile/NativePDB/PdbSymUid.h
    lldb/trunk/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
    lldb/trunk/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
    lldb/trunk/source/Symbol/ClangASTContext.cpp

Added: lldb/trunk/lit/SymbolFile/NativePDB/Inputs/local-variables.lldbinit
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lit/SymbolFile/NativePDB/Inputs/local-variables.lldbinit?rev=349067&view=auto
==============================================================================
--- lldb/trunk/lit/SymbolFile/NativePDB/Inputs/local-variables.lldbinit (added)
+++ lldb/trunk/lit/SymbolFile/NativePDB/Inputs/local-variables.lldbinit Thu Dec 13 10:17:51 2018
@@ -0,0 +1,32 @@
+break set -n main
+run a b c d e f g
+p argc
+step
+p SomeLocal
+step
+p Param1
+p Param2
+step
+p Param1
+p Param2
+p Local1
+step
+p Param1
+p Param2
+p Local1
+p Local2
+step
+p Param1
+p Param2
+p Local1
+p Local2
+step
+p Param1
+p Param2
+p Local1
+p Local2
+continue
+
+target modules dump ast
+
+quit

Added: lldb/trunk/lit/SymbolFile/NativePDB/local-variables.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lit/SymbolFile/NativePDB/local-variables.cpp?rev=349067&view=auto
==============================================================================
--- lldb/trunk/lit/SymbolFile/NativePDB/local-variables.cpp (added)
+++ lldb/trunk/lit/SymbolFile/NativePDB/local-variables.cpp Thu Dec 13 10:17:51 2018
@@ -0,0 +1,161 @@
+// clang-format off
+
+// REQUIRES: system-windows
+// RUN: %build -o %t.exe -- %s
+// RUN: env LLDB_USE_NATIVE_PDB_READER=1 %lldb -f %t.exe -s \
+// RUN:     %p/Inputs/local-variables.lldbinit 2>&1 | FileCheck %s
+
+int Function(int Param1, char Param2) {
+  unsigned Local1 = Param1 + 1;
+  char Local2 = Param2 + 1;
+  ++Local1;
+  ++Local2;
+  return Local1;
+}
+
+int main(int argc, char **argv) {
+  int SomeLocal = argc * 2;
+  return Function(SomeLocal, 'a');
+}
+
+// CHECK:      (lldb) target create "{{.*}}local-variables.cpp.tmp.exe"
+// CHECK-NEXT: Current executable set to '{{.*}}local-variables.cpp.tmp.exe'
+// CHECK-NEXT: (lldb) command source -s 0 '{{.*}}local-variables.lldbinit'
+// CHECK-NEXT: Executing commands in '{{.*}}local-variables.lldbinit'.
+// CHECK-NEXT: (lldb) break set -n main
+// CHECK-NEXT: Breakpoint 1: where = local-variables.cpp.tmp.exe`main + {{.*}} at local-variables.cpp:{{.*}}, address = {{.*}}
+// CHECK-NEXT: (lldb) run a b c d e f g
+// 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:      Process {{.*}} launched: '{{.*}}local-variables.cpp.tmp.exe'
+// CHECK-NEXT: (lldb) p argc
+// CHECK-NEXT: (int) $0 = 8
+// CHECK-NEXT: (lldb) step
+// 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:      (lldb) p SomeLocal
+// CHECK-NEXT: (int) $1 = 16
+// CHECK-NEXT: (lldb) step
+// 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:      (lldb) p Param1
+// CHECK-NEXT: (int) $2 = 16
+// CHECK-NEXT: (lldb) p Param2
+// CHECK-NEXT: (char) $3 = 'a'
+// CHECK-NEXT: (lldb) step
+// 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:      (lldb) p Param1
+// CHECK-NEXT: (int) $4 = 16
+// CHECK-NEXT: (lldb) p Param2
+// CHECK-NEXT: (char) $5 = 'a'
+// CHECK-NEXT: (lldb) p Local1
+// CHECK-NEXT: (unsigned int) $6 = 17
+// CHECK-NEXT: (lldb) step
+// 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:      (lldb) p Param1
+// CHECK-NEXT: (int) $7 = 16
+// CHECK-NEXT: (lldb) p Param2
+// CHECK-NEXT: (char) $8 = 'a'
+// CHECK-NEXT: (lldb) p Local1
+// CHECK-NEXT: (unsigned int) $9 = 17
+// CHECK-NEXT: (lldb) p Local2
+// CHECK-NEXT: (char) $10 = 'b'
+// CHECK-NEXT: (lldb) step
+// 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:      (lldb) p Param1
+// CHECK-NEXT: (int) $11 = 16
+// CHECK-NEXT: (lldb) p Param2
+// CHECK-NEXT: (char) $12 = 'a'
+// CHECK-NEXT: (lldb) p Local1
+// CHECK-NEXT: (unsigned int) $13 = 18
+// CHECK-NEXT: (lldb) p Local2
+// CHECK-NEXT: (char) $14 = 'b'
+// CHECK-NEXT: (lldb) step
+// 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:      (lldb) p Param1
+// CHECK-NEXT: (int) $15 = 16
+// CHECK-NEXT: (lldb) p Param2
+// CHECK-NEXT: (char) $16 = 'a'
+// CHECK-NEXT: (lldb) p Local1
+// CHECK-NEXT: (unsigned int) $17 = 18
+// CHECK-NEXT: (lldb) p Local2
+// CHECK-NEXT: (char) $18 = 'c'
+// CHECK-NEXT: (lldb) continue
+// CHECK-NEXT: Process {{.*}} resuming
+// CHECK-NEXT: Process {{.*}} exited with status = 18 (0x00000012)
+
+// CHECK:      (lldb) target modules dump ast
+// CHECK-NEXT: Dumping clang ast for 7 modules.
+// CHECK-NEXT: TranslationUnitDecl
+// CHECK-NEXT: |-FunctionDecl {{.*}} main 'int (int, char **)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} argc 'int'
+// CHECK-NEXT: | `-ParmVarDecl {{.*}} argv 'char **'
+// CHECK-NEXT: |-FunctionDecl {{.*}} Function 'int (int, char)'
+// CHECK-NEXT: | |-ParmVarDecl {{.*}} Param1 'int'
+// CHECK-NEXT: | `-ParmVarDecl {{.*}} Param2 'char'

Modified: lldb/trunk/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp?rev=349067&r1=349066&r2=349067&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp Thu Dec 13 10:17:51 2018
@@ -9,12 +9,14 @@
 
 #include "DWARFLocationExpression.h"
 
+#include "Plugins/Process/Utility/lldb-x86-register-enums.h"
 #include "lldb/Core/Module.h"
 #include "lldb/Core/Section.h"
 #include "lldb/Core/StreamBuffer.h"
 #include "lldb/Expression/DWARFExpression.h"
 #include "lldb/Utility/ArchSpec.h"
 #include "lldb/Utility/DataBufferHeap.h"
+
 #include "llvm/BinaryFormat/Dwarf.h"
 #include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
 #include "llvm/DebugInfo/CodeView/TypeIndex.h"
@@ -29,6 +31,467 @@ using namespace lldb_private::npdb;
 using namespace llvm::codeview;
 using namespace llvm::pdb;
 
+static const uint32_t g_code_view_to_lldb_registers_x86[] = {
+    LLDB_INVALID_REGNUM, // NONE
+    lldb_al_i386,        // AL
+    lldb_cl_i386,        // CL
+    lldb_dl_i386,        // DL
+    lldb_bl_i386,        // BL
+    lldb_ah_i386,        // AH
+    lldb_ch_i386,        // CH
+    lldb_dh_i386,        // DH
+    lldb_bh_i386,        // BH
+    lldb_ax_i386,        // AX
+    lldb_cx_i386,        // CX
+    lldb_dx_i386,        // DX
+    lldb_bx_i386,        // BX
+    lldb_sp_i386,        // SP
+    lldb_bp_i386,        // BP
+    lldb_si_i386,        // SI
+    lldb_di_i386,        // DI
+    lldb_eax_i386,       // EAX
+    lldb_ecx_i386,       // ECX
+    lldb_edx_i386,       // EDX
+    lldb_ebx_i386,       // EBX
+    lldb_esp_i386,       // ESP
+    lldb_ebp_i386,       // EBP
+    lldb_esi_i386,       // ESI
+    lldb_edi_i386,       // EDI
+    lldb_es_i386,        // ES
+    lldb_cs_i386,        // CS
+    lldb_ss_i386,        // SS
+    lldb_ds_i386,        // DS
+    lldb_fs_i386,        // FS
+    lldb_gs_i386,        // GS
+    LLDB_INVALID_REGNUM, // IP
+    LLDB_INVALID_REGNUM, // FLAGS
+    lldb_eip_i386,       // EIP
+    lldb_eflags_i386,    // EFLAGS
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, // TEMP
+    LLDB_INVALID_REGNUM, // TEMPH
+    LLDB_INVALID_REGNUM, // QUOTE
+    LLDB_INVALID_REGNUM, // PCDR3
+    LLDB_INVALID_REGNUM, // PCDR4
+    LLDB_INVALID_REGNUM, // PCDR5
+    LLDB_INVALID_REGNUM, // PCDR6
+    LLDB_INVALID_REGNUM, // PCDR7
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, // CR0
+    LLDB_INVALID_REGNUM, // CR1
+    LLDB_INVALID_REGNUM, // CR2
+    LLDB_INVALID_REGNUM, // CR3
+    LLDB_INVALID_REGNUM, // CR4
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    lldb_dr0_i386, // DR0
+    lldb_dr1_i386, // DR1
+    lldb_dr2_i386, // DR2
+    lldb_dr3_i386, // DR3
+    lldb_dr4_i386, // DR4
+    lldb_dr5_i386, // DR5
+    lldb_dr6_i386, // DR6
+    lldb_dr7_i386, // DR7
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, // GDTR
+    LLDB_INVALID_REGNUM, // GDTL
+    LLDB_INVALID_REGNUM, // IDTR
+    LLDB_INVALID_REGNUM, // IDTL
+    LLDB_INVALID_REGNUM, // LDTR
+    LLDB_INVALID_REGNUM, // TR
+    LLDB_INVALID_REGNUM, // PSEUDO1
+    LLDB_INVALID_REGNUM, // PSEUDO2
+    LLDB_INVALID_REGNUM, // PSEUDO3
+    LLDB_INVALID_REGNUM, // PSEUDO4
+    LLDB_INVALID_REGNUM, // PSEUDO5
+    LLDB_INVALID_REGNUM, // PSEUDO6
+    LLDB_INVALID_REGNUM, // PSEUDO7
+    LLDB_INVALID_REGNUM, // PSEUDO8
+    LLDB_INVALID_REGNUM, // PSEUDO9
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    lldb_st0_i386,       // ST0
+    lldb_st1_i386,       // ST1
+    lldb_st2_i386,       // ST2
+    lldb_st3_i386,       // ST3
+    lldb_st4_i386,       // ST4
+    lldb_st5_i386,       // ST5
+    lldb_st6_i386,       // ST6
+    lldb_st7_i386,       // ST7
+    LLDB_INVALID_REGNUM, // CTRL
+    LLDB_INVALID_REGNUM, // STAT
+    LLDB_INVALID_REGNUM, // TAG
+    LLDB_INVALID_REGNUM, // FPIP
+    LLDB_INVALID_REGNUM, // FPCS
+    LLDB_INVALID_REGNUM, // FPDO
+    LLDB_INVALID_REGNUM, // FPDS
+    LLDB_INVALID_REGNUM, // ISEM
+    LLDB_INVALID_REGNUM, // FPEIP
+    LLDB_INVALID_REGNUM, // FPEDO
+    lldb_mm0_i386,       // MM0
+    lldb_mm1_i386,       // MM1
+    lldb_mm2_i386,       // MM2
+    lldb_mm3_i386,       // MM3
+    lldb_mm4_i386,       // MM4
+    lldb_mm5_i386,       // MM5
+    lldb_mm6_i386,       // MM6
+    lldb_mm7_i386,       // MM7
+    lldb_xmm0_i386,      // XMM0
+    lldb_xmm1_i386,      // XMM1
+    lldb_xmm2_i386,      // XMM2
+    lldb_xmm3_i386,      // XMM3
+    lldb_xmm4_i386,      // XMM4
+    lldb_xmm5_i386,      // XMM5
+    lldb_xmm6_i386,      // XMM6
+    lldb_xmm7_i386       // XMM7
+};
+
+static const uint32_t g_code_view_to_lldb_registers_x86_64[] = {
+    LLDB_INVALID_REGNUM, // NONE
+    lldb_al_x86_64,      // AL
+    lldb_cl_x86_64,      // CL
+    lldb_dl_x86_64,      // DL
+    lldb_bl_x86_64,      // BL
+    lldb_ah_x86_64,      // AH
+    lldb_ch_x86_64,      // CH
+    lldb_dh_x86_64,      // DH
+    lldb_bh_x86_64,      // BH
+    lldb_ax_x86_64,      // AX
+    lldb_cx_x86_64,      // CX
+    lldb_dx_x86_64,      // DX
+    lldb_bx_x86_64,      // BX
+    lldb_sp_x86_64,      // SP
+    lldb_bp_x86_64,      // BP
+    lldb_si_x86_64,      // SI
+    lldb_di_x86_64,      // DI
+    lldb_eax_x86_64,     // EAX
+    lldb_ecx_x86_64,     // ECX
+    lldb_edx_x86_64,     // EDX
+    lldb_ebx_x86_64,     // EBX
+    lldb_esp_x86_64,     // ESP
+    lldb_ebp_x86_64,     // EBP
+    lldb_esi_x86_64,     // ESI
+    lldb_edi_x86_64,     // EDI
+    lldb_es_x86_64,      // ES
+    lldb_cs_x86_64,      // CS
+    lldb_ss_x86_64,      // SS
+    lldb_ds_x86_64,      // DS
+    lldb_fs_x86_64,      // FS
+    lldb_gs_x86_64,      // GS
+    LLDB_INVALID_REGNUM, // IP
+    LLDB_INVALID_REGNUM, // FLAGS
+    LLDB_INVALID_REGNUM, // EIP
+    LLDB_INVALID_REGNUM, // EFLAGS
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, // TEMP
+    LLDB_INVALID_REGNUM, // TEMPH
+    LLDB_INVALID_REGNUM, // QUOTE
+    LLDB_INVALID_REGNUM, // PCDR3
+    LLDB_INVALID_REGNUM, // PCDR4
+    LLDB_INVALID_REGNUM, // PCDR5
+    LLDB_INVALID_REGNUM, // PCDR6
+    LLDB_INVALID_REGNUM, // PCDR7
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, // CR0
+    LLDB_INVALID_REGNUM, // CR1
+    LLDB_INVALID_REGNUM, // CR2
+    LLDB_INVALID_REGNUM, // CR3
+    LLDB_INVALID_REGNUM, // CR4
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    lldb_dr0_x86_64, // DR0
+    lldb_dr1_x86_64, // DR1
+    lldb_dr2_x86_64, // DR2
+    lldb_dr3_x86_64, // DR3
+    lldb_dr4_x86_64, // DR4
+    lldb_dr5_x86_64, // DR5
+    lldb_dr6_x86_64, // DR6
+    lldb_dr7_x86_64, // DR7
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, // GDTR
+    LLDB_INVALID_REGNUM, // GDTL
+    LLDB_INVALID_REGNUM, // IDTR
+    LLDB_INVALID_REGNUM, // IDTL
+    LLDB_INVALID_REGNUM, // LDTR
+    LLDB_INVALID_REGNUM, // TR
+    LLDB_INVALID_REGNUM, // PSEUDO1
+    LLDB_INVALID_REGNUM, // PSEUDO2
+    LLDB_INVALID_REGNUM, // PSEUDO3
+    LLDB_INVALID_REGNUM, // PSEUDO4
+    LLDB_INVALID_REGNUM, // PSEUDO5
+    LLDB_INVALID_REGNUM, // PSEUDO6
+    LLDB_INVALID_REGNUM, // PSEUDO7
+    LLDB_INVALID_REGNUM, // PSEUDO8
+    LLDB_INVALID_REGNUM, // PSEUDO9
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    lldb_st0_x86_64,     // ST0
+    lldb_st1_x86_64,     // ST1
+    lldb_st2_x86_64,     // ST2
+    lldb_st3_x86_64,     // ST3
+    lldb_st4_x86_64,     // ST4
+    lldb_st5_x86_64,     // ST5
+    lldb_st6_x86_64,     // ST6
+    lldb_st7_x86_64,     // ST7
+    LLDB_INVALID_REGNUM, // CTRL
+    LLDB_INVALID_REGNUM, // STAT
+    LLDB_INVALID_REGNUM, // TAG
+    LLDB_INVALID_REGNUM, // FPIP
+    LLDB_INVALID_REGNUM, // FPCS
+    LLDB_INVALID_REGNUM, // FPDO
+    LLDB_INVALID_REGNUM, // FPDS
+    LLDB_INVALID_REGNUM, // ISEM
+    LLDB_INVALID_REGNUM, // FPEIP
+    LLDB_INVALID_REGNUM, // FPEDO
+    lldb_mm0_x86_64,     // MM0
+    lldb_mm1_x86_64,     // MM1
+    lldb_mm2_x86_64,     // MM2
+    lldb_mm3_x86_64,     // MM3
+    lldb_mm4_x86_64,     // MM4
+    lldb_mm5_x86_64,     // MM5
+    lldb_mm6_x86_64,     // MM6
+    lldb_mm7_x86_64,     // MM7
+    lldb_xmm0_x86_64,    // XMM0
+    lldb_xmm1_x86_64,    // XMM1
+    lldb_xmm2_x86_64,    // XMM2
+    lldb_xmm3_x86_64,    // XMM3
+    lldb_xmm4_x86_64,    // XMM4
+    lldb_xmm5_x86_64,    // XMM5
+    lldb_xmm6_x86_64,    // XMM6
+    lldb_xmm7_x86_64,    // XMM7
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM,
+    lldb_mxcsr_x86_64,   // MXCSR
+    LLDB_INVALID_REGNUM, // EDXEAX
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, // EMM0L
+    LLDB_INVALID_REGNUM, // EMM1L
+    LLDB_INVALID_REGNUM, // EMM2L
+    LLDB_INVALID_REGNUM, // EMM3L
+    LLDB_INVALID_REGNUM, // EMM4L
+    LLDB_INVALID_REGNUM, // EMM5L
+    LLDB_INVALID_REGNUM, // EMM6L
+    LLDB_INVALID_REGNUM, // EMM7L
+    LLDB_INVALID_REGNUM, // EMM0H
+    LLDB_INVALID_REGNUM, // EMM1H
+    LLDB_INVALID_REGNUM, // EMM2H
+    LLDB_INVALID_REGNUM, // EMM3H
+    LLDB_INVALID_REGNUM, // EMM4H
+    LLDB_INVALID_REGNUM, // EMM5H
+    LLDB_INVALID_REGNUM, // EMM6H
+    LLDB_INVALID_REGNUM, // EMM7H
+    LLDB_INVALID_REGNUM, // MM00
+    LLDB_INVALID_REGNUM, // MM01
+    LLDB_INVALID_REGNUM, // MM10
+    LLDB_INVALID_REGNUM, // MM11
+    LLDB_INVALID_REGNUM, // MM20
+    LLDB_INVALID_REGNUM, // MM21
+    LLDB_INVALID_REGNUM, // MM30
+    LLDB_INVALID_REGNUM, // MM31
+    LLDB_INVALID_REGNUM, // MM40
+    LLDB_INVALID_REGNUM, // MM41
+    LLDB_INVALID_REGNUM, // MM50
+    LLDB_INVALID_REGNUM, // MM51
+    LLDB_INVALID_REGNUM, // MM60
+    LLDB_INVALID_REGNUM, // MM61
+    LLDB_INVALID_REGNUM, // MM70
+    LLDB_INVALID_REGNUM, // MM71
+    lldb_xmm8_x86_64,    // XMM8
+    lldb_xmm9_x86_64,    // XMM9
+    lldb_xmm10_x86_64,   // XMM10
+    lldb_xmm11_x86_64,   // XMM11
+    lldb_xmm12_x86_64,   // XMM12
+    lldb_xmm13_x86_64,   // XMM13
+    lldb_xmm14_x86_64,   // XMM14
+    lldb_xmm15_x86_64,   // XMM15
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM,
+    lldb_sil_x86_64,   // SIL
+    lldb_dil_x86_64,   // DIL
+    lldb_bpl_x86_64,   // BPL
+    lldb_spl_x86_64,   // SPL
+    lldb_rax_x86_64,   // RAX
+    lldb_rbx_x86_64,   // RBX
+    lldb_rcx_x86_64,   // RCX
+    lldb_rdx_x86_64,   // RDX
+    lldb_rsi_x86_64,   // RSI
+    lldb_rdi_x86_64,   // RDI
+    lldb_rbp_x86_64,   // RBP
+    lldb_rsp_x86_64,   // RSP
+    lldb_r8_x86_64,    // R8
+    lldb_r9_x86_64,    // R9
+    lldb_r10_x86_64,   // R10
+    lldb_r11_x86_64,   // R11
+    lldb_r12_x86_64,   // R12
+    lldb_r13_x86_64,   // R13
+    lldb_r14_x86_64,   // R14
+    lldb_r15_x86_64,   // R15
+    lldb_r8l_x86_64,   // R8B
+    lldb_r9l_x86_64,   // R9B
+    lldb_r10l_x86_64,  // R10B
+    lldb_r11l_x86_64,  // R11B
+    lldb_r12l_x86_64,  // R12B
+    lldb_r13l_x86_64,  // R13B
+    lldb_r14l_x86_64,  // R14B
+    lldb_r15l_x86_64,  // R15B
+    lldb_r8w_x86_64,   // R8W
+    lldb_r9w_x86_64,   // R9W
+    lldb_r10w_x86_64,  // R10W
+    lldb_r11w_x86_64,  // R11W
+    lldb_r12w_x86_64,  // R12W
+    lldb_r13w_x86_64,  // R13W
+    lldb_r14w_x86_64,  // R14W
+    lldb_r15w_x86_64,  // R15W
+    lldb_r8d_x86_64,   // R8D
+    lldb_r9d_x86_64,   // R9D
+    lldb_r10d_x86_64,  // R10D
+    lldb_r11d_x86_64,  // R11D
+    lldb_r12d_x86_64,  // R12D
+    lldb_r13d_x86_64,  // R13D
+    lldb_r14d_x86_64,  // R14D
+    lldb_r15d_x86_64,  // R15D
+    lldb_ymm0_x86_64,  // AMD64_YMM0
+    lldb_ymm1_x86_64,  // AMD64_YMM1
+    lldb_ymm2_x86_64,  // AMD64_YMM2
+    lldb_ymm3_x86_64,  // AMD64_YMM3
+    lldb_ymm4_x86_64,  // AMD64_YMM4
+    lldb_ymm5_x86_64,  // AMD64_YMM5
+    lldb_ymm6_x86_64,  // AMD64_YMM6
+    lldb_ymm7_x86_64,  // AMD64_YMM7
+    lldb_ymm8_x86_64,  // AMD64_YMM8
+    lldb_ymm9_x86_64,  // AMD64_YMM9
+    lldb_ymm10_x86_64, // AMD64_YMM10
+    lldb_ymm11_x86_64, // AMD64_YMM11
+    lldb_ymm12_x86_64, // AMD64_YMM12
+    lldb_ymm13_x86_64, // AMD64_YMM13
+    lldb_ymm14_x86_64, // AMD64_YMM14
+    lldb_ymm15_x86_64, // AMD64_YMM15
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM,
+    lldb_bnd0_x86_64, // BND0
+    lldb_bnd1_x86_64, // BND1
+    lldb_bnd2_x86_64  // BND2
+};
+
+uint32_t GetLLDBRegisterNumber(llvm::Triple::ArchType arch_type,
+                               llvm::codeview::RegisterId register_id) {
+  switch (arch_type) {
+  case llvm::Triple::x86:
+    if (static_cast<uint16_t>(register_id) <
+        sizeof(g_code_view_to_lldb_registers_x86) /
+            sizeof(g_code_view_to_lldb_registers_x86[0]))
+      return g_code_view_to_lldb_registers_x86[static_cast<uint16_t>(
+          register_id)];
+
+    switch (register_id) {
+    case llvm::codeview::RegisterId::MXCSR:
+      return lldb_mxcsr_i386;
+    case llvm::codeview::RegisterId::BND0:
+      return lldb_bnd0_i386;
+    case llvm::codeview::RegisterId::BND1:
+      return lldb_bnd1_i386;
+    case llvm::codeview::RegisterId::BND2:
+      return lldb_bnd2_i386;
+    default:
+      return LLDB_INVALID_REGNUM;
+    }
+  case llvm::Triple::x86_64:
+    if (static_cast<uint16_t>(register_id) <
+        sizeof(g_code_view_to_lldb_registers_x86_64) /
+            sizeof(g_code_view_to_lldb_registers_x86_64[0]))
+      return g_code_view_to_lldb_registers_x86_64[static_cast<uint16_t>(
+          register_id)];
+
+    return LLDB_INVALID_REGNUM;
+  default:
+    return LLDB_INVALID_REGNUM;
+  }
+}
+
+uint32_t GetGenericRegisterNumber(llvm::codeview::RegisterId register_id) {
+  if (register_id == llvm::codeview::RegisterId::VFRAME)
+    return LLDB_REGNUM_GENERIC_FP;
+
+  return LLDB_INVALID_REGNUM;
+}
+
+static uint32_t GetRegisterNumber(llvm::Triple::ArchType arch_type,
+                                  llvm::codeview::RegisterId register_id,
+                                  RegisterKind &register_kind) {
+  register_kind = eRegisterKindLLDB;
+  uint32_t reg_num = GetLLDBRegisterNumber(arch_type, register_id);
+  if (reg_num != LLDB_INVALID_REGNUM)
+    return reg_num;
+
+  register_kind = eRegisterKindGeneric;
+  return GetGenericRegisterNumber(register_id);
+}
+
 static bool IsSimpleTypeSignedInteger(SimpleTypeKind kind) {
   switch (kind) {
   case SimpleTypeKind::Int128:
@@ -107,6 +570,46 @@ static DWARFExpression MakeLocationExpre
   return result;
 }
 
+static DWARFExpression MakeRegisterBasedLocationExpressionInternal(
+    llvm::codeview::RegisterId reg, llvm::Optional<int32_t> relative_offset,
+    lldb::ModuleSP module) {
+  return MakeLocationExpressionInternal(
+      module, [&](Stream &stream, RegisterKind &register_kind) -> bool {
+        uint32_t reg_num = GetRegisterNumber(
+            module->GetArchitecture().GetMachine(), reg, register_kind);
+        if (reg_num == LLDB_INVALID_REGNUM)
+          return false;
+
+        if (reg_num > 31) {
+          llvm::dwarf::LocationAtom base = relative_offset
+                                               ? llvm::dwarf::DW_OP_bregx
+                                               : llvm::dwarf::DW_OP_regx;
+          stream.PutHex8(base);
+          stream.PutULEB128(reg_num);
+        } else {
+          llvm::dwarf::LocationAtom base = relative_offset
+                                               ? llvm::dwarf::DW_OP_breg0
+                                               : llvm::dwarf::DW_OP_reg0;
+          stream.PutHex8(base + reg_num);
+        }
+
+        if (relative_offset)
+          stream.PutSLEB128(*relative_offset);
+
+        return true;
+      });
+}
+
+DWARFExpression lldb_private::npdb::MakeEnregisteredLocationExpression(
+    llvm::codeview::RegisterId reg, lldb::ModuleSP module) {
+  return MakeRegisterBasedLocationExpressionInternal(reg, llvm::None, module);
+}
+
+DWARFExpression lldb_private::npdb::MakeRegRelLocationExpression(
+    llvm::codeview::RegisterId reg, int32_t offset, lldb::ModuleSP module) {
+  return MakeRegisterBasedLocationExpressionInternal(reg, offset, module);
+}
+
 DWARFExpression lldb_private::npdb::MakeGlobalLocationExpression(
     uint16_t section, uint32_t offset, ModuleSP module) {
   assert(section > 0);

Modified: lldb/trunk/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.h?rev=349067&r1=349066&r2=349067&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.h Thu Dec 13 10:17:51 2018
@@ -11,6 +11,7 @@
 #define LLDB_PLUGINS_SYMBOLFILE_NATIVEPDB_DWARFLOCATIONEXPRESSION_H
 
 #include "lldb/lldb-forward.h"
+#include "llvm/DebugInfo/CodeView/CodeView.h"
 
 namespace llvm {
 class APSInt;
@@ -23,6 +24,13 @@ class TpiStream;
 } // namespace llvm
 namespace lldb_private {
 namespace npdb {
+DWARFExpression
+MakeEnregisteredLocationExpression(llvm::codeview::RegisterId reg,
+                                   lldb::ModuleSP module);
+
+DWARFExpression MakeRegRelLocationExpression(llvm::codeview::RegisterId reg,
+                                             int32_t offset,
+                                             lldb::ModuleSP module);
 DWARFExpression MakeGlobalLocationExpression(uint16_t section, uint32_t offset,
                                              lldb::ModuleSP module);
 DWARFExpression MakeConstantLocationExpression(

Modified: lldb/trunk/source/Plugins/SymbolFile/NativePDB/PdbSymUid.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/NativePDB/PdbSymUid.h?rev=349067&r1=349066&r2=349067&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/NativePDB/PdbSymUid.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/NativePDB/PdbSymUid.h Thu Dec 13 10:17:51 2018
@@ -93,6 +93,7 @@ class PdbSymUid {
   uint64_t m_repr = 0;
 
 public:
+  PdbSymUid() = default;
   PdbSymUid(uint64_t repr) : m_repr(repr) {}
   PdbSymUid(const PdbCompilandId &cid);
   PdbSymUid(const PdbCompilandSymId &csid);

Modified: lldb/trunk/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp?rev=349067&r1=349066&r2=349067&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp Thu Dec 13 10:17:51 2018
@@ -66,6 +66,15 @@ using namespace npdb;
 using namespace llvm::codeview;
 using namespace llvm::pdb;
 
+namespace {
+struct VariableInfo {
+  llvm::StringRef name;
+  TypeIndex type;
+  llvm::Optional<DWARFExpression> location;
+  llvm::Optional<Variable::RangeList> ranges;
+};
+} // namespace
+
 static lldb::LanguageType TranslateLanguage(PDB_Lang lang) {
   switch (lang) {
   case PDB_Lang::Cpp:
@@ -314,6 +323,94 @@ TranslateCallingConvention(llvm::codevie
   }
 }
 
+static Variable::RangeList
+MakeRangeList(const PdbIndex &index, const LocalVariableAddrRange &range,
+              llvm::ArrayRef<LocalVariableAddrGap> gaps) {
+  lldb::addr_t start =
+      index.MakeVirtualAddress(range.ISectStart, range.OffsetStart);
+  lldb::addr_t end = start + range.Range;
+
+  Variable::RangeList result;
+  while (!gaps.empty()) {
+    const LocalVariableAddrGap &gap = gaps.front();
+
+    lldb::addr_t size = gap.GapStartOffset - start;
+    result.Append(start, size);
+    start += gap.Range;
+    gaps = gaps.drop_front();
+  }
+
+  result.Append(start, end);
+  return result;
+}
+
+static VariableInfo GetVariableInformation(PdbIndex &index,
+                                           PdbCompilandSymId var_id,
+                                           ModuleSP module,
+                                           bool get_location_info) {
+  VariableInfo result;
+  CVSymbol sym = index.ReadSymbolRecord(var_id);
+
+  if (sym.kind() == S_REGREL32) {
+    RegRelativeSym reg(SymbolRecordKind::RegRelativeSym);
+    cantFail(SymbolDeserializer::deserializeAs<RegRelativeSym>(sym, reg));
+    result.type = reg.Type;
+    result.name = reg.Name;
+    if (get_location_info) {
+      result.location =
+          MakeRegRelLocationExpression(reg.Register, reg.Offset, module);
+      result.ranges.emplace();
+    }
+    return result;
+  }
+
+  if (sym.kind() == S_REGISTER) {
+    RegisterSym reg(SymbolRecordKind::RegisterSym);
+    cantFail(SymbolDeserializer::deserializeAs<RegisterSym>(sym, reg));
+    result.type = reg.Index;
+    result.name = reg.Name;
+    if (get_location_info) {
+      result.location =
+          MakeEnregisteredLocationExpression(reg.Register, module);
+      result.ranges.emplace();
+    }
+    return result;
+  }
+
+  if (sym.kind() == S_LOCAL) {
+    LocalSym local(SymbolRecordKind::LocalSym);
+    cantFail(SymbolDeserializer::deserializeAs<LocalSym>(sym, local));
+    result.type = local.Type;
+    result.name = local.Name;
+
+    if (!get_location_info)
+      return result;
+
+    PdbCompilandSymId loc_specifier_id(var_id.modi,
+                                       var_id.offset + sym.RecordData.size());
+    CVSymbol loc_specifier_cvs = index.ReadSymbolRecord(loc_specifier_id);
+    if (loc_specifier_cvs.kind() == S_DEFRANGE_FRAMEPOINTER_REL) {
+      DefRangeFramePointerRelSym loc(
+          SymbolRecordKind::DefRangeFramePointerRelSym);
+      cantFail(SymbolDeserializer::deserializeAs<DefRangeFramePointerRelSym>(
+          loc_specifier_cvs, loc));
+      // FIXME: The register needs to come from the S_FRAMEPROC symbol.
+      result.location =
+          MakeRegRelLocationExpression(RegisterId::RSP, loc.Offset, module);
+      result.ranges = MakeRangeList(index, loc.Range, loc.Gaps);
+    } else {
+      // FIXME: Handle other kinds
+      llvm::APSInt value;
+      value = 42;
+      result.location = MakeConstantLocationExpression(
+          TypeIndex::Int32(), index.tpi(), value, module);
+    }
+    return result;
+  }
+  llvm_unreachable("Symbol is not a local variable!");
+  return result;
+}
+
 void SymbolFileNativePDB::Initialize() {
   PluginManager::RegisterPlugin(GetPluginNameStatic(),
                                 GetPluginDescriptionStatic(), CreateInstance,
@@ -520,8 +617,45 @@ uint32_t SymbolFileNativePDB::GetNumComp
   return count;
 }
 
+Block &SymbolFileNativePDB::CreateBlock(PdbCompilandSymId block_id) {
+  CompilandIndexItem *cii = m_index->compilands().GetCompiland(block_id.modi);
+  CVSymbol sym = cii->m_debug_stream.readSymbolAtOffset(block_id.offset);
+  clang::DeclContext *parent_decl_ctx = m_clang->GetTranslationUnitDecl();
+
+  if (sym.kind() == S_GPROC32 || sym.kind() == S_LPROC32) {
+    // This is a function.  It must be global.  Creating the Function entry for
+    // it automatically creates a block for it.
+    CompUnitSP comp_unit = GetOrCreateCompileUnit(*cii);
+    return GetOrCreateFunction(block_id, *comp_unit)->GetBlock(false);
+  }
+
+  lldbassert(sym.kind() == S_BLOCK32);
+
+  // This is a block.  Its parent is either a function or another block.  In
+  // either case, its parent can be viewed as a block (e.g. a function contains
+  // 1 big block.  So just get the parent block and add this block to it.
+  BlockSym block(static_cast<SymbolRecordKind>(sym.kind()));
+  cantFail(SymbolDeserializer::deserializeAs<BlockSym>(sym, block));
+  lldbassert(block.Parent != 0);
+  PdbCompilandSymId parent_id(block_id.modi, block.Parent);
+  Block &parent_block = GetOrCreateBlock(parent_id);
+
+  lldb::user_id_t opaque_block_uid = toOpaqueUid(block_id);
+  BlockSP child_block = std::make_shared<Block>(opaque_block_uid);
+  parent_block.AddChild(child_block);
+  CompilerDeclContext cdc = GetDeclContextForUID(parent_block.GetID());
+  parent_decl_ctx =
+      static_cast<clang::DeclContext *>(cdc.GetOpaqueDeclContext());
+  clang::BlockDecl *block_decl =
+      m_clang->CreateBlockDeclaration(parent_decl_ctx);
+
+  m_blocks.insert({opaque_block_uid, child_block});
+  m_uid_to_decl.insert({opaque_block_uid, block_decl});
+  return *child_block;
+}
+
 lldb::FunctionSP SymbolFileNativePDB::CreateFunction(PdbCompilandSymId func_id,
-                                                     const SymbolContext &sc) {
+                                                     CompileUnit &comp_unit) {
   const CompilandIndexItem *cci =
       m_index->compilands().GetCompiland(func_id.modi);
   lldbassert(cci);
@@ -535,7 +669,7 @@ lldb::FunctionSP SymbolFileNativePDB::Cr
     return nullptr;
 
   AddressRange func_range(file_vm_addr, sol.length,
-                          sc.module_sp->GetSectionList());
+                          comp_unit.GetModule()->GetSectionList());
   if (!func_range.GetBaseAddress().IsValid())
     return nullptr;
 
@@ -546,27 +680,22 @@ lldb::FunctionSP SymbolFileNativePDB::Cr
   PdbTypeSymId sig_id(proc.FunctionType, false);
   Mangled mangled(proc.Name);
   FunctionSP func_sp = std::make_shared<Function>(
-      sc.comp_unit, toOpaqueUid(func_id), toOpaqueUid(sig_id), mangled,
+      &comp_unit, toOpaqueUid(func_id), toOpaqueUid(sig_id), mangled,
       func_type.get(), func_range);
 
-  sc.comp_unit->AddFunction(func_sp);
+  comp_unit.AddFunction(func_sp);
+
+  user_id_t opaque_func_uid = toOpaqueUid(func_id);
 
   clang::StorageClass storage = clang::SC_None;
   if (sym_record.kind() == S_LPROC32)
     storage = clang::SC_Static;
 
-  // There are two ways we could retrieve the parameter list.  The first is by
-  // iterating the arguments on the function signature type, however that would
-  // only tell us the types of the arguments and not the names.  The second is
-  // to iterate the CVSymbol records that follow the S_GPROC32 / S_LPROC32 until
-  // we have the correct number of arguments as stated by the function
-  // signature. The latter has more potential to go wrong in the face of
-  // improper debug info simply because we're assuming more about the layout of
-  // the records, but it is the only way to get argument names.
+  // The function signature only tells us the number of types of arguments, but
+  // not the names.  So we need to iterate the symbol stream looking for the
+  // corresponding symbol records to properly construct the AST.
   CVType sig_cvt;
-  CVType arg_list_cvt;
   ProcedureRecord sig_record;
-  ArgListRecord arg_list_record;
 
   sig_cvt = m_index->tpi().getType(proc.FunctionType);
   if (sig_cvt.kind() != LF_PROCEDURE)
@@ -574,8 +703,7 @@ lldb::FunctionSP SymbolFileNativePDB::Cr
   cantFail(
       TypeDeserializer::deserializeAs<ProcedureRecord>(sig_cvt, sig_record));
 
-  CompilerDeclContext context =
-      GetDeclContextContainingUID(toOpaqueUid(func_id));
+  CompilerDeclContext context = GetDeclContextContainingUID(opaque_func_uid);
 
   clang::DeclContext *decl_context =
       static_cast<clang::DeclContext *>(context.GetOpaqueDeclContext());
@@ -583,8 +711,9 @@ lldb::FunctionSP SymbolFileNativePDB::Cr
       decl_context, proc.Name.str().c_str(),
       func_type->GetForwardCompilerType(), storage, false);
 
-  lldbassert(m_uid_to_decl.count(toOpaqueUid(func_id)) == 0);
-  m_uid_to_decl[toOpaqueUid(func_id)] = function_decl;
+  lldbassert(m_uid_to_decl.count(opaque_func_uid) == 0);
+  m_uid_to_decl[opaque_func_uid] = function_decl;
+
   CVSymbolArray scope = limitSymbolArrayToScope(
       cci->m_debug_stream.getSymbolArray(), func_id.offset);
 
@@ -593,57 +722,34 @@ lldb::FunctionSP SymbolFileNativePDB::Cr
   auto end = scope.end();
   std::vector<clang::ParmVarDecl *> params;
   while (begin != end && params_remaining > 0) {
-    uint32_t record_offset = begin.offset();
-    CVSymbol sym = *begin++;
-
-    TypeIndex param_type;
-    llvm::StringRef param_name;
+    CVSymbol sym = *begin;
     switch (sym.kind()) {
-    case S_REGREL32: {
-      RegRelativeSym reg(SymbolRecordKind::RegRelativeSym);
-      cantFail(SymbolDeserializer::deserializeAs<RegRelativeSym>(sym, reg));
-      param_type = reg.Type;
-      param_name = reg.Name;
+    case S_REGREL32:
+    case S_REGISTER:
+    case S_LOCAL:
       break;
-    }
-    case S_REGISTER: {
-      RegisterSym reg(SymbolRecordKind::RegisterSym);
-      cantFail(SymbolDeserializer::deserializeAs<RegisterSym>(sym, reg));
-      param_type = reg.Index;
-      param_name = reg.Name;
-      break;
-    }
-    case S_LOCAL: {
-      LocalSym local(SymbolRecordKind::LocalSym);
-      cantFail(SymbolDeserializer::deserializeAs<LocalSym>(sym, local));
-      if ((local.Flags & LocalSymFlags::IsParameter) == LocalSymFlags::None)
-        continue;
-      param_type = local.Type;
-      param_name = local.Name;
-      break;
-    }
     case S_BLOCK32:
-      // All parameters should come before the first block.  If that isn't the
-      // case, then perhaps this is bad debug info that doesn't contain
-      // information about all parameters.
       params_remaining = 0;
       continue;
     default:
+      ++begin;
       continue;
     }
+    PdbCompilandSymId param_uid(func_id.modi, begin.offset());
+    VariableInfo var_info = GetVariableInformation(
+        *m_index, param_uid, GetObjectFile()->GetModule(), false);
 
-    PdbCompilandSymId param_uid(func_id.modi, record_offset);
-    TypeSP type_sp = GetOrCreateType(param_type);
+    TypeSP type_sp = GetOrCreateType(var_info.type);
     clang::ParmVarDecl *param = m_clang->CreateParameterDeclaration(
-        function_decl, param_name.str().c_str(),
+        function_decl, var_info.name.str().c_str(),
         type_sp->GetForwardCompilerType(), clang::SC_None);
     lldbassert(m_uid_to_decl.count(toOpaqueUid(param_uid)) == 0);
 
     m_uid_to_decl[toOpaqueUid(param_uid)] = param;
     params.push_back(param);
     --params_remaining;
+    ++begin;
   }
-
   if (!params.empty())
     m_clang->SetFunctionParameters(function_decl, params.data(), params.size());
 
@@ -1243,10 +1349,10 @@ lldb::TypeSP SymbolFileNativePDB::GetOrC
 }
 
 FunctionSP SymbolFileNativePDB::GetOrCreateFunction(PdbCompilandSymId func_id,
-                                                    const SymbolContext &sc) {
+                                                    CompileUnit &comp_unit) {
   auto emplace_result = m_functions.try_emplace(toOpaqueUid(func_id), nullptr);
   if (emplace_result.second)
-    emplace_result.first->second = CreateFunction(func_id, sc);
+    emplace_result.first->second = CreateFunction(func_id, comp_unit);
 
   lldbassert(emplace_result.first->second);
   return emplace_result.first->second;
@@ -1264,6 +1370,14 @@ SymbolFileNativePDB::GetOrCreateCompileU
   return emplace_result.first->second;
 }
 
+Block &SymbolFileNativePDB::GetOrCreateBlock(PdbCompilandSymId block_id) {
+  auto iter = m_blocks.find(toOpaqueUid(block_id));
+  if (iter != m_blocks.end())
+    return *iter->second;
+
+  return CreateBlock(block_id);
+}
+
 lldb::CompUnitSP SymbolFileNativePDB::ParseCompileUnitAtIndex(uint32_t index) {
   if (index >= GetNumCompileUnits())
     return CompUnitSP();
@@ -1326,19 +1440,35 @@ uint32_t SymbolFileNativePDB::ResolveSym
     resolved_flags |= eSymbolContextCompUnit;
   }
 
-  if (resolve_scope & eSymbolContextFunction) {
+  if (resolve_scope & eSymbolContextFunction ||
+      resolve_scope & eSymbolContextBlock) {
     lldbassert(sc.comp_unit);
     std::vector<SymbolAndUid> matches = m_index->FindSymbolsByVa(file_addr);
-    for (const auto &match : matches) {
+    // Search the matches in reverse.  This way if there are multiple matches
+    // (for example we are 3 levels deep in a nested scope) it will find the
+    // innermost one first.
+    for (const auto &match : llvm::reverse(matches)) {
       if (match.uid.kind() != PdbSymUidKind::CompilandSym)
         continue;
+
       PdbCompilandSymId csid = match.uid.asCompilandSym();
       CVSymbol cvs = m_index->ReadSymbolRecord(csid);
-      if (CVSymToPDBSym(cvs.kind()) != PDB_SymType::Function)
+      PDB_SymType type = CVSymToPDBSym(cvs.kind());
+      if (type != PDB_SymType::Function && type != PDB_SymType::Block)
         continue;
-      sc.function = GetOrCreateFunction(csid, sc).get();
-    }
+      if (type == PDB_SymType::Function) {
+        sc.function = GetOrCreateFunction(csid, *sc.comp_unit).get();
+        sc.block = sc.GetFunctionBlock();
+      }
+
+      if (type == PDB_SymType::Block) {
+        sc.block = &GetOrCreateBlock(csid);
+        sc.function = sc.block->CalculateSymbolContextFunction();
+      }
     resolved_flags |= eSymbolContextFunction;
+    resolved_flags |= eSymbolContextBlock;
+    break;
+    }
   }
 
   if (resolve_scope & eSymbolContextLineEntry) {
@@ -1496,7 +1626,9 @@ bool SymbolFileNativePDB::ParseImportedM
 
 size_t SymbolFileNativePDB::ParseFunctionBlocks(const SymbolContext &sc) {
   lldbassert(sc.comp_unit && sc.function);
-  return 0;
+  GetOrCreateBlock(PdbSymUid(sc.function->GetID()).asCompilandSym());
+  // FIXME: Parse child blocks
+  return 1;
 }
 
 void SymbolFileNativePDB::DumpClangAST(Stream &s) {
@@ -1558,9 +1690,8 @@ uint32_t SymbolFileNativePDB::FindFuncti
     SymbolContext sc;
 
     sc.comp_unit = GetOrCreateCompileUnit(cci).get();
-    sc.module_sp = sc.comp_unit->GetModule();
     PdbCompilandSymId func_id(proc.modi(), proc.SymOffset);
-    sc.function = GetOrCreateFunction(func_id, sc).get();
+    sc.function = GetOrCreateFunction(func_id, *sc.comp_unit).get();
 
     sc_list.Append(sc);
   }
@@ -1621,6 +1752,188 @@ size_t SymbolFileNativePDB::FindTypesByN
 
 size_t SymbolFileNativePDB::ParseTypes(const SymbolContext &sc) { return 0; }
 
+size_t
+SymbolFileNativePDB::ParseVariablesForCompileUnit(CompileUnit &comp_unit,
+                                                  VariableList &variables) {
+  PdbSymUid sym_uid(comp_unit.GetID());
+  lldbassert(sym_uid.kind() == PdbSymUidKind::Compiland);
+  return 0;
+}
+
+VariableSP SymbolFileNativePDB::CreateLocalVariable(PdbCompilandSymId scope_id,
+                                                    PdbCompilandSymId var_id,
+                                                    bool is_param) {
+  ModuleSP module = GetObjectFile()->GetModule();
+  VariableInfo var_info =
+      GetVariableInformation(*m_index, var_id, module, true);
+
+  CompilandIndexItem *cii = m_index->compilands().GetCompiland(var_id.modi);
+  CompUnitSP comp_unit_sp = GetOrCreateCompileUnit(*cii);
+  TypeSP type_sp = GetOrCreateType(var_info.type);
+  std::string name = var_info.name.str();
+  Declaration decl;
+  SymbolFileTypeSP sftype =
+      std::make_shared<SymbolFileType>(*this, type_sp->GetID());
+
+  ValueType var_scope =
+      is_param ? eValueTypeVariableArgument : eValueTypeVariableLocal;
+  VariableSP var_sp = std::make_shared<Variable>(
+      toOpaqueUid(var_id), name.c_str(), name.c_str(), sftype, var_scope,
+      comp_unit_sp.get(), *var_info.ranges, &decl, *var_info.location, false,
+      false, false);
+
+  CompilerDeclContext cdc = GetDeclContextForUID(toOpaqueUid(scope_id));
+  clang::DeclContext *decl_ctx =
+      static_cast<clang::DeclContext *>(cdc.GetOpaqueDeclContext());
+
+  // Parameter info should have already been added to the AST.
+  if (!is_param) {
+    clang::QualType qt =
+        ClangUtil::GetCanonicalQualType(type_sp->GetForwardCompilerType());
+
+    clang::VarDecl *var_decl =
+        m_clang->CreateVariableDeclaration(decl_ctx, name.c_str(), qt);
+    lldbassert(m_uid_to_decl.count(toOpaqueUid(var_id)) == 0);
+    m_uid_to_decl[toOpaqueUid(var_id)] = var_decl;
+  }
+
+  m_local_variables[toOpaqueUid(var_id)] = var_sp;
+  return var_sp;
+}
+
+VariableSP SymbolFileNativePDB::GetOrCreateLocalVariable(
+    PdbCompilandSymId scope_id, PdbCompilandSymId var_id, bool is_param) {
+  auto iter = m_local_variables.find(toOpaqueUid(var_id));
+  if (iter != m_local_variables.end())
+    return iter->second;
+
+  return CreateLocalVariable(scope_id, var_id, is_param);
+}
+
+size_t SymbolFileNativePDB::ParseVariablesForBlock(PdbCompilandSymId block_id) {
+  Block &block = GetOrCreateBlock(block_id);
+
+  size_t count = 0;
+
+  CompilandIndexItem *cii = m_index->compilands().GetCompiland(block_id.modi);
+  CVSymbol sym = cii->m_debug_stream.readSymbolAtOffset(block_id.offset);
+  uint32_t params_remaining = 0;
+  switch (sym.kind()) {
+  case S_GPROC32:
+  case S_LPROC32: {
+    ProcSym proc(static_cast<SymbolRecordKind>(sym.kind()));
+    cantFail(SymbolDeserializer::deserializeAs<ProcSym>(sym, proc));
+    CVType signature = m_index->tpi().getType(proc.FunctionType);
+    ProcedureRecord sig;
+    cantFail(TypeDeserializer::deserializeAs<ProcedureRecord>(signature, sig));
+    params_remaining = sig.getParameterCount();
+    break;
+  }
+  case S_BLOCK32:
+    break;
+  default:
+    lldbassert(false && "Symbol is not a block!");
+    return 0;
+  }
+
+  VariableListSP variables = block.GetBlockVariableList(false);
+  if (!variables) {
+    variables = std::make_shared<VariableList>();
+    block.SetVariableList(variables);
+  }
+
+  CVSymbolArray syms = limitSymbolArrayToScope(
+      cii->m_debug_stream.getSymbolArray(), block_id.offset);
+
+  // Skip the first record since it's a PROC32 or BLOCK32, and there's
+  // no point examining it since we know it's not a local variable.
+  syms.drop_front();
+  auto iter = syms.begin();
+  auto end = syms.end();
+
+  while (iter != end) {
+    uint32_t record_offset = iter.offset();
+    CVSymbol variable_cvs = *iter;
+    PdbCompilandSymId child_sym_id(block_id.modi, record_offset);
+    ++iter;
+
+    // If this is a block, recurse into its children and then skip it.
+    if (variable_cvs.kind() == S_BLOCK32) {
+      uint32_t block_end = getScopeEndOffset(variable_cvs);
+      count += ParseVariablesForBlock(child_sym_id);
+      iter = syms.at(block_end);
+      continue;
+    }
+
+    bool is_param = params_remaining > 0;
+    VariableSP variable;
+    switch (variable_cvs.kind()) {
+    case S_REGREL32:
+    case S_REGISTER:
+    case S_LOCAL:
+      variable = GetOrCreateLocalVariable(block_id, child_sym_id, is_param);
+      if (is_param)
+        --params_remaining;
+      variables->AddVariableIfUnique(variable);
+      break;
+    default:
+      break;
+    }
+  }
+
+  // Pass false for set_children, since we call this recursively so that the
+  // children will call this for themselves.
+  block.SetDidParseVariables(true, false);
+
+  return count;
+}
+
+size_t SymbolFileNativePDB::ParseVariablesForContext(const SymbolContext &sc) {
+  lldbassert(sc.function || sc.comp_unit);
+
+  VariableListSP variables;
+  PdbSymUid sym_uid;
+  if (sc.block) {
+    PdbSymUid block_id(sc.block->GetID());
+
+    size_t count = ParseVariablesForBlock(block_id.asCompilandSym());
+    return count;
+  }
+
+  if (sc.function) {
+    PdbSymUid block_id(sc.function->GetID());
+
+    size_t count = ParseVariablesForBlock(block_id.asCompilandSym());
+    return count;
+  }
+
+  if (sc.comp_unit) {
+    variables = sc.comp_unit->GetVariableList(false);
+    if (!variables) {
+      variables = std::make_shared<VariableList>();
+      sc.comp_unit->SetVariableList(variables);
+    }
+    return ParseVariablesForCompileUnit(*sc.comp_unit, *variables);
+  }
+
+  llvm_unreachable("Unreachable!");
+}
+
+CompilerDecl SymbolFileNativePDB::GetDeclForUID(lldb::user_id_t uid) {
+  auto iter = m_uid_to_decl.find(uid);
+  if (iter == m_uid_to_decl.end())
+    return CompilerDecl();
+
+  return {m_clang, iter->second};
+}
+
+CompilerDeclContext
+SymbolFileNativePDB::GetDeclContextForUID(lldb::user_id_t uid) {
+  CompilerDecl compiler_decl = GetDeclForUID(uid);
+  clang::Decl *decl = static_cast<clang::Decl *>(compiler_decl.GetOpaqueDecl());
+  return {m_clang, clang::Decl::castToDeclContext(decl)};
+}
+
 CompilerDeclContext
 SymbolFileNativePDB::GetDeclContextContainingUID(lldb::user_id_t uid) {
   // FIXME: This should look up the uid, decide if it's a symbol or a type, and

Modified: lldb/trunk/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h?rev=349067&r1=349066&r2=349067&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h Thu Dec 13 10:17:51 2018
@@ -109,10 +109,10 @@ public:
                                VariableList &variables) override;
 
   size_t ParseTypes(const SymbolContext &sc) override;
-  size_t ParseVariablesForContext(const SymbolContext &sc) override {
-    return 0;
-  }
+  size_t ParseVariablesForContext(const SymbolContext &sc) override;
 
+  CompilerDecl GetDeclForUID(lldb::user_id_t uid) override;
+  CompilerDeclContext GetDeclContextForUID(lldb::user_id_t uid) override;
   CompilerDeclContext GetDeclContextContainingUID(lldb::user_id_t uid) override;
   Type *ResolveTypeUID(lldb::user_id_t type_uid) override;
   llvm::Optional<ArrayInfo> GetDynamicArrayInfoForUID(
@@ -194,20 +194,30 @@ private:
                          clang::MSInheritanceAttr::Spelling inheritance);
 
   lldb::FunctionSP GetOrCreateFunction(PdbCompilandSymId func_id,
-                                       const SymbolContext &sc);
+                                       CompileUnit &comp_unit);
   lldb::CompUnitSP GetOrCreateCompileUnit(const CompilandIndexItem &cci);
   lldb::TypeSP GetOrCreateType(PdbTypeSymId type_id);
   lldb::TypeSP GetOrCreateType(llvm::codeview::TypeIndex ti);
   lldb::VariableSP GetOrCreateGlobalVariable(PdbGlobalSymId var_id);
+  Block &GetOrCreateBlock(PdbCompilandSymId block_id);
+  lldb::VariableSP GetOrCreateLocalVariable(PdbCompilandSymId scope_id,
+                                            PdbCompilandSymId var_id,
+                                            bool is_param);
 
   lldb::FunctionSP CreateFunction(PdbCompilandSymId func_id,
-                                  const SymbolContext &sc);
+                                  CompileUnit &comp_unit);
+  Block &CreateBlock(PdbCompilandSymId block_id);
+  lldb::VariableSP CreateLocalVariable(PdbCompilandSymId scope_id,
+                                       PdbCompilandSymId var_id, bool is_param);
   lldb::CompUnitSP CreateCompileUnit(const CompilandIndexItem &cci);
   lldb::TypeSP CreateType(PdbTypeSymId type_id);
   lldb::TypeSP CreateAndCacheType(PdbTypeSymId type_id);
   lldb::VariableSP CreateGlobalVariable(PdbGlobalSymId var_id);
   lldb::VariableSP CreateConstantSymbol(PdbGlobalSymId var_id,
                                         const llvm::codeview::CVSymbol &cvs);
+  size_t ParseVariablesForCompileUnit(CompileUnit &comp_unit,
+                                      VariableList &variables);
+  size_t ParseVariablesForBlock(PdbCompilandSymId block_id);
 
   llvm::BumpPtrAllocator m_allocator;
 
@@ -224,6 +234,8 @@ private:
       m_parent_types;
 
   llvm::DenseMap<lldb::user_id_t, lldb::VariableSP> m_global_vars;
+  llvm::DenseMap<lldb::user_id_t, lldb::VariableSP> m_local_variables;
+  llvm::DenseMap<lldb::user_id_t, lldb::BlockSP> m_blocks;
   llvm::DenseMap<lldb::user_id_t, lldb::FunctionSP> m_functions;
   llvm::DenseMap<lldb::user_id_t, lldb::CompUnitSP> m_compilands;
   llvm::DenseMap<lldb::user_id_t, lldb::TypeSP> m_types;

Modified: lldb/trunk/source/Symbol/ClangASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ClangASTContext.cpp?rev=349067&r1=349066&r2=349067&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/ClangASTContext.cpp (original)
+++ lldb/trunk/source/Symbol/ClangASTContext.cpp Thu Dec 13 10:17:51 2018
@@ -2218,10 +2218,13 @@ ParmVarDecl *ClangASTContext::CreatePara
     const CompilerType &param_type, int storage) {
   ASTContext *ast = getASTContext();
   assert(ast != nullptr);
-  return ParmVarDecl::Create(*ast, decl_ctx, SourceLocation(), SourceLocation(),
-                             name && name[0] ? &ast->Idents.get(name) : nullptr,
-                             ClangUtil::GetQualType(param_type), nullptr,
-                             (clang::StorageClass)storage, nullptr);
+  auto *decl =
+      ParmVarDecl::Create(*ast, decl_ctx, SourceLocation(), SourceLocation(),
+                          name && name[0] ? &ast->Idents.get(name) : nullptr,
+                          ClangUtil::GetQualType(param_type), nullptr,
+                          (clang::StorageClass)storage, nullptr);
+  decl_ctx->addDecl(decl);
+  return decl;
 }
 
 void ClangASTContext::SetFunctionParameters(FunctionDecl *function_decl,




More information about the lldb-commits mailing list