d-millar created this revision.
d-millar added a reviewer: LLDB.
Herald added subscribers: teemperor, mgorny.
d-millar requested review of this revision.

The patch include files necessary to extend the Scripting Bridge API with Java. 
 The edits follow the existing patterns for Python and Lua.


Repository:
  rLLDB LLDB

https://reviews.llvm.org/D111409

Files:
  lldb/CMakeLists.txt
  lldb/bindings/CMakeLists.txt
  lldb/bindings/java/CMakeLists.txt
  lldb/bindings/java/java-typemaps.swig
  lldb/bindings/java/java.swig
  lldb/cmake/modules/FindJavaAndSwig.cmake
  lldb/include/lldb/Host/Config.h.cmake
  lldb/source/API/CMakeLists.txt
  lldb/source/API/SBDebugger.cpp
  lldb/source/API/liblldb-private.exports
  lldb/source/API/liblldb.exports
  patch

Index: patch
===================================================================
--- /dev/null
+++ patch
@@ -0,0 +1,2403 @@
+diff --git a/lldb/CMakeLists.txt b/lldb/CMakeLists.txt
+index 594c769141b4..faf3846a0a16 100644
+--- a/lldb/CMakeLists.txt
++++ b/lldb/CMakeLists.txt
+@@ -1,106 +1,106 @@
+ cmake_minimum_required(VERSION 3.13.4)
+ 
+ # Add path for custom modules.
+ set(CMAKE_MODULE_PATH
+   ${CMAKE_MODULE_PATH}
+   "${CMAKE_CURRENT_SOURCE_DIR}/cmake"
+   "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules"
+   )
+ 
+ # If we are not building as part of LLVM, build LLDB as a standalone project,
+ # using LLVM as an external library.
+ if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
+   project(lldb)
+   include(LLDBStandalone)
+ 
+   set(CMAKE_CXX_STANDARD 14 CACHE STRING "C++ standard to conform to")
+   set(CMAKE_CXX_STANDARD_REQUIRED YES)
+   set(CMAKE_CXX_EXTENSIONS NO)
+ endif()
+ 
+ include(LLDBConfig)
+ include(AddLLDB)
+ 
+ # Define the LLDB_CONFIGURATION_xxx matching the build type.
+ if(uppercase_CMAKE_BUILD_TYPE STREQUAL "DEBUG" )
+   add_definitions(-DLLDB_CONFIGURATION_DEBUG)
+ endif()
+ 
+ if (WIN32)
+   add_definitions(-D_ENABLE_EXTENDED_ALIGNED_STORAGE)
+ endif()
+ 
+ if (LLDB_ENABLE_PYTHON)
+   if (NOT CMAKE_CROSSCOMPILING)
+     execute_process(
+       COMMAND ${Python3_EXECUTABLE}
+           -c "import distutils.sysconfig; print(distutils.sysconfig.get_python_lib(True, False, ''))"
+       OUTPUT_VARIABLE LLDB_PYTHON_DEFAULT_RELATIVE_PATH
+       OUTPUT_STRIP_TRAILING_WHITESPACE)
+ 
+     file(TO_CMAKE_PATH ${LLDB_PYTHON_DEFAULT_RELATIVE_PATH} LLDB_PYTHON_DEFAULT_RELATIVE_PATH)
+   else ()
+     if ("${LLDB_PYTHON_RELATIVE_PATH}" STREQUAL "")
+       message(FATAL_ERROR
+         "Crosscompiling LLDB with Python requires manually setting
+         LLDB_PYTHON_RELATIVE_PATH.")
+     endif ()
+   endif ()
+ 
+   set(LLDB_PYTHON_RELATIVE_PATH ${LLDB_PYTHON_DEFAULT_RELATIVE_PATH}
+     CACHE STRING "Path where Python modules are installed, relative to install prefix")
+ endif ()
+ 
+-if (LLDB_ENABLE_PYTHON OR LLDB_ENABLE_LUA)
++if (LLDB_ENABLE_PYTHON OR LLDB_ENABLE_LUA OR LLDB_ENABLE_JAVA)
+   add_subdirectory(bindings)
+ endif ()
+ 
+ # We need the headers generated by instrinsics_gen before we can compile
+ # any source file in LLDB as the imported Clang modules might include
+ # some of these generated headers. This approach is copied from Clang's main
+ # CMakeLists.txt, so it should kept in sync the code in Clang which was added
+ # in llvm-svn 308844.
+ if(LLVM_ENABLE_MODULES)
+   list(APPEND LLVM_COMMON_DEPENDS intrinsics_gen)
+ endif()
+ 
+ if(CMAKE_CROSSCOMPILING AND LLDB_BUILT_STANDALONE AND NOT LLDB_TABLEGEN_EXE)
+   set(LLVM_USE_HOST_TOOLS ON)
+   include(CrossCompile)
+   if (NOT NATIVE_LLVM_DIR OR NOT NATIVE_Clang_DIR)
+     message(FATAL_ERROR
+       "Crosscompiling standalone requires the variables NATIVE_{CLANG,LLVM}_DIR
+       for building the native lldb-tblgen used during the build process.")
+   endif()
+   llvm_create_cross_target(lldb NATIVE "" Release
+     -DLLVM_DIR=${NATIVE_LLVM_DIR}
+     -DClang_DIR=${NATIVE_Clang_DIR})
+ endif()
+ 
+ # TableGen
+ add_subdirectory(utils/TableGen)
+ 
+ add_subdirectory(source)
+ add_subdirectory(tools)
+ add_subdirectory(docs)
+ 
+ if (LLDB_ENABLE_PYTHON)
+   if(LLDB_BUILD_FRAMEWORK)
+     set(lldb_python_target_dir "${LLDB_FRAMEWORK_ABSOLUTE_BUILD_DIR}/LLDB.framework/Resources/Python/lldb")
+   else()
+     set(lldb_python_target_dir "${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${LLDB_PYTHON_RELATIVE_PATH}/lldb")
+   endif()
+   get_target_property(lldb_python_bindings_dir swig_wrapper_python BINARY_DIR)
+   finish_swig_python("lldb-python" "${lldb_python_bindings_dir}" "${lldb_python_target_dir}")
+ endif()
+ 
+ option(LLDB_INCLUDE_TESTS "Generate build targets for the LLDB unit tests." ${LLVM_INCLUDE_TESTS})
+ if(LLDB_INCLUDE_TESTS)
+   add_subdirectory(test)
+   add_subdirectory(unittests)
+   add_subdirectory(utils)
+ endif()
+ 
+ if(LLDB_BUILT_STANDALONE AND NOT LLVM_ENABLE_IDE)
+   llvm_distribution_add_targets()
+ endif()
+diff --git a/lldb/bindings/CMakeLists.txt b/lldb/bindings/CMakeLists.txt
+index 9759b069fdc4..780413104d7f 100644
+--- a/lldb/bindings/CMakeLists.txt
++++ b/lldb/bindings/CMakeLists.txt
+@@ -1,40 +1,45 @@
+ file(GLOB SWIG_INTERFACES interface/*.i)
+ file(GLOB_RECURSE SWIG_SOURCES *.swig)
+ file(GLOB SWIG_HEADERS
+   ${LLDB_SOURCE_DIR}/include/lldb/API/*.h
+   ${LLDB_SOURCE_DIR}/include/lldb/*.h
+ )
+ file(GLOB SWIG_PRIVATE_HEADERS
+   ${LLDB_SOURCE_DIR}/include/lldb/lldb-private*.h
+ )
+ foreach(private_header ${SWIG_PRIVATE_HEADERS})
+   list(REMOVE_ITEM SWIG_HEADERS ${private_header})
+ endforeach()
+ 
+ if(LLDB_BUILD_FRAMEWORK)
+   set(framework_arg --framework --target-platform Darwin)
+ endif()
+ 
+ if(APPLE)
+   set(DARWIN_EXTRAS "-D__APPLE__")
+ else()
+   set(DARWIN_EXTRAS "")
+ endif()
+ 
+ set(SWIG_COMMON_FLAGS
+   -c++
+   -features autodoc
+   -I${LLDB_SOURCE_DIR}/include
+   -I${CMAKE_CURRENT_SOURCE_DIR}
+   -D__STDC_LIMIT_MACROS
+   -D__STDC_CONSTANT_MACROS
+   ${DARWIN_EXTRAS}
+ )
+ 
+ if (LLDB_ENABLE_PYTHON)
+   add_subdirectory(python)
+ endif()
+ 
+ if (LLDB_ENABLE_LUA)
+   add_subdirectory(lua)
+ endif()
++
++if (LLDB_ENABLE_JAVA)
++  add_subdirectory(java)
++endif()
++
+diff --git a/lldb/include/lldb/Host/Config.h.cmake b/lldb/include/lldb/Host/Config.h.cmake
+index 777a6d1be541..d5bf522e7e97 100644
+--- a/lldb/include/lldb/Host/Config.h.cmake
++++ b/lldb/include/lldb/Host/Config.h.cmake
+@@ -1,54 +1,56 @@
+ //===-- Config.h -----------------------------------------------*- C++ -*-===//
+ //
+ // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+ // See https://llvm.org/LICENSE.txt for license information.
+ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+ //
+ //===----------------------------------------------------------------------===//
+ 
+ #ifndef LLDB_HOST_CONFIG_H
+ #define LLDB_HOST_CONFIG_H
+ 
+ #cmakedefine01 LLDB_EDITLINE_USE_WCHAR
+ 
+ #cmakedefine01 LLDB_HAVE_EL_RFUNC_T
+ 
+ #cmakedefine01 HAVE_SYS_EVENT_H
+ 
+ #cmakedefine01 HAVE_PPOLL
+ 
+ #cmakedefine01 HAVE_PTSNAME_R
+ 
+ #cmakedefine01 HAVE_PROCESS_VM_READV
+ 
+ #cmakedefine01 HAVE_NR_PROCESS_VM_READV
+ 
+ #ifndef HAVE_LIBCOMPRESSION
+ #cmakedefine HAVE_LIBCOMPRESSION
+ #endif
+ 
+ #cmakedefine01 LLDB_ENABLE_POSIX
+ 
+ #cmakedefine01 LLDB_ENABLE_TERMIOS
+ 
+ #cmakedefine01 LLDB_ENABLE_LZMA
+ 
+ #cmakedefine01 LLDB_ENABLE_CURSES
+ 
+ #cmakedefine01 CURSES_HAVE_NCURSES_CURSES_H
+ 
+ #cmakedefine01 LLDB_ENABLE_LIBEDIT
+ 
+ #cmakedefine01 LLDB_ENABLE_LIBXML2
+ 
++#cmakedefine01 LLDB_ENABLE_JAVA
++
+ #cmakedefine01 LLDB_ENABLE_LUA
+ 
+ #cmakedefine01 LLDB_ENABLE_PYTHON
+ 
+ #cmakedefine01 LLDB_EMBED_PYTHON_HOME
+ 
+ #cmakedefine LLDB_PYTHON_HOME R"(${LLDB_PYTHON_HOME})"
+ 
+ #define LLDB_LIBDIR_SUFFIX "${LLVM_LIBDIR_SUFFIX}"
+ 
+ #endif // #ifndef LLDB_HOST_CONFIG_H
+diff --git a/lldb/source/API/CMakeLists.txt b/lldb/source/API/CMakeLists.txt
+index 2e33f5c05c1a..014ae8b240f1 100644
+--- a/lldb/source/API/CMakeLists.txt
++++ b/lldb/source/API/CMakeLists.txt
+@@ -1,216 +1,244 @@
+ if ( CMAKE_SYSTEM_NAME MATCHES "Windows" )
+   add_definitions( -DEXPORT_LIBLLDB )
+ endif()
+ 
+ get_property(LLDB_ALL_PLUGINS GLOBAL PROPERTY LLDB_PLUGINS)
+ 
+ if(LLDB_BUILD_FRAMEWORK)
+   set(option_install_prefix INSTALL_PREFIX ${LLDB_FRAMEWORK_INSTALL_DIR})
+   set(option_framework FRAMEWORK)
+ endif()
+ 
+ if(LLDB_ENABLE_PYTHON)
+   get_target_property(python_bindings_dir swig_wrapper_python BINARY_DIR)
+   set(lldb_python_wrapper ${python_bindings_dir}/LLDBWrapPython.cpp)
+ endif()
+ 
+ if(LLDB_ENABLE_LUA)
+   get_target_property(lua_bindings_dir swig_wrapper_lua BINARY_DIR)
+   set(lldb_lua_wrapper ${lua_bindings_dir}/LLDBWrapLua.cpp)
+ endif()
+ 
++if(LLDB_ENABLE_JAVA)
++  get_target_property(java_bindings_dir swig_wrapper_java BINARY_DIR)
++  set(lldb_java_wrapper ${java_bindings_dir}/LLDBWrapJava.cpp)
++endif()
++
+ add_lldb_library(liblldb SHARED ${option_framework}
+   SBAddress.cpp
+   SBAttachInfo.cpp
+   SBBlock.cpp
+   SBBreakpoint.cpp
+   SBBreakpointLocation.cpp
+   SBBreakpointName.cpp
+   SBBreakpointOptionCommon.cpp
+   SBBroadcaster.cpp
+   SBCommandInterpreter.cpp
+   SBCommandInterpreterRunOptions.cpp
+   SBCommandReturnObject.cpp
+   SBCommunication.cpp
+   SBCompileUnit.cpp
+   SBData.cpp
+   SBDebugger.cpp
+   SBDeclaration.cpp
+   SBEnvironment.cpp
+   SBError.cpp
+   SBEvent.cpp
+   SBExecutionContext.cpp
+   SBExpressionOptions.cpp
+   SBFileSpec.cpp
+   SBFile.cpp
+   SBFileSpecList.cpp
+   SBFrame.cpp
+   SBFunction.cpp
+   SBHostOS.cpp
+   SBInstruction.cpp
+   SBInstructionList.cpp
+   SBLanguageRuntime.cpp
+   SBLaunchInfo.cpp
+   SBLineEntry.cpp
+   SBListener.cpp
+   SBMemoryRegionInfo.cpp
+   SBMemoryRegionInfoList.cpp
+   SBModule.cpp
+   SBModuleSpec.cpp
+   SBPlatform.cpp
+   SBProcess.cpp
+   SBProcessInfo.cpp
+   SBQueue.cpp
+   SBQueueItem.cpp
+   SBReproducer.cpp
+   SBSection.cpp
+   SBSourceManager.cpp
+   SBStream.cpp
+   SBStringList.cpp
+   SBStructuredData.cpp
+   SBSymbol.cpp
+   SBSymbolContext.cpp
+   SBSymbolContextList.cpp
+   SBTarget.cpp
+   SBThread.cpp
+   SBThreadCollection.cpp
+   SBThreadPlan.cpp
+   SBTrace.cpp
++  SBTraceOptions.cpp
+   SBType.cpp
+   SBTypeCategory.cpp
+   SBTypeEnumMember.cpp
+   SBTypeFilter.cpp
+   SBTypeFormat.cpp
+   SBTypeNameSpecifier.cpp
+   SBTypeSummary.cpp
+   SBTypeSynthetic.cpp
+   SBValue.cpp
+   SBValueList.cpp
+   SBVariablesOptions.cpp
+   SBWatchpoint.cpp
+   SBUnixSignals.cpp
+   SystemInitializerFull.cpp
+   ${lldb_python_wrapper}
+   ${lldb_lua_wrapper}
++  ${lldb_java_wrapper}
+ 
+   LINK_LIBS
+     lldbBase
+     lldbBreakpoint
+     lldbCore
+     lldbDataFormatters
+     lldbExpression
+     lldbHost
+     lldbInitialization
+     lldbInterpreter
+     lldbSymbol
+     lldbTarget
+     lldbUtility
+     ${LLDB_ALL_PLUGINS}
+   LINK_COMPONENTS
+     Support
+ 
+   ${option_install_prefix}
+ )
+ 
+ # lib/pythonX.Y/dist-packages/lldb/_lldb.so is a symlink to lib/liblldb.so,
+ # which depends on lib/libLLVM*.so (BUILD_SHARED_LIBS) or lib/libLLVM-10git.so
+ # (LLVM_LINK_LLVM_DYLIB). Add an additional rpath $ORIGIN/../../../../lib so
+ # that _lldb.so can be loaded from Python.
+ if(LLDB_ENABLE_PYTHON AND (BUILD_SHARED_LIBS OR LLVM_LINK_LLVM_DYLIB) AND UNIX AND NOT APPLE)
+   set_property(TARGET liblldb APPEND PROPERTY INSTALL_RPATH "\$ORIGIN/../../../../lib${LLVM_LIBDIR_SUFFIX}")
+ endif()
+ 
+ if(Python3_RPATH)
+   set_property(TARGET liblldb APPEND PROPERTY INSTALL_RPATH "${Python3_RPATH}")
+   set_property(TARGET liblldb APPEND PROPERTY BUILD_RPATH   "${Python3_RPATH}")
+ endif()
+ 
+ 
+ if(LLDB_ENABLE_PYTHON)
+   add_dependencies(liblldb swig_wrapper_python)
+ 
+   if (MSVC)
+     set_property(SOURCE ${lldb_python_wrapper} APPEND_STRING PROPERTY COMPILE_FLAGS " /W0")
+   else()
+     set_property(SOURCE ${lldb_python_wrapper} APPEND_STRING PROPERTY COMPILE_FLAGS " -w")
+   endif()
+ 
+   set_source_files_properties(${lldb_python_wrapper} PROPERTIES GENERATED ON)
+   if (CLANG_CL)
+     set_property(SOURCE ${lldb_python_wrapper} APPEND_STRING
+       PROPERTY COMPILE_FLAGS " -Wno-unused-function")
+   endif()
+   if (LLVM_COMPILER_IS_GCC_COMPATIBLE AND
+       NOT "${CMAKE_SYSTEM_NAME}" MATCHES "Darwin")
+     set_property(SOURCE ${lldb_python_wrapper} APPEND_STRING
+       PROPERTY COMPILE_FLAGS " -Wno-sequence-point -Wno-cast-qual")
+   endif ()
+ endif()
+ 
+ if(LLDB_ENABLE_LUA)
+   add_dependencies(liblldb swig_wrapper_lua)
+   target_include_directories(liblldb PRIVATE ${LUA_INCLUDE_DIR})
+ 
+   if (MSVC)
+     set_property(SOURCE ${lldb_lua_wrapper} APPEND_STRING PROPERTY COMPILE_FLAGS " /W0")
+   else()
+     set_property(SOURCE ${lldb_lua_wrapper} APPEND_STRING PROPERTY COMPILE_FLAGS " -w")
+   endif()
+ 
+   set_source_files_properties(${lldb_lua_wrapper} PROPERTIES GENERATED ON)
+ endif()
+ 
++if(LLDB_ENABLE_JAVA)
++  add_dependencies(liblldb swig_wrapper_java)
++  target_include_directories(liblldb PRIVATE ${JAVA_INCLUDE_DIR})
++  target_include_directories(liblldb PRIVATE ${JAVA_INCLUDE_DIR}/darwin)
++
++  if (MSVC)
++    set_property(SOURCE ${lldb_java_wrapper} APPEND_STRING PROPERTY COMPILE_FLAGS " /W0")
++  else()
++    set_property(SOURCE ${lldb_java_wrapper} APPEND_STRING PROPERTY COMPILE_FLAGS " ")
++  endif()
++
++  set_source_files_properties(${lldb_java_wrapper} PROPERTIES GENERATED ON)
++endif()
++
++
+ set_target_properties(liblldb
+   PROPERTIES
+   VERSION ${LLDB_VERSION}
+ )
+ 
+ if (NOT CMAKE_SYSTEM_NAME MATCHES "Windows")
+   if (NOT LLDB_EXPORT_ALL_SYMBOLS)
+     # If we're not exporting all symbols, we'll want to explicitly set
+     # the exported symbols here.  This prevents 'log enable --stack ...'
+     # from working on some systems but limits the liblldb size.
+     MESSAGE("-- Symbols (liblldb): exporting all symbols from the lldb namespace")
+     add_llvm_symbol_exports(liblldb ${CMAKE_CURRENT_SOURCE_DIR}/liblldb.exports)
+   else()
+     # Don't use an explicit export.  Instead, tell the linker to
+     # export all symbols.
+     MESSAGE("-- Symbols (liblldb): exporting all symbols from the lldb and lldb_private namespaces")
+     add_llvm_symbol_exports(liblldb ${CMAKE_CURRENT_SOURCE_DIR}/liblldb-private.exports)
+   endif()
+   set_target_properties(liblldb_exports PROPERTIES FOLDER "lldb misc")
+ endif()
+ 
+-if (NOT MSVC)
++if (MSVC)
++  # Only MSVC has the ABI compatibility problem and avoids using FindPythonLibs,
++  # so only it needs to explicitly link against ${Python3_LIBRARIES}
++  if (LLDB_ENABLE_PYTHON)
++    target_link_libraries(liblldb PRIVATE ${Python3_LIBRARIES})
++  endif()
++else()
+   set_target_properties(liblldb
+     PROPERTIES
+     OUTPUT_NAME lldb
+   )
+ endif()
+ 
+ # The Clang expression parser in LLDB requires the Clang resource directory to function.
+ if (TARGET clang-resource-headers)
+   # If building alongside Clang, just add a dependency to ensure it is build together with liblldb.
+   add_dependencies(liblldb clang-resource-headers)
+ else()
+   # In a standalone build create a symlink from the LLDB library directory that points to the
+   # resource directory in the Clang library directory. LLDB searches relative to its install path,
+   # and the symlink is created in the same relative path as the resource directory of Clang when
+   # building alongside Clang.
+   # When building the LLDB framework, this isn't necessary as there we copy everything we need into
+   # the framework (including the Clang resourece directory).
+   if(NOT LLDB_BUILD_FRAMEWORK)
+     set(LLDB_CLANG_RESOURCE_DIR_PARENT "$<TARGET_FILE_DIR:liblldb>/clang")
+     file(MAKE_DIRECTORY "${LLDB_CLANG_RESOURCE_DIR_PARENT}")
+     add_custom_command(TARGET liblldb POST_BUILD
+       COMMENT "Linking Clang resource dir into LLDB build directory: ${LLDB_CLANG_RESOURCE_DIR_PARENT}"
+       COMMAND ${CMAKE_COMMAND} -E make_directory "${LLDB_CLANG_RESOURCE_DIR_PARENT}"
+       COMMAND ${CMAKE_COMMAND} -E create_symlink "${LLDB_EXTERNAL_CLANG_RESOURCE_DIR}"
+               "${LLDB_CLANG_RESOURCE_DIR_PARENT}/${LLDB_CLANG_RESOURCE_DIR_NAME}"
+     )
+   endif()
+ endif()
+ 
+ if(LLDB_BUILD_FRAMEWORK)
+   include(LLDBFramework)
+ endif()
+diff --git a/lldb/source/API/SBDebugger.cpp b/lldb/source/API/SBDebugger.cpp
+index a854c22bb214..01fbfd6beeaa 100644
+--- a/lldb/source/API/SBDebugger.cpp
++++ b/lldb/source/API/SBDebugger.cpp
+@@ -1,1898 +1,1901 @@
+ //===-- SBDebugger.cpp ----------------------------------------------------===//
+ //
+ // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+ // See https://llvm.org/LICENSE.txt for license information.
+ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+ //
+ //===----------------------------------------------------------------------===//
+ 
+ #include "SBReproducerPrivate.h"
+ #include "SystemInitializerFull.h"
+ 
+ #include "lldb/API/SBDebugger.h"
+ 
+ #include "lldb/lldb-private.h"
+ 
+ #include "lldb/API/SBBroadcaster.h"
+ #include "lldb/API/SBCommandInterpreter.h"
+ #include "lldb/API/SBCommandInterpreterRunOptions.h"
+ #include "lldb/API/SBCommandReturnObject.h"
+ #include "lldb/API/SBError.h"
+ #include "lldb/API/SBEvent.h"
+ #include "lldb/API/SBFile.h"
+ #include "lldb/API/SBFrame.h"
+ #include "lldb/API/SBListener.h"
+ #include "lldb/API/SBProcess.h"
+ #include "lldb/API/SBSourceManager.h"
+ #include "lldb/API/SBStream.h"
+ #include "lldb/API/SBStringList.h"
+ #include "lldb/API/SBStructuredData.h"
+ #include "lldb/API/SBTarget.h"
+ #include "lldb/API/SBThread.h"
+ #include "lldb/API/SBTypeCategory.h"
+ #include "lldb/API/SBTypeFilter.h"
+ #include "lldb/API/SBTypeFormat.h"
+ #include "lldb/API/SBTypeNameSpecifier.h"
+ #include "lldb/API/SBTypeSummary.h"
+ #include "lldb/API/SBTypeSynthetic.h"
+ 
+ #include "lldb/Core/Debugger.h"
+ #include "lldb/Core/PluginManager.h"
+ #include "lldb/Core/Progress.h"
+ #include "lldb/Core/StreamFile.h"
+ #include "lldb/Core/StructuredDataImpl.h"
+ #include "lldb/DataFormatters/DataVisualization.h"
+ #include "lldb/Host/Config.h"
+ #include "lldb/Host/XML.h"
+ #include "lldb/Initialization/SystemLifetimeManager.h"
+ #include "lldb/Interpreter/CommandInterpreter.h"
+ #include "lldb/Interpreter/OptionArgParser.h"
+ #include "lldb/Interpreter/OptionGroupPlatform.h"
+ #include "lldb/Target/Process.h"
+ #include "lldb/Target/TargetList.h"
+ #include "lldb/Utility/Args.h"
+ #include "lldb/Utility/State.h"
+ 
+ #include "llvm/ADT/STLExtras.h"
+ #include "llvm/ADT/StringRef.h"
+ #include "llvm/Support/DynamicLibrary.h"
+ #include "llvm/Support/ManagedStatic.h"
+ 
+ using namespace lldb;
+ using namespace lldb_private;
+ 
+ static llvm::sys::DynamicLibrary LoadPlugin(const lldb::DebuggerSP &debugger_sp,
+                                             const FileSpec &spec,
+                                             Status &error) {
+   llvm::sys::DynamicLibrary dynlib =
+       llvm::sys::DynamicLibrary::getPermanentLibrary(spec.GetPath().c_str());
+   if (dynlib.isValid()) {
+     typedef bool (*LLDBCommandPluginInit)(lldb::SBDebugger & debugger);
+ 
+     lldb::SBDebugger debugger_sb(debugger_sp);
+     // This calls the bool lldb::PluginInitialize(lldb::SBDebugger debugger)
+     // function.
+     // TODO: mangle this differently for your system - on OSX, the first
+     // underscore needs to be removed and the second one stays
+     LLDBCommandPluginInit init_func =
+         (LLDBCommandPluginInit)(uintptr_t)dynlib.getAddressOfSymbol(
+             "_ZN4lldb16PluginInitializeENS_10SBDebuggerE");
+     if (init_func) {
+       if (init_func(debugger_sb))
+         return dynlib;
+       else
+         error.SetErrorString("plug-in refused to load "
+                              "(lldb::PluginInitialize(lldb::SBDebugger) "
+                              "returned false)");
+     } else {
+       error.SetErrorString("plug-in is missing the required initialization: "
+                            "lldb::PluginInitialize(lldb::SBDebugger)");
+     }
+   } else {
+     if (FileSystem::Instance().Exists(spec))
+       error.SetErrorString("this file does not represent a loadable dylib");
+     else
+       error.SetErrorString("no such file");
+   }
+   return llvm::sys::DynamicLibrary();
+ }
+ 
+ static llvm::ManagedStatic<SystemLifetimeManager> g_debugger_lifetime;
+ 
+ SBError SBInputReader::Initialize(
+     lldb::SBDebugger &sb_debugger,
+     unsigned long (*callback)(void *, lldb::SBInputReader *,
+                               lldb::InputReaderAction, char const *,
+                               unsigned long),
+     void *a, lldb::InputReaderGranularity b, char const *c, char const *d,
+     bool e) {
+   LLDB_RECORD_DUMMY(
+       lldb::SBError, SBInputReader, Initialize,
+       (lldb::SBDebugger &,
+        unsigned long (*)(void *, lldb::SBInputReader *, lldb::InputReaderAction,
+                          const char *, unsigned long),
+        void *, lldb::InputReaderGranularity, const char *, const char *, bool),
+       sb_debugger, callback, a, b, c, d, e);
+ 
+   return SBError();
+ }
+ 
+ void SBInputReader::SetIsDone(bool b) {
+   LLDB_RECORD_METHOD(void, SBInputReader, SetIsDone, (bool), b);
+ }
+ 
+ bool SBInputReader::IsActive() const {
+   LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBInputReader, IsActive);
+ 
+   return false;
+ }
+ 
+ SBDebugger::SBDebugger() { LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBDebugger); }
+ 
+ SBDebugger::SBDebugger(const lldb::DebuggerSP &debugger_sp)
+     : m_opaque_sp(debugger_sp) {
+   LLDB_RECORD_CONSTRUCTOR(SBDebugger, (const lldb::DebuggerSP &), debugger_sp);
+ }
+ 
+ SBDebugger::SBDebugger(const SBDebugger &rhs) : m_opaque_sp(rhs.m_opaque_sp) {
+   LLDB_RECORD_CONSTRUCTOR(SBDebugger, (const lldb::SBDebugger &), rhs);
+ }
+ 
+ SBDebugger::~SBDebugger() = default;
+ 
+ SBDebugger &SBDebugger::operator=(const SBDebugger &rhs) {
+   LLDB_RECORD_METHOD(lldb::SBDebugger &,
+                      SBDebugger, operator=,(const lldb::SBDebugger &), rhs);
+ 
+   if (this != &rhs) {
+     m_opaque_sp = rhs.m_opaque_sp;
+   }
+   return LLDB_RECORD_RESULT(*this);
+ }
+ 
+ const char *SBDebugger::GetBroadcasterClass() {
+   LLDB_RECORD_STATIC_METHOD_NO_ARGS(const char *, SBDebugger,
+                                     GetBroadcasterClass);
+ 
+   return Debugger::GetStaticBroadcasterClass().AsCString();
+ }
+ 
+ const char *SBDebugger::GetProgressFromEvent(const lldb::SBEvent &event,
+                                              uint64_t &progress_id,
+                                              uint64_t &completed,
+                                              uint64_t &total,
+                                              bool &is_debugger_specific) {
+   const Debugger::ProgressEventData *progress_data =
+       Debugger::ProgressEventData::GetEventDataFromEvent(event.get());
+   if (progress_data == nullptr)
+     return nullptr;
+   progress_id = progress_data->GetID();
+   completed = progress_data->GetCompleted();
+   total = progress_data->GetTotal();
+   is_debugger_specific = progress_data->IsDebuggerSpecific();
+   // We must record the static method _after_ the out parameters have been
+   // filled in.
+   LLDB_RECORD_STATIC_METHOD(
+       const char *, SBDebugger, GetProgressFromEvent,
+       (const lldb::SBEvent &, uint64_t &, uint64_t &, uint64_t &, bool &),
+       event, progress_id, completed, total, is_debugger_specific);
+   return LLDB_RECORD_RESULT(progress_data->GetMessage().c_str())
+ }
+ 
+ SBBroadcaster SBDebugger::GetBroadcaster() {
+   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBBroadcaster, SBDebugger, GetBroadcaster);
+   SBBroadcaster broadcaster(&m_opaque_sp->GetBroadcaster(), false);
+   return LLDB_RECORD_RESULT(broadcaster);
+ }
+ 
+ void SBDebugger::Initialize() {
+   LLDB_RECORD_STATIC_METHOD_NO_ARGS(void, SBDebugger, Initialize);
+   SBError ignored = SBDebugger::InitializeWithErrorHandling();
+ }
+ 
+ lldb::SBError SBDebugger::InitializeWithErrorHandling() {
+   LLDB_RECORD_STATIC_METHOD_NO_ARGS(lldb::SBError, SBDebugger,
+                                     InitializeWithErrorHandling);
+ 
+   SBError error;
+   if (auto e = g_debugger_lifetime->Initialize(
+           std::make_unique<SystemInitializerFull>(), LoadPlugin)) {
+     error.SetError(Status(std::move(e)));
+   }
+   return LLDB_RECORD_RESULT(error);
+ }
+ 
+ void SBDebugger::Terminate() {
+   LLDB_RECORD_STATIC_METHOD_NO_ARGS(void, SBDebugger, Terminate);
+ 
+   g_debugger_lifetime->Terminate();
+ }
+ 
+ void SBDebugger::Clear() {
+   LLDB_RECORD_METHOD_NO_ARGS(void, SBDebugger, Clear);
+ 
+   if (m_opaque_sp)
+     m_opaque_sp->ClearIOHandlers();
+ 
+   m_opaque_sp.reset();
+ }
+ 
+ SBDebugger SBDebugger::Create() {
+   LLDB_RECORD_STATIC_METHOD_NO_ARGS(lldb::SBDebugger, SBDebugger, Create);
+ 
+   return LLDB_RECORD_RESULT(SBDebugger::Create(false, nullptr, nullptr));
+ }
+ 
+ SBDebugger SBDebugger::Create(bool source_init_files) {
+   LLDB_RECORD_STATIC_METHOD(lldb::SBDebugger, SBDebugger, Create, (bool),
+                             source_init_files);
+ 
+   return LLDB_RECORD_RESULT(
+       SBDebugger::Create(source_init_files, nullptr, nullptr));
+ }
+ 
+ SBDebugger SBDebugger::Create(bool source_init_files,
+                               lldb::LogOutputCallback callback, void *baton)
+ 
+ {
+   LLDB_RECORD_DUMMY(lldb::SBDebugger, SBDebugger, Create,
+                     (bool, lldb::LogOutputCallback, void *), source_init_files,
+                     callback, baton);
+ 
+   SBDebugger debugger;
+ 
+   // Currently we have issues if this function is called simultaneously on two
+   // different threads. The issues mainly revolve around the fact that the
+   // lldb_private::FormatManager uses global collections and having two threads
+   // parsing the .lldbinit files can cause mayhem. So to get around this for
+   // now we need to use a mutex to prevent bad things from happening.
+   static std::recursive_mutex g_mutex;
+   std::lock_guard<std::recursive_mutex> guard(g_mutex);
+ 
+   debugger.reset(Debugger::CreateInstance(callback, baton));
+ 
+   SBCommandInterpreter interp = debugger.GetCommandInterpreter();
+   if (source_init_files) {
+     interp.get()->SkipLLDBInitFiles(false);
+     interp.get()->SkipAppInitFiles(false);
+     SBCommandReturnObject result;
+     interp.SourceInitFileInHomeDirectory(result, false);
+   } else {
+     interp.get()->SkipLLDBInitFiles(true);
+     interp.get()->SkipAppInitFiles(true);
+   }
+   return debugger;
+ }
+ 
+ void SBDebugger::Destroy(SBDebugger &debugger) {
+   LLDB_RECORD_STATIC_METHOD(void, SBDebugger, Destroy, (lldb::SBDebugger &),
+                             debugger);
+ 
+   Debugger::Destroy(debugger.m_opaque_sp);
+ 
+   if (debugger.m_opaque_sp.get() != nullptr)
+     debugger.m_opaque_sp.reset();
+ }
+ 
+ void SBDebugger::MemoryPressureDetected() {
+   LLDB_RECORD_STATIC_METHOD_NO_ARGS(void, SBDebugger, MemoryPressureDetected);
+ 
+   // Since this function can be call asynchronously, we allow it to be non-
+   // mandatory. We have seen deadlocks with this function when called so we
+   // need to safeguard against this until we can determine what is causing the
+   // deadlocks.
+ 
+   const bool mandatory = false;
+ 
+   ModuleList::RemoveOrphanSharedModules(mandatory);
+ }
+ 
+ bool SBDebugger::IsValid() const {
+   LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBDebugger, IsValid);
+   return this->operator bool();
+ }
+ SBDebugger::operator bool() const {
+   LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBDebugger, operator bool);
+ 
+   return m_opaque_sp.get() != nullptr;
+ }
+ 
+ void SBDebugger::SetAsync(bool b) {
+   LLDB_RECORD_METHOD(void, SBDebugger, SetAsync, (bool), b);
+ 
+   if (m_opaque_sp)
+     m_opaque_sp->SetAsyncExecution(b);
+ }
+ 
+ bool SBDebugger::GetAsync() {
+   LLDB_RECORD_METHOD_NO_ARGS(bool, SBDebugger, GetAsync);
+ 
+   return (m_opaque_sp ? m_opaque_sp->GetAsyncExecution() : false);
+ }
+ 
+ void SBDebugger::SkipLLDBInitFiles(bool b) {
+   LLDB_RECORD_METHOD(void, SBDebugger, SkipLLDBInitFiles, (bool), b);
+ 
+   if (m_opaque_sp)
+     m_opaque_sp->GetCommandInterpreter().SkipLLDBInitFiles(b);
+ }
+ 
+ void SBDebugger::SkipAppInitFiles(bool b) {
+   LLDB_RECORD_METHOD(void, SBDebugger, SkipAppInitFiles, (bool), b);
+ 
+   if (m_opaque_sp)
+     m_opaque_sp->GetCommandInterpreter().SkipAppInitFiles(b);
+ }
+ 
+ void SBDebugger::SetInputFileHandle(FILE *fh, bool transfer_ownership) {
+   LLDB_RECORD_METHOD(void, SBDebugger, SetInputFileHandle, (FILE *, bool), fh,
+                      transfer_ownership);
+   SetInputFile((FileSP)std::make_shared<NativeFile>(fh, transfer_ownership));
+ }
+ 
+ SBError SBDebugger::SetInputFile(FileSP file_sp) {
+   LLDB_RECORD_METHOD(SBError, SBDebugger, SetInputFile, (FileSP), file_sp);
+   return LLDB_RECORD_RESULT(SetInputFile(SBFile(file_sp)));
+ }
+ 
+ // Shouldn't really be settable after initialization as this could cause lots
+ // of problems; don't want users trying to switch modes in the middle of a
+ // debugging session.
+ SBError SBDebugger::SetInputFile(SBFile file) {
+   LLDB_RECORD_METHOD(SBError, SBDebugger, SetInputFile, (SBFile), file);
+ 
+   SBError error;
+   if (!m_opaque_sp) {
+     error.ref().SetErrorString("invalid debugger");
+     return LLDB_RECORD_RESULT(error);
+   }
+ 
+   repro::DataRecorder *recorder = nullptr;
+   if (repro::Generator *g = repro::Reproducer::Instance().GetGenerator())
+     recorder = g->GetOrCreate<repro::CommandProvider>().GetNewRecorder();
+ 
+   FileSP file_sp = file.m_opaque_sp;
+ 
+   static std::unique_ptr<repro::MultiLoader<repro::CommandProvider>> loader =
+       repro::MultiLoader<repro::CommandProvider>::Create(
+           repro::Reproducer::Instance().GetLoader());
+   if (loader) {
+     llvm::Optional<std::string> nextfile = loader->GetNextFile();
+     FILE *fh = nextfile ? FileSystem::Instance().Fopen(nextfile->c_str(), "r")
+                         : nullptr;
+     // FIXME Jonas Devlieghere: shouldn't this error be propagated out to the
+     // reproducer somehow if fh is NULL?
+     if (fh) {
+       file_sp = std::make_shared<NativeFile>(fh, true);
+     }
+   }
+ 
+   if (!file_sp || !file_sp->IsValid()) {
+     error.ref().SetErrorString("invalid file");
+     return LLDB_RECORD_RESULT(error);
+   }
+ 
+   m_opaque_sp->SetInputFile(file_sp, recorder);
+   return LLDB_RECORD_RESULT(error);
+ }
+ 
+ SBError SBDebugger::SetOutputFile(FileSP file_sp) {
+   LLDB_RECORD_METHOD(SBError, SBDebugger, SetOutputFile, (FileSP), file_sp);
+   return LLDB_RECORD_RESULT(SetOutputFile(SBFile(file_sp)));
+ }
+ 
+ void SBDebugger::SetOutputFileHandle(FILE *fh, bool transfer_ownership) {
+   LLDB_RECORD_METHOD(void, SBDebugger, SetOutputFileHandle, (FILE *, bool), fh,
+                      transfer_ownership);
+   SetOutputFile((FileSP)std::make_shared<NativeFile>(fh, transfer_ownership));
+ }
+ 
+ SBError SBDebugger::SetOutputFile(SBFile file) {
+   LLDB_RECORD_METHOD(SBError, SBDebugger, SetOutputFile, (SBFile file), file);
+   SBError error;
+   if (!m_opaque_sp) {
+     error.ref().SetErrorString("invalid debugger");
+     return LLDB_RECORD_RESULT(error);
+   }
+   if (!file) {
+     error.ref().SetErrorString("invalid file");
+     return LLDB_RECORD_RESULT(error);
+   }
+   m_opaque_sp->SetOutputFile(file.m_opaque_sp);
+   return LLDB_RECORD_RESULT(error);
+ }
+ 
+ void SBDebugger::SetErrorFileHandle(FILE *fh, bool transfer_ownership) {
+   LLDB_RECORD_METHOD(void, SBDebugger, SetErrorFileHandle, (FILE *, bool), fh,
+                      transfer_ownership);
+   SetErrorFile((FileSP)std::make_shared<NativeFile>(fh, transfer_ownership));
+ }
+ 
+ SBError SBDebugger::SetErrorFile(FileSP file_sp) {
+   LLDB_RECORD_METHOD(SBError, SBDebugger, SetErrorFile, (FileSP), file_sp);
+   return LLDB_RECORD_RESULT(SetErrorFile(SBFile(file_sp)));
+ }
+ 
+ SBError SBDebugger::SetErrorFile(SBFile file) {
+   LLDB_RECORD_METHOD(SBError, SBDebugger, SetErrorFile, (SBFile file), file);
+   SBError error;
+   if (!m_opaque_sp) {
+     error.ref().SetErrorString("invalid debugger");
+     return LLDB_RECORD_RESULT(error);
+   }
+   if (!file) {
+     error.ref().SetErrorString("invalid file");
+     return LLDB_RECORD_RESULT(error);
+   }
+   m_opaque_sp->SetErrorFile(file.m_opaque_sp);
+   return LLDB_RECORD_RESULT(error);
+ }
+ 
+ FILE *SBDebugger::GetInputFileHandle() {
+   LLDB_RECORD_METHOD_NO_ARGS(FILE *, SBDebugger, GetInputFileHandle);
+   if (m_opaque_sp) {
+     File &file_sp = m_opaque_sp->GetInputFile();
+     return LLDB_RECORD_RESULT(file_sp.GetStream());
+   }
+   return LLDB_RECORD_RESULT(nullptr);
+ }
+ 
+ SBFile SBDebugger::GetInputFile() {
+   LLDB_RECORD_METHOD_NO_ARGS(SBFile, SBDebugger, GetInputFile);
+   if (m_opaque_sp) {
+     return LLDB_RECORD_RESULT(SBFile(m_opaque_sp->GetInputFileSP()));
+   }
+   return LLDB_RECORD_RESULT(SBFile());
+ }
+ 
+ FILE *SBDebugger::GetOutputFileHandle() {
+   LLDB_RECORD_METHOD_NO_ARGS(FILE *, SBDebugger, GetOutputFileHandle);
+   if (m_opaque_sp) {
+     StreamFile &stream_file = m_opaque_sp->GetOutputStream();
+     return LLDB_RECORD_RESULT(stream_file.GetFile().GetStream());
+   }
+   return LLDB_RECORD_RESULT(nullptr);
+ }
+ 
+ SBFile SBDebugger::GetOutputFile() {
+   LLDB_RECORD_METHOD_NO_ARGS(SBFile, SBDebugger, GetOutputFile);
+   if (m_opaque_sp) {
+     SBFile file(m_opaque_sp->GetOutputStream().GetFileSP());
+     return LLDB_RECORD_RESULT(file);
+   }
+   return LLDB_RECORD_RESULT(SBFile());
+ }
+ 
+ FILE *SBDebugger::GetErrorFileHandle() {
+   LLDB_RECORD_METHOD_NO_ARGS(FILE *, SBDebugger, GetErrorFileHandle);
+ 
+   if (m_opaque_sp) {
+     StreamFile &stream_file = m_opaque_sp->GetErrorStream();
+     return LLDB_RECORD_RESULT(stream_file.GetFile().GetStream());
+   }
+   return LLDB_RECORD_RESULT(nullptr);
+ }
+ 
+ SBFile SBDebugger::GetErrorFile() {
+   LLDB_RECORD_METHOD_NO_ARGS(SBFile, SBDebugger, GetErrorFile);
+   SBFile file;
+   if (m_opaque_sp) {
+     SBFile file(m_opaque_sp->GetErrorStream().GetFileSP());
+     return LLDB_RECORD_RESULT(file);
+   }
+   return LLDB_RECORD_RESULT(SBFile());
+ }
+ 
+ void SBDebugger::SaveInputTerminalState() {
+   LLDB_RECORD_DUMMY_NO_ARGS(void, SBDebugger, SaveInputTerminalState);
+ 
+   if (m_opaque_sp)
+     m_opaque_sp->SaveInputTerminalState();
+ }
+ 
+ void SBDebugger::RestoreInputTerminalState() {
+   LLDB_RECORD_DUMMY_NO_ARGS(void, SBDebugger, RestoreInputTerminalState);
+ 
+   if (m_opaque_sp)
+     m_opaque_sp->RestoreInputTerminalState();
+ }
+ SBCommandInterpreter SBDebugger::GetCommandInterpreter() {
+   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBCommandInterpreter, SBDebugger,
+                              GetCommandInterpreter);
+ 
+   SBCommandInterpreter sb_interpreter;
+   if (m_opaque_sp)
+     sb_interpreter.reset(&m_opaque_sp->GetCommandInterpreter());
+ 
+   return LLDB_RECORD_RESULT(sb_interpreter);
+ }
+ 
+ void SBDebugger::HandleCommand(const char *command) {
+   LLDB_RECORD_METHOD(void, SBDebugger, HandleCommand, (const char *), command);
+ 
+   if (m_opaque_sp) {
+     TargetSP target_sp(m_opaque_sp->GetSelectedTarget());
+     std::unique_lock<std::recursive_mutex> lock;
+     if (target_sp)
+       lock = std::unique_lock<std::recursive_mutex>(target_sp->GetAPIMutex());
+ 
+     SBCommandInterpreter sb_interpreter(GetCommandInterpreter());
+     SBCommandReturnObject result;
+ 
+     sb_interpreter.HandleCommand(command, result, false);
+ 
+     result.PutError(m_opaque_sp->GetErrorStream().GetFileSP());
+     result.PutOutput(m_opaque_sp->GetOutputStream().GetFileSP());
+ 
+     if (!m_opaque_sp->GetAsyncExecution()) {
+       SBProcess process(GetCommandInterpreter().GetProcess());
+       ProcessSP process_sp(process.GetSP());
+       if (process_sp) {
+         EventSP event_sp;
+         ListenerSP lldb_listener_sp = m_opaque_sp->GetListener();
+         while (lldb_listener_sp->GetEventForBroadcaster(
+             process_sp.get(), event_sp, std::chrono::seconds(0))) {
+           SBEvent event(event_sp);
+           HandleProcessEvent(process, event, GetOutputFile(), GetErrorFile());
+         }
+       }
+     }
+   }
+ }
+ 
+ SBListener SBDebugger::GetListener() {
+   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBListener, SBDebugger, GetListener);
+ 
+   SBListener sb_listener;
+   if (m_opaque_sp)
+     sb_listener.reset(m_opaque_sp->GetListener());
+ 
+   return LLDB_RECORD_RESULT(sb_listener);
+ }
+ 
+ void SBDebugger::HandleProcessEvent(const SBProcess &process,
+                                     const SBEvent &event, SBFile out,
+                                     SBFile err) {
+   LLDB_RECORD_METHOD(
+       void, SBDebugger, HandleProcessEvent,
+       (const lldb::SBProcess &, const lldb::SBEvent &, SBFile, SBFile), process,
+       event, out, err);
+ 
+   return HandleProcessEvent(process, event, out.m_opaque_sp, err.m_opaque_sp);
+ }
+ 
+ void SBDebugger::HandleProcessEvent(const SBProcess &process,
+                                     const SBEvent &event, FILE *out,
+                                     FILE *err) {
+   LLDB_RECORD_METHOD(
+       void, SBDebugger, HandleProcessEvent,
+       (const lldb::SBProcess &, const lldb::SBEvent &, FILE *, FILE *), process,
+       event, out, err);
+ 
+   FileSP outfile = std::make_shared<NativeFile>(out, false);
+   FileSP errfile = std::make_shared<NativeFile>(err, false);
+   return HandleProcessEvent(process, event, outfile, errfile);
+ }
+ 
+ void SBDebugger::HandleProcessEvent(const SBProcess &process,
+                                     const SBEvent &event, FileSP out_sp,
+                                     FileSP err_sp) {
+ 
+   LLDB_RECORD_METHOD(
+       void, SBDebugger, HandleProcessEvent,
+       (const lldb::SBProcess &, const lldb::SBEvent &, FileSP, FileSP), process,
+       event, out_sp, err_sp);
+ 
+   if (!process.IsValid())
+     return;
+ 
+   TargetSP target_sp(process.GetTarget().GetSP());
+   if (!target_sp)
+     return;
+ 
+   const uint32_t event_type = event.GetType();
+   char stdio_buffer[1024];
+   size_t len;
+ 
+   std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
+ 
+   if (event_type &
+       (Process::eBroadcastBitSTDOUT | Process::eBroadcastBitStateChanged)) {
+     // Drain stdout when we stop just in case we have any bytes
+     while ((len = process.GetSTDOUT(stdio_buffer, sizeof(stdio_buffer))) > 0)
+       if (out_sp)
+         out_sp->Write(stdio_buffer, len);
+   }
+ 
+   if (event_type &
+       (Process::eBroadcastBitSTDERR | Process::eBroadcastBitStateChanged)) {
+     // Drain stderr when we stop just in case we have any bytes
+     while ((len = process.GetSTDERR(stdio_buffer, sizeof(stdio_buffer))) > 0)
+       if (err_sp)
+         err_sp->Write(stdio_buffer, len);
+   }
+ 
+   if (event_type & Process::eBroadcastBitStateChanged) {
+     StateType event_state = SBProcess::GetStateFromEvent(event);
+ 
+     if (event_state == eStateInvalid)
+       return;
+ 
+     bool is_stopped = StateIsStoppedState(event_state);
+     if (!is_stopped)
+       process.ReportEventState(event, out_sp);
+   }
+ }
+ 
+ SBSourceManager SBDebugger::GetSourceManager() {
+   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBSourceManager, SBDebugger,
+                              GetSourceManager);
+ 
+   SBSourceManager sb_source_manager(*this);
+   return LLDB_RECORD_RESULT(sb_source_manager);
+ }
+ 
+ bool SBDebugger::GetDefaultArchitecture(char *arch_name, size_t arch_name_len) {
+   LLDB_RECORD_CHAR_PTR_STATIC_METHOD(bool, SBDebugger, GetDefaultArchitecture,
+                                      (char *, size_t), arch_name, "",
+                                      arch_name_len);
+ 
+   if (arch_name && arch_name_len) {
+     ArchSpec default_arch = Target::GetDefaultArchitecture();
+ 
+     if (default_arch.IsValid()) {
+       const std::string &triple_str = default_arch.GetTriple().str();
+       if (!triple_str.empty())
+         ::snprintf(arch_name, arch_name_len, "%s", triple_str.c_str());
+       else
+         ::snprintf(arch_name, arch_name_len, "%s",
+                    default_arch.GetArchitectureName());
+       return true;
+     }
+   }
+   if (arch_name && arch_name_len)
+     arch_name[0] = '\0';
+   return false;
+ }
+ 
+ bool SBDebugger::SetDefaultArchitecture(const char *arch_name) {
+   LLDB_RECORD_STATIC_METHOD(bool, SBDebugger, SetDefaultArchitecture,
+                             (const char *), arch_name);
+ 
+   if (arch_name) {
+     ArchSpec arch(arch_name);
+     if (arch.IsValid()) {
+       Target::SetDefaultArchitecture(arch);
+       return true;
+     }
+   }
+   return false;
+ }
+ 
+ ScriptLanguage
+ SBDebugger::GetScriptingLanguage(const char *script_language_name) {
+   LLDB_RECORD_METHOD(lldb::ScriptLanguage, SBDebugger, GetScriptingLanguage,
+                      (const char *), script_language_name);
+ 
+   if (!script_language_name)
+     return eScriptLanguageDefault;
+   return OptionArgParser::ToScriptLanguage(
+       llvm::StringRef(script_language_name), eScriptLanguageDefault, nullptr);
+ }
+ 
+ const char *SBDebugger::GetVersionString() {
+   LLDB_RECORD_STATIC_METHOD_NO_ARGS(const char *, SBDebugger, GetVersionString);
+ 
+   return lldb_private::GetVersion();
+ }
+ 
+ const char *SBDebugger::StateAsCString(StateType state) {
+   LLDB_RECORD_STATIC_METHOD(const char *, SBDebugger, StateAsCString,
+                             (lldb::StateType), state);
+ 
+   return lldb_private::StateAsCString(state);
+ }
+ 
+ static void AddBoolConfigEntry(StructuredData::Dictionary &dict,
+                                llvm::StringRef name, bool value,
+                                llvm::StringRef description) {
+   auto entry_up = std::make_unique<StructuredData::Dictionary>();
+   entry_up->AddBooleanItem("value", value);
+   entry_up->AddStringItem("description", description);
+   dict.AddItem(name, std::move(entry_up));
+ }
+ 
+ static void AddLLVMTargets(StructuredData::Dictionary &dict) {
+   auto array_up = std::make_unique<StructuredData::Array>();
+ #define LLVM_TARGET(target)                                                    \
+   array_up->AddItem(std::make_unique<StructuredData::String>(#target));
+ #include "llvm/Config/Targets.def"
+   auto entry_up = std::make_unique<StructuredData::Dictionary>();
+   entry_up->AddItem("value", std::move(array_up));
+   entry_up->AddStringItem("description", "A list of configured LLVM targets.");
+   dict.AddItem("targets", std::move(entry_up));
+ }
+ 
+ SBStructuredData SBDebugger::GetBuildConfiguration() {
+   LLDB_RECORD_STATIC_METHOD_NO_ARGS(lldb::SBStructuredData, SBDebugger,
+                                     GetBuildConfiguration);
+ 
+   auto config_up = std::make_unique<StructuredData::Dictionary>();
+   AddBoolConfigEntry(
+       *config_up, "xml", XMLDocument::XMLEnabled(),
+       "A boolean value that indicates if XML support is enabled in LLDB");
+   AddBoolConfigEntry(
+       *config_up, "curses", LLDB_ENABLE_CURSES,
+       "A boolean value that indicates if curses support is enabled in LLDB");
+   AddBoolConfigEntry(
+       *config_up, "editline", LLDB_ENABLE_LIBEDIT,
+       "A boolean value that indicates if editline support is enabled in LLDB");
+   AddBoolConfigEntry(
+       *config_up, "lzma", LLDB_ENABLE_LZMA,
+       "A boolean value that indicates if lzma support is enabled in LLDB");
+   AddBoolConfigEntry(
+       *config_up, "python", LLDB_ENABLE_PYTHON,
+       "A boolean value that indicates if python support is enabled in LLDB");
+   AddBoolConfigEntry(
+       *config_up, "lua", LLDB_ENABLE_LUA,
+       "A boolean value that indicates if lua support is enabled in LLDB");
++  AddBoolConfigEntry(
++      *config_up, "java", LLDB_ENABLE_JAVA,
++      "A boolean value that indicates if java support is enabled in LLDB");
+   AddLLVMTargets(*config_up);
+ 
+   SBStructuredData data;
+   data.m_impl_up->SetObjectSP(std::move(config_up));
+   return LLDB_RECORD_RESULT(data);
+ }
+ 
+ bool SBDebugger::StateIsRunningState(StateType state) {
+   LLDB_RECORD_STATIC_METHOD(bool, SBDebugger, StateIsRunningState,
+                             (lldb::StateType), state);
+ 
+   const bool result = lldb_private::StateIsRunningState(state);
+ 
+   return result;
+ }
+ 
+ bool SBDebugger::StateIsStoppedState(StateType state) {
+   LLDB_RECORD_STATIC_METHOD(bool, SBDebugger, StateIsStoppedState,
+                             (lldb::StateType), state);
+ 
+   const bool result = lldb_private::StateIsStoppedState(state, false);
+ 
+   return result;
+ }
+ 
+ lldb::SBTarget SBDebugger::CreateTarget(const char *filename,
+                                         const char *target_triple,
+                                         const char *platform_name,
+                                         bool add_dependent_modules,
+                                         lldb::SBError &sb_error) {
+   LLDB_RECORD_METHOD(
+       lldb::SBTarget, SBDebugger, CreateTarget,
+       (const char *, const char *, const char *, bool, lldb::SBError &),
+       filename, target_triple, platform_name, add_dependent_modules, sb_error);
+ 
+   SBTarget sb_target;
+   TargetSP target_sp;
+   if (m_opaque_sp) {
+     sb_error.Clear();
+     OptionGroupPlatform platform_options(false);
+     platform_options.SetPlatformName(platform_name);
+ 
+     sb_error.ref() = m_opaque_sp->GetTargetList().CreateTarget(
+         *m_opaque_sp, filename, target_triple,
+         add_dependent_modules ? eLoadDependentsYes : eLoadDependentsNo,
+         &platform_options, target_sp);
+ 
+     if (sb_error.Success())
+       sb_target.SetSP(target_sp);
+   } else {
+     sb_error.SetErrorString("invalid debugger");
+   }
+ 
+   Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+   LLDB_LOGF(log,
+             "SBDebugger(%p)::CreateTarget (filename=\"%s\", triple=%s, "
+             "platform_name=%s, add_dependent_modules=%u, error=%s) => "
+             "SBTarget(%p)",
+             static_cast<void *>(m_opaque_sp.get()), filename, target_triple,
+             platform_name, add_dependent_modules, sb_error.GetCString(),
+             static_cast<void *>(target_sp.get()));
+ 
+   return LLDB_RECORD_RESULT(sb_target);
+ }
+ 
+ SBTarget
+ SBDebugger::CreateTargetWithFileAndTargetTriple(const char *filename,
+                                                 const char *target_triple) {
+   LLDB_RECORD_METHOD(lldb::SBTarget, SBDebugger,
+                      CreateTargetWithFileAndTargetTriple,
+                      (const char *, const char *), filename, target_triple);
+ 
+   SBTarget sb_target;
+   TargetSP target_sp;
+   if (m_opaque_sp) {
+     const bool add_dependent_modules = true;
+     Status error(m_opaque_sp->GetTargetList().CreateTarget(
+         *m_opaque_sp, filename, target_triple,
+         add_dependent_modules ? eLoadDependentsYes : eLoadDependentsNo, nullptr,
+         target_sp));
+     sb_target.SetSP(target_sp);
+   }
+ 
+   Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+   LLDB_LOGF(log,
+             "SBDebugger(%p)::CreateTargetWithFileAndTargetTriple "
+             "(filename=\"%s\", triple=%s) => SBTarget(%p)",
+             static_cast<void *>(m_opaque_sp.get()), filename, target_triple,
+             static_cast<void *>(target_sp.get()));
+ 
+   return LLDB_RECORD_RESULT(sb_target);
+ }
+ 
+ SBTarget SBDebugger::CreateTargetWithFileAndArch(const char *filename,
+                                                  const char *arch_cstr) {
+   LLDB_RECORD_METHOD(lldb::SBTarget, SBDebugger, CreateTargetWithFileAndArch,
+                      (const char *, const char *), filename, arch_cstr);
+ 
+   Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+ 
+   SBTarget sb_target;
+   TargetSP target_sp;
+   if (m_opaque_sp) {
+     Status error;
+     if (arch_cstr == nullptr) {
+       // The version of CreateTarget that takes an ArchSpec won't accept an
+       // empty ArchSpec, so when the arch hasn't been specified, we need to
+       // call the target triple version.
+       error = m_opaque_sp->GetTargetList().CreateTarget(*m_opaque_sp, filename, 
+           arch_cstr, eLoadDependentsYes, nullptr, target_sp);
+     } else {
+       PlatformSP platform_sp = m_opaque_sp->GetPlatformList()
+           .GetSelectedPlatform();
+       ArchSpec arch = Platform::GetAugmentedArchSpec(platform_sp.get(), 
+           arch_cstr);
+       if (arch.IsValid())
+         error = m_opaque_sp->GetTargetList().CreateTarget(*m_opaque_sp, filename, 
+             arch, eLoadDependentsYes, platform_sp, target_sp);
+       else
+         error.SetErrorStringWithFormat("invalid arch_cstr: %s", arch_cstr);
+     }
+     if (error.Success())
+       sb_target.SetSP(target_sp);
+   }
+ 
+   LLDB_LOGF(log,
+             "SBDebugger(%p)::CreateTargetWithFileAndArch (filename=\"%s\", "
+             "arch=%s) => SBTarget(%p)",
+             static_cast<void *>(m_opaque_sp.get()),
+             filename ? filename : "<unspecified>",
+             arch_cstr ? arch_cstr : "<unspecified>",
+             static_cast<void *>(target_sp.get()));
+ 
+   return LLDB_RECORD_RESULT(sb_target);
+ }
+ 
+ SBTarget SBDebugger::CreateTarget(const char *filename) {
+   LLDB_RECORD_METHOD(lldb::SBTarget, SBDebugger, CreateTarget, (const char *),
+                      filename);
+ 
+   SBTarget sb_target;
+   TargetSP target_sp;
+   if (m_opaque_sp) {
+     Status error;
+     const bool add_dependent_modules = true;
+     error = m_opaque_sp->GetTargetList().CreateTarget(
+         *m_opaque_sp, filename, "",
+         add_dependent_modules ? eLoadDependentsYes : eLoadDependentsNo, nullptr,
+         target_sp);
+ 
+     if (error.Success())
+       sb_target.SetSP(target_sp);
+   }
+   Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+   LLDB_LOGF(log,
+             "SBDebugger(%p)::CreateTarget (filename=\"%s\") => SBTarget(%p)",
+             static_cast<void *>(m_opaque_sp.get()), filename,
+             static_cast<void *>(target_sp.get()));
+   return LLDB_RECORD_RESULT(sb_target);
+ }
+ 
+ SBTarget SBDebugger::GetDummyTarget() {
+   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBTarget, SBDebugger, GetDummyTarget);
+ 
+   SBTarget sb_target;
+   if (m_opaque_sp) {
+     sb_target.SetSP(m_opaque_sp->GetDummyTarget().shared_from_this());
+   }
+   Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+   LLDB_LOGF(log, "SBDebugger(%p)::GetDummyTarget() => SBTarget(%p)",
+             static_cast<void *>(m_opaque_sp.get()),
+             static_cast<void *>(sb_target.GetSP().get()));
+   return LLDB_RECORD_RESULT(sb_target);
+ }
+ 
+ bool SBDebugger::DeleteTarget(lldb::SBTarget &target) {
+   LLDB_RECORD_METHOD(bool, SBDebugger, DeleteTarget, (lldb::SBTarget &),
+                      target);
+ 
+   bool result = false;
+   if (m_opaque_sp) {
+     TargetSP target_sp(target.GetSP());
+     if (target_sp) {
+       // No need to lock, the target list is thread safe
+       result = m_opaque_sp->GetTargetList().DeleteTarget(target_sp);
+       target_sp->Destroy();
+       target.Clear();
+     }
+   }
+ 
+   Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+   LLDB_LOGF(log, "SBDebugger(%p)::DeleteTarget (SBTarget(%p)) => %i",
+             static_cast<void *>(m_opaque_sp.get()),
+             static_cast<void *>(target.m_opaque_sp.get()), result);
+ 
+   return result;
+ }
+ 
+ SBTarget SBDebugger::GetTargetAtIndex(uint32_t idx) {
+   LLDB_RECORD_METHOD(lldb::SBTarget, SBDebugger, GetTargetAtIndex, (uint32_t),
+                      idx);
+ 
+   SBTarget sb_target;
+   if (m_opaque_sp) {
+     // No need to lock, the target list is thread safe
+     sb_target.SetSP(m_opaque_sp->GetTargetList().GetTargetAtIndex(idx));
+   }
+   return LLDB_RECORD_RESULT(sb_target);
+ }
+ 
+ uint32_t SBDebugger::GetIndexOfTarget(lldb::SBTarget target) {
+   LLDB_RECORD_METHOD(uint32_t, SBDebugger, GetIndexOfTarget, (lldb::SBTarget),
+                      target);
+ 
+   lldb::TargetSP target_sp = target.GetSP();
+   if (!target_sp)
+     return UINT32_MAX;
+ 
+   if (!m_opaque_sp)
+     return UINT32_MAX;
+ 
+   return m_opaque_sp->GetTargetList().GetIndexOfTarget(target.GetSP());
+ }
+ 
+ SBTarget SBDebugger::FindTargetWithProcessID(lldb::pid_t pid) {
+   LLDB_RECORD_METHOD(lldb::SBTarget, SBDebugger, FindTargetWithProcessID,
+                      (lldb::pid_t), pid);
+ 
+   SBTarget sb_target;
+   if (m_opaque_sp) {
+     // No need to lock, the target list is thread safe
+     sb_target.SetSP(m_opaque_sp->GetTargetList().FindTargetWithProcessID(pid));
+   }
+   return LLDB_RECORD_RESULT(sb_target);
+ }
+ 
+ SBTarget SBDebugger::FindTargetWithFileAndArch(const char *filename,
+                                                const char *arch_name) {
+   LLDB_RECORD_METHOD(lldb::SBTarget, SBDebugger, FindTargetWithFileAndArch,
+                      (const char *, const char *), filename, arch_name);
+ 
+   SBTarget sb_target;
+   if (m_opaque_sp && filename && filename[0]) {
+     // No need to lock, the target list is thread safe
+     ArchSpec arch = Platform::GetAugmentedArchSpec(
+         m_opaque_sp->GetPlatformList().GetSelectedPlatform().get(), arch_name);
+     TargetSP target_sp(
+         m_opaque_sp->GetTargetList().FindTargetWithExecutableAndArchitecture(
+             FileSpec(filename), arch_name ? &arch : nullptr));
+     sb_target.SetSP(target_sp);
+   }
+   return LLDB_RECORD_RESULT(sb_target);
+ }
+ 
+ SBTarget SBDebugger::FindTargetWithLLDBProcess(const ProcessSP &process_sp) {
+   SBTarget sb_target;
+   if (m_opaque_sp) {
+     // No need to lock, the target list is thread safe
+     sb_target.SetSP(
+         m_opaque_sp->GetTargetList().FindTargetWithProcess(process_sp.get()));
+   }
+   return sb_target;
+ }
+ 
+ uint32_t SBDebugger::GetNumTargets() {
+   LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBDebugger, GetNumTargets);
+ 
+   if (m_opaque_sp) {
+     // No need to lock, the target list is thread safe
+     return m_opaque_sp->GetTargetList().GetNumTargets();
+   }
+   return 0;
+ }
+ 
+ SBTarget SBDebugger::GetSelectedTarget() {
+   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBTarget, SBDebugger, GetSelectedTarget);
+ 
+   Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+ 
+   SBTarget sb_target;
+   TargetSP target_sp;
+   if (m_opaque_sp) {
+     // No need to lock, the target list is thread safe
+     target_sp = m_opaque_sp->GetTargetList().GetSelectedTarget();
+     sb_target.SetSP(target_sp);
+   }
+ 
+   if (log) {
+     SBStream sstr;
+     sb_target.GetDescription(sstr, eDescriptionLevelBrief);
+     LLDB_LOGF(log, "SBDebugger(%p)::GetSelectedTarget () => SBTarget(%p): %s",
+               static_cast<void *>(m_opaque_sp.get()),
+               static_cast<void *>(target_sp.get()), sstr.GetData());
+   }
+ 
+   return LLDB_RECORD_RESULT(sb_target);
+ }
+ 
+ void SBDebugger::SetSelectedTarget(SBTarget &sb_target) {
+   LLDB_RECORD_METHOD(void, SBDebugger, SetSelectedTarget, (lldb::SBTarget &),
+                      sb_target);
+ 
+   Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+ 
+   TargetSP target_sp(sb_target.GetSP());
+   if (m_opaque_sp) {
+     m_opaque_sp->GetTargetList().SetSelectedTarget(target_sp);
+   }
+   if (log) {
+     SBStream sstr;
+     sb_target.GetDescription(sstr, eDescriptionLevelBrief);
+     LLDB_LOGF(log, "SBDebugger(%p)::SetSelectedTarget () => SBTarget(%p): %s",
+               static_cast<void *>(m_opaque_sp.get()),
+               static_cast<void *>(target_sp.get()), sstr.GetData());
+   }
+ }
+ 
+ SBPlatform SBDebugger::GetSelectedPlatform() {
+   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBPlatform, SBDebugger, GetSelectedPlatform);
+ 
+   Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+ 
+   SBPlatform sb_platform;
+   DebuggerSP debugger_sp(m_opaque_sp);
+   if (debugger_sp) {
+     sb_platform.SetSP(debugger_sp->GetPlatformList().GetSelectedPlatform());
+   }
+   LLDB_LOGF(log, "SBDebugger(%p)::GetSelectedPlatform () => SBPlatform(%p): %s",
+             static_cast<void *>(m_opaque_sp.get()),
+             static_cast<void *>(sb_platform.GetSP().get()),
+             sb_platform.GetName());
+   return LLDB_RECORD_RESULT(sb_platform);
+ }
+ 
+ void SBDebugger::SetSelectedPlatform(SBPlatform &sb_platform) {
+   LLDB_RECORD_METHOD(void, SBDebugger, SetSelectedPlatform,
+                      (lldb::SBPlatform &), sb_platform);
+ 
+   Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+ 
+   DebuggerSP debugger_sp(m_opaque_sp);
+   if (debugger_sp) {
+     debugger_sp->GetPlatformList().SetSelectedPlatform(sb_platform.GetSP());
+   }
+ 
+   LLDB_LOGF(log, "SBDebugger(%p)::SetSelectedPlatform (SBPlatform(%p) %s)",
+             static_cast<void *>(m_opaque_sp.get()),
+             static_cast<void *>(sb_platform.GetSP().get()),
+             sb_platform.GetName());
+ }
+ 
+ uint32_t SBDebugger::GetNumPlatforms() {
+   LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBDebugger, GetNumPlatforms);
+ 
+   if (m_opaque_sp) {
+     // No need to lock, the platform list is thread safe
+     return m_opaque_sp->GetPlatformList().GetSize();
+   }
+   return 0;
+ }
+ 
+ SBPlatform SBDebugger::GetPlatformAtIndex(uint32_t idx) {
+   LLDB_RECORD_METHOD(lldb::SBPlatform, SBDebugger, GetPlatformAtIndex,
+                      (uint32_t), idx);
+ 
+   SBPlatform sb_platform;
+   if (m_opaque_sp) {
+     // No need to lock, the platform list is thread safe
+     sb_platform.SetSP(m_opaque_sp->GetPlatformList().GetAtIndex(idx));
+   }
+   return LLDB_RECORD_RESULT(sb_platform);
+ }
+ 
+ uint32_t SBDebugger::GetNumAvailablePlatforms() {
+   LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBDebugger, GetNumAvailablePlatforms);
+ 
+   uint32_t idx = 0;
+   while (true) {
+     if (!PluginManager::GetPlatformPluginNameAtIndex(idx)) {
+       break;
+     }
+     ++idx;
+   }
+   // +1 for the host platform, which should always appear first in the list.
+   return idx + 1;
+ }
+ 
+ SBStructuredData SBDebugger::GetAvailablePlatformInfoAtIndex(uint32_t idx) {
+   LLDB_RECORD_METHOD(lldb::SBStructuredData, SBDebugger,
+                      GetAvailablePlatformInfoAtIndex, (uint32_t), idx);
+ 
+   SBStructuredData data;
+   auto platform_dict = std::make_unique<StructuredData::Dictionary>();
+   llvm::StringRef name_str("name"), desc_str("description");
+ 
+   if (idx == 0) {
+     PlatformSP host_platform_sp(Platform::GetHostPlatform());
+     platform_dict->AddStringItem(
+         name_str, host_platform_sp->GetPluginName().GetStringRef());
+     platform_dict->AddStringItem(
+         desc_str, llvm::StringRef(host_platform_sp->GetDescription()));
+   } else if (idx > 0) {
+     const char *plugin_name =
+         PluginManager::GetPlatformPluginNameAtIndex(idx - 1);
+     if (!plugin_name) {
+       return LLDB_RECORD_RESULT(data);
+     }
+     platform_dict->AddStringItem(name_str, llvm::StringRef(plugin_name));
+ 
+     const char *plugin_desc =
+         PluginManager::GetPlatformPluginDescriptionAtIndex(idx - 1);
+     if (!plugin_desc) {
+       return LLDB_RECORD_RESULT(data);
+     }
+     platform_dict->AddStringItem(desc_str, llvm::StringRef(plugin_desc));
+   }
+ 
+   data.m_impl_up->SetObjectSP(
+       StructuredData::ObjectSP(platform_dict.release()));
+   return LLDB_RECORD_RESULT(data);
+ }
+ 
+ void SBDebugger::DispatchInput(void *baton, const void *data, size_t data_len) {
+   LLDB_RECORD_DUMMY(void, SBDebugger, DispatchInput,
+                     (void *, const void *, size_t), baton, data, data_len);
+ 
+   DispatchInput(data, data_len);
+ }
+ 
+ void SBDebugger::DispatchInput(const void *data, size_t data_len) {
+   LLDB_RECORD_DUMMY(void, SBDebugger, DispatchInput, (const void *, size_t),
+                     data, data_len);
+ 
+   //    Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
+   //
+   //    if (log)
+   //        LLDB_LOGF(log, "SBDebugger(%p)::DispatchInput (data=\"%.*s\",
+   //        size_t=%" PRIu64 ")",
+   //                     m_opaque_sp.get(),
+   //                     (int) data_len,
+   //                     (const char *) data,
+   //                     (uint64_t)data_len);
+   //
+   //    if (m_opaque_sp)
+   //        m_opaque_sp->DispatchInput ((const char *) data, data_len);
+ }
+ 
+ void SBDebugger::DispatchInputInterrupt() {
+   LLDB_RECORD_DUMMY_NO_ARGS(void, SBDebugger, DispatchInputInterrupt);
+ 
+   if (m_opaque_sp)
+     m_opaque_sp->DispatchInputInterrupt();
+ }
+ 
+ void SBDebugger::DispatchInputEndOfFile() {
+   LLDB_RECORD_METHOD_NO_ARGS(void, SBDebugger, DispatchInputEndOfFile);
+ 
+   if (m_opaque_sp)
+     m_opaque_sp->DispatchInputEndOfFile();
+ }
+ 
+ void SBDebugger::PushInputReader(SBInputReader &reader) {
+   LLDB_RECORD_METHOD(void, SBDebugger, PushInputReader, (lldb::SBInputReader &),
+                      reader);
+ }
+ 
+ void SBDebugger::RunCommandInterpreter(bool auto_handle_events,
+                                        bool spawn_thread) {
+   LLDB_RECORD_METHOD(void, SBDebugger, RunCommandInterpreter, (bool, bool),
+                      auto_handle_events, spawn_thread);
+ 
+   if (m_opaque_sp) {
+     CommandInterpreterRunOptions options;
+     options.SetAutoHandleEvents(auto_handle_events);
+     options.SetSpawnThread(spawn_thread);
+     m_opaque_sp->GetCommandInterpreter().RunCommandInterpreter(options);
+   }
+ }
+ 
+ void SBDebugger::RunCommandInterpreter(bool auto_handle_events,
+                                        bool spawn_thread,
+                                        SBCommandInterpreterRunOptions &options,
+                                        int &num_errors, bool &quit_requested,
+                                        bool &stopped_for_crash)
+ 
+ {
+   LLDB_RECORD_METHOD(void, SBDebugger, RunCommandInterpreter,
+                      (bool, bool, lldb::SBCommandInterpreterRunOptions &, int &,
+                       bool &, bool &),
+                      auto_handle_events, spawn_thread, options, num_errors,
+                      quit_requested, stopped_for_crash);
+ 
+   if (m_opaque_sp) {
+     options.SetAutoHandleEvents(auto_handle_events);
+     options.SetSpawnThread(spawn_thread);
+     CommandInterpreter &interp = m_opaque_sp->GetCommandInterpreter();
+     CommandInterpreterRunResult result =
+         interp.RunCommandInterpreter(options.ref());
+     num_errors = result.GetNumErrors();
+     quit_requested =
+         result.IsResult(lldb::eCommandInterpreterResultQuitRequested);
+     stopped_for_crash =
+         result.IsResult(lldb::eCommandInterpreterResultInferiorCrash);
+   }
+ }
+ 
+ SBCommandInterpreterRunResult SBDebugger::RunCommandInterpreter(
+     const SBCommandInterpreterRunOptions &options) {
+   LLDB_RECORD_METHOD(lldb::SBCommandInterpreterRunResult, SBDebugger,
+                      RunCommandInterpreter,
+                      (const lldb::SBCommandInterpreterRunOptions &), options);
+ 
+   if (!m_opaque_sp)
+     return LLDB_RECORD_RESULT(SBCommandInterpreterRunResult());
+ 
+   CommandInterpreter &interp = m_opaque_sp->GetCommandInterpreter();
+   CommandInterpreterRunResult result =
+       interp.RunCommandInterpreter(options.ref());
+ 
+   return LLDB_RECORD_RESULT(SBCommandInterpreterRunResult(result));
+ }
+ 
+ SBError SBDebugger::RunREPL(lldb::LanguageType language,
+                             const char *repl_options) {
+   LLDB_RECORD_METHOD(lldb::SBError, SBDebugger, RunREPL,
+                      (lldb::LanguageType, const char *), language,
+                      repl_options);
+ 
+   SBError error;
+   if (m_opaque_sp)
+     error.ref() = m_opaque_sp->RunREPL(language, repl_options);
+   else
+     error.SetErrorString("invalid debugger");
+   return LLDB_RECORD_RESULT(error);
+ }
+ 
+ void SBDebugger::reset(const DebuggerSP &debugger_sp) {
+   m_opaque_sp = debugger_sp;
+ }
+ 
+ Debugger *SBDebugger::get() const { return m_opaque_sp.get(); }
+ 
+ Debugger &SBDebugger::ref() const {
+   assert(m_opaque_sp.get());
+   return *m_opaque_sp;
+ }
+ 
+ const lldb::DebuggerSP &SBDebugger::get_sp() const { return m_opaque_sp; }
+ 
+ SBDebugger SBDebugger::FindDebuggerWithID(int id) {
+   LLDB_RECORD_STATIC_METHOD(lldb::SBDebugger, SBDebugger, FindDebuggerWithID,
+                             (int), id);
+ 
+   // No need to lock, the debugger list is thread safe
+   SBDebugger sb_debugger;
+   DebuggerSP debugger_sp = Debugger::FindDebuggerWithID(id);
+   if (debugger_sp)
+     sb_debugger.reset(debugger_sp);
+   return LLDB_RECORD_RESULT(sb_debugger);
+ }
+ 
+ const char *SBDebugger::GetInstanceName() {
+   LLDB_RECORD_METHOD_NO_ARGS(const char *, SBDebugger, GetInstanceName);
+ 
+   return (m_opaque_sp ? m_opaque_sp->GetInstanceName().AsCString() : nullptr);
+ }
+ 
+ SBError SBDebugger::SetInternalVariable(const char *var_name, const char *value,
+                                         const char *debugger_instance_name) {
+   LLDB_RECORD_STATIC_METHOD(lldb::SBError, SBDebugger, SetInternalVariable,
+                             (const char *, const char *, const char *),
+                             var_name, value, debugger_instance_name);
+ 
+   SBError sb_error;
+   DebuggerSP debugger_sp(Debugger::FindDebuggerWithInstanceName(
+       ConstString(debugger_instance_name)));
+   Status error;
+   if (debugger_sp) {
+     ExecutionContext exe_ctx(
+         debugger_sp->GetCommandInterpreter().GetExecutionContext());
+     error = debugger_sp->SetPropertyValue(&exe_ctx, eVarSetOperationAssign,
+                                           var_name, value);
+   } else {
+     error.SetErrorStringWithFormat("invalid debugger instance name '%s'",
+                                    debugger_instance_name);
+   }
+   if (error.Fail())
+     sb_error.SetError(error);
+   return LLDB_RECORD_RESULT(sb_error);
+ }
+ 
+ SBStringList
+ SBDebugger::GetInternalVariableValue(const char *var_name,
+                                      const char *debugger_instance_name) {
+   LLDB_RECORD_STATIC_METHOD(
+       lldb::SBStringList, SBDebugger, GetInternalVariableValue,
+       (const char *, const char *), var_name, debugger_instance_name);
+ 
+   DebuggerSP debugger_sp(Debugger::FindDebuggerWithInstanceName(
+       ConstString(debugger_instance_name)));
+   Status error;
+   if (debugger_sp) {
+     ExecutionContext exe_ctx(
+         debugger_sp->GetCommandInterpreter().GetExecutionContext());
+     lldb::OptionValueSP value_sp(
+         debugger_sp->GetPropertyValue(&exe_ctx, var_name, false, error));
+     if (value_sp) {
+       StreamString value_strm;
+       value_sp->DumpValue(&exe_ctx, value_strm, OptionValue::eDumpOptionValue);
+       const std::string &value_str = std::string(value_strm.GetString());
+       if (!value_str.empty()) {
+         StringList string_list;
+         string_list.SplitIntoLines(value_str);
+         return LLDB_RECORD_RESULT(SBStringList(&string_list));
+       }
+     }
+   }
+   return LLDB_RECORD_RESULT(SBStringList());
+ }
+ 
+ uint32_t SBDebugger::GetTerminalWidth() const {
+   LLDB_RECORD_METHOD_CONST_NO_ARGS(uint32_t, SBDebugger, GetTerminalWidth);
+ 
+   return (m_opaque_sp ? m_opaque_sp->GetTerminalWidth() : 0);
+ }
+ 
+ void SBDebugger::SetTerminalWidth(uint32_t term_width) {
+   LLDB_RECORD_DUMMY(void, SBDebugger, SetTerminalWidth, (uint32_t), term_width);
+ 
+   if (m_opaque_sp)
+     m_opaque_sp->SetTerminalWidth(term_width);
+ }
+ 
+ const char *SBDebugger::GetPrompt() const {
+   LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBDebugger, GetPrompt);
+ 
+   Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+ 
+   LLDB_LOGF(log, "SBDebugger(%p)::GetPrompt () => \"%s\"",
+             static_cast<void *>(m_opaque_sp.get()),
+             (m_opaque_sp ? m_opaque_sp->GetPrompt().str().c_str() : ""));
+ 
+   return (m_opaque_sp ? ConstString(m_opaque_sp->GetPrompt()).GetCString()
+                       : nullptr);
+ }
+ 
+ void SBDebugger::SetPrompt(const char *prompt) {
+   LLDB_RECORD_METHOD(void, SBDebugger, SetPrompt, (const char *), prompt);
+ 
+   if (m_opaque_sp)
+     m_opaque_sp->SetPrompt(llvm::StringRef(prompt));
+ }
+ 
+ const char *SBDebugger::GetReproducerPath() const {
+   LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBDebugger, GetReproducerPath);
+ 
+   return (m_opaque_sp
+               ? ConstString(m_opaque_sp->GetReproducerPath()).GetCString()
+               : nullptr);
+ }
+ 
+ ScriptLanguage SBDebugger::GetScriptLanguage() const {
+   LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::ScriptLanguage, SBDebugger,
+                                    GetScriptLanguage);
+ 
+   return (m_opaque_sp ? m_opaque_sp->GetScriptLanguage() : eScriptLanguageNone);
+ }
+ 
+ void SBDebugger::SetScriptLanguage(ScriptLanguage script_lang) {
+   LLDB_RECORD_METHOD(void, SBDebugger, SetScriptLanguage,
+                      (lldb::ScriptLanguage), script_lang);
+ 
+   if (m_opaque_sp) {
+     m_opaque_sp->SetScriptLanguage(script_lang);
+   }
+ }
+ 
+ bool SBDebugger::SetUseExternalEditor(bool value) {
+   LLDB_RECORD_METHOD(bool, SBDebugger, SetUseExternalEditor, (bool), value);
+ 
+   return (m_opaque_sp ? m_opaque_sp->SetUseExternalEditor(value) : false);
+ }
+ 
+ bool SBDebugger::GetUseExternalEditor() {
+   LLDB_RECORD_METHOD_NO_ARGS(bool, SBDebugger, GetUseExternalEditor);
+ 
+   return (m_opaque_sp ? m_opaque_sp->GetUseExternalEditor() : false);
+ }
+ 
+ bool SBDebugger::SetUseColor(bool value) {
+   LLDB_RECORD_METHOD(bool, SBDebugger, SetUseColor, (bool), value);
+ 
+   return (m_opaque_sp ? m_opaque_sp->SetUseColor(value) : false);
+ }
+ 
+ bool SBDebugger::GetUseColor() const {
+   LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBDebugger, GetUseColor);
+ 
+   return (m_opaque_sp ? m_opaque_sp->GetUseColor() : false);
+ }
+ 
+ bool SBDebugger::SetUseSourceCache(bool value) {
+   LLDB_RECORD_METHOD(bool, SBDebugger, SetUseSourceCache, (bool), value);
+ 
+   return (m_opaque_sp ? m_opaque_sp->SetUseSourceCache(value) : false);
+ }
+ 
+ bool SBDebugger::GetUseSourceCache() const {
+   LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBDebugger, GetUseSourceCache);
+ 
+   return (m_opaque_sp ? m_opaque_sp->GetUseSourceCache() : false);
+ }
+ 
+ bool SBDebugger::GetDescription(SBStream &description) {
+   LLDB_RECORD_METHOD(bool, SBDebugger, GetDescription, (lldb::SBStream &),
+                      description);
+ 
+   Stream &strm = description.ref();
+ 
+   if (m_opaque_sp) {
+     const char *name = m_opaque_sp->GetInstanceName().AsCString();
+     user_id_t id = m_opaque_sp->GetID();
+     strm.Printf("Debugger (instance: \"%s\", id: %" PRIu64 ")", name, id);
+   } else
+     strm.PutCString("No value");
+ 
+   return true;
+ }
+ 
+ user_id_t SBDebugger::GetID() {
+   LLDB_RECORD_METHOD_NO_ARGS(lldb::user_id_t, SBDebugger, GetID);
+ 
+   return (m_opaque_sp ? m_opaque_sp->GetID() : LLDB_INVALID_UID);
+ }
+ 
+ SBError SBDebugger::SetCurrentPlatform(const char *platform_name_cstr) {
+   LLDB_RECORD_METHOD(lldb::SBError, SBDebugger, SetCurrentPlatform,
+                      (const char *), platform_name_cstr);
+ 
+   SBError sb_error;
+   if (m_opaque_sp) {
+     if (platform_name_cstr && platform_name_cstr[0]) {
+       ConstString platform_name(platform_name_cstr);
+       PlatformSP platform_sp(Platform::Find(platform_name));
+ 
+       if (platform_sp) {
+         // Already have a platform with this name, just select it
+         m_opaque_sp->GetPlatformList().SetSelectedPlatform(platform_sp);
+       } else {
+         // We don't have a platform by this name yet, create one
+         platform_sp = Platform::Create(platform_name, sb_error.ref());
+         if (platform_sp) {
+           // We created the platform, now append and select it
+           bool make_selected = true;
+           m_opaque_sp->GetPlatformList().Append(platform_sp, make_selected);
+         }
+       }
+     } else {
+       sb_error.ref().SetErrorString("invalid platform name");
+     }
+   } else {
+     sb_error.ref().SetErrorString("invalid debugger");
+   }
+   return LLDB_RECORD_RESULT(sb_error);
+ }
+ 
+ bool SBDebugger::SetCurrentPlatformSDKRoot(const char *sysroot) {
+   LLDB_RECORD_METHOD(bool, SBDebugger, SetCurrentPlatformSDKRoot,
+                      (const char *), sysroot);
+ 
+   Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
+   if (m_opaque_sp) {
+     PlatformSP platform_sp(
+         m_opaque_sp->GetPlatformList().GetSelectedPlatform());
+ 
+     if (platform_sp) {
+       if (log && sysroot)
+         LLDB_LOGF(log, "SBDebugger::SetCurrentPlatformSDKRoot (\"%s\")",
+                   sysroot);
+       platform_sp->SetSDKRootDirectory(ConstString(sysroot));
+       return true;
+     }
+   }
+   return false;
+ }
+ 
+ bool SBDebugger::GetCloseInputOnEOF() const {
+   LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBDebugger, GetCloseInputOnEOF);
+ 
+   return (m_opaque_sp ? m_opaque_sp->GetCloseInputOnEOF() : false);
+ }
+ 
+ void SBDebugger::SetCloseInputOnEOF(bool b) {
+   LLDB_RECORD_METHOD(void, SBDebugger, SetCloseInputOnEOF, (bool), b);
+ 
+   if (m_opaque_sp)
+     m_opaque_sp->SetCloseInputOnEOF(b);
+ }
+ 
+ SBTypeCategory SBDebugger::GetCategory(const char *category_name) {
+   LLDB_RECORD_METHOD(lldb::SBTypeCategory, SBDebugger, GetCategory,
+                      (const char *), category_name);
+ 
+   if (!category_name || *category_name == 0)
+     return LLDB_RECORD_RESULT(SBTypeCategory());
+ 
+   TypeCategoryImplSP category_sp;
+ 
+   if (DataVisualization::Categories::GetCategory(ConstString(category_name),
+                                                  category_sp, false)) {
+     return LLDB_RECORD_RESULT(SBTypeCategory(category_sp));
+   } else {
+     return LLDB_RECORD_RESULT(SBTypeCategory());
+   }
+ }
+ 
+ SBTypeCategory SBDebugger::GetCategory(lldb::LanguageType lang_type) {
+   LLDB_RECORD_METHOD(lldb::SBTypeCategory, SBDebugger, GetCategory,
+                      (lldb::LanguageType), lang_type);
+ 
+   TypeCategoryImplSP category_sp;
+   if (DataVisualization::Categories::GetCategory(lang_type, category_sp)) {
+     return LLDB_RECORD_RESULT(SBTypeCategory(category_sp));
+   } else {
+     return LLDB_RECORD_RESULT(SBTypeCategory());
+   }
+ }
+ 
+ SBTypeCategory SBDebugger::CreateCategory(const char *category_name) {
+   LLDB_RECORD_METHOD(lldb::SBTypeCategory, SBDebugger, CreateCategory,
+                      (const char *), category_name);
+ 
+   if (!category_name || *category_name == 0)
+     return LLDB_RECORD_RESULT(SBTypeCategory());
+ 
+   TypeCategoryImplSP category_sp;
+ 
+   if (DataVisualization::Categories::GetCategory(ConstString(category_name),
+                                                  category_sp, true)) {
+     return LLDB_RECORD_RESULT(SBTypeCategory(category_sp));
+   } else {
+     return LLDB_RECORD_RESULT(SBTypeCategory());
+   }
+ }
+ 
+ bool SBDebugger::DeleteCategory(const char *category_name) {
+   LLDB_RECORD_METHOD(bool, SBDebugger, DeleteCategory, (const char *),
+                      category_name);
+ 
+   if (!category_name || *category_name == 0)
+     return false;
+ 
+   return DataVisualization::Categories::Delete(ConstString(category_name));
+ }
+ 
+ uint32_t SBDebugger::GetNumCategories() {
+   LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBDebugger, GetNumCategories);
+ 
+   return DataVisualization::Categories::GetCount();
+ }
+ 
+ SBTypeCategory SBDebugger::GetCategoryAtIndex(uint32_t index) {
+   LLDB_RECORD_METHOD(lldb::SBTypeCategory, SBDebugger, GetCategoryAtIndex,
+                      (uint32_t), index);
+ 
+   return LLDB_RECORD_RESULT(
+       SBTypeCategory(DataVisualization::Categories::GetCategoryAtIndex(index)));
+ }
+ 
+ SBTypeCategory SBDebugger::GetDefaultCategory() {
+   LLDB_RECORD_METHOD_NO_ARGS(lldb::SBTypeCategory, SBDebugger,
+                              GetDefaultCategory);
+ 
+   return LLDB_RECORD_RESULT(GetCategory("default"));
+ }
+ 
+ SBTypeFormat SBDebugger::GetFormatForType(SBTypeNameSpecifier type_name) {
+   LLDB_RECORD_METHOD(lldb::SBTypeFormat, SBDebugger, GetFormatForType,
+                      (lldb::SBTypeNameSpecifier), type_name);
+ 
+   SBTypeCategory default_category_sb = GetDefaultCategory();
+   if (default_category_sb.GetEnabled())
+     return LLDB_RECORD_RESULT(default_category_sb.GetFormatForType(type_name));
+   return LLDB_RECORD_RESULT(SBTypeFormat());
+ }
+ 
+ SBTypeSummary SBDebugger::GetSummaryForType(SBTypeNameSpecifier type_name) {
+   LLDB_RECORD_METHOD(lldb::SBTypeSummary, SBDebugger, GetSummaryForType,
+                      (lldb::SBTypeNameSpecifier), type_name);
+ 
+   if (!type_name.IsValid())
+     return LLDB_RECORD_RESULT(SBTypeSummary());
+   return LLDB_RECORD_RESULT(
+       SBTypeSummary(DataVisualization::GetSummaryForType(type_name.GetSP())));
+ }
+ 
+ SBTypeFilter SBDebugger::GetFilterForType(SBTypeNameSpecifier type_name) {
+   LLDB_RECORD_METHOD(lldb::SBTypeFilter, SBDebugger, GetFilterForType,
+                      (lldb::SBTypeNameSpecifier), type_name);
+ 
+   if (!type_name.IsValid())
+     return LLDB_RECORD_RESULT(SBTypeFilter());
+   return LLDB_RECORD_RESULT(
+       SBTypeFilter(DataVisualization::GetFilterForType(type_name.GetSP())));
+ }
+ 
+ SBTypeSynthetic SBDebugger::GetSyntheticForType(SBTypeNameSpecifier type_name) {
+   LLDB_RECORD_METHOD(lldb::SBTypeSynthetic, SBDebugger, GetSyntheticForType,
+                      (lldb::SBTypeNameSpecifier), type_name);
+ 
+   if (!type_name.IsValid())
+     return LLDB_RECORD_RESULT(SBTypeSynthetic());
+   return LLDB_RECORD_RESULT(SBTypeSynthetic(
+       DataVisualization::GetSyntheticForType(type_name.GetSP())));
+ }
+ 
+ static llvm::ArrayRef<const char *> GetCategoryArray(const char **categories) {
+   if (categories == nullptr)
+     return {};
+   size_t len = 0;
+   while (categories[len] != nullptr)
+     ++len;
+   return llvm::makeArrayRef(categories, len);
+ }
+ 
+ bool SBDebugger::EnableLog(const char *channel, const char **categories) {
+   LLDB_RECORD_METHOD(bool, SBDebugger, EnableLog, (const char *, const char **),
+                      channel, categories);
+ 
+   if (m_opaque_sp) {
+     uint32_t log_options =
+         LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_THREAD_NAME;
+     std::string error;
+     llvm::raw_string_ostream error_stream(error);
+     return m_opaque_sp->EnableLog(channel, GetCategoryArray(categories), "",
+                                   log_options, error_stream);
+   } else
+     return false;
+ }
+ 
+ void SBDebugger::SetLoggingCallback(lldb::LogOutputCallback log_callback,
+                                     void *baton) {
+   LLDB_RECORD_DUMMY(void, SBDebugger, SetLoggingCallback,
+                     (lldb::LogOutputCallback, void *), log_callback, baton);
+ 
+   if (m_opaque_sp) {
+     return m_opaque_sp->SetLoggingCallback(log_callback, baton);
+   }
+ }
+ 
+ namespace lldb_private {
+ namespace repro {
+ 
+ template <> void RegisterMethods<SBInputReader>(Registry &R) {
+   LLDB_REGISTER_METHOD(void, SBInputReader, SetIsDone, (bool));
+   LLDB_REGISTER_METHOD_CONST(bool, SBInputReader, IsActive, ());
+ }
+ 
+ static void SetFileHandleRedirect(SBDebugger *, FILE *, bool) {
+   // Do nothing.
+ }
+ 
+ static SBError SetFileRedirect(SBDebugger *, SBFile file) { return SBError(); }
+ 
+ static SBError SetFileRedirect(SBDebugger *, FileSP file) { return SBError(); }
+ 
+ template <> void RegisterMethods<SBDebugger>(Registry &R) {
+   // Custom implementation.
+   R.Register(&invoke<void (SBDebugger::*)(FILE *, bool)>::method<
+                  &SBDebugger::SetErrorFileHandle>::record,
+              &SetFileHandleRedirect);
+   R.Register(&invoke<void (SBDebugger::*)(FILE *, bool)>::method<
+                  &SBDebugger::SetOutputFileHandle>::record,
+              &SetFileHandleRedirect);
+ 
+   R.Register(&invoke<SBError (SBDebugger::*)(
+                  SBFile)>::method<&SBDebugger::SetInputFile>::record,
+              &SetFileRedirect);
+   R.Register(&invoke<SBError (SBDebugger::*)(
+                  SBFile)>::method<&SBDebugger::SetOutputFile>::record,
+              &SetFileRedirect);
+   R.Register(&invoke<SBError (SBDebugger::*)(
+                  SBFile)>::method<&SBDebugger::SetErrorFile>::record,
+              &SetFileRedirect);
+ 
+   R.Register(&invoke<SBError (SBDebugger::*)(
+                  FileSP)>::method<&SBDebugger::SetInputFile>::record,
+              &SetFileRedirect);
+   R.Register(&invoke<SBError (SBDebugger::*)(
+                  FileSP)>::method<&SBDebugger::SetOutputFile>::record,
+              &SetFileRedirect);
+   R.Register(&invoke<SBError (SBDebugger::*)(
+                  FileSP)>::method<&SBDebugger::SetErrorFile>::record,
+              &SetFileRedirect);
+ 
+   LLDB_REGISTER_CHAR_PTR_METHOD_STATIC(bool, SBDebugger,
+                                        GetDefaultArchitecture);
+ 
+   LLDB_REGISTER_CONSTRUCTOR(SBDebugger, ());
+   LLDB_REGISTER_CONSTRUCTOR(SBDebugger, (const lldb::DebuggerSP &));
+   LLDB_REGISTER_CONSTRUCTOR(SBDebugger, (const lldb::SBDebugger &));
+   LLDB_REGISTER_METHOD(lldb::SBDebugger &,
+                        SBDebugger, operator=,(const lldb::SBDebugger &));
+   LLDB_REGISTER_STATIC_METHOD(void, SBDebugger, Initialize, ());
+   LLDB_REGISTER_STATIC_METHOD(lldb::SBError, SBDebugger,
+                               InitializeWithErrorHandling, ());
+   LLDB_REGISTER_STATIC_METHOD(void, SBDebugger, Terminate, ());
+   LLDB_REGISTER_METHOD(void, SBDebugger, Clear, ());
+   LLDB_REGISTER_STATIC_METHOD(lldb::SBDebugger, SBDebugger, Create, ());
+   LLDB_REGISTER_STATIC_METHOD(lldb::SBDebugger, SBDebugger, Create, (bool));
+   LLDB_REGISTER_STATIC_METHOD(
+       const char *, SBDebugger, GetProgressFromEvent,
+       (const lldb::SBEvent &, uint64_t &, uint64_t &, uint64_t &, bool &));
+   LLDB_REGISTER_STATIC_METHOD(const char *, SBDebugger, GetBroadcasterClass,
+                               ());
+   LLDB_REGISTER_METHOD(SBBroadcaster, SBDebugger, GetBroadcaster, ());
+   LLDB_REGISTER_STATIC_METHOD(void, SBDebugger, Destroy, (lldb::SBDebugger &));
+   LLDB_REGISTER_STATIC_METHOD(void, SBDebugger, MemoryPressureDetected, ());
+   LLDB_REGISTER_METHOD_CONST(bool, SBDebugger, IsValid, ());
+   LLDB_REGISTER_METHOD_CONST(bool, SBDebugger, operator bool,());
+   LLDB_REGISTER_METHOD(void, SBDebugger, SetAsync, (bool));
+   LLDB_REGISTER_METHOD(bool, SBDebugger, GetAsync, ());
+   LLDB_REGISTER_METHOD(void, SBDebugger, SkipLLDBInitFiles, (bool));
+   LLDB_REGISTER_METHOD(void, SBDebugger, SkipAppInitFiles, (bool));
+   LLDB_REGISTER_METHOD(void, SBDebugger, SetInputFileHandle, (FILE *, bool));
+   LLDB_REGISTER_METHOD(FILE *, SBDebugger, GetInputFileHandle, ());
+   LLDB_REGISTER_METHOD(FILE *, SBDebugger, GetOutputFileHandle, ());
+   LLDB_REGISTER_METHOD(FILE *, SBDebugger, GetErrorFileHandle, ());
+   LLDB_REGISTER_METHOD(SBFile, SBDebugger, GetInputFile, ());
+   LLDB_REGISTER_METHOD(SBFile, SBDebugger, GetOutputFile, ());
+   LLDB_REGISTER_METHOD(SBFile, SBDebugger, GetErrorFile, ());
+   LLDB_REGISTER_METHOD(void, SBDebugger, SaveInputTerminalState, ());
+   LLDB_REGISTER_METHOD(void, SBDebugger, RestoreInputTerminalState, ());
+   LLDB_REGISTER_METHOD(lldb::SBCommandInterpreter, SBDebugger,
+                        GetCommandInterpreter, ());
+   LLDB_REGISTER_METHOD(void, SBDebugger, HandleCommand, (const char *));
+   LLDB_REGISTER_METHOD(lldb::SBListener, SBDebugger, GetListener, ());
+   LLDB_REGISTER_METHOD(
+       void, SBDebugger, HandleProcessEvent,
+       (const lldb::SBProcess &, const lldb::SBEvent &, FILE *, FILE *));
+   LLDB_REGISTER_METHOD(
+       void, SBDebugger, HandleProcessEvent,
+       (const lldb::SBProcess &, const lldb::SBEvent &, SBFile, SBFile));
+   LLDB_REGISTER_METHOD(
+       void, SBDebugger, HandleProcessEvent,
+       (const lldb::SBProcess &, const lldb::SBEvent &, FileSP, FileSP));
+   LLDB_REGISTER_METHOD(lldb::SBSourceManager, SBDebugger, GetSourceManager, ());
+   LLDB_REGISTER_STATIC_METHOD(bool, SBDebugger, SetDefaultArchitecture,
+                               (const char *));
+   LLDB_REGISTER_METHOD(lldb::ScriptLanguage, SBDebugger, GetScriptingLanguage,
+                        (const char *));
+   LLDB_REGISTER_STATIC_METHOD(const char *, SBDebugger, GetVersionString, ());
+   LLDB_REGISTER_STATIC_METHOD(const char *, SBDebugger, StateAsCString,
+                               (lldb::StateType));
+   LLDB_REGISTER_STATIC_METHOD(lldb::SBStructuredData, SBDebugger,
+                               GetBuildConfiguration, ());
+   LLDB_REGISTER_STATIC_METHOD(bool, SBDebugger, StateIsRunningState,
+                               (lldb::StateType));
+   LLDB_REGISTER_STATIC_METHOD(bool, SBDebugger, StateIsStoppedState,
+                               (lldb::StateType));
+   LLDB_REGISTER_METHOD(
+       lldb::SBTarget, SBDebugger, CreateTarget,
+       (const char *, const char *, const char *, bool, lldb::SBError &));
+   LLDB_REGISTER_METHOD(lldb::SBTarget, SBDebugger,
+                        CreateTargetWithFileAndTargetTriple,
+                        (const char *, const char *));
+   LLDB_REGISTER_METHOD(lldb::SBTarget, SBDebugger, CreateTargetWithFileAndArch,
+                        (const char *, const char *));
+   LLDB_REGISTER_METHOD(lldb::SBTarget, SBDebugger, CreateTarget,
+                        (const char *));
+   LLDB_REGISTER_METHOD(lldb::SBTarget, SBDebugger, GetDummyTarget, ());
+   LLDB_REGISTER_METHOD(bool, SBDebugger, DeleteTarget, (lldb::SBTarget &));
+   LLDB_REGISTER_METHOD(lldb::SBTarget, SBDebugger, GetTargetAtIndex,
+                        (uint32_t));
+   LLDB_REGISTER_METHOD(uint32_t, SBDebugger, GetIndexOfTarget,
+                        (lldb::SBTarget));
+   LLDB_REGISTER_METHOD(lldb::SBTarget, SBDebugger, FindTargetWithProcessID,
+                        (lldb::pid_t));
+   LLDB_REGISTER_METHOD(lldb::SBTarget, SBDebugger, FindTargetWithFileAndArch,
+                        (const char *, const char *));
+   LLDB_REGISTER_METHOD(uint32_t, SBDebugger, GetNumTargets, ());
+   LLDB_REGISTER_METHOD(lldb::SBTarget, SBDebugger, GetSelectedTarget, ());
+   LLDB_REGISTER_METHOD(void, SBDebugger, SetSelectedTarget, (lldb::SBTarget &));
+   LLDB_REGISTER_METHOD(lldb::SBPlatform, SBDebugger, GetSelectedPlatform, ());
+   LLDB_REGISTER_METHOD(void, SBDebugger, SetSelectedPlatform,
+                        (lldb::SBPlatform &));
+   LLDB_REGISTER_METHOD(uint32_t, SBDebugger, GetNumPlatforms, ());
+   LLDB_REGISTER_METHOD(lldb::SBPlatform, SBDebugger, GetPlatformAtIndex,
+                        (uint32_t));
+   LLDB_REGISTER_METHOD(uint32_t, SBDebugger, GetNumAvailablePlatforms, ());
+   LLDB_REGISTER_METHOD(lldb::SBStructuredData, SBDebugger,
+                        GetAvailablePlatformInfoAtIndex, (uint32_t));
+   LLDB_REGISTER_METHOD(void, SBDebugger, DispatchInputInterrupt, ());
+   LLDB_REGISTER_METHOD(void, SBDebugger, DispatchInputEndOfFile, ());
+   LLDB_REGISTER_METHOD(void, SBDebugger, PushInputReader,
+                        (lldb::SBInputReader &));
+   LLDB_REGISTER_METHOD(void, SBDebugger, RunCommandInterpreter, (bool, bool));
+   LLDB_REGISTER_METHOD(void, SBDebugger, RunCommandInterpreter,
+                        (bool, bool, lldb::SBCommandInterpreterRunOptions &,
+                         int &, bool &, bool &));
+   LLDB_REGISTER_METHOD(lldb::SBError, SBDebugger, RunREPL,
+                        (lldb::LanguageType, const char *));
+   LLDB_REGISTER_STATIC_METHOD(lldb::SBDebugger, SBDebugger, FindDebuggerWithID,
+                               (int));
+   LLDB_REGISTER_METHOD(const char *, SBDebugger, GetInstanceName, ());
+   LLDB_REGISTER_STATIC_METHOD(lldb::SBError, SBDebugger, SetInternalVariable,
+                               (const char *, const char *, const char *));
+   LLDB_REGISTER_STATIC_METHOD(lldb::SBStringList, SBDebugger,
+                               GetInternalVariableValue,
+                               (const char *, const char *));
+   LLDB_REGISTER_METHOD_CONST(uint32_t, SBDebugger, GetTerminalWidth, ());
+   LLDB_REGISTER_METHOD(void, SBDebugger, SetTerminalWidth, (uint32_t));
+   LLDB_REGISTER_METHOD_CONST(const char *, SBDebugger, GetPrompt, ());
+   LLDB_REGISTER_METHOD(void, SBDebugger, SetPrompt, (const char *));
+   LLDB_REGISTER_METHOD_CONST(const char *, SBDebugger, GetReproducerPath, ());
+   LLDB_REGISTER_METHOD_CONST(lldb::ScriptLanguage, SBDebugger,
+                              GetScriptLanguage, ());
+   LLDB_REGISTER_METHOD(void, SBDebugger, SetScriptLanguage,
+                        (lldb::ScriptLanguage));
+   LLDB_REGISTER_METHOD(bool, SBDebugger, SetUseExternalEditor, (bool));
+   LLDB_REGISTER_METHOD(bool, SBDebugger, GetUseExternalEditor, ());
+   LLDB_REGISTER_METHOD(bool, SBDebugger, SetUseColor, (bool));
+   LLDB_REGISTER_METHOD_CONST(bool, SBDebugger, GetUseColor, ());
+   LLDB_REGISTER_METHOD(bool, SBDebugger, GetDescription, (lldb::SBStream &));
+   LLDB_REGISTER_METHOD(lldb::user_id_t, SBDebugger, GetID, ());
+   LLDB_REGISTER_METHOD(lldb::SBError, SBDebugger, SetCurrentPlatform,
+                        (const char *));
+   LLDB_REGISTER_METHOD(bool, SBDebugger, SetCurrentPlatformSDKRoot,
+                        (const char *));
+   LLDB_REGISTER_METHOD_CONST(bool, SBDebugger, GetCloseInputOnEOF, ());
+   LLDB_REGISTER_METHOD(void, SBDebugger, SetCloseInputOnEOF, (bool));
+   LLDB_REGISTER_METHOD(lldb::SBTypeCategory, SBDebugger, GetCategory,
+                        (const char *));
+   LLDB_REGISTER_METHOD(lldb::SBTypeCategory, SBDebugger, GetCategory,
+                        (lldb::LanguageType));
+   LLDB_REGISTER_METHOD(lldb::SBTypeCategory, SBDebugger, CreateCategory,
+                        (const char *));
+   LLDB_REGISTER_METHOD(bool, SBDebugger, DeleteCategory, (const char *));
+   LLDB_REGISTER_METHOD(uint32_t, SBDebugger, GetNumCategories, ());
+   LLDB_REGISTER_METHOD(lldb::SBTypeCategory, SBDebugger, GetCategoryAtIndex,
+                        (uint32_t));
+   LLDB_REGISTER_METHOD(lldb::SBTypeCategory, SBDebugger, GetDefaultCategory,
+                        ());
+   LLDB_REGISTER_METHOD(lldb::SBTypeFormat, SBDebugger, GetFormatForType,
+                        (lldb::SBTypeNameSpecifier));
+   LLDB_REGISTER_METHOD(lldb::SBTypeSummary, SBDebugger, GetSummaryForType,
+                        (lldb::SBTypeNameSpecifier));
+   LLDB_REGISTER_METHOD(lldb::SBTypeSynthetic, SBDebugger, GetSyntheticForType,
+                        (lldb::SBTypeNameSpecifier));
+   LLDB_REGISTER_METHOD(lldb::SBTypeFilter, SBDebugger, GetFilterForType,
+                        (lldb::SBTypeNameSpecifier));
+   LLDB_REGISTER_METHOD(bool, SBDebugger, EnableLog,
+                        (const char *, const char **));
+   LLDB_REGISTER_METHOD(lldb::SBCommandInterpreterRunResult, SBDebugger,
+                        RunCommandInterpreter,
+                        (const lldb::SBCommandInterpreterRunOptions &));
+ }
+ 
+ } // namespace repro
+ } // namespace lldb_private
+diff --git a/lldb/source/API/liblldb-private.exports b/lldb/source/API/liblldb-private.exports
+index 9b3d86dfc892..e6c3bd9e80b9 100644
+--- a/lldb/source/API/liblldb-private.exports
++++ b/lldb/source/API/liblldb-private.exports
+@@ -1,6 +1,7 @@
+ _ZN4lldb*
+ _ZNK4lldb*
+ _ZN12lldb_private*
+ _ZNK12lldb_private*
+ init_lld*
+ PyInit__lldb*
++Java*
+diff --git a/lldb/source/API/liblldb.exports b/lldb/source/API/liblldb.exports
+index 3ceb562c7ed1..fcc506ff0f84 100644
+--- a/lldb/source/API/liblldb.exports
++++ b/lldb/source/API/liblldb.exports
+@@ -1,4 +1,7 @@
+ _ZN4lldb*
+ _ZNK4lldb*
++_ZN12lldb*
++_ZNK12lldb*
+ init_lld*
+ PyInit__lldb*
++Java*
Index: lldb/source/API/liblldb.exports
===================================================================
--- lldb/source/API/liblldb.exports
+++ lldb/source/API/liblldb.exports
@@ -1,4 +1,7 @@
 _ZN4lldb*
 _ZNK4lldb*
+_ZN12lldb*
+_ZNK12lldb*
 init_lld*
 PyInit__lldb*
+Java*
Index: lldb/source/API/liblldb-private.exports
===================================================================
--- lldb/source/API/liblldb-private.exports
+++ lldb/source/API/liblldb-private.exports
@@ -4,3 +4,4 @@
 _ZNK12lldb_private*
 init_lld*
 PyInit__lldb*
+Java*
Index: lldb/source/API/SBDebugger.cpp
===================================================================
--- lldb/source/API/SBDebugger.cpp
+++ lldb/source/API/SBDebugger.cpp
@@ -736,6 +736,9 @@
   AddBoolConfigEntry(
       *config_up, "lua", LLDB_ENABLE_LUA,
       "A boolean value that indicates if lua support is enabled in LLDB");
+  AddBoolConfigEntry(
+      *config_up, "java", LLDB_ENABLE_JAVA,
+      "A boolean value that indicates if java support is enabled in LLDB");
   AddLLVMTargets(*config_up);
 
   SBStructuredData data;
Index: lldb/source/API/CMakeLists.txt
===================================================================
--- lldb/source/API/CMakeLists.txt
+++ lldb/source/API/CMakeLists.txt
@@ -19,6 +19,11 @@
   set(lldb_lua_wrapper ${lua_bindings_dir}/LLDBWrapLua.cpp)
 endif()
 
+if(LLDB_ENABLE_JAVA)
+  get_target_property(java_bindings_dir swig_wrapper_java BINARY_DIR)
+  set(lldb_java_wrapper ${java_bindings_dir}/LLDBWrapJava.cpp)
+endif()
+
 add_lldb_library(liblldb SHARED ${option_framework}
   SBAddress.cpp
   SBAttachInfo.cpp
@@ -76,6 +81,7 @@
   SBThreadCollection.cpp
   SBThreadPlan.cpp
   SBTrace.cpp
+  SBTraceOptions.cpp
   SBType.cpp
   SBTypeCategory.cpp
   SBTypeEnumMember.cpp
@@ -92,6 +98,7 @@
   SystemInitializerFull.cpp
   ${lldb_python_wrapper}
   ${lldb_lua_wrapper}
+  ${lldb_java_wrapper}
 
   LINK_LIBS
     lldbBase
@@ -160,6 +167,21 @@
   set_source_files_properties(${lldb_lua_wrapper} PROPERTIES GENERATED ON)
 endif()
 
+if(LLDB_ENABLE_JAVA)
+  add_dependencies(liblldb swig_wrapper_java)
+  target_include_directories(liblldb PRIVATE ${JAVA_INCLUDE_DIR})
+  target_include_directories(liblldb PRIVATE ${JAVA_INCLUDE_DIR}/darwin)
+
+  if (MSVC)
+    set_property(SOURCE ${lldb_java_wrapper} APPEND_STRING PROPERTY COMPILE_FLAGS " /W0")
+  else()
+    set_property(SOURCE ${lldb_java_wrapper} APPEND_STRING PROPERTY COMPILE_FLAGS " ")
+  endif()
+
+  set_source_files_properties(${lldb_java_wrapper} PROPERTIES GENERATED ON)
+endif()
+
+
 set_target_properties(liblldb
   PROPERTIES
   VERSION ${LLDB_VERSION}
@@ -181,7 +203,13 @@
   set_target_properties(liblldb_exports PROPERTIES FOLDER "lldb misc")
 endif()
 
-if (NOT MSVC)
+if (MSVC)
+  # Only MSVC has the ABI compatibility problem and avoids using FindPythonLibs,
+  # so only it needs to explicitly link against ${Python3_LIBRARIES}
+  if (LLDB_ENABLE_PYTHON)
+    target_link_libraries(liblldb PRIVATE ${Python3_LIBRARIES})
+  endif()
+else()
   set_target_properties(liblldb
     PROPERTIES
     OUTPUT_NAME lldb
Index: lldb/include/lldb/Host/Config.h.cmake
===================================================================
--- lldb/include/lldb/Host/Config.h.cmake
+++ lldb/include/lldb/Host/Config.h.cmake
@@ -41,6 +41,8 @@
 
 #cmakedefine01 LLDB_ENABLE_LIBXML2
 
+#cmakedefine01 LLDB_ENABLE_JAVA
+
 #cmakedefine01 LLDB_ENABLE_LUA
 
 #cmakedefine01 LLDB_ENABLE_PYTHON
Index: lldb/cmake/modules/FindJavaAndSwig.cmake
===================================================================
--- /dev/null
+++ lldb/cmake/modules/FindJavaAndSwig.cmake
@@ -0,0 +1,32 @@
+#.rst:
+# FindJavaAndSwig
+# --------------
+#
+# Find Java and SWIG as a whole.
+
+#if(JAVA_LIBRARIES AND JAVA_INCLUDE_DIR AND SWIG_EXECUTABLE)
+if(SWIG_EXECUTABLE)
+  set(JAVAANDSWIG_FOUND TRUE)
+else()
+  find_package(SWIG 2.0)
+  if (SWIG_FOUND)
+    find_package(Java 11.0)
+    if(JAVA_FOUND AND SWIG_FOUND)
+      mark_as_advanced(
+        JAVA_LIBRARIES
+        JAVA_INCLUDE_DIR
+        SWIG_EXECUTABLE)
+    endif()
+  else()
+    message(STATUS "SWIG 2 or later is required for Java support in LLDB but could not be found")
+  endif()
+
+  include(FindPackageHandleStandardArgs)
+  find_package_handle_standard_args(JavaAndSwig
+                                    FOUND_VAR
+                                      JAVAANDSWIG_FOUND
+                                    REQUIRED_VARS
+                                      JAVA_LIBRARIES
+                                      JAVA_INCLUDE_DIR
+                                      SWIG_EXECUTABLE)
+endif()
Index: lldb/bindings/java/java.swig
===================================================================
--- /dev/null
+++ lldb/bindings/java/java.swig
@@ -0,0 +1,25 @@
+/* ###
+ * IP: Apache License 2.0 with LLVM Exceptions
+ */
+/*
+   lldb.swig
+
+   This is the input file for SWIG, to create the appropriate C++ wrappers and
+   functions for various scripting languages, to enable them to call the
+   liblldb Script Bridge functions.
+*/
+
+%module lldb
+
+%include <std_string.i>
+%include "java-typemaps.swig"
+%include "macros.swig"
+%include "headers.swig"
+
+%{
+using namespace lldb_private;
+using namespace lldb;
+%}
+
+%include "interfaces.swig"
+//%include "lua-wrapper.swig"
Index: lldb/bindings/java/java-typemaps.swig
===================================================================
--- /dev/null
+++ lldb/bindings/java/java-typemaps.swig
@@ -0,0 +1,21 @@
+/* ###
+ * IP: Apache License 2.0 with LLVM Exceptions
+ */
+%include <typemaps.i>
+%include <carrays.i>
+%include <various.i>
+
+%typemap(javabase) ByteArray "SWIGTYPE_p_void"
+%typemap(javabody) ByteArray %{
+  private long swigCPtr; // Minor bodge to work around private variable in parent
+  private boolean swigCMemOwn;
+  public $javaclassname(long cPtr, boolean cMemoryOwn) {
+    super(cPtr, cMemoryOwn);
+    this.swigCPtr = SWIGTYPE_p_void.getCPtr(this);
+    swigCMemOwn = cMemoryOwn;
+  }
+%}
+
+%array_class(jbyte, ByteArray);
+
+%apply char **STRING_ARRAY { char ** }
Index: lldb/bindings/java/CMakeLists.txt
===================================================================
--- /dev/null
+++ lldb/bindings/java/CMakeLists.txt
@@ -0,0 +1,23 @@
+/* ###
+ * IP: Apache License 2.0 with LLVM Exceptions
+ */
+add_custom_command(
+  OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/LLDBWrapJava.cpp
+  DEPENDS ${SWIG_SOURCES}
+  DEPENDS ${SWIG_INTERFACES}
+  DEPENDS ${SWIG_HEADERS}
+  COMMAND ${SWIG_EXECUTABLE}
+      ${SWIG_COMMON_FLAGS}
+      -I${CMAKE_CURRENT_SOURCE_DIR}
+      -java
+      -package SWIG
+      -c++
+      -outdir ${CMAKE_CURRENT_BINARY_DIR}
+      -o ${CMAKE_CURRENT_BINARY_DIR}/LLDBWrapJava.cpp
+      ${CMAKE_CURRENT_SOURCE_DIR}/java.swig
+  VERBATIM
+  COMMENT "Building LLDB Java wrapper")
+
+add_custom_target(swig_wrapper_java ALL DEPENDS
+  ${CMAKE_CURRENT_BINARY_DIR}/LLDBWrapJava.cpp
+)
Index: lldb/bindings/CMakeLists.txt
===================================================================
--- lldb/bindings/CMakeLists.txt
+++ lldb/bindings/CMakeLists.txt
@@ -38,3 +38,8 @@
 if (LLDB_ENABLE_LUA)
   add_subdirectory(lua)
 endif()
+
+if (LLDB_ENABLE_JAVA)
+  add_subdirectory(java)
+endif()
+
Index: lldb/CMakeLists.txt
===================================================================
--- lldb/CMakeLists.txt
+++ lldb/CMakeLists.txt
@@ -51,7 +51,7 @@
     CACHE STRING "Path where Python modules are installed, relative to install prefix")
 endif ()
 
-if (LLDB_ENABLE_PYTHON OR LLDB_ENABLE_LUA)
+if (LLDB_ENABLE_PYTHON OR LLDB_ENABLE_LUA OR LLDB_ENABLE_JAVA)
   add_subdirectory(bindings)
 endif ()
 
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to