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 "llvm/Support/VirtualFileSystem.h"
20 #include "gtest/gtest.h"
23 using namespace clang
;
24 using namespace clang::frontend
;
29 class NullCodeGenAction
: public CodeGenAction
{
31 NullCodeGenAction(llvm::LLVMContext
*_VMContext
= nullptr)
32 : CodeGenAction(Backend_EmitMCNull
, _VMContext
) {}
34 // The action does not call methods of ATContext.
35 void ExecuteAction() override
{
36 CompilerInstance
&CI
= getCompilerInstance();
37 if (!CI
.hasPreprocessor())
40 CI
.createSema(getTranslationUnitKind(), nullptr);
45 TEST(CodeGenTest
, TestNullCodeGen
) {
46 auto Invocation
= std::make_shared
<CompilerInvocation
>();
47 Invocation
->getPreprocessorOpts().addRemappedFile(
49 MemoryBuffer::getMemBuffer("").release());
50 Invocation
->getFrontendOpts().Inputs
.push_back(
51 FrontendInputFile("test.cc", Language::CXX
));
52 Invocation
->getFrontendOpts().ProgramAction
= EmitLLVM
;
53 Invocation
->getTargetOpts().Triple
= "i386-unknown-linux-gnu";
54 CompilerInstance Compiler
;
55 Compiler
.setInvocation(std::move(Invocation
));
56 Compiler
.createDiagnostics(*llvm::vfs::getRealFileSystem());
57 EXPECT_TRUE(Compiler
.hasDiagnostics());
59 std::unique_ptr
<FrontendAction
> Act(new NullCodeGenAction
);
60 bool Success
= Compiler
.ExecuteAction(*Act
);
64 TEST(CodeGenTest
, CodeGenFromIRMemBuffer
) {
65 auto Invocation
= std::make_shared
<CompilerInvocation
>();
66 std::unique_ptr
<MemoryBuffer
> MemBuffer
=
67 MemoryBuffer::getMemBuffer("", "test.ll");
68 Invocation
->getFrontendOpts().Inputs
.push_back(
69 FrontendInputFile(*MemBuffer
, Language::LLVM_IR
));
70 Invocation
->getFrontendOpts().ProgramAction
= frontend::EmitLLVMOnly
;
71 Invocation
->getTargetOpts().Triple
= "i386-unknown-linux-gnu";
72 CompilerInstance Compiler
;
73 Compiler
.setInvocation(std::move(Invocation
));
74 Compiler
.createDiagnostics(*llvm::vfs::getRealFileSystem());
75 EXPECT_TRUE(Compiler
.hasDiagnostics());
77 EmitLLVMOnlyAction Action
;
78 bool Success
= Compiler
.ExecuteAction(Action
);
82 TEST(CodeGenTest
, DebugInfoCWDCodeGen
) {
83 // Check that debug info is accessing the current working directory from the
84 // VFS instead of calling \p llvm::sys::fs::current_path() directly.
86 auto Sept
= llvm::sys::path::get_separator();
87 auto VFS
= std::make_unique
<llvm::vfs::InMemoryFileSystem
>();
88 VFS
->setCurrentWorkingDirectory(
89 std::string(llvm::formatv("{0}in-memory-fs-cwd", Sept
)));
90 std::string TestPath
=
91 std::string(llvm::formatv("{0}in-memory-fs-cwd{0}test.cpp", Sept
));
92 VFS
->addFile(TestPath
, 0, llvm::MemoryBuffer::getMemBuffer("int x;\n"));
94 auto Invocation
= std::make_shared
<CompilerInvocation
>();
95 Invocation
->getFrontendOpts().Inputs
.push_back(
96 FrontendInputFile("test.cpp", Language::CXX
));
97 Invocation
->getFrontendOpts().ProgramAction
= EmitLLVM
;
98 Invocation
->getTargetOpts().Triple
= "x86_64-unknown-linux-gnu";
99 Invocation
->getCodeGenOpts().setDebugInfo(codegenoptions::FullDebugInfo
);
100 CompilerInstance Compiler
;
102 SmallString
<256> IRBuffer
;
103 Compiler
.setOutputStream(std::make_unique
<raw_svector_ostream
>(IRBuffer
));
104 Compiler
.setInvocation(std::move(Invocation
));
105 Compiler
.createDiagnostics(*VFS
);
106 Compiler
.createFileManager(std::move(VFS
));
108 EmitLLVMAction Action
;
109 bool Success
= Compiler
.ExecuteAction(Action
);
110 EXPECT_TRUE(Success
);
112 SmallString
<128> RealCWD
;
113 llvm::sys::fs::current_path(RealCWD
);
114 EXPECT_TRUE(!RealCWD
.empty());
115 EXPECT_FALSE(IRBuffer
.str().contains(RealCWD
));
116 EXPECT_TRUE(IRBuffer
.str().contains("in-memory-fs-cwd"));