Skip to content

Commit 91b7196

Browse files
authored
Make all public API functions dispatchable from a single .td definition. (#906)
Default arguments were lost through the dispatch function pointer indirection, requiring ~245 DFLT_* macro workarounds across the test suite. 47 public functions were not dispatchable at all. Function signatures in the dispatch table could drift from CppInterOp.h because the two were maintained independently.
1 parent 2e0183b commit 91b7196

25 files changed

Lines changed: 2233 additions & 1192 deletions

.github/actions/Build_and_Test_CppInterOp/action.yml

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,22 @@ runs:
177177
CPLUS_INCLUDE_PATH="${LLVM_DIR}/llvm/include:${LLVM_DIR}/clang/include:${LLVM_BUILD_DIR}/include:${LLVM_BUILD_DIR}/tools/clang/include:$PWD/include"
178178
fi
179179
180+
# Build native cppinterop-tblgen for .inc file generation.
181+
# Use the native LLVM build (not the Emscripten cross-build) since
182+
# cppinterop-tblgen only needs libLLVMTableGen and libLLVMSupport.
183+
NATIVE_LLVM_BUILD_DIR="$(pwd)/llvm-project/native_build"
184+
mkdir -p native_cppinterop_build && pushd native_cppinterop_build
185+
cmake -DCMAKE_BUILD_TYPE=Release \
186+
-DLLVM_DIR=$NATIVE_LLVM_BUILD_DIR/lib/cmake/llvm \
187+
-DCPPINTEROP_ENABLE_TESTING=OFF \
188+
-DCPPINTEROP_BUILD_TABLEGEN_ONLY=ON \
189+
../
190+
cmake --build . --target cppinterop-tblgen -j ${{ env.ncpus }}
191+
export CPPINTEROP_TBLGEN_EXE=$(find $PWD -name cppinterop-tblgen -type f | head -1)
192+
echo "Found cppinterop-tblgen at: $CPPINTEROP_TBLGEN_EXE"
193+
echo "CPPINTEROP_TBLGEN_EXE=$CPPINTEROP_TBLGEN_EXE" >> $GITHUB_ENV
194+
popd
195+
180196
# Build CppInterOp next to cling and llvm-project.
181197
mkdir build
182198
cd build
@@ -195,6 +211,7 @@ runs:
195211
-DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=ON \
196212
-DLLVM_ENABLE_WERROR=On \
197213
-DSYSROOT_PATH=$SYSROOT_PATH \
214+
-DCPPINTEROP_TABLEGEN_EXE=$CPPINTEROP_TBLGEN_EXE \
198215
../
199216
else
200217
emcmake cmake -DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} \
@@ -208,6 +225,7 @@ runs:
208225
-DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=ON \
209226
-DLLVM_ENABLE_WERROR=On \
210227
-DSYSROOT_PATH=$SYSROOT_PATH \
228+
-DCPPINTEROP_TABLEGEN_EXE=$CPPINTEROP_TBLGEN_EXE \
211229
../
212230
fi
213231
emmake make -j ${{ env.ncpus }} check-cppinterop
@@ -353,6 +371,7 @@ runs:
353371
-DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=ON \
354372
-DLLVM_ENABLE_WERROR=On \
355373
-DSYSROOT_PATH=${{ env.SYSROOT_PATH }} \
374+
-DCPPINTEROP_TABLEGEN_EXE=$CPPINTEROP_TBLGEN_EXE \
356375
../
357376
else
358377
emcmake cmake -DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} \
@@ -365,6 +384,7 @@ runs:
365384
-DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=ON \
366385
-DLLVM_ENABLE_WERROR=On \
367386
-DSYSROOT_PATH=${{ env.SYSROOT_PATH }} \
387+
-DCPPINTEROP_TABLEGEN_EXE=$CPPINTEROP_TBLGEN_EXE \
368388
../
369389
fi
370390
os="${{ matrix.os }}"
@@ -461,6 +481,21 @@ runs:
461481
echo "CPLUS_INCLUDE_PATH=$env:CPLUS_INCLUDE_PATH" >> $env:GITHUB_ENV
462482
}
463483
484+
# Build native cppinterop-tblgen for .inc file generation.
485+
mkdir native_cppinterop_build
486+
pushd native_cppinterop_build
487+
$env:NATIVE_LLVM_BUILD_DIR="$env:PWD_DIR\llvm-project\native_build"
488+
cmake -DCMAKE_BUILD_TYPE=Release `
489+
-DLLVM_DIR="$env:NATIVE_LLVM_BUILD_DIR\lib\cmake\llvm" `
490+
-DCPPINTEROP_ENABLE_TESTING=OFF `
491+
-DCPPINTEROP_BUILD_TABLEGEN_ONLY=ON `
492+
..\
493+
cmake --build . --target cppinterop-tblgen -j ${{ env.ncpus }}
494+
$env:CPPINTEROP_TBLGEN_EXE = (Get-ChildItem -Recurse -Filter "cppinterop-tblgen.exe" | Select-Object -First 1).FullName
495+
echo "Found cppinterop-tblgen at: $env:CPPINTEROP_TBLGEN_EXE"
496+
echo "CPPINTEROP_TBLGEN_EXE=$env:CPPINTEROP_TBLGEN_EXE" >> $env:GITHUB_ENV
497+
popd
498+
464499
# Build CppInterOp next to cling and llvm-project.
465500
mkdir build
466501
cd build
@@ -480,6 +515,7 @@ runs:
480515
-DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=ON `
481516
-DLLVM_ENABLE_WERROR=On `
482517
-DSYSROOT_PATH="$env:SYSROOT_PATH" `
518+
-DCPPINTEROP_TABLEGEN_EXE="$env:CPPINTEROP_TBLGEN_EXE" `
483519
..\
484520
}
485521
else
@@ -495,6 +531,7 @@ runs:
495531
-DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=ON `
496532
-DLLVM_ENABLE_WERROR=On `
497533
-DSYSROOT_PATH="$env:SYSROOT_PATH" `
534+
-DCPPINTEROP_TABLEGEN_EXE="$env:CPPINTEROP_TBLGEN_EXE" `
498535
..\
499536
}
500537
function Error-OnFailure {
@@ -570,6 +607,7 @@ runs:
570607
-DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=ON `
571608
-DLLVM_ENABLE_WERROR=On `
572609
-DSYSROOT_PATH=${{ env.SYSROOT_PATH }} `
610+
-DCPPINTEROP_TABLEGEN_EXE="${{ env.CPPINTEROP_TBLGEN_EXE }}" `
573611
..\
574612
}
575613
else
@@ -584,6 +622,7 @@ runs:
584622
-DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=ON `
585623
-DLLVM_ENABLE_WERROR=On `
586624
-DSYSROOT_PATH=${{ env.SYSROOT_PATH }} `
625+
-DCPPINTEROP_TABLEGEN_EXE="${{ env.CPPINTEROP_TBLGEN_EXE }}" `
587626
..\
588627
}
589628
Error-OnFailure { emmake make -j ${{ env.ncpus }} check-cppinterop }

