90
90
#include < unistd.h>
91
91
#endif // WIN32
92
92
93
- #if CLANG_VERSION_MAJOR > 22
93
+ // Runtime symbols required if the library using JIT (Cpp::Evaluate) does not
94
+ // link to llvm
95
+ #ifndef CPPINTEROP_USE_CLING
96
+ #if CLANG_VERSION_MAJOR >= 22
94
97
extern " C" void * __clang_Interpreter_SetValueWithAlloc (void * This, void * OutVal,
95
98
void * OpaqueType)
96
99
#else
97
100
void * __clang_Interpreter_SetValueWithAlloc (void * This, void * OutVal,
98
101
void * OpaqueType);
99
102
#endif
100
103
104
+ #if CLANG_VERSION_MAJOR >= 19
101
105
extern " C" void __clang_Interpreter_SetValueNoAlloc (void * This,
102
106
void * OutVal,
103
107
void * OpaqueType, ...);
108
+ #elif CLANG_VERSION_MAJOR == 18
109
+ void __clang_Interpreter_SetValueNoAlloc (void *, void *, void *);
110
+ void __clang_Interpreter_SetValueNoAlloc (void *, void *, void *, void *);
111
+ void __clang_Interpreter_SetValueNoAlloc (void *, void *, void *, float );
112
+ void __clang_Interpreter_SetValueNoAlloc (void *, void *, void *, double );
113
+ void __clang_Interpreter_SetValueNoAlloc (void *, void *, void *, long double );
114
+ void __clang_Interpreter_SetValueNoAlloc (void *, void *, void *,
115
+ unsigned long long );
116
+ #endif
117
+ #endif // CPPINTEROP_USE_CLING
104
118
105
119
namespace Cpp {
106
120
@@ -3488,10 +3502,12 @@ TInterp_t CreateInterpreter(const std::vector<const char*>& Args /*={}*/,
3488
3502
3489
3503
// Define runtime symbols in the JIT dylib for clang-repl
3490
3504
#ifndef CPPINTEROP_USE_CLING
3491
- #if CLANG_VERSION_MAJOR > 22
3505
+ // llvm > 22 has this defined as a C symbol that does not require mangling
3506
+ #if CLANG_VERSION_MAJOR >= 22
3492
3507
DefineAbsoluteSymbol (*I, " __clang_Interpreter_SetValueWithAlloc" ,
3493
- (uint64_t )&__clang_Interpreter_SetValueNoAlloc );
3508
+ (uint64_t )&__clang_Interpreter_SetValueWithAlloc );
3494
3509
#else
3510
+ // obtain mangled name
3495
3511
auto * D = static_cast <clang::Decl*>(
3496
3512
Cpp::GetNamed (" __clang_Interpreter_SetValueWithAlloc" ));
3497
3513
if (auto * FD = llvm::dyn_cast<FunctionDecl>(D)) {
@@ -3502,8 +3518,64 @@ TInterp_t CreateInterpreter(const std::vector<const char*>& Args /*={}*/,
3502
3518
(uint64_t )&__clang_Interpreter_SetValueWithAlloc);
3503
3519
}
3504
3520
#endif
3521
+ // llvm < 19 has multiple overloads of __clang_Interpreter_SetValueNoAlloc
3522
+ #if CLANG_VERSION_MAJOR < 19
3523
+ // obtain all 6 candidates, and obtain the correct Decl for each overload
3524
+ // using BestOverloadFunctionMatch. We then map the decl to the correct
3525
+ // function pointer (force the compiler to find the right declarion by casting
3526
+ // to the corresponding function pointer signature) and then register it.
3527
+ const std::vector<TCppFunction_t> Methods = Cpp::GetFunctionsUsingName (
3528
+ Cpp::GetGlobalScope (), " __clang_Interpreter_SetValueNoAlloc" );
3529
+ std::string mangledName;
3530
+ ASTContext& Ctxt = I->getSema ().getASTContext ();
3531
+ auto * TAI = Ctxt.VoidPtrTy .getAsOpaquePtr ();
3532
+
3533
+ // possible parameter lists for __clang_Interpreter_SetValueNoAlloc overloads
3534
+ // in LLVM 18
3535
+ const std::vector<std::vector<Cpp::TemplateArgInfo>> a_params = {
3536
+ {TAI, TAI, TAI},
3537
+ {TAI, TAI, TAI, TAI},
3538
+ {TAI, TAI, TAI, Ctxt.FloatTy .getAsOpaquePtr ()},
3539
+ {TAI, TAI, TAI, Ctxt.DoubleTy .getAsOpaquePtr ()},
3540
+ {TAI, TAI, TAI, Ctxt.LongDoubleTy .getAsOpaquePtr ()},
3541
+ {TAI, TAI, TAI, Ctxt.UnsignedLongLongTy .getAsOpaquePtr ()}};
3542
+
3543
+ using FP0 = void (*)(void *, void *, void *);
3544
+ using FP1 = void (*)(void *, void *, void *, void *);
3545
+ using FP2 = void (*)(void *, void *, void *, float );
3546
+ using FP3 = void (*)(void *, void *, void *, double );
3547
+ using FP4 = void (*)(void *, void *, void *, long double );
3548
+ using FP5 = void (*)(void *, void *, void *, unsigned long long );
3549
+
3550
+ const std::vector<void *> func_pointers = {
3551
+ reinterpret_cast <void *>(
3552
+ static_cast <FP0>(&__clang_Interpreter_SetValueNoAlloc)),
3553
+ reinterpret_cast <void *>(
3554
+ static_cast <FP1>(&__clang_Interpreter_SetValueNoAlloc)),
3555
+ reinterpret_cast <void *>(
3556
+ static_cast <FP2>(&__clang_Interpreter_SetValueNoAlloc)),
3557
+ reinterpret_cast <void *>(
3558
+ static_cast <FP3>(&__clang_Interpreter_SetValueNoAlloc)),
3559
+ reinterpret_cast <void *>(
3560
+ static_cast <FP4>(&__clang_Interpreter_SetValueNoAlloc)),
3561
+ reinterpret_cast <void *>(
3562
+ static_cast <FP5>(&__clang_Interpreter_SetValueNoAlloc))};
3563
+
3564
+ // these symbols are not externed, so we need to mangle their names
3565
+ for (size_t i = 0 ; i < a_params.size (); ++i) {
3566
+ auto * decl = static_cast <clang::Decl*>(
3567
+ Cpp::BestOverloadFunctionMatch (Methods, {}, a_params[i]));
3568
+ if (auto * fd = llvm::dyn_cast<clang::FunctionDecl>(decl)) {
3569
+ auto gd = clang::GlobalDecl (fd);
3570
+ compat::maybeMangleDeclName (gd, mangledName);
3571
+ DefineAbsoluteSymbol (*I, mangledName.c_str (),
3572
+ reinterpret_cast <uint64_t >(func_pointers[i]));
3573
+ }
3574
+ }
3575
+ #else
3505
3576
DefineAbsoluteSymbol (*I, " __clang_Interpreter_SetValueNoAlloc" ,
3506
3577
(uint64_t )&__clang_Interpreter_SetValueNoAlloc);
3578
+ #endif
3507
3579
#endif
3508
3580
return I;
3509
3581
}
0 commit comments