[SCCP] Avoid modifying AdditionalUsers while iterating over it
[llvm-project.git] / clang / unittests / CodeGen / TestCompiler.h
blobc2fd8ac7c13778910947c55ea7bf737af77e527c
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 //===----------------------------------------------------------------------===//
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/Host.h"
25 namespace llvm {
27 struct TestCompiler {
28 LLVMContext Context;
29 clang::CompilerInstance compiler;
30 std::unique_ptr<clang::CodeGenerator> CG;
31 llvm::Module *M = nullptr;
32 unsigned PtrSize = 0;
34 TestCompiler(clang::LangOptions LO,
35 clang::CodeGenOptions CGO = clang::CodeGenOptions()) {
36 compiler.getLangOpts() = LO;
37 compiler.getCodeGenOpts() = CGO;
38 compiler.createDiagnostics();
40 std::string TrStr = llvm::Triple::normalize(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 compiler.getDiagnostics(),
48 std::make_shared<clang::TargetOptions>(compiler.getTargetOpts())));
50 const clang::TargetInfo &TInfo = compiler.getTarget();
51 PtrSize = TInfo.getPointerWidth(0) / 8;
53 compiler.createFileManager();
54 compiler.createSourceManager(compiler.getFileManager());
55 compiler.createPreprocessor(clang::TU_Prefix);
57 compiler.createASTContext();
59 CG.reset(CreateLLVMCodeGen(compiler.getDiagnostics(),
60 "main-module",
61 compiler.getHeaderSearchOpts(),
62 compiler.getPreprocessorOpts(),
63 compiler.getCodeGenOpts(),
64 Context));
67 void init(const char *TestProgram,
68 std::unique_ptr<clang::ASTConsumer> Consumer = nullptr) {
69 if (!Consumer)
70 Consumer = std::move(CG);
72 compiler.setASTConsumer(std::move(Consumer));
74 compiler.createSema(clang::TU_Prefix, nullptr);
76 clang::SourceManager &sm = compiler.getSourceManager();
77 sm.setMainFileID(sm.createFileID(
78 llvm::MemoryBuffer::getMemBuffer(TestProgram), clang::SrcMgr::C_User));
81 const BasicBlock *compile() {
82 clang::ParseAST(compiler.getSema(), false, false);
83 M =
84 static_cast<clang::CodeGenerator&>(compiler.getASTConsumer()).GetModule();
86 // Do not expect more than one function definition.
87 auto FuncPtr = M->begin();
88 for (; FuncPtr != M->end(); ++FuncPtr)
89 if (!FuncPtr->isDeclaration())
90 break;
91 assert(FuncPtr != M->end());
92 const llvm::Function &Func = *FuncPtr;
93 ++FuncPtr;
94 for (; FuncPtr != M->end(); ++FuncPtr)
95 if (!FuncPtr->isDeclaration())
96 break;
97 assert(FuncPtr == M->end());
99 // The function must consist of single basic block.
100 auto BBPtr = Func.begin();
101 assert(Func.begin() != Func.end());
102 const BasicBlock &BB = *BBPtr;
103 ++BBPtr;
104 assert(BBPtr == Func.end());
106 return &BB;
110 } // namespace llvm
111 #endif // CLANG_UNITTESTS_CODEGEN_TESTCOMPILER_H