Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions interpreter/CppInterOp/.bazelrc
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,7 @@ test --test_output=errors
# The C++ toolchain (clang from the LLVM tree) and all ABI-critical flags are
# centralized in the cppyy_bazel module, which registers @llvm//:cc_toolchain.
# No per-repo compiler wiring needed.

# The dispatch tests dlopen <CPPINTEROP_BIN_DIR>/lib/libclangCppInterOp.so.
# In the standalone build the runfiles root (the test cwd) is that prefix.
test --test_env=CPPINTEROP_BIN_DIR=.
4 changes: 2 additions & 2 deletions interpreter/CppInterOp/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@
*.app

# Directories
build
install
build*
install*

# CLion files
.idea
Expand Down
37 changes: 23 additions & 14 deletions interpreter/CppInterOp/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,18 @@ cc_library(
includes = ["include"],
)

# Tests resolve repo files against CPPINTEROP_SRC_DIR / CPPINTEROP_BIN_DIR,
# which here is the runfiles root (the test's cwd). repo_rloc self-corrects
# between the standalone build (main repo -> ".") and use as an external dep
# (-> "../<canon>"). This BUILD is always @cppinterop, so is_main_repo() marks
# the self-reference.
_CPPINTEROP_RUNFILES_DIR = repo_rloc(
"@cppinterop",
is_main_repo(repository_name()),
)

_CPPINTEROP_SRC_DIR_COPT = "-DCPPINTEROP_SRC_DIR=\\\"" + _CPPINTEROP_RUNFILES_DIR + "\\\""

# CppInterOpTests: the main gtest suite. Source list = CMake's
# add_cppinterop_unittest(CppInterOpTests ...) plus the non-EMSCRIPTEN
# target_sources additions (CUDATest, VTableOverlayTest) plus main.cpp.
Expand All @@ -335,8 +347,13 @@ cppinterop_cc_test(
"unittests/CppInterOp/VariableReflectionTest.cpp",
"unittests/CppInterOp/main.cpp",
],
# The APINotes check builds an -I into the checkout, so ship that directory.
data = glob(["unittests/CppInterOp/APINotes/**"]),
# CMake sets -Wno-pedantic on VariableReflectionTest.cpp; applied suite-wide.
extra_copts = ["-Wno-pedantic"],
extra_copts = [
"-Wno-pedantic",
_CPPINTEROP_SRC_DIR_COPT,
],
extra_deps = [":CAPITestC"],
)

Expand All @@ -352,29 +369,20 @@ cppinterop_cc_test(
],
)

# TracingTests reads CppInterOp.h, the generated .inc, and lib/*.cpp at runtime,
# relative to CPPINTEROP_DIR / CPPINTEROP_BINARY_DIR (the repo's runfiles root,
# which is the test's cwd). repo_rloc self-corrects between the standalone build
# (cppinterop is the main repo -> ".") and being an external dep (-> "../<canon>").
# This BUILD is always @cppinterop, so is_main_repo() marks the self-reference.
# No test-source changes needed.
_CPPINTEROP_RUNFILES_DIR = repo_rloc(
"@cppinterop",
is_main_repo(repository_name()),
)

# TracingTests reads CppInterOp.h, the generated .inc, and lib/*.cpp at runtime.
cppinterop_cc_test(
name = "TracingTests",
srcs = [
"unittests/CppInterOp/TestPaths.h",
"unittests/CppInterOp/TracingTests.cpp",
"unittests/CppInterOp/Utils.cpp",
"unittests/CppInterOp/Utils.h",
"unittests/CppInterOp/main.cpp",
],
data = glob(["lib/CppInterOp/*.cpp"]),
extra_copts = [
"-DCPPINTEROP_DIR=\\\"" + _CPPINTEROP_RUNFILES_DIR + "\\\"",
"-DCPPINTEROP_BINARY_DIR=\\\"" + _CPPINTEROP_RUNFILES_DIR + "\\\"",
_CPPINTEROP_SRC_DIR_COPT,
"-DCPPINTEROP_BIN_DIR=\\\"" + _CPPINTEROP_RUNFILES_DIR + "\\\"",
],
)

Expand All @@ -385,6 +393,7 @@ cppinterop_dispatch_cc_test(
"unittests/CppInterOp/DispatchInit.cpp",
"unittests/CppInterOp/DispatchSmokeTest.cpp",
"unittests/CppInterOp/DispatchTest.cpp",
"unittests/CppInterOp/TestPaths.h",
"unittests/CppInterOp/main.cpp",
],
)
Expand Down
Empty file.
2 changes: 1 addition & 1 deletion interpreter/CppInterOp/cppinterop-version.tag
Original file line number Diff line number Diff line change
@@ -1 +1 @@
7cb23ca494cdaf3d5e6cc57318c4f561abcf1d84
261bebbf25c8f709d2e2490fe6e3f876f6ec5920
4 changes: 4 additions & 0 deletions interpreter/CppInterOp/include/CppInterOp/CXCppInterOp.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ CPPINTEROP_API intptr_t cppinterop_Evaluate(const char* code, bool* HadError);
CPPINTEROP_API CppInterOpArray
cppinterop_GetClassTemplatedMethods(const char* name, CppConstDeclRef parent);

/// C-ABI bridge for \c Cpp::LoadLibrary. The optional \c std::string*
/// reason argument is C++-only, so the generated wrapper is suppressed.
CPPINTEROP_API bool cppinterop_LoadLibrary(const char* lib_stem, bool lookup);

