summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-04-26 19:24:53 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-04-26 19:24:53 +0000
commit5060b64b7d79491d507a75201be161fd0c38fcbb (patch)
treef4791d04b99ac52da01e646e5a6c9ce22ade61b9
parentd44a35e87e405ae98902dc491ba70ed82f58f592 (diff)
downloadsrc-test2-5060b64b7d79491d507a75201be161fd0c38fcbb.tar.gz
src-test2-5060b64b7d79491d507a75201be161fd0c38fcbb.zip
Notes
-rw-r--r--cmake/modules/LLDBConfig.cmake6
-rw-r--r--cmake/platforms/Android.cmake155
-rw-r--r--examples/python/disassembly_mode.py48
-rw-r--r--include/lldb/API/LLDB.h2
-rw-r--r--include/lldb/API/SBDefines.h2
-rw-r--r--include/lldb/API/SBError.h1
-rw-r--r--include/lldb/API/SBProcess.h27
-rw-r--r--include/lldb/API/SBStructuredData.h10
-rw-r--r--include/lldb/API/SBTrace.h122
-rw-r--r--include/lldb/API/SBTraceOptions.h58
-rw-r--r--include/lldb/Core/StructuredDataImpl.h95
-rw-r--r--include/lldb/Core/TraceOptions.h62
-rw-r--r--include/lldb/Core/ValueObject.h26
-rw-r--r--include/lldb/Host/SocketAddress.h5
-rw-r--r--include/lldb/Target/Process.h74
-rw-r--r--include/lldb/lldb-enumerations.h7
-rw-r--r--include/lldb/lldb-forward.h4
-rw-r--r--packages/Python/lldbsuite/test/functionalities/unwind/noreturn/TestNoreturnUnwind.py2
-rw-r--r--packages/Python/lldbsuite/test/functionalities/watchpoint/step_over_watchpoint/TestStepOverWatchpoint.py2
-rw-r--r--packages/Python/lldbsuite/test/lang/c/inlines/main.c5
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/class_static/TestStaticVariables.py2
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/llvm-style/Makefile3
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/llvm-style/TestLLVMStyle.py7
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/llvm-style/main.cpp36
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/nsimport/TestCppNsImport.py4
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/symbols/Makefile3
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/symbols/TestSymbols.py7
-rw-r--r--packages/Python/lldbsuite/test/lang/cpp/symbols/main.cpp40
-rw-r--r--scripts/interface/SBProcess.i3
-rw-r--r--scripts/interface/SBStructuredData.i3
-rw-r--r--scripts/interface/SBTrace.i34
-rw-r--r--scripts/interface/SBTraceOptions.i38
-rw-r--r--scripts/lldb.swig4
-rw-r--r--source/API/CMakeLists.txt2
-rw-r--r--source/API/SBProcess.cpp22
-rw-r--r--source/API/SBStructuredData.cpp81
-rw-r--r--source/API/SBTrace.cpp109
-rw-r--r--source/API/SBTraceOptions.cpp94
-rw-r--r--source/Core/ValueObject.cpp34
-rw-r--r--source/Host/common/SocketAddress.cpp32
-rw-r--r--source/Host/freebsd/Host.cpp164
-rw-r--r--source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp505
-rw-r--r--source/Plugins/InstrumentationRuntime/ThreadSanitizer/ThreadSanitizerRuntime.cpp2
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxx.cpp3
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp65
-rw-r--r--source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h2
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp8
-rw-r--r--tools/debugserver/source/RNBRemote.cpp2
-rw-r--r--unittests/Host/SocketAddressTest.cpp25
-rwxr-xr-xwww/build.html55
50 files changed, 1423 insertions, 679 deletions
diff --git a/cmake/modules/LLDBConfig.cmake b/cmake/modules/LLDBConfig.cmake
index 60af9504ee8a..c40a24f056d8 100644
--- a/cmake/modules/LLDBConfig.cmake
+++ b/cmake/modules/LLDBConfig.cmake
@@ -250,12 +250,6 @@ endif()
set(LLDB_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
set(LLDB_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR})
-# If building on a 32-bit system, make sure off_t can store offsets > 2GB
-if( CMAKE_SIZEOF_VOID_P EQUAL 4 )
- add_definitions( -D_LARGEFILE_SOURCE )
- add_definitions( -D_FILE_OFFSET_BITS=64 )
-endif()
-
if (CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR)
message(FATAL_ERROR "In-source builds are not allowed. CMake would overwrite "
"the makefiles distributed with LLDB. Please create a directory and run cmake "
diff --git a/cmake/platforms/Android.cmake b/cmake/platforms/Android.cmake
deleted file mode 100644
index 789322f4353c..000000000000
--- a/cmake/platforms/Android.cmake
+++ /dev/null
@@ -1,155 +0,0 @@
-# Toolchain config for Android standalone NDK.
-#
-# Usage:
-# build host llvm and clang first
-# cmake -DCMAKE_TOOLCHAIN_FILE=../lldb/cmake/platforms/Android.cmake \
-# -DANDROID_TOOLCHAIN_DIR=<toolchain_dir> \
-# -DANDROID_ABI=<target_abi> \
-# -DCMAKE_CXX_COMPILER_VERSION=<gcc_version> \
-# -DLLVM_TARGET_ARCH=<llvm_target_arch> \
-# -DLLVM_TARGETS_TO_BUILD=<llvm_targets_to_build> \
-# -DLLVM_TABLEGEN=<path_to_llvm-tblgen> \
-# -DCLANG_TABLEGEN=<path_to_clang-tblgen>
-#
-# Current Support:
-# ANDROID_ABI = x86, x86_64
-# CMAKE_CXX_COMPILER_VERSION = 4.9
-# LLVM_TARGET_ARCH = X86
-# LLVM_TARGETS_TO_BUILD = X86
-# LLVM_TABLEGEN = path to host llvm-tblgen
-# CLANG_TABLEGEN = path to host clang-tblgen
-
-if( DEFINED CMAKE_CROSSCOMPILING )
- return()
-endif()
-
-get_property( IS_IN_TRY_COMPILE GLOBAL PROPERTY IN_TRY_COMPILE )
-if( IS_IN_TRY_COMPILE )
- # this seems necessary and works fine but I'm unsure if it breaks anything
- return()
-endif()
-
-set( CMAKE_SYSTEM_NAME Android )
-include( CMakeForceCompiler )
-
-# flags and definitions
-add_definitions( -DANDROID -DLLDB_DISABLE_LIBEDIT )
-set( ANDROID True )
-set( LLDB_DEFAULT_DISABLE_LIBEDIT True )
-
-# linking lldb-server statically for Android avoids the need to ship two
-# binaries (pie for API 21+ and non-pie for API 16-). It's possible to use
-# a non-pie shim on API 16-, but that requires lldb-server to dynamically export
-# its symbols, which significantly increases the binary size. Static linking, on
-# the other hand, has little to no effect on the binary size.
-if( NOT DEFINED LLVM_BUILD_STATIC )
- set( LLVM_BUILD_STATIC True CACHE INTERNAL "" FORCE )
- set( LLVM_ENABLE_PIC FALSE CACHE INTERNAL "" FORCE )
- set( BUILD_SHARED_LIBS FALSE CACHE INTERNAL "" FORCE )
-endif()
-
-set( ANDROID_ABI "${ANDROID_ABI}" CACHE INTERNAL "Android Abi" FORCE )
-if( ANDROID_ABI STREQUAL "x86" )
- set( CMAKE_SYSTEM_PROCESSOR "i686" )
- set( ANDROID_TOOLCHAIN_NAME "i686-linux-android" )
-elseif( ANDROID_ABI STREQUAL "x86_64" )
- set( CMAKE_SYSTEM_PROCESSOR "x86_64" )
- set( ANDROID_TOOLCHAIN_NAME "x86_64-linux-android" )
-elseif( ANDROID_ABI STREQUAL "armeabi" )
- set( CMAKE_SYSTEM_PROCESSOR "armv5te" )
- set( ANDROID_TOOLCHAIN_NAME "arm-linux-androideabi" )
-elseif( ANDROID_ABI STREQUAL "aarch64" )
- set( CMAKE_SYSTEM_PROCESSOR "aarch64" )
- set( ANDROID_TOOLCHAIN_NAME "aarch64-linux-android" )
-elseif( ANDROID_ABI STREQUAL "mips" )
- set( CMAKE_SYSTEM_PROCESSOR "mips" )
- set( ANDROID_TOOLCHAIN_NAME "mipsel-linux-android" )
-elseif( ANDROID_ABI STREQUAL "mips64" )
- set( CMAKE_SYSTEM_PROCESSOR "mips64" )
- set( ANDROID_TOOLCHAIN_NAME "mips64el-linux-android" )
-else()
- message( SEND_ERROR "Unknown ANDROID_ABI = \"${ANDROID_ABI}\"." )
-endif()
-
-set( ANDROID_TOOLCHAIN_DIR "${ANDROID_TOOLCHAIN_DIR}" CACHE PATH "Android standalone toolchain directory" )
-set( ANDROID_SYSROOT "${ANDROID_TOOLCHAIN_DIR}/sysroot" CACHE PATH "Android Sysroot" )
-
-# CMAKE_EXECUTABLE_SUFFIX is undefined in CMAKE_TOOLCHAIN_FILE
-if( WIN32 )
- set( EXECUTABLE_SUFFIX ".exe" )
-endif()
-
-set( PYTHON_EXECUTABLE "${ANDROID_TOOLCHAIN_DIR}/bin/python${EXECUTABLE_SUFFIX}" CACHE PATH "Python exec path" )
-
-if( NOT CMAKE_C_COMPILER )
- set( CMAKE_C_COMPILER "${ANDROID_TOOLCHAIN_DIR}/bin/${ANDROID_TOOLCHAIN_NAME}-gcc${EXECUTABLE_SUFFIX}" CACHE PATH "C compiler" )
- set( CMAKE_CXX_COMPILER "${ANDROID_TOOLCHAIN_DIR}/bin/${ANDROID_TOOLCHAIN_NAME}-g++${EXECUTABLE_SUFFIX}" CACHE PATH "C++ compiler" )
- set( CMAKE_ASM_COMPILER "${ANDROID_TOOLCHAIN_DIR}/bin/${ANDROID_TOOLCHAIN_NAME}-gcc${EXECUTABLE_SUFFIX}" CACHE PATH "assembler" )
- set( CMAKE_STRIP "${ANDROID_TOOLCHAIN_DIR}/bin/${ANDROID_TOOLCHAIN_NAME}-strip${EXECUTABLE_SUFFIX}" CACHE PATH "strip" )
- set( CMAKE_AR "${ANDROID_TOOLCHAIN_DIR}/bin/${ANDROID_TOOLCHAIN_NAME}-ar${EXECUTABLE_SUFFIX}" CACHE PATH "archive" )
- set( CMAKE_LINKER "${ANDROID_TOOLCHAIN_DIR}/bin/${ANDROID_TOOLCHAIN_NAME}-ld${EXECUTABLE_SUFFIX}" CACHE PATH "linker" )
- set( CMAKE_NM "${ANDROID_TOOLCHAIN_DIR}/bin/${ANDROID_TOOLCHAIN_NAME}-nm${EXECUTABLE_SUFFIX}" CACHE PATH "nm" )
- set( CMAKE_OBJCOPY "${ANDROID_TOOLCHAIN_DIR}/bin/${ANDROID_TOOLCHAIN_NAME}-objcopy${EXECUTABLE_SUFFIX}" CACHE PATH "objcopy" )
- set( CMAKE_OBJDUMP "${ANDROID_TOOLCHAIN_DIR}/bin/${ANDROID_TOOLCHAIN_NAME}-objdump${EXECUTABLE_SUFFIX}" CACHE PATH "objdump" )
- set( CMAKE_RANLIB "${ANDROID_TOOLCHAIN_DIR}/bin/${ANDROID_TOOLCHAIN_NAME}-ranlib${EXECUTABLE_SUFFIX}" CACHE PATH "ranlib" )
-endif()
-
-set( ANDROID_CXX_FLAGS "--sysroot=${ANDROID_SYSROOT} -funwind-tables -fsigned-char -no-canonical-prefixes" )
-# TODO: different ARM abi have different flags such as neon, vfpv etc
-if( X86 )
- set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -funswitch-loops -finline-limit=300" )
-elseif( ANDROID_ABI STREQUAL "armeabi" )
- # 64 bit atomic operations used in c++ libraries require armv7-a instructions
- # armv5te and armv6 were tried but do not work.
- set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -march=armv7-a -mthumb" )
-elseif( ANDROID_ABI STREQUAL "mips" )
- # http://b.android.com/182094
- list( FIND LLDB_SYSTEM_LIBS atomic index )
- if( index EQUAL -1 )
- list( APPEND LLDB_SYSTEM_LIBS atomic )
- set( LLDB_SYSTEM_LIBS ${LLDB_SYSTEM_LIBS} CACHE INTERNAL "" FORCE )
- endif()
-endif()
-
-# Use gold linker and enable safe ICF in case of x86, x86_64 and arm
-if ( ANDROID_ABI STREQUAL "x86" OR
- ANDROID_ABI STREQUAL "x86_64" OR
- ANDROID_ABI STREQUAL "armeabi")
- set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} -fuse-ld=gold -Wl,--icf=safe" )
-endif()
-
-if( NOT LLVM_BUILD_STATIC )
- # PIE is required for API 21+ so we enable it if we're not statically linking
- # unfortunately, it is not supported before API 16 so we need to do something
- # else there see http://llvm.org/pr23457
- set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -pie -fPIE" )
-endif()
-
-# linker flags
-set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS} -fdata-sections -ffunction-sections" )
-set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} -Wl,--gc-sections" )
-
-# cache flags
-set( CMAKE_CXX_FLAGS "" CACHE STRING "c++ flags" )
-set( CMAKE_C_FLAGS "" CACHE STRING "c flags" )
-set( CMAKE_EXE_LINKER_FLAGS "-Wl,-z,nocopyreloc" CACHE STRING "executable linker flags" )
-set( ANDROID_CXX_FLAGS "${ANDROID_CXX_FLAGS}" CACHE INTERNAL "Android c/c++ flags" )
-set( ANDROID_LINKER_FLAGS "${ANDROID_LINKER_FLAGS}" CACHE INTERNAL "Android c/c++ linker flags" )
-
-# final flags
-set( CMAKE_CXX_FLAGS "${ANDROID_CXX_FLAGS} ${CMAKE_CXX_FLAGS}" )
-set( CMAKE_C_FLAGS "${ANDROID_CXX_FLAGS} ${CMAKE_C_FLAGS}" )
-set( CMAKE_EXE_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} ${CMAKE_EXE_LINKER_FLAGS}" )
-
-# global includes and link directories
-set( ANDROID_INCLUDE_DIRS "${ANDROID_TOOLCHAIN_DIR}/include/c++/${ANDROID_COMPILER_VERSION}" )
-list( APPEND ANDROID_INCLUDE_DIRS "${ANDROID_TOOLCHAIN_DIR}/include/python2.7" )
-include_directories( SYSTEM "${ANDROID_SYSROOT}/usr/include" ${ANDROID_INCLUDE_DIRS} )
-
-# target environment
-set( CMAKE_FIND_ROOT_PATH "${ANDROID_TOOLCHAIN_DIR}/bin" "${ANDROID_TOOLCHAIN_DIR}/${ANDROID_TOOLCHAIN_NAME}" "${ANDROID_SYSROOT}" )
-
-# only search for libraries and includes in the ndk toolchain
-set( CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY )
-set( CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY )
-set( CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY )
diff --git a/examples/python/disassembly_mode.py b/examples/python/disassembly_mode.py
new file mode 100644
index 000000000000..19647cc6555e
--- /dev/null
+++ b/examples/python/disassembly_mode.py
@@ -0,0 +1,48 @@
+""" Adds the 'toggle-disassembly' command to switch you into a disassembly only mode """
+import lldb
+
+class DisassemblyMode:
+ def __init__(self, debugger, unused):
+ self.dbg = debugger
+ self.interp = debugger.GetCommandInterpreter()
+ self.store_state()
+ self.mode_off = True
+
+ def store_state(self):
+ self.dis_count = self.get_string_value("stop-disassembly-count")
+ self.dis_display = self.get_string_value("stop-disassembly-display")
+ self.before_count = self.get_string_value("stop-line-count-before")
+ self.after_count = self.get_string_value("stop-line-count-after")
+
+ def get_string_value(self, setting):
+ result = lldb.SBCommandReturnObject()
+ self.interp.HandleCommand("settings show " + setting, result)
+ value = result.GetOutput().split(" = ")[1].rstrip("\n")
+ return value
+
+ def set_value(self, setting, value):
+ result = lldb.SBCommandReturnObject()
+ self.interp.HandleCommand("settings set " + setting + " " + value, result)
+
+ def __call__(self, debugger, command, exe_ctx, result):
+ if self.mode_off:
+ self.mode_off = False
+ self.store_state()
+ self.set_value("stop-disassembly-display","always")
+ self.set_value("stop-disassembly-count", "8")
+ self.set_value("stop-line-count-before", "0")
+ self.set_value("stop-line-count-after", "0")
+ result.AppendMessage("Disassembly mode on.")
+ else:
+ self.mode_off = True
+ self.set_value("stop-disassembly-display",self.dis_display)
+ self.set_value("stop-disassembly-count", self.dis_count)
+ self.set_value("stop-line-count-before", self.before_count)
+ self.set_value("stop-line-count-after", self.after_count)
+ result.AppendMessage("Disassembly mode off.")
+
+ def get_short_help(self):
+ return "Toggles between a disassembly only mode and normal source mode\n"
+
+def __lldb_init_module(debugger, unused):
+ debugger.HandleCommand("command script add -c disassembly_mode.DisassemblyMode toggle-disassembly")
diff --git a/include/lldb/API/LLDB.h b/include/lldb/API/LLDB.h
index d8604cd07114..cf61b10184d6 100644
--- a/include/lldb/API/LLDB.h
+++ b/include/lldb/API/LLDB.h
@@ -63,6 +63,8 @@
#include "lldb/API/SBThread.h"
#include "lldb/API/SBThreadCollection.h"
#include "lldb/API/SBThreadPlan.h"
+#include "lldb/API/SBTrace.h"
+#include "lldb/API/SBTraceOptions.h"
#include "lldb/API/SBType.h"
#include "lldb/API/SBTypeCategory.h"
#include "lldb/API/SBTypeEnumMember.h"
diff --git a/include/lldb/API/SBDefines.h b/include/lldb/API/SBDefines.h
index 25443c4761af..d70e912d9200 100644
--- a/include/lldb/API/SBDefines.h
+++ b/include/lldb/API/SBDefines.h
@@ -79,6 +79,8 @@ class LLDB_API SBTarget;
class LLDB_API SBThread;
class LLDB_API SBThreadCollection;
class LLDB_API SBThreadPlan;
+class LLDB_API SBTrace;
+class LLDB_API SBTraceOptions;
class LLDB_API SBType;
class LLDB_API SBTypeCategory;
class LLDB_API SBTypeEnumMember;
diff --git a/include/lldb/API/SBError.h b/include/lldb/API/SBError.h
index 7f2f3a6cc5ec..a3b1f87053ad 100644
--- a/include/lldb/API/SBError.h
+++ b/include/lldb/API/SBError.h
@@ -61,6 +61,7 @@ protected:
friend class SBProcess;
friend class SBStructuredData;
friend class SBThread;
+ friend class SBTrace;
friend class SBTarget;
friend class SBValue;
friend class SBWatchpoint;
diff --git a/include/lldb/API/SBProcess.h b/include/lldb/API/SBProcess.h
index fd95790c6686..0ee3a989d1b6 100644
--- a/include/lldb/API/SBProcess.h
+++ b/include/lldb/API/SBProcess.h
@@ -234,6 +234,33 @@ public:
bool GetDescription(lldb::SBStream &description);
+ //------------------------------------------------------------------
+ /// Start Tracing with the given SBTraceOptions.
+ ///
+ /// @param[in] options
+ /// Class containing trace options like trace buffer size, meta
+ /// data buffer size, TraceType and any custom parameters
+ /// {formatted as a JSON Dictionary}. In case of errors in
+ /// formatting, an error would be reported.
+ /// It must be noted that tracing options such as buffer sizes
+ /// or other custom parameters passed maybe invalid for some
+ /// trace technologies. In such cases the trace implementations
+ /// could choose to either throw an error or could round off to
+ /// the nearest valid options to start tracing if the passed
+ /// value is not supported. To obtain the actual used trace
+ /// options please use the GetTraceConfig API. For the custom
+ /// parameters, only the parameters recognized by the target
+ /// would be used and others would be ignored.
+ ///
+ /// @param[out] error
+ /// An error explaining what went wrong.
+ ///
+ /// @return
+ /// A SBTrace instance, which should be used
+ /// to get the trace data or other trace related operations.
+ //------------------------------------------------------------------
+ lldb::SBTrace StartTrace(SBTraceOptions &options, lldb::SBError &error);
+
uint32_t GetNumSupportedHardwareWatchpoints(lldb::SBError &error) const;
//------------------------------------------------------------------
diff --git a/include/lldb/API/SBStructuredData.h b/include/lldb/API/SBStructuredData.h
index 9f0203bb245a..5fb5d3be65ad 100644
--- a/include/lldb/API/SBStructuredData.h
+++ b/include/lldb/API/SBStructuredData.h
@@ -13,8 +13,6 @@
#include "lldb/API/SBDefines.h"
#include "lldb/API/SBModule.h"
-class StructuredDataImpl;
-
namespace lldb {
class SBStructuredData {
@@ -31,14 +29,18 @@ public:
bool IsValid() const;
+ lldb::SBError SetFromJSON(lldb::SBStream &stream);
+
void Clear();
lldb::SBError GetAsJSON(lldb::SBStream &stream) const;
lldb::SBError GetDescription(lldb::SBStream &stream) const;
-private:
- std::unique_ptr<StructuredDataImpl> m_impl_up;
+protected:
+ friend class SBTraceOptions;
+
+ StructuredDataImplUP m_impl_up;
};
}
diff --git a/include/lldb/API/SBTrace.h b/include/lldb/API/SBTrace.h
new file mode 100644
index 000000000000..e29a5db7cc46
--- /dev/null
+++ b/include/lldb/API/SBTrace.h
@@ -0,0 +1,122 @@
+//===-- SBTrace.h -----------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SBTrace_h_
+#define LLDB_SBTrace_h_
+
+#include "lldb/API/SBDefines.h"
+#include "lldb/API/SBError.h"
+
+class TraceImpl;
+
+namespace lldb {
+
+class LLDB_API SBTrace {
+public:
+ SBTrace();
+ //------------------------------------------------------------------
+ /// Obtain the trace data as raw bytes.
+ ///
+ /// @param[out] error
+ /// An error explaining what went wrong.
+ ///
+ /// @param[in] buf
+ /// Buffer to write the trace data to.
+ ///
+ /// @param[in] size
+ /// The size of the buffer used to read the data. This is
+ /// also the size of the data intended to read. It is also
+ /// possible to partially read the trace data for some trace
+ /// technologies by specifying a smaller buffer.
+ ///
+ /// @param[in] offset
+ /// The start offset to begin reading the trace data.
+ ///
+ /// @param[in] thread_id
+ /// Tracing could be started for the complete process or a
+ /// single thread, in the first case the uid obtained would
+ /// map to all the threads existing within the process and the
+ /// ones spawning later. The thread_id parameter can be used in
+ /// such a scenario to select the trace data for a specific
+ /// thread.
+ ///
+ /// @return
+ /// The size of the trace data effectively read by the API call.
+ //------------------------------------------------------------------
+ size_t GetTraceData(SBError &error, void *buf, size_t size, size_t offset = 0,
+ lldb::tid_t thread_id = LLDB_INVALID_THREAD_ID);
+
+ //------------------------------------------------------------------
+ /// Obtain any meta data as raw bytes for the tracing instance.
+ /// The input parameter definition is similar to the previous
+ /// function.
+ //------------------------------------------------------------------
+ size_t GetMetaData(SBError &error, void *buf, size_t size, size_t offset = 0,
+ lldb::tid_t thread_id = LLDB_INVALID_THREAD_ID);
+
+ //------------------------------------------------------------------
+ /// Stop the tracing instance. Stopping the trace will also
+ /// lead to deletion of any gathered trace data.
+ ///
+ /// @param[out] error
+ /// An error explaining what went wrong.
+ ///
+ /// @param[in] thread_id
+ /// The user id could map to a tracing instance for a thread
+ /// or could also map to a group of threads being traced with
+ /// the same trace options. A thread_id is normally optional
+ /// except in the case of tracing a complete process and tracing
+ /// needs to switched off on a particular thread.
+ /// A situation could occur where initially a thread (lets say
+ /// thread A) is being individually traced with a particular uid
+ /// and then tracing is started on the complete process, in this
+ /// case thread A will continue without any change. All newly
+ /// spawned threads would be traced with the uid of the process.
+ /// Now if the StopTrace API is called for the whole process,
+ /// thread A will not be stopped and must be stopped separately.
+ //------------------------------------------------------------------
+ void StopTrace(SBError &error,
+ lldb::tid_t thread_id = LLDB_INVALID_THREAD_ID);
+
+ //------------------------------------------------------------------
+ /// Get the trace configuration being used for the trace instance.
+ /// The threadid in the SBTraceOptions needs to be set when the
+ /// configuration used by a specific thread is being requested.
+ ///
+ /// @param[out] options
+ /// The trace options actually used by the trace instance
+ /// would be filled by the API.
+ ///
+ /// @param[out] error
+ /// An error explaining what went wrong.
+ //------------------------------------------------------------------
+ void GetTraceConfig(SBTraceOptions &options, SBError &error);
+
+ lldb::user_id_t GetTraceUID();
+
+ bool IsValid();
+
+protected:
+ typedef std::shared_ptr<TraceImpl> TraceImplSP;
+
+ friend class SBProcess;
+
+ void SetTraceUID(lldb::user_id_t uid);
+
+ TraceImplSP m_trace_impl_sp;
+
+ lldb::ProcessSP GetSP() const;
+
+ void SetSP(const ProcessSP &process_sp);
+
+ lldb::ProcessWP m_opaque_wp;
+};
+} // namespace lldb
+
+#endif // LLDB_SBTrace_h_
diff --git a/include/lldb/API/SBTraceOptions.h b/include/lldb/API/SBTraceOptions.h
new file mode 100644
index 000000000000..c9735e1ca246
--- /dev/null
+++ b/include/lldb/API/SBTraceOptions.h
@@ -0,0 +1,58 @@
+//===-- SBTraceOptions ------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SBTRACEOPTIONS_H_
+#define SBTRACEOPTIONS_H_
+
+#include "lldb/API/SBDefines.h"
+
+namespace lldb {
+
+class LLDB_API SBTraceOptions {
+public:
+ SBTraceOptions();
+
+ lldb::TraceType getType() const;
+
+ uint64_t getTraceBufferSize() const;
+
+ /// The trace parameters consist of any custom parameters
+ /// apart from the generic parameters such as
+ /// TraceType, trace_buffer_size and meta_data_buffer_size.
+ /// The returned parameters would be formatted as a JSON Dictionary.
+ lldb::SBStructuredData getTraceParams(lldb::SBError &error);
+
+ uint64_t getMetaDataBufferSize() const;
+
+ /// SBStructuredData is meant to hold any custom parameters
+ /// apart from meta buffer size and trace size. They should
+ /// be formatted as a JSON Dictionary.
+ void setTraceParams(lldb::SBStructuredData &params);
+
+ void setType(lldb::TraceType type);
+
+ void setTraceBufferSize(uint64_t size);
+
+ void setMetaDataBufferSize(uint64_t size);
+
+ void setThreadID(lldb::tid_t thread_id);
+
+ lldb::tid_t getThreadID();
+
+ bool IsValid();
+
+protected:
+ friend class SBProcess;
+ friend class SBTrace;
+
+ lldb::TraceOptionsSP m_traceoptions_sp;
+};
+}
+
+#endif /* SBTRACEOPTIONS_H_ */
diff --git a/include/lldb/Core/StructuredDataImpl.h b/include/lldb/Core/StructuredDataImpl.h
new file mode 100644
index 000000000000..94f9cce52548
--- /dev/null
+++ b/include/lldb/Core/StructuredDataImpl.h
@@ -0,0 +1,95 @@
+//===-- StructuredDataImpl.h ------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_StructuredDataImpl_h_
+#define liblldb_StructuredDataImpl_h_
+
+#include "lldb/Core/Event.h"
+#include "lldb/Core/StructuredData.h"
+#include "lldb/Utility/Error.h"
+#include "lldb/Utility/Stream.h"
+#include "lldb/Target/StructuredDataPlugin.h"
+#include "lldb/lldb-forward.h"
+
+#pragma mark--
+#pragma mark StructuredDataImpl
+
+namespace lldb_private {
+
+class StructuredDataImpl {
+public:
+ StructuredDataImpl() : m_plugin_wp(), m_data_sp() {}
+
+ StructuredDataImpl(const StructuredDataImpl &rhs) = default;
+
+ StructuredDataImpl(const lldb::EventSP &event_sp)
+ : m_plugin_wp(
+ EventDataStructuredData::GetPluginFromEvent(event_sp.get())),
+ m_data_sp(EventDataStructuredData::GetObjectFromEvent(event_sp.get())) {
+ }
+
+ ~StructuredDataImpl() = default;
+
+ StructuredDataImpl &operator=(const StructuredDataImpl &rhs) = default;
+
+ bool IsValid() const { return m_data_sp.get() != nullptr; }
+
+ void Clear() {
+ m_plugin_wp.reset();
+ m_data_sp.reset();
+ }
+
+ Error GetAsJSON(Stream &stream) const {
+ Error error;
+
+ if (!m_data_sp) {
+ error.SetErrorString("No structured data.");
+ return error;
+ }
+
+ m_data_sp->Dump(stream);
+ return error;
+ }
+
+ Error GetDescription(Stream &stream) const {
+ Error error;
+
+ if (!m_data_sp) {
+ error.SetErrorString("Cannot pretty print structured data: "
+ "no data to print.");
+ return error;
+ }
+
+ // Grab the plugin.
+ auto plugin_sp = lldb::StructuredDataPluginSP(m_plugin_wp);
+ if (!plugin_sp) {
+ error.SetErrorString("Cannot pretty print structured data: "
+ "plugin doesn't exist.");
+ return error;
+ }
+
+ // Get the data's description.
+ return plugin_sp->GetDescription(m_data_sp, stream);
+ }
+
+ StructuredData::ObjectSP GetObjectSP() {
+ return m_data_sp;
+ }
+
+ void SetObjectSP(const StructuredData::ObjectSP &obj) {
+ m_data_sp = obj;
+ }
+
+private:
+
+ lldb::StructuredDataPluginWP m_plugin_wp;
+ StructuredData::ObjectSP m_data_sp;
+};
+}
+#endif
diff --git a/include/lldb/Core/TraceOptions.h b/include/lldb/Core/TraceOptions.h
new file mode 100644
index 000000000000..ffa2bae7f659
--- /dev/null
+++ b/include/lldb/Core/TraceOptions.h
@@ -0,0 +1,62 @@
+//===-- TraceOptions.h ------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_TraceOptions_h_
+#define liblldb_TraceOptions_h_
+
+#include "lldb/lldb-defines.h"
+#include "lldb/lldb-enumerations.h"
+
+#include "lldb/Core/StructuredData.h"
+
+namespace lldb_private {
+class TraceOptions {
+public:
+ TraceOptions()
+ : m_trace_params(new StructuredData::Dictionary()) {}
+
+ const StructuredData::DictionarySP &getTraceParams() const {
+ return m_trace_params;
+ }
+
+ lldb::TraceType getType() const { return m_type; }
+
+ uint64_t getTraceBufferSize() const { return m_trace_buffer_size; }
+
+ uint64_t getMetaDataBufferSize() const { return m_meta_data_buffer_size; }
+
+ void setTraceParams(const StructuredData::DictionarySP &dict_obj) {
+ m_trace_params = dict_obj;
+ }
+
+ void setType(lldb::TraceType type) { m_type = type; }
+
+ void setTraceBufferSize(uint64_t size) { m_trace_buffer_size = size; }
+
+ void setMetaDataBufferSize(uint64_t size) { m_meta_data_buffer_size = size; }
+
+ void setThreadID(lldb::tid_t thread_id) { m_thread_id = thread_id; }
+
+ lldb::tid_t getThreadID() { return m_thread_id; }
+
+private:
+ lldb::TraceType m_type;
+ uint64_t m_trace_buffer_size;
+ uint64_t m_meta_data_buffer_size;
+ lldb::tid_t m_thread_id;
+
+ /// m_trace_params is meant to hold any custom parameters
+ /// apart from meta buffer size and trace size.
+ /// The interpretation of such parameters is left to
+ /// the lldb-server.
+ StructuredData::DictionarySP m_trace_params;
+};
+}
+
+#endif // liblldb_TraceOptions_h_ \ No newline at end of file
diff --git a/include/lldb/Core/ValueObject.h b/include/lldb/Core/ValueObject.h
index 1c923f317b7c..0898754b211a 100644
--- a/include/lldb/Core/ValueObject.h
+++ b/include/lldb/Core/ValueObject.h
@@ -27,6 +27,7 @@
#include "lldb/lldb-private-enumerations.h" // for AddressType
#include "lldb/lldb-types.h" // for addr_t, offs...
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h" // for StringRef
@@ -37,7 +38,6 @@
#include <mutex> // for recursive_mutex
#include <string> // for string
#include <utility> // for pair
-#include <vector>
#include <stddef.h> // for size_t
#include <stdint.h> // for uint32_t
@@ -489,35 +489,19 @@ public:
virtual lldb::ValueObjectSP GetChildAtIndex(size_t idx, bool can_create);
// this will always create the children if necessary
- lldb::ValueObjectSP
- GetChildAtIndexPath(const std::initializer_list<size_t> &idxs,
- size_t *index_of_error = nullptr);
-
- lldb::ValueObjectSP GetChildAtIndexPath(const std::vector<size_t> &idxs,
+ lldb::ValueObjectSP GetChildAtIndexPath(llvm::ArrayRef<size_t> idxs,
size_t *index_of_error = nullptr);
- lldb::ValueObjectSP GetChildAtIndexPath(
- const std::initializer_list<std::pair<size_t, bool>> &idxs,
- size_t *index_of_error = nullptr);
-
lldb::ValueObjectSP
- GetChildAtIndexPath(const std::vector<std::pair<size_t, bool>> &idxs,
+ GetChildAtIndexPath(llvm::ArrayRef<std::pair<size_t, bool>> idxs,
size_t *index_of_error = nullptr);
// this will always create the children if necessary
- lldb::ValueObjectSP
- GetChildAtNamePath(const std::initializer_list<ConstString> &names,
- ConstString *name_of_error = nullptr);
-
- lldb::ValueObjectSP GetChildAtNamePath(const std::vector<ConstString> &names,
+ lldb::ValueObjectSP GetChildAtNamePath(llvm::ArrayRef<ConstString> names,
ConstString *name_of_error = nullptr);
- lldb::ValueObjectSP GetChildAtNamePath(
- const std::initializer_list<std::pair<ConstString, bool>> &names,
- ConstString *name_of_error = nullptr);
-
lldb::ValueObjectSP
- GetChildAtNamePath(const std::vector<std::pair<ConstString, bool>> &names,
+ GetChildAtNamePath(llvm::ArrayRef<std::pair<ConstString, bool>> names,
ConstString *name_of_error = nullptr);
virtual lldb::ValueObjectSP GetChildMemberWithName(const ConstString &name,
diff --git a/include/lldb/Host/SocketAddress.h b/include/lldb/Host/SocketAddress.h
index bc66ad915bbe..8e9026ba962c 100644
--- a/include/lldb/Host/SocketAddress.h
+++ b/include/lldb/Host/SocketAddress.h
@@ -41,8 +41,9 @@ public:
//----------------------------------------------------------------------------
// Static method to get all address information for a host and/or service
//----------------------------------------------------------------------------
- static std::vector<SocketAddress> GetAddressInfo(const char *hostname,
- const char *servname);
+ static std::vector<SocketAddress>
+ GetAddressInfo(const char *hostname, const char *servname, int ai_family,
+ int ai_socktype, int ai_protocol, int ai_flags = 0);
//------------------------------------------------------------------
// Constructors and Destructors
diff --git a/include/lldb/Target/Process.h b/include/lldb/Target/Process.h
index 56bbbfd53fdd..9a749efa7ae1 100644
--- a/include/lldb/Target/Process.h
+++ b/include/lldb/Target/Process.h
@@ -36,6 +36,7 @@
#include "lldb/Core/PluginInterface.h"
#include "lldb/Core/StructuredData.h"
#include "lldb/Core/ThreadSafeValue.h"
+#include "lldb/Core/TraceOptions.h"
#include "lldb/Core/UserSettingsController.h"
#include "lldb/Host/HostThread.h"
#include "lldb/Host/ProcessRunLock.h"
@@ -2766,6 +2767,79 @@ public:
lldb::StructuredDataPluginSP
GetStructuredDataPlugin(const ConstString &type_name) const;
+ //------------------------------------------------------------------
+ /// Starts tracing with the configuration provided in options. To
+ /// enable tracing on the complete process the thread_id in the
+ /// options should be set to LLDB_INVALID_THREAD_ID. The API returns
+ /// a user_id which is needed by other API's that manipulate the
+ /// trace instance.
+ /// The handling of erroneous or unsupported configuration is left
+ /// to the trace technology implementations in the server, as they
+ /// could be returned as an error, or rounded to a valid
+ /// configuration to start tracing. In the later case the
+ /// GetTraceConfig should supply the actual used trace
+ /// configuration.
+ //------------------------------------------------------------------
+ virtual lldb::user_id_t StartTrace(lldb::TraceOptionsSP &options,
+ Error &error) {
+ error.SetErrorString("Not implemented");
+ return LLDB_INVALID_UID;
+ }
+
+ //------------------------------------------------------------------
+ /// Stops the tracing instance leading to deletion of the trace
+ /// data. The tracing instance is identified by the user_id which
+ /// is obtained when tracing was started from the StartTrace.
+ /// In case tracing of the complete process needs to be stopped
+ /// the thread_id should be set to LLDB_INVALID_THREAD_ID.
+ /// In the other case that tracing on an individual thread needs
+ /// to be stopped a thread_id can be supplied.
+ //------------------------------------------------------------------
+ virtual void StopTrace(lldb::user_id_t uid, lldb::tid_t thread_id,
+ Error &error) {
+ error.SetErrorString("Not implemented");
+ }
+
+ //------------------------------------------------------------------
+ /// Provides the trace data as raw bytes. A buffer needs to be
+ /// supplied to copy the trace data. The exact behavior of this API
+ /// may vary across trace technology, as some may support partial
+ /// reading of the trace data from a specified offset while some
+ /// may not. The thread_id should be used to select a particular
+ /// thread for trace extraction.
+ //------------------------------------------------------------------
+ virtual size_t GetData(lldb::user_id_t uid, lldb::tid_t thread_id,
+ Error &error, void *buf, size_t size,
+ size_t offset = 0) {
+ error.SetErrorString("Not implemented");
+ return 0;
+ }
+
+ //------------------------------------------------------------------
+ /// Similar API as above except for obtaining meta data
+ //------------------------------------------------------------------
+ virtual size_t GetMetaData(lldb::user_id_t uid, lldb::tid_t thread_id,
+ Error &error, void *buf, size_t size,
+ size_t offset = 0) {
+ error.SetErrorString("Not implemented");
+ return 0;
+ }
+
+ //------------------------------------------------------------------
+ /// API to obtain the trace configuration used by a trace instance.
+ /// Configurations that may be specific to some trace technology
+ /// should be stored in the custom parameters. The options are
+ /// transported to the server, which shall interpret accordingly.
+ /// The thread_id can be specified in the options to obtain the
+ /// configuration used by a specific thread. The thread_id specified
+ /// should also match the uid otherwise an error will be returned.
+ //------------------------------------------------------------------
+ virtual void GetTraceConfig(lldb::user_id_t uid, Error &error,
+ lldb::TraceOptionsSP &options) {
+ error.SetErrorString("Not implemented");
+ return;
+ }
+
protected:
void SetState(lldb::EventSP &event_sp);
diff --git a/include/lldb/lldb-enumerations.h b/include/lldb/lldb-enumerations.h
index cf42828e2d5a..ad10bbba1a57 100644
--- a/include/lldb/lldb-enumerations.h
+++ b/include/lldb/lldb-enumerations.h
@@ -718,6 +718,13 @@ enum BasicType {
eBasicTypeOther
};
+enum TraceType {
+ eTraceTypeNone = 0,
+
+ // Hardware Trace generated by the processor.
+ eTraceTypeProcessorTrace
+};
+
FLAGS_ENUM(TypeClass){
eTypeClassInvalid = (0u), eTypeClassArray = (1u << 0),
eTypeClassBlockPointer = (1u << 1), eTypeClassBuiltin = (1u << 2),
diff --git a/include/lldb/lldb-forward.h b/include/lldb/lldb-forward.h
index 0970d691d802..2180b31527e0 100644
--- a/include/lldb/lldb-forward.h
+++ b/include/lldb/lldb-forward.h
@@ -215,6 +215,7 @@ class StreamFile;
class StreamString;
class StringList;
struct StringSummaryFormat;
+class StructuredDataImpl;
class StructuredDataPlugin;
class SystemRuntime;
class TypeSummaryImpl;
@@ -254,6 +255,7 @@ class ThreadPlanStepRange;
class ThreadPlanStepThrough;
class ThreadPlanTracer;
class ThreadSpec;
+class TraceOptions;
class Type;
class TypeAndOrName;
class TypeCategoryMap;
@@ -430,6 +432,7 @@ typedef std::weak_ptr<lldb_private::Stream> StreamWP;
typedef std::shared_ptr<lldb_private::StreamFile> StreamFileSP;
typedef std::shared_ptr<lldb_private::StringSummaryFormat>
StringTypeSummaryImplSP;
+typedef std::unique_ptr<lldb_private::StructuredDataImpl> StructuredDataImplUP;
typedef std::shared_ptr<lldb_private::StructuredDataPlugin>
StructuredDataPluginSP;
typedef std::weak_ptr<lldb_private::StructuredDataPlugin>
@@ -451,6 +454,7 @@ typedef std::weak_ptr<lldb_private::Thread> ThreadWP;
typedef std::shared_ptr<lldb_private::ThreadCollection> ThreadCollectionSP;
typedef std::shared_ptr<lldb_private::ThreadPlan> ThreadPlanSP;
typedef std::shared_ptr<lldb_private::ThreadPlanTracer> ThreadPlanTracerSP;
+typedef std::shared_ptr<lldb_private::TraceOptions> TraceOptionsSP;
typedef std::shared_ptr<lldb_private::Type> TypeSP;
typedef std::weak_ptr<lldb_private::Type> TypeWP;
typedef std::shared_ptr<lldb_private::TypeCategoryImpl> TypeCategoryImplSP;
diff --git a/packages/Python/lldbsuite/test/functionalities/unwind/noreturn/TestNoreturnUnwind.py b/packages/Python/lldbsuite/test/functionalities/unwind/noreturn/TestNoreturnUnwind.py
index 3998b9d8ab54..eafe62a0e08f 100644
--- a/packages/Python/lldbsuite/test/functionalities/unwind/noreturn/TestNoreturnUnwind.py
+++ b/packages/Python/lldbsuite/test/functionalities/unwind/noreturn/TestNoreturnUnwind.py
@@ -17,7 +17,7 @@ class NoreturnUnwind(TestBase):
mydir = TestBase.compute_mydir(__file__)
@skipIfWindows # clang-cl does not support gcc style attributes.
- @expectedFailureAndroid(bugnumber="llvm.org/pr31192", archs=["x86_64"])
+ @expectedFailureAndroid(bugnumber="llvm.org/pr31192")
@expectedFailureAll(bugnumber="llvm.org/pr31192", oslist=['linux'], compiler="gcc", archs=['arm'])
def test(self):
"""Test that we can backtrace correctly with 'noreturn' functions on the stack"""
diff --git a/packages/Python/lldbsuite/test/functionalities/watchpoint/step_over_watchpoint/TestStepOverWatchpoint.py b/packages/Python/lldbsuite/test/functionalities/watchpoint/step_over_watchpoint/TestStepOverWatchpoint.py
index f1d7acfcc5ec..15657708ce46 100644
--- a/packages/Python/lldbsuite/test/functionalities/watchpoint/step_over_watchpoint/TestStepOverWatchpoint.py
+++ b/packages/Python/lldbsuite/test/functionalities/watchpoint/step_over_watchpoint/TestStepOverWatchpoint.py
@@ -89,7 +89,7 @@ class TestStepOverWatchpoint(TestBase):
# resolve_location=True, read=False, write=True
write_watchpoint = write_value.Watch(True, False, True, error)
- self.assertTrue(read_watchpoint, "Failed to set write watchpoint.")
+ self.assertTrue(write_watchpoint, "Failed to set write watchpoint.")
self.assertTrue(error.Success(),
"Error while setting watchpoint: %s" %
error.GetCString())
diff --git a/packages/Python/lldbsuite/test/lang/c/inlines/main.c b/packages/Python/lldbsuite/test/lang/c/inlines/main.c
index e9bd894bf726..f45e4e2b1497 100644
--- a/packages/Python/lldbsuite/test/lang/c/inlines/main.c
+++ b/packages/Python/lldbsuite/test/lang/c/inlines/main.c
@@ -5,6 +5,11 @@ inline void test2(int) __attribute__ ((always_inline));
void test2(int b) {
printf("test2(%d)\n", b); //% self.expect("expression b", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["42"])
+ {
+ int c = b * 2;
+ printf("c=%d\n", c); //% self.expect("expression b", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["42"])
+ //% self.expect("expression c", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["84"])
+ }
}
void test1(int a) {
diff --git a/packages/Python/lldbsuite/test/lang/cpp/class_static/TestStaticVariables.py b/packages/Python/lldbsuite/test/lang/cpp/class_static/TestStaticVariables.py
index 0100a2727b38..d167f0a5591d 100644
--- a/packages/Python/lldbsuite/test/lang/cpp/class_static/TestStaticVariables.py
+++ b/packages/Python/lldbsuite/test/lang/cpp/class_static/TestStaticVariables.py
@@ -61,7 +61,7 @@ class StaticVariableTestCase(TestBase):
bugnumber="Compiler emits incomplete debug info")
@expectedFailureAll(
compiler=["clang"],
- compiler_version=["<", "3.8"],
+ compiler_version=["<", "3.9"],
bugnumber='llvm.org/pr20550')
@add_test_categories(['pyapi'])
def test_with_python_api(self):
diff --git a/packages/Python/lldbsuite/test/lang/cpp/llvm-style/Makefile b/packages/Python/lldbsuite/test/lang/cpp/llvm-style/Makefile
new file mode 100644
index 000000000000..aae93a20b9c8
--- /dev/null
+++ b/packages/Python/lldbsuite/test/lang/cpp/llvm-style/Makefile
@@ -0,0 +1,3 @@
+LEVEL = ../../../make
+CXX_SOURCES := main.cpp
+include $(LEVEL)/Makefile.rules \ No newline at end of file
diff --git a/packages/Python/lldbsuite/test/lang/cpp/llvm-style/TestLLVMStyle.py b/packages/Python/lldbsuite/test/lang/cpp/llvm-style/TestLLVMStyle.py
new file mode 100644
index 000000000000..8e83a3ab1a4a
--- /dev/null
+++ b/packages/Python/lldbsuite/test/lang/cpp/llvm-style/TestLLVMStyle.py
@@ -0,0 +1,7 @@
+from lldbsuite.test import lldbinline
+from lldbsuite.test import decorators
+
+lldbinline.MakeInlineTest(
+ __file__, globals(), [
+ decorators.expectedFailureAll(
+ oslist=["windows"], bugnumber="llvm.org/pr24764")]) \ No newline at end of file
diff --git a/packages/Python/lldbsuite/test/lang/cpp/llvm-style/main.cpp b/packages/Python/lldbsuite/test/lang/cpp/llvm-style/main.cpp
new file mode 100644
index 000000000000..21ce8ca7080c
--- /dev/null
+++ b/packages/Python/lldbsuite/test/lang/cpp/llvm-style/main.cpp
@@ -0,0 +1,36 @@
+//===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LIDENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+namespace n {
+ struct D {
+ int i;
+ static int anInt() { return 2; }
+ int dump() { return i; }
+ };
+
+ class C {
+ public:
+ int foo(D *D);
+ };
+}
+
+using namespace n;
+
+int C::foo(D* D) {
+ return D->dump(); //% self.expect("expression -- D->dump()", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["int", "2"])
+ //% self.expect("expression -- D::anInt()", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["int", "2"])
+
+}
+
+int main (int argc, char const *argv[])
+{
+ D myD { D::anInt() };
+ C().foo(&myD);
+ return 0;
+}
diff --git a/packages/Python/lldbsuite/test/lang/cpp/nsimport/TestCppNsImport.py b/packages/Python/lldbsuite/test/lang/cpp/nsimport/TestCppNsImport.py
index 878cc4fd4f76..fb7fadffa783 100644
--- a/packages/Python/lldbsuite/test/lang/cpp/nsimport/TestCppNsImport.py
+++ b/packages/Python/lldbsuite/test/lang/cpp/nsimport/TestCppNsImport.py
@@ -111,8 +111,8 @@ class TestCppNsImport(TestBase):
test_result = frame.EvaluateExpression("imported")
self.assertTrue(
- test_result.IsValid() and test_result.GetError().Fail(),
- "imported is ambiguous")
+ test_result.IsValid() and test_result.GetValueAsSigned() == 99,
+ "imported = 99")
test_result = frame.EvaluateExpression("single")
self.assertTrue(
diff --git a/packages/Python/lldbsuite/test/lang/cpp/symbols/Makefile b/packages/Python/lldbsuite/test/lang/cpp/symbols/Makefile
new file mode 100644
index 000000000000..99bfa7e03b47
--- /dev/null
+++ b/packages/Python/lldbsuite/test/lang/cpp/symbols/Makefile
@@ -0,0 +1,3 @@
+LEVEL = ../../../make
+CXX_SOURCES := main.cpp
+include $(LEVEL)/Makefile.rules
diff --git a/packages/Python/lldbsuite/test/lang/cpp/symbols/TestSymbols.py b/packages/Python/lldbsuite/test/lang/cpp/symbols/TestSymbols.py
new file mode 100644
index 000000000000..af362f5be5d7
--- /dev/null
+++ b/packages/Python/lldbsuite/test/lang/cpp/symbols/TestSymbols.py
@@ -0,0 +1,7 @@
+from lldbsuite.test import lldbinline
+from lldbsuite.test import decorators
+
+lldbinline.MakeInlineTest(
+ __file__, globals(), [
+ decorators.expectedFailureAll(
+ oslist=["windows"], bugnumber="llvm.org/pr24764")])
diff --git a/packages/Python/lldbsuite/test/lang/cpp/symbols/main.cpp b/packages/Python/lldbsuite/test/lang/cpp/symbols/main.cpp
new file mode 100644
index 000000000000..292f9f64bcca
--- /dev/null
+++ b/packages/Python/lldbsuite/test/lang/cpp/symbols/main.cpp
@@ -0,0 +1,40 @@
+//===-- main.cpp ------------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LIDENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+void *D = 0;
+
+class D {
+ static int i;
+};
+
+int D::i = 3;
+
+namespace errno {
+ int j = 4;
+};
+
+int twice(int n)
+{
+ return n * 2; //% self.expect("expression -- D::i", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["int", "3"])
+ //% self.expect("expression -- D", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["void"])
+ //% self.expect("expression -- errno::j", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["int", "4"])
+}
+
+const char getAChar()
+{
+ const char D[] = "Hello world";
+ return D[0]; //% self.expect("expression -- D::i", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["int", "3"])
+ //% self.expect("expression -- D", DATA_TYPES_DISPLAYED_CORRECTLY, substrs = ["char", "Hello"])
+}
+
+int main (int argc, char const *argv[])
+{
+ int six = twice(3);
+ return 0;
+}
diff --git a/scripts/interface/SBProcess.i b/scripts/interface/SBProcess.i
index b5e12a086fe4..527442e274ec 100644
--- a/scripts/interface/SBProcess.i
+++ b/scripts/interface/SBProcess.i
@@ -408,6 +408,9 @@ public:
lldb::SBError
SaveCore(const char *file_name);
+ lldb::SBTrace
+ StartTrace(SBTraceOptions &options, lldb::SBError &error);
+
lldb::SBError
GetMemoryRegionInfo(lldb::addr_t load_addr, lldb::SBMemoryRegionInfo &region_info);
diff --git a/scripts/interface/SBStructuredData.i b/scripts/interface/SBStructuredData.i
index 225b088c4337..1c55bacd31be 100644
--- a/scripts/interface/SBStructuredData.i
+++ b/scripts/interface/SBStructuredData.i
@@ -38,5 +38,8 @@ namespace lldb {
lldb::SBError
GetDescription(lldb::SBStream &stream) const;
+
+ lldb::SBError
+ SetFromJSON(lldb::SBStream &stream);
};
}
diff --git a/scripts/interface/SBTrace.i b/scripts/interface/SBTrace.i
new file mode 100644
index 000000000000..799fd717c21d
--- /dev/null
+++ b/scripts/interface/SBTrace.i
@@ -0,0 +1,34 @@
+//===-- SWIG Interface for SBTrace.h ----------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+namespace lldb {
+
+class LLDB_API SBTrace {
+public:
+ SBTrace();
+ size_t GetTraceData(SBError &error, void *buf,
+ size_t size, size_t offset,
+ lldb::tid_t thread_id);
+
+ size_t GetMetaData(SBError &error, void *buf,
+ size_t size, size_t offset,
+ lldb::tid_t thread_id);
+
+ void StopTrace(SBError &error,
+ lldb::tid_t thread_id);
+
+ void GetTraceConfig(SBTraceOptions &options,
+ SBError &error);
+
+ lldb::user_id_t GetTraceUID();
+
+ bool IsValid();
+
+};
+} // namespace lldb \ No newline at end of file
diff --git a/scripts/interface/SBTraceOptions.i b/scripts/interface/SBTraceOptions.i
new file mode 100644
index 000000000000..2fe6590842e3
--- /dev/null
+++ b/scripts/interface/SBTraceOptions.i
@@ -0,0 +1,38 @@
+//===-- SWIG Interface for SBTraceOptions -----------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+namespace lldb {
+
+class LLDB_API SBTraceOptions {
+public:
+ SBTraceOptions();
+
+ lldb::TraceType getType() const;
+
+ uint64_t getTraceBufferSize() const;
+
+ lldb::SBStructuredData getTraceParams(lldb::SBError &error);
+
+ uint64_t getMetaDataBufferSize() const;
+
+ void setTraceParams(lldb::SBStructuredData &params);
+
+ void setType(lldb::TraceType type);
+
+ void setTraceBufferSize(uint64_t size);
+
+ void setMetaDataBufferSize(uint64_t size);
+
+ void setThreadID(lldb::tid_t thread_id);
+
+ lldb::tid_t getThreadID();
+
+ bool IsValid();
+};
+}
diff --git a/scripts/lldb.swig b/scripts/lldb.swig
index e81fabb19fb8..b0325e611d70 100644
--- a/scripts/lldb.swig
+++ b/scripts/lldb.swig
@@ -103,6 +103,8 @@ import six
#include "lldb/API/SBThread.h"
#include "lldb/API/SBThreadCollection.h"
#include "lldb/API/SBThreadPlan.h"
+#include "lldb/API/SBTrace.h"
+#include "lldb/API/SBTraceOptions.h"
#include "lldb/API/SBType.h"
#include "lldb/API/SBTypeCategory.h"
#include "lldb/API/SBTypeEnumMember.h"
@@ -186,6 +188,8 @@ import six
%include "./interface/SBThread.i"
%include "./interface/SBThreadCollection.i"
%include "./interface/SBThreadPlan.i"
+%include "./interface/SBTrace.i"
+%include "./interface/SBTraceOptions.i"
%include "./interface/SBType.i"
%include "./interface/SBTypeCategory.i"
%include "./interface/SBTypeEnumMember.i"
diff --git a/source/API/CMakeLists.txt b/source/API/CMakeLists.txt
index 3b852a3d7402..9dd21bcf2aaf 100644
--- a/source/API/CMakeLists.txt
+++ b/source/API/CMakeLists.txt
@@ -67,6 +67,8 @@ add_lldb_library(liblldb SHARED
SBThread.cpp
SBThreadCollection.cpp
SBThreadPlan.cpp
+ SBTrace.cpp
+ SBTraceOptions.cpp
SBType.cpp
SBTypeCategory.cpp
SBTypeEnumMember.cpp
diff --git a/source/API/SBProcess.cpp b/source/API/SBProcess.cpp
index 4cb367a03ad6..5614cb468a69 100644
--- a/source/API/SBProcess.cpp
+++ b/source/API/SBProcess.cpp
@@ -44,6 +44,8 @@
#include "lldb/API/SBStructuredData.h"
#include "lldb/API/SBThread.h"
#include "lldb/API/SBThreadCollection.h"
+#include "lldb/API/SBTrace.h"
+#include "lldb/API/SBTraceOptions.h"
#include "lldb/API/SBUnixSignals.h"
using namespace lldb;
@@ -349,6 +351,26 @@ size_t SBProcess::GetAsyncProfileData(char *dst, size_t dst_len) const {
return bytes_read;
}
+lldb::SBTrace SBProcess::StartTrace(SBTraceOptions &options,
+ lldb::SBError &error) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+ ProcessSP process_sp(GetSP());
+ error.Clear();
+ SBTrace trace_instance;
+ trace_instance.SetSP(process_sp);
+ lldb::user_id_t uid = LLDB_INVALID_UID;
+
+ if (!process_sp) {
+ error.SetErrorString("invalid process");
+ } else {
+
+ uid = process_sp->StartTrace(options.m_traceoptions_sp, error.ref());
+ trace_instance.SetTraceUID(uid);
+ LLDB_LOG(log, "SBProcess::returned uid - %" PRIx64, uid);
+ }
+ return trace_instance;
+}
+
void SBProcess::ReportEventState(const SBEvent &event, FILE *out) const {
if (out == NULL)
return;
diff --git a/source/API/SBStructuredData.cpp b/source/API/SBStructuredData.cpp
index 6d4c862306f9..2fca56f2f223 100644
--- a/source/API/SBStructuredData.cpp
+++ b/source/API/SBStructuredData.cpp
@@ -12,6 +12,7 @@
#include "lldb/API/SBStream.h"
#include "lldb/Core/Event.h"
#include "lldb/Core/StructuredData.h"
+#include "lldb/Core/StructuredDataImpl.h"
#include "lldb/Target/StructuredDataPlugin.h"
#include "lldb/Utility/Error.h"
#include "lldb/Utility/Stream.h"
@@ -20,70 +21,6 @@ using namespace lldb;
using namespace lldb_private;
#pragma mark--
-#pragma mark StructuredDataImpl
-
-class StructuredDataImpl {
-public:
- StructuredDataImpl() : m_plugin_wp(), m_data_sp() {}
-
- StructuredDataImpl(const StructuredDataImpl &rhs) = default;
-
- StructuredDataImpl(const EventSP &event_sp)
- : m_plugin_wp(
- EventDataStructuredData::GetPluginFromEvent(event_sp.get())),
- m_data_sp(EventDataStructuredData::GetObjectFromEvent(event_sp.get())) {
- }
-
- ~StructuredDataImpl() = default;
-
- StructuredDataImpl &operator=(const StructuredDataImpl &rhs) = default;
-
- bool IsValid() const { return m_data_sp.get() != nullptr; }
-
- void Clear() {
- m_plugin_wp.reset();
- m_data_sp.reset();
- }
-
- SBError GetAsJSON(lldb_private::Stream &stream) const {
- SBError sb_error;
-
- if (!m_data_sp) {
- sb_error.SetErrorString("No structured data.");
- return sb_error;
- }
-
- m_data_sp->Dump(stream);
- return sb_error;
- }
-
- Error GetDescription(lldb_private::Stream &stream) const {
- Error error;
-
- if (!m_data_sp) {
- error.SetErrorString("Cannot pretty print structured data: "
- "no data to print.");
- return error;
- }
-
- // Grab the plugin.
- auto plugin_sp = StructuredDataPluginSP(m_plugin_wp);
- if (!plugin_sp) {
- error.SetErrorString("Cannot pretty print structured data: "
- "plugin doesn't exist.");
- return error;
- }
-
- // Get the data's description.
- return plugin_sp->GetDescription(m_data_sp, stream);
- }
-
-private:
- StructuredDataPluginWP m_plugin_wp;
- StructuredData::ObjectSP m_data_sp;
-};
-
-#pragma mark--
#pragma mark SBStructuredData
SBStructuredData::SBStructuredData() : m_impl_up(new StructuredDataImpl()) {}
@@ -102,12 +39,26 @@ operator=(const lldb::SBStructuredData &rhs) {
return *this;
}
+lldb::SBError SBStructuredData::SetFromJSON(lldb::SBStream &stream) {
+ lldb::SBError error;
+ std::string json_str(stream.GetData());
+
+ StructuredData::ObjectSP json_obj = StructuredData::ParseJSON(json_str);
+ m_impl_up->SetObjectSP(json_obj);
+
+ if (!json_obj || json_obj->GetType() != StructuredData::Type::eTypeDictionary)
+ error.SetErrorString("Invalid Syntax");
+ return error;
+}
+
bool SBStructuredData::IsValid() const { return m_impl_up->IsValid(); }
void SBStructuredData::Clear() { m_impl_up->Clear(); }
SBError SBStructuredData::GetAsJSON(lldb::SBStream &stream) const {
- return m_impl_up->GetAsJSON(stream.ref());
+ SBError error;
+ error.SetError(m_impl_up->GetAsJSON(stream.ref()));
+ return error;
}
lldb::SBError SBStructuredData::GetDescription(lldb::SBStream &stream) const {
diff --git a/source/API/SBTrace.cpp b/source/API/SBTrace.cpp
new file mode 100644
index 000000000000..18f7d36e7759
--- /dev/null
+++ b/source/API/SBTrace.cpp
@@ -0,0 +1,109 @@
+//===-- SBTrace.cpp ---------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Utility/Log.h"
+#include "lldb/Target/Process.h"
+
+#include "lldb/API/SBTrace.h"
+#include "lldb/API/SBTraceOptions.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+class TraceImpl {
+public:
+ lldb::user_id_t uid;
+};
+
+lldb::ProcessSP SBTrace::GetSP() const { return m_opaque_wp.lock(); }
+
+size_t SBTrace::GetTraceData(SBError &error, void *buf, size_t size,
+ size_t offset, lldb::tid_t thread_id) {
+ size_t bytes_read = 0;
+ ProcessSP process_sp(GetSP());
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+ error.Clear();
+
+ if (!process_sp) {
+ error.SetErrorString("invalid process");
+ } else {
+ bytes_read = process_sp->GetData(GetTraceUID(), thread_id, error.ref(), buf,
+ size, offset);
+ LLDB_LOG(log, "SBTrace::bytes_read - %" PRIx64, bytes_read);
+ }
+ return bytes_read;
+}
+
+size_t SBTrace::GetMetaData(SBError &error, void *buf, size_t size,
+ size_t offset, lldb::tid_t thread_id) {
+ size_t bytes_read = 0;
+ ProcessSP process_sp(GetSP());
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+ error.Clear();
+
+ if (!process_sp) {
+ error.SetErrorString("invalid process");
+ } else {
+
+ bytes_read = process_sp->GetMetaData(GetTraceUID(), thread_id, error.ref(),
+ buf, size, offset);
+ LLDB_LOG(log, "SBTrace::bytes_read - %" PRIx64, bytes_read);
+ }
+ return bytes_read;
+}
+
+void SBTrace::StopTrace(SBError &error, lldb::tid_t thread_id) {
+ ProcessSP process_sp(GetSP());
+ error.Clear();
+
+ if (!process_sp) {
+ error.SetErrorString("invalid process");
+ return;
+ }
+ process_sp->StopTrace(GetTraceUID(), thread_id, error.ref());
+}
+
+void SBTrace::GetTraceConfig(SBTraceOptions &options, SBError &error) {
+ ProcessSP process_sp(GetSP());
+ error.Clear();
+
+ if (!process_sp) {
+ error.SetErrorString("invalid process");
+ } else {
+ process_sp->GetTraceConfig(GetTraceUID(), error.ref(),
+ options.m_traceoptions_sp);
+ }
+}
+
+lldb::user_id_t SBTrace::GetTraceUID() {
+ if (m_trace_impl_sp)
+ return m_trace_impl_sp->uid;
+ return LLDB_INVALID_UID;
+}
+
+void SBTrace::SetTraceUID(lldb::user_id_t uid) {
+ if (m_trace_impl_sp)
+ m_trace_impl_sp->uid = uid;
+}
+
+SBTrace::SBTrace() {
+ m_trace_impl_sp.reset(new TraceImpl);
+ if (m_trace_impl_sp)
+ m_trace_impl_sp->uid = LLDB_INVALID_UID;
+}
+
+void SBTrace::SetSP(const ProcessSP &process_sp) { m_opaque_wp = process_sp; }
+
+bool SBTrace::IsValid() {
+ if (!m_trace_impl_sp)
+ return false;
+ if (!GetSP())
+ return false;
+ return true;
+}
diff --git a/source/API/SBTraceOptions.cpp b/source/API/SBTraceOptions.cpp
new file mode 100644
index 000000000000..474fa911f7ec
--- /dev/null
+++ b/source/API/SBTraceOptions.cpp
@@ -0,0 +1,94 @@
+//===-- SBTraceOptions.cpp --------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/API/SBTraceOptions.h"
+#include "lldb/API/SBError.h"
+#include "lldb/API/SBStructuredData.h"
+#include "lldb/Utility/Log.h"
+#include "lldb/Core/StructuredDataImpl.h"
+#include "lldb/Core/TraceOptions.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+SBTraceOptions::SBTraceOptions() {
+ m_traceoptions_sp.reset(new TraceOptions());
+}
+
+lldb::TraceType SBTraceOptions::getType() const {
+ if (m_traceoptions_sp)
+ return m_traceoptions_sp->getType();
+ return lldb::TraceType::eTraceTypeNone;
+}
+
+uint64_t SBTraceOptions::getTraceBufferSize() const {
+ if (m_traceoptions_sp)
+ return m_traceoptions_sp->getTraceBufferSize();
+ return 0;
+}
+
+lldb::SBStructuredData SBTraceOptions::getTraceParams(lldb::SBError &error) {
+ error.Clear();
+ const lldb_private::StructuredData::DictionarySP dict_obj =
+ m_traceoptions_sp->getTraceParams();
+ lldb::SBStructuredData structData;
+ if (dict_obj && structData.m_impl_up)
+ structData.m_impl_up->SetObjectSP(dict_obj->shared_from_this());
+ else
+ error.SetErrorString("Empty trace params");
+ return structData;
+}
+
+uint64_t SBTraceOptions::getMetaDataBufferSize() const {
+ if (m_traceoptions_sp)
+ return m_traceoptions_sp->getTraceBufferSize();
+ return 0;
+}
+
+void SBTraceOptions::setTraceParams(lldb::SBStructuredData &params) {
+ if (m_traceoptions_sp && params.m_impl_up) {
+ StructuredData::ObjectSP obj_sp = params.m_impl_up->GetObjectSP();
+ if (obj_sp && obj_sp->GetAsDictionary() != nullptr)
+ m_traceoptions_sp->setTraceParams(
+ std::static_pointer_cast<StructuredData::Dictionary>(obj_sp));
+ }
+ return;
+}
+
+void SBTraceOptions::setType(lldb::TraceType type) {
+ if (m_traceoptions_sp)
+ m_traceoptions_sp->setType(type);
+}
+
+void SBTraceOptions::setTraceBufferSize(uint64_t size) {
+ if (m_traceoptions_sp)
+ m_traceoptions_sp->setTraceBufferSize(size);
+}
+
+void SBTraceOptions::setMetaDataBufferSize(uint64_t size) {
+ if (m_traceoptions_sp)
+ m_traceoptions_sp->setMetaDataBufferSize(size);
+}
+
+bool SBTraceOptions::IsValid() {
+ if (m_traceoptions_sp)
+ return true;
+ return false;
+}
+
+void SBTraceOptions::setThreadID(lldb::tid_t thread_id) {
+ if (m_traceoptions_sp)
+ m_traceoptions_sp->setThreadID(thread_id);
+}
+
+lldb::tid_t SBTraceOptions::getThreadID() {
+ if (m_traceoptions_sp)
+ return m_traceoptions_sp->getThreadID();
+ return LLDB_INVALID_THREAD_ID;
+}
diff --git a/source/Core/ValueObject.cpp b/source/Core/ValueObject.cpp
index 381763dab8e1..9e6b9da78b99 100644
--- a/source/Core/ValueObject.cpp
+++ b/source/Core/ValueObject.cpp
@@ -481,21 +481,8 @@ ValueObjectSP ValueObject::GetChildAtIndex(size_t idx, bool can_create) {
return child_sp;
}
-ValueObjectSP
-ValueObject::GetChildAtIndexPath(const std::initializer_list<size_t> &idxs,
- size_t *index_of_error) {
- return GetChildAtIndexPath(std::vector<size_t>(idxs), index_of_error);
-}
-
-ValueObjectSP ValueObject::GetChildAtIndexPath(
- const std::initializer_list<std::pair<size_t, bool>> &idxs,
- size_t *index_of_error) {
- return GetChildAtIndexPath(std::vector<std::pair<size_t, bool>>(idxs),
- index_of_error);
-}
-
lldb::ValueObjectSP
-ValueObject::GetChildAtIndexPath(const std::vector<size_t> &idxs,
+ValueObject::GetChildAtIndexPath(llvm::ArrayRef<size_t> idxs,
size_t *index_of_error) {
if (idxs.size() == 0)
return GetSP();
@@ -512,7 +499,7 @@ ValueObject::GetChildAtIndexPath(const std::vector<size_t> &idxs,
}
lldb::ValueObjectSP ValueObject::GetChildAtIndexPath(
- const std::vector<std::pair<size_t, bool>> &idxs, size_t *index_of_error) {
+ llvm::ArrayRef<std::pair<size_t, bool>> idxs, size_t *index_of_error) {
if (idxs.size() == 0)
return GetSP();
ValueObjectSP root(GetSP());
@@ -528,20 +515,7 @@ lldb::ValueObjectSP ValueObject::GetChildAtIndexPath(
}
lldb::ValueObjectSP
-ValueObject::GetChildAtNamePath(const std::initializer_list<ConstString> &names,
- ConstString *name_of_error) {
- return GetChildAtNamePath(std::vector<ConstString>(names), name_of_error);
-}
-
-lldb::ValueObjectSP ValueObject::GetChildAtNamePath(
- const std::initializer_list<std::pair<ConstString, bool>> &names,
- ConstString *name_of_error) {
- return GetChildAtNamePath(std::vector<std::pair<ConstString, bool>>(names),
- name_of_error);
-}
-
-lldb::ValueObjectSP
-ValueObject::GetChildAtNamePath(const std::vector<ConstString> &names,
+ValueObject::GetChildAtNamePath(llvm::ArrayRef<ConstString> names,
ConstString *name_of_error) {
if (names.size() == 0)
return GetSP();
@@ -558,7 +532,7 @@ ValueObject::GetChildAtNamePath(const std::vector<ConstString> &names,
}
lldb::ValueObjectSP ValueObject::GetChildAtNamePath(
- const std::vector<std::pair<ConstString, bool>> &names,
+ llvm::ArrayRef<std::pair<ConstString, bool>> names,
ConstString *name_of_error) {
if (names.size() == 0)
return GetSP();
diff --git a/source/Host/common/SocketAddress.cpp b/source/Host/common/SocketAddress.cpp
index 48c3ec1c48ed..b41cef6ca2eb 100644
--- a/source/Host/common/SocketAddress.cpp
+++ b/source/Host/common/SocketAddress.cpp
@@ -227,6 +227,18 @@ bool SocketAddress::getaddrinfo(const char *host, const char *service,
int ai_flags) {
Clear();
+ auto addresses = GetAddressInfo(host, service, ai_family, ai_socktype, ai_protocol, ai_flags);
+ if (!addresses.empty())
+ *this = addresses[0];
+ return IsValid();
+}
+
+std::vector<SocketAddress>
+SocketAddress::GetAddressInfo(const char *hostname, const char *servname,
+ int ai_family, int ai_socktype, int ai_protocol,
+ int ai_flags) {
+ std::vector<SocketAddress> addr_list;
+
struct addrinfo hints;
memset(&hints, 0, sizeof(hints));
hints.ai_family = ai_family;
@@ -234,26 +246,8 @@ bool SocketAddress::getaddrinfo(const char *host, const char *service,
hints.ai_protocol = ai_protocol;
hints.ai_flags = ai_flags;
- bool result = false;
- struct addrinfo *service_info_list = NULL;
- int err = ::getaddrinfo(host, service, &hints, &service_info_list);
- if (err == 0 && service_info_list) {
- *this = service_info_list;
- result = IsValid();
- }
-
- if (service_info_list)
- ::freeaddrinfo(service_info_list);
-
- return result;
-}
-
-std::vector<SocketAddress> SocketAddress::GetAddressInfo(const char *hostname,
- const char *servname) {
- std::vector<SocketAddress> addr_list;
-
struct addrinfo *service_info_list = NULL;
- int err = ::getaddrinfo(hostname, servname, NULL, &service_info_list);
+ int err = ::getaddrinfo(hostname, servname, &hints, &service_info_list);
if (err == 0 && service_info_list) {
for (struct addrinfo *service_ptr = service_info_list; service_ptr != NULL;
service_ptr = service_ptr->ai_next) {
diff --git a/source/Host/freebsd/Host.cpp b/source/Host/freebsd/Host.cpp
index 9415b2bb3fd0..f1abb49055e5 100644
--- a/source/Host/freebsd/Host.cpp
+++ b/source/Host/freebsd/Host.cpp
@@ -55,49 +55,53 @@ using namespace lldb_private;
static bool
GetFreeBSDProcessArgs(const ProcessInstanceInfoMatch *match_info_ptr,
ProcessInstanceInfo &process_info) {
- if (process_info.ProcessIDIsValid()) {
- int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_ARGS,
- (int)process_info.GetProcessID()};
-
- char arg_data[8192];
- size_t arg_data_size = sizeof(arg_data);
- if (::sysctl(mib, 4, arg_data, &arg_data_size, NULL, 0) == 0) {
- DataExtractor data(arg_data, arg_data_size, endian::InlHostByteOrder(),
- sizeof(void *));
- lldb::offset_t offset = 0;
- const char *cstr;
-
- cstr = data.GetCStr(&offset);
- if (cstr) {
- process_info.GetExecutableFile().SetFile(cstr, false);
-
- if (!(match_info_ptr == NULL ||
- NameMatches(
- process_info.GetExecutableFile().GetFilename().GetCString(),
- match_info_ptr->GetNameMatchType(),
- match_info_ptr->GetProcessInfo().GetName())))
- return false;
-
- Args &proc_args = process_info.GetArguments();
- while (1) {
- const uint8_t *p = data.PeekData(offset, 1);
- while ((p != NULL) && (*p == '\0') && offset < arg_data_size) {
- ++offset;
- p = data.PeekData(offset, 1);
- }
- if (p == NULL || offset >= arg_data_size)
- return true;
-
- cstr = data.GetCStr(&offset);
- if (cstr)
- proc_args.AppendArgument(llvm::StringRef(cstr));
- else
- return true;
- }
- }
+ if (!process_info.ProcessIDIsValid())
+ return false;
+
+ int pid = process_info.GetProcessID();
+
+ int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_ARGS, pid};
+
+ char arg_data[8192];
+ size_t arg_data_size = sizeof(arg_data);
+ if (::sysctl(mib, 4, arg_data, &arg_data_size, NULL, 0) != 0)
+ return false;
+
+ DataExtractor data(arg_data, arg_data_size, endian::InlHostByteOrder(),
+ sizeof(void *));
+ lldb::offset_t offset = 0;
+ const char *cstr;
+
+ cstr = data.GetCStr(&offset);
+ if (!cstr)
+ return false;
+
+ process_info.GetExecutableFile().SetFile(cstr, false);
+
+ if (!(match_info_ptr == NULL ||
+ NameMatches(process_info.GetExecutableFile().GetFilename().GetCString(),
+ match_info_ptr->GetNameMatchType(),
+ match_info_ptr->GetProcessInfo().GetName())))
+ return false;
+
+ Args &proc_args = process_info.GetArguments();
+ while (1) {
+ const uint8_t *p = data.PeekData(offset, 1);
+ while ((p != NULL) && (*p == '\0') && offset < arg_data_size) {
+ ++offset;
+ p = data.PeekData(offset, 1);
}
+ if (p == NULL || offset >= arg_data_size)
+ break;
+
+ cstr = data.GetCStr(&offset);
+ if (!cstr)
+ break;
+
+ proc_args.AppendArgument(llvm::StringRef(cstr));
}
- return false;
+
+ return true;
}
static bool GetFreeBSDProcessCPUType(ProcessInstanceInfo &process_info) {
@@ -113,26 +117,31 @@ static bool GetFreeBSDProcessCPUType(ProcessInstanceInfo &process_info) {
static bool GetFreeBSDProcessUserAndGroup(ProcessInstanceInfo &process_info) {
struct kinfo_proc proc_kinfo;
size_t proc_kinfo_size;
+ const int pid = process_info.GetProcessID();
+ int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, pid};
- if (process_info.ProcessIDIsValid()) {
- int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID,
- (int)process_info.GetProcessID()};
- proc_kinfo_size = sizeof(struct kinfo_proc);
-
- if (::sysctl(mib, 4, &proc_kinfo, &proc_kinfo_size, NULL, 0) == 0) {
- if (proc_kinfo_size > 0) {
- process_info.SetParentProcessID(proc_kinfo.ki_ppid);
- process_info.SetUserID(proc_kinfo.ki_ruid);
- process_info.SetGroupID(proc_kinfo.ki_rgid);
- process_info.SetEffectiveUserID(proc_kinfo.ki_uid);
- if (proc_kinfo.ki_ngroups > 0)
- process_info.SetEffectiveGroupID(proc_kinfo.ki_groups[0]);
- else
- process_info.SetEffectiveGroupID(UINT32_MAX);
- return true;
- }
- }
- }
+ if (!process_info.ProcessIDIsValid())
+ goto error;
+
+ proc_kinfo_size = sizeof(struct kinfo_proc);
+
+ if (::sysctl(mib, 4, &proc_kinfo, &proc_kinfo_size, NULL, 0) != 0)
+ goto error;
+
+ if (proc_kinfo_size == 0)
+ goto error;
+
+ process_info.SetParentProcessID(proc_kinfo.ki_ppid);
+ process_info.SetUserID(proc_kinfo.ki_ruid);
+ process_info.SetGroupID(proc_kinfo.ki_rgid);
+ process_info.SetEffectiveUserID(proc_kinfo.ki_uid);
+ if (proc_kinfo.ki_ngroups > 0)
+ process_info.SetEffectiveGroupID(proc_kinfo.ki_groups[0]);
+ else
+ process_info.SetEffectiveGroupID(UINT32_MAX);
+ return true;
+
+error:
process_info.SetParentProcessID(LLDB_INVALID_PROCESS_ID);
process_info.SetUserID(UINT32_MAX);
process_info.SetGroupID(UINT32_MAX);
@@ -143,7 +152,11 @@ static bool GetFreeBSDProcessUserAndGroup(ProcessInstanceInfo &process_info) {
uint32_t Host::FindProcesses(const ProcessInstanceInfoMatch &match_info,
ProcessInstanceInfoList &process_infos) {
+ const ::pid_t our_pid = ::getpid();
+ const ::uid_t our_uid = ::getuid();
std::vector<struct kinfo_proc> kinfos;
+ // Special case, if lldb is being run as root we can attach to anything.
+ bool all_users = match_info.GetMatchAllUsers() || (our_uid == 0);
int mib[3] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL};
@@ -163,29 +176,24 @@ uint32_t Host::FindProcesses(const ProcessInstanceInfoMatch &match_info,
const size_t actual_pid_count = (pid_data_size / sizeof(struct kinfo_proc));
- bool all_users = match_info.GetMatchAllUsers();
- const ::pid_t our_pid = getpid();
- const uid_t our_uid = getuid();
for (size_t i = 0; i < actual_pid_count; i++) {
const struct kinfo_proc &kinfo = kinfos[i];
- const bool kinfo_user_matches = (all_users || (kinfo.ki_ruid == our_uid) ||
- // Special case, if lldb is being run as
- // root we can attach to anything.
- (our_uid == 0));
-
- if (kinfo_user_matches == false || // Make sure the user is acceptable
- kinfo.ki_pid == our_pid || // Skip this process
- kinfo.ki_pid == 0 || // Skip kernel (kernel pid is zero)
- kinfo.ki_stat == SZOMB || // Zombies are bad, they like brains...
- kinfo.ki_flag & P_TRACED || // Being debugged?
- kinfo.ki_flag & P_WEXIT) // Working on exiting
+
+ /* Make sure the user is acceptable */
+ if (!all_users && kinfo.ki_ruid != our_uid)
+ continue;
+
+ if (kinfo.ki_pid == our_pid || // Skip this process
+ kinfo.ki_pid == 0 || // Skip kernel (kernel pid is 0)
+ kinfo.ki_stat == SZOMB || // Zombies are bad
+ kinfo.ki_flag & P_TRACED || // Being debugged?
+ kinfo.ki_flag & P_WEXIT) // Working on exiting
continue;
// Every thread is a process in FreeBSD, but all the threads of a single
- // process
- // have the same pid. Do not store the process info in the result list if a
- // process
- // with given identifier is already registered there.
+ // process have the same pid. Do not store the process info in the
+ // result list if a process with given identifier is already registered
+ // there.
bool already_registered = false;
for (uint32_t pi = 0;
!already_registered && (const int)kinfo.ki_numthreads > 1 &&
diff --git a/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp b/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
index 70c77e9cde33..1f78fb96bc34 100644
--- a/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
+++ b/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
@@ -814,9 +814,8 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
FindExternalVisibleDecls(context, lldb::ModuleSP(), namespace_decl,
current_id);
}
-
- if (!context.m_found.variable && !context.m_found.local_vars_nsp)
- ClangASTSource::FindExternalVisibleDecls(context);
+
+ ClangASTSource::FindExternalVisibleDecls(context);
}
void ClangExpressionDeclMap::FindExternalVisibleDecls(
@@ -1217,7 +1216,7 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
}
}
- if (var) {
+ if (var && !variable_found) {
variable_found = true;
valobj = ValueObjectVariable::Create(frame, var);
AddOneVariable(context, var, valobj, current_id);
@@ -1248,303 +1247,297 @@ void ClangExpressionDeclMap::FindExternalVisibleDecls(
}
}
- if (!context.m_found.variable) {
- const bool include_inlines = false;
- const bool append = false;
+ const bool include_inlines = false;
+ const bool append = false;
- if (namespace_decl && module_sp) {
- const bool include_symbols = false;
+ if (namespace_decl && module_sp) {
+ const bool include_symbols = false;
- module_sp->FindFunctions(name, &namespace_decl, eFunctionNameTypeBase,
- include_symbols, include_inlines, append,
- sc_list);
- } else if (target && !namespace_decl) {
- const bool include_symbols = true;
+ module_sp->FindFunctions(name, &namespace_decl, eFunctionNameTypeBase,
+ include_symbols, include_inlines, append,
+ sc_list);
+ } else if (target && !namespace_decl) {
+ const bool include_symbols = true;
- // TODO Fix FindFunctions so that it doesn't return
- // instance methods for eFunctionNameTypeBase.
+ // TODO Fix FindFunctions so that it doesn't return
+ // instance methods for eFunctionNameTypeBase.
- target->GetImages().FindFunctions(name, eFunctionNameTypeFull,
- include_symbols, include_inlines,
- append, sc_list);
- }
+ target->GetImages().FindFunctions(name, eFunctionNameTypeFull,
+ include_symbols, include_inlines,
+ append, sc_list);
+ }
- // If we found more than one function, see if we can use the
- // frame's decl context to remove functions that are shadowed
- // by other functions which match in type but are nearer in scope.
- //
- // AddOneFunction will not add a function whose type has already been
- // added, so if there's another function in the list with a matching
- // type, check to see if their decl context is a parent of the current
- // frame's or was imported via a and using statement, and pick the
- // best match according to lookup rules.
- if (sc_list.GetSize() > 1) {
- // Collect some info about our frame's context.
- StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr();
- SymbolContext frame_sym_ctx;
- if (frame != nullptr)
- frame_sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction |
- lldb::eSymbolContextBlock);
- CompilerDeclContext frame_decl_context =
- frame_sym_ctx.block != nullptr
- ? frame_sym_ctx.block->GetDeclContext()
- : CompilerDeclContext();
-
- // We can't do this without a compiler decl context for our frame.
- if (frame_decl_context) {
- clang::DeclContext *frame_decl_ctx =
- (clang::DeclContext *)frame_decl_context.GetOpaqueDeclContext();
- ClangASTContext *ast = llvm::dyn_cast_or_null<ClangASTContext>(
- frame_decl_context.GetTypeSystem());
-
- // Structure to hold the info needed when comparing function
- // declarations.
- struct FuncDeclInfo {
- ConstString m_name;
- CompilerType m_copied_type;
- uint32_t m_decl_lvl;
- SymbolContext m_sym_ctx;
- };
-
- // First, symplify things by looping through the symbol contexts
- // to remove unwanted functions and separate out the functions we
- // want to compare and prune into a separate list.
- // Cache the info needed about the function declarations in a
- // vector for efficiency.
- SymbolContextList sc_sym_list;
- uint32_t num_indices = sc_list.GetSize();
- std::vector<FuncDeclInfo> fdi_cache;
- fdi_cache.reserve(num_indices);
- for (uint32_t index = 0; index < num_indices; ++index) {
- FuncDeclInfo fdi;
- SymbolContext sym_ctx;
- sc_list.GetContextAtIndex(index, sym_ctx);
-
- // We don't know enough about symbols to compare them,
- // but we should keep them in the list.
- Function *function = sym_ctx.function;
- if (!function) {
- sc_sym_list.Append(sym_ctx);
- continue;
- }
- // Filter out functions without declaration contexts, as well as
- // class/instance methods, since they'll be skipped in the
- // code that follows anyway.
- CompilerDeclContext func_decl_context = function->GetDeclContext();
- if (!func_decl_context ||
- func_decl_context.IsClassMethod(nullptr, nullptr, nullptr))
- continue;
- // We can only prune functions for which we can copy the type.
- CompilerType func_clang_type =
- function->GetType()->GetFullCompilerType();
- CompilerType copied_func_type = GuardedCopyType(func_clang_type);
- if (!copied_func_type) {
- sc_sym_list.Append(sym_ctx);
- continue;
- }
+ // If we found more than one function, see if we can use the
+ // frame's decl context to remove functions that are shadowed
+ // by other functions which match in type but are nearer in scope.
+ //
+ // AddOneFunction will not add a function whose type has already been
+ // added, so if there's another function in the list with a matching
+ // type, check to see if their decl context is a parent of the current
+ // frame's or was imported via a and using statement, and pick the
+ // best match according to lookup rules.
+ if (sc_list.GetSize() > 1) {
+ // Collect some info about our frame's context.
+ StackFrame *frame = m_parser_vars->m_exe_ctx.GetFramePtr();
+ SymbolContext frame_sym_ctx;
+ if (frame != nullptr)
+ frame_sym_ctx = frame->GetSymbolContext(lldb::eSymbolContextFunction |
+ lldb::eSymbolContextBlock);
+ CompilerDeclContext frame_decl_context =
+ frame_sym_ctx.block != nullptr ? frame_sym_ctx.block->GetDeclContext()
+ : CompilerDeclContext();
- fdi.m_sym_ctx = sym_ctx;
- fdi.m_name = function->GetName();
- fdi.m_copied_type = copied_func_type;
- fdi.m_decl_lvl = LLDB_INVALID_DECL_LEVEL;
- if (fdi.m_copied_type && func_decl_context) {
- // Call CountDeclLevels to get the number of parent scopes we
- // have to look through before we find the function declaration.
- // When comparing functions of the same type, the one with a
- // lower count will be closer to us in the lookup scope and
- // shadows the other.
- clang::DeclContext *func_decl_ctx =
- (clang::DeclContext *)
- func_decl_context.GetOpaqueDeclContext();
- fdi.m_decl_lvl =
- ast->CountDeclLevels(frame_decl_ctx, func_decl_ctx,
- &fdi.m_name, &fdi.m_copied_type);
- }
- fdi_cache.emplace_back(fdi);
- }
+ // We can't do this without a compiler decl context for our frame.
+ if (frame_decl_context) {
+ clang::DeclContext *frame_decl_ctx =
+ (clang::DeclContext *)frame_decl_context.GetOpaqueDeclContext();
+ ClangASTContext *ast = llvm::dyn_cast_or_null<ClangASTContext>(
+ frame_decl_context.GetTypeSystem());
- // Loop through the functions in our cache looking for matching types,
- // then compare their scope levels to see which is closer.
- std::multimap<CompilerType, const FuncDeclInfo *> matches;
- for (const FuncDeclInfo &fdi : fdi_cache) {
- const CompilerType t = fdi.m_copied_type;
- auto q = matches.find(t);
- if (q != matches.end()) {
- if (q->second->m_decl_lvl > fdi.m_decl_lvl)
- // This function is closer; remove the old set.
- matches.erase(t);
- else if (q->second->m_decl_lvl < fdi.m_decl_lvl)
- // The functions in our set are closer - skip this one.
- continue;
- }
- matches.insert(std::make_pair(t, &fdi));
+ // Structure to hold the info needed when comparing function
+ // declarations.
+ struct FuncDeclInfo {
+ ConstString m_name;
+ CompilerType m_copied_type;
+ uint32_t m_decl_lvl;
+ SymbolContext m_sym_ctx;
+ };
+
+ // First, symplify things by looping through the symbol contexts
+ // to remove unwanted functions and separate out the functions we
+ // want to compare and prune into a separate list.
+ // Cache the info needed about the function declarations in a
+ // vector for efficiency.
+ SymbolContextList sc_sym_list;
+ uint32_t num_indices = sc_list.GetSize();
+ std::vector<FuncDeclInfo> fdi_cache;
+ fdi_cache.reserve(num_indices);
+ for (uint32_t index = 0; index < num_indices; ++index) {
+ FuncDeclInfo fdi;
+ SymbolContext sym_ctx;
+ sc_list.GetContextAtIndex(index, sym_ctx);
+
+ // We don't know enough about symbols to compare them,
+ // but we should keep them in the list.
+ Function *function = sym_ctx.function;
+ if (!function) {
+ sc_sym_list.Append(sym_ctx);
+ continue;
+ }
+ // Filter out functions without declaration contexts, as well as
+ // class/instance methods, since they'll be skipped in the
+ // code that follows anyway.
+ CompilerDeclContext func_decl_context = function->GetDeclContext();
+ if (!func_decl_context ||
+ func_decl_context.IsClassMethod(nullptr, nullptr, nullptr))
+ continue;
+ // We can only prune functions for which we can copy the type.
+ CompilerType func_clang_type =
+ function->GetType()->GetFullCompilerType();
+ CompilerType copied_func_type = GuardedCopyType(func_clang_type);
+ if (!copied_func_type) {
+ sc_sym_list.Append(sym_ctx);
+ continue;
}
- // Loop through our matches and add their symbol contexts to our list.
- SymbolContextList sc_func_list;
- for (const auto &q : matches)
- sc_func_list.Append(q.second->m_sym_ctx);
+ fdi.m_sym_ctx = sym_ctx;
+ fdi.m_name = function->GetName();
+ fdi.m_copied_type = copied_func_type;
+ fdi.m_decl_lvl = LLDB_INVALID_DECL_LEVEL;
+ if (fdi.m_copied_type && func_decl_context) {
+ // Call CountDeclLevels to get the number of parent scopes we
+ // have to look through before we find the function declaration.
+ // When comparing functions of the same type, the one with a
+ // lower count will be closer to us in the lookup scope and
+ // shadows the other.
+ clang::DeclContext *func_decl_ctx =
+ (clang::DeclContext *)func_decl_context.GetOpaqueDeclContext();
+ fdi.m_decl_lvl = ast->CountDeclLevels(
+ frame_decl_ctx, func_decl_ctx, &fdi.m_name, &fdi.m_copied_type);
+ }
+ fdi_cache.emplace_back(fdi);
+ }
- // Rejoin the lists with the functions in front.
- sc_list = sc_func_list;
- sc_list.Append(sc_sym_list);
+ // Loop through the functions in our cache looking for matching types,
+ // then compare their scope levels to see which is closer.
+ std::multimap<CompilerType, const FuncDeclInfo *> matches;
+ for (const FuncDeclInfo &fdi : fdi_cache) {
+ const CompilerType t = fdi.m_copied_type;
+ auto q = matches.find(t);
+ if (q != matches.end()) {
+ if (q->second->m_decl_lvl > fdi.m_decl_lvl)
+ // This function is closer; remove the old set.
+ matches.erase(t);
+ else if (q->second->m_decl_lvl < fdi.m_decl_lvl)
+ // The functions in our set are closer - skip this one.
+ continue;
+ }
+ matches.insert(std::make_pair(t, &fdi));
}
- }
- if (sc_list.GetSize()) {
- Symbol *extern_symbol = NULL;
- Symbol *non_extern_symbol = NULL;
+ // Loop through our matches and add their symbol contexts to our list.
+ SymbolContextList sc_func_list;
+ for (const auto &q : matches)
+ sc_func_list.Append(q.second->m_sym_ctx);
- for (uint32_t index = 0, num_indices = sc_list.GetSize();
- index < num_indices; ++index) {
- SymbolContext sym_ctx;
- sc_list.GetContextAtIndex(index, sym_ctx);
+ // Rejoin the lists with the functions in front.
+ sc_list = sc_func_list;
+ sc_list.Append(sc_sym_list);
+ }
+ }
- if (sym_ctx.function) {
- CompilerDeclContext decl_ctx = sym_ctx.function->GetDeclContext();
+ if (sc_list.GetSize()) {
+ Symbol *extern_symbol = NULL;
+ Symbol *non_extern_symbol = NULL;
- if (!decl_ctx)
- continue;
+ for (uint32_t index = 0, num_indices = sc_list.GetSize();
+ index < num_indices; ++index) {
+ SymbolContext sym_ctx;
+ sc_list.GetContextAtIndex(index, sym_ctx);
- // Filter out class/instance methods.
- if (decl_ctx.IsClassMethod(nullptr, nullptr, nullptr))
- continue;
+ if (sym_ctx.function) {
+ CompilerDeclContext decl_ctx = sym_ctx.function->GetDeclContext();
- AddOneFunction(context, sym_ctx.function, NULL, current_id);
- context.m_found.function_with_type_info = true;
- context.m_found.function = true;
- } else if (sym_ctx.symbol) {
- if (sym_ctx.symbol->GetType() == eSymbolTypeReExported && target) {
- sym_ctx.symbol = sym_ctx.symbol->ResolveReExportedSymbol(*target);
- if (sym_ctx.symbol == NULL)
- continue;
- }
+ if (!decl_ctx)
+ continue;
- if (sym_ctx.symbol->IsExternal())
- extern_symbol = sym_ctx.symbol;
- else
- non_extern_symbol = sym_ctx.symbol;
+ // Filter out class/instance methods.
+ if (decl_ctx.IsClassMethod(nullptr, nullptr, nullptr))
+ continue;
+
+ AddOneFunction(context, sym_ctx.function, NULL, current_id);
+ context.m_found.function_with_type_info = true;
+ context.m_found.function = true;
+ } else if (sym_ctx.symbol) {
+ if (sym_ctx.symbol->GetType() == eSymbolTypeReExported && target) {
+ sym_ctx.symbol = sym_ctx.symbol->ResolveReExportedSymbol(*target);
+ if (sym_ctx.symbol == NULL)
+ continue;
}
+
+ if (sym_ctx.symbol->IsExternal())
+ extern_symbol = sym_ctx.symbol;
+ else
+ non_extern_symbol = sym_ctx.symbol;
}
+ }
- if (!context.m_found.function_with_type_info) {
- for (clang::NamedDecl *decl : decls_from_modules) {
- if (llvm::isa<clang::FunctionDecl>(decl)) {
- clang::NamedDecl *copied_decl =
- llvm::cast_or_null<FunctionDecl>(m_ast_importer_sp->CopyDecl(
- m_ast_context, &decl->getASTContext(), decl));
- if (copied_decl) {
- context.AddNamedDecl(copied_decl);
- context.m_found.function_with_type_info = true;
- }
+ if (!context.m_found.function_with_type_info) {
+ for (clang::NamedDecl *decl : decls_from_modules) {
+ if (llvm::isa<clang::FunctionDecl>(decl)) {
+ clang::NamedDecl *copied_decl =
+ llvm::cast_or_null<FunctionDecl>(m_ast_importer_sp->CopyDecl(
+ m_ast_context, &decl->getASTContext(), decl));
+ if (copied_decl) {
+ context.AddNamedDecl(copied_decl);
+ context.m_found.function_with_type_info = true;
}
}
}
+ }
- if (!context.m_found.function_with_type_info) {
- if (extern_symbol) {
- AddOneFunction(context, NULL, extern_symbol, current_id);
- context.m_found.function = true;
- } else if (non_extern_symbol) {
- AddOneFunction(context, NULL, non_extern_symbol, current_id);
- context.m_found.function = true;
- }
+ if (!context.m_found.function_with_type_info) {
+ if (extern_symbol) {
+ AddOneFunction(context, NULL, extern_symbol, current_id);
+ context.m_found.function = true;
+ } else if (non_extern_symbol) {
+ AddOneFunction(context, NULL, non_extern_symbol, current_id);
+ context.m_found.function = true;
}
}
+ }
- if (!context.m_found.function_with_type_info) {
- // Try the modules next.
+ if (!context.m_found.function_with_type_info) {
+ // Try the modules next.
- do {
- if (ClangModulesDeclVendor *modules_decl_vendor =
- m_target->GetClangModulesDeclVendor()) {
- bool append = false;
- uint32_t max_matches = 1;
- std::vector<clang::NamedDecl *> decls;
+ do {
+ if (ClangModulesDeclVendor *modules_decl_vendor =
+ m_target->GetClangModulesDeclVendor()) {
+ bool append = false;
+ uint32_t max_matches = 1;
+ std::vector<clang::NamedDecl *> decls;
- if (!modules_decl_vendor->FindDecls(name, append, max_matches,
- decls))
- break;
+ if (!modules_decl_vendor->FindDecls(name, append, max_matches, decls))
+ break;
- clang::NamedDecl *const decl_from_modules = decls[0];
+ clang::NamedDecl *const decl_from_modules = decls[0];
- if (llvm::isa<clang::FunctionDecl>(decl_from_modules)) {
- if (log) {
- log->Printf(" CAS::FEVD[%u] Matching function found for "
- "\"%s\" in the modules",
- current_id, name.GetCString());
- }
+ if (llvm::isa<clang::FunctionDecl>(decl_from_modules)) {
+ if (log) {
+ log->Printf(" CAS::FEVD[%u] Matching function found for "
+ "\"%s\" in the modules",
+ current_id, name.GetCString());
+ }
- clang::Decl *copied_decl = m_ast_importer_sp->CopyDecl(
- m_ast_context, &decl_from_modules->getASTContext(),
- decl_from_modules);
- clang::FunctionDecl *copied_function_decl =
- copied_decl ? dyn_cast<clang::FunctionDecl>(copied_decl)
- : nullptr;
+ clang::Decl *copied_decl = m_ast_importer_sp->CopyDecl(
+ m_ast_context, &decl_from_modules->getASTContext(),
+ decl_from_modules);
+ clang::FunctionDecl *copied_function_decl =
+ copied_decl ? dyn_cast<clang::FunctionDecl>(copied_decl)
+ : nullptr;
- if (!copied_function_decl) {
- if (log)
- log->Printf(" CAS::FEVD[%u] - Couldn't export a function "
- "declaration from the modules",
- current_id);
+ if (!copied_function_decl) {
+ if (log)
+ log->Printf(" CAS::FEVD[%u] - Couldn't export a function "
+ "declaration from the modules",
+ current_id);
- break;
- }
+ break;
+ }
- MaybeRegisterFunctionBody(copied_function_decl);
+ MaybeRegisterFunctionBody(copied_function_decl);
- context.AddNamedDecl(copied_function_decl);
+ context.AddNamedDecl(copied_function_decl);
- context.m_found.function_with_type_info = true;
- context.m_found.function = true;
- } else if (llvm::isa<clang::VarDecl>(decl_from_modules)) {
- if (log) {
- log->Printf(" CAS::FEVD[%u] Matching variable found for "
- "\"%s\" in the modules",
- current_id, name.GetCString());
- }
+ context.m_found.function_with_type_info = true;
+ context.m_found.function = true;
+ } else if (llvm::isa<clang::VarDecl>(decl_from_modules)) {
+ if (log) {
+ log->Printf(" CAS::FEVD[%u] Matching variable found for "
+ "\"%s\" in the modules",
+ current_id, name.GetCString());
+ }
- clang::Decl *copied_decl = m_ast_importer_sp->CopyDecl(
- m_ast_context, &decl_from_modules->getASTContext(),
- decl_from_modules);
- clang::VarDecl *copied_var_decl =
- copied_decl ? dyn_cast_or_null<clang::VarDecl>(copied_decl)
- : nullptr;
+ clang::Decl *copied_decl = m_ast_importer_sp->CopyDecl(
+ m_ast_context, &decl_from_modules->getASTContext(),
+ decl_from_modules);
+ clang::VarDecl *copied_var_decl =
+ copied_decl ? dyn_cast_or_null<clang::VarDecl>(copied_decl)
+ : nullptr;
- if (!copied_var_decl) {
- if (log)
- log->Printf(" CAS::FEVD[%u] - Couldn't export a variable "
- "declaration from the modules",
- current_id);
+ if (!copied_var_decl) {
+ if (log)
+ log->Printf(" CAS::FEVD[%u] - Couldn't export a variable "
+ "declaration from the modules",
+ current_id);
- break;
- }
+ break;
+ }
- context.AddNamedDecl(copied_var_decl);
+ context.AddNamedDecl(copied_var_decl);
- context.m_found.variable = true;
- }
+ context.m_found.variable = true;
}
- } while (0);
- }
-
- if (target && !context.m_found.variable && !namespace_decl) {
- // We couldn't find a non-symbol variable for this. Now we'll hunt for
- // a generic
- // data symbol, and -- if it is found -- treat it as a variable.
-
- const Symbol *data_symbol = FindGlobalDataSymbol(*target, name);
-
- if (data_symbol) {
- std::string warning("got name from symbols: ");
- warning.append(name.AsCString());
- const unsigned diag_id =
- m_ast_context->getDiagnostics().getCustomDiagID(
- clang::DiagnosticsEngine::Level::Warning, "%0");
- m_ast_context->getDiagnostics().Report(diag_id) << warning.c_str();
- AddOneGenericVariable(context, *data_symbol, current_id);
- context.m_found.variable = true;
}
+ } while (0);
+ }
+
+ if (target && !context.m_found.variable && !namespace_decl) {
+ // We couldn't find a non-symbol variable for this. Now we'll hunt for
+ // a generic
+ // data symbol, and -- if it is found -- treat it as a variable.
+
+ const Symbol *data_symbol = FindGlobalDataSymbol(*target, name);
+
+ if (data_symbol) {
+ std::string warning("got name from symbols: ");
+ warning.append(name.AsCString());
+ const unsigned diag_id =
+ m_ast_context->getDiagnostics().getCustomDiagID(
+ clang::DiagnosticsEngine::Level::Warning, "%0");
+ m_ast_context->getDiagnostics().Report(diag_id) << warning.c_str();
+ AddOneGenericVariable(context, *data_symbol, current_id);
+ context.m_found.variable = true;
}
}
}
diff --git a/source/Plugins/InstrumentationRuntime/ThreadSanitizer/ThreadSanitizerRuntime.cpp b/source/Plugins/InstrumentationRuntime/ThreadSanitizer/ThreadSanitizerRuntime.cpp
index cbc77ebe9987..562d988be837 100644
--- a/source/Plugins/InstrumentationRuntime/ThreadSanitizer/ThreadSanitizerRuntime.cpp
+++ b/source/Plugins/InstrumentationRuntime/ThreadSanitizer/ThreadSanitizerRuntime.cpp
@@ -588,7 +588,7 @@ addr_t ThreadSanitizerRuntime::GetFirstNonInternalFramePc(
ModuleSP runtime_module_sp = GetRuntimeModuleSP();
StructuredData::Array *trace_array = trace->GetAsArray();
- for (int i = 0; i < trace_array->GetSize(); i++) {
+ for (size_t i = 0; i < trace_array->GetSize(); i++) {
if (skip_one_frame && i == 0)
continue;
diff --git a/source/Plugins/Language/CPlusPlus/LibCxx.cpp b/source/Plugins/Language/CPlusPlus/LibCxx.cpp
index 72d99671612c..659a12b7eecf 100644
--- a/source/Plugins/Language/CPlusPlus/LibCxx.cpp
+++ b/source/Plugins/Language/CPlusPlus/LibCxx.cpp
@@ -395,7 +395,8 @@ static bool ExtractLibcxxStringInfo(ValueObject &valobj,
if (!D)
return false;
- ValueObjectSP layout_decider(D->GetChildAtIndexPath({0, 0}));
+ ValueObjectSP layout_decider(
+ D->GetChildAtIndexPath(llvm::ArrayRef<size_t>({0, 0})));
// this child should exist
if (!layout_decider)
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index e2902d5ef787..1d8b759d2fa8 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -3682,7 +3682,7 @@ DWARFASTParserClang::GetClangDeclContextForDIE(const DWARFDIE &die) {
break;
case DW_TAG_lexical_block:
- decl_ctx = (clang::DeclContext *)ResolveBlockDIE(die);
+ decl_ctx = GetDeclContextForBlock(die);
try_parsing_type = false;
break;
@@ -3704,6 +3704,69 @@ DWARFASTParserClang::GetClangDeclContextForDIE(const DWARFDIE &die) {
return nullptr;
}
+static bool IsSubroutine(const DWARFDIE &die) {
+ switch (die.Tag()) {
+ case DW_TAG_subprogram:
+ case DW_TAG_inlined_subroutine:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static DWARFDIE GetContainingFunctionWithAbstractOrigin(const DWARFDIE &die) {
+ for (DWARFDIE candidate = die; candidate; candidate = candidate.GetParent()) {
+ if (IsSubroutine(candidate)) {
+ if (candidate.GetReferencedDIE(DW_AT_abstract_origin)) {
+ return candidate;
+ } else {
+ return DWARFDIE();
+ }
+ }
+ }
+ assert(!"Shouldn't call GetContainingFunctionWithAbstractOrigin on something "
+ "not in a function");
+ return DWARFDIE();
+}
+
+static DWARFDIE FindAnyChildWithAbstractOrigin(const DWARFDIE &context) {
+ for (DWARFDIE candidate = context.GetFirstChild(); candidate.IsValid();
+ candidate = candidate.GetSibling()) {
+ if (candidate.GetReferencedDIE(DW_AT_abstract_origin)) {
+ return candidate;
+ }
+ }
+ return DWARFDIE();
+}
+
+static DWARFDIE FindFirstChildWithAbstractOrigin(const DWARFDIE &block,
+ const DWARFDIE &function) {
+ assert(IsSubroutine(function));
+ for (DWARFDIE context = block; context != function.GetParent();
+ context = context.GetParent()) {
+ assert(!IsSubroutine(context) || context == function);
+ if (DWARFDIE child = FindAnyChildWithAbstractOrigin(context)) {
+ return child;
+ }
+ }
+ return DWARFDIE();
+}
+
+clang::DeclContext *
+DWARFASTParserClang::GetDeclContextForBlock(const DWARFDIE &die) {
+ assert(die.Tag() == DW_TAG_lexical_block);
+ DWARFDIE containing_function_with_abstract_origin =
+ GetContainingFunctionWithAbstractOrigin(die);
+ if (!containing_function_with_abstract_origin) {
+ return (clang::DeclContext *)ResolveBlockDIE(die);
+ }
+ DWARFDIE child = FindFirstChildWithAbstractOrigin(
+ die, containing_function_with_abstract_origin);
+ CompilerDeclContext decl_context =
+ GetDeclContextContainingUIDFromDWARF(child);
+ return (clang::DeclContext *)decl_context.GetOpaqueDeclContext();
+}
+
clang::BlockDecl *DWARFASTParserClang::ResolveBlockDIE(const DWARFDIE &die) {
if (die && die.Tag() == DW_TAG_lexical_block) {
clang::BlockDecl *decl =
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h b/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
index 3d6d08eef9ed..57c1fc07b2b6 100644
--- a/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
+++ b/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
@@ -66,6 +66,8 @@ protected:
class DelayedAddObjCClassProperty;
typedef std::vector<DelayedAddObjCClassProperty> DelayedPropertyList;
+ clang::DeclContext *GetDeclContextForBlock(const DWARFDIE &die);
+
clang::BlockDecl *ResolveBlockDIE(const DWARFDIE &die);
clang::NamespaceDecl *ResolveNamespaceDIE(const DWARFDIE &die);
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index 856c371636d9..973b5ef9fb46 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -3051,7 +3051,13 @@ SymbolFileDWARF::GetDeclContextDIEContainingDIE(const DWARFDIE &orig_die) {
case DW_TAG_lexical_block:
case DW_TAG_subprogram:
return die;
-
+ case DW_TAG_inlined_subroutine: {
+ DWARFDIE abs_die = die.GetReferencedDIE(DW_AT_abstract_origin);
+ if (abs_die) {
+ return abs_die;
+ }
+ break;
+ }
default:
break;
}
diff --git a/tools/debugserver/source/RNBRemote.cpp b/tools/debugserver/source/RNBRemote.cpp
index 4c1f27eb1cb8..94260c619293 100644
--- a/tools/debugserver/source/RNBRemote.cpp
+++ b/tools/debugserver/source/RNBRemote.cpp
@@ -3614,7 +3614,7 @@ rnb_err_t RNBRemote::HandlePacket_qSupported(const char *p) {
bool enable_compression = false;
(void)enable_compression;
-#if (defined (TARGET_OS_WATCH) && TARGET_OS_WATCHOS == 1) || (defined (TARGET_OS_IOS) && TARGET_OS_IOS == 1) || (defined (TARGET_OS_TVOS) && TARGET_OS_TVOS == 1)
+#if (defined (TARGET_OS_WATCH) && TARGET_OS_WATCH == 1) || (defined (TARGET_OS_IOS) && TARGET_OS_IOS == 1) || (defined (TARGET_OS_TV) && TARGET_OS_TV == 1)
enable_compression = true;
#endif
diff --git a/unittests/Host/SocketAddressTest.cpp b/unittests/Host/SocketAddressTest.cpp
index 3c18137ac063..17f9ccc19028 100644
--- a/unittests/Host/SocketAddressTest.cpp
+++ b/unittests/Host/SocketAddressTest.cpp
@@ -12,8 +12,21 @@
#include "lldb/Host/SocketAddress.h"
namespace {
-class SocketAddressTest : public ::testing::Test {};
-}
+class SocketAddressTest : public testing::Test {
+public:
+ static void SetUpTestCase() {
+#ifdef _MSC_VER
+ WSADATA data;
+ ASSERT_EQ(0, WSAStartup(MAKEWORD(2, 2), &data));
+#endif
+ }
+ static void TearDownTestCase() {
+#ifdef _MSC_VER
+ ASSERT_EQ(0, WSACleanup());
+#endif
+ }
+};
+} // namespace
using namespace lldb_private;
@@ -34,6 +47,14 @@ TEST_F(SocketAddressTest, Set) {
ASSERT_EQ(1139, sa.GetPort());
}
+TEST_F(SocketAddressTest, GetAddressInfo) {
+ auto addr = SocketAddress::GetAddressInfo("127.0.0.1", nullptr, AF_UNSPEC,
+ SOCK_STREAM, IPPROTO_TCP);
+ ASSERT_EQ(1u, addr.size());
+ EXPECT_EQ(AF_INET, addr[0].GetFamily());
+ EXPECT_EQ("127.0.0.1", addr[0].GetIPAddress());
+}
+
#ifdef _WIN32
// we need to test our inet_ntop implementation for Windows XP
diff --git a/www/build.html b/www/build.html
index 5734bf9573aa..fbb35ae554ed 100755
--- a/www/build.html
+++ b/www/build.html
@@ -354,9 +354,8 @@
the target architecture. Since you already have a checkout of clang and lldb, you
can compile a host version of clang in a separate folder and use that.
Alternatively you can use system clang or even cross-gcc if your distribution
- provides such packages (e.g., <code>g++-aarch64-linux-gnu</code> on Ubuntu). On
- Android, a working toolchain can be produced by downloading the Android NDK and
- running the contained <code>make-standalone-toolchain.sh</code> script.
+ provides such packages (e.g., <code>g++-aarch64-linux-gnu</code>
+ on Ubuntu).
</p>
<p>
@@ -381,11 +380,6 @@
</p>
<p>
- In the case of Android, all required headers and libraries are provided by the
- aforementioned <code>make-standalone-toolchain.sh</code> script.
- </p>
-
- <p>
Once all of the dependencies are in place, it's just a matter of configuring the
build system with the locations and arguments of all the necessary tools. The most
important cmake options here are:
@@ -472,38 +466,37 @@
<h3>Example 2: Cross-compiling for Android on Linux</h3>
<p>
- All tools needed to build LLDB for android are available in the Android NDK. For
- example, we can produce an x86 toolchain along with all the libraries and headers
- by running
+ In the case of Android, the toolchain and all required headers and
+ libraries are available in the Android NDK.
</p>
- <code>
- ./build/tools/make-standalone-toolchain.sh \<br/>
- --platform=android-21 \<br/>
- --toolchain=x86-4.9 \<br/>
- --install-dir=$HOME/Toolchains/x86-android-toolchain
- </code>
+
<p>
- from inside the unzipped NDK. Toolchains for other architectures can be produced in
- a similar manner.
+ The NDK also contains a cmake toolchain file, which makes
+ configuring the build much simpler. The compiler, include and
+ library paths will be configured by the toolchain file and all you
+ need to do is to select the architecture (ANDROID_ABI) and
+ platform level (ANDROID_PLATFORM, should be at least 21). You will
+ also need to set ANDROID_ALLOW_UNDEFINED_SYMBOLS=On, as the
+ toolchain file defaults to "no undefined symbols in shared
+ libraries", which is not compatible with some llvm libraries. The
+ first version of NDK which supports this approach is r14.
</p>
-
<p>
- For Android we provide a Android.cmake script which sets a lot of the required
- options automatically. A cmake build can therefore be prepared with the following parameters:
+ For example, the following arguments are sufficient to configure
+ an android arm64 build:
</p>
<code>
- -DCMAKE_TOOLCHAIN_FILE=cmake/platforms/Android.cmake \<br/>
- -DANDROID_TOOLCHAIN_DIR=$HOME/Toolchains/x86-android-toolchain \<br/>
- -DANDROID_ABI=x86 \<br/>
- -DLLVM_HOST_TRIPLE=i386-unknown-linux-android \<br/>
- -DLLVM_TABLEGEN=&lt;path-to-host&gt;/bin/llvm-tblgen \<br/>
- -DCLANG_TABLEGEN=&lt;path-to-host&gt;/bin/clang-tblgen
+ -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK_HOME/build/cmake/android.toolchain.cmake \<br/>
+ -DANDROID_ABI=arm64-v8a \<br/>
+ -DANDROID_PLATFORM=android-21 \<br/>
+ -DANDROID_ALLOW_UNDEFINED_SYMBOLS=On \<br/>
+ -DLLVM_HOST_TRIPLE=aarch64-unknown-linux-android \<br/>
+ -DCROSS_TOOLCHAIN_FLAGS_NATIVE='-DCMAKE_C_COMPILER=cc;-DCMAKE_CXX_COMPILER=c++' <br/>
</code>
<p>
- Note that the full LLVM build is not functional on android yet, so simply running
- <code>ninja</code> will not work. You will need to manually specify the target you
- want to build: <code>lldb</code>, <code>lldb-server</code>, etc.
+ Note that currently only lldb-server is functional on android. The
+ lldb client is not supported and unlikely to work.
</p>
</div>
<div class="postfooter"></div>