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/TargetParser/Host.h"
24
25namespace llvm {
26
27struct TestCompiler {
28 LLVMContext Context;
29 clang::CompilerInstance compiler;
30 std::unique_ptr<clang::CodeGenerator> CG;
31 llvm::Module *M = nullptr;
32 unsigned PtrSize = 0;
33
34 TestCompiler(clang::LangOptions LO,
35 clang::CodeGenOptions CGO = clang::CodeGenOptions()) {
36 compiler.getLangOpts() = LO;
37 compiler.getCodeGenOpts() = CGO;
38 compiler.createDiagnostics();
39
40 std::string TrStr = llvm::Triple::normalize(Str: llvm::sys::getProcessTriple());
41 llvm::Triple Tr(TrStr);
42 Tr.setOS(Triple::Linux);
43 Tr.setVendor(Triple::VendorType::UnknownVendor);
44 Tr.setEnvironment(Triple::EnvironmentType::UnknownEnvironment);
45 compiler.getTargetOpts().Triple = Tr.getTriple();
46 compiler.setTarget(clang::TargetInfo::CreateTargetInfo(
47 Diags&: compiler.getDiagnostics(),
48 Opts: std::make_shared<clang::TargetOptions>(args&: compiler.getTargetOpts())));
49
50 const clang::TargetInfo &TInfo = compiler.getTarget();
51 PtrSize = TInfo.getPointerWidth(AddrSpace: clang::LangAS::Default) / 8;
52
53 compiler.createFileManager();
54 compiler.createSourceManager(FileMgr&: compiler.getFileManager());
55 compiler.createPreprocessor(TUKind: clang::TU_Prefix);
56
57 compiler.createASTContext();
58
59 CG.reset(p: CreateLLVMCodeGen(
60 Diags&: compiler.getDiagnostics(), ModuleName: "main-module",
61 FS: &compiler.getVirtualFileSystem(), HeaderSearchOpts: compiler.getHeaderSearchOpts(),
62 PreprocessorOpts: compiler.getPreprocessorOpts(), CGO: compiler.getCodeGenOpts(), C&: Context));
63 }
64
65 void init(const char *TestProgram,
66 std::unique_ptr<clang::ASTConsumer> Consumer = nullptr) {
67 if (!Consumer)
68 Consumer = std::move(CG);
69
70 compiler.setASTConsumer(std::move(Consumer));
71
72 compiler.createSema(TUKind: clang::TU_Prefix, CompletionConsumer: nullptr);
73
74 clang::SourceManager &sm = compiler.getSourceManager();
75 sm.setMainFileID(sm.createFileID(
76 Buffer: llvm::MemoryBuffer::getMemBuffer(InputData: TestProgram), FileCharacter: clang::SrcMgr::C_User));
77 }
78
79 const BasicBlock *compile() {
80 clang::ParseAST(S&: compiler.getSema(), PrintStats: false, SkipFunctionBodies: false);
81 M =
82 static_cast<clang::CodeGenerator&>(compiler.getASTConsumer()).GetModule();
83
84 // Do not expect more than one function definition.
85 auto FuncPtr = M->begin();
86 for (; FuncPtr != M->end(); ++FuncPtr)
87 if (!FuncPtr->isDeclaration())
88 break;
89 assert(FuncPtr != M->end());
90 const llvm::Function &Func = *FuncPtr;
91 ++FuncPtr;
92 for (; FuncPtr != M->end(); ++FuncPtr)
93 if (!FuncPtr->isDeclaration())
94 break;
95 assert(FuncPtr == M->end());
96
97 // The function must consist of single basic block.
98 auto BBPtr = Func.begin();
99 assert(Func.begin() != Func.end());
100 const BasicBlock &BB = *BBPtr;
101 ++BBPtr;
102 assert(BBPtr == Func.end());
103
104 return &BB;
105 }
106};
107
108} // namespace llvm
109#endif // CLANG_UNITTESTS_CODEGEN_TESTCOMPILER_H
110

source code of clang/unittests/CodeGen/TestCompiler.h