1 //=== unittests/CodeGen/TestCompiler.h - Match on the LLVM IR ---*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 #ifndef CLANG_UNITTESTS_CODEGEN_TESTCOMPILER_H
10 #define CLANG_UNITTESTS_CODEGEN_TESTCOMPILER_H
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"
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"
30 clang::CompilerInstance compiler
;
31 std::unique_ptr
<clang::CodeGenerator
> CG
;
32 llvm::Module
*M
= nullptr;
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());
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())));
51 const clang::TargetInfo
&TInfo
= compiler
.getTarget();
52 PtrSize
= TInfo
.getPointerWidth(clang::LangAS::Default
) / 8;
54 compiler
.createFileManager();
55 compiler
.createSourceManager(compiler
.getFileManager());
56 compiler
.createPreprocessor(clang::TU_Prefix
);
58 compiler
.createASTContext();
60 CG
.reset(CreateLLVMCodeGen(
61 compiler
.getDiagnostics(), "main-module",
62 &compiler
.getVirtualFileSystem(), compiler
.getHeaderSearchOpts(),
63 compiler
.getPreprocessorOpts(), compiler
.getCodeGenOpts(), Context
));
66 void init(const char *TestProgram
,
67 std::unique_ptr
<clang::ASTConsumer
> Consumer
= nullptr) {
69 Consumer
= std::move(CG
);
71 compiler
.setASTConsumer(std::move(Consumer
));
73 compiler
.createSema(clang::TU_Prefix
, nullptr);
75 clang::SourceManager
&sm
= compiler
.getSourceManager();
76 sm
.setMainFileID(sm
.createFileID(
77 llvm::MemoryBuffer::getMemBuffer(TestProgram
), clang::SrcMgr::C_User
));
80 const BasicBlock
*compile() {
81 clang::ParseAST(compiler
.getSema(), false, false);
83 static_cast<clang::CodeGenerator
&>(compiler
.getASTConsumer()).GetModule();
85 // Do not expect more than one function definition.
86 auto FuncPtr
= M
->begin();
87 for (; FuncPtr
!= M
->end(); ++FuncPtr
)
88 if (!FuncPtr
->isDeclaration())
90 assert(FuncPtr
!= M
->end());
91 const llvm::Function
&Func
= *FuncPtr
;
93 for (; FuncPtr
!= M
->end(); ++FuncPtr
)
94 if (!FuncPtr
->isDeclaration())
96 assert(FuncPtr
== M
->end());
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
;
103 assert(BBPtr
== Func
.end());
110 #endif // CLANG_UNITTESTS_CODEGEN_TESTCOMPILER_H