//===--- 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;
  DiagnosticOptions DiagOpts;
  CIOpts.Diags =
      CompilerInstance::createDiagnostics(*CIOpts.VFS, DiagOpts, &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::move(CI));
  Clang->createVirtualFileSystem(VFS, &DiagsClient);
  Clang->createDiagnostics(&DiagsClient, false);
  Clang->createFileManager();
  if (!Clang->createTarget())
    return nullptr;

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

} // namespace clangd
} // namespace clang
