diff options
| -rw-r--r-- | CMakeLists.txt | 2 | ||||
| -rw-r--r-- | cmake/modules/LLDBStandalone.cmake | 5 | ||||
| -rw-r--r-- | include/lldb/Core/Error.h | 11 | ||||
| -rw-r--r-- | include/lldb/Symbol/Type.h | 5 | ||||
| -rw-r--r-- | packages/Python/lldbsuite/test/lang/c/register_variables/TestRegisterVariables.py | 2 | ||||
| -rw-r--r-- | packages/Python/lldbsuite/test/lldbdwarf.py | 256 | ||||
| -rw-r--r-- | packages/Python/lldbsuite/test/tools/lldb-server/TestLldbGdbServer.py | 10 | ||||
| -rwxr-xr-x | scripts/Xcode/build-llvm.py | 4 | ||||
| -rw-r--r-- | source/Core/Module.cpp | 12 | ||||
| -rw-r--r-- | source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp | 5 | ||||
| -rw-r--r-- | source/Plugins/InstrumentationRuntime/ThreadSanitizer/ThreadSanitizerRuntime.cpp | 3 | ||||
| -rw-r--r-- | source/Symbol/ClangASTContext.cpp | 3 | ||||
| -rw-r--r-- | source/Symbol/Type.cpp | 87 | ||||
| -rw-r--r-- | source/Symbol/TypeList.cpp | 10 | ||||
| -rw-r--r-- | source/Symbol/TypeMap.cpp | 10 | ||||
| -rw-r--r-- | tools/lldb-server/CMakeLists.txt | 8 | ||||
| -rw-r--r-- | unittests/Core/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | unittests/Core/ErrorTest.cpp | 19 | ||||
| -rw-r--r-- | unittests/Symbol/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | unittests/Symbol/TestType.cpp | 51 | 
20 files changed, 433 insertions, 72 deletions
| diff --git a/CMakeLists.txt b/CMakeLists.txt index b860a93ff926d..32b4580a58731 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,7 +28,7 @@ if (NOT LLDB_DISABLE_PYTHON)      # Don't set -m when building the framework.      set(FINISH_EXTRA_ARGS "-m")    endif() -  set(LLDB_WRAP_PYTHON ${LLDB_PYTHON_TARGET_DIR}/LLDBWrapPython.cpp) +  set(LLDB_WRAP_PYTHON ${LLDB_BINARY_DIR}/scripts/LLDBWrapPython.cpp)    add_subdirectory(scripts)  endif () diff --git a/cmake/modules/LLDBStandalone.cmake b/cmake/modules/LLDBStandalone.cmake index d849602c57b6b..a142b757569ce 100644 --- a/cmake/modules/LLDBStandalone.cmake +++ b/cmake/modules/LLDBStandalone.cmake @@ -21,7 +21,8 @@ if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)        "--libdir"        "--includedir"        "--prefix" -      "--src-root") +      "--src-root" +      "--cmakedir")      execute_process(        COMMAND ${CONFIG_COMMAND}        RESULT_VARIABLE HAD_ERROR @@ -47,6 +48,7 @@ if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)    list(GET CONFIG_OUTPUT 3 INCLUDE_DIR)    list(GET CONFIG_OUTPUT 4 LLVM_OBJ_ROOT)    list(GET CONFIG_OUTPUT 5 MAIN_SRC_DIR) +  list(GET CONFIG_OUTPUT 6 LLVM_CMAKE_PATH)    if(NOT MSVC_IDE)      set(LLVM_ENABLE_ASSERTIONS ${ENABLE_ASSERTIONS} @@ -65,7 +67,6 @@ if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)    find_program(LLVM_TABLEGEN_EXE "llvm-tblgen" ${LLVM_TOOLS_BINARY_DIR}      NO_DEFAULT_PATH) -  set(LLVM_CMAKE_PATH "${LLVM_BINARY_DIR}/lib${LLVM_LIBDIR_SUFFIX}/cmake/llvm")    set(LLVMCONFIG_FILE "${LLVM_CMAKE_PATH}/LLVMConfig.cmake")    if(EXISTS ${LLVMCONFIG_FILE})      list(APPEND CMAKE_MODULE_PATH "${LLVM_CMAKE_PATH}") diff --git a/include/lldb/Core/Error.h b/include/lldb/Core/Error.h index f33464816a16f..8131580991ad9 100644 --- a/include/lldb/Core/Error.h +++ b/include/lldb/Core/Error.h @@ -12,6 +12,7 @@  #if defined(__cplusplus)  #include "llvm/Support/DataTypes.h" +#include "llvm/Support/FormatVariadic.h"  #include <cstdarg>  #include <cstdio> @@ -300,5 +301,15 @@ protected:  } // namespace lldb_private +namespace llvm { +template <> struct format_provider<lldb_private::Error> { +  static void format(const lldb_private::Error &error, llvm::raw_ostream &OS, +                     llvm::StringRef Options) { +    llvm::format_provider<llvm::StringRef>::format(error.AsCString(), OS, +                                                   Options); +  } +}; +} +  #endif // #if defined(__cplusplus)  #endif // #ifndef __DCError_h__ diff --git a/include/lldb/Symbol/Type.h b/include/lldb/Symbol/Type.h index 13c95e71ffeb9..b2a65fabf8f9a 100644 --- a/include/lldb/Symbol/Type.h +++ b/include/lldb/Symbol/Type.h @@ -201,8 +201,9 @@ public:    // From a fully qualified typename, split the type into the type basename    // and the remaining type scope (namespaces/classes). -  static bool GetTypeScopeAndBasename(const char *&name_cstr, -                                      std::string &scope, std::string &basename, +  static bool GetTypeScopeAndBasename(const llvm::StringRef& name, +                                      llvm::StringRef &scope, +                                      llvm::StringRef &basename,                                        lldb::TypeClass &type_class);    void SetEncodingType(Type *encoding_type) { m_encoding_type = encoding_type; } diff --git a/packages/Python/lldbsuite/test/lang/c/register_variables/TestRegisterVariables.py b/packages/Python/lldbsuite/test/lang/c/register_variables/TestRegisterVariables.py index f11491e6d633f..1f3ae3ffcb591 100644 --- a/packages/Python/lldbsuite/test/lang/c/register_variables/TestRegisterVariables.py +++ b/packages/Python/lldbsuite/test/lang/c/register_variables/TestRegisterVariables.py @@ -101,6 +101,8 @@ class RegisterVariableTestCase(TestBase):      @expectedFailureAll(compiler="clang", compiler_version=['<', '3.5'])      @expectedFailureAll(compiler="gcc", compiler_version=[              '>=', '4.8.2'], archs=["i386"]) +    @expectedFailureAll(compiler="gcc", compiler_version=[ +            '<', '4.9'], archs=["x86_64"])      def test_and_run_command(self):          """Test expressions on register values.""" diff --git a/packages/Python/lldbsuite/test/lldbdwarf.py b/packages/Python/lldbsuite/test/lldbdwarf.py new file mode 100644 index 0000000000000..1b50eb130ab9e --- /dev/null +++ b/packages/Python/lldbsuite/test/lldbdwarf.py @@ -0,0 +1,256 @@ +""" This module implement Dwarf expression opcode parser. """ + +import lldb + +# DWARF Expression operators. +DW_OP_addr                          = 0x03 +DW_OP_deref                         = 0x06 +DW_OP_const1u                       = 0x08 +DW_OP_const1s                       = 0x09 +DW_OP_const2u                       = 0x0A +DW_OP_const2s                       = 0x0B +DW_OP_const4u                       = 0x0C +DW_OP_const4s                       = 0x0D +DW_OP_const8u                       = 0x0E +DW_OP_const8s                       = 0x0F +DW_OP_constu                        = 0x10 +DW_OP_consts                        = 0x11 +DW_OP_dup                           = 0x12 +DW_OP_drop                          = 0x13 +DW_OP_over                          = 0x14 +DW_OP_pick                          = 0x15 +DW_OP_swap                          = 0x16 +DW_OP_rot                           = 0x17 +DW_OP_xderef                        = 0x18 +DW_OP_abs                           = 0x19 +DW_OP_and                           = 0x1A +DW_OP_div                           = 0x1B +DW_OP_minus                         = 0x1C +DW_OP_mod                           = 0x1D +DW_OP_mul                           = 0x1E +DW_OP_neg                           = 0x1F +DW_OP_not                           = 0x20 +DW_OP_or                            = 0x21 +DW_OP_plus                          = 0x22 +DW_OP_plus_uconst                   = 0x23 +DW_OP_shl                           = 0x24 +DW_OP_shr                           = 0x25 +DW_OP_shra                          = 0x26 +DW_OP_xor                           = 0x27 +DW_OP_skip                          = 0x2F +DW_OP_bra                           = 0x28 +DW_OP_eq                            = 0x29 +DW_OP_ge                            = 0x2A +DW_OP_gt                            = 0x2B +DW_OP_le                            = 0x2C +DW_OP_lt                            = 0x2D +DW_OP_ne                            = 0x2E +DW_OP_lit0                          = 0x30 +DW_OP_lit1                          = 0x31 +DW_OP_lit2                          = 0x32 +DW_OP_lit3                          = 0x33 +DW_OP_lit4                          = 0x34 +DW_OP_lit5                          = 0x35 +DW_OP_lit6                          = 0x36 +DW_OP_lit7                          = 0x37 +DW_OP_lit8                          = 0x38 +DW_OP_lit9                          = 0x39 +DW_OP_lit10                         = 0x3A +DW_OP_lit11                         = 0x3B +DW_OP_lit12                         = 0x3C +DW_OP_lit13                         = 0x3D +DW_OP_lit14                         = 0x3E +DW_OP_lit15                         = 0x3F +DW_OP_lit16                         = 0x40 +DW_OP_lit17                         = 0x41 +DW_OP_lit18                         = 0x42 +DW_OP_lit19                         = 0x43 +DW_OP_lit20                         = 0x44 +DW_OP_lit21                         = 0x45 +DW_OP_lit22                         = 0x46 +DW_OP_lit23                         = 0x47 +DW_OP_lit24                         = 0x48 +DW_OP_lit25                         = 0x49 +DW_OP_lit26                         = 0x4A +DW_OP_lit27                         = 0x4B +DW_OP_lit28                         = 0x4C +DW_OP_lit29                         = 0x4D +DW_OP_lit30                         = 0x4E +DW_OP_lit31                         = 0x4F +DW_OP_reg0                          = 0x50 +DW_OP_reg1                          = 0x51 +DW_OP_reg2                          = 0x52 +DW_OP_reg3                          = 0x53 +DW_OP_reg4                          = 0x54 +DW_OP_reg5                          = 0x55 +DW_OP_reg6                          = 0x56 +DW_OP_reg7                          = 0x57 +DW_OP_reg8                          = 0x58 +DW_OP_reg9                          = 0x59 +DW_OP_reg10                         = 0x5A +DW_OP_reg11                         = 0x5B +DW_OP_reg12                         = 0x5C +DW_OP_reg13                         = 0x5D +DW_OP_reg14                         = 0x5E +DW_OP_reg15                         = 0x5F +DW_OP_reg16                         = 0x60 +DW_OP_reg17                         = 0x61 +DW_OP_reg18                         = 0x62 +DW_OP_reg19                         = 0x63 +DW_OP_reg20                         = 0x64 +DW_OP_reg21                         = 0x65 +DW_OP_reg22                         = 0x66 +DW_OP_reg23                         = 0x67 +DW_OP_reg24                         = 0x68 +DW_OP_reg25                         = 0x69 +DW_OP_reg26                         = 0x6A +DW_OP_reg27                         = 0x6B +DW_OP_reg28                         = 0x6C +DW_OP_reg29                         = 0x6D +DW_OP_reg30                         = 0x6E +DW_OP_reg31                         = 0x6F +DW_OP_breg0                         = 0x70 +DW_OP_breg1                         = 0x71 +DW_OP_breg2                         = 0x72 +DW_OP_breg3                         = 0x73 +DW_OP_breg4                         = 0x74 +DW_OP_breg5                         = 0x75 +DW_OP_breg6                         = 0x76 +DW_OP_breg7                         = 0x77 +DW_OP_breg8                         = 0x78 +DW_OP_breg9                         = 0x79 +DW_OP_breg10                        = 0x7A +DW_OP_breg11                        = 0x7B +DW_OP_breg12                        = 0x7C +DW_OP_breg13                        = 0x7D +DW_OP_breg14                        = 0x7E +DW_OP_breg15                        = 0x7F +DW_OP_breg16                        = 0x80 +DW_OP_breg17                        = 0x81 +DW_OP_breg18                        = 0x82 +DW_OP_breg19                        = 0x83 +DW_OP_breg20                        = 0x84 +DW_OP_breg21                        = 0x85 +DW_OP_breg22                        = 0x86 +DW_OP_breg23                        = 0x87 +DW_OP_breg24                        = 0x88 +DW_OP_breg25                        = 0x89 +DW_OP_breg26                        = 0x8A +DW_OP_breg27                        = 0x8B +DW_OP_breg28                        = 0x8C +DW_OP_breg29                        = 0x8D +DW_OP_breg30                        = 0x8E +DW_OP_breg31                        = 0x8F +DW_OP_regx                          = 0x90 +DW_OP_fbreg                         = 0x91 +DW_OP_bregx                         = 0x92 +DW_OP_piece                         = 0x93 +DW_OP_deref_size                    = 0x94 +DW_OP_xderef_size                   = 0x95 +DW_OP_nop                           = 0x96 +DW_OP_push_object_address           = 0x97 +DW_OP_call2                         = 0x98 +DW_OP_call4                         = 0x99 +DW_OP_call_ref                      = 0x9A +DW_OP_form_tls_address              = 0x9B +DW_OP_call_frame_cfa                = 0x9C +DW_OP_bit_piece                     = 0x9D +DW_OP_implicit_value                = 0x9E +DW_OP_stack_value                   = 0x9F +DW_OP_lo_user                       = 0xE0 +DW_OP_GNU_push_tls_address          = 0xE0 +DW_OP_APPLE_uninit                  = 0xF0 +DW_OP_hi_user                       = 0xFF + + +class DwarfOpcodeParser(object): + +    def updateRegInfoBitsize(self, reg_info, byte_order): +        """ Update the regInfo bit size. """ + +        # Evaluate Dwarf Expression +        expr_result = self.evaluateDwarfExpression(reg_info["dynamic_size_dwarf_expr_bytes"], +                                                    byte_order) + +        if expr_result == 0: +            reg_info["bitsize"] = 32 +        elif expr_result == 1: +            reg_info["bitsize"] = 64 + + +    def evaluateDwarfExpression(self, dwarf_opcode, byte_order): +        """Evaluate Dwarf Expression. """ + +        dwarf_opcode = [dwarf_opcode[i:i+2] for i in range(0,len(dwarf_opcode),2)] +        dwarf_data = [] +        for index in range(len(dwarf_opcode)): + +            if index < len(dwarf_opcode): +                val = int(dwarf_opcode[index], 16) +            else: +                break + +            if val == DW_OP_regx: +                # Read register number  +                self.assertTrue(len(dwarf_opcode) > (index + 1)) +                reg_no = int(dwarf_opcode.pop(index + 1), 16) + +                self.reset_test_sequence() +                # Read register value +                self.test_sequence.add_log_lines( +                             ["read packet: $p{0:x}#00".format(reg_no), +                             {"direction": "send", "regex": r"^\$([0-9a-fA-F]+)#", +                             "capture": {1: "p_response"}}],True) +                 +                Context = self.expect_gdbremote_sequence() +                self.assertIsNotNone(Context) +                p_response = Context.get("p_response") +                self.assertIsNotNone(p_response) + +                if byte_order == lldb.eByteOrderLittle: +                   # In case of little endian +                   # first decode the HEX ASCII bytes and then reverse it +                   # to get actual value of SR register +                   p_response = "".join(reversed([p_response[i:i+2] for i in range(0, +                                                  len(p_response),2)])) +                # Push register value +                dwarf_data.append(int(p_response,16)) + +            elif val == DW_OP_lit1: +                # Push literal 1 +                dwarf_data.append(1) +            +            elif val == DW_OP_lit26: +                # Push literal 26 +                dwarf_data.append(26) + +            elif val == DW_OP_shl: +                # left shift and push the result back +                self.assertTrue(len(dwarf_data) > 1) +                shift_amount = dwarf_data.pop() +                val_to_shift = dwarf_data.pop() +                result = val_to_shift << shift_amount +                dwarf_data.append(result) + +            elif val == DW_OP_shr: +                # Right shift and push the result back +                self.assertTrue(len(dwarf_data) > 1) +                shift_amount = dwarf_data.pop() +                val_to_shift = dwarf_data.pop() +                result = val_to_shift >> shift_amount +                dwarf_data.append(result) + +            elif val == DW_OP_and: +                # And of topmost 2 elements and push the result back +                first_ele = dwarf_data.pop() +                second_ele = dwarf_data.pop() +                result = first_ele & second_ele +                dwarf_data.append(result) + +            else: +                self.assertTrue(False and "Unprocess Dwarf Opcode") + +        self.assertTrue(len(dwarf_data) == 1) +        expr_result = dwarf_data.pop() +        return expr_result + diff --git a/packages/Python/lldbsuite/test/tools/lldb-server/TestLldbGdbServer.py b/packages/Python/lldbsuite/test/tools/lldb-server/TestLldbGdbServer.py index 1ba49f339402a..b69ac3f8d2a30 100644 --- a/packages/Python/lldbsuite/test/tools/lldb-server/TestLldbGdbServer.py +++ b/packages/Python/lldbsuite/test/tools/lldb-server/TestLldbGdbServer.py @@ -20,10 +20,11 @@ import platform  import signal  from lldbsuite.test.decorators import *  from lldbsuite.test.lldbtest import * +from lldbsuite.test.lldbdwarf import *  from lldbsuite.test import lldbutil -class LldbGdbServerTestCase(gdbremote_testcase.GdbRemoteTestCaseBase): +class LldbGdbServerTestCase(gdbremote_testcase.GdbRemoteTestCaseBase, DwarfOpcodeParser):      mydir = TestBase.compute_mydir(__file__) @@ -541,6 +542,10 @@ class LldbGdbServerTestCase(gdbremote_testcase.GdbRemoteTestCaseBase):          self.assertIsNotNone(reg_infos)          self.assertTrue(len(reg_infos) > 0) +        inferior_exe_path = os.path.abspath("a.out") +        Target = self.dbg.CreateTarget(inferior_exe_path) +        byte_order = Target.GetByteOrder() +          # Read value for each register.          reg_index = 0          for reg_info in reg_infos: @@ -565,6 +570,9 @@ class LldbGdbServerTestCase(gdbremote_testcase.GdbRemoteTestCaseBase):              # Verify the response length.              p_response = context.get("p_response")              self.assertIsNotNone(p_response) + +            if "dynamic_size_dwarf_expr_bytes" in reg_info: +                self.updateRegInfoBitsize(reg_info, byte_order)              self.assertEqual(len(p_response), 2 * int(reg_info["bitsize"]) / 8)              # Increment loop diff --git a/scripts/Xcode/build-llvm.py b/scripts/Xcode/build-llvm.py index 792f92558b4d3..c00907e935cff 100755 --- a/scripts/Xcode/build-llvm.py +++ b/scripts/Xcode/build-llvm.py @@ -22,12 +22,12 @@ def LLVM_HASH_INCLUDES_DIFFS():  def LLVM_REF(): -    llvm_ref = "master" +    llvm_ref = "release_40"      return llvm_ref  def CLANG_REF(): -    clang_ref = "master" +    clang_ref = "release_40"      return clang_ref  # For use with Xcode-style builds diff --git a/source/Core/Module.cpp b/source/Core/Module.cpp index 220773b5ad405..28f140b41e1e9 100644 --- a/source/Core/Module.cpp +++ b/source/Core/Module.cpp @@ -995,8 +995,8 @@ size_t Module::FindTypes(      TypeList &types) {    size_t num_matches = 0;    const char *type_name_cstr = name.GetCString(); -  std::string type_scope; -  std::string type_basename; +  llvm::StringRef type_scope; +  llvm::StringRef type_basename;    const bool append = true;    TypeClass type_class = eTypeClassAny;    TypeMap typesmap; @@ -1006,13 +1006,9 @@ size_t Module::FindTypes(      // from the root namespace and implies and exact match. The typenames we      // get back from clang do not start with "::" so we need to strip this off      // in order to get the qualified names to match +    exact_match = type_scope.consume_front("::"); -    if (type_scope.size() >= 2 && type_scope[0] == ':' && -        type_scope[1] == ':') { -      type_scope.erase(0, 2); -      exact_match = true; -    } -    ConstString type_basename_const_str(type_basename.c_str()); +    ConstString type_basename_const_str(type_basename);      if (FindTypes_Impl(sc, type_basename_const_str, nullptr, append,                         max_matches, searched_symbol_files, typesmap)) {        typesmap.RemoveMismatchedTypes(type_scope, type_basename, type_class, diff --git a/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp b/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp index f8539379f7da1..f60587ed2fff8 100644 --- a/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp +++ b/source/Plugins/ExpressionParser/Clang/ASTResultSynthesizer.cpp @@ -346,8 +346,7 @@ bool ASTResultSynthesizer::SynthesizeBodyResult(CompoundStmt *Body,      ExprResult address_of_expr =          m_sema->CreateBuiltinUnaryOp(SourceLocation(), UO_AddrOf, last_expr);      if (address_of_expr.get()) -      m_sema->AddInitializerToDecl(result_decl, address_of_expr.get(), true, -                                   false); +      m_sema->AddInitializerToDecl(result_decl, address_of_expr.get(), true);      else        return false;    } else { @@ -359,7 +358,7 @@ bool ASTResultSynthesizer::SynthesizeBodyResult(CompoundStmt *Body,      if (!result_decl)        return false; -    m_sema->AddInitializerToDecl(result_decl, last_expr, true, false); +    m_sema->AddInitializerToDecl(result_decl, last_expr, true);    }    DC->addDecl(result_decl); diff --git a/source/Plugins/InstrumentationRuntime/ThreadSanitizer/ThreadSanitizerRuntime.cpp b/source/Plugins/InstrumentationRuntime/ThreadSanitizer/ThreadSanitizerRuntime.cpp index 3010724306e4f..d8a46e5d45507 100644 --- a/source/Plugins/InstrumentationRuntime/ThreadSanitizer/ThreadSanitizerRuntime.cpp +++ b/source/Plugins/InstrumentationRuntime/ThreadSanitizer/ThreadSanitizerRuntime.cpp @@ -206,7 +206,8 @@ CreateStackTrace(ValueObjectSP o,    StructuredData::Array *trace = new StructuredData::Array();    ValueObjectSP trace_value_object =        o->GetValueForExpressionPath(trace_item_name.c_str()); -  for (int j = 0; j < 8; j++) { +  size_t count = trace_value_object->GetNumChildren(); +  for (size_t j = 0; j < count; j++) {      addr_t trace_addr =          trace_value_object->GetChildAtIndex(j, true)->GetValueAsUnsigned(0);      if (trace_addr == 0) diff --git a/source/Symbol/ClangASTContext.cpp b/source/Symbol/ClangASTContext.cpp index 3d37b7083b747..49b28349fd156 100644 --- a/source/Symbol/ClangASTContext.cpp +++ b/source/Symbol/ClangASTContext.cpp @@ -1528,8 +1528,7 @@ ClassTemplateDecl *ClangASTContext::CreateClassTemplateDecl(        *ast,        decl_ctx, // What decl context do we use here? TU? The actual decl                  // context? -      SourceLocation(), decl_name, template_param_list, template_cxx_decl, -      nullptr); +      SourceLocation(), decl_name, template_param_list, template_cxx_decl);    if (class_template_decl) {      if (access_type != eAccessNone) diff --git a/source/Symbol/Type.cpp b/source/Symbol/Type.cpp index 2df193fa45e55..80d08bf742fc1 100644 --- a/source/Symbol/Type.cpp +++ b/source/Symbol/Type.cpp @@ -620,50 +620,59 @@ ConstString Type::GetQualifiedName() {    return GetForwardCompilerType().GetConstTypeName();  } -bool Type::GetTypeScopeAndBasename(const char *&name_cstr, std::string &scope, -                                   std::string &basename, +bool Type::GetTypeScopeAndBasename(const llvm::StringRef& name, +                                   llvm::StringRef &scope, +                                   llvm::StringRef &basename,                                     TypeClass &type_class) { -  // Protect against null c string. -    type_class = eTypeClassAny; -  if (name_cstr && name_cstr[0]) { -    llvm::StringRef name_strref(name_cstr); -    if (name_strref.startswith("struct ")) { -      name_cstr += 7; -      type_class = eTypeClassStruct; -    } else if (name_strref.startswith("class ")) { -      name_cstr += 6; -      type_class = eTypeClassClass; -    } else if (name_strref.startswith("union ")) { -      name_cstr += 6; -      type_class = eTypeClassUnion; -    } else if (name_strref.startswith("enum ")) { -      name_cstr += 5; -      type_class = eTypeClassEnumeration; -    } else if (name_strref.startswith("typedef ")) { -      name_cstr += 8; -      type_class = eTypeClassTypedef; -    } -    const char *basename_cstr = name_cstr; -    const char *namespace_separator = ::strstr(basename_cstr, "::"); -    if (namespace_separator) { -      const char *template_arg_char = ::strchr(basename_cstr, '<'); -      while (namespace_separator != nullptr) { -        if (template_arg_char && -            namespace_separator > template_arg_char) // but namespace'd template -                                                     // arguments are still good -                                                     // to go -          break; -        basename_cstr = namespace_separator + 2; -        namespace_separator = strstr(basename_cstr, "::"); -      } -      if (basename_cstr > name_cstr) { -        scope.assign(name_cstr, basename_cstr - name_cstr); -        basename.assign(basename_cstr); -        return true; +  if (name.empty()) +    return false; + +  basename = name; +  if (basename.consume_front("struct ")) +    type_class = eTypeClassStruct; +  else if (basename.consume_front("class ")) +    type_class = eTypeClassClass; +  else if (basename.consume_front("union ")) +    type_class = eTypeClassUnion; +  else if (basename.consume_front("enum ")) +    type_class = eTypeClassEnumeration; +  else if (basename.consume_front("typedef ")) +    type_class = eTypeClassTypedef; + +  size_t namespace_separator = basename.find("::"); +  if (namespace_separator == llvm::StringRef::npos) +    return false; + +  size_t template_begin = basename.find('<'); +  while (namespace_separator != llvm::StringRef::npos) { +    if (template_begin != llvm::StringRef::npos && +        namespace_separator > template_begin) { +      size_t template_depth = 1; +      llvm::StringRef template_arg = +          basename.drop_front(template_begin + 1); +      while (template_depth > 0 && !template_arg.empty()) { +        if (template_arg.front() == '<') +          template_depth++; +        else if (template_arg.front() == '>') +          template_depth--; +        template_arg = template_arg.drop_front(1);        } +      if (template_depth != 0) +        return false; // We have an invalid type name. Bail out. +      if (template_arg.empty()) +        break; // The template ends at the end of the full name. +      basename = template_arg; +    } else { +      basename = basename.drop_front(namespace_separator + 2);      } +    template_begin = basename.find('<'); +    namespace_separator = basename.find("::"); +  } +  if (basename.size() < name.size()) { +    scope = name.take_front(name.size() - basename.size()); +    return true;    }    return false;  } diff --git a/source/Symbol/TypeList.cpp b/source/Symbol/TypeList.cpp index 4d32afcb05167..4fcaff3daf901 100644 --- a/source/Symbol/TypeList.cpp +++ b/source/Symbol/TypeList.cpp @@ -108,13 +108,13 @@ void TypeList::Dump(Stream *s, bool show_context) {  void TypeList::RemoveMismatchedTypes(const char *qualified_typename,                                       bool exact_match) { -  std::string type_scope; -  std::string type_basename; +  llvm::StringRef type_scope; +  llvm::StringRef type_basename;    TypeClass type_class = eTypeClassAny;    if (!Type::GetTypeScopeAndBasename(qualified_typename, type_scope,                                       type_basename, type_class)) {      type_basename = qualified_typename; -    type_scope.clear(); +    type_scope = "";    }    return RemoveMismatchedTypes(type_scope, type_basename, type_class,                                 exact_match); @@ -145,8 +145,8 @@ void TypeList::RemoveMismatchedTypes(const std::string &type_scope,      ConstString match_type_name_const_str(the_type->GetQualifiedName());      if (match_type_name_const_str) {        const char *match_type_name = match_type_name_const_str.GetCString(); -      std::string match_type_scope; -      std::string match_type_basename; +      llvm::StringRef match_type_scope; +      llvm::StringRef match_type_basename;        if (Type::GetTypeScopeAndBasename(match_type_name, match_type_scope,                                          match_type_basename,                                          match_type_class)) { diff --git a/source/Symbol/TypeMap.cpp b/source/Symbol/TypeMap.cpp index 21eb611e7b867..40c6558d58255 100644 --- a/source/Symbol/TypeMap.cpp +++ b/source/Symbol/TypeMap.cpp @@ -152,13 +152,13 @@ void TypeMap::Dump(Stream *s, bool show_context) {  void TypeMap::RemoveMismatchedTypes(const char *qualified_typename,                                      bool exact_match) { -  std::string type_scope; -  std::string type_basename; +  llvm::StringRef type_scope; +  llvm::StringRef type_basename;    TypeClass type_class = eTypeClassAny;    if (!Type::GetTypeScopeAndBasename(qualified_typename, type_scope,                                       type_basename, type_class)) {      type_basename = qualified_typename; -    type_scope.clear(); +    type_scope = "";    }    return RemoveMismatchedTypes(type_scope, type_basename, type_class,                                 exact_match); @@ -189,8 +189,8 @@ void TypeMap::RemoveMismatchedTypes(const std::string &type_scope,      ConstString match_type_name_const_str(the_type->GetQualifiedName());      if (match_type_name_const_str) {        const char *match_type_name = match_type_name_const_str.GetCString(); -      std::string match_type_scope; -      std::string match_type_basename; +      llvm::StringRef match_type_scope; +      llvm::StringRef match_type_basename;        if (Type::GetTypeScopeAndBasename(match_type_name, match_type_scope,                                          match_type_basename,                                          match_type_class)) { diff --git a/tools/lldb-server/CMakeLists.txt b/tools/lldb-server/CMakeLists.txt index 19c3a9bbabb4f..c3b405f67b2e7 100644 --- a/tools/lldb-server/CMakeLists.txt +++ b/tools/lldb-server/CMakeLists.txt @@ -183,7 +183,13 @@ else()    target_link_libraries(lldb-server ${LLDB_USED_LIBS})    target_link_libraries(lldb-server ${CLANG_USED_LIBS})  endif() -llvm_config(lldb-server ${LLVM_LINK_COMPONENTS}) +if(NOT LLVM_LINK_LLVM_DYLIB) +  # This is necessary in !LLVM_LINK_LLVM_DYLIB as LLDB's libs do not track their +  # dependencies properly. It is conditional because in a LLVM_LINK_LLVM_DYLIB +  # build it would introduce duplicate symbols (add_lldb_tool links to libLLVM, +  # and this would add the individual .a files as well). +  llvm_config(lldb-server ${LLVM_LINK_COMPONENTS}) +endif()  target_link_libraries(lldb-server ${LLDB_SYSTEM_LIBS}) diff --git a/unittests/Core/CMakeLists.txt b/unittests/Core/CMakeLists.txt index da880010e4be9..980bc5b9f9ae2 100644 --- a/unittests/Core/CMakeLists.txt +++ b/unittests/Core/CMakeLists.txt @@ -2,6 +2,7 @@ add_lldb_unittest(LLDBCoreTests    ArchSpecTest.cpp    BroadcasterTest.cpp    DataExtractorTest.cpp +  ErrorTest.cpp    ListenerTest.cpp    ScalarTest.cpp    StructuredDataTest.cpp diff --git a/unittests/Core/ErrorTest.cpp b/unittests/Core/ErrorTest.cpp new file mode 100644 index 0000000000000..f3727bbd78ae3 --- /dev/null +++ b/unittests/Core/ErrorTest.cpp @@ -0,0 +1,19 @@ +//===-- ErrorTest.cpp -------------------------------------------*- C++ -*-===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "gtest/gtest.h" +#include "lldb/Core/Error.h" + +using namespace lldb_private; + +TEST(ErrorTest, Formatv) { +  EXPECT_EQ("", llvm::formatv("{0}", Error()).str()); +  EXPECT_EQ("Hello Error", llvm::formatv("{0}", Error("Hello Error")).str()); +  EXPECT_EQ("Hello", llvm::formatv("{0:5}", Error("Hello Error")).str()); +} diff --git a/unittests/Symbol/CMakeLists.txt b/unittests/Symbol/CMakeLists.txt index ef41f3fd62a87..75cabddba5c4e 100644 --- a/unittests/Symbol/CMakeLists.txt +++ b/unittests/Symbol/CMakeLists.txt @@ -1,3 +1,4 @@  add_lldb_unittest(SymbolTests    TestClangASTContext.cpp +  TestType.cpp    ) diff --git a/unittests/Symbol/TestType.cpp b/unittests/Symbol/TestType.cpp new file mode 100644 index 0000000000000..68128b89329c9 --- /dev/null +++ b/unittests/Symbol/TestType.cpp @@ -0,0 +1,51 @@ +//===-- TestType.cpp --------------------------------------------*- C++ -*-===// +// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "gtest/gtest.h" + +#include "lldb/Symbol/Type.h" + +using namespace lldb; +using namespace lldb_private; + +namespace { +void TestGetTypeScopeAndBasenameHelper(const char *full_type, +                                       bool expected_is_scoped, +                                       const char *expected_scope, +                                       const char *expected_name) { +  llvm::StringRef scope, name; +  lldb::TypeClass type_class; +  bool is_scoped = +      Type::GetTypeScopeAndBasename(full_type, scope, name, type_class); +  EXPECT_EQ(is_scoped, expected_is_scoped); +  if (expected_is_scoped) { +    EXPECT_EQ(scope, expected_scope); +    EXPECT_EQ(name, expected_name); +  } +} +}; + +TEST(Type, GetTypeScopeAndBasename) { +  TestGetTypeScopeAndBasenameHelper("int", false, "", ""); +  TestGetTypeScopeAndBasenameHelper("std::string", true, "std::", "string"); +  TestGetTypeScopeAndBasenameHelper("std::set<int>", true, "std::", "set<int>"); +  TestGetTypeScopeAndBasenameHelper("std::set<int, std::less<int>>", true, +                                    "std::", "set<int, std::less<int>>"); +  TestGetTypeScopeAndBasenameHelper("std::string::iterator", true, +                                    "std::string::", "iterator"); +  TestGetTypeScopeAndBasenameHelper("std::set<int>::iterator", true, +                                    "std::set<int>::", "iterator"); +  TestGetTypeScopeAndBasenameHelper( +      "std::set<int, std::less<int>>::iterator", true, +      "std::set<int, std::less<int>>::", "iterator"); +  TestGetTypeScopeAndBasenameHelper( +      "std::set<int, std::less<int>>::iterator<bool>", true, +      "std::set<int, std::less<int>>::", "iterator<bool>"); +} | 
