192f9852fSVassil Vassilev //===- unittests/Interpreter/InterpreterTest.cpp --- Interpreter tests ----===// 292f9852fSVassil Vassilev // 392f9852fSVassil Vassilev // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 492f9852fSVassil Vassilev // See https://llvm.org/LICENSE.txt for license information. 592f9852fSVassil Vassilev // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 692f9852fSVassil Vassilev // 792f9852fSVassil Vassilev //===----------------------------------------------------------------------===// 892f9852fSVassil Vassilev // 992f9852fSVassil Vassilev // Unit tests for Clang's Interpreter library. 1092f9852fSVassil Vassilev // 1192f9852fSVassil Vassilev //===----------------------------------------------------------------------===// 1292f9852fSVassil Vassilev 13a871470aSStefan Gränitz #include "InterpreterTestFixture.h" 14a871470aSStefan Gränitz 1592f9852fSVassil Vassilev #include "clang/AST/Decl.h" 1692f9852fSVassil Vassilev #include "clang/AST/DeclGroup.h" 174fb0805cSVassil Vassilev #include "clang/AST/Mangle.h" 1892f9852fSVassil Vassilev #include "clang/Frontend/CompilerInstance.h" 1992f9852fSVassil Vassilev #include "clang/Frontend/TextDiagnosticPrinter.h" 20647d2728SStefan Gränitz #include "clang/Interpreter/Interpreter.h" 215111286fSJun Zhang #include "clang/Interpreter/Value.h" 224fb0805cSVassil Vassilev #include "clang/Sema/Lookup.h" 234fb0805cSVassil Vassilev #include "clang/Sema/Sema.h" 244fb0805cSVassil Vassilev 2592f9852fSVassil Vassilev #include "gmock/gmock.h" 2692f9852fSVassil Vassilev #include "gtest/gtest.h" 2792f9852fSVassil Vassilev 2892f9852fSVassil Vassilev using namespace clang; 2992f9852fSVassil Vassilev 305111286fSJun Zhang int Global = 42; 315111286fSJun Zhang // JIT reports symbol not found on Windows without the visibility attribute. 325111286fSJun Zhang REPL_EXTERNAL_VISIBILITY int getGlobal() { return Global; } 335111286fSJun Zhang REPL_EXTERNAL_VISIBILITY void setGlobal(int val) { Global = val; } 345111286fSJun Zhang 3592f9852fSVassil Vassilev namespace { 36a871470aSStefan Gränitz 37a871470aSStefan Gränitz class InterpreterTest : public InterpreterTestBase { 38a871470aSStefan Gränitz // TODO: Collect common variables and utility functions here 39a871470aSStefan Gränitz }; 40a871470aSStefan Gränitz 4192f9852fSVassil Vassilev using Args = std::vector<const char *>; 4292f9852fSVassil Vassilev static std::unique_ptr<Interpreter> 4392f9852fSVassil Vassilev createInterpreter(const Args &ExtraArgs = {}, 4492f9852fSVassil Vassilev DiagnosticConsumer *Client = nullptr) { 4592f9852fSVassil Vassilev Args ClangArgs = {"-Xclang", "-emit-llvm-only"}; 4692f9852fSVassil Vassilev ClangArgs.insert(ClangArgs.end(), ExtraArgs.begin(), ExtraArgs.end()); 47ddeab07cSAnubhab Ghosh auto CB = clang::IncrementalCompilerBuilder(); 48ddeab07cSAnubhab Ghosh CB.SetCompilerArgs(ClangArgs); 49ddeab07cSAnubhab Ghosh auto CI = cantFail(CB.CreateCpp()); 5092f9852fSVassil Vassilev if (Client) 5192f9852fSVassil Vassilev CI->getDiagnostics().setClient(Client, /*ShouldOwnClient=*/false); 5292f9852fSVassil Vassilev return cantFail(clang::Interpreter::create(std::move(CI))); 5392f9852fSVassil Vassilev } 5492f9852fSVassil Vassilev 5511b47c10SVassil Vassilev static size_t DeclsSize(TranslationUnitDecl *PTUDecl) { 5611b47c10SVassil Vassilev return std::distance(PTUDecl->decls().begin(), PTUDecl->decls().end()); 576775fc6fSVassil Vassilev } 586775fc6fSVassil Vassilev 59a871470aSStefan Gränitz TEST_F(InterpreterTest, Sanity) { 6011b47c10SVassil Vassilev std::unique_ptr<Interpreter> Interp = createInterpreter(); 6111b47c10SVassil Vassilev 6211b47c10SVassil Vassilev using PTU = PartialTranslationUnit; 6311b47c10SVassil Vassilev 6411b47c10SVassil Vassilev PTU &R1(cantFail(Interp->Parse("void g(); void g() {}"))); 6511b47c10SVassil Vassilev EXPECT_EQ(2U, DeclsSize(R1.TUPart)); 6611b47c10SVassil Vassilev 6711b47c10SVassil Vassilev PTU &R2(cantFail(Interp->Parse("int i;"))); 6811b47c10SVassil Vassilev EXPECT_EQ(1U, DeclsSize(R2.TUPart)); 6911b47c10SVassil Vassilev } 7011b47c10SVassil Vassilev 7111b47c10SVassil Vassilev static std::string DeclToString(Decl *D) { 7211b47c10SVassil Vassilev return llvm::cast<NamedDecl>(D)->getQualifiedNameAsString(); 7392f9852fSVassil Vassilev } 7492f9852fSVassil Vassilev 75a871470aSStefan Gränitz TEST_F(InterpreterTest, IncrementalInputTopLevelDecls) { 7692f9852fSVassil Vassilev std::unique_ptr<Interpreter> Interp = createInterpreter(); 7711b47c10SVassil Vassilev auto R1 = Interp->Parse("int var1 = 42; int f() { return var1; }"); 7892f9852fSVassil Vassilev // gtest doesn't expand into explicit bool conversions. 7911b47c10SVassil Vassilev EXPECT_TRUE(!!R1); 8011b47c10SVassil Vassilev auto R1DeclRange = R1->TUPart->decls(); 8111b47c10SVassil Vassilev EXPECT_EQ(2U, DeclsSize(R1->TUPart)); 8211b47c10SVassil Vassilev EXPECT_EQ("var1", DeclToString(*R1DeclRange.begin())); 8311b47c10SVassil Vassilev EXPECT_EQ("f", DeclToString(*(++R1DeclRange.begin()))); 8492f9852fSVassil Vassilev 8511b47c10SVassil Vassilev auto R2 = Interp->Parse("int var2 = f();"); 8611b47c10SVassil Vassilev EXPECT_TRUE(!!R2); 8711b47c10SVassil Vassilev auto R2DeclRange = R2->TUPart->decls(); 8811b47c10SVassil Vassilev EXPECT_EQ(1U, DeclsSize(R2->TUPart)); 8911b47c10SVassil Vassilev EXPECT_EQ("var2", DeclToString(*R2DeclRange.begin())); 9092f9852fSVassil Vassilev } 9192f9852fSVassil Vassilev 92a871470aSStefan Gränitz TEST_F(InterpreterTest, Errors) { 9392f9852fSVassil Vassilev Args ExtraArgs = {"-Xclang", "-diagnostic-log-file", "-Xclang", "-"}; 9492f9852fSVassil Vassilev 9592f9852fSVassil Vassilev // Create the diagnostic engine with unowned consumer. 9692f9852fSVassil Vassilev std::string DiagnosticOutput; 9792f9852fSVassil Vassilev llvm::raw_string_ostream DiagnosticsOS(DiagnosticOutput); 9892f9852fSVassil Vassilev auto DiagPrinter = std::make_unique<TextDiagnosticPrinter>( 9992f9852fSVassil Vassilev DiagnosticsOS, new DiagnosticOptions()); 10092f9852fSVassil Vassilev 10192f9852fSVassil Vassilev auto Interp = createInterpreter(ExtraArgs, DiagPrinter.get()); 10292f9852fSVassil Vassilev auto Err = Interp->Parse("intentional_error v1 = 42; ").takeError(); 10392f9852fSVassil Vassilev using ::testing::HasSubstr; 104ac84ada9SYoungsuk Kim EXPECT_THAT(DiagnosticOutput, 10592f9852fSVassil Vassilev HasSubstr("error: unknown type name 'intentional_error'")); 10692f9852fSVassil Vassilev EXPECT_EQ("Parsing failed.", llvm::toString(std::move(Err))); 10792f9852fSVassil Vassilev 10811b47c10SVassil Vassilev auto RecoverErr = Interp->Parse("int var1 = 42;"); 10911b47c10SVassil Vassilev EXPECT_TRUE(!!RecoverErr); 11092f9852fSVassil Vassilev } 11192f9852fSVassil Vassilev 11292f9852fSVassil Vassilev // Here we test whether the user can mix declarations and statements. The 11392f9852fSVassil Vassilev // interpreter should be smart enough to recognize the declarations from the 11492f9852fSVassil Vassilev // statements and wrap the latter into a declaration, producing valid code. 11598f9bb38SStefan Gränitz 116a871470aSStefan Gränitz TEST_F(InterpreterTest, DeclsAndStatements) { 11792f9852fSVassil Vassilev Args ExtraArgs = {"-Xclang", "-diagnostic-log-file", "-Xclang", "-"}; 11892f9852fSVassil Vassilev 11992f9852fSVassil Vassilev // Create the diagnostic engine with unowned consumer. 12092f9852fSVassil Vassilev std::string DiagnosticOutput; 12192f9852fSVassil Vassilev llvm::raw_string_ostream DiagnosticsOS(DiagnosticOutput); 12292f9852fSVassil Vassilev auto DiagPrinter = std::make_unique<TextDiagnosticPrinter>( 12392f9852fSVassil Vassilev DiagnosticsOS, new DiagnosticOptions()); 12492f9852fSVassil Vassilev 12592f9852fSVassil Vassilev auto Interp = createInterpreter(ExtraArgs, DiagPrinter.get()); 12611b47c10SVassil Vassilev auto R1 = Interp->Parse( 12792f9852fSVassil Vassilev "int var1 = 42; extern \"C\" int printf(const char*, ...);"); 12892f9852fSVassil Vassilev // gtest doesn't expand into explicit bool conversions. 12911b47c10SVassil Vassilev EXPECT_TRUE(!!R1); 13092f9852fSVassil Vassilev 13111b47c10SVassil Vassilev auto *PTU1 = R1->TUPart; 13211b47c10SVassil Vassilev EXPECT_EQ(2U, DeclsSize(PTU1)); 13392f9852fSVassil Vassilev 13411b47c10SVassil Vassilev auto R2 = Interp->Parse("var1++; printf(\"var1 value %d\\n\", var1);"); 135dc488935SVassil Vassilev EXPECT_TRUE(!!R2); 13692f9852fSVassil Vassilev } 13792f9852fSVassil Vassilev 138a871470aSStefan Gränitz TEST_F(InterpreterTest, UndoCommand) { 139dea5a9ccSJun Zhang Args ExtraArgs = {"-Xclang", "-diagnostic-log-file", "-Xclang", "-"}; 140dea5a9ccSJun Zhang 141dea5a9ccSJun Zhang // Create the diagnostic engine with unowned consumer. 142dea5a9ccSJun Zhang std::string DiagnosticOutput; 143dea5a9ccSJun Zhang llvm::raw_string_ostream DiagnosticsOS(DiagnosticOutput); 144dea5a9ccSJun Zhang auto DiagPrinter = std::make_unique<TextDiagnosticPrinter>( 145dea5a9ccSJun Zhang DiagnosticsOS, new DiagnosticOptions()); 146dea5a9ccSJun Zhang 147dea5a9ccSJun Zhang auto Interp = createInterpreter(ExtraArgs, DiagPrinter.get()); 148dea5a9ccSJun Zhang 149dea5a9ccSJun Zhang // Fail to undo. 150dea5a9ccSJun Zhang auto Err1 = Interp->Undo(); 151dea5a9ccSJun Zhang EXPECT_EQ("Operation failed. Too many undos", 152dea5a9ccSJun Zhang llvm::toString(std::move(Err1))); 153dea5a9ccSJun Zhang auto Err2 = Interp->Parse("int foo = 42;"); 154dea5a9ccSJun Zhang EXPECT_TRUE(!!Err2); 155dea5a9ccSJun Zhang auto Err3 = Interp->Undo(2); 156dea5a9ccSJun Zhang EXPECT_EQ("Operation failed. Too many undos", 157dea5a9ccSJun Zhang llvm::toString(std::move(Err3))); 158dea5a9ccSJun Zhang 159dea5a9ccSJun Zhang // Succeed to undo. 160dea5a9ccSJun Zhang auto Err4 = Interp->Parse("int x = 42;"); 161dea5a9ccSJun Zhang EXPECT_TRUE(!!Err4); 162dea5a9ccSJun Zhang auto Err5 = Interp->Undo(); 163dea5a9ccSJun Zhang EXPECT_FALSE(Err5); 164dea5a9ccSJun Zhang auto Err6 = Interp->Parse("int x = 24;"); 165dea5a9ccSJun Zhang EXPECT_TRUE(!!Err6); 166dea5a9ccSJun Zhang auto Err7 = Interp->Parse("#define X 42"); 167dea5a9ccSJun Zhang EXPECT_TRUE(!!Err7); 168dea5a9ccSJun Zhang auto Err8 = Interp->Undo(); 169dea5a9ccSJun Zhang EXPECT_FALSE(Err8); 170dea5a9ccSJun Zhang auto Err9 = Interp->Parse("#define X 24"); 171dea5a9ccSJun Zhang EXPECT_TRUE(!!Err9); 172dea5a9ccSJun Zhang 173dea5a9ccSJun Zhang // Undo input contains errors. 174dea5a9ccSJun Zhang auto Err10 = Interp->Parse("int y = ;"); 175dea5a9ccSJun Zhang EXPECT_FALSE(!!Err10); 176dea5a9ccSJun Zhang EXPECT_EQ("Parsing failed.", llvm::toString(Err10.takeError())); 177dea5a9ccSJun Zhang auto Err11 = Interp->Parse("int y = 42;"); 178dea5a9ccSJun Zhang EXPECT_TRUE(!!Err11); 179dea5a9ccSJun Zhang auto Err12 = Interp->Undo(); 180dea5a9ccSJun Zhang EXPECT_FALSE(Err12); 181dea5a9ccSJun Zhang } 182dea5a9ccSJun Zhang 1834fb0805cSVassil Vassilev static std::string MangleName(NamedDecl *ND) { 1844fb0805cSVassil Vassilev ASTContext &C = ND->getASTContext(); 1854fb0805cSVassil Vassilev std::unique_ptr<MangleContext> MangleC(C.createMangleContext()); 1864fb0805cSVassil Vassilev std::string mangledName; 1874fb0805cSVassil Vassilev llvm::raw_string_ostream RawStr(mangledName); 1884fb0805cSVassil Vassilev MangleC->mangleName(ND, RawStr); 189ac84ada9SYoungsuk Kim return mangledName; 1904fb0805cSVassil Vassilev } 1914fb0805cSVassil Vassilev 192a871470aSStefan Gränitz TEST_F(InterpreterTest, FindMangledNameSymbol) { 1934fb0805cSVassil Vassilev std::unique_ptr<Interpreter> Interp = createInterpreter(); 1944fb0805cSVassil Vassilev 1954fb0805cSVassil Vassilev auto &PTU(cantFail(Interp->Parse("int f(const char*) {return 0;}"))); 1964fb0805cSVassil Vassilev EXPECT_EQ(1U, DeclsSize(PTU.TUPart)); 1974fb0805cSVassil Vassilev auto R1DeclRange = PTU.TUPart->decls(); 1984fb0805cSVassil Vassilev 1994fb0805cSVassil Vassilev NamedDecl *FD = cast<FunctionDecl>(*R1DeclRange.begin()); 2004fb0805cSVassil Vassilev // Lower the PTU 2014fb0805cSVassil Vassilev if (llvm::Error Err = Interp->Execute(PTU)) { 2024fb0805cSVassil Vassilev // We cannot execute on the platform. 2034fb0805cSVassil Vassilev consumeError(std::move(Err)); 2044fb0805cSVassil Vassilev return; 2054fb0805cSVassil Vassilev } 2064fb0805cSVassil Vassilev 2074fb0805cSVassil Vassilev std::string MangledName = MangleName(FD); 208452cb7f2SVassil Vassilev auto Addr = Interp->getSymbolAddress(MangledName); 209452cb7f2SVassil Vassilev EXPECT_FALSE(!Addr); 210452cb7f2SVassil Vassilev EXPECT_NE(0U, Addr->getValue()); 2114fb0805cSVassil Vassilev GlobalDecl GD(FD); 212452cb7f2SVassil Vassilev EXPECT_EQ(*Addr, cantFail(Interp->getSymbolAddress(GD))); 213452cb7f2SVassil Vassilev cantFail( 214452cb7f2SVassil Vassilev Interp->ParseAndExecute("extern \"C\" int printf(const char*,...);")); 215452cb7f2SVassil Vassilev Addr = Interp->getSymbolAddress("printf"); 216452cb7f2SVassil Vassilev EXPECT_FALSE(!Addr); 217452cb7f2SVassil Vassilev 218452cb7f2SVassil Vassilev // FIXME: Re-enable when we investigate the way we handle dllimports on Win. 219452cb7f2SVassil Vassilev #ifndef _WIN32 2203403686bSSam James EXPECT_EQ((uintptr_t)&printf, Addr->getValue()); 221452cb7f2SVassil Vassilev #endif // _WIN32 2224fb0805cSVassil Vassilev } 2234fb0805cSVassil Vassilev 2241566f1ffSVassil Vassilev static Value AllocateObject(TypeDecl *TD, Interpreter &Interp) { 2254fb0805cSVassil Vassilev std::string Name = TD->getQualifiedNameAsString(); 2261566f1ffSVassil Vassilev Value Addr; 2272759e470SVassil Vassilev // FIXME: Consider providing an option in clang::Value to take ownership of 2282759e470SVassil Vassilev // the memory created from the interpreter. 2292759e470SVassil Vassilev // cantFail(Interp.ParseAndExecute("new " + Name + "()", &Addr)); 2302759e470SVassil Vassilev 2312759e470SVassil Vassilev // The lifetime of the temporary is extended by the clang::Value. 2322759e470SVassil Vassilev cantFail(Interp.ParseAndExecute(Name + "()", &Addr)); 2334fb0805cSVassil Vassilev return Addr; 2344fb0805cSVassil Vassilev } 2354fb0805cSVassil Vassilev 2364fb0805cSVassil Vassilev static NamedDecl *LookupSingleName(Interpreter &Interp, const char *Name) { 2374fb0805cSVassil Vassilev Sema &SemaRef = Interp.getCompilerInstance()->getSema(); 2384fb0805cSVassil Vassilev ASTContext &C = SemaRef.getASTContext(); 2394fb0805cSVassil Vassilev DeclarationName DeclName = &C.Idents.get(Name); 2404fb0805cSVassil Vassilev LookupResult R(SemaRef, DeclName, SourceLocation(), Sema::LookupOrdinaryName); 2414fb0805cSVassil Vassilev SemaRef.LookupName(R, SemaRef.TUScope); 2424fb0805cSVassil Vassilev assert(!R.empty()); 2434fb0805cSVassil Vassilev return R.getFoundDecl(); 2444fb0805cSVassil Vassilev } 2454fb0805cSVassil Vassilev 246a871470aSStefan Gränitz TEST_F(InterpreterTest, InstantiateTemplate) { 2474fb0805cSVassil Vassilev // FIXME: We cannot yet handle delayed template parsing. If we run with 2484fb0805cSVassil Vassilev // -fdelayed-template-parsing we try adding the newly created decl to the 2494fb0805cSVassil Vassilev // active PTU which causes an assert. 2504fb0805cSVassil Vassilev std::vector<const char *> Args = {"-fno-delayed-template-parsing"}; 2514fb0805cSVassil Vassilev std::unique_ptr<Interpreter> Interp = createInterpreter(Args); 2524fb0805cSVassil Vassilev 2535111286fSJun Zhang llvm::cantFail(Interp->Parse("extern \"C\" int printf(const char*,...);" 2544fb0805cSVassil Vassilev "class A {};" 2554fb0805cSVassil Vassilev "struct B {" 2564fb0805cSVassil Vassilev " template<typename T>" 2573ad0c6b7SElizabeth Andrews " static int callme(T) { return 42; }" 2584fb0805cSVassil Vassilev "};")); 2594fb0805cSVassil Vassilev auto &PTU = llvm::cantFail(Interp->Parse("auto _t = &B::callme<A*>;")); 2604fb0805cSVassil Vassilev auto PTUDeclRange = PTU.TUPart->decls(); 2614fb0805cSVassil Vassilev EXPECT_EQ(1, std::distance(PTUDeclRange.begin(), PTUDeclRange.end())); 2624fb0805cSVassil Vassilev 2634fb0805cSVassil Vassilev // Lower the PTU 2644fb0805cSVassil Vassilev if (llvm::Error Err = Interp->Execute(PTU)) { 2654fb0805cSVassil Vassilev // We cannot execute on the platform. 2664fb0805cSVassil Vassilev consumeError(std::move(Err)); 2674fb0805cSVassil Vassilev return; 2684fb0805cSVassil Vassilev } 2694fb0805cSVassil Vassilev 2704fb0805cSVassil Vassilev TypeDecl *TD = cast<TypeDecl>(LookupSingleName(*Interp, "A")); 2711566f1ffSVassil Vassilev Value NewA = AllocateObject(TD, *Interp); 2724fb0805cSVassil Vassilev 2734fb0805cSVassil Vassilev // Find back the template specialization 2744fb0805cSVassil Vassilev VarDecl *VD = static_cast<VarDecl *>(*PTUDeclRange.begin()); 2754fb0805cSVassil Vassilev UnaryOperator *UO = llvm::cast<UnaryOperator>(VD->getInit()); 2764fb0805cSVassil Vassilev NamedDecl *TmpltSpec = llvm::cast<DeclRefExpr>(UO->getSubExpr())->getDecl(); 2774fb0805cSVassil Vassilev 2784fb0805cSVassil Vassilev std::string MangledName = MangleName(TmpltSpec); 2794fb0805cSVassil Vassilev typedef int (*TemplateSpecFn)(void *); 280fe1f3445SJun Zhang auto fn = 281fe1f3445SJun Zhang cantFail(Interp->getSymbolAddress(MangledName)).toPtr<TemplateSpecFn>(); 2821566f1ffSVassil Vassilev EXPECT_EQ(42, fn(NewA.getPtr())); 2834fb0805cSVassil Vassilev } 2844fb0805cSVassil Vassilev 285a871470aSStefan Gränitz TEST_F(InterpreterTest, Value) { 286c63b9a5aSNico Weber std::vector<const char *> Args = {"-fno-sized-deallocation"}; 287c63b9a5aSNico Weber std::unique_ptr<Interpreter> Interp = createInterpreter(Args); 2885111286fSJun Zhang 2895111286fSJun Zhang Value V1; 2905111286fSJun Zhang llvm::cantFail(Interp->ParseAndExecute("int x = 42;")); 2915111286fSJun Zhang llvm::cantFail(Interp->ParseAndExecute("x", &V1)); 2925111286fSJun Zhang EXPECT_TRUE(V1.isValid()); 2935111286fSJun Zhang EXPECT_TRUE(V1.hasValue()); 2945111286fSJun Zhang EXPECT_EQ(V1.getInt(), 42); 2955111286fSJun Zhang EXPECT_EQ(V1.convertTo<int>(), 42); 2965111286fSJun Zhang EXPECT_TRUE(V1.getType()->isIntegerType()); 2975111286fSJun Zhang EXPECT_EQ(V1.getKind(), Value::K_Int); 2985111286fSJun Zhang EXPECT_FALSE(V1.isManuallyAlloc()); 2995111286fSJun Zhang 300aa962d67SStefan Gränitz Value V1b; 301aa962d67SStefan Gränitz llvm::cantFail(Interp->ParseAndExecute("char c = 42;")); 302aa962d67SStefan Gränitz llvm::cantFail(Interp->ParseAndExecute("c", &V1b)); 303aa962d67SStefan Gränitz EXPECT_TRUE(V1b.getKind() == Value::K_Char_S || 304aa962d67SStefan Gränitz V1b.getKind() == Value::K_Char_U); 305aa962d67SStefan Gränitz 3065111286fSJun Zhang Value V2; 3075111286fSJun Zhang llvm::cantFail(Interp->ParseAndExecute("double y = 3.14;")); 3085111286fSJun Zhang llvm::cantFail(Interp->ParseAndExecute("y", &V2)); 3095111286fSJun Zhang EXPECT_TRUE(V2.isValid()); 3105111286fSJun Zhang EXPECT_TRUE(V2.hasValue()); 3115111286fSJun Zhang EXPECT_EQ(V2.getDouble(), 3.14); 3125111286fSJun Zhang EXPECT_EQ(V2.convertTo<double>(), 3.14); 3135111286fSJun Zhang EXPECT_TRUE(V2.getType()->isFloatingType()); 3145111286fSJun Zhang EXPECT_EQ(V2.getKind(), Value::K_Double); 3155111286fSJun Zhang EXPECT_FALSE(V2.isManuallyAlloc()); 3165111286fSJun Zhang 3175111286fSJun Zhang Value V3; 3185111286fSJun Zhang llvm::cantFail(Interp->ParseAndExecute( 3195111286fSJun Zhang "struct S { int* p; S() { p = new int(42); } ~S() { delete p; }};")); 3205111286fSJun Zhang llvm::cantFail(Interp->ParseAndExecute("S{}", &V3)); 3215111286fSJun Zhang EXPECT_TRUE(V3.isValid()); 3225111286fSJun Zhang EXPECT_TRUE(V3.hasValue()); 3235111286fSJun Zhang EXPECT_TRUE(V3.getType()->isRecordType()); 3245111286fSJun Zhang EXPECT_EQ(V3.getKind(), Value::K_PtrOrObj); 3255111286fSJun Zhang EXPECT_TRUE(V3.isManuallyAlloc()); 3265111286fSJun Zhang 3275111286fSJun Zhang Value V4; 3285111286fSJun Zhang llvm::cantFail(Interp->ParseAndExecute("int getGlobal();")); 3295111286fSJun Zhang llvm::cantFail(Interp->ParseAndExecute("void setGlobal(int);")); 3305111286fSJun Zhang llvm::cantFail(Interp->ParseAndExecute("getGlobal()", &V4)); 3315111286fSJun Zhang EXPECT_EQ(V4.getInt(), 42); 3325111286fSJun Zhang EXPECT_TRUE(V4.getType()->isIntegerType()); 3335111286fSJun Zhang 3345111286fSJun Zhang Value V5; 3355111286fSJun Zhang // Change the global from the compiled code. 3365111286fSJun Zhang setGlobal(43); 3375111286fSJun Zhang llvm::cantFail(Interp->ParseAndExecute("getGlobal()", &V5)); 3385111286fSJun Zhang EXPECT_EQ(V5.getInt(), 43); 3395111286fSJun Zhang EXPECT_TRUE(V5.getType()->isIntegerType()); 3405111286fSJun Zhang 3415111286fSJun Zhang // Change the global from the interpreted code. 3425111286fSJun Zhang llvm::cantFail(Interp->ParseAndExecute("setGlobal(44);")); 3435111286fSJun Zhang EXPECT_EQ(getGlobal(), 44); 3445111286fSJun Zhang 3455111286fSJun Zhang Value V6; 3465111286fSJun Zhang llvm::cantFail(Interp->ParseAndExecute("void foo() {}")); 3475111286fSJun Zhang llvm::cantFail(Interp->ParseAndExecute("foo()", &V6)); 3485111286fSJun Zhang EXPECT_TRUE(V6.isValid()); 3495111286fSJun Zhang EXPECT_FALSE(V6.hasValue()); 3505111286fSJun Zhang EXPECT_TRUE(V6.getType()->isVoidType()); 3515111286fSJun Zhang EXPECT_EQ(V6.getKind(), Value::K_Void); 3525111286fSJun Zhang EXPECT_FALSE(V2.isManuallyAlloc()); 3535111286fSJun Zhang 3545111286fSJun Zhang Value V7; 3555111286fSJun Zhang llvm::cantFail(Interp->ParseAndExecute("foo", &V7)); 3565111286fSJun Zhang EXPECT_TRUE(V7.isValid()); 3575111286fSJun Zhang EXPECT_TRUE(V7.hasValue()); 3585111286fSJun Zhang EXPECT_TRUE(V7.getType()->isFunctionProtoType()); 3595111286fSJun Zhang EXPECT_EQ(V7.getKind(), Value::K_PtrOrObj); 3605111286fSJun Zhang EXPECT_FALSE(V7.isManuallyAlloc()); 3615111286fSJun Zhang 3625111286fSJun Zhang Value V8; 3635111286fSJun Zhang llvm::cantFail(Interp->ParseAndExecute("struct SS{ void f() {} };")); 3645111286fSJun Zhang llvm::cantFail(Interp->ParseAndExecute("&SS::f", &V8)); 3655111286fSJun Zhang EXPECT_TRUE(V8.isValid()); 3665111286fSJun Zhang EXPECT_TRUE(V8.hasValue()); 3675111286fSJun Zhang EXPECT_TRUE(V8.getType()->isMemberFunctionPointerType()); 3685111286fSJun Zhang EXPECT_EQ(V8.getKind(), Value::K_PtrOrObj); 3695111286fSJun Zhang EXPECT_TRUE(V8.isManuallyAlloc()); 3705111286fSJun Zhang 3715111286fSJun Zhang Value V9; 3725111286fSJun Zhang llvm::cantFail(Interp->ParseAndExecute("struct A { virtual int f(); };")); 3735111286fSJun Zhang llvm::cantFail( 3745111286fSJun Zhang Interp->ParseAndExecute("struct B : A { int f() { return 42; }};")); 3755111286fSJun Zhang llvm::cantFail(Interp->ParseAndExecute("int (B::*ptr)() = &B::f;")); 3765111286fSJun Zhang llvm::cantFail(Interp->ParseAndExecute("ptr", &V9)); 3775111286fSJun Zhang EXPECT_TRUE(V9.isValid()); 3785111286fSJun Zhang EXPECT_TRUE(V9.hasValue()); 3795111286fSJun Zhang EXPECT_TRUE(V9.getType()->isMemberFunctionPointerType()); 3805111286fSJun Zhang EXPECT_EQ(V9.getKind(), Value::K_PtrOrObj); 3815111286fSJun Zhang EXPECT_TRUE(V9.isManuallyAlloc()); 3825111286fSJun Zhang } 383a871470aSStefan Gränitz 384*61c8b715SVipul Cariappa TEST_F(InterpreterTest, TranslationUnit_CanonicalDecl) { 385*61c8b715SVipul Cariappa std::vector<const char *> Args; 386*61c8b715SVipul Cariappa std::unique_ptr<Interpreter> Interp = createInterpreter(Args); 387*61c8b715SVipul Cariappa 388*61c8b715SVipul Cariappa Sema &sema = Interp->getCompilerInstance()->getSema(); 389*61c8b715SVipul Cariappa 390*61c8b715SVipul Cariappa llvm::cantFail(Interp->ParseAndExecute("int x = 42;")); 391*61c8b715SVipul Cariappa 392*61c8b715SVipul Cariappa TranslationUnitDecl *TU = 393*61c8b715SVipul Cariappa sema.getASTContext().getTranslationUnitDecl()->getCanonicalDecl(); 394*61c8b715SVipul Cariappa 395*61c8b715SVipul Cariappa llvm::cantFail(Interp->ParseAndExecute("long y = 84;")); 396*61c8b715SVipul Cariappa 397*61c8b715SVipul Cariappa EXPECT_EQ(TU, 398*61c8b715SVipul Cariappa sema.getASTContext().getTranslationUnitDecl()->getCanonicalDecl()); 399*61c8b715SVipul Cariappa 400*61c8b715SVipul Cariappa llvm::cantFail(Interp->ParseAndExecute("char z = 'z';")); 401*61c8b715SVipul Cariappa 402*61c8b715SVipul Cariappa EXPECT_EQ(TU, 403*61c8b715SVipul Cariappa sema.getASTContext().getTranslationUnitDecl()->getCanonicalDecl()); 404*61c8b715SVipul Cariappa } 405*61c8b715SVipul Cariappa 40692f9852fSVassil Vassilev } // end anonymous namespace 407