https://github.com/weliveindetail created 
https://github.com/llvm/llvm-project/pull/93816

Reduce code bloat by checking test requirements in a common test fixture

From fd02a874601b8a72d05c3c1b219e28600851b56b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Stefan=20Gr=C3=A4nitz?= <stefan.graen...@gmail.com>
Date: Thu, 30 May 2024 14:32:52 +0200
Subject: [PATCH] [clang-repl] Introduce common fixture class in unittests
 (NFC)

---
 .../Interpreter/CodeCompletionTest.cpp        | 233 ++++++------------
 .../Interpreter/IncrementalProcessingTest.cpp |  21 +-
 .../Interpreter/InterpreterExtensionsTest.cpp |  65 ++---
 .../unittests/Interpreter/InterpreterTest.cpp | 100 ++------
 .../Interpreter/InterpreterTestFixture.h      |  67 +++++
 5 files changed, 191 insertions(+), 295 deletions(-)
 create mode 100644 clang/unittests/Interpreter/InterpreterTestFixture.h

diff --git a/clang/unittests/Interpreter/CodeCompletionTest.cpp 
b/clang/unittests/Interpreter/CodeCompletionTest.cpp
index 72c02c683fafd..89a86a5391627 100644
--- a/clang/unittests/Interpreter/CodeCompletionTest.cpp
+++ b/clang/unittests/Interpreter/CodeCompletionTest.cpp
@@ -1,3 +1,17 @@
+//===- unittests/Interpreter/CodeCompletionTest.cpp 
-----------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Unit tests for Clang's Interpreter library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "InterpreterTestFixture.h"
+
 #include "clang/Interpreter/CodeCompletion.h"
 #include "clang/Frontend/CompilerInstance.h"
 #include "clang/Interpreter/Interpreter.h"
