xref: /llvm-project/clang/unittests/Interpreter/InterpreterTest.cpp (revision 61c8b7159a740d43a6a0fa52756eb479e1a9c1c3)
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