#ifdef __cplusplus
} // extern "C"
#pragma clang diagnostic pop
Expand Down
21 changes: 17 additions & 4 deletions interpreter/CppInterOp/include/CppInterOp/CppInterOpTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -411,11 +411,10 @@ enum class AllocType : unsigned char {
New,
NewArr,
Malloc,
Unknown,
CustomAlloc,
Null,
OperatorNew,
OperatorNewArr
OperatorNewArr,
Null,
Unknown
};

enum class DeallocType : unsigned char {
Expand All @@ -432,6 +431,20 @@ inline QualKind operator|(QualKind a, QualKind b) {
static_cast<unsigned char>(b));
}

enum class OwnershipBehaviour : unsigned char {
Unknown = 0, // If function does not have any ownership attribute, it is
// assumed to be Unknown, not None
OwnershipReturns = 1 << 0,
OwnershipHolds = 1 << 1,
OwnershipTakes = 1 << 2
};

inline OwnershipBehaviour operator|(OwnershipBehaviour A,
OwnershipBehaviour B) {
return static_cast<OwnershipBehaviour>(static_cast<unsigned char>(A) |
static_cast<unsigned char>(B));
}

enum class ValueKind : std::uint8_t {
None,
LValue,
Expand Down
47 changes: 36 additions & 11 deletions interpreter/CppInterOp/lib/CppInterOp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,17 @@ if (LLVM_LINK_LLVM_DYLIB)
)
set(new_libs ${link_libs})
set(libs ${new_libs})
# LLVM component libraries behind libLLVM.so that static clang archives
# reference without declaring them in their link interfaces (the dylib
# umbrella covered them). Substituted for the LLVM shared target below.
# Do NOT expand to every LLVM library: some (e.g. LLVMInterpreter) require
# optional dependencies (libffi) that may not be installed.
set(llvm_component_libs LLVMFrontendDriver)
foreach(component_lib ${llvm_component_libs})
if(NOT TARGET ${component_lib})
list(REMOVE_ITEM llvm_component_libs ${component_lib})
endif()
endforeach()
while(NOT "${new_libs}" STREQUAL "")
foreach(lib ${new_libs})
if(TARGET ${lib})
Expand All @@ -75,22 +86,36 @@ if (LLVM_LINK_LLVM_DYLIB)
continue()
endif()
foreach(transitive_lib ${transitive_libs})
if(NOT TARGET ${transitive_lib})
continue()
# Replace the LLVM shared library (libLLVM.so) that packages like
# Debian's declare as the link interface of the static clang archives
# with the static LLVM component libraries: some LLVM libs are only
# reachable through that umbrella (e.g. LLVMFrontendDriver for
# llvm::driver::createTLII in clangCodeGen), so dropping it outright
# produces unresolved symbols at link time.
# Everything else must be kept verbatim: plain items (rt, dl, m) and
# non-LLVM targets (e.g. ZLIB::ZLIB) are LLVM's system dependencies
# that the static archives still need.
if(TARGET ${transitive_lib}
AND "${transitive_lib}" MATCHES "^LLVM")
get_target_property(lib_type ${transitive_lib} TYPE)
if("${lib_type}" STREQUAL "SHARED_LIBRARY"
OR "${lib_type}" STREQUAL "MODULE_LIBRARY")
foreach(component_lib ${llvm_component_libs})
if(TARGET ${component_lib} AND NOT ${component_lib} IN_LIST static_transitive_libs)
list(APPEND static_transitive_libs ${component_lib})
endif()
endforeach()
continue()
endif()
endif()
get_target_property(lib_type ${transitive_lib} TYPE)
if("${lib_type}" STREQUAL "STATIC_LIBRARY")
list(APPEND static_transitive_libs ${transitive_lib})
else()
# Filter our libLLVM.so and friends.
continue()
endif()
if(NOT ${transitive_lib} IN_LIST libs)
list(APPEND static_transitive_libs ${transitive_lib})
if(TARGET ${transitive_lib} AND NOT ${transitive_lib} IN_LIST libs)
list(APPEND newer_libs ${transitive_lib})
list(APPEND libs ${transitive_lib})
endif()
endforeach(transitive_lib)
# Update the target properties with the list of only static libraries.
# Update the target properties with the filtered dependency list
# (shared LLVM umbrella replaced by static component libraries).
set_target_properties(${lib} PROPERTIES INTERFACE_LINK_LIBRARIES "${static_transitive_libs}")
set(static_transitive_libs "")
endif()
Expand Down
5 changes: 5 additions & 0 deletions interpreter/CppInterOp/lib/CppInterOp/CXCppInterOp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,11 @@ CPPINTEROP_API intptr_t cppinterop_Evaluate(const char* code, bool* HadError) {
return Cpp::Evaluate(code, HadError);
}

// The std::string* reason argument of Cpp::LoadLibrary is C++-only.
CPPINTEROP_API bool cppinterop_LoadLibrary(const char* lib_stem, bool lookup) {
return Cpp::LoadLibrary(lib_stem, lookup);
}

// GetClassTemplatedMethods returns bool AND fills a vector out-param.
// The C wrapper drops the bool (caller checks arr.size > 0 instead).
CPPINTEROP_API Cpp::CppInterOpArray
Expand Down
Loading
Loading