@@ -12,132 +26,86 @@
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
-#if defined(_AIX) || defined(__MVS__)
-#define CLANG_INTERPRETER_PLATFORM_CANNOT_CREATE_LLJIT
-#endif
-
 using namespace clang;
 namespace {
 auto CB = clang::IncrementalCompilerBuilder();
 
-static std::unique_ptr<Interpreter> createInterpreter() {
-  auto CI = cantFail(CB.CreateCpp());
-  return cantFail(clang::Interpreter::create(std::move(CI)));
-}
-
-static std::vector<std::string> runComp(clang::Interpreter &MainInterp,
-                                        llvm::StringRef Input,
-                                        llvm::Error &ErrR) {
-  auto CI = CB.CreateCpp();
-  if (auto Err = CI.takeError()) {
-    ErrR = std::move(Err);
-    return {};
-  }
-
-  auto Interp = clang::Interpreter::create(std::move(*CI));
-  if (auto Err = Interp.takeError()) {
-    // log the error and returns an empty vector;
-    ErrR = std::move(Err);
-
-    return {};
+class CodeCompletionTest : public InterpreterTestBase {
+public:
+  std::unique_ptr<CompilerInstance> CI;
+  std::unique_ptr<Interpreter> Interp;
+
+  CodeCompletionTest() : CI(cantFail(CB.CreateCpp())), 
Interp(cantFail(clang::Interpreter::create(std::move(CI)))) {}
+
+  std::vector<std::string> runComp(llvm::StringRef Input,
+                                   llvm::Error &ErrR) {
+    auto ComplCI = CB.CreateCpp();
+    if (auto Err = ComplCI.takeError()) {
+      ErrR = std::move(Err);
+      return {};
+    }
+
+    auto ComplInterp = clang::Interpreter::create(std::move(*ComplCI));
+    if (auto Err = ComplInterp.takeError()) {
+      ErrR = std::move(Err);
+      return {};
+    }
+
+    std::vector<std::string> Results;
+    std::vector<std::string> Comps;
+    auto *ParentCI = this->Interp->getCompilerInstance();
+    auto *MainCI = (*ComplInterp)->getCompilerInstance();
+    auto CC = ReplCodeCompleter();
+    CC.codeComplete(MainCI, Input, /* Lines */ 1, Input.size() + 1,
+                    ParentCI, Results);
+
+    for (auto Res : Results)
+      if (Res.find(CC.Prefix) == 0)
+        Comps.push_back(Res);
+    return Comps;
   }
+};
 
-  std::vector<std::string> Results;
-  std::vector<std::string> Comps;
-  auto *MainCI = (*Interp)->getCompilerInstance();
-  auto CC = ReplCodeCompleter();
-  CC.codeComplete(MainCI, Input, /* Lines */ 1, Input.size() + 1,
-                  MainInterp.getCompilerInstance(), Results);
-
-  for (auto Res : Results)
-    if (Res.find(CC.Prefix) == 0)
-      Comps.push_back(Res);
-  return Comps;
-}
-
-static bool HostSupportsJit() {
-  auto J = llvm::orc::LLJITBuilder().create();
-  if (J)
-    return true;
-  LLVMConsumeError(llvm::wrap(J.takeError()));
-  return false;
-}
-
-#ifdef CLANG_INTERPRETER_PLATFORM_CANNOT_CREATE_LLJIT
-TEST(CodeCompletionTest, DISABLED_Sanity) {
-#else
-TEST(CodeCompletionTest, Sanity) {
-#endif
-  if (!HostSupportsJit())
-    GTEST_SKIP();
-  auto Interp = createInterpreter();
+TEST_F(CodeCompletionTest, Sanity) {
   cantFail(Interp->Parse("int foo = 12;"));
   auto Err = llvm::Error::success();
-  auto comps = runComp(*Interp, "f", Err);
+  auto comps = runComp("f", Err);
   EXPECT_EQ((size_t)2, comps.size()); // float and foo
   EXPECT_EQ(comps[0], std::string("float"));
   EXPECT_EQ(comps[1], std::string("foo"));
   EXPECT_EQ((bool)Err, false);
 }
 
-#ifdef CLANG_INTERPRETER_PLATFORM_CANNOT_CREATE_LLJIT
-TEST(CodeCompletionTest, DISABLED_SanityNoneValid) {
-#else
-TEST(CodeCompletionTest, SanityNoneValid) {
-#endif
-  if (!HostSupportsJit())
-    GTEST_SKIP();
-  auto Interp = createInterpreter();
+TEST_F(CodeCompletionTest, SanityNoneValid) {
   cantFail(Interp->Parse("int foo = 12;"));
   auto Err = llvm::Error::success();
-  auto comps = runComp(*Interp, "babanana", Err);
+  auto comps = runComp("babanana", Err);
   EXPECT_EQ((size_t)0, comps.size()); // foo and float
   EXPECT_EQ((bool)Err, false);
 }
 
-#ifdef CLANG_INTERPRETER_PLATFORM_CANNOT_CREATE_LLJIT
-TEST(CodeCompletionTest, DISABLED_TwoDecls) {
-#else
-TEST(CodeCompletionTest, TwoDecls) {
-#endif
-  if (!HostSupportsJit())
-    GTEST_SKIP();
-  auto Interp = createInterpreter();
+TEST_F(CodeCompletionTest, TwoDecls) {
   cantFail(Interp->Parse("int application = 12;"));
   cantFail(Interp->Parse("int apple = 12;"));
   auto Err = llvm::Error::success();
-  auto comps = runComp(*Interp, "app", Err);
+  auto comps = runComp("app", Err);
   EXPECT_EQ((size_t)2, comps.size());
   EXPECT_EQ((bool)Err, false);
 }
 
-#ifdef CLANG_INTERPRETER_PLATFORM_CANNOT_CREATE_LLJIT
-TEST(CodeCompletionTest, DISABLED_CompFunDeclsNoError) {
-#else
-TEST(CodeCompletionTest, CompFunDeclsNoError) {
-#endif
-  if (!HostSupportsJit())
-    GTEST_SKIP();
-  auto Interp = createInterpreter();
+TEST_F(CodeCompletionTest, CompFunDeclsNoError) {
   auto Err = llvm::Error::success();
-  auto comps = runComp(*Interp, "void app(", Err);
+  auto comps = runComp("void app(", Err);
   EXPECT_EQ((bool)Err, false);
 }
 
-#ifdef CLANG_INTERPRETER_PLATFORM_CANNOT_CREATE_LLJIT
-TEST(CodeCompletionTest, DISABLED_TypedDirected) {
-#else
-TEST(CodeCompletionTest, TypedDirected) {
-#endif
-  if (!HostSupportsJit())
-    GTEST_SKIP();
-  auto Interp = createInterpreter();
+TEST_F(CodeCompletionTest, TypedDirected) {
   cantFail(Interp->Parse("int application = 12;"));
   cantFail(Interp->Parse("char apple = '2';"));
   cantFail(Interp->Parse("void add(int &SomeInt){}"));
   {
     auto Err = llvm::Error::success();
-    auto comps = runComp(*Interp, std::string("add("), Err);
+    auto comps = runComp(std::string("add("), Err);
     EXPECT_EQ((size_t)1, comps.size());
     EXPECT_EQ((bool)Err, false);
   }
@@ -146,7 +114,7 @@ TEST(CodeCompletionTest, TypedDirected) {
 
   {
     auto Err = llvm::Error::success();
-    auto comps = runComp(*Interp, std::string("add("), Err);
+    auto comps = runComp(std::string("add("), Err);
     EXPECT_EQ((size_t)2, comps.size());
     EXPECT_EQ(comps[0], "application");
     EXPECT_EQ(comps[1], "banana");
@@ -155,21 +123,14 @@ TEST(CodeCompletionTest, TypedDirected) {
 
   {
     auto Err = llvm::Error::success();
-    auto comps = runComp(*Interp, std::string("add(b"), Err);
+    auto comps = runComp(std::string("add(b"), Err);
     EXPECT_EQ((size_t)1, comps.size());
     EXPECT_EQ(comps[0], "banana");
     EXPECT_EQ((bool)Err, false);
   }
 }
 
-#ifdef CLANG_INTERPRETER_PLATFORM_CANNOT_CREATE_LLJIT
-TEST(CodeCompletionTest, DISABLED_SanityClasses) {
-#else
-TEST(CodeCompletionTest, SanityClasses) {
-#endif
-  if (!HostSupportsJit())
-    GTEST_SKIP();
-  auto Interp = createInterpreter();
+TEST_F(CodeCompletionTest, SanityClasses) {
   cantFail(Interp->Parse("struct Apple{};"));
   cantFail(Interp->Parse("void takeApple(Apple &a1){}"));
   cantFail(Interp->Parse("Apple a1;"));
@@ -177,107 +138,72 @@ TEST(CodeCompletionTest, SanityClasses) {
 
   {
     auto Err = llvm::Error::success();
-    auto comps = runComp(*Interp, "takeApple(", Err);
+    auto comps = runComp("takeApple(", Err);
     EXPECT_EQ((size_t)1, comps.size());
     EXPECT_EQ(comps[0], std::string("a1"));
     EXPECT_EQ((bool)Err, false);
   }
   {
     auto Err = llvm::Error::success();
-    auto comps = runComp(*Interp, std::string("takeAppleCopy("), Err);
+    auto comps = runComp(std::string("takeAppleCopy("), Err);
     EXPECT_EQ((size_t)1, comps.size());
     EXPECT_EQ(comps[0], std::string("a1"));
     EXPECT_EQ((bool)Err, false);
   }
 }
 
-#ifdef CLANG_INTERPRETER_PLATFORM_CANNOT_CREATE_LLJIT
-TEST(CodeCompletionTest, DISABLED_SubClassing) {
-#else
-TEST(CodeCompletionTest, SubClassing) {
-#endif
-  if (!HostSupportsJit())
-    GTEST_SKIP();
-  auto Interp = createInterpreter();
+TEST_F(CodeCompletionTest, SubClassing) {
   cantFail(Interp->Parse("struct Fruit {};"));
   cantFail(Interp->Parse("struct Apple : Fruit{};"));
   cantFail(Interp->Parse("void takeFruit(Fruit &f){}"));
   cantFail(Interp->Parse("Apple a1;"));
   cantFail(Interp->Parse("Fruit f1;"));
   auto Err = llvm::Error::success();
-  auto comps = runComp(*Interp, std::string("takeFruit("), Err);
+  auto comps = runComp(std::string("takeFruit("), Err);
   EXPECT_EQ((size_t)2, comps.size());
   EXPECT_EQ(comps[0], std::string("a1"));
   EXPECT_EQ(comps[1], std::string("f1"));
   EXPECT_EQ((bool)Err, false);
 }
 
-#ifdef CLANG_INTERPRETER_PLATFORM_CANNOT_CREATE_LLJIT
-TEST(CodeCompletionTest, DISABLED_MultipleArguments) {
-#else
-TEST(CodeCompletionTest, MultipleArguments) {
-#endif
-  if (!HostSupportsJit())
-    GTEST_SKIP();
-  auto Interp = createInterpreter();
+TEST_F(CodeCompletionTest, MultipleArguments) {
   cantFail(Interp->Parse("int foo = 42;"));
   cantFail(Interp->Parse("char fowl = 'A';"));
   cantFail(Interp->Parse("void takeTwo(int &a, char b){}"));
   auto Err = llvm::Error::success();
-  auto comps = runComp(*Interp, std::string("takeTwo(foo,  "), Err);
+  auto comps = runComp(std::string("takeTwo(foo,  "), Err);
   EXPECT_EQ((size_t)1, comps.size());
   EXPECT_EQ(comps[0], std::string("fowl"));
   EXPECT_EQ((bool)Err, false);
 }
 
-#ifdef CLANG_INTERPRETER_PLATFORM_CANNOT_CREATE_LLJIT
-TEST(CodeCompletionTest, DISABLED_Methods) {
-#else
-TEST(CodeCompletionTest, Methods) {
-#endif
-  if (!HostSupportsJit())
-    GTEST_SKIP();
-  auto Interp = createInterpreter();
+TEST_F(CodeCompletionTest, Methods) {
   cantFail(Interp->Parse(
       "struct Foo{int add(int a){return 42;} int par(int b){return 42;}};"));
   cantFail(Interp->Parse("Foo f1;"));
 
   auto Err = llvm::Error::success();
-  auto comps = runComp(*Interp, std::string("f1."), Err);
+  auto comps = runComp(std::string("f1."), Err);
   EXPECT_EQ((size_t)2, comps.size());
   EXPECT_EQ(comps[0], std::string("add"));
   EXPECT_EQ(comps[1], std::string("par"));
   EXPECT_EQ((bool)Err, false);
 }
 
-#ifdef CLANG_INTERPRETER_PLATFORM_CANNOT_CREATE_LLJIT
-TEST(CodeCompletionTest, DISABLED_MethodsInvocations) {
-#else
-TEST(CodeCompletionTest, MethodsInvocations) {
-#endif
-  if (!HostSupportsJit())
-    GTEST_SKIP();
-  auto Interp = createInterpreter();
+TEST_F(CodeCompletionTest, MethodsInvocations) {
   cantFail(Interp->Parse(
       "struct Foo{int add(int a){return 42;} int par(int b){return 42;}};"));
   cantFail(Interp->Parse("Foo f1;"));
   cantFail(Interp->Parse("int a = 84;"));
 
   auto Err = llvm::Error::success();
-  auto comps = runComp(*Interp, std::string("f1.add("), Err);
+  auto comps = runComp(std::string("f1.add("), Err);
   EXPECT_EQ((size_t)1, comps.size());
   EXPECT_EQ(comps[0], std::string("a"));
   EXPECT_EQ((bool)Err, false);
 }
 
-#ifdef CLANG_INTERPRETER_PLATFORM_CANNOT_CREATE_LLJIT
-TEST(CodeCompletionTest, DISABLED_NestedInvocations) {
-#else
-TEST(CodeCompletionTest, NestedInvocations) {
-#endif
-  if (!HostSupportsJit())
-    GTEST_SKIP();
-  auto Interp = createInterpreter();
+TEST_F(CodeCompletionTest, NestedInvocations) {
   cantFail(Interp->Parse(
       "struct Foo{int add(int a){return 42;} int par(int b){return 42;}};"));
   cantFail(Interp->Parse("Foo f1;"));
@@ -285,26 +211,19 @@ TEST(CodeCompletionTest, NestedInvocations) {
   cantFail(Interp->Parse("int plus(int a, int b) { return a + b; }"));
 
   auto Err = llvm::Error::success();
-  auto comps = runComp(*Interp, std::string("plus(42, f1.add("), Err);
+  auto comps = runComp(std::string("plus(42, f1.add("), Err);
   EXPECT_EQ((size_t)1, comps.size());
   EXPECT_EQ(comps[0], std::string("a"));
   EXPECT_EQ((bool)Err, false);
 }
 
-#ifdef CLANG_INTERPRETER_PLATFORM_CANNOT_CREATE_LLJIT
-TEST(CodeCompletionTest, DISABLED_TemplateFunctions) {
-#else
-TEST(CodeCompletionTest, TemplateFunctions) {
-#endif
-  if (!HostSupportsJit())
-    GTEST_SKIP();
-  auto Interp = createInterpreter();
+TEST_F(CodeCompletionTest, TemplateFunctions) {
   cantFail(
       Interp->Parse("template <typename T> T id(T a) { return a;} "));
   cantFail(Interp->Parse("int apple = 84;"));
   {
     auto Err = llvm::Error::success();
-    auto comps = runComp(*Interp, std::string("id<int>("), Err);
+    auto comps = runComp(std::string("id<int>("), Err);
     EXPECT_EQ((size_t)1, comps.size());
     EXPECT_EQ(comps[0], std::string("apple"));
     EXPECT_EQ((bool)Err, false);
@@ -315,7 +234,7 @@ TEST(CodeCompletionTest, TemplateFunctions) {
   cantFail(Interp->Parse("char pear = '4';"));
   {
     auto Err = llvm::Error::success();
-    auto comps = runComp(*Interp, std::string("pickFirst(apple, "), Err);
+    auto comps = runComp(std::string("pickFirst(apple, "), Err);
     EXPECT_EQ((size_t)1, comps.size());
     EXPECT_EQ(comps[0], std::string("apple"));
     EXPECT_EQ((bool)Err, false);
diff --git a/clang/unittests/Interpreter/IncrementalProcessingTest.cpp 
b/clang/unittests/Interpreter/IncrementalProcessingTest.cpp
index 732753f11306e..1abf5ad222879 100644
--- a/clang/unittests/Interpreter/IncrementalProcessingTest.cpp
+++ b/clang/unittests/Interpreter/IncrementalProcessingTest.cpp
@@ -6,6 +6,8 @@
 //
 
//===----------------------------------------------------------------------===//
 
+#include "InterpreterTestFixture.h"
+
 #include "clang/AST/ASTConsumer.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/RecursiveASTVisitor.h"
@@ -36,6 +38,8 @@ using namespace clang;
 
 namespace {
 
+class IncrementalProcessingTest : public InterpreterTestBase {};
+
 // Incremental processing produces several modules, all using the same "main
 // file". Make sure CodeGen can cope with that, e.g. for static initializers.
 const char TestProgram1[] = "extern \"C\" int funcForProg1() { return 17; }\n"
@@ -56,22 +60,7 @@ const Function *getGlobalInit(llvm::Module *M) {
   return nullptr;
 }
 
-static bool HostSupportsJit() {
-  auto J = llvm::orc::LLJITBuilder().create();
-  if (J)
-    return true;
-  LLVMConsumeError(llvm::wrap(J.takeError()));
-  return false;
-}
-
-#ifdef CLANG_INTERPRETER_PLATFORM_CANNOT_CREATE_LLJIT
-TEST(IncrementalProcessing, DISABLED_EmitCXXGlobalInitFunc) {
-#else
-TEST(IncrementalProcessing, EmitCXXGlobalInitFunc) {
-#endif
-  if (!HostSupportsJit())
-    GTEST_SKIP();
-
+TEST_F(IncrementalProcessingTest, EmitCXXGlobalInitFunc) {
   std::vector<const char *> ClangArgv = {"-Xclang", "-emit-llvm-only"};
   auto CB = clang::IncrementalCompilerBuilder();
   CB.SetCompilerArgs(ClangArgv);
diff --git a/clang/unittests/Interpreter/InterpreterExtensionsTest.cpp 
b/clang/unittests/Interpreter/InterpreterExtensionsTest.cpp
index e22a78048d525..02d4a3c782889 100644
--- a/clang/unittests/Interpreter/InterpreterExtensionsTest.cpp
+++ b/clang/unittests/Interpreter/InterpreterExtensionsTest.cpp
@@ -10,6 +10,8 @@
 //
 
//===----------------------------------------------------------------------===//
 
+#include "InterpreterTestFixture.h"
+
 #include "clang/Interpreter/Interpreter.h"
 
 #include "clang/AST/Expr.h"
@@ -37,34 +39,33 @@
 using namespace clang;
 namespace {
 
-static bool HostSupportsJit() {
-  auto J = llvm::orc::LLJITBuilder().create();
-  if (J)
-    return true;
-  LLVMConsumeError(llvm::wrap(J.takeError()));
-  return false;
-}
-
-// Some tests require a arm-registered-target
-static bool IsARMTargetRegistered() {
-  llvm::Triple TT;
-  TT.setArch(llvm::Triple::arm);
-  TT.setVendor(llvm::Triple::UnknownVendor);
-  TT.setOS(llvm::Triple::UnknownOS);
-
-  std::string UnusedErr;
-  return llvm::TargetRegistry::lookupTarget(TT.str(), UnusedErr);
-}
+class InterpreterExtensionsTest : public InterpreterTestBase {
+protected:
+  void SetUp() override {
+#ifdef CLANG_INTERPRETER_PLATFORM_CANNOT_CREATE_LLJIT
+    GTEST_SKIP();
+#endif
+  }
 
-struct LLVMInitRAII {
-  LLVMInitRAII() {
+  static void SetUpTestSuite() {
     llvm::InitializeAllTargets();
     llvm::InitializeAllTargetInfos();
     llvm::InitializeAllTargetMCs();
     llvm::InitializeAllAsmPrinters();
   }
-  ~LLVMInitRAII() { llvm::llvm_shutdown(); }
-} LLVMInit;
+
+public:
+  // Some tests require a arm-registered-target
+  static bool IsARMTargetRegistered() {
+    llvm::Triple TT;
+    TT.setArch(llvm::Triple::arm);
+    TT.setVendor(llvm::Triple::UnknownVendor);
+    TT.setOS(llvm::Triple::UnknownOS);
+
+    std::string UnusedErr;
+    return llvm::TargetRegistry::lookupTarget(TT.str(), UnusedErr);
+  }
+};
 
 class RecordRuntimeIBMetrics : public Interpreter {
   struct NoopRuntimeInterfaceBuilder : public RuntimeInterfaceBuilder {
@@ -103,12 +104,8 @@ class RecordRuntimeIBMetrics : public Interpreter {
   NoopRuntimeInterfaceBuilder *RuntimeIBPtr = nullptr;
 };
 
-#ifdef CLANG_INTERPRETER_PLATFORM_CANNOT_CREATE_LLJIT
-TEST(InterpreterExtensionsTest, DISABLED_FindRuntimeInterface) {
-#else
-TEST(InterpreterExtensionsTest, FindRuntimeInterface) {
-#endif
-  if (!HostSupportsJit())
+TEST_F(InterpreterExtensionsTest, FindRuntimeInterface) {
+  if (!HostSupportsJIT())
     GTEST_SKIP();
 
   clang::IncrementalCompilerBuilder CB;
@@ -140,11 +137,7 @@ class CustomJBInterpreter : public Interpreter {
   llvm::Error CreateExecutor() { return Interpreter::CreateExecutor(); }
 };
 
-#ifdef CLANG_INTERPRETER_PLATFORM_CANNOT_CREATE_LLJIT
-TEST(InterpreterExtensionsTest, DISABLED_DefaultCrossJIT) {
-#else
-TEST(InterpreterExtensionsTest, DefaultCrossJIT) {
-#endif
+TEST_F(InterpreterExtensionsTest, DefaultCrossJIT) {
   if (!IsARMTargetRegistered())
     GTEST_SKIP();
 
@@ -156,11 +149,7 @@ TEST(InterpreterExtensionsTest, DefaultCrossJIT) {
   cantFail(std::move(ErrOut));
 }
 
-#ifdef CLANG_INTERPRETER_PLATFORM_CANNOT_CREATE_LLJIT
-TEST(InterpreterExtensionsTest, DISABLED_CustomCrossJIT) {
-#else
-TEST(InterpreterExtensionsTest, CustomCrossJIT) {
-#endif
+TEST_F(InterpreterExtensionsTest, CustomCrossJIT) {
   if (!IsARMTargetRegistered())
     GTEST_SKIP();
 
diff --git a/clang/unittests/Interpreter/InterpreterTest.cpp 
b/clang/unittests/Interpreter/InterpreterTest.cpp
index 5294a4bce1ace..3b07d6d1cf5d2 100644
--- a/clang/unittests/Interpreter/InterpreterTest.cpp
+++ b/clang/unittests/Interpreter/InterpreterTest.cpp
@@ -10,6 +10,8 @@
 //
 
//===----------------------------------------------------------------------===//
 
+#include "InterpreterTestFixture.h"
+
 #include "clang/Interpreter/Interpreter.h"
 
 #include "clang/AST/Decl.h"
@@ -30,16 +32,17 @@
 
 using namespace clang;
 
-#if defined(_AIX)
-#define CLANG_INTERPRETER_NO_SUPPORT_EXEC
-#endif
-
 int Global = 42;
 // JIT reports symbol not found on Windows without the visibility attribute.
 REPL_EXTERNAL_VISIBILITY int getGlobal() { return Global; }
 REPL_EXTERNAL_VISIBILITY void setGlobal(int val) { Global = val; }
 
 namespace {
+
+class InterpreterTest : public InterpreterTestBase {
+  // TODO: Collect common variables and utility functions here
+};
+
 using Args = std::vector<const char *>;
 static std::unique_ptr<Interpreter>
 createInterpreter(const Args &ExtraArgs = {},
@@ -54,34 +57,11 @@ createInterpreter(const Args &ExtraArgs = {},
   return cantFail(clang::Interpreter::create(std::move(CI)));
 }
 
-static bool HostSupportsJit() {
-  auto J = llvm::orc::LLJITBuilder().create();
-  if (J)
-    return true;
-  LLVMConsumeError(llvm::wrap(J.takeError()));
-  return false;
-}
-
-struct LLVMInitRAII {
-  LLVMInitRAII() {
-    llvm::InitializeNativeTarget();
-    llvm::InitializeNativeTargetAsmPrinter();
-  }
-  ~LLVMInitRAII() { llvm::llvm_shutdown(); }
-} LLVMInit;
-
 static size_t DeclsSize(TranslationUnitDecl *PTUDecl) {
   return std::distance(PTUDecl->decls().begin(), PTUDecl->decls().end());
 }
 
-#ifdef CLANG_INTERPRETER_NO_SUPPORT_EXEC
-TEST(InterpreterTest, DISABLED_Sanity) {
-#else
-TEST(InterpreterTest, Sanity) {
-#endif
-  if (!HostSupportsJit())
-    GTEST_SKIP();
-
+TEST_F(InterpreterTest, Sanity) {
   std::unique_ptr<Interpreter> Interp = createInterpreter();
 
   using PTU = PartialTranslationUnit;
@@ -97,14 +77,7 @@ static std::string DeclToString(Decl *D) {
   return llvm::cast<NamedDecl>(D)->getQualifiedNameAsString();
 }
 
-#ifdef CLANG_INTERPRETER_NO_SUPPORT_EXEC
-TEST(InterpreterTest, DISABLED_IncrementalInputTopLevelDecls) {
-#else
-TEST(InterpreterTest, IncrementalInputTopLevelDecls) {
-#endif
-  if (!HostSupportsJit())
-    GTEST_SKIP();
-
+TEST_F(InterpreterTest, IncrementalInputTopLevelDecls) {
   std::unique_ptr<Interpreter> Interp = createInterpreter();
   auto R1 = Interp->Parse("int var1 = 42; int f() { return var1; }");
   // gtest doesn't expand into explicit bool conversions.
@@ -121,14 +94,7 @@ TEST(InterpreterTest, IncrementalInputTopLevelDecls) {
   EXPECT_EQ("var2", DeclToString(*R2DeclRange.begin()));
 }
 
-#ifdef CLANG_INTERPRETER_NO_SUPPORT_EXEC
-TEST(InterpreterTest, DISABLED_Errors) {
-#else
-TEST(InterpreterTest, Errors) {
-#endif
-  if (!HostSupportsJit())
-    GTEST_SKIP();
-
+TEST_F(InterpreterTest, Errors) {
   Args ExtraArgs = {"-Xclang", "-diagnostic-log-file", "-Xclang", "-"};
 
   // Create the diagnostic engine with unowned consumer.
@@ -151,14 +117,8 @@ TEST(InterpreterTest, Errors) {
 // Here we test whether the user can mix declarations and statements. The
 // interpreter should be smart enough to recognize the declarations from the
 // statements and wrap the latter into a declaration, producing valid code.
-#ifdef CLANG_INTERPRETER_NO_SUPPORT_EXEC
-TEST(InterpreterTest, DISABLED_DeclsAndStatements) {
-#else
-TEST(InterpreterTest, DeclsAndStatements) {
-#endif
-  if (!HostSupportsJit())
-    GTEST_SKIP();
 
+TEST_F(InterpreterTest, DeclsAndStatements) {
   Args ExtraArgs = {"-Xclang", "-diagnostic-log-file", "-Xclang", "-"};
 
   // Create the diagnostic engine with unowned consumer.
@@ -180,14 +140,7 @@ TEST(InterpreterTest, DeclsAndStatements) {
   EXPECT_TRUE(!!R2);
 }
 
-#ifdef CLANG_INTERPRETER_NO_SUPPORT_EXEC
-TEST(InterpreterTest, DISABLED_UndoCommand) {
-#else
-TEST(InterpreterTest, UndoCommand) {
-#endif
-  if (!HostSupportsJit())
-    GTEST_SKIP();
-
+TEST_F(InterpreterTest, UndoCommand) {
   Args ExtraArgs = {"-Xclang", "-diagnostic-log-file", "-Xclang", "-"};
 
   // Create the diagnostic engine with unowned consumer.
@@ -241,14 +194,7 @@ static std::string MangleName(NamedDecl *ND) {
   return RawStr.str();
 }
 
-#ifdef CLANG_INTERPRETER_NO_SUPPORT_EXEC
-TEST(InterpreterTest, DISABLED_FindMangledNameSymbol) {
-#else
-TEST(InterpreterTest, FindMangledNameSymbol) {
-#endif
-  if (!HostSupportsJit())
-    GTEST_SKIP();
-
+TEST_F(InterpreterTest, FindMangledNameSymbol) {
   std::unique_ptr<Interpreter> Interp = createInterpreter();
 
   auto &PTU(cantFail(Interp->Parse("int f(const char*) {return 0;}")));
@@ -302,14 +248,7 @@ static NamedDecl *LookupSingleName(Interpreter &Interp, 
const char *Name) {
   return R.getFoundDecl();
 }
 
-#ifdef CLANG_INTERPRETER_NO_SUPPORT_EXEC
-TEST(InterpreterTest, DISABLED_InstantiateTemplate) {
-#else
-TEST(InterpreterTest, InstantiateTemplate) {
-#endif
-  if (!HostSupportsJit())
-    GTEST_SKIP();
-
+TEST_F(InterpreterTest, InstantiateTemplate) {
   // FIXME: We cannot yet handle delayed template parsing. If we run with
   // -fdelayed-template-parsing we try adding the newly created decl to the
   // active PTU which causes an assert.
@@ -348,15 +287,7 @@ TEST(InterpreterTest, InstantiateTemplate) {
   EXPECT_EQ(42, fn(NewA.getPtr()));
 }
 
-#ifdef CLANG_INTERPRETER_NO_SUPPORT_EXEC
-TEST(InterpreterTest, DISABLED_Value) {
-#else
-TEST(InterpreterTest, Value) {
-#endif
-  // We cannot execute on the platform.
-  if (!HostSupportsJit())
-    GTEST_SKIP();
-
+TEST_F(InterpreterTest, Value) {
   std::unique_ptr<Interpreter> Interp = createInterpreter();
 
   Value V1;
@@ -453,4 +384,5 @@ TEST(InterpreterTest, Value) {
   EXPECT_EQ(V9.getKind(), Value::K_PtrOrObj);
   EXPECT_TRUE(V9.isManuallyAlloc());
 }
+
 } // end anonymous namespace
diff --git a/clang/unittests/Interpreter/InterpreterTestFixture.h 
b/clang/unittests/Interpreter/InterpreterTestFixture.h
new file mode 100644
index 0000000000000..6b4cba208025a
--- /dev/null
+++ b/clang/unittests/Interpreter/InterpreterTestFixture.h
@@ -0,0 +1,67 @@
+//===- unittests/Interpreter/InterpreterTestBase.h ------------------ C++ 
-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_UNITTESTS_INTERPRETER_INTERPRETERTESTBASE_H
+#define LLVM_CLANG_UNITTESTS_INTERPRETER_INTERPRETERTESTBASE_H
+
+#include "clang/Testing/TestClangConfig.h"
+#include "clang/Tooling/Tooling.h"
+
+#include "llvm/ExecutionEngine/Orc/LLJIT.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/TargetSelect.h"
+
+#include "gtest/gtest.h"
+
+#if defined(_AIX) || defined(__MVS__)
+#define CLANG_INTERPRETER_PLATFORM_CANNOT_CREATE_LLJIT
+#endif
+
+namespace clang {
+
+class InterpreterTestBase : public ::testing::Test {
+protected:
+  static bool HostSupportsJIT() {
+    if (auto JIT = llvm::orc::LLJITBuilder().create()) {
+      return true;
+    } else {
+      llvm::consumeError(JIT.takeError());
+      return false;
+    }
+  }
+
+  void SetUp() override {
+#ifdef CLANG_INTERPRETER_PLATFORM_CANNOT_CREATE_LLJIT
+    GTEST_SKIP();
+#else
+    if (!HostSupportsJIT())
+      GTEST_SKIP();
+#endif
+  }
+
+  void TearDown() override {
+  }
+
+  static void SetUpTestSuite() {
+    llvm::InitializeNativeTarget();
+    llvm::InitializeNativeTargetAsmPrinter();
+  }
+
+  static void TearDownTestSuite() {
+    llvm::llvm_shutdown();
+  }
+};
+
+class InterpreterTestWithParams : public InterpreterTestBase,
+                                  public 
::testing::WithParamInterface<TestClangConfig> {};
+
+} // namespace clang
+
+//#undef CLANG_INTERPRETER_PLATFORM_CANNOT_CREATE_LLJIT
+
+#endif // LLVM_CLANG_UNITTESTS_INTERPRETER_INTERPRETERTESTBASE_H

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to