154e655b3SVassil Vassilev //=== unittests/CodeGen/TestCompiler.h - Match on the LLVM IR ---*- C++ -*-===// 254e655b3SVassil Vassilev // 354e655b3SVassil Vassilev // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 454e655b3SVassil Vassilev // See https://llvm.org/LICENSE.txt for license information. 554e655b3SVassil Vassilev // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 654e655b3SVassil Vassilev // 754e655b3SVassil Vassilev //===----------------------------------------------------------------------===// 854e655b3SVassil Vassilev 954e655b3SVassil Vassilev #ifndef CLANG_UNITTESTS_CODEGEN_TESTCOMPILER_H 1054e655b3SVassil Vassilev #define CLANG_UNITTESTS_CODEGEN_TESTCOMPILER_H 1154e655b3SVassil Vassilev 1254e655b3SVassil Vassilev 1354e655b3SVassil Vassilev #include "clang/AST/ASTConsumer.h" 1454e655b3SVassil Vassilev #include "clang/Basic/TargetInfo.h" 1554e655b3SVassil Vassilev #include "clang/Basic/TargetOptions.h" 1654e655b3SVassil Vassilev #include "clang/CodeGen/ModuleBuilder.h" 1754e655b3SVassil Vassilev #include "clang/Frontend/CompilerInstance.h" 1854e655b3SVassil Vassilev #include "clang/Parse/ParseAST.h" 1954e655b3SVassil Vassilev 2054e655b3SVassil Vassilev #include "llvm/IR/Constants.h" 2154e655b3SVassil Vassilev #include "llvm/IR/LLVMContext.h" 2254e655b3SVassil Vassilev #include "llvm/IR/Module.h" 23*df9a14d7SKadir Cetinkaya #include "llvm/Support/VirtualFileSystem.h" 24d768bf99SArchibald Elliott #include "llvm/TargetParser/Host.h" 2554e655b3SVassil Vassilev 2654e655b3SVassil Vassilev namespace llvm { 2754e655b3SVassil Vassilev 2854e655b3SVassil Vassilev struct TestCompiler { 2954e655b3SVassil Vassilev LLVMContext Context; 3054e655b3SVassil Vassilev clang::CompilerInstance compiler; 3154e655b3SVassil Vassilev std::unique_ptr<clang::CodeGenerator> CG; 3254e655b3SVassil Vassilev llvm::Module *M = nullptr; 3354e655b3SVassil Vassilev unsigned PtrSize = 0; 3454e655b3SVassil Vassilev 3554e655b3SVassil Vassilev TestCompiler(clang::LangOptions LO, 3654e655b3SVassil Vassilev clang::CodeGenOptions CGO = clang::CodeGenOptions()) { 3754e655b3SVassil Vassilev compiler.getLangOpts() = LO; 3854e655b3SVassil Vassilev compiler.getCodeGenOpts() = CGO; 39*df9a14d7SKadir Cetinkaya compiler.createDiagnostics(*llvm::vfs::getRealFileSystem()); 4054e655b3SVassil Vassilev 4154e655b3SVassil Vassilev std::string TrStr = llvm::Triple::normalize(llvm::sys::getProcessTriple()); 4254e655b3SVassil Vassilev llvm::Triple Tr(TrStr); 4354e655b3SVassil Vassilev Tr.setOS(Triple::Linux); 4454e655b3SVassil Vassilev Tr.setVendor(Triple::VendorType::UnknownVendor); 4554e655b3SVassil Vassilev Tr.setEnvironment(Triple::EnvironmentType::UnknownEnvironment); 4654e655b3SVassil Vassilev compiler.getTargetOpts().Triple = Tr.getTriple(); 4754e655b3SVassil Vassilev compiler.setTarget(clang::TargetInfo::CreateTargetInfo( 4854e655b3SVassil Vassilev compiler.getDiagnostics(), 4954e655b3SVassil Vassilev std::make_shared<clang::TargetOptions>(compiler.getTargetOpts()))); 5054e655b3SVassil Vassilev 5154e655b3SVassil Vassilev const clang::TargetInfo &TInfo = compiler.getTarget(); 52a602f76aSAlex Richardson PtrSize = TInfo.getPointerWidth(clang::LangAS::Default) / 8; 5354e655b3SVassil Vassilev 5454e655b3SVassil Vassilev compiler.createFileManager(); 5554e655b3SVassil Vassilev compiler.createSourceManager(compiler.getFileManager()); 5654e655b3SVassil Vassilev compiler.createPreprocessor(clang::TU_Prefix); 5754e655b3SVassil Vassilev 5854e655b3SVassil Vassilev compiler.createASTContext(); 5954e655b3SVassil Vassilev 608dfaecc4SArgyrios Kyrtzidis CG.reset(CreateLLVMCodeGen( 618dfaecc4SArgyrios Kyrtzidis compiler.getDiagnostics(), "main-module", 628dfaecc4SArgyrios Kyrtzidis &compiler.getVirtualFileSystem(), compiler.getHeaderSearchOpts(), 638dfaecc4SArgyrios Kyrtzidis compiler.getPreprocessorOpts(), compiler.getCodeGenOpts(), Context)); 6454e655b3SVassil Vassilev } 6554e655b3SVassil Vassilev 6654e655b3SVassil Vassilev void init(const char *TestProgram, 6754e655b3SVassil Vassilev std::unique_ptr<clang::ASTConsumer> Consumer = nullptr) { 6854e655b3SVassil Vassilev if (!Consumer) 6954e655b3SVassil Vassilev Consumer = std::move(CG); 7054e655b3SVassil Vassilev 7154e655b3SVassil Vassilev compiler.setASTConsumer(std::move(Consumer)); 7254e655b3SVassil Vassilev 7354e655b3SVassil Vassilev compiler.createSema(clang::TU_Prefix, nullptr); 7454e655b3SVassil Vassilev 7554e655b3SVassil Vassilev clang::SourceManager &sm = compiler.getSourceManager(); 7654e655b3SVassil Vassilev sm.setMainFileID(sm.createFileID( 7754e655b3SVassil Vassilev llvm::MemoryBuffer::getMemBuffer(TestProgram), clang::SrcMgr::C_User)); 7854e655b3SVassil Vassilev } 7954e655b3SVassil Vassilev 8054e655b3SVassil Vassilev const BasicBlock *compile() { 8154e655b3SVassil Vassilev clang::ParseAST(compiler.getSema(), false, false); 8254e655b3SVassil Vassilev M = 8354e655b3SVassil Vassilev static_cast<clang::CodeGenerator&>(compiler.getASTConsumer()).GetModule(); 8454e655b3SVassil Vassilev 8554e655b3SVassil Vassilev // Do not expect more than one function definition. 8654e655b3SVassil Vassilev auto FuncPtr = M->begin(); 8754e655b3SVassil Vassilev for (; FuncPtr != M->end(); ++FuncPtr) 8854e655b3SVassil Vassilev if (!FuncPtr->isDeclaration()) 8954e655b3SVassil Vassilev break; 9054e655b3SVassil Vassilev assert(FuncPtr != M->end()); 9154e655b3SVassil Vassilev const llvm::Function &Func = *FuncPtr; 9254e655b3SVassil Vassilev ++FuncPtr; 9354e655b3SVassil Vassilev for (; FuncPtr != M->end(); ++FuncPtr) 9454e655b3SVassil Vassilev if (!FuncPtr->isDeclaration()) 9554e655b3SVassil Vassilev break; 9654e655b3SVassil Vassilev assert(FuncPtr == M->end()); 9754e655b3SVassil Vassilev 9854e655b3SVassil Vassilev // The function must consist of single basic block. 9954e655b3SVassil Vassilev auto BBPtr = Func.begin(); 10054e655b3SVassil Vassilev assert(Func.begin() != Func.end()); 10154e655b3SVassil Vassilev const BasicBlock &BB = *BBPtr; 10254e655b3SVassil Vassilev ++BBPtr; 10354e655b3SVassil Vassilev assert(BBPtr == Func.end()); 10454e655b3SVassil Vassilev 10554e655b3SVassil Vassilev return &BB; 10654e655b3SVassil Vassilev } 10754e655b3SVassil Vassilev }; 10854e655b3SVassil Vassilev 10954e655b3SVassil Vassilev } // namespace llvm 11054e655b3SVassil Vassilev #endif // CLANG_UNITTESTS_CODEGEN_TESTCOMPILER_H 111