================
@@ -0,0 +1,250 @@
+//===- CompilerInstanceWithContext.cpp - clang scanning compiler instance 
-===//
+//
+// 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 "clang/Tooling/DependencyScanning/CompilerInstanceWithContext.h"
+#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Frontend/FrontendActions.h"
+#include "clang/Tooling/DependencyScanning/DependencyScanningWorker.h"
+#include "clang/Tooling/DependencyScanning/ModuleDepCollector.h"
+#include "llvm/TargetParser/Host.h"
+
+using namespace clang;
+using namespace tooling;
+using namespace dependencies;
+
+const std::string CompilerInstanceWithContext::FakeFileBuffer =
+    std::string(MAX_NUM_NAMES, ' ');
+
+llvm::Error CompilerInstanceWithContext::initialize() {
+  // Virtual file system setup
+  // - Set the current working directory.
+  Worker.BaseFS->setCurrentWorkingDirectory(CWD);
+  OverlayFS =
+      llvm::makeIntrusiveRefCnt<llvm::vfs::OverlayFileSystem>(Worker.BaseFS);
+  InMemoryFS = llvm::makeIntrusiveRefCnt<llvm::vfs::InMemoryFileSystem>();
+  InMemoryFS->setCurrentWorkingDirectory(CWD);
+
+  // - Create the fake file as scanning input source file and setup overlay
+  //   FS.
+  SmallString<128> FakeInputPath;
+  llvm::sys::fs::createUniquePath("ScanningCI-%%%%%%%%.input", FakeInputPath,
+                                  /*MakeAbsolute=*/false);
+  InMemoryFS->addFile(FakeInputPath, 0,
+                      llvm::MemoryBuffer::getMemBuffer(FakeFileBuffer));
+  InMemoryOverlay = InMemoryFS;
+  // TODO: we need to handle CAS/CASFS here.
+  //    if (Worker.CAS && !Worker.DepCASFS)
+  //     InMemoryOverlay = llvm::cas::createCASProvidingFileSystem(
+  //         Worker.CAS, std::move(InMemoryFS));
+  OverlayFS->pushOverlay(InMemoryOverlay);
+
+  // Augument the command line.
+  CommandLine.emplace_back(FakeInputPath);
+
+  // Create the file manager, the diagnostics engine, and the source manager.
+  FileMgr = std::make_unique<FileManager>(FileSystemOptions{}, OverlayFS);
+  DiagnosticOutput.clear();
+  auto DiagOpts = createDiagOptions(CommandLine);
+  DiagPrinter = std::make_unique<TextDiagnosticPrinter>(DiagnosticsOS,
+                                                        *(DiagOpts.release()));
+  std::vector<const char *> CCommandLine(CommandLine.size(), nullptr);
+  llvm::transform(CommandLine, CCommandLine.begin(),
+                  [](const std::string &Str) { return Str.c_str(); });
+  DiagOpts = CreateAndPopulateDiagOpts(CCommandLine);
+  sanitizeDiagOpts(*DiagOpts);
+  Diags = CompilerInstance::createDiagnostics(*OverlayFS, 
*(DiagOpts.release()),
+                                              DiagPrinter.get(),
+                                              /*ShouldOwnClient=*/false);
+  SrcMgr = std::make_unique<SourceManager>(*Diags, *FileMgr);
+  Diags->setSourceManager(SrcMgr.get());
+
+  // Create the compiler invocation.
+  Driver = std::make_unique<driver::Driver>(
+      CCommandLine[0], llvm::sys::getDefaultTargetTriple(), *Diags,
+      "clang LLVM compiler", OverlayFS);
+  Driver->setTitle("clang_based_tool");
+  Compilation.reset(Driver->BuildCompilation(llvm::ArrayRef(CCommandLine)));
+
+  if (Compilation->containsError()) {
+    return llvm::make_error<llvm::StringError>("Failed to build compilation",
+                                               llvm::inconvertibleErrorCode());
+  }
+
+  const driver::Command &Command = *(Compilation->getJobs().begin());
+  const auto &CommandArgs = Command.getArguments();
+  size_t ArgSize = CommandArgs.size();
+  assert(ArgSize >= 1 && "Cannot have a command with 0 args");
+  const char *FirstArg = CommandArgs[0];
+  if (strcmp(FirstArg, "-cc1"))
+    return llvm::make_error<llvm::StringError>(
+        "Incorrect compilation command, missing cc1",
+        llvm::inconvertibleErrorCode());
+  Invocation = std::make_unique<CompilerInvocation>();
+  CompilerInvocation::CreateFromArgs(*Invocation, Command.getArguments(),
+                                     *Diags, Command.getExecutable());
----------------
qiongsiwu wrote:

I'd like to chat off line about this in a bit more detail to understand what 
exactly I can make local. It seems that a lot of these are wired into the 
diagnostics engine, which is in turn used in the compiler invocation and the 
compiler instance. 

https://github.com/llvm/llvm-project/pull/160207
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to