//===- unittests/Frontend/CodeGenActionTest.cpp --- FrontendAction tests --===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// Unit tests for CodeGenAction.
//
//===----------------------------------------------------------------------===//

#include "clang/CodeGen/CodeGenAction.h"
#include "clang/Basic/LangStandard.h"
#include "clang/CodeGen/BackendUtil.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Lex/PreprocessorOptions.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/VirtualFileSystem.h"
#include "gtest/gtest.h"

using namespace llvm;
using namespace clang;
using namespace clang::frontend;

namespace {


class NullCodeGenAction : public CodeGenAction {
public:
  NullCodeGenAction(llvm::LLVMContext *_VMContext = nullptr)
    : CodeGenAction(Backend_EmitMCNull, _VMContext) {}

  // The action does not call methods of ATContext.
  void ExecuteAction() override {
    CompilerInstance &CI = getCompilerInstance();
    if (!CI.hasPreprocessor())
      return;
    if (!CI.hasSema())
      CI.createSema(getTranslationUnitKind(), nullptr);
  }
};


TEST(CodeGenTest, TestNullCodeGen) {
  auto Invocation = std::make_shared<CompilerInvocation>();
  Invocation->getPreprocessorOpts().addRemappedFile(
      "test.cc",
      MemoryBuffer::getMemBuffer("").release());
  Invocation->getFrontendOpts().Inputs.push_back(
      FrontendInputFile("test.cc", Language::CXX));
  Invocation->getFrontendOpts().ProgramAction = EmitLLVM;
  Invocation->getTargetOpts().Triple = "i386-unknown-linux-gnu";
  CompilerInstance Compiler;
  Compiler.setInvocation(std::move(Invocation));
  Compiler.createDiagnostics(*llvm::vfs::getRealFileSystem());
  EXPECT_TRUE(Compiler.hasDiagnostics());

  std::unique_ptr<FrontendAction> Act(new NullCodeGenAction);
  bool Success = Compiler.ExecuteAction(*Act);
  EXPECT_TRUE(Success);
}

TEST(CodeGenTest, CodeGenFromIRMemBuffer) {
  auto Invocation = std::make_shared<CompilerInvocation>();
  std::unique_ptr<MemoryBuffer> MemBuffer =
      MemoryBuffer::getMemBuffer("", "test.ll");
  Invocation->getFrontendOpts().Inputs.push_back(
      FrontendInputFile(*MemBuffer, Language::LLVM_IR));
  Invocation->getFrontendOpts().ProgramAction = frontend::EmitLLVMOnly;
  Invocation->getTargetOpts().Triple = "i386-unknown-linux-gnu";
  CompilerInstance Compiler;
  Compiler.setInvocation(std::move(Invocation));
  Compiler.createDiagnostics(*llvm::vfs::getRealFileSystem());
  EXPECT_TRUE(Compiler.hasDiagnostics());

  EmitLLVMOnlyAction Action;
  bool Success = Compiler.ExecuteAction(Action);
  EXPECT_TRUE(Success);
}

TEST(CodeGenTest, DebugInfoCWDCodeGen) {
  // Check that debug info is accessing the current working directory from the
  // VFS instead of calling \p llvm::sys::fs::current_path() directly.

  auto Sept = llvm::sys::path::get_separator();
  auto VFS = std::make_unique<llvm::vfs::InMemoryFileSystem>();
  VFS->setCurrentWorkingDirectory(
      std::string(llvm::formatv("{0}in-memory-fs-cwd", Sept)));
  std::string TestPath =
      std::string(llvm::formatv("{0}in-memory-fs-cwd{0}test.cpp", Sept));
  VFS->addFile(TestPath, 0, llvm::MemoryBuffer::getMemBuffer("int x;\n"));

  auto Invocation = std::make_shared<CompilerInvocation>();
  Invocation->getFrontendOpts().Inputs.push_back(
      FrontendInputFile("test.cpp", Language::CXX));
  Invocation->getFrontendOpts().ProgramAction = EmitLLVM;
  Invocation->getTargetOpts().Triple = "x86_64-unknown-linux-gnu";
  Invocation->getCodeGenOpts().setDebugInfo(codegenoptions::FullDebugInfo);
  CompilerInstance Compiler;

  SmallString<256> IRBuffer;
  Compiler.setOutputStream(std::make_unique<raw_svector_ostream>(IRBuffer));
  Compiler.setInvocation(std::move(Invocation));
  Compiler.createDiagnostics(*VFS);
  Compiler.createFileManager(std::move(VFS));

  EmitLLVMAction Action;
  bool Success = Compiler.ExecuteAction(Action);
  EXPECT_TRUE(Success);

  SmallString<128> RealCWD;
  llvm::sys::fs::current_path(RealCWD);
  EXPECT_TRUE(!RealCWD.empty());
  EXPECT_FALSE(IRBuffer.str().contains(RealCWD));
  EXPECT_TRUE(IRBuffer.str().contains("in-memory-fs-cwd"));
}
}
