[Lldb-commits] [lldb] r374201 - Re-land "[test] Split LLDB tests into API, Shell & Unit"

Jonas Devlieghere via lldb-commits lldb-commits at lists.llvm.org
Wed Oct 9 12:22:04 PDT 2019


Added: lldb/trunk/test/Shell/SymbolFile/PDB/typedefs.test
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/Shell/SymbolFile/PDB/typedefs.test?rev=374201&view=auto
==============================================================================
--- lldb/trunk/test/Shell/SymbolFile/PDB/typedefs.test (added)
+++ lldb/trunk/test/Shell/SymbolFile/PDB/typedefs.test Wed Oct  9 12:22:02 2019
@@ -0,0 +1,59 @@
+REQUIRES: system-windows, msvc
+RUN: %build --compiler=msvc --arch=32 --nodefaultlib --output=%T/SimpleTypesTest.cpp.typedefs.exe %S/Inputs/SimpleTypesTest.cpp
+RUN: lldb-test symbols %T/SimpleTypesTest.cpp.typedefs.exe | FileCheck %s
+
+; Generate 32-bit target
+
+; FIXME: PDB does not have line information for typedef statements so source
+; and line information for them is not tested.
+
+; Note, types `long double` and `double` have same bit size in MSVC and there
+; is no information in the PDB to distinguish them. So the compiler type for
+; both of them is the same.
+
+CHECK: Module [[MOD:.*]]
+CHECK: SymbolFile pdb ([[MOD]])
+CHECK-DAG: name = "char32_t", size = 4, compiler_type = {{.*}} char32_t
+CHECK-DAG: name = "char16_t", size = 2, compiler_type = {{.*}} char16_t
+CHECK-DAG: Type{{.*}} , name = "unsigned long", size = 4, compiler_type = {{.*}} unsigned long
+CHECK-DAG: Type{{.*}} , size = 40, compiler_type = {{.*}} unsigned long [10]
+CHECK-DAG: Type{{.*}} , name = "ULongArrayTypedef", compiler_type = {{.*}} typedef ULongArrayTypedef
+
+; Note: compiler_type of `long double` is represented by the one for `double`
+CHECK-DAG: Type{{.*}} , name = "double", size = 8, compiler_type = {{.*}} double
+CHECK-DAG: Type{{.*}} , size = 4, compiler_type = {{.*}} double *
+CHECK-DAG: Type{{.*}} , size = 4, compiler_type = {{.*}} double *&
+CHECK-DAG: Type{{.*}} , name = "RefTypedef", compiler_type = {{.*}} typedef RefTypedef
+
+CHECK-DAG: Type{{.*}} , name = "wchar_t", size = 2, compiler_type = {{.*}} wchar_t
+
+CHECK-DAG: Type{{.*}} , name = "int", size = 4, compiler_type = {{.*}} int
+CHECK-DAG: Type{{.*}} , size = 4, compiler_type = {{.*}} int &
+CHECK-DAG: Type{{.*}} , name = "unsigned char", size = 1, compiler_type = {{.*}} unsigned char
+CHECK-DAG: Type{{.*}} , size = 4, compiler_type = {{.*}} unsigned char *
+CHECK-DAG: Type{{.*}} , size = 4, compiler_type = {{.*}} unsigned char **
+CHECK-DAG: Type{{.*}} , name = "short", size = 2, compiler_type = {{.*}} short
+CHECK-DAG: Type{{.*}} , size = 4, compiler_type = {{.*}} short *
+CHECK-DAG: Type{{.*}} , name = "const double", size = 8, compiler_type = {{.*}} const double
+CHECK-DAG: Type{{.*}} , name = "volatile bool", size = 1, compiler_type = {{.*}} volatile _Bool
+CHECK-DAG: Type{{.*}} , name = "long long", size = 8, compiler_type = {{.*}} long long
+CHECK-DAG: Type{{.*}} , compiler_type = {{.*}} long long (int &, unsigned char **, short *, const double, volatile _Bool)
+CHECK-DAG: Type{{.*}} , name = "FuncPtrTypedef", compiler_type = {{.*}} typedef FuncPtrTypedef
+
+CHECK-DAG: Type{{.*}} , name = "void", compiler_type = {{.*}} void
+CHECK-DAG: Type{{.*}} , size = 4, compiler_type = {{.*}} void *
+CHECK-DAG: Type{{.*}} , name = "long", size = 4, compiler_type = {{.*}} long
+CHECK-DAG: Type{{.*}} , name = "unsigned short", size = 2, compiler_type = {{.*}} unsigned short
+CHECK-DAG: Type{{.*}} , name = "unsigned int", size = 4, compiler_type = {{.*}} unsigned int
+CHECK-DAG: Type{{.*}} , name = "char", size = 1, compiler_type = {{.*}} char
+CHECK-DAG: Type{{.*}} , name = "signed char", size = 1, compiler_type = {{.*}} signed char
+CHECK-DAG: Type{{.*}} , compiler_type = {{.*}} char (void *, long, unsigned short, unsigned int, ...)
+CHECK-DAG: Type{{.*}} , size = 4, compiler_type = {{.*}} char (*)(void *, long, unsigned short, unsigned int, ...)
+CHECK-DAG: Type{{.*}} , name = "VarArgsFuncTypedef", compiler_type = {{.*}} typedef VarArgsFuncTypedef
+
+CHECK-DAG: Type{{.*}} , name = "float", size = 4, compiler_type = {{.*}} float
+CHECK-DAG: Type{{.*}} , compiler_type = {{.*}} float (...)
+CHECK-DAG: Type{{.*}} , size = 4, compiler_type = {{.*}} float (*)(...)
+CHECK-DAG: Type{{.*}} , name = "VarArgsFuncTypedefA", compiler_type = {{.*}} typedef VarArgsFuncTypedefA
+
+CHECK-DAG: {{^[0-9A-F]+}}:   CompileUnit{{[{]0x[0-9a-f]+[}]}}, language = "c++", file = '{{.*}}\SimpleTypesTest.cpp'

Added: lldb/trunk/test/Shell/SymbolFile/PDB/udt-layout.test
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/Shell/SymbolFile/PDB/udt-layout.test?rev=374201&view=auto
==============================================================================
--- lldb/trunk/test/Shell/SymbolFile/PDB/udt-layout.test (added)
+++ lldb/trunk/test/Shell/SymbolFile/PDB/udt-layout.test Wed Oct  9 12:22:02 2019
@@ -0,0 +1,51 @@
+REQUIRES: system-windows, lld
+RUN: %build --compiler=clang-cl --output=%t.exe %S/Inputs/UdtLayoutTest.cpp
+RUN: %lldb -b -s %S/Inputs/UdtLayoutTest.script -- %t.exe | FileCheck %s
+
+CHECK:(int) int C::abc = 123
+CHECK:(List [16]) ls = {
+CHECK:  [15] = {
+CHECK:    Prev = 0x00000000
+CHECK:    Next = 0x00000000
+CHECK:    Value = {
+CHECK:      B<0> = {
+CHECK:        A = {
+CHECK:          _u = (_u1 = '\x02', _u2 = 2, _u3 = 2)
+CHECK:        }
+CHECK:        _a = '\x01'
+CHECK:        _b = 2
+CHECK:        _c = 3
+CHECK:      }
+CHECK:      B<1> = {
+CHECK:        A = {
+CHECK:          _u = (_u1 = '\x02', _u2 = 2, _u3 = 2)
+CHECK:        }
+CHECK:        _a = '\x02'
+CHECK:        _b = 4
+CHECK:        _c = 6
+CHECK:      }
+CHECK:      B<2> = {
+CHECK:        A = {
+CHECK:          _u = (_u1 = '\x02', _u2 = 2, _u3 = 2)
+CHECK:        }
+CHECK:        _a = '\x03'
+CHECK:        _b = 6
+CHECK:        _c = 9
+CHECK:      }
+CHECK:      B<3> = {
+CHECK:        A = {
+CHECK:          _u = (_u1 = '\x02', _u2 = 2, _u3 = 2)
+CHECK:        }
+CHECK:        _a = '\x04'
+CHECK:        _b = 8
+CHECK:        _c = 12
+CHECK:      }
+CHECK:      A = {
+CHECK:        _u = (_u1 = '\x02', _u2 = 2, _u3 = 2)
+CHECK:      }
+CHECK:      _x = 5
+CHECK:      _y = 10
+CHECK:      _z = '\x0f'
+CHECK:    }
+CHECK:  }
+CHECK:}

Added: lldb/trunk/test/Shell/SymbolFile/PDB/variables-locations.test
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/Shell/SymbolFile/PDB/variables-locations.test?rev=374201&view=auto
==============================================================================
--- lldb/trunk/test/Shell/SymbolFile/PDB/variables-locations.test (added)
+++ lldb/trunk/test/Shell/SymbolFile/PDB/variables-locations.test Wed Oct  9 12:22:02 2019
@@ -0,0 +1,20 @@
+REQUIRES: system-windows, lld
+RUN: %build --compiler=clang-cl --output=%t.exe %S/Inputs/VariablesLocationsTest.cpp
+RUN: env LLDB_USE_NATIVE_PDB_READER=0 %lldb -b -s %S/Inputs/VariablesLocationsTest.script -- %t.exe | FileCheck %s
+RUN: env LLDB_USE_NATIVE_PDB_READER=1 %lldb -b -s %S/Inputs/VariablesLocationsTest.script -- %t.exe | FileCheck %s
+
+CHECK: g_var = 2222
+
+CHECK: arg_0 = 1111
+CHECK: arg_1 = 0.123
+
+CHECK: loc_0 = 'x'
+CHECK: loc_1 = 0.567
+
+CHECK: loc_0 = true
+CHECK: loc_1 = 3333
+
+CHECK: arg_0 = 22
+
+CHECK: loc_0 = (a = 1234)
+CHECK: loc_1 = 5678

