//===--- Compiler.cpp --------------------------------------------*- C++-*-===//
//
// 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
//
//===----------------------------------------------------------------------===//

#include "Compiler.h"
#include "support/Logger.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Frontend/CompilerInvocation.h"
#include "clang/Lex/PreprocessorOptions.h"
#include "clang/Serialization/PCHContainerOperations.h"
#include "llvm/ADT/StringRef.h"

namespace clang {
namespace clangd {

void IgnoreDiagnostics::log(DiagnosticsEngine::Level DiagLevel,
                            const clang::Diagnostic &Info) {
  // FIXME: format lazily, in case vlog is off.
  llvm::SmallString<64> Message;
  Info.FormatDiagnostic(Message);

  llvm::SmallString<64> Location;
  if (Info.hasSourceManager() && Info.getLocation().isValid()) {
    auto &SourceMgr = Info.getSourceManager();
    auto Loc = SourceMgr.getFileLoc(Info.getLocation());
    llvm::raw_svector_ostream OS(Location);
    Loc.print(OS, SourceMgr);
    OS << ":";
  }

  clangd::vlog("Ignored diagnostic. {0}{1}", Location, Message);
}

void IgnoreDiagnostics::HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
                                         const clang::Diagnostic &Info) {
  IgnoreDiagnostics::log(DiagLevel, Info);
}

static bool AllowCrashPragmasForTest = false;
void allowCrashPragmasForTest() { AllowCrashPragmasForTest = true; }

void disableUnsupportedOptions(CompilerInvocation &CI) {
  // Disable "clang -verify" diagnostics, they are rarely useful in clangd, and
  // our compiler invocation set-up doesn't seem to work with it (leading
  // assertions in VerifyDiagnosticConsumer).
  CI.getDiagnosticOpts().VerifyDiagnostics = false;
  CI.getDiagnosticOpts().ShowColors = false;

  // Disable any dependency outputting, we don't want to generate files or write
  // to stdout/stderr.
  CI.getDependencyOutputOpts().ShowIncludesDest = ShowIncludesDestination::None;
  CI.getDependencyOutputOpts().OutputFile.clear();
  CI.getDependencyOutputOpts().HeaderIncludeOutputFile.clear();
  CI.getDependencyOutputOpts().DOTOutputFile.clear();
  CI.getDependencyOutputOpts().ModuleDependencyOutputDir.clear();

  // Disable any pch generation/usage operations. Since serialized preamble
  // format is unstable, using an incompatible one might result in unexpected
  // behaviours, including crashes.
  CI.getPreprocessorOpts().ImplicitPCHInclude.clear();
  CI.getPreprocessorOpts().PrecompiledPreambleBytes = {0, false};
  CI.getPreprocessorOpts().PCHThroughHeader.clear();
  CI.getPreprocessorOpts().PCHWithHdrStop = false;
  CI.getPreprocessorOpts().PCHWithHdrStopCreate = false;
  // Don't crash on `#pragma clang __debug parser_crash`
  if (!AllowCrashPragmasForTest)
    CI.getPreprocessorOpts().DisablePragmaDebugCrash = true;

  // Always default to raw container format as clangd doesn't registry any other
  // and clang dies when faced with unknown formats.
  CI.getHeaderSearchOpts().ModuleFormat =
      PCHContainerOperations().getRawReader().getFormats().front().str();

  CI.getFrontendOpts().Plugins.clear();
  CI.getFrontendOpts().AddPluginActions.clear();
  CI.getFrontendOpts().PluginArgs.clear();
  CI.getFrontendOpts().ProgramAction = frontend::ParseSyntaxOnly;
  CI.getFrontendOpts().ActionName.clear();

  // These options mostly affect codegen, and aren't relevant to clangd. And
  // clang will die immediately when these files are not existed.
  // Disable these uninteresting options to make clangd more robust.
  CI.getLangOpts().NoSanitizeFiles.clear();
  CI.getLangOpts().XRayAttrListFiles.clear();
  CI.getLangOpts().ProfileListFiles.clear();
  CI.getLangOpts().XRayAlwaysInstrumentFiles.clear();
  CI.getLangOpts().XRayNeverInstrumentFiles.clear();
}

std::unique_ptr<CompilerInvocation>
buildCompilerInvocation(const ParseInputs &Inputs, clang::DiagnosticConsumer &D,
                        std::vector<std::string> *CC1Args) {
  llvm::ArrayRef<std::string> Argv = Inputs.CompileCommand.CommandLine;
  if (Argv.empty())
    return nullptr;
  std::vector<const char *> ArgStrs;
  ArgStrs.reserve(Argv.size() + 1);
  // In asserts builds, CompilerInvocation redundantly reads/parses cc1 args as
  // a sanity test. This is not useful to clangd, and costs 10% of test time.
  // To avoid mismatches between assert/production builds, disable it always.
  ArgStrs = {Argv.front().c_str(), "-Xclang", "-no-round-trip-args"};
  for (const auto &S : Argv.drop_front())
    ArgStrs.push_back(S.c_str());

  CreateInvocationOptions CIOpts;
  CIOpts.VFS = Inputs.TFS->view(Inputs.CompileCommand.Directory);
  CIOpts.CC1Args = CC1Args;
  CIOpts.RecoverOnError = true;
  CIOpts.Diags = CompilerInstance::createDiagnostics(
      *CIOpts.VFS, new DiagnosticOptions, &D, false);
  CIOpts.ProbePrecompiled = false;
  std::unique_ptr<CompilerInvocation> CI = createInvocation(ArgStrs, CIOpts);
  if (!CI)
    return nullptr;
  // createInvocationFromCommandLine sets DisableFree.
  CI->getFrontendOpts().DisableFree = false;
  CI->getLangOpts().CommentOpts.ParseAllComments = true;
  CI->getLangOpts().RetainCommentsFromSystemHeaders = true;

  disableUnsupportedOptions(*CI);
  return CI;
}

std::unique_ptr<CompilerInstance>
prepareCompilerInstance(std::unique_ptr<clang::CompilerInvocation> CI,
                        const PrecompiledPreamble *Preamble,
                        std::unique_ptr<llvm::MemoryBuffer> Buffer,
                        llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
                        DiagnosticConsumer &DiagsClient) {
  assert(VFS && "VFS is null");
  assert(!CI->getPreprocessorOpts().RetainRemappedFileBuffers &&
         "Setting RetainRemappedFileBuffers to true will cause a memory leak "
         "of ContentsBuffer");

  // NOTE: we use Buffer.get() when adding remapped files, so we have to make
  // sure it will be released if no error is emitted.
  if (Preamble) {
    Preamble->OverridePreamble(*CI, VFS, Buffer.get());
  } else {
    CI->getPreprocessorOpts().addRemappedFile(
        CI->getFrontendOpts().Inputs[0].getFile(), Buffer.get());
  }

  auto Clang = std::make_unique<CompilerInstance>(
      std::make_shared<PCHContainerOperations>());
  Clang->setInvocation(std::move(CI));
  Clang->createDiagnostics(*VFS, &DiagsClient, false);

  if (auto VFSWithRemapping = createVFSFromCompilerInvocation(
          Clang->getInvocation(), Clang->getDiagnostics(), VFS))
    VFS = VFSWithRemapping;
  Clang->createFileManager(VFS);

  if (!Clang->createTarget())
    return nullptr;

  // RemappedFileBuffers will handle the lifetime of the Buffer pointer,
  // release it.
  Buffer.release();
  return Clang;
}

} // namespace clangd
} // namespace clang