.github/workflows/clang-tidy-review.yml

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,17 +35,34 @@ jobs:
3535
id: review
3636
with:
3737
build_dir: build
38-
apt_packages: cmake,libxml2,libxml2-dev,libtinfo-dev,zlib1g-dev,libzstd-dev
38+
# llvm-dev provides linkable libLLVMTableGen.a for building
39+
# cppinterop-tblgen. The KyleMayes binary LLVM distribution has
40+
# incompatible .a files. The system LLVM version doesn't need to
41+
# match CppInterOp's minimum (19) since the TableGen library API
42+
# is stable — only the tblgen binary is built against it. The
43+
# real CppInterOp analysis uses the KyleMayes LLVM via LLVM_DIR.
44+
apt_packages: cmake,libxml2,libxml2-dev,libtinfo-dev,zlib1g-dev,libzstd-dev,llvm-dev
3945
split_workflow: true
4046
config_file: .clang-tidy
47+
# Two-stage cmake: (1) build cppinterop-tblgen against system
48+
# LLVM, (2) configure CppInterOp against KyleMayes LLVM with the
49+
# native tblgen binary, then generate .inc files.
4150
cmake_command: >
51+
SYSTEM_LLVM_DIR=$(find /usr/lib/llvm-* -path '*/cmake/llvm/LLVMConfig.cmake' -printf '%h' -quit 2>/dev/null || echo "/usr/lib/llvm-18/lib/cmake/llvm") &&
52+
cmake . -B tblgen_build -DCMAKE_BUILD_TYPE=Release
53+
-DLLVM_DIR=$SYSTEM_LLVM_DIR
54+
-DCPPINTEROP_BUILD_TABLEGEN_ONLY=ON &&
55+
cmake --build tblgen_build --target cppinterop-tblgen --parallel $(nproc --all) &&
56+
TBLGEN_EXE=$(find $(pwd)/tblgen_build -name cppinterop-tblgen -type f | head -1) &&
4257
cmake . -B build -DCMAKE_BUILD_TYPE="Release"
4358
-DCMAKE_C_COMPILER="$GITHUB_WORKSPACE/llvm/bin/clang"
4459
-DCMAKE_CXX_COMPILER="$GITHUB_WORKSPACE/llvm/bin/clang++"
4560
-DLLVM_DIR="$GITHUB_WORKSPACE/llvm"
4661
-DBUILD_SHARED_LIBS=ON
47-
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON &&
62+
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON
63+
-DCPPINTEROP_TABLEGEN_EXE=$TBLGEN_EXE &&
4864
cd build &&
65+
cmake --build . --target CppInterOpTableGen --parallel $(nproc --all) &&
4966
cmake --build . --target googletest --parallel $(nproc --all)
5067
5168
- name: Upload artifacts

