[llvm-branch-commits] [lldb] 567fc97 - Revert "[lldb][RPC] Upstream lldb-rpc-gen tool (#138031)"
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Thu Jul 3 15:52:38 PDT 2025
Author: Chelsea Cassanova
Date: 2025-07-03T15:52:35-07:00
New Revision: 567fc97be4881ce3656e45c0b2cc7e85e08dde3d
URL: https://github.com/llvm/llvm-project/commit/567fc97be4881ce3656e45c0b2cc7e85e08dde3d
DIFF: https://github.com/llvm/llvm-project/commit/567fc97be4881ce3656e45c0b2cc7e85e08dde3d.diff
LOG: Revert "[lldb][RPC] Upstream lldb-rpc-gen tool (#138031)"
This reverts commit 9bfb347ea0a0a260eb505921dfc0cb824a6ced5d.
Added:
Modified:
lldb/cmake/modules/LLDBConfig.cmake
lldb/test/CMakeLists.txt
lldb/test/Shell/helper/toolchain.py
lldb/test/Shell/lit.site.cfg.py.in
lldb/tools/CMakeLists.txt
Removed:
lldb/test/Shell/RPC/Generator/Inputs/SBDummy.h
lldb/test/Shell/RPC/Generator/Tests/CheckRPCGenToolByproducts.test
lldb/test/Shell/RPC/Generator/lit.local.cfg
lldb/tools/lldb-rpc/CMakeLists.txt
lldb/tools/lldb-rpc/LLDBRPCGeneration.cmake
lldb/tools/lldb-rpc/LLDBRPCHeaders.cmake
lldb/tools/lldb-rpc/lldb-rpc-gen/CMakeLists.txt
lldb/tools/lldb-rpc/lldb-rpc-gen/RPCCommon.cpp
lldb/tools/lldb-rpc/lldb-rpc-gen/RPCCommon.h
lldb/tools/lldb-rpc/lldb-rpc-gen/lldb-rpc-gen.cpp
################################################################################
diff --git a/lldb/cmake/modules/LLDBConfig.cmake b/lldb/cmake/modules/LLDBConfig.cmake
index f674c29682160..8c30b6e09d2c7 100644
--- a/lldb/cmake/modules/LLDBConfig.cmake
+++ b/lldb/cmake/modules/LLDBConfig.cmake
@@ -323,6 +323,4 @@ else()
set(LLDB_CAN_USE_DEBUGSERVER OFF)
endif()
-set(LLDB_BUILD_LLDBRPC ON CACHE BOOL "")
-
include(LLDBGenerateConfig)
diff --git a/lldb/test/CMakeLists.txt b/lldb/test/CMakeLists.txt
index 7cf239c7f95ab..6449ac5a9247f 100644
--- a/lldb/test/CMakeLists.txt
+++ b/lldb/test/CMakeLists.txt
@@ -132,10 +132,6 @@ if(TARGET lldb-framework)
add_lldb_test_dependency(lldb-framework)
endif()
-if (LLDB_BUILD_LLDBRPC)
- add_lldb_test_dependency(lldb-rpc-generate-sources)
-endif()
-
# Add dependencies that are not exported targets when building standalone.
if(NOT LLDB_BUILT_STANDALONE)
add_lldb_test_dependency(
@@ -253,8 +249,7 @@ llvm_canonicalize_cmake_booleans(
LLDB_TEST_SHELL_DISABLE_REMOTE
LLDB_TOOL_LLDB_SERVER_BUILD
LLDB_USE_SYSTEM_DEBUGSERVER
- LLDB_IS_64_BITS
- LLDB_BUILD_LLDBRPC)
+ LLDB_IS_64_BITS)
# Configure the individual test suites.
add_subdirectory(API)
diff --git a/lldb/test/Shell/RPC/Generator/Inputs/SBDummy.h b/lldb/test/Shell/RPC/Generator/Inputs/SBDummy.h
deleted file mode 100644
index e69de29bb2d1d..0000000000000
diff --git a/lldb/test/Shell/RPC/Generator/Tests/CheckRPCGenToolByproducts.test b/lldb/test/Shell/RPC/Generator/Tests/CheckRPCGenToolByproducts.test
deleted file mode 100644
index 15fcf8fb39c7d..0000000000000
--- a/lldb/test/Shell/RPC/Generator/Tests/CheckRPCGenToolByproducts.test
+++ /dev/null
@@ -1,9 +0,0 @@
-RUN: %lldb-rpc-gen --output-dir=%t %S/../Inputs/SBDummy.h
-
-RUN: ls %t | FileCheck %s
-
-# We're just making sure that the tool emits the class names,
-# methods and skipped methods file in the output directory.
-CHECK: SBAPI.def
-CHECK: SBClasses.def
-CHECK: SkippedMethods.txt
diff --git a/lldb/test/Shell/RPC/Generator/lit.local.cfg b/lldb/test/Shell/RPC/Generator/lit.local.cfg
deleted file mode 100644
index db9494781c00c..0000000000000
--- a/lldb/test/Shell/RPC/Generator/lit.local.cfg
+++ /dev/null
@@ -1,3 +0,0 @@
-# All tests for the tool need lldb-rpc-gen to be built.
-if not config.lldb_has_lldbrpc:
- config.unsupported = True
diff --git a/lldb/test/Shell/helper/toolchain.py b/lldb/test/Shell/helper/toolchain.py
index 728f6347242f1..42968128f2702 100644
--- a/lldb/test/Shell/helper/toolchain.py
+++ b/lldb/test/Shell/helper/toolchain.py
@@ -156,16 +156,6 @@ def use_lldb_substitutions(config):
extra_args=["platform"],
unresolved="ignore",
),
- ToolSubst(
- "%lldb-rpc-gen",
- command=FindTool("lldb-rpc-gen"),
- # We need the LLDB build directory root to pass into the tool, not the test build root.
- extra_args=[
- "-p " + config.lldb_build_directory + "/..",
- '--extra-arg="-resource-dir=' + config.clang_resource_dir + '"',
- ],
- unresolved="ignore",
- ),
"lldb-test",
"lldb-dap",
ToolSubst(
diff --git a/lldb/test/Shell/lit.site.cfg.py.in b/lldb/test/Shell/lit.site.cfg.py.in
index beaa41e6fd379..5be5359217769 100644
--- a/lldb/test/Shell/lit.site.cfg.py.in
+++ b/lldb/test/Shell/lit.site.cfg.py.in
@@ -33,7 +33,6 @@ config.lldb_build_directory = "@LLDB_TEST_BUILD_DIRECTORY@"
config.have_lldb_server = @LLDB_TOOL_LLDB_SERVER_BUILD@
config.lldb_system_debugserver = @LLDB_USE_SYSTEM_DEBUGSERVER@
config.llvm_use_sanitizer = "@LLVM_USE_SANITIZER@"
-config.lldb_has_lldbrpc = @LLDB_BUILD_LLDBRPC@
# The shell tests use their own module caches.
config.lldb_module_cache = os.path.join("@LLDB_TEST_MODULE_CACHE_LLDB@", "lldb-shell")
config.clang_module_cache = os.path.join("@LLDB_TEST_MODULE_CACHE_CLANG@", "lldb-shell")
diff --git a/lldb/tools/CMakeLists.txt b/lldb/tools/CMakeLists.txt
index 73ffbbbee3056..6804dc234555b 100644
--- a/lldb/tools/CMakeLists.txt
+++ b/lldb/tools/CMakeLists.txt
@@ -10,9 +10,6 @@ add_subdirectory(lldb-fuzzer EXCLUDE_FROM_ALL)
add_lldb_tool_subdirectory(lldb-instr)
add_lldb_tool_subdirectory(lldb-dap)
-if (LLDB_BUILD_LLDBRPC)
- add_lldb_tool_subdirectory(lldb-rpc)
-endif()
if (CMAKE_SYSTEM_NAME MATCHES "Darwin")
add_lldb_tool_subdirectory(darwin-debug)
diff --git a/lldb/tools/lldb-rpc/CMakeLists.txt b/lldb/tools/lldb-rpc/CMakeLists.txt
deleted file mode 100644
index fdd6cf9163e96..0000000000000
--- a/lldb/tools/lldb-rpc/CMakeLists.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-include(CheckCXXCompilerFlag)
-# Umbrella target for the entire framework is a default target.
-add_custom_target(lldb-rpc ALL)
-
-if(LLDB_CODESIGN_IDENTITY)
- # Use explicit LLDB identity
- set(LLVM_CODESIGNING_IDENTITY ${LLDB_CODESIGN_IDENTITY})
-else()
- # Use explicit LLVM identity or default to ad-hoc signing if empty
- if(NOT LLVM_CODESIGNING_IDENTITY)
- set(LLVM_CODESIGNING_IDENTITY -)
- endif()
-endif()
-
-# LLDBRPCGeneration.cmake needs the LLDB_RPC_GEN_EXE variable
-# which gets defined in the lldb-rpc-gen folder, so we're adding
-# this folder before we add that file.
-add_lldb_tool_subdirectory(lldb-rpc-gen)
-include(${CMAKE_CURRENT_SOURCE_DIR}/LLDBRPCGeneration.cmake)
-include(${CMAKE_CURRENT_SOURCE_DIR}/LLDBRPCHeaders.cmake)
-
-add_dependencies(lldb-rpc lldb-rpc-generate-sources liblldbrpc-headers)
diff --git a/lldb/tools/lldb-rpc/LLDBRPCGeneration.cmake b/lldb/tools/lldb-rpc/LLDBRPCGeneration.cmake
deleted file mode 100644
index e093f150701b3..0000000000000
--- a/lldb/tools/lldb-rpc/LLDBRPCGeneration.cmake
+++ /dev/null
@@ -1,60 +0,0 @@
-if (NOT DEFINED LLDB_RPC_GEN_EXE)
- message(FATAL_ERROR
- "Unable to generate lldb-rpc sources because LLDB_RPC_GEN_EXE is not
- defined. If you are cross-compiling, please build lldb-rpc-gen for your host
- platform.")
-endif()
-set(lldb_rpc_generated_dir "${CMAKE_CURRENT_BINARY_DIR}/generated")
-
-file(GLOB api_headers ${LLDB_SOURCE_DIR}/include/lldb/API/SB*.h)
-# We don't generate SBCommunication
-list(REMOVE_ITEM api_headers ${LLDB_SOURCE_DIR}/include/lldb/API/SBCommunication.h)
-# SBDefines.h is mostly definitions and forward declarations, nothing to
-# generate.
-list(REMOVE_ITEM api_headers ${LLDB_SOURCE_DIR}/include/lldb/API/SBDefines.h)
-
-# Generate the list of byproducts. Note that we cannot just glob the files in
-# the directory with the generated sources because BYPRODUCTS needs to be known
-# at configure time but the files are generated at build time.
-set(lldb_rpc_gen_byproducts
- ${lldb_rpc_generated_dir}/SBClasses.def
- ${lldb_rpc_generated_dir}/SBAPI.def
- ${lldb_rpc_generated_dir}/lldb.py
- ${lldb_rpc_server_generated_source_dir}/SBAPI.h
-)
-
-# Make sure that the clang-resource-dir is set correctly or else the tool will
-# fail to run. This is only needed when we do a standalone build.
-set(clang_resource_dir_arg)
-if (LLDB_BUILT_STANDALONE)
- if (TARGET clang-resource-headers)
- set(clang_resource_headers_dir
- $<TARGET_PROPERTY:clang-resource-headers,INTERFACE_INCLUDE_DIRECTORIES>)
- set(clang_resource_dir_arg --extra-arg="-resource-dir=${clang_resource_headers_dir}/..")
- else()
- set(clang_resource_dir_arg --extra-arg="-resource-dir=${LLDB_EXTERNAL_CLANG_RESOURCE_DIR}")
- endif()
-endif()
-
-add_custom_command(OUTPUT ${lldb_rpc_gen_byproducts}
- COMMAND ${CMAKE_COMMAND} -E make_directory
- ${lldb_rpc_generated_dir}
-
- COMMAND ${LLDB_RPC_GEN_EXE}
- -p ${CMAKE_BINARY_DIR}
- --output-dir=${lldb_rpc_generated_dir}
- ${clang_resource_dir_arg}
- --extra-arg="-USWIG"
- ${api_headers}
-
- DEPENDS ${LLDB_RPC_GEN_EXE} ${api_headers}
- COMMENT "Generating sources for lldb-rpc-server..."
- WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
-)
-
-add_custom_target(lldb-rpc-generate-sources
- DEPENDS
- ${lldb_rpc_gen_byproducts}
- lldb-sbapi-dwarf-enums)
-
-add_dependencies(lldb-rpc-generate-sources clang-resource-headers)
diff --git a/lldb/tools/lldb-rpc/LLDBRPCHeaders.cmake b/lldb/tools/lldb-rpc/LLDBRPCHeaders.cmake
deleted file mode 100644
index 97ad481140248..0000000000000
--- a/lldb/tools/lldb-rpc/LLDBRPCHeaders.cmake
+++ /dev/null
@@ -1,101 +0,0 @@
-set(derived_headers_location "${CMAKE_CURRENT_BINARY_DIR}/DerivedHeaders")
-
-# Obtain the original headers from their staged location in the build directory.
-set(original_headers_location "${CMAKE_BINARY_DIR}/include/lldb")
-set(headers_to_process
- SBDefines.h
- lldb-defines.h
- lldb-enumerations.h
- lldb-types.h
-)
-
-file(MAKE_DIRECTORY ${derived_headers_location})
-
-# Take the original headers and convert them RPC as necessary using the conversion script.
-set(original_headers)
-set(derived_headers)
-foreach(header ${headers_to_process})
- set(original_header "${original_headers_location}/${header}")
-
- get_filename_component(header_filename ${header} NAME)
- string(REPLACE "lldb-" "lldb-rpc-" rpc_header_filename "${header_filename}")
- set(derived_header "${derived_headers_location}/${rpc_header_filename}")
-
- list(APPEND original_headers "${original_header}")
- list(APPEND derived_headers "${derived_header}")
- add_custom_command(OUTPUT ${derived_header}
- COMMAND ${Python3_EXECUTABLE} ${LLDB_SOURCE_DIR}/scripts/convert-lldb-header-to-rpc-header.py
- ${original_header} ${derived_header}
- DEPENDS ${original_header}
-
- COMMENT "Creating ${derived_header}"
- )
-endforeach()
-
-# Do the same thing for any header files that were autogenerated.
-set(generated_headers_to_process
- API/SBLanguages.h
-)
-foreach(header ${generated_headers_to_process})
- set(original_header "${LLDB_OBJ_DIR}/include/lldb/${header}")
-
- get_filename_component(header_filename ${header} NAME)
- string(REPLACE "lldb-" "lldb-rpc-" rpc_header_filename "${header_filename}")
- set(derived_header "${derived_headers_location}/${rpc_header_filename}")
-
- list(APPEND original_headers "${original_header}")
- list(APPEND derived_headers "${derived_header}")
- add_custom_command(OUTPUT ${derived_header}
- COMMAND ${CMAKE_COMMAND} -E copy ${original_header} ${derived_header}
- COMMAND ${Python3_EXECUTABLE} ${LLDB_SOURCE_DIR}/scripts/convert-lldb-header-to-rpc-header.py
- ${original_header} ${derived_header}
- DEPENDS lldb-sbapi-dwarf-enums
-
- COMMENT "Creating ${derived_header}"
- )
-endforeach()
-
-add_custom_target(copy-aux-rpc-headers DEPENDS ${derived_headers})
-add_dependencies(copy-aux-rpc-headers liblldb-header-staging)
-
-list(APPEND public_headers
- ${derived_headers_location}/SBDefines.h
- ${derived_headers_location}/SBLanguages.h
- ${derived_headers_location}/lldb-rpc-enumerations.h
- ${derived_headers_location}/lldb-rpc-types.h
- ${derived_headers_location}/lldb-rpc-defines.h
-)
-
-# Collect and preprocess headers for the framework bundle
-set(version_header
- ${derived_headers_location}/lldb-rpc-defines.h
-)
-
-function(FixIncludePaths in subfolder out)
- get_filename_component(base_name ${in} NAME)
- set(parked_header ${CMAKE_CURRENT_BINARY_DIR}/ParkedHeaders/${subfolder}/${base_name})
- set(${out} ${parked_header} PARENT_SCOPE)
- find_program(unifdef_EXECUTABLE unifdef)
-
- add_custom_command(OUTPUT ${parked_header}
- COMMAND ${LLDB_SOURCE_DIR}/scripts/framework-header-fix.py
- -f lldb_rpc -i ${in} -o ${parked_header} -p ${unifdef_EXECUTABLE} USWIG
- DEPENDS ${in}
- COMMENT "Fixing includes in ${in}"
- )
-endfunction()
-
-set(preprocessed_headers)
-
-# Apply include-paths fix and any version fix on all headers and park them.
-foreach(source_header ${public_headers})
- FixIncludePaths(${source_header} Headers parked_header)
- list(APPEND preprocessed_headers ${parked_header})
-endforeach()
-
-# Wrap header preprocessing in a target, so liblldbrpc can depend on.
-add_custom_target(liblldbrpc-headers DEPENDS ${preprocessed_headers})
-add_dependencies(liblldbrpc-headers copy-aux-rpc-headers liblldb-header-staging)
-set_target_properties(liblldbrpc-headers PROPERTIES
- LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/ParkedHeaders
-)
diff --git a/lldb/tools/lldb-rpc/lldb-rpc-gen/CMakeLists.txt b/lldb/tools/lldb-rpc/lldb-rpc-gen/CMakeLists.txt
deleted file mode 100644
index 0a7d80519c564..0000000000000
--- a/lldb/tools/lldb-rpc/lldb-rpc-gen/CMakeLists.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-add_lldb_tool(lldb-rpc-gen
- RPCCommon.cpp
- lldb-rpc-gen.cpp
-
- CLANG_LIBS
- clangAST
- clangBasic
- clangCodeGen
- clangFrontend
- clangLex
- clangRewrite
- clangSerialization
- clangTooling
-
- LINK_COMPONENTS
- Support
- )
-
-if (NOT DEFINED LLDB_RPC_GEN_EXE)
- set(LLDB_RPC_GEN_EXE $<TARGET_FILE:lldb-rpc-gen> CACHE STRING "Executable that generates lldb-rpc-server")
-endif()
diff --git a/lldb/tools/lldb-rpc/lldb-rpc-gen/RPCCommon.cpp b/lldb/tools/lldb-rpc/lldb-rpc-gen/RPCCommon.cpp
deleted file mode 100644
index 37831a0cf195c..0000000000000
--- a/lldb/tools/lldb-rpc/lldb-rpc-gen/RPCCommon.cpp
+++ /dev/null
@@ -1,501 +0,0 @@
-//===-- RPCCommon.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 "RPCCommon.h"
-
-#include "clang/AST/AST.h"
-#include "clang/AST/Attr.h"
-#include "clang/AST/DeclBase.h"
-#include "clang/AST/Mangle.h"
-#include "clang/Lex/Lexer.h"
-
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/StringExtras.h"
-#include "llvm/ADT/StringMap.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/raw_ostream.h"
-
-#include <cstring>
-
-using namespace clang;
-
-// We intentionally do not generate some classes because they are currently
-// inconvenient, they aren't really used by most consumers, or we're not sure
-// why they exist.
-static constexpr llvm::StringRef DisallowedClasses[] = {
- "SBCommunication", // This class is pretty much unused by consumers, so we
- // skip it.
- "SBInputReader", // This class is pretty much unused by consumers, so we
- // skip it.
- "SBCommandPluginInterface", // This class uses virtual functions, and the SB
- // API should not have those, so we skip this
- // class.
- "SBCommand", // There's nothing too
diff icult about this one, but many of
- // its methods take a SBCommandPluginInterface pointer so
- // there's no reason to support this.
-};
-
-// NOTE: In lldb-rpc-gen, we use mangled names when we need to work with
-// functions. We do this because we support many functions that have overloads,
-// and mangled names have no ambiguity which makes it easier to keep track of.
-// This is also possible since the LLDB SB API is stable.
-
-// We intentionally avoid generating certain methods either because they are
-//
diff icult to support correctly or they aren't really used much from C++.
-// NOTE: These methods are marked as deprecated using LLDB_DEPRECATED.
-// Normally this macro defines to the deprecated annotation, but this
-// functionality is removed in SBDefines.h when generating SWIG bindings which
-// we use for testing. Because of this, there is no annotation for the tool to
-// pick up on so this list will be used while we have this restriction in
-// SBDefines.h.
-static constexpr llvm::StringRef DisallowedMethods[] = {
- // The threading functionality in SBHostOS is deprecated and thus we do not
- // generate them. It would be ideal to add the annotations to the methods
- // and then support not generating deprecated methods. However, without
- // annotations the generator generates most things correctly. This one is
- // problematic because it returns a pointer to an "opaque" structure
- // (thread_t) that is not `void *`, so special casing it is more effort than
- // it's worth.
- "_ZN4lldb8SBHostOS10ThreadJoinEP17_opaque_pthread_tPPvPNS_7SBErrorE",
- "_ZN4lldb8SBHostOS12ThreadCancelEP17_opaque_pthread_tPNS_7SBErrorE",
- "_ZN4lldb8SBHostOS12ThreadCreateEPKcPFPvS3_ES3_PNS_7SBErrorE",
- "_ZN4lldb8SBHostOS12ThreadDetachEP17_opaque_pthread_tPNS_7SBErrorE",
- "_ZN4lldb8SBHostOS13ThreadCreatedEPKc",
-};
-
-static constexpr llvm::StringRef ClassesWithoutDefaultCtor[] = {
- "SBHostOS",
- "SBReproducer",
-};
-
-static constexpr llvm::StringRef ClassesWithoutCopyOperations[] = {
- "SBHostOS",
- "SBReproducer",
- "SBStream",
- "SBProgress",
-};
-
-static constexpr llvm::StringRef MethodsWithPointerPlusLen[] = {
- "_ZN4lldb6SBData11ReadRawDataERNS_7SBErrorEyPvm",
- "_ZN4lldb6SBData7SetDataERNS_7SBErrorEPKvmNS_9ByteOrderEh",
- "_ZN4lldb6SBData20SetDataWithOwnershipERNS_7SBErrorEPKvmNS_9ByteOrderEh",
- "_ZN4lldb6SBData25CreateDataFromUInt64ArrayENS_9ByteOrderEjPym",
- "_ZN4lldb6SBData25CreateDataFromUInt32ArrayENS_9ByteOrderEjPjm",
- "_ZN4lldb6SBData25CreateDataFromSInt64ArrayENS_9ByteOrderEjPxm",
- "_ZN4lldb6SBData25CreateDataFromSInt32ArrayENS_9ByteOrderEjPim",
- "_ZN4lldb6SBData25CreateDataFromDoubleArrayENS_9ByteOrderEjPdm",
- "_ZN4lldb6SBData22SetDataFromUInt64ArrayEPym",
- "_ZN4lldb6SBData22SetDataFromUInt32ArrayEPjm",
- "_ZN4lldb6SBData22SetDataFromSInt64ArrayEPxm",
- "_ZN4lldb6SBData22SetDataFromSInt32ArrayEPim",
- "_ZN4lldb6SBData22SetDataFromDoubleArrayEPdm",
- "_ZN4lldb10SBDebugger22GetDefaultArchitectureEPcm",
- "_ZN4lldb10SBDebugger13DispatchInputEPvPKvm",
- "_ZN4lldb10SBDebugger13DispatchInputEPKvm",
- "_ZN4lldb6SBFile4ReadEPhmPm",
- "_ZN4lldb6SBFile5WriteEPKhmPm",
- "_ZNK4lldb10SBFileSpec7GetPathEPcm",
- "_ZN4lldb10SBFileSpec11ResolvePathEPKcPcm",
- "_ZN4lldb8SBModule10GetVersionEPjj",
- "_ZN4lldb12SBModuleSpec12SetUUIDBytesEPKhm",
- "_ZNK4lldb9SBProcess9GetSTDOUTEPcm",
- "_ZNK4lldb9SBProcess9GetSTDERREPcm",
- "_ZNK4lldb9SBProcess19GetAsyncProfileDataEPcm",
- "_ZN4lldb9SBProcess10ReadMemoryEyPvmRNS_7SBErrorE",
- "_ZN4lldb9SBProcess11WriteMemoryEyPKvmRNS_7SBErrorE",
- "_ZN4lldb9SBProcess21ReadCStringFromMemoryEyPvmRNS_7SBErrorE",
- "_ZNK4lldb16SBStructuredData14GetStringValueEPcm",
- "_ZN4lldb8SBTarget23BreakpointCreateByNamesEPPKcjjRKNS_"
- "14SBFileSpecListES6_",
- "_ZN4lldb8SBTarget10ReadMemoryENS_9SBAddressEPvmRNS_7SBErrorE",
- "_ZN4lldb8SBTarget15GetInstructionsENS_9SBAddressEPKvm",
- "_ZN4lldb8SBTarget25GetInstructionsWithFlavorENS_9SBAddressEPKcPKvm",
- "_ZN4lldb8SBTarget15GetInstructionsEyPKvm",
- "_ZN4lldb8SBTarget25GetInstructionsWithFlavorEyPKcPKvm",
- "_ZN4lldb8SBThread18GetStopDescriptionEPcm",
- // The below mangled names are used for dummy methods in shell tests
- // that test the emitters' output. If you're adding any new mangled names
- // from the actual SB API to this list please add them above.
- "_ZN4lldb33SBRPC_"
- "CHECKCONSTCHARPTRPTRWITHLEN27CheckConstCharPtrPtrWithLenEPPKcm",
- "_ZN4lldb19SBRPC_CHECKARRAYPTR13CheckArrayPtrEPPKcm",
- "_ZN4lldb18SBRPC_CHECKVOIDPTR12CheckVoidPtrEPvm",
-};
-
-// These classes inherit from rpc::ObjectRef directly (as opposed to
-// rpc::LocalObjectRef). Changing them from ObjectRef to LocalObjectRef is ABI
-// breaking, so we preserve that compatibility here.
-//
-// lldb-rpc-gen emits classes as LocalObjectRefs by default.
-//
-// FIXME: Does it matter which one it emits by default?
-static constexpr llvm::StringRef ClassesThatInheritFromObjectRef[] = {
- "SBAddress",
- "SBBreakpointName",
- "SBCommandInterpreter",
- "SBCommandReturnObject",
- "SBError",
- "SBExecutionContext",
- "SBExpressionOptions",
- "SBFileSpec",
- "SBFileSpecList",
- "SBFormat",
- "SBFunction",
- "SBHistoricalFrame",
- "SBHistoricalLineEntry",
- "SBHistoricalLineEntryList",
- "SBLineEntry",
- "SBStream",
- "SBStringList",
- "SBStructuredData",
- "SBSymbolContext",
- "SBSymbolContextList",
- "SBTypeMember",
- "SBTypeSummaryOptions",
- "SBValueList",
-};
-
-QualType lldb_rpc_gen::GetUnderlyingType(QualType T) {
- QualType UnderlyingType;
- if (T->isPointerType())
- UnderlyingType = T->getPointeeType();
- else if (T->isReferenceType())
- UnderlyingType = T.getNonReferenceType();
- else
- UnderlyingType = T;
-
- return UnderlyingType;
-}
-
-QualType lldb_rpc_gen::GetUnqualifiedUnderlyingType(QualType T) {
- return GetUnderlyingType(T).getUnqualifiedType();
-}
-
-std::string lldb_rpc_gen::GetMangledName(ASTContext &Context,
- CXXMethodDecl *MDecl) {
- std::string Mangled;
- llvm::raw_string_ostream MangledStream(Mangled);
-
- GlobalDecl GDecl;
- if (const auto *CtorDecl = dyn_cast<CXXConstructorDecl>(MDecl))
- GDecl = GlobalDecl(CtorDecl, Ctor_Complete);
- else if (const auto *DtorDecl = dyn_cast<CXXDestructorDecl>(MDecl))
- GDecl = GlobalDecl(DtorDecl, Dtor_Deleting);
- else
- GDecl = GlobalDecl(MDecl);
-
- MangleContext *MC = Context.createMangleContext();
- MC->mangleName(GDecl, MangledStream);
- return Mangled;
-}
-
-static auto CheckTypeForLLDBPrivate = [](const Type *Ty) {};
-bool lldb_rpc_gen::TypeIsFromLLDBPrivate(QualType T) {
- auto CheckTypeForLLDBPrivate = [](const Type *Ty) {
- if (!Ty)
- return false;
- const auto *CXXRDecl = Ty->getAsCXXRecordDecl();
- if (!CXXRDecl)
- return false;
- const auto *NSDecl =
- llvm::dyn_cast<NamespaceDecl>(CXXRDecl->getDeclContext());
- if (!NSDecl)
- return false;
- return NSDecl->getName() == "lldb_private";
- };
-
- // First, get the underlying type (remove qualifications and strip off any
- // pointers/references). Then we'll need to desugar this type. This will
- // remove things like typedefs, so instead of seeing "lldb::DebuggerSP" we'll
- // actually see something like "std::shared_ptr<lldb_private::Debugger>".
- QualType UnqualifiedUnderlyingType = GetUnqualifiedUnderlyingType(T);
- const Type *DesugaredType =
- UnqualifiedUnderlyingType->getUnqualifiedDesugaredType();
- assert(DesugaredType && "DesugaredType from a valid Type is nullptr!");
-
- // Check the type itself.
- if (CheckTypeForLLDBPrivate(DesugaredType))
- return true;
-
- // If that didn't work, it's possible that the type has a template argument
- // that is an lldb_private type.
- if (const auto *TemplateSDecl =
- llvm::dyn_cast_or_null<ClassTemplateSpecializationDecl>(
- DesugaredType->getAsCXXRecordDecl())) {
- for (const TemplateArgument &TA :
- TemplateSDecl->getTemplateArgs().asArray()) {
- if (TA.getKind() != TemplateArgument::Type)
- continue;
- if (CheckTypeForLLDBPrivate(TA.getAsType().getTypePtr()))
- return true;
- }
- }
- return false;
-}
-
-bool lldb_rpc_gen::TypeIsSBClass(QualType T) {
- QualType UnqualifiedUnderlyingType = GetUnqualifiedUnderlyingType(T);
- const auto *CXXRDecl = UnqualifiedUnderlyingType->getAsCXXRecordDecl();
- if (!CXXRDecl)
- return false; // SB Classes are always C++ classes
-
- return CXXRDecl->getName().starts_with("SB");
-}
-
-bool lldb_rpc_gen::TypeIsConstCharPtr(QualType T) {
- if (!T->isPointerType())
- return false;
-
- QualType UnderlyingType = T->getPointeeType();
- if (!UnderlyingType.isConstQualified())
- return false;
-
- // NOTE: We should be able to do `UnderlyingType->isCharType` but that will
- // return true for `const uint8_t *` since that is effectively an unsigned
- // char pointer. We currently do not support pointers other than `const char
- // *` and `const char **`.
- return UnderlyingType->isSpecificBuiltinType(BuiltinType::Char_S) ||
- UnderlyingType->isSpecificBuiltinType(BuiltinType::SChar);
-}
-
-bool lldb_rpc_gen::TypeIsConstCharPtrPtr(QualType T) {
- if (!T->isPointerType())
- return false;
-
- return TypeIsConstCharPtr(T->getPointeeType());
-}
-
-bool lldb_rpc_gen::TypeIsDisallowedClass(QualType T) {
- QualType UUT = GetUnqualifiedUnderlyingType(T);
- const auto *CXXRDecl = UUT->getAsCXXRecordDecl();
- if (!CXXRDecl)
- return false;
-
- llvm::StringRef DeclName = CXXRDecl->getName();
- for (const llvm::StringRef DisallowedClass : DisallowedClasses)
- if (DeclName == DisallowedClass)
- return true;
- return false;
-}
-
-bool lldb_rpc_gen::TypeIsCallbackFunctionPointer(QualType T) {
- return T->isFunctionPointerType();
-}
-
-bool lldb_rpc_gen::MethodIsDisallowed(ASTContext &Context,
- CXXMethodDecl *MDecl) {
- bool isDisallowed = false;
- std::string MangledName = lldb_rpc_gen::GetMangledName(Context, MDecl);
- if (llvm::is_contained(DisallowedMethods, MangledName))
- isDisallowed = true;
-
- if (MDecl->hasAttrs()) {
- for (auto *attr : MDecl->getAttrs()) {
- if (strcmp(attr->getAttrName()->getNameStart(), "deprecated") == 0)
- isDisallowed = true;
- }
- }
- return isDisallowed;
-}
-
-bool lldb_rpc_gen::HasCallbackParameter(CXXMethodDecl *MDecl) {
- bool HasCallbackParameter = false;
- bool HasBatonParameter = false;
- auto End = MDecl->parameters().end();
- for (auto Iter = MDecl->parameters().begin(); Iter != End; Iter++) {
- if ((*Iter)->getType()->isFunctionPointerType())
- HasCallbackParameter = true;
- else if ((*Iter)->getType()->isVoidPointerType())
- HasBatonParameter = true;
- }
-
- return HasCallbackParameter && HasBatonParameter;
-}
-
-// NOTE: There's possibly a more clever way to do this, but we're keeping
-// the string replacement way here. Here is why it is written this way:
-// By the time we have already created a `Method` object, we have extracted the
-// `QualifiedName` and the relevant QualTypes for parameters/return types, many
-// of which contains "lldb::" in them. To change it in a way that would be
-// friendly to liblldbrpc, we would need to have a way of replacing that
-// namespace at the time of creating a Method, and only for liblldbrpc methods.
-// IMO this would complicate Method more than what I'm doing here, and not
-// necessarily for any more benefit.
-// In clang-tools-extra, there is a ChangeNamespaces tool which tries to do
-// something similar to this. It also operates primarily on string replacement,
-// but uses more sophisticated clang tooling to do so.
-// For now, this will do what we need it to do.
-std::string
-lldb_rpc_gen::ReplaceLLDBNamespaceWithRPCNamespace(std::string Name) {
- const char *lldb_namespace = "lldb::";
- auto Pos = Name.find(lldb_namespace);
- while (Pos != std::string::npos) {
- constexpr size_t SizeOfLLDBNamespace = 6;
- Name.replace(Pos, SizeOfLLDBNamespace, "lldb_rpc::");
- Pos = Name.find(lldb_namespace);
- }
- return Name;
-}
-
-std::string lldb_rpc_gen::StripLLDBNamespace(std::string Name) {
- const char *lldb_namespace = "lldb::";
- auto Pos = Name.find(lldb_namespace);
- if (Pos != std::string::npos) {
- constexpr size_t SizeOfLLDBNamespace = 6;
- Name = Name.substr(Pos + SizeOfLLDBNamespace);
- }
- return Name;
-}
-
-bool lldb_rpc_gen::SBClassRequiresDefaultCtor(const std::string &ClassName) {
- return !llvm::is_contained(ClassesWithoutDefaultCtor, ClassName);
-}
-
-bool lldb_rpc_gen::SBClassRequiresCopyCtorAssign(const std::string &ClassName) {
- return !llvm::is_contained(ClassesWithoutCopyOperations, ClassName);
-}
-
-bool lldb_rpc_gen::SBClassInheritsFromObjectRef(const std::string &ClassName) {
- return llvm::is_contained(ClassesThatInheritFromObjectRef, ClassName);
-}
-
-std::string lldb_rpc_gen::GetSBClassNameFromType(QualType T) {
- assert(lldb_rpc_gen::TypeIsSBClass(T) &&
- "Cannot get SBClass name from non-SB class type!");
-
- QualType UnqualifiedUnderlyingType = GetUnqualifiedUnderlyingType(T);
- const auto *CXXRDecl = UnqualifiedUnderlyingType->getAsCXXRecordDecl();
- assert(CXXRDecl && "SB class was not CXXRecordDecl!");
- if (!CXXRDecl)
- return std::string();
-
- return CXXRDecl->getName().str();
-}
-lldb_rpc_gen::Method::Method(CXXMethodDecl *MDecl, const PrintingPolicy &Policy,
- ASTContext &Context)
- : Policy(Policy), Context(Context),
- QualifiedName(MDecl->getQualifiedNameAsString()),
- BaseName(MDecl->getNameAsString()),
- MangledName(lldb_rpc_gen::GetMangledName(Context, MDecl)),
- ReturnType(MDecl->getReturnType()), IsConst(MDecl->isConst()),
- IsInstance(MDecl->isInstance()), IsCtor(isa<CXXConstructorDecl>(MDecl)),
- IsCopyAssign(MDecl->isCopyAssignmentOperator()),
- IsMoveAssign(MDecl->isMoveAssignmentOperator()),
- IsDtor(isa<CXXDestructorDecl>(MDecl)),
- IsConversionMethod(isa<CXXConversionDecl>(MDecl)) {
- uint8_t UnnamedArgIdx = 0;
- bool PrevParamWasPointer = false;
- for (const auto *ParamDecl : MDecl->parameters()) {
- Param param;
- if (ParamDecl->hasDefaultArg())
- param.DefaultValueText =
- Lexer::getSourceText(
- CharSourceRange::getTokenRange(
- ParamDecl->getDefaultArg()->getSourceRange()),
- Context.getSourceManager(), Context.getLangOpts())
- .str();
-
- param.IsFollowedByLen = false;
- param.Name = ParamDecl->getNameAsString();
- // If the parameter has no name, we'll generate one
- if (param.Name.empty()) {
- param.Name = "arg" + std::to_string(UnnamedArgIdx);
- UnnamedArgIdx++;
- }
- param.Type = ParamDecl->getType();
-
- // FIXME: Instead of using this heuristic, the ideal thing would be to add
- // annotations to the SBAPI methods themselves. For now, we have a list of
- // methods that we know will need this.
- if (PrevParamWasPointer) {
- PrevParamWasPointer = false;
- const bool IsIntegerType = param.Type->isIntegerType() &&
- !param.Type->isBooleanType() &&
- !param.Type->isEnumeralType();
- if (IsIntegerType && llvm::is_contained(MethodsWithPointerPlusLen,
- llvm::StringRef(MangledName)))
- Params.back().IsFollowedByLen = true;
- }
-
- if (param.Type->isPointerType() &&
- !lldb_rpc_gen::TypeIsConstCharPtr(param.Type) &&
- !param.Type->isFunctionPointerType())
- PrevParamWasPointer = true;
-
- if (param.Type->isFunctionPointerType())
- ContainsFunctionPointerParameter = true;
-
- Params.push_back(param);
- }
-
- if (IsInstance)
- ThisType = MDecl->getThisType();
-
- if (const auto *CtorDecl = dyn_cast<CXXConstructorDecl>(MDecl)) {
- IsExplicitCtorOrConversionMethod = CtorDecl->isExplicit();
- IsCopyCtor = CtorDecl->isCopyConstructor();
- IsMoveCtor = CtorDecl->isMoveConstructor();
- } else if (const auto *ConversionDecl = dyn_cast<CXXConversionDecl>(MDecl))
- IsExplicitCtorOrConversionMethod = ConversionDecl->isExplicit();
-}
-
-// Adding a '<' allows us to use Methods in ordered containers.
-// The ordering is on memory addresses.
-bool lldb_rpc_gen::Method::operator<(const lldb_rpc_gen::Method &rhs) const {
- return this < &rhs;
-}
-
-std::string
-lldb_rpc_gen::Method::CreateParamListAsString(GenerationKind Generation,
- bool IncludeDefaultValue) const {
- assert((!IncludeDefaultValue || Generation == eLibrary) &&
- "Default values should only be emitted on the library side!");
-
- std::vector<std::string> ParamList;
-
- if (Generation == eLibrary && RequiresConnectionParameter())
- ParamList.push_back("const rpc::Connection &connection");
-
- for (const auto &Param : Params) {
- std::string ParamString;
- llvm::raw_string_ostream ParamStringStream(ParamString);
-
- if (Generation == eLibrary)
- ParamStringStream << lldb_rpc_gen::ReplaceLLDBNamespaceWithRPCNamespace(
- Param.Type.getAsString(Policy));
- else
- ParamStringStream << Param.Type.getAsString(Policy);
-
- ParamStringStream << " " << Param.Name;
- if (IncludeDefaultValue && Generation == eLibrary &&
- !Param.DefaultValueText.empty())
- ParamStringStream << " = "
- << lldb_rpc_gen::ReplaceLLDBNamespaceWithRPCNamespace(
- Param.DefaultValueText);
-
- ParamList.push_back(ParamString);
- }
-
- return llvm::join(ParamList, ", ");
-}
-
-bool lldb_rpc_gen::Method::RequiresConnectionParameter() const {
- if (!IsCtor && IsInstance)
- return false;
- if (IsCopyCtor || IsMoveCtor)
- return false;
- for (const auto &Param : Params)
- // We can re-use the connection from our parameter if possible.
- // Const-qualified parameters are input parameters and already
- // have a valid connection to provide to the current method.
- if (TypeIsSBClass(Param.Type) &&
- GetUnderlyingType(Param.Type).isConstQualified())
- return false;
-
- return true;
-}
diff --git a/lldb/tools/lldb-rpc/lldb-rpc-gen/RPCCommon.h b/lldb/tools/lldb-rpc/lldb-rpc-gen/RPCCommon.h
deleted file mode 100644
index edc03b4f81a3d..0000000000000
--- a/lldb/tools/lldb-rpc/lldb-rpc-gen/RPCCommon.h
+++ /dev/null
@@ -1,108 +0,0 @@
-//===-- RPCCommon.h -------------------------------------------------------===//
-//
-// 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_RPC_GEN_RPCCOMMON_H
-#define LLDB_RPC_GEN_RPCCOMMON_H
-
-#include "clang/AST/AST.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/DeclCXX.h"
-#include "llvm/Support/ToolOutputFile.h"
-#include "llvm/Support/raw_ostream.h"
-
-#include <string>
-
-using namespace clang;
-
-namespace lldb_rpc_gen {
-QualType GetUnderlyingType(QualType T);
-QualType GetUnqualifiedUnderlyingType(QualType T);
-std::string GetMangledName(ASTContext &Context, CXXMethodDecl *MDecl);
-
-bool TypeIsFromLLDBPrivate(QualType T);
-bool TypeIsSBClass(QualType T);
-bool TypeIsConstCharPtr(QualType T);
-bool TypeIsConstCharPtrPtr(QualType T);
-bool TypeIsDisallowedClass(QualType T);
-bool TypeIsCallbackFunctionPointer(QualType T);
-
-bool MethodIsDisallowed(ASTContext &Context, CXXMethodDecl *MDecl);
-bool HasCallbackParameter(CXXMethodDecl *MDecl);
-
-std::string ReplaceLLDBNamespaceWithRPCNamespace(std::string Name);
-std::string StripLLDBNamespace(std::string Name);
-bool SBClassRequiresDefaultCtor(const std::string &ClassName);
-bool SBClassRequiresCopyCtorAssign(const std::string &ClassName);
-bool SBClassInheritsFromObjectRef(const std::string &ClassName);
-std::string GetSBClassNameFromType(QualType T);
-struct Param {
- std::string Name;
- QualType Type;
- std::string DefaultValueText;
- bool IsFollowedByLen;
-};
-
-enum GenerationKind : bool { eServer, eLibrary };
-
-struct Method {
- enum Type { eOther, eConstructor, eDestructor };
-
- Method(CXXMethodDecl *MDecl, const PrintingPolicy &Policy,
- ASTContext &Context);
-
- // Adding a '<' allows us to use Methods in ordered containers.
- // The ordering is on memory addresses.
- bool operator<(const lldb_rpc_gen::Method &rhs) const;
- const PrintingPolicy &Policy;
- const ASTContext &Context;
- std::string QualifiedName;
- std::string BaseName;
- std::string MangledName;
- QualType ReturnType;
- QualType ThisType;
- std::vector<Param> Params;
- bool IsConst = false;
- bool IsInstance = false;
- bool IsCtor = false;
- bool IsCopyCtor = false;
- bool IsCopyAssign = false;
- bool IsMoveCtor = false;
- bool IsMoveAssign = false;
- bool IsDtor = false;
- bool IsConversionMethod = false;
- bool IsExplicitCtorOrConversionMethod = false;
- bool ContainsFunctionPointerParameter = false;
-
- std::string CreateParamListAsString(GenerationKind Generation,
- bool IncludeDefaultValue = false) const;
-
- bool RequiresConnectionParameter() const;
-};
-
-std::string
-GetDefaultArgumentsForConstructor(std::string ClassName,
- const lldb_rpc_gen::Method &method);
-
-class FileEmitter {
-protected:
- FileEmitter(std::unique_ptr<llvm::ToolOutputFile> &&OutputFile)
- : OutputFile(std::move(OutputFile)), IndentLevel(0) {}
- void EmitLine(const std::string &line) {
- for (auto i = 0; i < IndentLevel; i++)
- OutputFile->os() << " ";
-
- OutputFile->os() << line << "\n";
- }
-
- void EmitNewLine() { OutputFile->os() << "\n"; }
-
- std::unique_ptr<llvm::ToolOutputFile> OutputFile;
- uint8_t IndentLevel;
-};
-} // namespace lldb_rpc_gen
-#endif // LLDB_RPC_GEN_RPCCOMMON_H
diff --git a/lldb/tools/lldb-rpc/lldb-rpc-gen/lldb-rpc-gen.cpp b/lldb/tools/lldb-rpc/lldb-rpc-gen/lldb-rpc-gen.cpp
deleted file mode 100644
index dc26369e36ef1..0000000000000
--- a/lldb/tools/lldb-rpc/lldb-rpc-gen/lldb-rpc-gen.cpp
+++ /dev/null
@@ -1,346 +0,0 @@
-//===-- lldb-rpc-gen.cpp ----------------------------------------*- 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
-//
-//===----------------------------------------------------------------------===//
-
-#include "RPCCommon.h"
-
-#include "clang/AST/AST.h"
-#include "clang/AST/ASTConsumer.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/RecursiveASTVisitor.h"
-#include "clang/Basic/SourceManager.h"
-#include "clang/CodeGen/ObjectFilePCHContainerWriter.h"
-#include "clang/Frontend/CompilerInstance.h"
-#include "clang/Frontend/FrontendAction.h"
-#include "clang/Frontend/FrontendActions.h"
-#include "clang/Serialization/ObjectFilePCHContainerReader.h"
-#include "clang/Tooling/CommonOptionsParser.h"
-#include "clang/Tooling/Tooling.h"
-
-#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/Path.h"
-#include "llvm/Support/ToolOutputFile.h"
-#include "llvm/Support/raw_ostream.h"
-
-using namespace clang;
-using namespace clang::driver;
-using namespace clang::tooling;
-
-static llvm::cl::OptionCategory RPCGenCategory("Tool for generating LLDBRPC");
-
-static llvm::cl::opt<std::string>
- OutputDir("output-dir",
- llvm::cl::desc("Directory to output generated files to"),
- llvm::cl::init(""), llvm::cl::cat(RPCGenCategory));
-
-static std::unique_ptr<llvm::ToolOutputFile>
-CreateOutputFile(llvm::StringRef OutputDir, llvm::StringRef Filename) {
- llvm::SmallString<256> Path(OutputDir);
- llvm::sys::path::append(Path, Filename);
-
- std::error_code EC;
- auto OutputFile =
- std::make_unique<llvm::ToolOutputFile>(Path, EC, llvm::sys::fs::OF_None);
- if (EC) {
- llvm::errs() << "Failed to create output file: " << Path << "!\n";
- return nullptr;
- }
- return OutputFile;
-}
-
-struct GeneratedByproducts {
- std::set<std::string> ClassNames;
- std::set<std::string> MangledMethodNames;
- std::set<std::string> SkippedMethodNames;
-};
-
-enum SupportLevel {
- eUnsupported,
- eUnimplemented,
- eImplemented,
-};
-
-class SBVisitor : public RecursiveASTVisitor<SBVisitor> {
-public:
- SBVisitor(GeneratedByproducts &Byproducts, SourceManager &Manager,
- ASTContext &Context)
- : Byproducts(Byproducts), Manager(Manager), Context(Context) {}
-
- ~SBVisitor() {}
-
- bool VisitCXXRecordDecl(CXXRecordDecl *RDecl) {
- if (ShouldSkipRecord(RDecl))
- return true;
-
- const std::string ClassName = RDecl->getNameAsString();
- Byproducts.ClassNames.insert(ClassName);
-
- // Print 'bool' instead of '_Bool'.
- PrintingPolicy Policy(Context.getLangOpts());
- Policy.Bool = true;
-
- for (CXXMethodDecl *MDecl : RDecl->methods()) {
- const std::string MangledName =
- lldb_rpc_gen::GetMangledName(Context, MDecl);
- const bool IsDisallowed =
- lldb_rpc_gen::MethodIsDisallowed(Context, MDecl);
- SupportLevel MethodSupportLevel = GetMethodSupportLevel(MDecl);
- if (MethodSupportLevel == eImplemented && !IsDisallowed) {
- const lldb_rpc_gen::Method Method(MDecl, Policy, Context);
- Byproducts.MangledMethodNames.insert(MangledName);
- } else if (MethodSupportLevel == eUnimplemented)
- Byproducts.SkippedMethodNames.insert(MangledName);
- }
- return true;
- }
-
-private:
- /// Determines whether we should skip a RecordDecl.
- /// Conditions for skipping:
- /// - Anything not in the header itself
- /// - Certain inconvenient classes
- /// - Records without definitions (forward declarations)
- bool ShouldSkipRecord(CXXRecordDecl *Decl) {
- const Type *DeclType = Decl->getTypeForDecl();
- QualType CanonicalType = DeclType->getCanonicalTypeInternal();
- return !Manager.isInMainFile(Decl->getBeginLoc()) ||
- !Decl->hasDefinition() || Decl->getDefinition() != Decl ||
- lldb_rpc_gen::TypeIsDisallowedClass(CanonicalType);
- }
-
- /// Check the support level for a type
- /// Known unsupported types:
- /// - FILE * (We do not want to expose this primitive)
- /// - Types that are internal to LLDB
- SupportLevel GetTypeSupportLevel(QualType Type) {
- const std::string TypeName = Type.getAsString();
- if (TypeName == "FILE *" || lldb_rpc_gen::TypeIsFromLLDBPrivate(Type))
- return eUnsupported;
-
- if (lldb_rpc_gen::TypeIsDisallowedClass(Type))
- return eUnsupported;
-
- return eImplemented;
- }
-
- /// Determine the support level of a given method.
- /// Known unsupported methods:
- /// - Non-public methods (lldb-rpc is a client and can only see public
- /// things)
- /// - Copy assignment operators (the client side will handle this)
- /// - Move assignment operators (the client side will handle this)
- /// - Methods involving unsupported types.
- /// Known unimplemented methods:
- /// - No variadic functions, e.g. Printf
- SupportLevel GetMethodSupportLevel(CXXMethodDecl *MDecl) {
- AccessSpecifier AS = MDecl->getAccess();
- if (AS != AccessSpecifier::AS_public)
- return eUnsupported;
- if (MDecl->isCopyAssignmentOperator())
- return eUnsupported;
- if (MDecl->isMoveAssignmentOperator())
- return eUnsupported;
-
- if (MDecl->isVariadic())
- return eUnimplemented;
-
- SupportLevel ReturnTypeLevel = GetTypeSupportLevel(MDecl->getReturnType());
- if (ReturnTypeLevel != eImplemented)
- return ReturnTypeLevel;
-
- for (auto *ParamDecl : MDecl->parameters()) {
- SupportLevel ParamTypeLevel = GetTypeSupportLevel(ParamDecl->getType());
- if (ParamTypeLevel != eImplemented)
- return ParamTypeLevel;
- }
-
- // FIXME: If a callback does not take a `void *baton` parameter, it is
- // considered unsupported at this time. On the server-side, we hijack the
- // baton argument in order to pass additional information to the server-side
- // callback so we can correctly perform a reverse RPC call back to the
- // client. Without this baton, we would need the server-side callback to
- // have some side channel by which it obtained that information, and
- // spending time designing that doesn't outweight the cost of doing it at
- // the moment.
- bool HasCallbackParameter = false;
- bool HasBatonParameter = false;
- auto End = MDecl->parameters().end();
- for (auto Iter = MDecl->parameters().begin(); Iter != End; Iter++) {
- if ((*Iter)->getType()->isFunctionPointerType()) {
- HasCallbackParameter = true;
- continue;
- }
-
- // FIXME: We assume that if we have a function pointer and a void pointer
- // together in the same parameter list, that it is not followed by a
- // length argument. If that changes, we will need to revisit this
- // implementation.
- if ((*Iter)->getType()->isVoidPointerType())
- HasBatonParameter = true;
- }
-
- if (HasCallbackParameter && !HasBatonParameter)
- return eUnimplemented;
-
- return eImplemented;
- }
-
- GeneratedByproducts &Byproducts;
- SourceManager &Manager;
- ASTContext &Context;
-};
-
-class SBConsumer : public ASTConsumer {
-public:
- SBConsumer(GeneratedByproducts &Byproducts, SourceManager &Manager,
- ASTContext &Context)
- : Visitor(Byproducts, Manager, Context) {}
- bool HandleTopLevelDecl(DeclGroupRef DR) override {
- for (Decl *D : DR)
- Visitor.TraverseDecl(D);
-
- return true;
- }
-
-private:
- SBVisitor Visitor;
-};
-
-class SBAction : public ASTFrontendAction {
-public:
- SBAction(GeneratedByproducts &Byproducts) : Byproducts(Byproducts) {}
-
- std::unique_ptr<ASTConsumer>
- CreateASTConsumer(CompilerInstance &CI, llvm::StringRef File) override {
- llvm::StringRef FilenameNoExt =
- llvm::sys::path::stem(llvm::sys::path::filename(File));
-
- return std::make_unique<SBConsumer>(Byproducts, CI.getSourceManager(),
- CI.getASTContext());
- }
-
-private:
- GeneratedByproducts &Byproducts;
-};
-
-class SBActionFactory : public FrontendActionFactory {
-public:
- SBActionFactory(GeneratedByproducts &Byproducts) : Byproducts(Byproducts) {}
-
- std::unique_ptr<FrontendAction> create() override {
- return std::make_unique<SBAction>(Byproducts);
- }
-
-private:
- GeneratedByproducts &Byproducts;
-};
-
-bool EmitClassNamesFile(std::set<std::string> &ClassNames) {
- static constexpr llvm::StringLiteral ClassNamesFileName = "SBClasses.def";
- std::unique_ptr<llvm::ToolOutputFile> ClassNamesFile =
- CreateOutputFile(OutputDir.getValue(), ClassNamesFileName);
- if (!ClassNamesFile)
- return false;
-
- ClassNamesFile->os() << "#ifndef SBCLASS\n"
- << "#error \"SBClass must be defined\"\n"
- << "#endif\n";
-
- for (const auto &ClassName : ClassNames) {
- if (ClassName == "SBStream" || ClassName == "SBProgress")
- ClassNamesFile->os() << "#if !defined(SBCLASS_EXCLUDE_NONCOPYABLE)\n";
- else if (ClassName == "SBReproducer")
- ClassNamesFile->os() << "#if !defined(SBCLASS_EXCLUDE_STATICONLY)\n";
-
- ClassNamesFile->os() << "SBCLASS(" << ClassName << ")\n";
- if (ClassName == "SBStream" || ClassName == "SBReproducer" ||
- ClassName == "SBProgress")
- ClassNamesFile->os() << "#endif\n";
- }
- ClassNamesFile->keep();
- return true;
-}
-
-bool EmitMethodNamesFile(std::set<std::string> &MangledMethodNames) {
- static constexpr llvm::StringLiteral MethodNamesFileName = "SBAPI.def";
- std::unique_ptr<llvm::ToolOutputFile> MethodNamesFile =
- CreateOutputFile(OutputDir.getValue(), MethodNamesFileName);
- if (!MethodNamesFile)
- return false;
-
- MethodNamesFile->os() << "#ifndef GENERATE_SBAPI\n"
- << "#error \"GENERATE_SBAPI must be defined\"\n"
- << "#endif\n";
-
- for (const auto &MangledName : MangledMethodNames) {
- MethodNamesFile->os() << "GENERATE_SBAPI(" << MangledName << ")\n";
- }
- MethodNamesFile->keep();
- return true;
-}
-
-bool EmitSkippedMethodsFile(std::set<std::string> &SkippedMethodNames) {
- static constexpr llvm::StringLiteral FileName = "SkippedMethods.txt";
- std::unique_ptr<llvm::ToolOutputFile> File =
- CreateOutputFile(OutputDir.getValue(), FileName);
- if (!File)
- return false;
-
- for (const auto &Skipped : SkippedMethodNames)
- File->os() << Skipped << "\n";
- File->keep();
- return true;
-}
-
-int main(int argc, const char *argv[]) {
- auto ExpectedParser = CommonOptionsParser::create(
- argc, argv, RPCGenCategory, llvm::cl::OneOrMore,
- "Tool for generating LLDBRPC interfaces and implementations");
-
- if (!ExpectedParser) {
- llvm::errs() << ExpectedParser.takeError();
- return 1;
- }
-
- if (OutputDir.empty()) {
- llvm::errs() << "Please specify an output directory for the generated "
- "files with --output-dir!\n";
- return 1;
- }
-
- // Create the output directory if the user specified one does not exist.
- if (!llvm::sys::fs::exists(OutputDir.getValue())) {
- llvm::sys::fs::create_directory(OutputDir.getValue());
- }
-
- CommonOptionsParser &OP = ExpectedParser.get();
- auto PCHOpts = std::make_shared<PCHContainerOperations>();
- PCHOpts->registerWriter(std::make_unique<ObjectFilePCHContainerWriter>());
- PCHOpts->registerReader(std::make_unique<ObjectFilePCHContainerReader>());
-
- ClangTool T(OP.getCompilations(), OP.getSourcePathList(), PCHOpts);
-
- GeneratedByproducts Byproducts;
-
- SBActionFactory Factory(Byproducts);
- auto Result = T.run(&Factory);
- if (!EmitClassNamesFile(Byproducts.ClassNames)) {
- llvm::errs() << "Failed to create SB Class file\n";
- return 1;
- }
- if (!EmitMethodNamesFile(Byproducts.MangledMethodNames)) {
- llvm::errs() << "Failed to create Method Names file\n";
- return 1;
- }
- if (!EmitSkippedMethodsFile(Byproducts.SkippedMethodNames)) {
- llvm::errs() << "Failed to create Skipped Methods file\n";
- return 1;
- }
-
- return Result;
-}
More information about the llvm-branch-commits
mailing list