Added: lldb/trunk/test/Shell/SymbolFile/PDB/variables.test
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/Shell/SymbolFile/PDB/variables.test?rev=374201&view=auto
==============================================================================
--- lldb/trunk/test/Shell/SymbolFile/PDB/variables.test (added)
+++ lldb/trunk/test/Shell/SymbolFile/PDB/variables.test Wed Oct  9 12:22:02 2019
@@ -0,0 +1,66 @@
+REQUIRES: system-windows, msvc
+RUN: %build --compiler=clang-cl --mode=compile --arch=64 --nodefaultlib --output=%T/VariablesTest.cpp.obj %S/Inputs/VariablesTest.cpp
+RUN: %build --compiler=msvc --mode=link --arch=64 --nodefaultlib --output=%T/VariablesTest.cpp.exe %T/VariablesTest.cpp.obj
+RUN: lldb-test symbols %T/VariablesTest.cpp.exe > %T/VariablesTest.out
+RUN: FileCheck --check-prefix=GLOBALS --input-file=%T/VariablesTest.out %s
+RUN: FileCheck --check-prefix=FUNC-F --input-file=%T/VariablesTest.out %s
+RUN: FileCheck --check-prefix=FUNC-MAIN --input-file=%T/VariablesTest.out %s
+RUN: FileCheck --check-prefix=FUNC-CONSTRUCTOR --input-file=%T/VariablesTest.out %s
+RUN: FileCheck --check-prefix=FUNC-MEMBER --input-file=%T/VariablesTest.out %s
+
+GLOBALS: Module [[MOD:.*]]
+GLOBALS: SymbolFile pdb ([[MOD]])
+GLOBALS:     CompileUnit{{.*}}, language = "c++", file = '{{.*}}\VariablesTest.cpp'
+GLOBALS-DAG:   Variable{{.*}}, name = "g_IntVar"
+GLOBALS-SAME:  scope = global, location = {{.*}}, external
+GLOBALS-DAG:   Variable{{.*}}, name = "m_StaticClassMember"
+GLOBALS-SAME:  scope = global, location = {{.*}}, external
+GLOBALS-DAG:   Variable{{.*}}, name = "g_pConst"
+GLOBALS-SAME:  scope = global, location = {{.*}}, external
+GLOBALS-DAG:   Variable{{.*}}, name = "same_name_var"
+GLOBALS-SAME:  scope = global, location = {{.*}}, external
+GLOBALS-DAG:   Variable{{.*}}, name = "g_EnumVar"
+GLOBALS-SAME:  scope = global, location = {{.*}}, external
+GLOBALS-DAG:   Variable{{.*}}, name = "g_tls"
+GLOBALS-SAME:  scope = thread local, location = {{.*}}, external
+GLOBALS-DAG:   Variable{{.*}}, name = "ClassVar"
+GLOBALS-SAME:  scope = global, location = {{.*}}, external
+GLOBALS-DAG:   Variable{{.*}}, name = "g_Const"
+GLOBALS-SAME:  scope = ??? (2)
+GLOBALS:     Function
+
+FUNC-F:      Function{{.*}}, mangled = ?f@@YAHHH at Z
+FUNC-F-NEXT:   Block
+FUNC-F-NEXT:     Variable{{.*}}, name = "var_arg1"
+FUNC-F-SAME:                     scope = parameter
+FUNC-F-NEXT:     Variable{{.*}}, name = "var_arg2"
+FUNC-F-SAME:                     scope = parameter
+FUNC-F-NEXT:     Variable{{.*}}, name = "same_name_var"
+FUNC-F-SAME:                     scope = local
+
+FUNC-MAIN:      Function{{.*}}, mangled = main
+FUNC-MAIN-NEXT:   Block
+FUNC-MAIN-NEXT:     Variable{{.*}}, name = "same_name_var"
+FUNC-MAIN-SAME:                     scope = local
+FUNC-MAIN-NEXT:     Variable{{.*}}, name = "local_const"
+FUNC-MAIN-SAME:                     scope = local
+FUNC-MAIN-NEXT:     Variable{{.*}}, name = "local_CString"
+FUNC-MAIN-SAME:                     scope = local
+FUNC-MAIN-NEXT:     Variable{{.*}}, name = "local_pCString"
+FUNC-MAIN-SAME:                     scope = local
+FUNC-MAIN-NEXT:     Variable{{.*}}, name = "a"
+FUNC-MAIN-SAME:                     scope = local
+
+FUNC-CONSTRUCTOR:      Function{{.*}}, mangled = ??0Class@@QEAA at H@Z
+FUNC-CONSTRUCTOR-NEXT:   Block
+FUNC-CONSTRUCTOR-NEXT:     Variable{{.*}}, name = "this"
+FUNC-CONSTRUCTOR-SAME:                     scope = parameter
+FUNC-CONSTRUCTOR-SAME:                     artificial
+FUNC-CONSTRUCTOR-NEXT:     Variable{{.*}}, name = "a"
+FUNC-CONSTRUCTOR-SAME:                     scope = parameter
+
+FUNC-MEMBER:      Function{{.*}}, mangled = ?Func at Class@@QEAAXXZ
+FUNC-MEMBER-NEXT:   Block
+FUNC-MEMBER-NEXT:     Variable{{.*}}, name = "this"
+FUNC-MEMBER-SAME:                     scope = parameter
+FUNC-MEMBER-SAME:                     artificial

Added: lldb/trunk/test/Shell/SymbolFile/PDB/vbases.test
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/Shell/SymbolFile/PDB/vbases.test?rev=374201&view=auto
==============================================================================
--- lldb/trunk/test/Shell/SymbolFile/PDB/vbases.test (added)
+++ lldb/trunk/test/Shell/SymbolFile/PDB/vbases.test Wed Oct  9 12:22:02 2019
@@ -0,0 +1,15 @@
+REQUIRES: system-windows, lld
+RUN: %build --compiler=clang-cl --output=%t.exe %S/Inputs/VBases.cpp
+RUN: %lldb -b -s %S/Inputs/VBases.script -- %t.exe | FileCheck %s
+
+CHECK: {
+CHECK:   A = (a = '\x01')
+CHECK:   B = (b = 2)
+CHECK:   c = 3
+CHECK: }
+
+CHECK: {
+CHECK:   A = (a = '\x01')
+CHECK:   B = (b = 2)
+CHECK:   c = 3
+CHECK: }

Added: lldb/trunk/test/Shell/SymbolFile/dissassemble-entry-point.s
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/Shell/SymbolFile/dissassemble-entry-point.s?rev=374201&view=auto
==============================================================================
--- lldb/trunk/test/Shell/SymbolFile/dissassemble-entry-point.s (added)
+++ lldb/trunk/test/Shell/SymbolFile/dissassemble-entry-point.s Wed Oct  9 12:22:02 2019
@@ -0,0 +1,13 @@
+# REQUIRES: lld, arm
+
+# RUN: llvm-mc -triple=thumbv7-eabi %s -filetype=obj -o %t.o
+# RUN: ld.lld %t.o -o %t --section-start=.text=0x8074 -e 0x8075 -s
+# RUN: %lldb -x -b -o 'dis -s 0x8074 -e 0x8080' -- %t | FileCheck %s
+# CHECK:      {{.*}}[0x8074] <+0>: movs   r0, #0x2a
+# CHECK-NEXT: {{.*}}[0x8076] <+2>: movs   r7, #0x1
+# CHECK-NEXT: {{.*}}[0x8078] <+4>: svc    #0x0
+
+_start:
+    movs r0, #0x2a
+    movs r7, #0x1
+    svc #0x0
\ No newline at end of file

Added: lldb/trunk/test/Shell/SymbolFile/sizeless-symbol.test
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/Shell/SymbolFile/sizeless-symbol.test?rev=374201&view=auto
==============================================================================
--- lldb/trunk/test/Shell/SymbolFile/sizeless-symbol.test (added)
+++ lldb/trunk/test/Shell/SymbolFile/sizeless-symbol.test Wed Oct  9 12:22:02 2019
@@ -0,0 +1,14 @@
+# Some targets do not have the .size directive.
+# RUN: %clang -target x86_64-unknown-unknown-elf %S/Inputs/sizeless-symbol.s -c -o %t.o
+# RUN: %lldb %t.o -s %s -o quit | FileCheck %s
+
+image lookup --address 1
+# CHECK: Summary: sizeless-symbol.test.tmp.o`sizeful
+image lookup --address 2
+# CHECK: Summary: sizeless-symbol.test.tmp.o`sizeful + 1
+image dump symtab
+# CHECK:     Index   UserID DSX Type            File Address/Value Load Address       Size               Flags      Name
+# CHECK-NEXT:------- ------ --- --------------- ------------------ ------------------ ------------------ ---------- ----------------------------------
+# CHECK-NEXT:[    0]      1     Code            0x0000000000000003                    0x0000000000000000 0x00000000 sizeend
+# CHECK-NEXT:[    1]      2     Code            0x0000000000000001                    0x0000000000000002 0x00000000 sizeful
+# CHECK-NEXT:[    2]      3     Code            0x0000000000000001                    0x0000000000000000 0x00000000 sizeless

Added: lldb/trunk/test/Shell/SymbolFile/target-symbols-add-unwind.test
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/Shell/SymbolFile/target-symbols-add-unwind.test?rev=374201&view=auto
==============================================================================
--- lldb/trunk/test/Shell/SymbolFile/target-symbols-add-unwind.test (added)
+++ lldb/trunk/test/Shell/SymbolFile/target-symbols-add-unwind.test Wed Oct  9 12:22:02 2019
@@ -0,0 +1,26 @@
+# TODO: When it's possible to run "image show-unwind" without a running
+# process, we can remove the unsupported line below, and hard-code an ELF
+# triple in the test.
+# UNSUPPORTED: system-windows, system-darwin
+
+# RUN: cd %T
+# RUN: %clang %S/Inputs/target-symbols-add-unwind.c -g \
+# RUN:   -fno-unwind-tables -o target-symbols-add-unwind.debug
+# RUN: llvm-objcopy --strip-debug target-symbols-add-unwind.debug \
+# RUN:   target-symbols-add-unwind.stripped
+# RUN: %lldb target-symbols-add-unwind.stripped -s %s -o quit | FileCheck %s
+
+process launch --stop-at-entry
+image show-unwind -n main
+# CHECK-LABEL: image show-unwind -n main
+# CHECK-NOT: debug_frame UnwindPlan:
+
+target symbols add -s target-symbols-add-unwind.stripped target-symbols-add-unwind.debug
+# CHECK-LABEL: target symbols add
+# CHECK: symbol file {{.*}} has been added to {{.*}}
+
+image show-unwind -n main
+# CHECK-LABEL: image show-unwind -n main
+# CHECK: debug_frame UnwindPlan:
+# CHECK-NEXT: This UnwindPlan originally sourced from DWARF CFI
+# CHECK-NEXT: This UnwindPlan is sourced from the compiler: yes.

Added: lldb/trunk/test/Shell/Unwind/Inputs/call-asm.c
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/Shell/Unwind/Inputs/call-asm.c?rev=374201&view=auto
==============================================================================
--- lldb/trunk/test/Shell/Unwind/Inputs/call-asm.c (added)
+++ lldb/trunk/test/Shell/Unwind/Inputs/call-asm.c Wed Oct  9 12:22:02 2019
@@ -0,0 +1,3 @@
+int asm_main() asm("asm_main");
+
+int main() { return asm_main(); }

Added: lldb/trunk/test/Shell/Unwind/Inputs/eh-frame-dwarf-unwind.s
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/Shell/Unwind/Inputs/eh-frame-dwarf-unwind.s?rev=374201&view=auto
==============================================================================
--- lldb/trunk/test/Shell/Unwind/Inputs/eh-frame-dwarf-unwind.s (added)
+++ lldb/trunk/test/Shell/Unwind/Inputs/eh-frame-dwarf-unwind.s Wed Oct  9 12:22:02 2019
@@ -0,0 +1,39 @@
+        .text
+        .globl  bar
+bar:
+        .cfi_startproc
+        leal    (%edi, %edi), %eax
+        ret
+        .cfi_endproc
+
+        .globl  foo
+foo:
+        .cfi_startproc
+        .cfi_escape 0x16, 0x10, 0x06, 0x38, 0x1c, 0x06, 0x08, 0x47, 0x1c
+        call    bar
+        addl    $1, %eax
+        popq    %rdi
+        subq    $0x47, %rdi
+        jmp     *%rdi # Return
+        .cfi_endproc
+
+        .globl  asm_main
+asm_main:
+        .cfi_startproc
+        pushq   %rbp
+        .cfi_def_cfa_offset 16
+        .cfi_offset 6, -16
+        movq    %rsp, %rbp
+        .cfi_def_cfa_register 6
+        movl    $47, %edi
+
+        # Non-standard calling convention. The real return address must be
+        # decremented by 0x47.
+        leaq    0x47+1f(%rip), %rax
+        pushq   %rax
+        jmp     foo # call
+1:
+        popq    %rbp
+        .cfi_def_cfa 7, 8
+        ret
+        .cfi_endproc

