Skip to content

Commit

Permalink
Add support for libc++abi.
Browse files Browse the repository at this point in the history
Extends C++ interop with autodetected support for libc++abi in addition to the existing support for libcxxrt and libsubc++.

Fixes #142.
  • Loading branch information
ngrewe authored and davidchisnall committed Dec 15, 2020
1 parent bd274a7 commit 014f386
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 9 deletions.
7 changes: 7 additions & 0 deletions CMake/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@ project(test_cxx_runtime)
add_executable(test_cxx_runtime typeinfo_test.cc)
add_executable(test_cxx_stdlib typeinfo_test.cc)
if (CXX_RUNTIME)
if (CXX_RUNTIME MATCHES ".*libc\\+\\+abi.*")
find_library(M_LIBRARY m)
if (M_LIBRARY)
target_link_libraries(test_cxx_runtime ${M_LIBRARY})
endif()
endif()
set(CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "")
target_link_libraries(test_cxx_runtime ${CXX_RUNTIME})
set_target_properties(test_cxx_runtime PROPERTIES
LINKER_LANGUAGE C)
Expand Down
3 changes: 3 additions & 0 deletions CMake/typeinfo_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ class type_info2 : public std::type_info
virtual bool __do_catch(const type_info *thrown_type,
void **thrown_object,
unsigned outer) const { return true; }
virtual bool __do_upcast(
const __class_type_info *target,
void **thrown_object) const { return true; };
};
bool type_info2::__is_pointer_p() const { return true; }

Expand Down
28 changes: 24 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -291,9 +291,11 @@ if (ENABLE_OBJCXX)
if (NOT CXX_RUNTIME)
test_cxx(supc++ false)
endif (NOT CXX_RUNTIME)
# libc++abi does not currently work, don't try it.
if (NOT CXX_RUNTIME)
# test_cxx(c++abi false)
list (FIND CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "c++" _libcxx_index)
if (${_libcxx_index} GREATER -1)
test_cxx(c++abi false)
endif()
endif (NOT CXX_RUNTIME)

# If we have a C++ ABI library, then we can produce a single libobjc that
Expand Down Expand Up @@ -325,6 +327,9 @@ if (ENABLE_OBJCXX)
MAIN_DEPENDENCY eh_trampoline.cc)
list(APPEND libobjc_ASM_SRCS eh_trampoline.s)
list(APPEND libobjc_CXX_SRCS objcxx_eh.cc)

# Find libm for linking, as some versions of libc++ don't link against it
find_library(M_LIBRARY m)
endif ()
endif (ENABLE_OBJCXX)

Expand Down Expand Up @@ -377,6 +382,11 @@ if (LIBGC)
target_link_libraries(objc ${LIBGC})
endif ()

# Explicitly link libm, as an implicit dependency of the C++ runtime
if (M_LIBRARY)
target_link_libraries(objc ${M_LIBRARY})
endif ()

# Make weak symbols work on OS X
if (APPLE)
set(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS
Expand Down Expand Up @@ -459,8 +469,18 @@ include (CPack)
if (BOEHM_GC)
set(PC_REQUIRES_PRIVATE_BOEHM_GC "Requires.private: bdw-gc")
endif ()
if (ENABLE_OBJCXX AND NOT CXXRT_IS_STDLIB)
set(PC_LIBS_PRIVATE "Libs.private: -l${CXX_RUNTIME}")
if (ENABLE_OBJCXX)
if (CXXRT_IS_STDLIB)
set(PC_LIBS_PRIVATE ${CMAKE_CXX_IMPLICIT_LINK_LIBRARIES})
else()
list(APPEND PC_LIBS_PRIVATE ${CXX_RUNTIME})
if (M_LIBRARY)
list(APPEND PC_LIBS_PRIVATE ${M_LIBRARY})
endif ()
endif()
list(REMOVE_DUPLICATES PC_LIBS_PRIVATE)
string(REPLACE ";" " -l" PC_LIBS_PRIVATE "${PC_LIBS_PRIVATE}")
set(PC_LIBS_PRIVATE "Libs.private: -l${PC_LIBS_PRIVATE}")
endif()

configure_file("libobjc.pc.in" "libobjc.pc" @ONLY)
Expand Down
23 changes: 20 additions & 3 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,36 @@ jobs:
matrix:
Debug:
BuildType: Debug
StdLib: libstdc++
CxxFlags: ""
Release:
BuildType: Release
StdLib: libstdc++
CxxFlags: ""
Debug-libc++:
BuildType: Debug
StdLib: libc++
CxxFlags: "-stdlib=libc++"
Release-libc++:
BuildType: Release
StdLib: libc++
CxxFlags: "-stdlib=libc++"
steps:
- checkout: self
submodules: true
- script: |
sudo add-apt-repository "deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-8 main"
sudo apt-get update
sudo apt-get install -y ninja-build
sudo apt-get install -y clang-8
sudo apt-get install -y ninja-build clang-8
if [ "$(StdLib)" = "libc++" ]; then
sudo apt-get install -qy libc++-8-dev libc++abi-8-dev
fi
displayName: Install Dependencies
- task: CMake@1
displayName: Generate Build Scripts
inputs:
cmakeArgs: '.. -GNinja -DCMAKE_BUILD_TYPE=$(BuildType) -DTESTS=ON -DCMAKE_CXX_COMPILER=clang++-8 -DCMAKE_C_COMPILER=clang-8'
cmakeArgs: '.. -GNinja -DCMAKE_BUILD_TYPE=$(BuildType) -DTESTS=ON -DCMAKE_CXX_COMPILER=clang++-8 -DCMAKE_C_COMPILER=clang-8 -DCMAKE_CXX_FLAGS="$(CxxFlags)"'

- script: |
ninja
Expand All @@ -32,6 +48,7 @@ jobs:
- script: |
ctest -j 4 --output-on-failure -T test
displayName: 'Test'
workingDirectory: build
failOnStderr: false
- task: PublishTestResults@2
Expand Down
14 changes: 12 additions & 2 deletions objcxx_eh.cc
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,16 @@ namespace gnustep
unsigned outer) const;
};
}

static inline id dereference_thrown_object_pointer(void** obj) {
/* libc++-abi does not have __is_pointer_p and won't do the double dereference
* required to get the object pointer. We need to do it ourselves if we have
* caught an exception with libc++'s exception class. */
if (cxx_exception_class == llvm_cxx_exception_class) {
return **(id**)obj;
}
return *(id*)obj;
}
};


Expand All @@ -316,7 +326,7 @@ bool gnustep::libobjc::__objc_class_type_info::__do_catch(const type_info *throw
|| (AppleCompatibleMode &&
dynamic_cast<const __objc_class_type_info*>(thrownType)))
{
thrown = *(id*)obj;
thrown = dereference_thrown_object_pointer(obj);
// nil only matches id catch handlers in Apple-compatible mode, or when thrown as an id
if (0 == thrown)
{
Expand All @@ -328,7 +338,7 @@ bool gnustep::libobjc::__objc_class_type_info::__do_catch(const type_info *throw
}
else if (dynamic_cast<const __objc_class_type_info*>(thrownType))
{
thrown = *(id*)obj;
thrown = dereference_thrown_object_pointer(obj);
found = isKindOfClass((Class)objc_getClass(thrownType->name()),
(Class)objc_getClass(name()));
}
Expand Down

0 comments on commit 014f386

Please sign in to comment.