[LV] Add test showing debug output for loops with uncountable BTCs.
[llvm-project.git] / clang / unittests / Interpreter / InterpreterExtensionsTest.cpp
blob29af464dbcebb98e6b5983cf9ffcaea45721d54f
1 //===- unittests/Interpreter/InterpreterExtensionsTest.cpp ----------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // Unit tests for Clang's Interpreter library.
11 //===----------------------------------------------------------------------===//
13 #include "InterpreterTestFixture.h"
15 #include "clang/Interpreter/Interpreter.h"
17 #include "clang/AST/Expr.h"
18 #include "clang/Frontend/CompilerInstance.h"
19 #include "clang/Sema/Lookup.h"
20 #include "clang/Sema/Sema.h"
22 #include "llvm/ExecutionEngine/Orc/LLJIT.h"
23 #include "llvm/ExecutionEngine/Orc/Shared/ExecutorAddress.h"
24 #include "llvm/MC/TargetRegistry.h"
25 #include "llvm/Support/Threading.h"
26 #include "llvm/Testing/Support/Error.h"
28 #include "gmock/gmock.h"
29 #include "gtest/gtest.h"
31 #include <system_error>
33 #if defined(_AIX) || defined(__MVS__)
34 #define CLANG_INTERPRETER_PLATFORM_CANNOT_CREATE_LLJIT
35 #endif
37 using namespace clang;
38 namespace {
40 class InterpreterExtensionsTest : public InterpreterTestBase {
41 protected:
42 void SetUp() override {
43 #ifdef CLANG_INTERPRETER_PLATFORM_CANNOT_CREATE_LLJIT
44 GTEST_SKIP();
45 #endif
48 static void SetUpTestSuite() {
49 llvm::InitializeAllTargets();
50 llvm::InitializeAllTargetInfos();
51 llvm::InitializeAllTargetMCs();
52 llvm::InitializeAllAsmPrinters();
55 public:
56 // Some tests require a arm-registered-target
57 static bool IsARMTargetRegistered() {
58 llvm::Triple TT;
59 TT.setArch(llvm::Triple::arm);
60 TT.setVendor(llvm::Triple::UnknownVendor);
61 TT.setOS(llvm::Triple::UnknownOS);
63 std::string UnusedErr;
64 return llvm::TargetRegistry::lookupTarget(TT.str(), UnusedErr);
68 struct OutOfProcInterpreter : public Interpreter {
69 OutOfProcInterpreter(
70 std::unique_ptr<CompilerInstance> CI, llvm::Error &ErrOut,
71 std::unique_ptr<clang::ASTConsumer> Consumer,
72 std::unique_ptr<llvm::orc::LLJITBuilder> JITBuilder = nullptr)
73 : Interpreter(std::move(CI), ErrOut, std::move(JITBuilder),
74 std::move(Consumer)) {}
77 TEST_F(InterpreterExtensionsTest, FindRuntimeInterface) {
78 if (!HostSupportsJIT())
79 GTEST_SKIP();
81 clang::IncrementalCompilerBuilder CB;
82 llvm::Error ErrOut = llvm::Error::success();
83 auto CI = cantFail(CB.CreateCpp());
84 // Do not attach the default consumer which is specialized for in-process.
85 class NoopConsumer : public ASTConsumer {};
86 std::unique_ptr<ASTConsumer> C = std::make_unique<NoopConsumer>();
87 OutOfProcInterpreter I(std::move(CI), ErrOut, std::move(C),
88 /*JITBuilder=*/nullptr);
89 cantFail(std::move(ErrOut));
90 cantFail(I.Parse("int a = 1; a"));
91 cantFail(I.Parse("int b = 2; b"));
92 cantFail(I.Parse("int c = 3; c"));
94 // Make sure no clang::Value logic is attached by the Interpreter.
95 Value V1;
96 llvm::cantFail(I.ParseAndExecute("int x = 42;"));
97 llvm::cantFail(I.ParseAndExecute("x", &V1));
98 EXPECT_FALSE(V1.isValid());
99 EXPECT_FALSE(V1.hasValue());
102 class CustomJBInterpreter : public Interpreter {
103 using CustomJITBuilderCreatorFunction =
104 std::function<llvm::Expected<std::unique_ptr<llvm::orc::LLJITBuilder>>()>;
105 CustomJITBuilderCreatorFunction JBCreator = nullptr;
107 public:
108 CustomJBInterpreter(std::unique_ptr<CompilerInstance> CI, llvm::Error &ErrOut,
109 std::unique_ptr<llvm::orc::LLJITBuilder> JB)
110 : Interpreter(std::move(CI), ErrOut, std::move(JB)) {}
112 ~CustomJBInterpreter() override {
113 // Skip cleanUp() because it would trigger LLJIT default dtors
114 Interpreter::ResetExecutor();
117 llvm::Error CreateExecutor() { return Interpreter::CreateExecutor(); }
120 TEST_F(InterpreterExtensionsTest, DefaultCrossJIT) {
121 if (!IsARMTargetRegistered())
122 GTEST_SKIP();
124 IncrementalCompilerBuilder CB;
125 CB.SetTargetTriple("armv6-none-eabi");
126 auto CI = cantFail(CB.CreateCpp());
127 llvm::Error ErrOut = llvm::Error::success();
128 CustomJBInterpreter Interp(std::move(CI), ErrOut, nullptr);
129 cantFail(std::move(ErrOut));
132 TEST_F(InterpreterExtensionsTest, CustomCrossJIT) {
133 if (!IsARMTargetRegistered())
134 GTEST_SKIP();
136 std::string TargetTriple = "armv6-none-eabi";
138 IncrementalCompilerBuilder CB;
139 CB.SetTargetTriple(TargetTriple);
140 auto CI = cantFail(CB.CreateCpp());
142 using namespace llvm::orc;
143 LLJIT *JIT = nullptr;
144 std::vector<std::unique_ptr<llvm::MemoryBuffer>> Objs;
145 auto JTMB = JITTargetMachineBuilder(llvm::Triple(TargetTriple));
146 JTMB.setCPU("cortex-m0plus");
148 auto JB = std::make_unique<LLJITBuilder>();
149 JB->setJITTargetMachineBuilder(JTMB);
150 JB->setPlatformSetUp(setUpInactivePlatform);
151 JB->setNotifyCreatedCallback([&](LLJIT &J) {
152 ObjectLayer &ObjLayer = J.getObjLinkingLayer();
153 auto *JITLinkObjLayer = llvm::dyn_cast<ObjectLinkingLayer>(&ObjLayer);
154 JITLinkObjLayer->setReturnObjectBuffer(
155 [&Objs](std::unique_ptr<llvm::MemoryBuffer> MB) {
156 Objs.push_back(std::move(MB));
158 JIT = &J;
159 return llvm::Error::success();
162 llvm::Error ErrOut = llvm::Error::success();
163 CustomJBInterpreter Interp(std::move(CI), ErrOut, std::move(JB));
164 cantFail(std::move(ErrOut));
166 EXPECT_EQ(0U, Objs.size());
167 cantFail(Interp.ParseAndExecute("int a = 1;"));
168 ASSERT_NE(JIT, nullptr); // But it is, because JBCreator was never called
169 ExecutorAddr Addr = cantFail(JIT->lookup("a"));
170 EXPECT_NE(0U, Addr.getValue());
171 EXPECT_EQ(1U, Objs.size());
174 } // end anonymous namespace