xref: /llvm-project/clang/unittests/CodeGen/TestCompiler.h (revision df9a14d7bbf1180e4f1474254c9d7ed6bcb4ce55)
1 //=== unittests/CodeGen/TestCompiler.h - Match on the LLVM IR ---*- C++ -*-===//
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-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef CLANG_UNITTESTS_CODEGEN_TESTCOMPILER_H
10 #define CLANG_UNITTESTS_CODEGEN_TESTCOMPILER_H
11 
12 
13 #include "clang/AST/ASTConsumer.h"
14 #include "clang/Basic/TargetInfo.h"
15 #include "clang/Basic/TargetOptions.h"
16 #include "clang/CodeGen/ModuleBuilder.h"
17 #include "clang/Frontend/CompilerInstance.h"
18 #include "clang/Parse/ParseAST.h"
19 
20 #include "llvm/IR/Constants.h"
21 #include "llvm/IR/LLVMContext.h"
22 #include "llvm/IR/Module.h"
23 #include "llvm/Support/VirtualFileSystem.h"
24 #include "llvm/TargetParser/Host.h"
25 
26 namespace llvm {
27 
28 struct TestCompiler {
29   LLVMContext Context;
30   clang::CompilerInstance compiler;
31   std::unique_ptr<clang::CodeGenerator> CG;
32   llvm::Module *M = nullptr;
33   unsigned PtrSize = 0;
34 
35   TestCompiler(clang::LangOptions LO,
36                clang::CodeGenOptions CGO = clang::CodeGenOptions()) {
37     compiler.getLangOpts() = LO;
38     compiler.getCodeGenOpts() = CGO;
39     compiler.createDiagnostics(*llvm::vfs::getRealFileSystem());
40 
41     std::string TrStr = llvm::Triple::normalize(llvm::sys::getProcessTriple());
42     llvm::Triple Tr(TrStr);
43     Tr.setOS(Triple::Linux);
44     Tr.setVendor(Triple::VendorType::UnknownVendor);
45     Tr.setEnvironment(Triple::EnvironmentType::UnknownEnvironment);
46     compiler.getTargetOpts().Triple = Tr.getTriple();
47     compiler.setTarget(clang::TargetInfo::CreateTargetInfo(
48         compiler.getDiagnostics(),
49         std::make_shared<clang::TargetOptions>(compiler.getTargetOpts())));
50 
51     const clang::TargetInfo &TInfo = compiler.getTarget();
52     PtrSize = TInfo.getPointerWidth(clang::LangAS::Default) / 8;
53 
54     compiler.createFileManager();
55     compiler.createSourceManager(compiler.getFileManager());
56     compiler.createPreprocessor(clang::TU_Prefix);
57 
58     compiler.createASTContext();
59 
60     CG.reset(CreateLLVMCodeGen(
61         compiler.getDiagnostics(), "main-module",
62         &compiler.getVirtualFileSystem(), compiler.getHeaderSearchOpts(),
63         compiler.getPreprocessorOpts(), compiler.getCodeGenOpts(), Context));
64   }
65 
66   void init(const char *TestProgram,
67             std::unique_ptr<clang::ASTConsumer> Consumer = nullptr) {
68     if (!Consumer)
69       Consumer = std::move(CG);
70 
71     compiler.setASTConsumer(std::move(Consumer));
72 
73     compiler.createSema(clang::TU_Prefix, nullptr);
74 
75     clang::SourceManager &sm = compiler.getSourceManager();
76     sm.setMainFileID(sm.createFileID(
77         llvm::MemoryBuffer::getMemBuffer(TestProgram), clang::SrcMgr::C_User));
78   }
79 
80   const BasicBlock *compile() {
81     clang::ParseAST(compiler.getSema(), false, false);
82     M =
83       static_cast<clang::CodeGenerator&>(compiler.getASTConsumer()).GetModule();
84 
85     // Do not expect more than one function definition.
86     auto FuncPtr = M->begin();
87     for (; FuncPtr != M->end(); ++FuncPtr)
88       if (!FuncPtr->isDeclaration())
89         break;
90     assert(FuncPtr != M->end());
91     const llvm::Function &Func = *FuncPtr;
92     ++FuncPtr;
93     for (; FuncPtr != M->end(); ++FuncPtr)
94       if (!FuncPtr->isDeclaration())
95         break;
96     assert(FuncPtr == M->end());
97 
98     // The function must consist of single basic block.
99     auto BBPtr = Func.begin();
100     assert(Func.begin() != Func.end());
101     const BasicBlock &BB = *BBPtr;
102     ++BBPtr;
103     assert(BBPtr == Func.end());
104 
105     return &BB;
106   }
107 };
108 
109 } // namespace llvm
110 #endif // CLANG_UNITTESTS_CODEGEN_TESTCOMPILER_H
111