Added: lldb/trunk/test/Shell/Unwind/Inputs/eh-frame-small-fde.s
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/Shell/Unwind/Inputs/eh-frame-small-fde.s?rev=374201&view=auto
==============================================================================
--- lldb/trunk/test/Shell/Unwind/Inputs/eh-frame-small-fde.s (added)
+++ lldb/trunk/test/Shell/Unwind/Inputs/eh-frame-small-fde.s Wed Oct  9 12:22:02 2019
@@ -0,0 +1,48 @@
+        .text
+        .globl  bar
+        .type   bar, @function
+bar:
+.LFB0:
+        .cfi_startproc
+        leal    (%edi, %edi), %eax
+        ret
+        .cfi_endproc
+.LFE0:
+        .size   bar, .-bar
+        .globl  foo
+        .type   foo, @function
+foo:
+.LFB1:
+        nop # Make the FDE entry start one byte later than the actual function.
+        .cfi_startproc
+        .cfi_register %rip, %r13
+        call    bar
+        addl    $1, %eax
+        jmp     *%r13 # Return
+        .cfi_endproc
+.LFE1:
+        .size   foo, .-foo
+        .globl  main
+        .type   main, @function
+main:
+.LFB2:
+        .cfi_startproc
+        pushq   %rbp
+        .cfi_def_cfa_offset 16
+        .cfi_offset 6, -16
+        movq    %rsp, %rbp
+        .cfi_def_cfa_register 6
+        movl    $47, %edi
+
+        # Non-standard calling convention. Put return address in r13.
+        pushq   %r13
+        leaq    1f(%rip), %r13
+        jmp     foo # call
+1:
+        popq    %r13
+        popq    %rbp
+        .cfi_def_cfa 7, 8
+        ret
+        .cfi_endproc
+.LFE2:
+        .size   main, .-main

Added: lldb/trunk/test/Shell/Unwind/Inputs/prefer-debug-over-eh-frame.s
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/Shell/Unwind/Inputs/prefer-debug-over-eh-frame.s?rev=374201&view=auto
==============================================================================
--- lldb/trunk/test/Shell/Unwind/Inputs/prefer-debug-over-eh-frame.s (added)
+++ lldb/trunk/test/Shell/Unwind/Inputs/prefer-debug-over-eh-frame.s Wed Oct  9 12:22:02 2019
@@ -0,0 +1,38 @@
+        .cfi_sections .eh_frame, .debug_frame
+        .text
+        .globl  bar
+bar:
+        .cfi_startproc
+        leal    (%edi, %edi), %eax
+        ret
+        .cfi_endproc
+
+        .globl  foo
+foo:
+        .cfi_startproc
+        pushq   %rbp
+        .cfi_def_cfa_offset 16
+        .cfi_offset %rbp, -16
+        movq    %rsp, %rbp
+        .cfi_def_cfa_register %rbp
+        call    bar
+        addl    $1, %eax
+        popq    %rbp
+        ret
+        .cfi_endproc
+
+        .globl  asm_main
+asm_main:
+        .cfi_startproc
+        pushq   %rbp
+        .cfi_def_cfa_offset 16
+        .cfi_offset 6, -16
+        movq    %rsp, %rbp
+        .cfi_def_cfa_register 6
+        movl    $47, %edi
+
+        call foo
+        popq    %rbp
+        .cfi_def_cfa 7, 8
+        ret
+        .cfi_endproc

Added: lldb/trunk/test/Shell/Unwind/Inputs/trap_frame_sym_ctx.s
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/Shell/Unwind/Inputs/trap_frame_sym_ctx.s?rev=374201&view=auto
==============================================================================
--- lldb/trunk/test/Shell/Unwind/Inputs/trap_frame_sym_ctx.s (added)
+++ lldb/trunk/test/Shell/Unwind/Inputs/trap_frame_sym_ctx.s Wed Oct  9 12:22:02 2019
@@ -0,0 +1,42 @@
+        .text
+        .globl  bar
+bar:
+        .cfi_startproc
+        leal    (%edi, %edi), %eax
+        ret
+        .cfi_endproc
+
+        .globl  asm_main
+asm_main:
+        .cfi_startproc
+        pushq   %rbp
+        .cfi_def_cfa_offset 16
+        .cfi_offset %rbp, -16
+        movq    %rsp, %rbp
+        .cfi_def_cfa_register %rbp
+        movl    $47, %edi
+
+        # install tramp as return address
+        # (similar to signal return trampolines on some platforms)
+        leaq    tramp(%rip), %rax
+        pushq   %rax
+        jmp     bar # call, with return address pointing to tramp
+
+        popq    %rbp
+        .cfi_def_cfa %rsp, 8
+        ret
+        .cfi_endproc
+
+        .globl  tramp
+tramp:
+        .cfi_startproc
+        .cfi_signal_frame
+        # Emit cfi to line up with the frame created by asm_main
+        .cfi_def_cfa_offset 16
+        .cfi_offset %rbp, -16
+        .cfi_def_cfa_register %rbp
+        # copy asm_main's epilog to clean up the frame
+        popq    %rbp
+        .cfi_def_cfa %rsp, 8
+        ret
+        .cfi_endproc

Added: lldb/trunk/test/Shell/Unwind/Inputs/unwind-plan-dwarf-dump.s
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/Shell/Unwind/Inputs/unwind-plan-dwarf-dump.s?rev=374201&view=auto
==============================================================================
--- lldb/trunk/test/Shell/Unwind/Inputs/unwind-plan-dwarf-dump.s (added)
+++ lldb/trunk/test/Shell/Unwind/Inputs/unwind-plan-dwarf-dump.s Wed Oct  9 12:22:02 2019
@@ -0,0 +1,13 @@
+        .text
+        .globl  main
+        .type   main, @function
+main:
+.LFB0:
+        .cfi_startproc
+        .cfi_escape 0x0f, 0x05, 0x77, 0x00, 0x08, 0x00, 0x22
+        .cfi_escape 0x16, 0x10, 0x04, 0x09, 0xf8, 0x22, 0x06
+        movl    $47, %eax
+        ret
+        .cfi_endproc
+.LFE0:
+        .size   main, .-main

Added: lldb/trunk/test/Shell/Unwind/eh-frame-dwarf-unwind.test
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/Shell/Unwind/eh-frame-dwarf-unwind.test?rev=374201&view=auto
==============================================================================
--- lldb/trunk/test/Shell/Unwind/eh-frame-dwarf-unwind.test (added)
+++ lldb/trunk/test/Shell/Unwind/eh-frame-dwarf-unwind.test Wed Oct  9 12:22:02 2019
@@ -0,0 +1,23 @@
+# Test handing of dwarf expressions specifying the location of registers, if
+# those expressions refer to the frame's CFA value.
+
+# UNSUPPORTED: system-windows
+# REQUIRES: target-x86_64, native
+
+# RUN: %clang %p/Inputs/call-asm.c %p/Inputs/eh-frame-dwarf-unwind.s -o %t
+# RUN: %lldb %t -s %s -o exit | FileCheck %s
+
+breakpoint set -n bar
+# CHECK: Breakpoint 1: where = {{.*}}`bar
+
+process launch
+# CHECK: stop reason = breakpoint 1.1
+
+thread backtrace
+# CHECK: frame #0: {{.*}}`bar
+# CHECK: frame #1: {{.*}}`foo + 5
+# CHECK: frame #2: {{.*}}`asm_main + 22
+
+target modules show-unwind -n foo
+# CHECK: eh_frame UnwindPlan:
+# CHECK: row[0]: 0: CFA=rsp +8 => rip=DW_OP_lit8 , DW_OP_minus , DW_OP_deref , DW_OP_const1u 0x47, DW_OP_minus

Added: lldb/trunk/test/Shell/Unwind/eh-frame-small-fde.test
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/Shell/Unwind/eh-frame-small-fde.test?rev=374201&view=auto
==============================================================================
--- lldb/trunk/test/Shell/Unwind/eh-frame-small-fde.test (added)
+++ lldb/trunk/test/Shell/Unwind/eh-frame-small-fde.test Wed Oct  9 12:22:02 2019
@@ -0,0 +1,22 @@
+# This test that we are able to unwind using eh_frame in case an FDE entry does
+# not cover the entire range of a function we are unwinding through.
+
+# REQUIRES: target-x86_64, system-linux, native
+
+# RUN: %clang %p/Inputs/eh-frame-small-fde.s -o %t
+# RUN: %lldb %t -s %s -o exit | FileCheck %s
+
+breakpoint set -n bar
+# CHECK: Breakpoint 1: where = {{.*}}`bar
+
+process launch
+# CHECK: stop reason = breakpoint 1.1
+
+thread backtrace
+# CHECK: frame #0: {{.*}}`bar
+# CHECK: frame #1: {{.*}}`foo + 6
+# CHECK: frame #2: {{.*}}`main + 20
+
+target modules show-unwind -n foo
+# CHECK: eh_frame UnwindPlan:
+# CHECK: row[0]: 0: CFA=rsp +8 => rip=r13

Added: lldb/trunk/test/Shell/Unwind/prefer-debug-over-eh-frame.test
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/Shell/Unwind/prefer-debug-over-eh-frame.test?rev=374201&view=auto
==============================================================================
--- lldb/trunk/test/Shell/Unwind/prefer-debug-over-eh-frame.test (added)
+++ lldb/trunk/test/Shell/Unwind/prefer-debug-over-eh-frame.test Wed Oct  9 12:22:02 2019
@@ -0,0 +1,24 @@
+# Test that we prefer debug_frame over eh_frame unwind plans. They usually
+# contain the same information, and we rarely have both kinds of entries for a
+# single function. However, in theory the debug_frame plan can be more complete,
+# whereas eh_frame is only required to be correct at places where exceptions can
+# be thrown.
+
+# UNSUPPORTED: system-windows
+# XFAIL: system-darwin
+# REQUIRES: target-x86_64, native
+
+# RUN: %clang -g %p/Inputs/call-asm.c %p/Inputs/prefer-debug-over-eh-frame.s -o %t
+# RUN: %lldb %t -s %s -o exit | FileCheck %s
+
+breakpoint set -n bar
+# CHECK: Breakpoint 1: where = {{.*}}`bar
+
+process launch
+# CHECK: stop reason = breakpoint 1.1
+
+target modules show-unwind -n foo
+# CHECK: Asynchronous (not restricted to call-sites) UnwindPlan is 'DWARF CFI plus augmentation from assembly parsing'
+# CHECK: Synchronous (restricted to call-sites) UnwindPlan is 'DWARF CFI'
+# CHECK: eh_frame UnwindPlan:
+# CHECK: debug_frame UnwindPlan:

