diff --git a/lib/CppInterOp/CppInterOpInterpreter.h b/lib/CppInterOp/CppInterOpInterpreter.h index 4833c0bd5..8189f9653 100644 --- a/lib/CppInterOp/CppInterOpInterpreter.h +++ b/lib/CppInterOp/CppInterOpInterpreter.h @@ -154,6 +154,7 @@ class Interpreter { llvm::InitializeAllTargetInfos(); llvm::InitializeAllTargets(); llvm::InitializeAllTargetMCs(); + llvm::InitializeAllAsmParsers(); llvm::InitializeAllAsmPrinters(); std::vector vargs(argv + 1, argv + argc); diff --git a/unittests/CppInterOp/InterpreterTest.cpp b/unittests/CppInterOp/InterpreterTest.cpp index 5800fe64e..bbcf27b43 100644 --- a/unittests/CppInterOp/InterpreterTest.cpp +++ b/unittests/CppInterOp/InterpreterTest.cpp @@ -448,3 +448,31 @@ TEST(InterpreterTest, MultipleInterpreter) { std::string cerrs = testing::internal::GetCapturedStderr(); EXPECT_STREQ(cerrs.c_str(), "printf_jit called!\n"); } + +TEST(InterpreterTest, ASMParsing) { +#ifdef EMSCRIPTEN + GTEST_SKIP() << "Test fails for Emscipten builds"; +#endif +#ifdef _WIN32 + GTEST_SKIP() << "Disabled on Windows. Needs fixing."; +#endif + if (llvm::sys::RunningOnValgrind()) + GTEST_SKIP() << "XFAIL due to Valgrind report"; + if (!IsTargetX86()) + GTEST_SKIP() << "Skipped on ARM, we test ASM for x86_64"; + std::vector interpreter_args = {"-include", "new"}; + auto* I = Cpp::CreateInterpreter(interpreter_args); + EXPECT_TRUE(I); + + EXPECT_TRUE(Cpp::Declare(R"( + void foo(int &input) { + __asm__ volatile ("addl $10, %0" : "+r"(input)); + } + )", + I) == 0); + + bool hasError; + EXPECT_TRUE(Cpp::Process("int b = 42; foo(b);") == 0); + EXPECT_TRUE(Cpp::Evaluate("b", &hasError) == 52); + EXPECT_FALSE(hasError); +} diff --git a/unittests/CppInterOp/Utils.cpp b/unittests/CppInterOp/Utils.cpp index e048b0df5..623e9fd12 100644 --- a/unittests/CppInterOp/Utils.cpp +++ b/unittests/CppInterOp/Utils.cpp @@ -9,6 +9,8 @@ #include "clang/Sema/Lookup.h" #include "clang/Sema/Sema.h" +#include "llvm/TargetParser/Triple.h" + #include #include #include @@ -57,6 +59,15 @@ void TestUtils::GetAllSubDecls(Decl *D, std::vector& SubDecls, } } +bool IsTargetX86() { +#ifndef CPPINTEROP_USE_CLING + llvm::Triple triple(Interp->getCompilerInstance()->getTargetOpts().Triple); +#else + llvm::Triple triple(Interp->getCI()->getTargetOpts().Triple); +#endif + return triple.isX86(); +} + const char* get_c_string(CXString string) { return static_cast(string.data); } diff --git a/unittests/CppInterOp/Utils.h b/unittests/CppInterOp/Utils.h index 2b7b12590..3e5bd12a8 100644 --- a/unittests/CppInterOp/Utils.h +++ b/unittests/CppInterOp/Utils.h @@ -34,4 +34,6 @@ void dispose_string(CXString string); CXScope make_scope(const clang::Decl* D, const CXInterpreter I); +bool IsTargetX86(); + #endif // CPPINTEROP_UNITTESTS_LIBCPPINTEROP_UTILS_H