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