Added: lldb/trunk/test/Shell/Unwind/trap_frame_sym_ctx.test
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/Shell/Unwind/trap_frame_sym_ctx.test?rev=374201&view=auto
==============================================================================
--- lldb/trunk/test/Shell/Unwind/trap_frame_sym_ctx.test (added)
+++ lldb/trunk/test/Shell/Unwind/trap_frame_sym_ctx.test Wed Oct  9 12:22:02 2019
@@ -0,0 +1,21 @@
+# Test that symbol contexts for trap handler frames are set correctly even when
+# the pc is at the start of the function.
+
+# UNSUPPORTED: system-windows
+# REQUIRES: target-x86_64, native
+
+# RUN: %clang %p/Inputs/call-asm.c %p/Inputs/trap_frame_sym_ctx.s -o %t
+# RUN: %lldb %t -s %s -o exit | FileCheck %s
+
+settings append target.trap-handler-names tramp
+
+breakpoint set -n bar
+# CHECK: Breakpoint 1: where = {{.*}}`bar
+
+process launch
+# CHECK: stop reason = breakpoint 1.1
+
+thread backtrace
+# CHECK: frame #0: {{.*}}`bar
+# CHECK: frame #1: {{.*}}`tramp
+# CHECK: frame #2: {{.*}}`main

Added: lldb/trunk/test/Shell/Unwind/unwind-plan-dwarf-dump.test
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/Shell/Unwind/unwind-plan-dwarf-dump.test?rev=374201&view=auto
==============================================================================
--- lldb/trunk/test/Shell/Unwind/unwind-plan-dwarf-dump.test (added)
+++ lldb/trunk/test/Shell/Unwind/unwind-plan-dwarf-dump.test Wed Oct  9 12:22:02 2019
@@ -0,0 +1,14 @@
+# REQUIRES: target-x86_64, system-linux, native
+
+# RUN: %clang %p/Inputs/unwind-plan-dwarf-dump.s -o %t
+# RUN: %lldb %t -s %s -o exit | FileCheck %s
+
+breakpoint set -n main
+# CHECK: Breakpoint 1:
+
+process launch
+# CHECK: stop reason = breakpoint 1.1
+
+target modules show-unwind -n main
+# CHECK: eh_frame UnwindPlan:
+# CHECK: row[0]:    0: CFA=DW_OP_breg7 +0, DW_OP_const1u 0x00, DW_OP_plus  => rip=DW_OP_const1s -8, DW_OP_plus , DW_OP_deref

Added: lldb/trunk/test/Shell/Watchpoint/Inputs/main.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/Shell/Watchpoint/Inputs/main.cpp?rev=374201&view=auto
==============================================================================
--- lldb/trunk/test/Shell/Watchpoint/Inputs/main.cpp (added)
+++ lldb/trunk/test/Shell/Watchpoint/Inputs/main.cpp Wed Oct  9 12:22:02 2019
@@ -0,0 +1,13 @@
+#include <stdio.h>
+
+int main (int argc, char const *argv[])
+{
+    struct {
+        int a;
+        int b;
+        int c;
+    } MyAggregateDataType;
+
+    printf ("Set break point at this line.\n");
+    return 0;
+}

Added: lldb/trunk/test/Shell/Watchpoint/SetErrorCases.test
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/Shell/Watchpoint/SetErrorCases.test?rev=374201&view=auto
==============================================================================
--- lldb/trunk/test/Shell/Watchpoint/SetErrorCases.test (added)
+++ lldb/trunk/test/Shell/Watchpoint/SetErrorCases.test Wed Oct  9 12:22:02 2019
@@ -0,0 +1,28 @@
+# RUN: %clangxx %p/Inputs/main.cpp -g -o %t.out
+# RUN: %lldb -b -o 'settings set interpreter.stop-command-source-on-error false' -s %s %t.out 2>&1 | FileCheck %s
+
+settings show interpreter.stop-command-source-on-error
+# CHECK: interpreter.stop-command-source-on-error (boolean) = false
+
+b main.cpp:11
+run
+# CHECK: stopped
+# CHECK-NEXT: stop reason = breakpoint
+
+watchpoint set
+# CHECK: Commands for setting a watchpoint.
+# CHECK: The following subcommands are supported:
+# CHECK: Set a watchpoint on an address by supplying an expression.
+# CHECK: Set a watchpoint on a variable.
+
+watchpoint set variable -w read_write
+# CHECK: error: required argument missing
+
+watchpoint set expression -w write --
+# CHECK: error: expression evaluation of address to watch failed
+
+watchpoint set expression MyAggregateDataType
+# CHECK: error: expression did not evaluate to an address
+
+watchpoint set variable -s -128
+# CHECK: error: invalid enumeration value

Added: lldb/trunk/test/Shell/helper/__init__.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/Shell/helper/__init__.py?rev=374201&view=auto
==============================================================================
    (empty)

