xref: /llvm-project/clang/unittests/Frontend/CodeGenActionTest.cpp (revision 8dfaecc4c24494337933aff9d9166486ca0949f1)
1 //===- unittests/Frontend/CodeGenActionTest.cpp --- FrontendAction tests --===//
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 // Unit tests for CodeGenAction.
10 //
11 //===----------------------------------------------------------------------===//
12 
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"
20 
21 using namespace llvm;
22 using namespace clang;
23 using namespace clang::frontend;
24 
25 namespace {
26 
27 
28 class NullCodeGenAction : public CodeGenAction {
29 public:
30   NullCodeGenAction(llvm::LLVMContext *_VMContext = nullptr)
31     : CodeGenAction(Backend_EmitMCNull, _VMContext) {}
32 
33   // The action does not call methods of ATContext.
34   void ExecuteAction() override {
35     CompilerInstance &CI = getCompilerInstance();
36     if (!CI.hasPreprocessor())
37       return;
38     if (!CI.hasSema())
39       CI.createSema(getTranslationUnitKind(), nullptr);
40   }
41 };
42 
43 
44 TEST(CodeGenTest, TestNullCodeGen) {
45   auto Invocation = std::make_shared<CompilerInvocation>();
46   Invocation->getPreprocessorOpts().addRemappedFile(
47       "test.cc",
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());
57 
58   std::unique_ptr<FrontendAction> Act(new NullCodeGenAction);
59   bool Success = Compiler.ExecuteAction(*Act);
60   EXPECT_TRUE(Success);
61 }
62 
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());
75 
76   EmitLLVMOnlyAction Action;
77   bool Success = Compiler.ExecuteAction(Action);
78   EXPECT_TRUE(Success);
79 }
80 
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.
84 
85   auto VFS = std::make_unique<llvm::vfs::InMemoryFileSystem>();
86   VFS->setCurrentWorkingDirectory("/in-memory-fs-cwd");
87   auto Sept = llvm::sys::path::get_separator();
88   std::string TestPath =
89       std::string(llvm::formatv("{0}in-memory-fs-cwd{0}test.cpp", Sept));
90   VFS->addFile(TestPath, 0, llvm::MemoryBuffer::getMemBuffer("int x;\n"));
91 
92   auto Invocation = std::make_shared<CompilerInvocation>();
93   Invocation->getFrontendOpts().Inputs.push_back(
94       FrontendInputFile("test.cpp", Language::CXX));
95   Invocation->getFrontendOpts().ProgramAction = EmitLLVM;
96   Invocation->getTargetOpts().Triple = "x86_64-unknown-linux-gnu";
97   Invocation->getCodeGenOpts().setDebugInfo(codegenoptions::FullDebugInfo);
98   CompilerInstance Compiler;
99 
100   SmallString<256> IRBuffer;
101   Compiler.setOutputStream(std::make_unique<raw_svector_ostream>(IRBuffer));
102   Compiler.setInvocation(std::move(Invocation));
103   Compiler.createDiagnostics();
104   Compiler.createFileManager(std::move(VFS));
105 
106   EmitLLVMAction Action;
107   bool Success = Compiler.ExecuteAction(Action);
108   EXPECT_TRUE(Success);
109 
110   SmallString<128> RealCWD;
111   llvm::sys::fs::current_path(RealCWD);
112   EXPECT_TRUE(!RealCWD.empty());
113   EXPECT_FALSE(IRBuffer.str().contains(RealCWD));
114   EXPECT_TRUE(IRBuffer.str().contains("in-memory-fs-cwd"));
115 }
116 }
117