brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.1 KiB · 4d7841a Raw
92 lines · cpp
1//=== unittests/CodeGen/IncrementalProcessingTest.cpp - IncrementalCodeGen ===//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-exception6//7//===----------------------------------------------------------------------===//8 9#include "InterpreterTestFixture.h"10 11#include "clang/AST/ASTConsumer.h"12#include "clang/AST/ASTContext.h"13#include "clang/AST/RecursiveASTVisitor.h"14#include "clang/Basic/TargetInfo.h"15#include "clang/CodeGen/ModuleBuilder.h"16#include "clang/Frontend/CompilerInstance.h"17#include "clang/Interpreter/Interpreter.h"18#include "clang/Lex/Preprocessor.h"19#include "clang/Parse/Parser.h"20#include "clang/Sema/Sema.h"21 22#include "llvm/IR/LLVMContext.h"23#include "llvm/IR/Module.h"24#include "llvm/TargetParser/Host.h"25#include "llvm/TargetParser/Triple.h"26 27#include "gtest/gtest.h"28 29#include <memory>30 31#if defined(_AIX) || defined(__MVS__)32#define CLANG_INTERPRETER_PLATFORM_CANNOT_CREATE_LLJIT33#endif34 35using namespace llvm;36using namespace clang;37 38namespace {39 40class IncrementalProcessingTest : public InterpreterTestBase {};41 42// Incremental processing produces several modules, all using the same "main43// file". Make sure CodeGen can cope with that, e.g. for static initializers.44const char TestProgram1[] = "extern \"C\" int funcForProg1() { return 17; }\n"45                            "struct EmitCXXGlobalInitFunc1 {\n"46                            "   EmitCXXGlobalInitFunc1() {}\n"47                            "} test1;";48 49const char TestProgram2[] = "extern \"C\" int funcForProg2() { return 42; }\n"50                            "struct EmitCXXGlobalInitFunc2 {\n"51                            "   EmitCXXGlobalInitFunc2() {}\n"52                            "} test2;";53 54const Function *getGlobalInit(llvm::Module *M) {55  for (const auto &Func : *M)56    if (Func.hasName() && Func.getName().starts_with("_GLOBAL__sub_I_"))57      return &Func;58 59  return nullptr;60}61 62TEST_F(IncrementalProcessingTest, EmitCXXGlobalInitFunc) {63  std::vector<const char *> ClangArgv = {"-Xclang", "-emit-llvm-only"};64  auto CB = clang::IncrementalCompilerBuilder();65  CB.SetCompilerArgs(ClangArgv);66  auto CI = cantFail(CB.CreateCpp());67  auto Interp = llvm::cantFail(Interpreter::create(std::move(CI)));68 69  std::array<clang::PartialTranslationUnit *, 2> PTUs;70 71  PTUs[0] = &llvm::cantFail(Interp->Parse(TestProgram1));72  ASSERT_TRUE(PTUs[0]->TheModule);73  ASSERT_TRUE(PTUs[0]->TheModule->getFunction("funcForProg1"));74 75  PTUs[1] = &llvm::cantFail(Interp->Parse(TestProgram2));76  ASSERT_TRUE(PTUs[1]->TheModule);77  ASSERT_TRUE(PTUs[1]->TheModule->getFunction("funcForProg2"));78  // First code should not end up in second module:79  ASSERT_FALSE(PTUs[1]->TheModule->getFunction("funcForProg1"));80 81  // Make sure global inits exist and are unique:82  const Function *GlobalInit1 = getGlobalInit(PTUs[0]->TheModule.get());83  ASSERT_TRUE(GlobalInit1);84 85  const Function *GlobalInit2 = getGlobalInit(PTUs[1]->TheModule.get());86  ASSERT_TRUE(GlobalInit2);87 88  ASSERT_FALSE(GlobalInit1->getName() == GlobalInit2->getName());89}90 91} // end anonymous namespace92