Added: lldb/trunk/test/Shell/helper/build.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/Shell/helper/build.py?rev=374201&view=auto
==============================================================================
--- lldb/trunk/test/Shell/helper/build.py (added)
+++ lldb/trunk/test/Shell/helper/build.py Wed Oct  9 12:22:02 2019
@@ -0,0 +1,799 @@
+#! /usr/bin/env python
+
+from __future__ import print_function
+
+import argparse
+import os
+import signal
+import subprocess
+import sys
+
+if sys.platform == 'win32':
+    # This module was renamed in Python 3.  Make sure to import it using a
+    # consistent name regardless of python version.
+    try:
+        import winreg
+    except:
+        import _winreg as winreg
+
+if __name__ != "__main__":
+    raise RuntimeError("Do not import this script, run it instead")
+
+
+parser = argparse.ArgumentParser(description='LLDB compilation wrapper')
+parser.add_argument('--arch',
+                    metavar='arch',
+                    dest='arch',
+                    required=True,
+                    default='host',
+                    choices=['32', '64', 'host'],
+                    help='Specify the architecture to target.')
+
+parser.add_argument('--compiler',
+                    metavar='compiler',
+                    dest='compiler',
+                    required=True,
+                    help='Path to a compiler executable, or one of the values [any, msvc, clang-cl, gcc, clang]')
+
+parser.add_argument('--libs-dir',
+                    metavar='directory',
+                    dest='libs_dir',
+                    required=False,
+                    action='append',
+                    help='If specified, a path to linked libraries to be passed via -L')
+
+parser.add_argument('--tools-dir',
+                    metavar='directory',
+                    dest='tools_dir',
+                    required=False,
+                    action='append',
+                    help='If specified, a path to search in addition to PATH when --compiler is not an exact path')
+
+if sys.platform == 'darwin':
+    parser.add_argument('--apple-sdk',
+                        metavar='apple_sdk',
+                        dest='apple_sdk',
+                        default="macosx",
+                        help='Specify the name of the Apple SDK (macosx, macosx.internal, iphoneos, iphoneos.internal, or path to SDK) and use the appropriate tools from that SDK\'s toolchain.')
+
+parser.add_argument('--output', '-o',
+                    dest='output',
+                    metavar='file',
+                    required=False,
+                    default='',
+                    help='Path to output file')
+
+parser.add_argument('--outdir', '-d',
+                    dest='outdir',
+                    metavar='directory',
+                    required=False,
+                    help='Directory for output files')
+
+parser.add_argument('--nodefaultlib',
+                    dest='nodefaultlib',
+                    action='store_true',
+                    default=False,
+                    help='When specified, the resulting image should not link against system libraries or include system headers.  Useful when writing cross-targeting tests.')
+
+parser.add_argument('--opt',
+                    dest='opt',
+                    default='none',
+                    choices=['none', 'basic', 'lto'],
+                    help='Optimization level')
+
+parser.add_argument('--mode',
+                    dest='mode',
+                    default='compile-and-link',
+                    choices=['compile', 'link', 'compile-and-link'],
+                    help='Specifies whether to compile, link, or both')
+
+parser.add_argument('--noclean',
+                    dest='clean',
+                    action='store_false',
+                    default=True,
+                    help='Dont clean output file before building')
+
+parser.add_argument('--verbose',
+                    dest='verbose',
+                    action='store_true',
+                    default=False,
+                    help='Print verbose output')
+
+parser.add_argument('-n', '--dry-run',
+                    dest='dry',
+                    action='store_true',
+                    default=False,
+                    help='Print the commands that would run, but dont actually run them')
+
+parser.add_argument('inputs',
+                    metavar='file',
+                    nargs='+',
+                    help='Source file(s) to compile / object file(s) to link')
+
+
+args = parser.parse_args(args=sys.argv[1:])
+
+
+def to_string(b):
+    """Return the parameter as type 'str', possibly encoding it.
+
+    In Python2, the 'str' type is the same as 'bytes'. In Python3, the
+    'str' type is (essentially) Python2's 'unicode' type, and 'bytes' is
+    distinct.
+
+    This function is copied from llvm/utils/lit/lit/util.py
+    """
+    if isinstance(b, str):
+        # In Python2, this branch is taken for types 'str' and 'bytes'.
+        # In Python3, this branch is taken only for 'str'.
+        return b
+    if isinstance(b, bytes):
+        # In Python2, this branch is never taken ('bytes' is handled as 'str').
+        # In Python3, this is true only for 'bytes'.
+        try:
+            return b.decode('utf-8')
+        except UnicodeDecodeError:
+            # If the value is not valid Unicode, return the default
+            # repr-line encoding.
+            return str(b)
+
+    # By this point, here's what we *don't* have:
+    #
+    #  - In Python2:
+    #    - 'str' or 'bytes' (1st branch above)
+    #  - In Python3:
+    #    - 'str' (1st branch above)
+    #    - 'bytes' (2nd branch above)
+    #
+    # The last type we might expect is the Python2 'unicode' type. There is no
+    # 'unicode' type in Python3 (all the Python3 cases were already handled). In
+    # order to get a 'str' object, we need to encode the 'unicode' object.
+    try:
+        return b.encode('utf-8')
+    except AttributeError:
+        raise TypeError('not sure how to convert %s to %s' % (type(b), str))
+
+def format_text(lines, indent_0, indent_n):
+    result = ' ' * indent_0 + lines[0]
+    for next in lines[1:]:
+        result = result + '\n{0}{1}'.format(' ' * indent_n, next)
+    return result
+
+def print_environment(env):
+    if env is None:
+        print('    Inherited')
+        return
+    for e in env:
+        value = env[e]
+        lines = value.split(os.pathsep)
+        formatted_value = format_text(lines, 0, 7 + len(e))
+        print('    {0} = {1}'.format(e, formatted_value))
+
+def find_executable(binary_name, search_paths):
+    if sys.platform == 'win32':
+        binary_name = binary_name + '.exe'
+
+    search_paths = os.pathsep.join(search_paths)
+    paths = search_paths + os.pathsep + os.environ.get('PATH', '')
+    for path in paths.split(os.pathsep):
+        p = os.path.join(path, binary_name)
+        if os.path.exists(p) and not os.path.isdir(p):
+            return os.path.normpath(p)
+    return None
+
+def find_toolchain(compiler, tools_dir):
+    if compiler == 'msvc':
+        return ('msvc', find_executable('cl', tools_dir))
+    if compiler == 'clang-cl':
+        return ('clang-cl', find_executable('clang-cl', tools_dir))
+    if compiler == 'gcc':
+        return ('gcc', find_executable('g++', tools_dir))
+    if compiler == 'clang':
+        return ('clang', find_executable('clang++', tools_dir))
+    if compiler == 'any':
+        priorities = []
+        if sys.platform == 'win32':
+            priorities = ['clang-cl', 'msvc', 'clang', 'gcc']
+        else:
+            priorities = ['clang', 'gcc', 'clang-cl']
+        for toolchain in priorities:
+            (type, dir) = find_toolchain(toolchain, tools_dir)
+            if type and dir:
+                return (type, dir)
+        # Could not find any toolchain.
+        return (None, None)
+
+    # From here on, assume that |compiler| is a path to a file.
+    file = os.path.basename(compiler)
+    name, ext = os.path.splitext(file)
+    if file.lower() == 'cl.exe':
+        return ('msvc', compiler)
+    if name == 'clang-cl':
+        return ('clang-cl', compiler)
+    if name.startswith('clang'):
+        return ('clang', compiler)
+    if name.startswith('gcc') or name.startswith('g++'):
+        return ('gcc', compiler)
+    if name == 'cc' or name == 'c++':
+        return ('generic', compiler)
+    return ('unknown', compiler)
+
+class Builder(object):
+    def __init__(self, toolchain_type, args, obj_ext):
+        self.toolchain_type = toolchain_type
+        self.inputs = args.inputs
+        self.arch = args.arch
+        self.opt = args.opt
+        self.outdir = args.outdir
+        self.compiler = args.compiler
+        self.clean = args.clean
+        self.output = args.output
+        self.mode = args.mode
+        self.nodefaultlib = args.nodefaultlib
+        self.verbose = args.verbose
+        self.obj_ext = obj_ext
+        self.lib_paths = args.libs_dir
+
+    def _exe_file_name(self):
+        assert self.mode != 'compile'
+        return self.output
+
+    def _output_name(self, input, extension, with_executable=False):
+        basename = os.path.splitext(os.path.basename(input))[0] + extension
+        if with_executable:
+            exe_basename = os.path.basename(self._exe_file_name())
+            basename = exe_basename + '-' + basename
+
+        output = os.path.join(self.outdir, basename)
+        return os.path.normpath(output)
+
+    def _obj_file_names(self):
+        if self.mode == 'link':
+            return self.inputs
+
+        if self.mode == 'compile-and-link':
+            # Object file names should factor in both the input file (source)
+            # name and output file (executable) name, to ensure that two tests
+            # which share a common source file don't race to write the same
+            # object file.
+            return [self._output_name(x, self.obj_ext, True) for x in self.inputs]
+
+        if self.mode == 'compile' and self.output:
+            return [self.output]
+
+        return [self._output_name(x, self.obj_ext) for x in self.inputs]
+
+    def build_commands(self):
+        commands = []
+        if self.mode == 'compile' or self.mode == 'compile-and-link':
+            for input, output in zip(self.inputs, self._obj_file_names()):
+                commands.append(self._get_compilation_command(input, output))
+        if self.mode == 'link' or self.mode == 'compile-and-link':
+            commands.append(self._get_link_command())
+        return commands
+
+
+class MsvcBuilder(Builder):
+    def __init__(self, toolchain_type, args):
+        Builder.__init__(self, toolchain_type, args, '.obj')
+
+        self.msvc_arch_str = 'x86' if self.arch == '32' else 'x64'
+
+        if toolchain_type == 'msvc':
+            # Make sure we're using the appropriate toolchain for the desired
+            # target type.
+            compiler_parent_dir = os.path.dirname(self.compiler)
+            selected_target_version = os.path.basename(compiler_parent_dir)
+            if selected_target_version != self.msvc_arch_str:
+                host_dir = os.path.dirname(compiler_parent_dir)
+                self.compiler = os.path.join(host_dir, self.msvc_arch_str, 'cl.exe')
+                if self.verbose:
+                    print('Using alternate compiler "{0}" to match selected target.'.format(self.compiler))
+
+        if self.mode == 'link' or self.mode == 'compile-and-link':
+            self.linker = self._find_linker('link') if toolchain_type == 'msvc' else self._find_linker('lld-link', args.tools_dir)
+            if not self.linker:
+                raise ValueError('Unable to find an appropriate linker.')
+
+        self.compile_env, self.link_env = self._get_visual_studio_environment()
+
+    def _find_linker(self, name, search_paths=[]):
+        compiler_dir = os.path.dirname(self.compiler)
+        linker_path = find_executable(name, [compiler_dir] + search_paths)
+        if linker_path is None:
+            raise ValueError('Could not find \'{}\''.format(name))
+        return linker_path
+
+    def _get_vc_install_dir(self):
+        dir = os.getenv('VCINSTALLDIR', None)
+        if dir:
+            if self.verbose:
+                print('Using %VCINSTALLDIR% {}'.format(dir))
+            return dir
+
+        dir = os.getenv('VSINSTALLDIR', None)
+        if dir:
+            if self.verbose:
+                print('Using %VSINSTALLDIR% {}'.format(dir))
+            return os.path.join(dir, 'VC')
+
+        dir = os.getenv('VS2019INSTALLDIR', None)
+        if dir:
+            if self.verbose:
+                print('Using %VS2019INSTALLDIR% {}'.format(dir))
+            return os.path.join(dir, 'VC')
+
+        dir = os.getenv('VS2017INSTALLDIR', None)
+        if dir:
+            if self.verbose:
+                print('Using %VS2017INSTALLDIR% {}'.format(dir))
+            return os.path.join(dir, 'VC')
+
+        dir = os.getenv('VS2015INSTALLDIR', None)
+        if dir:
+            if self.verbose:
+                print('Using %VS2015INSTALLDIR% {}'.format(dir))
+            return os.path.join(dir, 'VC')
+        return None
+
+    def _get_vctools_version(self):
+        ver = os.getenv('VCToolsVersion', None)
+        if ver:
+            if self.verbose:
+                print('Using %VCToolsVersion% {}'.format(ver))
+            return ver
+
+        vcinstalldir = self._get_vc_install_dir()
+        vcinstalldir = os.path.join(vcinstalldir, 'Tools', 'MSVC')
+        subdirs = next(os.walk(vcinstalldir))[1]
+        if not subdirs:
+            return None
+
+        from distutils.version import StrictVersion
+        subdirs.sort(key=lambda x : StrictVersion(x))
+
+        if self.verbose:
+            full_path = os.path.join(vcinstalldir, subdirs[-1])
+            print('Using VC tools version directory {0} found by directory walk.'.format(full_path))
+        return subdirs[-1]
+
+    def _get_vctools_install_dir(self):
+        dir = os.getenv('VCToolsInstallDir', None)
+        if dir:
+            if self.verbose:
+                print('Using %VCToolsInstallDir% {}'.format(dir))
+            return dir
+
+        vcinstalldir = self._get_vc_install_dir()
+        if not vcinstalldir:
+            return None
+        vctoolsver = self._get_vctools_version()
+        if not vctoolsver:
+            return None
+        result = os.path.join(vcinstalldir, 'Tools', 'MSVC', vctoolsver)
+        if not os.path.exists(result):
+            return None
+        if self.verbose:
+            print('Using VC tools install dir {} found by directory walk'.format(result))
+        return result
+
+    def _find_windows_sdk_in_registry_view(self, view):
+        products_key = None
+        roots_key = None
+        installed_options_keys = []
+        try:
+            sam = view | winreg.KEY_READ
+            products_key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE,
+                                          r'Software\Microsoft\Windows Kits\Installed Products',
+                                          0,
+                                          sam)
+
+            # This is the GUID for the desktop component.  If this is present
+            # then the components required for the Desktop SDK are installed.
+            # If not it will throw an exception.
+            winreg.QueryValueEx(products_key, '{5A3D81EC-D870-9ECF-D997-24BDA6644752}')
+
+            roots_key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE,
+                                       r'Software\Microsoft\Windows Kits\Installed Roots',
+                                       0,
+                                       sam)
+            root_dir = winreg.QueryValueEx(roots_key, 'KitsRoot10')
+            root_dir = to_string(root_dir[0])
+            sdk_versions = []
+            index = 0
+            while True:
+                # Installed SDK versions are stored as sub-keys of the
+                # 'Installed Roots' key.  Find all of their names, then sort
+                # them by version
+                try:
+                    ver_key = winreg.EnumKey(roots_key, index)
+                    sdk_versions.append(ver_key)
+                    index = index + 1
+                except WindowsError:
+                    break
+            if not sdk_versions:
+                return (None, None)
+
+            # Windows SDK version numbers consist of 4 dotted components, so we
+            # have to use LooseVersion, as StrictVersion supports 3 or fewer.
+            from distutils.version import LooseVersion
+            sdk_versions.sort(key=lambda x : LooseVersion(x), reverse=True)
+            option_value_name = 'OptionId.DesktopCPP' + self.msvc_arch_str
+            for v in sdk_versions:
+                try:
+                    version_subkey = v + r'\Installed Options'
+                    key = winreg.OpenKey(roots_key, version_subkey)
+                    installed_options_keys.append(key)
+                    (value, value_type) = winreg.QueryValueEx(key, option_value_name)
+                    if value == 1:
+                        # The proper architecture is installed.  Return the
+                        # associated paths.
+                        if self.verbose:
+                            print('Found Installed Windows SDK v{0} at {1}'.format(v, root_dir))
+                        return (root_dir, v)
+                except:
+                    continue
+        except:
+            return (None, None)
+        finally:
+            del products_key
+            del roots_key
+            for k in installed_options_keys:
+                del k
+        return (None, None)
+
+    def _find_windows_sdk_in_registry(self):
+        # This could be a clang-cl cross-compile.  If so, there's no registry
+        # so just exit.
+        if sys.platform != 'win32':
+            return (None, None)
+        if self.verbose:
+            print('Looking for Windows SDK in 64-bit registry.')
+        dir, ver = self._find_windows_sdk_in_registry_view(winreg.KEY_WOW64_64KEY)
+        if not dir or not ver:
+            if self.verbose:
+                print('Looking for Windows SDK in 32-bit registry.')
+            dir, ver = self._find_windows_sdk_in_registry_view(winreg.KEY_WOW64_32KEY)
+
+        return (dir, ver)
+
+    def _get_winsdk_dir(self):
+        # If a Windows SDK is specified in the environment, use that.  Otherwise
+        # try to find one in the Windows registry.
+        dir = os.getenv('WindowsSdkDir', None)
+        if not dir or not os.path.exists(dir):
+            return self._find_windows_sdk_in_registry()
+        ver = os.getenv('WindowsSDKLibVersion', None)
+        if not ver:
+            return self._find_windows_sdk_in_registry()
+
+        ver = ver.rstrip('\\')
+        if self.verbose:
+            print('Using %WindowsSdkDir% {}'.format(dir))
+            print('Using %WindowsSDKLibVersion% {}'.format(ver))
+        return (dir, ver)
+
+    def _get_msvc_native_toolchain_dir(self):
+        assert self.toolchain_type == 'msvc'
+        compiler_dir = os.path.dirname(self.compiler)
+        target_dir = os.path.dirname(compiler_dir)
+        host_name = os.path.basename(target_dir)
+        host_name = host_name[4:].lower()
+        return os.path.join(target_dir, host_name)
+
+    def _get_visual_studio_environment(self):
+        vctools = self._get_vctools_install_dir()
+        winsdk, winsdkver = self._get_winsdk_dir()
+
+        if not vctools and self.verbose:
+            print('Unable to find VC tools installation directory.')
+        if (not winsdk or not winsdkver) and self.verbose:
+            print('Unable to find Windows SDK directory.')
+
+        vcincludes = []
+        vclibs = []
+        sdkincludes = []
+        sdklibs = []
+        if vctools is not None:
+            includes = [['ATLMFC', 'include'], ['include']]
+            libs = [['ATLMFC', 'lib'], ['lib']]
+            vcincludes = [os.path.join(vctools, *y) for y in includes]
+            vclibs = [os.path.join(vctools, *y) for y in libs]
+        if winsdk is not None:
+            includes = [['include', winsdkver, 'ucrt'],
+                        ['include', winsdkver, 'shared'],
+                        ['include', winsdkver, 'um'],
+                        ['include', winsdkver, 'winrt'],
+                        ['include', winsdkver, 'cppwinrt']]
+            libs = [['lib', winsdkver, 'ucrt'],
+                    ['lib', winsdkver, 'um']]
+            sdkincludes = [os.path.join(winsdk, *y) for y in includes]
+            sdklibs = [os.path.join(winsdk, *y) for y in libs]
+
+        includes = vcincludes + sdkincludes
+        libs = vclibs + sdklibs
+        libs = [os.path.join(x, self.msvc_arch_str) for x in libs]
+        compileenv = None
+        linkenv = None
+        defaultenv = {}
+        if sys.platform == 'win32':
+            defaultenv = { x : os.environ[x] for x in
+                          ['SystemDrive', 'SystemRoot', 'TMP', 'TEMP'] }
+            # The directory to mspdbcore.dll needs to be in PATH, but this is
+            # always in the native toolchain path, not the cross-toolchain
+            # path.  So, for example, if we're using HostX64\x86 then we need
+            # to add HostX64\x64 to the path, and if we're using HostX86\x64
+            # then we need to add HostX86\x86 to the path.
+            if self.toolchain_type == 'msvc':
+                defaultenv['PATH'] = self._get_msvc_native_toolchain_dir()
+
+        if includes:
+            compileenv = {}
+            compileenv['INCLUDE'] = os.pathsep.join(includes)
+            compileenv.update(defaultenv)
+        if libs:
+            linkenv = {}
+            linkenv['LIB'] = os.pathsep.join(libs)
+            linkenv.update(defaultenv)
+        return (compileenv, linkenv)
+
+    def _ilk_file_names(self):
+        if self.mode == 'link':
+            return []
+
+        return [self._output_name(x, '.ilk') for x in self.inputs]
+
+    def _pdb_file_name(self):
+        if self.mode == 'compile':
+            return None
+        return os.path.splitext(self.output)[0] + '.pdb'
+
+    def _get_compilation_command(self, source, obj):
+        args = []
+
+        args.append(self.compiler)
+        if self.toolchain_type == 'clang-cl':
+            args.append('-m' + self.arch)
+
+        if self.opt == 'none':
+            args.append('/Od')
+        elif self.opt == 'basic':
+            args.append('/O2')
+        elif self.opt == 'lto':
+            if self.toolchain_type == 'msvc':
+                args.append('/GL')
+                args.append('/Gw')
+            else:
+                args.append('-flto=thin')
+        if self.nodefaultlib:
+            args.append('/GS-')
+            args.append('/GR-')
+        args.append('/Z7')
+        if self.toolchain_type == 'clang-cl':
+            args.append('-Xclang')
+            args.append('-fkeep-static-consts')
+            args.append('-fms-compatibility-version=19')
+        args.append('/c')
+
+        args.append('/Fo' + obj)
+        if self.toolchain_type == 'clang-cl':
+            args.append('--')
+        args.append(source)
+
+        return ('compiling', [source], obj,
+                self.compile_env,
+                args)
+
+    def _get_link_command(self):
+        args = []
+        args.append(self.linker)
+        args.append('/DEBUG:FULL')
+        args.append('/INCREMENTAL:NO')
+        if self.nodefaultlib:
+            args.append('/nodefaultlib')
+            args.append('/entry:main')
+        args.append('/PDB:' + self._pdb_file_name())
+        args.append('/OUT:' + self._exe_file_name())
+        args.extend(self._obj_file_names())
+
+        return ('linking', self._obj_file_names(), self._exe_file_name(),
+                self.link_env,
+                args)
+
+    def build_commands(self):
+        commands = []
+        if self.mode == 'compile' or self.mode == 'compile-and-link':
+            for input, output in zip(self.inputs, self._obj_file_names()):
+                commands.append(self._get_compilation_command(input, output))
+        if self.mode == 'link' or self.mode == 'compile-and-link':
+            commands.append(self._get_link_command())
+        return commands
+
+    def output_files(self):
+        outputs = []
+        if self.mode == 'compile' or self.mode == 'compile-and-link':
+            outputs.extend(self._ilk_file_names())
+            outputs.extend(self._obj_file_names())
+        if self.mode == 'link' or self.mode == 'compile-and-link':
+            outputs.append(self._pdb_file_name())
+            outputs.append(self._exe_file_name())
+
+        return [x for x in outputs if x is not None]
+
+class GccBuilder(Builder):
+    def __init__(self, toolchain_type, args):
+        Builder.__init__(self, toolchain_type, args, '.o')
+
+    def _get_compilation_command(self, source, obj):
+        args = []
+
+        args.append(self.compiler)
+        args.append('-m' + self.arch)
+
+        args.append('-g')
+        if self.opt == 'none':
+            args.append('-O0')
+        elif self.opt == 'basic':
+            args.append('-O2')
+        elif self.opt == 'lto':
+            args.append('-flto=thin')
+        if self.nodefaultlib:
+            args.append('-nostdinc')
+            args.append('-static')
+        args.append('-c')
+
+        args.extend(['-o', obj])
+        args.append(source)
+
+        return ('compiling', [source], obj, None, args)
+
+    def _get_link_command(self):
+        args = []
+        args.append(self.compiler)
+        args.append('-m' + self.arch)
+        if self.nodefaultlib:
+            args.append('-nostdlib')
+            args.append('-static')
+            main_symbol = 'main'
+            if sys.platform == 'darwin':
+                main_symbol = '_main'
+            args.append('-Wl,-e,' + main_symbol)
+        if sys.platform.startswith('netbsd'):
+            for x in self.lib_paths:
+                args += ['-L' + x, '-Wl,-rpath,' + x]
+        args.extend(['-o', self._exe_file_name()])
+        args.extend(self._obj_file_names())
+
+        return ('linking', self._obj_file_names(), self._exe_file_name(), None, args)
+
+
+    def output_files(self):
+        outputs = []
+        if self.mode == 'compile' or self.mode == 'compile-and-link':
+            outputs.extend(self._obj_file_names())
+        if self.mode == 'link' or self.mode == 'compile-and-link':
+            outputs.append(self._exe_file_name())
+
+        return outputs
+
+def indent(text, spaces):
+    def prefixed_lines():
+        prefix = ' ' * spaces
+        for line in text.splitlines(True):
+            yield prefix + line
+    return ''.join(prefixed_lines())
+
+def build(commands):
+    global args
+    for (status, inputs, output, env, child_args) in commands:
+        print('\n\n')
+        inputs = [os.path.basename(x) for x in inputs]
+        output = os.path.basename(output)
+        print(status + ' {0} -> {1}'.format('+'.join(inputs), output))
+
+        if args.verbose:
+            print('  Command Line: ' + ' '.join(child_args))
+            print('  Env:')
+            print_environment(env)
+        if args.dry:
+            continue
+
+        popen = subprocess.Popen(child_args,
+                                 stdout=subprocess.PIPE,
+                                 stderr=subprocess.PIPE,
+                                 env=env,
+                                 universal_newlines=True)
+        stdout, stderr = popen.communicate()
+        res = popen.wait()
+        if res == -signal.SIGINT:
+            raise KeyboardInterrupt
+        print('  STDOUT:')
+        print(indent(stdout, 4))
+        if res != 0:
+            print('  STDERR:')
+            print(indent(stderr, 4))
+            sys.exit(res)
+
+def clean(files):
+    global args
+    if not files:
+        return
+    for o in files:
+        file = o if args.verbose else os.path.basename(o)
+        print('Cleaning {0}'.format(file))
+        try:
+            if os.path.exists(o):
+                if not args.dry:
+                    os.remove(o)
+                if args.verbose:
+                    print('  The file was successfully cleaned.')
+            elif args.verbose:
+                print('  The file does not exist.')
+        except:
+            if args.verbose:
+                print('  The file could not be removed.')
+
+def fix_arguments(args):
+    if not args.inputs:
+        raise ValueError('No input files specified')
+
+    if args.output and args.mode == 'compile' and len(args.inputs) > 1:
+        raise ValueError('Cannot specify -o with mode=compile and multiple source files.  Use --outdir instead.')
+
+    if not args.dry:
+        args.inputs = [os.path.abspath(x) for x in args.inputs]
+
+    # If user didn't specify the outdir, use the directory of the first input.
+    if not args.outdir:
+        if args.output:
+            args.outdir = os.path.dirname(args.output)
+        else:
+            args.outdir = os.path.dirname(args.inputs[0])
+            args.outdir = os.path.abspath(args.outdir)
+        args.outdir = os.path.normpath(args.outdir)
+
+    # If user specified a non-absolute path for the output file, append the
+    # output directory to it.
+    if args.output:
+        if not os.path.isabs(args.output):
+            args.output = os.path.join(args.outdir, args.output)
+        args.output = os.path.normpath(args.output)
+
+fix_arguments(args)
+
+(toolchain_type, toolchain_path) = find_toolchain(args.compiler, args.tools_dir)
+if not toolchain_path or not toolchain_type:
+    print('Unable to find toolchain {0}'.format(args.compiler))
+    sys.exit(1)
+
+if args.verbose:
+    print('Script Arguments:')
+    print('  Arch: ' + args.arch)
+    print('  Compiler: ' + args.compiler)
+    print('  Outdir: ' + args.outdir)
+    print('  Output: ' + args.output)
+    print('  Nodefaultlib: ' + str(args.nodefaultlib))
+    print('  Opt: ' + args.opt)
+    print('  Mode: ' + args.mode)
+    print('  Clean: ' + str(args.clean))
+    print('  Verbose: ' + str(args.verbose))
+    print('  Dryrun: ' + str(args.dry))
+    print('  Inputs: ' + format_text(args.inputs, 0, 10))
+    print('Script Environment:')
+    print_environment(os.environ)
+
+args.compiler = toolchain_path
+if not os.path.exists(args.compiler) and not args.dry:
+    raise ValueError('The toolchain {} does not exist.'.format(args.compiler))
+
+if toolchain_type == 'msvc' or toolchain_type=='clang-cl':
+    builder = MsvcBuilder(toolchain_type, args)
+else:
+    builder = GccBuilder(toolchain_type, args)
+
+if args.clean:
+    clean(builder.output_files())
+
+cmds = builder.build_commands()
+
+build(cmds)

