1 //===- unittests/Interpreter/InterpreterTest.cpp --- Interpreter tests ----===//
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
7 //===----------------------------------------------------------------------===//
9 // Unit tests for Clang's Interpreter library.
11 //===----------------------------------------------------------------------===//
13 #include "InterpreterTestFixture.h"
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/Interpreter.h"
21 #include "clang/Interpreter/Value.h"
22 #include "clang/Sema/Lookup.h"
23 #include "clang/Sema/Sema.h"
25 #include "gmock/gmock.h"
26 #include "gtest/gtest.h"
28 using namespace clang
;
31 // JIT reports symbol not found on Windows without the visibility attribute.
32 REPL_EXTERNAL_VISIBILITY
int getGlobal() { return Global
; }
33 REPL_EXTERNAL_VISIBILITY
void setGlobal(int val
) { Global
= val
; }
37 class InterpreterTest
: public InterpreterTestBase
{
38 // TODO: Collect common variables and utility functions here
41 using Args
= std::vector
<const char *>;
42 static std::unique_ptr
<Interpreter
>
43 createInterpreter(const Args
&ExtraArgs
= {},
44 DiagnosticConsumer
*Client
= nullptr) {
45 Args ClangArgs
= {"-Xclang", "-emit-llvm-only"};
46 ClangArgs
.insert(ClangArgs
.end(), ExtraArgs
.begin(), ExtraArgs
.end());
47 auto CB
= clang::IncrementalCompilerBuilder();
48 CB
.SetCompilerArgs(ClangArgs
);
49 auto CI
= cantFail(CB
.CreateCpp());
51 CI
->getDiagnostics().setClient(Client
, /*ShouldOwnClient=*/false);
52 return cantFail(clang::Interpreter::create(std::move(CI
)));
55 static size_t DeclsSize(TranslationUnitDecl
*PTUDecl
) {
56 return std::distance(PTUDecl
->decls().begin(), PTUDecl
->decls().end());
59 TEST_F(InterpreterTest
, Sanity
) {
60 std::unique_ptr
<Interpreter
> Interp
= createInterpreter();
62 using PTU
= PartialTranslationUnit
;
64 PTU
&R1(cantFail(Interp
->Parse("void g(); void g() {}")));
65 EXPECT_EQ(2U, DeclsSize(R1
.TUPart
));
67 PTU
&R2(cantFail(Interp
->Parse("int i;")));
68 EXPECT_EQ(1U, DeclsSize(R2
.TUPart
));
71 static std::string
DeclToString(Decl
*D
) {
72 return llvm::cast
<NamedDecl
>(D
)->getQualifiedNameAsString();
75 TEST_F(InterpreterTest
, IncrementalInputTopLevelDecls
) {
76 std::unique_ptr
<Interpreter
> Interp
= createInterpreter();
77 auto R1
= Interp
->Parse("int var1 = 42; int f() { return var1; }");
78 // gtest doesn't expand into explicit bool conversions.
80 auto R1DeclRange
= R1
->TUPart
->decls();
81 EXPECT_EQ(2U, DeclsSize(R1
->TUPart
));
82 EXPECT_EQ("var1", DeclToString(*R1DeclRange
.begin()));
83 EXPECT_EQ("f", DeclToString(*(++R1DeclRange
.begin())));
85 auto R2
= Interp
->Parse("int var2 = f();");
87 auto R2DeclRange
= R2
->TUPart
->decls();
88 EXPECT_EQ(1U, DeclsSize(R2
->TUPart
));
89 EXPECT_EQ("var2", DeclToString(*R2DeclRange
.begin()));
92 TEST_F(InterpreterTest
, Errors
) {
93 Args ExtraArgs
= {"-Xclang", "-diagnostic-log-file", "-Xclang", "-"};
95 // Create the diagnostic engine with unowned consumer.
96 std::string DiagnosticOutput
;
97 llvm::raw_string_ostream
DiagnosticsOS(DiagnosticOutput
);
98 auto DiagPrinter
= std::make_unique
<TextDiagnosticPrinter
>(
99 DiagnosticsOS
, new DiagnosticOptions());
101 auto Interp
= createInterpreter(ExtraArgs
, DiagPrinter
.get());
102 auto Err
= Interp
->Parse("intentional_error v1 = 42; ").takeError();
103 using ::testing::HasSubstr
;
104 EXPECT_THAT(DiagnosticOutput
,
105 HasSubstr("error: unknown type name 'intentional_error'"));
106 EXPECT_EQ("Parsing failed.", llvm::toString(std::move(Err
)));
108 auto RecoverErr
= Interp
->Parse("int var1 = 42;");
109 EXPECT_TRUE(!!RecoverErr
);
112 // Here we test whether the user can mix declarations and statements. The
113 // interpreter should be smart enough to recognize the declarations from the
114 // statements and wrap the latter into a declaration, producing valid code.
116 TEST_F(InterpreterTest
, DeclsAndStatements
) {
117 Args ExtraArgs
= {"-Xclang", "-diagnostic-log-file", "-Xclang", "-"};
119 // Create the diagnostic engine with unowned consumer.
120 std::string DiagnosticOutput
;
121 llvm::raw_string_ostream
DiagnosticsOS(DiagnosticOutput
);
122 auto DiagPrinter
= std::make_unique
<TextDiagnosticPrinter
>(
123 DiagnosticsOS
, new DiagnosticOptions());
125 auto Interp
= createInterpreter(ExtraArgs
, DiagPrinter
.get());
126 auto R1
= Interp
->Parse(
127 "int var1 = 42; extern \"C\" int printf(const char*, ...);");
128 // gtest doesn't expand into explicit bool conversions.
131 auto *PTU1
= R1
->TUPart
;
132 EXPECT_EQ(2U, DeclsSize(PTU1
));
134 auto R2
= Interp
->Parse("var1++; printf(\"var1 value %d\\n\", var1);");
138 TEST_F(InterpreterTest
, UndoCommand
) {
139 Args ExtraArgs
= {"-Xclang", "-diagnostic-log-file", "-Xclang", "-"};
141 // Create the diagnostic engine with unowned consumer.
142 std::string DiagnosticOutput
;
143 llvm::raw_string_ostream
DiagnosticsOS(DiagnosticOutput
);
144 auto DiagPrinter
= std::make_unique
<TextDiagnosticPrinter
>(
145 DiagnosticsOS
, new DiagnosticOptions());
147 auto Interp
= createInterpreter(ExtraArgs
, DiagPrinter
.get());
150 auto Err1
= Interp
->Undo();
151 EXPECT_EQ("Operation failed. Too many undos",
152 llvm::toString(std::move(Err1
)));
153 auto Err2
= Interp
->Parse("int foo = 42;");
155 auto Err3
= Interp
->Undo(2);
156 EXPECT_EQ("Operation failed. Too many undos",
157 llvm::toString(std::move(Err3
)));
160 auto Err4
= Interp
->Parse("int x = 42;");
162 auto Err5
= Interp
->Undo();
164 auto Err6
= Interp
->Parse("int x = 24;");
166 auto Err7
= Interp
->Parse("#define X 42");
168 auto Err8
= Interp
->Undo();
170 auto Err9
= Interp
->Parse("#define X 24");
173 // Undo input contains errors.
174 auto Err10
= Interp
->Parse("int y = ;");
175 EXPECT_FALSE(!!Err10
);
176 EXPECT_EQ("Parsing failed.", llvm::toString(Err10
.takeError()));
177 auto Err11
= Interp
->Parse("int y = 42;");
178 EXPECT_TRUE(!!Err11
);
179 auto Err12
= Interp
->Undo();
183 static std::string
MangleName(NamedDecl
*ND
) {
184 ASTContext
&C
= ND
->getASTContext();
185 std::unique_ptr
<MangleContext
> MangleC(C
.createMangleContext());
186 std::string mangledName
;
187 llvm::raw_string_ostream
RawStr(mangledName
);
188 MangleC
->mangleName(ND
, RawStr
);
192 TEST_F(InterpreterTest
, FindMangledNameSymbol
) {
193 std::unique_ptr
<Interpreter
> Interp
= createInterpreter();
195 auto &PTU(cantFail(Interp
->Parse("int f(const char*) {return 0;}")));
196 EXPECT_EQ(1U, DeclsSize(PTU
.TUPart
));
197 auto R1DeclRange
= PTU
.TUPart
->decls();
199 NamedDecl
*FD
= cast
<FunctionDecl
>(*R1DeclRange
.begin());
201 if (llvm::Error Err
= Interp
->Execute(PTU
)) {
202 // We cannot execute on the platform.
203 consumeError(std::move(Err
));
207 std::string MangledName
= MangleName(FD
);
208 auto Addr
= Interp
->getSymbolAddress(MangledName
);
210 EXPECT_NE(0U, Addr
->getValue());
212 EXPECT_EQ(*Addr
, cantFail(Interp
->getSymbolAddress(GD
)));
214 Interp
->ParseAndExecute("extern \"C\" int printf(const char*,...);"));
215 Addr
= Interp
->getSymbolAddress("printf");
218 // FIXME: Re-enable when we investigate the way we handle dllimports on Win.
220 EXPECT_EQ((uintptr_t)&printf
, Addr
->getValue());
224 static Value
AllocateObject(TypeDecl
*TD
, Interpreter
&Interp
) {
225 std::string Name
= TD
->getQualifiedNameAsString();
227 // FIXME: Consider providing an option in clang::Value to take ownership of
228 // the memory created from the interpreter.
229 // cantFail(Interp.ParseAndExecute("new " + Name + "()", &Addr));
231 // The lifetime of the temporary is extended by the clang::Value.
232 cantFail(Interp
.ParseAndExecute(Name
+ "()", &Addr
));
236 static NamedDecl
*LookupSingleName(Interpreter
&Interp
, const char *Name
) {
237 Sema
&SemaRef
= Interp
.getCompilerInstance()->getSema();
238 ASTContext
&C
= SemaRef
.getASTContext();
239 DeclarationName DeclName
= &C
.Idents
.get(Name
);
240 LookupResult
R(SemaRef
, DeclName
, SourceLocation(), Sema::LookupOrdinaryName
);
241 SemaRef
.LookupName(R
, SemaRef
.TUScope
);
243 return R
.getFoundDecl();
246 TEST_F(InterpreterTest
, InstantiateTemplate
) {
247 // FIXME: We cannot yet handle delayed template parsing. If we run with
248 // -fdelayed-template-parsing we try adding the newly created decl to the
249 // active PTU which causes an assert.
250 std::vector
<const char *> Args
= {"-fno-delayed-template-parsing"};
251 std::unique_ptr
<Interpreter
> Interp
= createInterpreter(Args
);
253 llvm::cantFail(Interp
->Parse("extern \"C\" int printf(const char*,...);"
256 " template<typename T>"
257 " static int callme(T) { return 42; }"
259 auto &PTU
= llvm::cantFail(Interp
->Parse("auto _t = &B::callme<A*>;"));
260 auto PTUDeclRange
= PTU
.TUPart
->decls();
261 EXPECT_EQ(1, std::distance(PTUDeclRange
.begin(), PTUDeclRange
.end()));
264 if (llvm::Error Err
= Interp
->Execute(PTU
)) {
265 // We cannot execute on the platform.
266 consumeError(std::move(Err
));
270 TypeDecl
*TD
= cast
<TypeDecl
>(LookupSingleName(*Interp
, "A"));
271 Value NewA
= AllocateObject(TD
, *Interp
);
273 // Find back the template specialization
274 VarDecl
*VD
= static_cast<VarDecl
*>(*PTUDeclRange
.begin());
275 UnaryOperator
*UO
= llvm::cast
<UnaryOperator
>(VD
->getInit());
276 NamedDecl
*TmpltSpec
= llvm::cast
<DeclRefExpr
>(UO
->getSubExpr())->getDecl();
278 std::string MangledName
= MangleName(TmpltSpec
);
279 typedef int (*TemplateSpecFn
)(void *);
281 cantFail(Interp
->getSymbolAddress(MangledName
)).toPtr
<TemplateSpecFn
>();
282 EXPECT_EQ(42, fn(NewA
.getPtr()));
285 TEST_F(InterpreterTest
, Value
) {
286 std::vector
<const char *> Args
= {"-fno-sized-deallocation"};
287 std::unique_ptr
<Interpreter
> Interp
= createInterpreter(Args
);
290 llvm::cantFail(Interp
->ParseAndExecute("int x = 42;"));
291 llvm::cantFail(Interp
->ParseAndExecute("x", &V1
));
292 EXPECT_TRUE(V1
.isValid());
293 EXPECT_TRUE(V1
.hasValue());
294 EXPECT_EQ(V1
.getInt(), 42);
295 EXPECT_EQ(V1
.convertTo
<int>(), 42);
296 EXPECT_TRUE(V1
.getType()->isIntegerType());
297 EXPECT_EQ(V1
.getKind(), Value::K_Int
);
298 EXPECT_FALSE(V1
.isManuallyAlloc());
301 llvm::cantFail(Interp
->ParseAndExecute("char c = 42;"));
302 llvm::cantFail(Interp
->ParseAndExecute("c", &V1b
));
303 EXPECT_TRUE(V1b
.getKind() == Value::K_Char_S
||
304 V1b
.getKind() == Value::K_Char_U
);
307 llvm::cantFail(Interp
->ParseAndExecute("double y = 3.14;"));
308 llvm::cantFail(Interp
->ParseAndExecute("y", &V2
));
309 EXPECT_TRUE(V2
.isValid());
310 EXPECT_TRUE(V2
.hasValue());
311 EXPECT_EQ(V2
.getDouble(), 3.14);
312 EXPECT_EQ(V2
.convertTo
<double>(), 3.14);
313 EXPECT_TRUE(V2
.getType()->isFloatingType());
314 EXPECT_EQ(V2
.getKind(), Value::K_Double
);
315 EXPECT_FALSE(V2
.isManuallyAlloc());
318 llvm::cantFail(Interp
->ParseAndExecute(
319 "struct S { int* p; S() { p = new int(42); } ~S() { delete p; }};"));
320 llvm::cantFail(Interp
->ParseAndExecute("S{}", &V3
));
321 EXPECT_TRUE(V3
.isValid());
322 EXPECT_TRUE(V3
.hasValue());
323 EXPECT_TRUE(V3
.getType()->isRecordType());
324 EXPECT_EQ(V3
.getKind(), Value::K_PtrOrObj
);
325 EXPECT_TRUE(V3
.isManuallyAlloc());
328 llvm::cantFail(Interp
->ParseAndExecute("int getGlobal();"));
329 llvm::cantFail(Interp
->ParseAndExecute("void setGlobal(int);"));
330 llvm::cantFail(Interp
->ParseAndExecute("getGlobal()", &V4
));
331 EXPECT_EQ(V4
.getInt(), 42);
332 EXPECT_TRUE(V4
.getType()->isIntegerType());
335 // Change the global from the compiled code.
337 llvm::cantFail(Interp
->ParseAndExecute("getGlobal()", &V5
));
338 EXPECT_EQ(V5
.getInt(), 43);
339 EXPECT_TRUE(V5
.getType()->isIntegerType());
341 // Change the global from the interpreted code.
342 llvm::cantFail(Interp
->ParseAndExecute("setGlobal(44);"));
343 EXPECT_EQ(getGlobal(), 44);
346 llvm::cantFail(Interp
->ParseAndExecute("void foo() {}"));
347 llvm::cantFail(Interp
->ParseAndExecute("foo()", &V6
));
348 EXPECT_TRUE(V6
.isValid());
349 EXPECT_FALSE(V6
.hasValue());
350 EXPECT_TRUE(V6
.getType()->isVoidType());
351 EXPECT_EQ(V6
.getKind(), Value::K_Void
);
352 EXPECT_FALSE(V2
.isManuallyAlloc());
355 llvm::cantFail(Interp
->ParseAndExecute("foo", &V7
));
356 EXPECT_TRUE(V7
.isValid());
357 EXPECT_TRUE(V7
.hasValue());
358 EXPECT_TRUE(V7
.getType()->isFunctionProtoType());
359 EXPECT_EQ(V7
.getKind(), Value::K_PtrOrObj
);
360 EXPECT_FALSE(V7
.isManuallyAlloc());
363 llvm::cantFail(Interp
->ParseAndExecute("struct SS{ void f() {} };"));
364 llvm::cantFail(Interp
->ParseAndExecute("&SS::f", &V8
));
365 EXPECT_TRUE(V8
.isValid());
366 EXPECT_TRUE(V8
.hasValue());
367 EXPECT_TRUE(V8
.getType()->isMemberFunctionPointerType());
368 EXPECT_EQ(V8
.getKind(), Value::K_PtrOrObj
);
369 EXPECT_TRUE(V8
.isManuallyAlloc());
372 llvm::cantFail(Interp
->ParseAndExecute("struct A { virtual int f(); };"));
374 Interp
->ParseAndExecute("struct B : A { int f() { return 42; }};"));
375 llvm::cantFail(Interp
->ParseAndExecute("int (B::*ptr)() = &B::f;"));
376 llvm::cantFail(Interp
->ParseAndExecute("ptr", &V9
));
377 EXPECT_TRUE(V9
.isValid());
378 EXPECT_TRUE(V9
.hasValue());
379 EXPECT_TRUE(V9
.getType()->isMemberFunctionPointerType());
380 EXPECT_EQ(V9
.getKind(), Value::K_PtrOrObj
);
381 EXPECT_TRUE(V9
.isManuallyAlloc());
384 TEST_F(InterpreterTest
, TranslationUnit_CanonicalDecl
) {
385 std::vector
<const char *> Args
;
386 std::unique_ptr
<Interpreter
> Interp
= createInterpreter(Args
);
388 Sema
&sema
= Interp
->getCompilerInstance()->getSema();
390 llvm::cantFail(Interp
->ParseAndExecute("int x = 42;"));
392 TranslationUnitDecl
*TU
=
393 sema
.getASTContext().getTranslationUnitDecl()->getCanonicalDecl();
395 llvm::cantFail(Interp
->ParseAndExecute("long y = 84;"));
398 sema
.getASTContext().getTranslationUnitDecl()->getCanonicalDecl());
400 llvm::cantFail(Interp
->ParseAndExecute("char z = 'z';"));
403 sema
.getASTContext().getTranslationUnitDecl()->getCanonicalDecl());
406 } // end anonymous namespace