CMakeLists.txt

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ set(CMAKE_CXX_EXTENSIONS NO)
1212
option(CPPINTEROP_USE_CLING "Use Cling as backend" OFF)
1313
option(CPPINTEROP_USE_REPL "Use clang-repl as backend" ON)
1414
option(CPPINTEROP_ENABLE_TESTING "Enable the CppInterOp testing infrastructure." ON)
15+
option(CPPINTEROP_BUILD_TABLEGEN_ONLY "Only build cppinterop-tblgen (for cross-compilation)" OFF)
1516
if(EMSCRIPTEN)
1617
set(CPPINTEROP_EXTRA_WASM_FLAGS "-fwasm-exceptions" CACHE STRING "Extra flags for wasm")
1718
endif()
@@ -24,6 +25,19 @@ endif()
2425
if( CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR )
2526
project(CppInterOp)
2627

28+
# When only building cppinterop-tblgen for cross-compilation, skip
29+
# all find_package calls and library/test subdirectories. Only needs
30+
# LLVM_DIR pointing to a native LLVM build with libLLVMTableGen.
31+
if(CPPINTEROP_BUILD_TABLEGEN_ONLY)
32+
find_package(LLVM REQUIRED CONFIG)
33+
include_directories(${LLVM_INCLUDE_DIRS})
34+
include(AddLLVM)
35+
include(HandleLLVMOptions)
36+
include(TableGen)
37+
add_subdirectory(utils/TableGen)
38+
return()
39+
endif()
40+
2741
if (NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
2842
message(WARNING "No build type selected. Defaulted CMAKE_BUILD_TYPE=Release.\n"
2943
"Valid options are: None, Debug, Release, RelWithDebInfo, MinSizeRel.")
@@ -300,10 +314,14 @@ endif()
300314

301315
include(AddLLVM)
302316
include(HandleLLVMOptions)
317+
include(TableGen)
303318
endif()
304319

305320
set(CMAKE_INCLUDE_CURRENT_DIR ON)
306321

322+
# Generated .inc files from cppinterop-tblgen live under the build tree.
323+
include_directories(${CMAKE_BINARY_DIR}/include)
324+
307325
# In rare cases we might want to have clang installed in a different place
308326
# than llvm and the header files should be found first (even though the
309327
# LLVM_INCLUDE_DIRS) contain clang headers, too.
@@ -443,6 +461,7 @@ install(DIRECTORY include/
443461
FILES_MATCHING
444462
PATTERN "*.def"
445463
PATTERN "*.h"
464+
PATTERN "*.inc"
446465
PATTERN ".svn" EXCLUDE
447466
)
448467

@@ -548,6 +567,9 @@ if (CPPINTEROP_INCLUDE_DOCS)
548567
add_subdirectory(docs)
549568
endif()
550569

570+
if(NOT EMSCRIPTEN AND NOT CPPINTEROP_TABLEGEN_EXE)
571+
add_subdirectory(utils/TableGen)
572+
endif()
551573
add_subdirectory(lib)
552574
if (CPPINTEROP_ENABLE_TESTING)
553575
add_subdirectory(unittests)

docs/Emscripten-build-instructions.rst

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,44 @@ and
208208
$env:CMAKE_PREFIX_PATH=$env:PREFIX
209209
$env:CMAKE_SYSTEM_PREFIX_PATH=$env:PREFIX
210210
211-
on Windows. Now to build and test your Emscripten build of CppInterOp on Linux and osx execute the following
211+
on Windows. Before building the Emscripten version of CppInterOp, we need
212+
to build ``cppinterop-tblgen`` natively. This tool generates ``.inc`` files
213+
from ``.td`` definitions and must run on the host (not under Emscripten).
214+
We use the native LLVM build from the earlier step since it has the required
215+
``libLLVMTableGen`` library.
216+
217+
On Linux and osx:
218+
219+
.. code:: bash
220+
221+
cd ../CppInterOp/
222+
NATIVE_LLVM_BUILD_DIR=$(pwd)/../llvm-project/native_build
223+
mkdir -p native_cppinterop_build && cd native_cppinterop_build
224+
cmake -DCMAKE_BUILD_TYPE=Release \
225+
-DLLVM_DIR=$NATIVE_LLVM_BUILD_DIR/lib/cmake/llvm \
226+
-DCPPINTEROP_BUILD_TABLEGEN_ONLY=ON \
227+
../
228+
cmake --build . --target cppinterop-tblgen -j $(nproc --all)
229+
export CPPINTEROP_TBLGEN_EXE=$(find $PWD -name cppinterop-tblgen -type f | head -1)
230+
cd ..
231+
232+
On Windows:
233+
234+
.. code:: powershell
235+
236+
cd ..\CppInterOp\
237+
$env:NATIVE_LLVM_BUILD_DIR="$env:PWD_DIR\llvm-project\native_build"
238+
mkdir native_cppinterop_build
239+
cd native_cppinterop_build
240+
cmake -DCMAKE_BUILD_TYPE=Release `
241+
-DLLVM_DIR="$env:NATIVE_LLVM_BUILD_DIR\lib\cmake\llvm" `
242+
-DCPPINTEROP_BUILD_TABLEGEN_ONLY=ON `
243+
..\
244+
cmake --build . --target cppinterop-tblgen -j $(nproc --all)
245+
$env:CPPINTEROP_TBLGEN_EXE = (Get-ChildItem -Recurse -Filter "cppinterop-tblgen.exe" | Select-Object -First 1).FullName
246+
cd ..
247+
248+
Now to build and test your Emscripten build of CppInterOp on Linux and osx execute the following
212249
(BUILD_SHARED_LIBS=ON is only needed if building xeus-cpp, as CppInterOp can be built as an Emscripten static library)
213250

214251
.. code:: bash
@@ -223,6 +260,7 @@ on Windows. Now to build and test your Emscripten build of CppInterOp on Linux a
223260
-DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=ON \
224261
-DCMAKE_INSTALL_PREFIX=$PREFIX \
225262
-DSYSROOT_PATH=$SYSROOT_PATH \
263+
-DCPPINTEROP_TABLEGEN_EXE=$CPPINTEROP_TBLGEN_EXE \
226264
../
227265
emmake make -j $(nproc --all) check-cppinterop
228266
@@ -241,6 +279,7 @@ To build and test your Emscripten build of CppInterOp on Windows execute the fol
241279
-DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=ON `
242280
-DLLVM_ENABLE_WERROR=On `
243281
-DSYSROOT_PATH="$env:SYSROOT_PATH" `
282+
-DCPPINTEROP_TABLEGEN_EXE="$env:CPPINTEROP_TBLGEN_EXE" `
244283
..\
245284
emmake make -j $(nproc --all) check-cppinterop
246285

0 commit comments

Comments
 (0)