Propchange: lldb/trunk/test/Shell/helper/build.py
------------------------------------------------------------------------------
    svn:executable = *

Added: lldb/trunk/test/Shell/helper/toolchain.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/Shell/helper/toolchain.py?rev=374201&view=auto
==============================================================================
--- lldb/trunk/test/Shell/helper/toolchain.py (added)
+++ lldb/trunk/test/Shell/helper/toolchain.py Wed Oct  9 12:22:02 2019
@@ -0,0 +1,131 @@
+import os
+import itertools
+import platform
+import subprocess
+import sys
+
+import lit.util
+from lit.llvm import llvm_config
+from lit.llvm.subst import FindTool
+from lit.llvm.subst import ToolSubst
+
+def use_lldb_substitutions(config):
+    # Set up substitutions for primary tools.  These tools must come from config.lldb_tools_dir
+    # which is basically the build output directory.  We do not want to find these in path or
+    # anywhere else, since they are specifically the programs which are actually being tested.
+
+    dsname = 'debugserver' if platform.system() in ['Darwin'] else 'lldb-server'
+    dsargs = [] if platform.system() in ['Darwin'] else ['gdbserver']
+
+    build_script = os.path.dirname(__file__)
+    build_script = os.path.join(build_script, 'build.py')
+    build_script_args = [build_script,
+                        '--compiler=any', # Default to best compiler
+                        '--arch=' + str(config.lldb_bitness)]
+    if config.lldb_lit_tools_dir:
+        build_script_args.append('--tools-dir={0}'.format(config.lldb_lit_tools_dir))
+    if config.lldb_tools_dir:
+        build_script_args.append('--tools-dir={0}'.format(config.lldb_tools_dir))
+    if config.llvm_libs_dir:
+        build_script_args.append('--libs-dir={0}'.format(config.llvm_libs_dir))
+
+    lldb_init = os.path.join(config.test_exec_root, 'Shell', 'lit-lldb-init')
+
+    primary_tools = [
+        ToolSubst('%lldb',
+                  command=FindTool('lldb'),
+                  extra_args=['--no-lldbinit', '-S', lldb_init]),
+        ToolSubst('%lldb-init',
+                  command=FindTool('lldb'),
+                  extra_args=['-S', lldb_init]),
+        ToolSubst('%debugserver',
+                  command=FindTool(dsname),
+                  extra_args=dsargs,
+                  unresolved='ignore'),
+        ToolSubst('%platformserver',
+                  command=FindTool('lldb-server'),
+                  extra_args=['platform'],
+                  unresolved='ignore'),
+        'lldb-test',
+        'lldb-instr',
+        ToolSubst('%build',
+                  command="'" + sys.executable + "'",
+                  extra_args=build_script_args)
+        ]
+
+    llvm_config.add_tool_substitutions(primary_tools,
+                                       [config.lldb_tools_dir])
+
+def _use_msvc_substitutions(config):
+    # If running from a Visual Studio Command prompt (e.g. vcvars), this will
+    # detect the include and lib paths, and find cl.exe and link.exe and create
+    # substitutions for each of them that explicitly specify /I and /L paths
+    cl = lit.util.which('cl')
+    link = lit.util.which('link')
+
+    if not cl or not link:
+        return
+
+    cl = '"' + cl + '"'
+    link = '"' + link + '"'
+    includes = os.getenv('INCLUDE', '').split(';')
+    libs = os.getenv('LIB', '').split(';')
+
+    config.available_features.add('msvc')
+    compiler_flags = ['"/I{}"'.format(x) for x in includes if os.path.exists(x)]
+    linker_flags = ['"/LIBPATH:{}"'.format(x) for x in libs if os.path.exists(x)]
+
+    tools = [
+        ToolSubst('%msvc_cl', command=cl, extra_args=compiler_flags),
+        ToolSubst('%msvc_link', command=link, extra_args=linker_flags)]
+    llvm_config.add_tool_substitutions(tools)
+    return
+
+def use_support_substitutions(config):
+    # Set up substitutions for support tools.  These tools can be overridden at the CMake
+    # level (by specifying -DLLDB_LIT_TOOLS_DIR), installed, or as a last resort, we can use
+    # the just-built version.
+    flags = []
+    if platform.system() in ['Darwin']:
+        try:
+            out = subprocess.check_output(['xcrun', '--show-sdk-path']).strip()
+            res = 0
+        except OSError:
+            res = -1
+        if res == 0 and out:
+            sdk_path = lit.util.to_string(out)
+            llvm_config.lit_config.note('using SDKROOT: %r' % sdk_path)
+            flags = ['-isysroot', sdk_path]
+    elif platform.system() in ['NetBSD', 'OpenBSD', 'Linux']:
+        flags = ['-pthread']
+
+    if sys.platform.startswith('netbsd'):
+        # needed e.g. to use freshly built libc++
+        flags += ['-L' + config.llvm_libs_dir,
+                  '-Wl,-rpath,' + config.llvm_libs_dir]
+
+    # The clang module cache is used for building inferiors.
+    flags += ['-fmodules-cache-path={}'.format(config.clang_module_cache)]
+
+    additional_tool_dirs=[]
+    if config.lldb_lit_tools_dir:
+        additional_tool_dirs.append(config.lldb_lit_tools_dir)
+
+    llvm_config.use_clang(additional_flags=flags,
+                          additional_tool_dirs=additional_tool_dirs,
+                          required=True)
+
+    if sys.platform == 'win32':
+        _use_msvc_substitutions(config)
+
+    have_lld = llvm_config.use_lld(additional_tool_dirs=additional_tool_dirs,
+                                   required=False)
+    if have_lld:
+        config.available_features.add('lld')
+
+
+    support_tools = ['yaml2obj', 'obj2yaml', 'llvm-pdbutil',
+                     'llvm-mc', 'llvm-readobj', 'llvm-objdump',
+                     'llvm-objcopy', 'lli']
+    additional_tool_dirs += [config.lldb_tools_dir, config.llvm_tools_dir]
+    llvm_config.add_tool_substitutions(support_tools, additional_tool_dirs)

