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