diff --git a/lib/Interpreter/CXCppInterOp.cpp b/lib/Interpreter/CXCppInterOp.cpp index 0f4566016..031096c91 100644 --- a/lib/Interpreter/CXCppInterOp.cpp +++ b/lib/Interpreter/CXCppInterOp.cpp @@ -271,8 +271,15 @@ static inline compat::Interpreter* getInterpreter(const CXInterpreterImpl* I) { } CXInterpreter clang_createInterpreter(const char* const* argv, int argc) { - auto* I = new CXInterpreterImpl(); // NOLINT(*-owning-memory) + auto I = std::make_unique(); +#ifdef CPPINTEROP_USE_CLING I->Interp = std::make_unique(argc, argv); +#else + I->Interp = compat::Interpreter::create(argc, argv); + if (!I->Interp) { + return nullptr; + } +#endif // create a bridge between CXTranslationUnit and clang::Interpreter // auto AU = std::make_unique(false); // AU->FileMgr = I->Interp->getCompilerInstance().getFileManager(); @@ -281,7 +288,7 @@ CXInterpreter clang_createInterpreter(const char* const* argv, int argc) { // AU->Ctx = &I->Interp->getSema().getASTContext(); // I->TU.reset(MakeCXTranslationUnit(static_cast(clang_createIndex(0, // 0)), AU)); - return I; + return I.release(); } CXInterpreter clang_createInterpreterFromRawPtr(TInterp_t I) { diff --git a/lib/Interpreter/Compatibility.h b/lib/Interpreter/Compatibility.h index 88169028e..7550fa8d5 100644 --- a/lib/Interpreter/Compatibility.h +++ b/lib/Interpreter/Compatibility.h @@ -294,9 +294,11 @@ createClangInterpreter(std::vector& args) { return nullptr; } if (CudaEnabled) { - if (auto Err = (*innerOrErr)->LoadDynamicLibrary("libcudart.so")) + if (auto Err = (*innerOrErr)->LoadDynamicLibrary("libcudart.so")) { llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(), "Failed load libcudart.so runtime:"); + return nullptr; + } } return std::move(*innerOrErr); diff --git a/lib/Interpreter/CppInterOp.cpp b/lib/Interpreter/CppInterOp.cpp index 3575bb2fa..9cfafe2f1 100755 --- a/lib/Interpreter/CppInterOp.cpp +++ b/lib/Interpreter/CppInterOp.cpp @@ -2957,7 +2957,15 @@ namespace Cpp { std::back_inserter(ClingArgv), [&](const std::string& str) { return str.c_str(); }); +#ifdef CPPINTEROP_USE_CLING auto I = new compat::Interpreter(ClingArgv.size(), &ClingArgv[0]); +#else + auto Interp = compat::Interpreter::create( + static_cast(ClingArgv.size()), ClingArgv.data()); + if (!Interp) + return nullptr; + auto* I = Interp.release(); +#endif // Honor -mllvm. // diff --git a/lib/Interpreter/CppInterOpInterpreter.h b/lib/Interpreter/CppInterOpInterpreter.h index 01b6d9795..9f22fb1b3 100644 --- a/lib/Interpreter/CppInterOpInterpreter.h +++ b/lib/Interpreter/CppInterOpInterpreter.h @@ -25,6 +25,7 @@ #if CLANG_VERSION_MAJOR >= 19 #include "clang/Sema/Redeclaration.h" #endif +#include "clang/Serialization/ModuleFileExtension.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallSet.h" @@ -34,6 +35,10 @@ #include "llvm/Support/Compiler.h" #include "llvm/Support/Error.h" #include "llvm/Support/TargetSelect.h" +#include "llvm/Support/raw_ostream.h" + +#include +#include namespace clang { class CompilerInstance; @@ -136,11 +141,14 @@ class Interpreter { private: std::unique_ptr inner; + Interpreter(std::unique_ptr CI) : inner(std::move(CI)) {} + public: - Interpreter(int argc, const char* const* argv, const char* llvmdir = 0, - const std::vector>& - moduleExtensions = {}, - void* extraLibHandle = 0, bool noRuntime = true) { + static std::unique_ptr + create(int argc, const char* const* argv, const char* llvmdir = nullptr, + const std::vector>& + moduleExtensions = {}, + void* extraLibHandle = nullptr, bool noRuntime = true) { // Initialize all targets (required for device offloading) llvm::InitializeAllTargetInfos(); llvm::InitializeAllTargets(); @@ -148,7 +156,13 @@ class Interpreter { llvm::InitializeAllAsmPrinters(); std::vector vargs(argv + 1, argv + argc); - inner = compat::createClangInterpreter(vargs); + auto CI = compat::createClangInterpreter(vargs); + if (!CI) { + llvm::errs() << "Interpreter creation failed\n"; + return nullptr; + } + + return std::unique_ptr(new Interpreter(std::move(CI))); } ~Interpreter() {} diff --git a/unittests/CppInterOp/CUDATest.cpp b/unittests/CppInterOp/CUDATest.cpp index ea171b46e..f697007cf 100644 --- a/unittests/CppInterOp/CUDATest.cpp +++ b/unittests/CppInterOp/CUDATest.cpp @@ -13,7 +13,8 @@ static bool HasCudaSDK() { // FIXME: Enable this for cling. return false; #endif // CLANG_VERSION_MAJOR < 16 - Cpp::CreateInterpreter({}, {"--cuda"}); + if (!Cpp::CreateInterpreter({}, {"--cuda"})) + return false; return Cpp::Declare("__global__ void test_func() {}" "test_func<<<1,1>>>();") == 0; }; @@ -30,7 +31,8 @@ static bool HasCudaRuntime() { if (!HasCudaSDK()) return false; - Cpp::CreateInterpreter({}, {"--cuda"}); + if (!Cpp::CreateInterpreter({}, {"--cuda"})) + return false; if (Cpp::Declare("__global__ void test_func() {}" "test_func<<<1,1>>>();")) return false; @@ -74,4 +76,4 @@ TEST(CUDATest, CUDARuntime) { GTEST_SKIP() << "Skipping CUDA tests as CUDA runtime not found"; EXPECT_TRUE(HasCudaRuntime()); -} +} \ No newline at end of file diff --git a/unittests/CppInterOp/InterpreterTest.cpp b/unittests/CppInterOp/InterpreterTest.cpp index 71e1ca991..008ea01e7 100644 --- a/unittests/CppInterOp/InterpreterTest.cpp +++ b/unittests/CppInterOp/InterpreterTest.cpp @@ -167,6 +167,25 @@ TEST(InterpreterTest, CreateInterpreter) { #endif } +#ifndef CPPINTEROP_USE_CLING +TEST(InterpreterTest, CreateInterpreterCAPI) { + const char* argv[] = {"-std=c++17"}; + auto *CXI = clang_createInterpreter(argv, 1); + auto CLI = clang_Interpreter_getClangInterpreter(CXI); + EXPECT_TRUE(CLI); + clang_Interpreter_dispose(CXI); +} + +TEST(InterpreterTest, CreateInterpreterCAPIFailure) { +#ifdef _WIN32 + GTEST_SKIP() << "Disabled on Windows. Needs fixing."; +#endif + const char* argv[] = {"-fsyntax-only", "-Xclang", "-invalid-plugin"}; + auto *CXI = clang_createInterpreter(argv, 3); + EXPECT_EQ(CXI, nullptr); +} +#endif + #ifdef LLVM_BINARY_DIR TEST(InterpreterTest, DetectResourceDir) { #ifdef EMSCRIPTEN