Added: lldb/trunk/test/Shell/lit-lldb-init.in
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/Shell/lit-lldb-init.in?rev=374201&view=auto
==============================================================================
--- lldb/trunk/test/Shell/lit-lldb-init.in (added)
+++ lldb/trunk/test/Shell/lit-lldb-init.in Wed Oct  9 12:22:02 2019
@@ -0,0 +1,5 @@
+# LLDB init file for the LIT tests.
+settings set symbols.enable-external-lookup false
+settings set plugin.process.gdb-remote.packet-timeout 60
+settings set interpreter.echo-comment-commands false
+settings set symbols.clang-modules-cache-path "@LLDB_TEST_MODULE_CACHE_LLDB@"

Added: lldb/trunk/test/Shell/lit.cfg.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/Shell/lit.cfg.py?rev=374201&view=auto
==============================================================================
--- lldb/trunk/test/Shell/lit.cfg.py (added)
+++ lldb/trunk/test/Shell/lit.cfg.py Wed Oct  9 12:22:02 2019
@@ -0,0 +1,107 @@
+# -*- Python -*-
+
+import os
+import platform
+import re
+import shutil
+import site
+import sys
+
+import lit.formats
+from lit.llvm import llvm_config
+from lit.llvm.subst import FindTool
+from lit.llvm.subst import ToolSubst
+from distutils.spawn import find_executable
+
+site.addsitedir(os.path.dirname(__file__))
+from helper import toolchain
+
+# name: The name of this test suite.
+config.name = 'lldb-shell'
+
+# testFormat: The test format to use to interpret tests.
+config.test_format = lit.formats.ShTest(not llvm_config.use_lit_shell)
+
+# suffixes: A list of file extensions to treat as test files. This is overriden
+# by individual lit.local.cfg files in the test subdirectories.
+config.suffixes = ['.test', '.cpp', '.s']
+
+# excludes: A list of directories to exclude from the testsuite. The 'Inputs'
+# subdirectories contain auxiliary inputs for various tests in their parent
+# directories.
+config.excludes = ['Inputs', 'CMakeLists.txt', 'README.txt', 'LICENSE.txt']
+
+# test_source_root: The root path where tests are located.
+config.test_source_root = os.path.dirname(__file__)
+
+# test_exec_root: The root path where tests should be run.
+config.test_exec_root = os.path.join(config.lldb_obj_root, 'test')
+
+
+llvm_config.use_default_substitutions()
+
+toolchain.use_lldb_substitutions(config)
+
+toolchain.use_support_substitutions(config)
+
+
+if re.match(r'^arm(hf.*-linux)|(.*-linux-gnuabihf)', config.target_triple):
+    config.available_features.add("armhf-linux")
+
+def calculate_arch_features(arch_string):
+    # This will add a feature such as x86, arm, mips, etc for each built
+    # target
+    features = []
+    for arch in arch_string.split():
+        features.append(arch.lower())
+    return features
+
+# Run llvm-config and add automatically add features for whether we have
+# assertions enabled, whether we are in debug mode, and what targets we
+# are built for.
+llvm_config.feature_config(
+    [('--assertion-mode', {'ON': 'asserts'}),
+     ('--build-mode', {'DEBUG': 'debug'}),
+     ('--targets-built', calculate_arch_features)
+     ])
+
+# Clean the module caches in the test build directory. This is necessary in an
+# incremental build whenever clang changes underneath, so doing it once per
+# lit.py invocation is close enough.
+for cachedir in [config.clang_module_cache, config.lldb_module_cache]:
+    if os.path.isdir(cachedir):
+        print("Deleting module cache at %s."%cachedir)
+        shutil.rmtree(cachedir)
+
+# Set a default per-test timeout of 10 minutes. Setting a timeout per test
+# requires that killProcessAndChildren() is supported on the platform and
+# lit complains if the value is set but it is not supported.
+supported, errormsg = lit_config.maxIndividualTestTimeIsSupported
+if supported:
+    lit_config.maxIndividualTestTime = 600
+else:
+    lit_config.warning("Could not set a default per-test timeout. " + errormsg)
+
+
+# If running tests natively, check for CPU features needed for some tests.
+
+if 'native' in config.available_features:
+    cpuid_exe = lit.util.which('lit-cpuid', config.lldb_tools_dir)
+    if cpuid_exe is None:
+        lit_config.warning("lit-cpuid not found, tests requiring CPU extensions will be skipped")
+    else:
+        out, err, exitcode = lit.util.executeCommand([cpuid_exe])
+        if exitcode == 0:
+            for x in out.split():
+                config.available_features.add('native-cpu-%s' % x)
+        else:
+            lit_config.warning("lit-cpuid failed: %s" % err)
+
+if not config.lldb_disable_python:
+    config.available_features.add('python')
+
+if config.lldb_enable_lzma:
+    config.available_features.add('lzma')
+
+if find_executable('xz') != None:
+    config.available_features.add('xz')

