diff --git a/lib/Interpreter/CXCppInterOp.cpp b/lib/Interpreter/CXCppInterOp.cpp index 0f4566016..5f91fa4e2 100644 --- a/lib/Interpreter/CXCppInterOp.cpp +++ b/lib/Interpreter/CXCppInterOp.cpp @@ -271,8 +271,17 @@ 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(); // NOLINT(*-owning-memory) +#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 + return I.release(); + // I->Interp = std::make_unique(argc, argv); // create a bridge between CXTranslationUnit and clang::Interpreter // auto AU = std::make_unique(false); // AU->FileMgr = I->Interp->getCompilerInstance().getFileManager(); @@ -281,7 +290,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; } CXInterpreter clang_createInterpreterFromRawPtr(TInterp_t I) { 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 cdac4f768..254e10fca 100644 --- a/lib/Interpreter/CppInterOpInterpreter.h +++ b/lib/Interpreter/CppInterOpInterpreter.h @@ -136,11 +136,15 @@ 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(); @@ -150,7 +154,13 @@ class Interpreter { std::vector vargs(argv + 1, argv + argc); vargs.push_back("-include"); vargs.push_back("new"); - 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/InterpreterTest.cpp b/unittests/CppInterOp/InterpreterTest.cpp index 55cd3f742..30bf6bd61 100644 --- a/unittests/CppInterOp/InterpreterTest.cpp +++ b/unittests/CppInterOp/InterpreterTest.cpp @@ -166,6 +166,29 @@ TEST(InterpreterTest, CreateInterpreter) { #endif } +TEST(InterpreterTest, CreateInterpreterCAPI) { +#ifdef CPPINTEROP_USE_CLING + GTEST_SKIP() << "C API is not available in this build"; +#endif + // C API + 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 CPPINTEROP_USE_CLING + GTEST_SKIP() << "C API is not available in this build"; +#endif + const char* argv[] = {"-fsyntax-only", "-Xclang", "-invalid-plugin"}; + testing::internal::CaptureStderr(); // Suppress error messages + auto *CXI = clang_createInterpreter(argv, 3); + std::string capturedStderr = testing::internal::GetCapturedStderr(); + EXPECT_EQ(CXI, nullptr); +} + #ifdef LLVM_BINARY_DIR TEST(InterpreterTest, DetectResourceDir) { #ifdef EMSCRIPTEN