xref: /llvm-project/clang/unittests/Interpreter/InterpreterTest.cpp (revision 98f9bb384af1beb62eb62a353f0585281bee8c26)
1 //===- unittests/Interpreter/InterpreterTest.cpp --- Interpreter tests ----===//
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.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "clang/Interpreter/Interpreter.h"
14 
15 #include "clang/AST/Decl.h"
16 #include "clang/AST/DeclGroup.h"
17 #include "clang/AST/Mangle.h"
18 #include "clang/Frontend/CompilerInstance.h"
19 #include "clang/Frontend/TextDiagnosticPrinter.h"
20 #include "clang/Interpreter/Value.h"
21 #include "clang/Sema/Lookup.h"
22 #include "clang/Sema/Sema.h"
23 
24 #include "llvm/ExecutionEngine/Orc/LLJIT.h"
25 #include "llvm/Support/ManagedStatic.h"
26 #include "llvm/Support/TargetSelect.h"
27 
28 #include "gmock/gmock.h"
29 #include "gtest/gtest.h"
30 
31 using namespace clang;
32 
33 #if defined(_AIX)
34 #define CLANG_INTERPRETER_NO_SUPPORT_EXEC
35 #endif
36 
37 int Global = 42;
38 // JIT reports symbol not found on Windows without the visibility attribute.
39 REPL_EXTERNAL_VISIBILITY int getGlobal() { return Global; }
40 REPL_EXTERNAL_VISIBILITY void setGlobal(int val) { Global = val; }
41 
42 namespace {
43 using Args = std::vector<const char *>;
44 static std::unique_ptr<Interpreter>
45 createInterpreter(const Args &ExtraArgs = {},
46                   DiagnosticConsumer *Client = nullptr) {
47   Args ClangArgs = {"-Xclang", "-emit-llvm-only"};
48   ClangArgs.insert(ClangArgs.end(), ExtraArgs.begin(), ExtraArgs.end());
49   auto CB = clang::IncrementalCompilerBuilder();
50   CB.SetCompilerArgs(ClangArgs);
51   auto CI = cantFail(CB.CreateCpp());
52   if (Client)
53     CI->getDiagnostics().setClient(Client, /*ShouldOwnClient=*/false);
54   return cantFail(clang::Interpreter::create(std::move(CI)));
55 }
56 
57 static bool HostSupportsJit() {
58   auto J = llvm::orc::LLJITBuilder().create();
59   if (J)
60     return true;
61   LLVMConsumeError(llvm::wrap(J.takeError()));
62   return false;
63 }
64 
65 struct LLVMInitRAII {
66   LLVMInitRAII() {
67     llvm::InitializeNativeTarget();
68     llvm::InitializeNativeTargetAsmPrinter();
69   }
70   ~LLVMInitRAII() { llvm::llvm_shutdown(); }
71 } LLVMInit;
72 
73 static size_t DeclsSize(TranslationUnitDecl *PTUDecl) {
74   return std::distance(PTUDecl->decls().begin(), PTUDecl->decls().end());
75 }
76 
77 TEST(InterpreterTest, Sanity) {
78   if (!HostSupportsJit())
79     GTEST_SKIP();
80 
81   std::unique_ptr<Interpreter> Interp = createInterpreter();
82 
83   using PTU = PartialTranslationUnit;
84 
85   PTU &R1(cantFail(Interp->Parse("void g(); void g() {}")));
86   EXPECT_EQ(2U, DeclsSize(R1.TUPart));
87 
88   PTU &R2(cantFail(Interp->Parse("int i;")));
89   EXPECT_EQ(1U, DeclsSize(R2.TUPart));
90 }
91 
92 static std::string DeclToString(Decl *D) {
93   return llvm::cast<NamedDecl>(D)->getQualifiedNameAsString();
94 }
95 
96 #ifdef CLANG_INTERPRETER_NO_SUPPORT_EXEC
97 TEST(InterpreterTest, DISABLED_IncrementalInputTopLevelDecls) {
98 #else
99 TEST(InterpreterTest, IncrementalInputTopLevelDecls) {
100 #endif
101   if (!HostSupportsJit())
102     GTEST_SKIP();
103 
104   std::unique_ptr<Interpreter> Interp = createInterpreter();
105   auto R1 = Interp->Parse("int var1 = 42; int f() { return var1; }");
106   // gtest doesn't expand into explicit bool conversions.
107   EXPECT_TRUE(!!R1);
108   auto R1DeclRange = R1->TUPart->decls();
109   EXPECT_EQ(2U, DeclsSize(R1->TUPart));
110   EXPECT_EQ("var1", DeclToString(*R1DeclRange.begin()));
111   EXPECT_EQ("f", DeclToString(*(++R1DeclRange.begin())));
112 
113   auto R2 = Interp->Parse("int var2 = f();");
114   EXPECT_TRUE(!!R2);
115   auto R2DeclRange = R2->TUPart->decls();
116   EXPECT_EQ(1U, DeclsSize(R2->TUPart));
117   EXPECT_EQ("var2", DeclToString(*R2DeclRange.begin()));
118 }
119 
120 #ifdef CLANG_INTERPRETER_NO_SUPPORT_EXEC
121 TEST(InterpreterTest, DISABLED_Errors) {
122 #else
123 TEST(InterpreterTest, Errors) {
124 #endif
125   if (!HostSupportsJit())
126     GTEST_SKIP();
127 
128   Args ExtraArgs = {"-Xclang", "-diagnostic-log-file", "-Xclang", "-"};
129 
130   // Create the diagnostic engine with unowned consumer.
131   std::string DiagnosticOutput;
132   llvm::raw_string_ostream DiagnosticsOS(DiagnosticOutput);
133   auto DiagPrinter = std::make_unique<TextDiagnosticPrinter>(
134       DiagnosticsOS, new DiagnosticOptions());
135 
136   auto Interp = createInterpreter(ExtraArgs, DiagPrinter.get());
137   auto Err = Interp->Parse("intentional_error v1 = 42; ").takeError();
138   using ::testing::HasSubstr;
139   EXPECT_THAT(DiagnosticsOS.str(),
140               HasSubstr("error: unknown type name 'intentional_error'"));
141   EXPECT_EQ("Parsing failed.", llvm::toString(std::move(Err)));
142 
143   auto RecoverErr = Interp->Parse("int var1 = 42;");
144   EXPECT_TRUE(!!RecoverErr);
145 }
146 
147 // Here we test whether the user can mix declarations and statements. The
148 // interpreter should be smart enough to recognize the declarations from the
149 // statements and wrap the latter into a declaration, producing valid code.
150 #ifdef CLANG_INTERPRETER_NO_SUPPORT_EXEC
151 TEST(InterpreterTest, DISABLED_DeclsAndStatements) {
152 #else
153 TEST(InterpreterTest, DeclsAndStatements) {
154 #endif
155   if (!HostSupportsJit())
156     GTEST_SKIP();
157 
158   Args ExtraArgs = {"-Xclang", "-diagnostic-log-file", "-Xclang", "-"};
159 
160   // Create the diagnostic engine with unowned consumer.
161   std::string DiagnosticOutput;
162   llvm::raw_string_ostream DiagnosticsOS(DiagnosticOutput);
163   auto DiagPrinter = std::make_unique<TextDiagnosticPrinter>(
164       DiagnosticsOS, new DiagnosticOptions());
165 
166   auto Interp = createInterpreter(ExtraArgs, DiagPrinter.get());
167   auto R1 = Interp->Parse(
168       "int var1 = 42; extern \"C\" int printf(const char*, ...);");
169   // gtest doesn't expand into explicit bool conversions.
170   EXPECT_TRUE(!!R1);
171 
172   auto *PTU1 = R1->TUPart;
173   EXPECT_EQ(2U, DeclsSize(PTU1));
174 
175   auto R2 = Interp->Parse("var1++; printf(\"var1 value %d\\n\", var1);");
176   EXPECT_TRUE(!!R2);
177 }
178 
179 #ifdef CLANG_INTERPRETER_NO_SUPPORT_EXEC
180 TEST(InterpreterTest, DISABLED_UndoCommand) {
181 #else
182 TEST(InterpreterTest, UndoCommand) {
183 #endif
184   if (!HostSupportsJit())
185     GTEST_SKIP();
186 
187   Args ExtraArgs = {"-Xclang", "-diagnostic-log-file", "-Xclang", "-"};
188 
189   // Create the diagnostic engine with unowned consumer.
190   std::string DiagnosticOutput;
191   llvm::raw_string_ostream DiagnosticsOS(DiagnosticOutput);
192   auto DiagPrinter = std::make_unique<TextDiagnosticPrinter>(
193       DiagnosticsOS, new DiagnosticOptions());
194 
195   auto Interp = createInterpreter(ExtraArgs, DiagPrinter.get());
196 
197   // Fail to undo.
198   auto Err1 = Interp->Undo();
199   EXPECT_EQ("Operation failed. Too many undos",
200             llvm::toString(std::move(Err1)));
201   auto Err2 = Interp->Parse("int foo = 42;");
202   EXPECT_TRUE(!!Err2);
203   auto Err3 = Interp->Undo(2);
204   EXPECT_EQ("Operation failed. Too many undos",
205             llvm::toString(std::move(Err3)));
206 
207   // Succeed to undo.
208   auto Err4 = Interp->Parse("int x = 42;");
209   EXPECT_TRUE(!!Err4);
210   auto Err5 = Interp->Undo();
211   EXPECT_FALSE(Err5);
212   auto Err6 = Interp->Parse("int x = 24;");
213   EXPECT_TRUE(!!Err6);
214   auto Err7 = Interp->Parse("#define X 42");
215   EXPECT_TRUE(!!Err7);
216   auto Err8 = Interp->Undo();
217   EXPECT_FALSE(Err8);
218   auto Err9 = Interp->Parse("#define X 24");
219   EXPECT_TRUE(!!Err9);
220 
221   // Undo input contains errors.
222   auto Err10 = Interp->Parse("int y = ;");
223   EXPECT_FALSE(!!Err10);
224   EXPECT_EQ("Parsing failed.", llvm::toString(Err10.takeError()));
225   auto Err11 = Interp->Parse("int y = 42;");
226   EXPECT_TRUE(!!Err11);
227   auto Err12 = Interp->Undo();
228   EXPECT_FALSE(Err12);
229 }
230 
231 static std::string MangleName(NamedDecl *ND) {
232   ASTContext &C = ND->getASTContext();
233   std::unique_ptr<MangleContext> MangleC(C.createMangleContext());
234   std::string mangledName;
235   llvm::raw_string_ostream RawStr(mangledName);
236   MangleC->mangleName(ND, RawStr);
237   return RawStr.str();
238 }
239 
240 #ifdef CLANG_INTERPRETER_NO_SUPPORT_EXEC
241 TEST(InterpreterTest, DISABLED_FindMangledNameSymbol) {
242 #else
243 TEST(InterpreterTest, FindMangledNameSymbol) {
244 #endif
245   if (!HostSupportsJit())
246     GTEST_SKIP();
247 
248   std::unique_ptr<Interpreter> Interp = createInterpreter();
249 
250   auto &PTU(cantFail(Interp->Parse("int f(const char*) {return 0;}")));
251   EXPECT_EQ(1U, DeclsSize(PTU.TUPart));
252   auto R1DeclRange = PTU.TUPart->decls();
253 
254   NamedDecl *FD = cast<FunctionDecl>(*R1DeclRange.begin());
255   // Lower the PTU
256   if (llvm::Error Err = Interp->Execute(PTU)) {
257     // We cannot execute on the platform.
258     consumeError(std::move(Err));
259     return;
260   }
261 
262   std::string MangledName = MangleName(FD);
263   auto Addr = Interp->getSymbolAddress(MangledName);
264   EXPECT_FALSE(!Addr);
265   EXPECT_NE(0U, Addr->getValue());
266   GlobalDecl GD(FD);
267   EXPECT_EQ(*Addr, cantFail(Interp->getSymbolAddress(GD)));
268   cantFail(
269       Interp->ParseAndExecute("extern \"C\" int printf(const char*,...);"));
270   Addr = Interp->getSymbolAddress("printf");
271   EXPECT_FALSE(!Addr);
272 
273   // FIXME: Re-enable when we investigate the way we handle dllimports on Win.
274 #ifndef _WIN32
275   EXPECT_EQ((uintptr_t)&printf, Addr->getValue());
276 #endif // _WIN32
277 }
278 
279 static Value AllocateObject(TypeDecl *TD, Interpreter &Interp) {
280   std::string Name = TD->getQualifiedNameAsString();
281   Value Addr;
282   // FIXME: Consider providing an option in clang::Value to take ownership of
283   // the memory created from the interpreter.
284   // cantFail(Interp.ParseAndExecute("new " + Name + "()", &Addr));
285 
286   // The lifetime of the temporary is extended by the clang::Value.
287   cantFail(Interp.ParseAndExecute(Name + "()", &Addr));
288   return Addr;
289 }
290 
291 static NamedDecl *LookupSingleName(Interpreter &Interp, const char *Name) {
292   Sema &SemaRef = Interp.getCompilerInstance()->getSema();
293   ASTContext &C = SemaRef.getASTContext();
294   DeclarationName DeclName = &C.Idents.get(Name);
295   LookupResult R(SemaRef, DeclName, SourceLocation(), Sema::LookupOrdinaryName);
296   SemaRef.LookupName(R, SemaRef.TUScope);
297   assert(!R.empty());
298   return R.getFoundDecl();
299 }
300 
301 #ifdef CLANG_INTERPRETER_NO_SUPPORT_EXEC
302 TEST(InterpreterTest, DISABLED_InstantiateTemplate) {
303 #else
304 TEST(InterpreterTest, InstantiateTemplate) {
305 #endif
306   if (!HostSupportsJit())
307     GTEST_SKIP();
308 
309   // FIXME: We cannot yet handle delayed template parsing. If we run with
310   // -fdelayed-template-parsing we try adding the newly created decl to the
311   // active PTU which causes an assert.
312   std::vector<const char *> Args = {"-fno-delayed-template-parsing"};
313   std::unique_ptr<Interpreter> Interp = createInterpreter(Args);
314 
315   llvm::cantFail(Interp->Parse("extern \"C\" int printf(const char*,...);"
316                                "class A {};"
317                                "struct B {"
318                                "  template<typename T>"
319                                "  static int callme(T) { return 42; }"
320                                "};"));
321   auto &PTU = llvm::cantFail(Interp->Parse("auto _t = &B::callme<A*>;"));
322   auto PTUDeclRange = PTU.TUPart->decls();
323   EXPECT_EQ(1, std::distance(PTUDeclRange.begin(), PTUDeclRange.end()));
324 
325   // Lower the PTU
326   if (llvm::Error Err = Interp->Execute(PTU)) {
327     // We cannot execute on the platform.
328     consumeError(std::move(Err));
329     return;
330   }
331 
332   TypeDecl *TD = cast<TypeDecl>(LookupSingleName(*Interp, "A"));
333   Value NewA = AllocateObject(TD, *Interp);
334 
335   // Find back the template specialization
336   VarDecl *VD = static_cast<VarDecl *>(*PTUDeclRange.begin());
337   UnaryOperator *UO = llvm::cast<UnaryOperator>(VD->getInit());
338   NamedDecl *TmpltSpec = llvm::cast<DeclRefExpr>(UO->getSubExpr())->getDecl();
339 
340   std::string MangledName = MangleName(TmpltSpec);
341   typedef int (*TemplateSpecFn)(void *);
342   auto fn =
343       cantFail(Interp->getSymbolAddress(MangledName)).toPtr<TemplateSpecFn>();
344   EXPECT_EQ(42, fn(NewA.getPtr()));
345 }
346 
347 #ifdef CLANG_INTERPRETER_NO_SUPPORT_EXEC
348 TEST(InterpreterTest, DISABLED_Value) {
349 #else
350 TEST(InterpreterTest, Value) {
351 #endif
352   // We cannot execute on the platform.
353   if (!HostSupportsJit())
354     GTEST_SKIP();
355 
356   std::unique_ptr<Interpreter> Interp = createInterpreter();
357 
358   Value V1;
359   llvm::cantFail(Interp->ParseAndExecute("int x = 42;"));
360   llvm::cantFail(Interp->ParseAndExecute("x", &V1));
361   EXPECT_TRUE(V1.isValid());
362   EXPECT_TRUE(V1.hasValue());
363   EXPECT_EQ(V1.getInt(), 42);
364   EXPECT_EQ(V1.convertTo<int>(), 42);
365   EXPECT_TRUE(V1.getType()->isIntegerType());
366   EXPECT_EQ(V1.getKind(), Value::K_Int);
367   EXPECT_FALSE(V1.isManuallyAlloc());
368 
369   Value V1b;
370   llvm::cantFail(Interp->ParseAndExecute("char c = 42;"));
371   llvm::cantFail(Interp->ParseAndExecute("c", &V1b));
372   EXPECT_TRUE(V1b.getKind() == Value::K_Char_S ||
373               V1b.getKind() == Value::K_Char_U);
374 
375   Value V2;
376   llvm::cantFail(Interp->ParseAndExecute("double y = 3.14;"));
377   llvm::cantFail(Interp->ParseAndExecute("y", &V2));
378   EXPECT_TRUE(V2.isValid());
379   EXPECT_TRUE(V2.hasValue());
380   EXPECT_EQ(V2.getDouble(), 3.14);
381   EXPECT_EQ(V2.convertTo<double>(), 3.14);
382   EXPECT_TRUE(V2.getType()->isFloatingType());
383   EXPECT_EQ(V2.getKind(), Value::K_Double);
384   EXPECT_FALSE(V2.isManuallyAlloc());
385 
386   Value V3;
387   llvm::cantFail(Interp->ParseAndExecute(
388       "struct S { int* p; S() { p = new int(42); } ~S() { delete p; }};"));
389   llvm::cantFail(Interp->ParseAndExecute("S{}", &V3));
390   EXPECT_TRUE(V3.isValid());
391   EXPECT_TRUE(V3.hasValue());
392   EXPECT_TRUE(V3.getType()->isRecordType());
393   EXPECT_EQ(V3.getKind(), Value::K_PtrOrObj);
394   EXPECT_TRUE(V3.isManuallyAlloc());
395 
396   Value V4;
397   llvm::cantFail(Interp->ParseAndExecute("int getGlobal();"));
398   llvm::cantFail(Interp->ParseAndExecute("void setGlobal(int);"));
399   llvm::cantFail(Interp->ParseAndExecute("getGlobal()", &V4));
400   EXPECT_EQ(V4.getInt(), 42);
401   EXPECT_TRUE(V4.getType()->isIntegerType());
402 
403   Value V5;
404   // Change the global from the compiled code.
405   setGlobal(43);
406   llvm::cantFail(Interp->ParseAndExecute("getGlobal()", &V5));
407   EXPECT_EQ(V5.getInt(), 43);
408   EXPECT_TRUE(V5.getType()->isIntegerType());
409 
410   // Change the global from the interpreted code.
411   llvm::cantFail(Interp->ParseAndExecute("setGlobal(44);"));
412   EXPECT_EQ(getGlobal(), 44);
413 
414   Value V6;
415   llvm::cantFail(Interp->ParseAndExecute("void foo() {}"));
416   llvm::cantFail(Interp->ParseAndExecute("foo()", &V6));
417   EXPECT_TRUE(V6.isValid());
418   EXPECT_FALSE(V6.hasValue());
419   EXPECT_TRUE(V6.getType()->isVoidType());
420   EXPECT_EQ(V6.getKind(), Value::K_Void);
421   EXPECT_FALSE(V2.isManuallyAlloc());
422 
423   Value V7;
424   llvm::cantFail(Interp->ParseAndExecute("foo", &V7));
425   EXPECT_TRUE(V7.isValid());
426   EXPECT_TRUE(V7.hasValue());
427   EXPECT_TRUE(V7.getType()->isFunctionProtoType());
428   EXPECT_EQ(V7.getKind(), Value::K_PtrOrObj);
429   EXPECT_FALSE(V7.isManuallyAlloc());
430 
431   Value V8;
432   llvm::cantFail(Interp->ParseAndExecute("struct SS{ void f() {} };"));
433   llvm::cantFail(Interp->ParseAndExecute("&SS::f", &V8));
434   EXPECT_TRUE(V8.isValid());
435   EXPECT_TRUE(V8.hasValue());
436   EXPECT_TRUE(V8.getType()->isMemberFunctionPointerType());
437   EXPECT_EQ(V8.getKind(), Value::K_PtrOrObj);
438   EXPECT_TRUE(V8.isManuallyAlloc());
439 
440   Value V9;
441   llvm::cantFail(Interp->ParseAndExecute("struct A { virtual int f(); };"));
442   llvm::cantFail(
443       Interp->ParseAndExecute("struct B : A { int f() { return 42; }};"));
444   llvm::cantFail(Interp->ParseAndExecute("int (B::*ptr)() = &B::f;"));
445   llvm::cantFail(Interp->ParseAndExecute("ptr", &V9));
446   EXPECT_TRUE(V9.isValid());
447   EXPECT_TRUE(V9.hasValue());
448   EXPECT_TRUE(V9.getType()->isMemberFunctionPointerType());
449   EXPECT_EQ(V9.getKind(), Value::K_PtrOrObj);
450   EXPECT_TRUE(V9.isManuallyAlloc());
451 }
452 } // end anonymous namespace
453