1 //===- unittests/Frontend/CodeGenActionTest.cpp --- FrontendAction tests --===//
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 // Unit tests for CodeGenAction.
11 //===----------------------------------------------------------------------===//
13 #include "clang/CodeGen/CodeGenAction.h"
14 #include "clang/Basic/LangStandard.h"
15 #include "clang/CodeGen/BackendUtil.h"
16 #include "clang/Frontend/CompilerInstance.h"
17 #include "clang/Lex/PreprocessorOptions.h"
18 #include "llvm/Support/FormatVariadic.h"
19 #include "gtest/gtest.h"
22 using namespace clang
;
23 using namespace clang::frontend
;
28 class NullCodeGenAction
: public CodeGenAction
{
30 NullCodeGenAction(llvm::LLVMContext
*_VMContext
= nullptr)
31 : CodeGenAction(Backend_EmitMCNull
, _VMContext
) {}
33 // The action does not call methods of ATContext.
34 void ExecuteAction() override
{
35 CompilerInstance
&CI
= getCompilerInstance();
36 if (!CI
.hasPreprocessor())
39 CI
.createSema(getTranslationUnitKind(), nullptr);
44 TEST(CodeGenTest
, TestNullCodeGen
) {
45 auto Invocation
= std::make_shared
<CompilerInvocation
>();
46 Invocation
->getPreprocessorOpts().addRemappedFile(
48 MemoryBuffer::getMemBuffer("").release());
49 Invocation
->getFrontendOpts().Inputs
.push_back(
50 FrontendInputFile("test.cc", Language::CXX
));
51 Invocation
->getFrontendOpts().ProgramAction
= EmitLLVM
;
52 Invocation
->getTargetOpts().Triple
= "i386-unknown-linux-gnu";
53 CompilerInstance Compiler
;
54 Compiler
.setInvocation(std::move(Invocation
));
55 Compiler
.createDiagnostics();
56 EXPECT_TRUE(Compiler
.hasDiagnostics());
58 std::unique_ptr
<FrontendAction
> Act(new NullCodeGenAction
);
59 bool Success
= Compiler
.ExecuteAction(*Act
);
63 TEST(CodeGenTest
, CodeGenFromIRMemBuffer
) {
64 auto Invocation
= std::make_shared
<CompilerInvocation
>();
65 std::unique_ptr
<MemoryBuffer
> MemBuffer
=
66 MemoryBuffer::getMemBuffer("", "test.ll");
67 Invocation
->getFrontendOpts().Inputs
.push_back(
68 FrontendInputFile(*MemBuffer
, Language::LLVM_IR
));
69 Invocation
->getFrontendOpts().ProgramAction
= frontend::EmitLLVMOnly
;
70 Invocation
->getTargetOpts().Triple
= "i386-unknown-linux-gnu";
71 CompilerInstance Compiler
;
72 Compiler
.setInvocation(std::move(Invocation
));
73 Compiler
.createDiagnostics();
74 EXPECT_TRUE(Compiler
.hasDiagnostics());
76 EmitLLVMOnlyAction Action
;
77 bool Success
= Compiler
.ExecuteAction(Action
);
81 TEST(CodeGenTest
, DebugInfoCWDCodeGen
) {
82 // Check that debug info is accessing the current working directory from the
83 // VFS instead of calling \p llvm::sys::fs::current_path() directly.
85 auto Sept
= llvm::sys::path::get_separator();
86 auto VFS
= std::make_unique
<llvm::vfs::InMemoryFileSystem
>();
87 VFS
->setCurrentWorkingDirectory(
88 std::string(llvm::formatv("{0}in-memory-fs-cwd", Sept
)));
89 std::string TestPath
=
90 std::string(llvm::formatv("{0}in-memory-fs-cwd{0}test.cpp", Sept
));
91 VFS
->addFile(TestPath
, 0, llvm::MemoryBuffer::getMemBuffer("int x;\n"));
93 auto Invocation
= std::make_shared
<CompilerInvocation
>();
94 Invocation
->getFrontendOpts().Inputs
.push_back(
95 FrontendInputFile("test.cpp", Language::CXX
));
96 Invocation
->getFrontendOpts().ProgramAction
= EmitLLVM
;
97 Invocation
->getTargetOpts().Triple
= "x86_64-unknown-linux-gnu";
98 Invocation
->getCodeGenOpts().setDebugInfo(codegenoptions::FullDebugInfo
);
99 CompilerInstance Compiler
;
101 SmallString
<256> IRBuffer
;
102 Compiler
.setOutputStream(std::make_unique
<raw_svector_ostream
>(IRBuffer
));
103 Compiler
.setInvocation(std::move(Invocation
));
104 Compiler
.createDiagnostics();
105 Compiler
.createFileManager(std::move(VFS
));
107 EmitLLVMAction Action
;
108 bool Success
= Compiler
.ExecuteAction(Action
);
109 EXPECT_TRUE(Success
);
111 SmallString
<128> RealCWD
;
112 llvm::sys::fs::current_path(RealCWD
);
113 EXPECT_TRUE(!RealCWD
.empty());
114 EXPECT_FALSE(IRBuffer
.str().contains(RealCWD
));
115 EXPECT_TRUE(IRBuffer
.str().contains("in-memory-fs-cwd"));