Added: lldb/trunk/test/Shell/lit.site.cfg.py.in
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/Shell/lit.site.cfg.py.in?rev=374201&view=auto
==============================================================================
--- lldb/trunk/test/Shell/lit.site.cfg.py.in (added)
+++ lldb/trunk/test/Shell/lit.site.cfg.py.in Wed Oct  9 12:22:02 2019
@@ -0,0 +1,44 @@
+ at LIT_SITE_CFG_IN_HEADER@
+
+config.llvm_src_root = "@LLVM_SOURCE_DIR@"
+config.llvm_obj_root = "@LLVM_BINARY_DIR@"
+config.llvm_tools_dir = "@LLVM_TOOLS_DIR@"
+config.llvm_libs_dir = "@LLVM_LIBS_DIR@"
+config.llvm_shlib_dir = "@SHLIBDIR@"
+config.lit_tools_dir = "@LLVM_LIT_TOOLS_DIR@"
+config.lldb_obj_root = "@LLDB_BINARY_DIR@"
+config.lldb_libs_dir = "@LLDB_LIBS_DIR@"
+config.lldb_tools_dir = "@LLDB_TOOLS_DIR@"
+# Since it comes from the command line, it may have backslashes which
+# should not need to be escaped.
+config.lldb_lit_tools_dir = r"@LLDB_LIT_TOOLS_DIR@"
+config.target_triple = "@TARGET_TRIPLE@"
+config.python_executable = "@PYTHON_EXECUTABLE@"
+config.have_zlib = @LLVM_ENABLE_ZLIB@
+config.lldb_enable_lzma = @LLDB_ENABLE_LZMA@
+config.host_triple = "@LLVM_HOST_TRIPLE@"
+config.lldb_bitness = 64 if @LLDB_IS_64_BITS@ else 32
+config.lldb_disable_python = @LLDB_DISABLE_PYTHON@
+config.lldb_build_directory = "@LLDB_TEST_BUILD_DIRECTORY@"
+config.lldb_module_cache = "@LLDB_TEST_MODULE_CACHE_LLDB@"
+config.clang_module_cache = "@LLDB_TEST_MODULE_CACHE_CLANG@"
+
+# Support substitution of the tools and libs dirs with user parameters. This is
+# used when we can't determine the tool dir at configuration time.
+try:
+    config.llvm_tools_dir = config.llvm_tools_dir % lit_config.params
+    config.llvm_libs_dir = config.llvm_libs_dir % lit_config.params
+    config.llvm_shlib_dir = config.llvm_shlib_dir % lit_config.params
+    config.lldb_libs_dir = config.lldb_libs_dir % lit_config.params
+    config.lldb_tools_dir = config.lldb_tools_dir % lit_config.params
+    config.lldb_lit_tools_dir = config.lldb_lit_tools_dir % lit_config.params
+
+except KeyError as e:
+    key, = e.args
+    lit_config.fatal("unable to find %r parameter, use '--param=%s=VALUE'" % (key,key))
+
+import lit.llvm
+lit.llvm.initialize(lit_config, config)
+
+# Let the main config do the real work.
+lit_config.load_config(config, "@LLDB_SOURCE_DIR@/test/Shell/lit.cfg.py")

Added: lldb/trunk/test/Unit/README.md
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/Unit/README.md?rev=374201&view=auto
==============================================================================
--- lldb/trunk/test/Unit/README.md (added)
+++ lldb/trunk/test/Unit/README.md Wed Oct  9 12:22:02 2019
@@ -0,0 +1,4 @@
+# LLDB Unit Tests
+
+This directory only exists for the lit test driver. The actual tests live in
+the `unittest` directory in top level LLDB directory.

Added: lldb/trunk/test/Unit/lit.cfg.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/Unit/lit.cfg.py?rev=374201&view=auto
==============================================================================
--- lldb/trunk/test/Unit/lit.cfg.py (added)
+++ lldb/trunk/test/Unit/lit.cfg.py Wed Oct  9 12:22:02 2019
@@ -0,0 +1,30 @@
+# -*- Python -*-
+
+# Configuration file for the 'lit' test runner.
+
+import os
+import sys
+
+import lit.formats
+from lit.llvm import llvm_config
+
+# name: The name of this test suite.
+config.name = 'lldb-unit'
+
+# suffixes: A list of file extensions to treat as test files.
+config.suffixes =  []
+
+# test_source_root: The root path where unit test binaries are located.
+# test_exec_root: The root path where tests should be run.
+config.test_source_root = os.path.join(config.lldb_obj_root, 'unittests')
+config.test_exec_root = config.test_source_root
+
+# One of our unit tests dynamically links against python.dll, and on Windows
+# it needs to be able to find it at runtime.  This is fine if Python is on your
+# system PATH, but if it's not, then this unit test executable will fail to run.
+# We can solve this by forcing the Python directory onto the system path here.
+llvm_config.with_system_environment('PATH')
+llvm_config.with_environment('PATH', os.path.dirname(sys.executable), append_path=True)
+
+# testFormat: The test format to use to interpret tests.
+config.test_format = lit.formats.GoogleTest(config.llvm_build_mode, 'Tests')

Added: lldb/trunk/test/Unit/lit.site.cfg.py.in
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/Unit/lit.site.cfg.py.in?rev=374201&view=auto
==============================================================================
--- lldb/trunk/test/Unit/lit.site.cfg.py.in (added)
+++ lldb/trunk/test/Unit/lit.site.cfg.py.in Wed Oct  9 12:22:02 2019
@@ -0,0 +1,29 @@
+ at LIT_SITE_CFG_IN_HEADER@
+
+config.test_exec_root = "@LLDB_BINARY_DIR@"
+config.llvm_src_root = "@LLVM_SOURCE_DIR@"
+config.llvm_obj_root = "@LLVM_BINARY_DIR@"
+config.llvm_tools_dir = "@LLVM_TOOLS_DIR@"
+config.llvm_libs_dir = "@LLVM_LIBS_DIR@"
+config.llvm_build_mode = "@LLVM_BUILD_MODE@"
+config.lit_tools_dir = "@LLVM_LIT_TOOLS_DIR@"
+config.lldb_obj_root = "@LLDB_BINARY_DIR@"
+config.lldb_src_root = "@LLDB_SOURCE_DIR@"
+config.target_triple = "@TARGET_TRIPLE@"
+config.python_executable = "@PYTHON_EXECUTABLE@"
+
+# Support substitution of the tools and libs dirs with user parameters. This is
+# used when we can't determine the tool dir at configuration time.
+try:
+    config.llvm_tools_dir = config.llvm_tools_dir % lit_config.params
+    config.llvm_libs_dir = config.llvm_libs_dir % lit_config.params
+    config.llvm_build_mode = config.llvm_build_mode % lit_config.params
+except KeyError as e:
+    key, = e.args
+    lit_config.fatal("unable to find %r parameter, use '--param=%s=VALUE'" % (key,key))
+
+import lit.llvm
+lit.llvm.initialize(lit_config, config)
+
+# Let the main config do the real work.
+lit_config.load_config(config, "@LLDB_SOURCE_DIR@/test/Unit/lit.cfg.py")

Removed: lldb/trunk/test/dotest.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/dotest.py?rev=374200&view=auto
==============================================================================
--- lldb/trunk/test/dotest.py (original)
+++ lldb/trunk/test/dotest.py (removed)
@@ -1,7 +0,0 @@
-#!/usr/bin/env python
-
-if __name__ == "__main__":
-    import use_lldb_suite
-
-    import lldbsuite.test
-    lldbsuite.test.run_suite()

Added: lldb/trunk/test/lit.cfg.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lit.cfg.py?rev=374201&view=auto
==============================================================================
--- lldb/trunk/test/lit.cfg.py (added)
+++ lldb/trunk/test/lit.cfg.py Wed Oct  9 12:22:02 2019
@@ -0,0 +1,41 @@
+# -*- Python -*-
+
+import os
+import platform
+import re
+import shutil
+import site
+import sys
+
+import lit.formats
+from lit.llvm import llvm_config
+from lit.llvm.subst import FindTool
+from lit.llvm.subst import ToolSubst
+from distutils.spawn import find_executable
+
+# This is the top level configuration. Most of these configuration options will
+# be overriden by individual lit configuration files in the test
+# subdirectories.
+
+# name: The name of this test suite.
+config.name = 'lldb'
+
+# testFormat: The test format to use to interpret tests.
+config.test_format = lit.formats.ShTest(not llvm_config.use_lit_shell)
+
+# suffixes: A list of file extensions to treat as test files. This is overriden
+# by individual lit.local.cfg files in the test subdirectories.
+config.suffixes = ['.test', '.cpp', '.s']
+
+# excludes: A list of directories to exclude from the testsuite. The 'Inputs'
+# subdirectories contain auxiliary inputs for various tests in their parent
+# directories.
+config.excludes = ['Inputs', 'CMakeLists.txt', 'README.txt', 'LICENSE.txt']
+
+# test_source_root: The root path where tests are located.
+config.test_source_root = os.path.dirname(__file__)
+
+# test_exec_root: The root path where tests should be run.
+config.test_exec_root = os.path.join(config.lldb_obj_root, 'test')
+
+llvm_config.use_default_substitutions()

Added: lldb/trunk/test/lit.site.cfg.py.in
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lit.site.cfg.py.in?rev=374201&view=auto
==============================================================================
--- lldb/trunk/test/lit.site.cfg.py.in (added)
+++ lldb/trunk/test/lit.site.cfg.py.in Wed Oct  9 12:22:02 2019
@@ -0,0 +1,29 @@
+ at LIT_SITE_CFG_IN_HEADER@
+
+config.test_exec_root = "@LLDB_BINARY_DIR@"
+config.llvm_src_root = "@LLVM_SOURCE_DIR@"
+config.llvm_obj_root = "@LLVM_BINARY_DIR@"
+config.llvm_tools_dir = "@LLVM_TOOLS_DIR@"
+config.llvm_libs_dir = "@LLVM_LIBS_DIR@"
+config.llvm_build_mode = "@LLVM_BUILD_MODE@"
+config.lit_tools_dir = "@LLVM_LIT_TOOLS_DIR@"
+config.lldb_obj_root = "@LLDB_BINARY_DIR@"
+config.lldb_src_root = "@LLDB_SOURCE_DIR@"
+config.target_triple = "@TARGET_TRIPLE@"
+config.python_executable = "@PYTHON_EXECUTABLE@"
+
+# Support substitution of the tools and libs dirs with user parameters. This is
+# used when we can't determine the tool dir at configuration time.
+try:
+    config.llvm_tools_dir = config.llvm_tools_dir % lit_config.params
+    config.llvm_libs_dir = config.llvm_libs_dir % lit_config.params
+    config.llvm_build_mode = config.llvm_build_mode % lit_config.params
+except KeyError as e:
+    key, = e.args
+    lit_config.fatal("unable to find %r parameter, use '--param=%s=VALUE'" % (key,key))
+
+import lit.llvm
+lit.llvm.initialize(lit_config, config)
+
+# Let the main config do the real work.
+lit_config.load_config(config, "@LLDB_SOURCE_DIR@/test/lit.cfg.py")

Removed: lldb/trunk/test/testcases
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/testcases?rev=374200&view=auto
==============================================================================
--- lldb/trunk/test/testcases (original)
+++ lldb/trunk/test/testcases (removed)
@@ -1 +0,0 @@
-link ../packages/Python/lldbsuite/test
\ No newline at end of file

Removed: lldb/trunk/test/use_lldb_suite.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/use_lldb_suite.py?rev=374200&view=auto
==============================================================================
--- lldb/trunk/test/use_lldb_suite.py (original)
+++ lldb/trunk/test/use_lldb_suite.py (removed)
@@ -1,28 +0,0 @@
-import inspect
-import os
-import sys
-
-
-def find_lldb_root():
-    lldb_root = os.path.dirname(
-        os.path.abspath(inspect.getfile(inspect.currentframe()))
-    )
-    while True:
-        lldb_root = os.path.dirname(lldb_root)
-        if lldb_root is None:
-            return None
-
-        test_path = os.path.join(lldb_root, "use_lldb_suite_root.py")
-        if os.path.isfile(test_path):
-            return lldb_root
-    return None
-
-lldb_root = find_lldb_root()
-if lldb_root is not None:
-    import imp
-    fp, pathname, desc = imp.find_module("use_lldb_suite_root", [lldb_root])
-    try:
-        imp.load_module("use_lldb_suite_root", fp, pathname, desc)
-    finally:
-        if fp:
-            fp.close()




More information about the lldb-commits mailing list