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 "InterpreterTestFixture.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/Interpreter.h" 21 #include "clang/Interpreter/Value.h" 22 #include "clang/Sema/Lookup.h" 23 #include "clang/Sema/Sema.h" 24 25 #include "gmock/gmock.h" 26 #include "gtest/gtest.h" 27 28 using namespace clang; 29 30 int Global = 42; 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; } 34 35 namespace { 36 37 class InterpreterTest : public InterpreterTestBase { 38 // TODO: Collect common variables and utility functions here 39 }; 40 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()); 50 if (Client) 51 CI->getDiagnostics().setClient(Client, /*ShouldOwnClient=*/false); 52 return cantFail(clang::Interpreter::create(std::move(CI))); 53 } 54 55 static size_t DeclsSize(TranslationUnitDecl *PTUDecl) { 56 return std::distance(PTUDecl->decls().begin(), PTUDecl->decls().end()); 57 } 58 59 TEST_F(InterpreterTest, Sanity) { 60 std::unique_ptr<Interpreter> Interp = createInterpreter(); 61 62 using PTU = PartialTranslationUnit; 63 64 PTU &R1(cantFail(Interp->Parse("void g(); void g() {}"))); 65 EXPECT_EQ(2U, DeclsSize(R1.TUPart)); 66 67 PTU &R2(cantFail(Interp->Parse("int i;"))); 68 EXPECT_EQ(1U, DeclsSize(R2.TUPart)); 69 } 70 71 static std::string DeclToString(Decl *D) { 72 return llvm::cast<NamedDecl>(D)->getQualifiedNameAsString(); 73 } 74 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. 79 EXPECT_TRUE(!!R1); 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()))); 84 85 auto R2 = Interp->Parse("int var2 = f();"); 86 EXPECT_TRUE(!!R2); 87 auto R2DeclRange = R2->TUPart->decls(); 88 EXPECT_EQ(1U, DeclsSize(R2->TUPart)); 89 EXPECT_EQ("var2", DeclToString(*R2DeclRange.begin())); 90 } 91 92 TEST_F(InterpreterTest, Errors) { 93 Args ExtraArgs = {"-Xclang", "-diagnostic-log-file", "-Xclang", "-"}; 94 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()); 100 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))); 107 108 auto RecoverErr = Interp->Parse("int var1 = 42;"); 109 EXPECT_TRUE(!!RecoverErr); 110 } 111 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. 115 116 TEST_F(InterpreterTest, DeclsAndStatements) { 117 Args ExtraArgs = {"-Xclang", "-diagnostic-log-file", "-Xclang", "-"}; 118 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()); 124 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. 129 EXPECT_TRUE(!!R1); 130 131 auto *PTU1 = R1->TUPart; 132 EXPECT_EQ(2U, DeclsSize(PTU1)); 133 134 auto R2 = Interp->Parse("var1++; printf(\"var1 value %d\\n\", var1);"); 135 EXPECT_TRUE(!!R2); 136 } 137 138 TEST_F(InterpreterTest, UndoCommand) { 139 Args ExtraArgs = {"-Xclang", "-diagnostic-log-file", "-Xclang", "-"}; 140 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()); 146 147 auto Interp = createInterpreter(ExtraArgs, DiagPrinter.get()); 148 149 // Fail to undo. 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;"); 154 EXPECT_TRUE(!!Err2); 155 auto Err3 = Interp->Undo(2); 156 EXPECT_EQ("Operation failed. Too many undos", 157 llvm::toString(std::move(Err3))); 158 159 // Succeed to undo. 160 auto Err4 = Interp->Parse("int x = 42;"); 161 EXPECT_TRUE(!!Err4); 162 auto Err5 = Interp->Undo(); 163 EXPECT_FALSE(Err5); 164 auto Err6 = Interp->Parse("int x = 24;"); 165 EXPECT_TRUE(!!Err6); 166 auto Err7 = Interp->Parse("#define X 42"); 167 EXPECT_TRUE(!!Err7); 168 auto Err8 = Interp->Undo(); 169 EXPECT_FALSE(Err8); 170 auto Err9 = Interp->Parse("#define X 24"); 171 EXPECT_TRUE(!!Err9); 172 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(); 180 EXPECT_FALSE(Err12); 181 } 182 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); 189 return mangledName; 190 } 191 192 TEST_F(InterpreterTest, FindMangledNameSymbol) { 193 std::unique_ptr<Interpreter> Interp = createInterpreter(); 194 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(); 198 199 NamedDecl *FD = cast<FunctionDecl>(*R1DeclRange.begin()); 200 // Lower the PTU 201 if (llvm::Error Err = Interp->Execute(PTU)) { 202 // We cannot execute on the platform. 203 consumeError(std::move(Err)); 204 return; 205 } 206 207 std::string MangledName = MangleName(FD); 208 auto Addr = Interp->getSymbolAddress(MangledName); 209 EXPECT_FALSE(!Addr); 210 EXPECT_NE(0U, Addr->getValue()); 211 GlobalDecl GD(FD); 212 EXPECT_EQ(*Addr, cantFail(Interp->getSymbolAddress(GD))); 213 cantFail( 214 Interp->ParseAndExecute("extern \"C\" int printf(const char*,...);")); 215 Addr = Interp->getSymbolAddress("printf"); 216 EXPECT_FALSE(!Addr); 217 218 // FIXME: Re-enable when we investigate the way we handle dllimports on Win. 219 #ifndef _WIN32 220 EXPECT_EQ((uintptr_t)&printf, Addr->getValue()); 221 #endif // _WIN32 222 } 223 224 static Value AllocateObject(TypeDecl *TD, Interpreter &Interp) { 225 std::string Name = TD->getQualifiedNameAsString(); 226 Value Addr; 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)); 230 231 // The lifetime of the temporary is extended by the clang::Value. 232 cantFail(Interp.ParseAndExecute(Name + "()", &Addr)); 233 return Addr; 234 } 235 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); 242 assert(!R.empty()); 243 return R.getFoundDecl(); 244 } 245 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); 252 253 llvm::cantFail(Interp->Parse("extern \"C\" int printf(const char*,...);" 254 "class A {};" 255 "struct B {" 256 " template<typename T>" 257 " static int callme(T) { return 42; }" 258 "};")); 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())); 262 263 // Lower the PTU 264 if (llvm::Error Err = Interp->Execute(PTU)) { 265 // We cannot execute on the platform. 266 consumeError(std::move(Err)); 267 return; 268 } 269 270 TypeDecl *TD = cast<TypeDecl>(LookupSingleName(*Interp, "A")); 271 Value NewA = AllocateObject(TD, *Interp); 272 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(); 277 278 std::string MangledName = MangleName(TmpltSpec); 279 typedef int (*TemplateSpecFn)(void *); 280 auto fn = 281 cantFail(Interp->getSymbolAddress(MangledName)).toPtr<TemplateSpecFn>(); 282 EXPECT_EQ(42, fn(NewA.getPtr())); 283 } 284 285 TEST_F(InterpreterTest, Value) { 286 std::vector<const char *> Args = {"-fno-sized-deallocation"}; 287 std::unique_ptr<Interpreter> Interp = createInterpreter(Args); 288 289 Value V1; 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()); 299 300 Value V1b; 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); 305 306 Value V2; 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()); 316 317 Value V3; 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()); 326 327 Value V4; 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()); 333 334 Value V5; 335 // Change the global from the compiled code. 336 setGlobal(43); 337 llvm::cantFail(Interp->ParseAndExecute("getGlobal()", &V5)); 338 EXPECT_EQ(V5.getInt(), 43); 339 EXPECT_TRUE(V5.getType()->isIntegerType()); 340 341 // Change the global from the interpreted code. 342 llvm::cantFail(Interp->ParseAndExecute("setGlobal(44);")); 343 EXPECT_EQ(getGlobal(), 44); 344 345 Value V6; 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()); 353 354 Value V7; 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()); 361 362 Value V8; 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()); 370 371 Value V9; 372 llvm::cantFail(Interp->ParseAndExecute("struct A { virtual int f(); };")); 373 llvm::cantFail( 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()); 382 } 383 384 TEST_F(InterpreterTest, TranslationUnit_CanonicalDecl) { 385 std::vector<const char *> Args; 386 std::unique_ptr<Interpreter> Interp = createInterpreter(Args); 387 388 Sema &sema = Interp->getCompilerInstance()->getSema(); 389 390 llvm::cantFail(Interp->ParseAndExecute("int x = 42;")); 391 392 TranslationUnitDecl *TU = 393 sema.getASTContext().getTranslationUnitDecl()->getCanonicalDecl(); 394 395 llvm::cantFail(Interp->ParseAndExecute("long y = 84;")); 396 397 EXPECT_EQ(TU, 398 sema.getASTContext().getTranslationUnitDecl()->getCanonicalDecl()); 399 400 llvm::cantFail(Interp->ParseAndExecute("char z = 'z';")); 401 402 EXPECT_EQ(TU, 403 sema.getASTContext().getTranslationUnitDecl()->getCanonicalDecl()); 404 } 405 406 } // end anonymous namespace 407