Skip to content

Commit 094754c

Browse files
committed
Cleaning up CompilerInstanceWithContext's initialization.
1 parent 1948276 commit 094754c

File tree

2 files changed

+58
-125
lines changed

2 files changed

+58
-125
lines changed

clang/include/clang/Tooling/DependencyScanning/DependencyScannerImpl.h

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,8 @@ initVFSForTUBuferScanning(IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS,
120120
StringRef WorkingDirectory,
121121
llvm::MemoryBufferRef TUBuffer);
122122

123-
std::pair<IntrusiveRefCntPtr<llvm::vfs::FileSystem>, std::vector<std::string>>
123+
std::pair<IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem>,
124+
std::vector<std::string>>
124125
initVFSForByNameScanning(IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS,
125126
ArrayRef<std::string> CommandLine,
126127
StringRef WorkingDirectory, StringRef ModuleName);
@@ -163,16 +164,10 @@ class CompilerInstanceWithContext {
163164

164165
// Context - file systems
165166
llvm::IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> OverlayFS;
166-
llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFS;
167-
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> InMemoryOverlay;
168167

169-
// Context - Diagnostics engine, file manager and source mamanger.
170-
std::string DiagnosticOutput;
171-
llvm::raw_string_ostream DiagnosticsOS;
172-
std::unique_ptr<TextDiagnosticPrinter> DiagPrinter;
173-
IntrusiveRefCntPtr<DiagnosticsEngine> Diags;
174-
std::unique_ptr<FileManager> FileMgr;
175-
std::unique_ptr<SourceManager> SrcMgr;
168+
// Context - Diagnostics engine.
169+
std::unique_ptr<TextDiagnosticsPrinterWithOutput> DiagPrinterWithOS;
170+
std::unique_ptr<DignosticsEngineWithDiagOpts> DiagEngineWithCmdAndOpts;
176171

177172
// Context - compiler invocation
178173
std::unique_ptr<clang::driver::Driver> Driver;
@@ -196,8 +191,7 @@ class CompilerInstanceWithContext {
196191
public:
197192
CompilerInstanceWithContext(DependencyScanningWorker &Worker, StringRef CWD,
198193
const std::vector<std::string> &CMD)
199-
: Worker(Worker), CWD(CWD), CommandLine(CMD),
200-
DiagnosticsOS(DiagnosticOutput) {};
194+
: Worker(Worker), CWD(CWD), CommandLine(CMD) {};
201195

202196
llvm::Error initialize();
203197
llvm::Error computeDependencies(StringRef ModuleName,

clang/lib/Tooling/DependencyScanning/DependencyScannerImpl.cpp

Lines changed: 52 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -456,7 +456,8 @@ initVFSForTUBuferScanning(IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS,
456456
return std::make_pair(ModifiedFS, ModifiedCommandLine);
457457
}
458458

459-
std::pair<IntrusiveRefCntPtr<llvm::vfs::FileSystem>, std::vector<std::string>>
459+
std::pair<IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem>,
460+
std::vector<std::string>>
460461
initVFSForByNameScanning(IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS,
461462
ArrayRef<std::string> CommandLine,
462463
StringRef WorkingDirectory, StringRef ModuleName) {
@@ -489,6 +490,9 @@ bool initializeScanCompilerInstance(
489490
IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS,
490491
DiagnosticConsumer *DiagConsumer, DependencyScanningService &Service,
491492
IntrusiveRefCntPtr<DependencyScanningWorkerFilesystem> DepFS) {
493+
// TODO: the commented out code here should be un-commented when
494+
// we enable CAS.
495+
// ScanInstance.getInvocation().getCASOpts() = Worker.CASOpts;
492496
ScanInstance.setBuildingModule(false);
493497

494498
ScanInstance.createVirtualFileSystem(FS, DiagConsumer);
@@ -710,56 +714,18 @@ const std::string CompilerInstanceWithContext::FakeFileBuffer =
710714
std::string(MAX_NUM_NAMES, ' ');
711715

712716
llvm::Error CompilerInstanceWithContext::initialize() {
713-
// Virtual file system setup
714-
// - Set the current working directory.
715-
Worker.BaseFS->setCurrentWorkingDirectory(CWD);
716-
OverlayFS =
717-
llvm::makeIntrusiveRefCnt<llvm::vfs::OverlayFileSystem>(Worker.BaseFS);
718-
InMemoryFS = llvm::makeIntrusiveRefCnt<llvm::vfs::InMemoryFileSystem>();
719-
InMemoryFS->setCurrentWorkingDirectory(CWD);
720-
721-
// - Create the fake file as scanning input source file and setup overlay
722-
// FS.
723-
SmallString<128> FakeInputPath;
724-
llvm::sys::fs::createUniquePath("ScanningCI-%%%%%%%%.input", FakeInputPath,
725-
/*MakeAbsolute=*/false);
726-
InMemoryFS->addFile(FakeInputPath, 0,
727-
llvm::MemoryBuffer::getMemBuffer(FakeFileBuffer));
728-
InMemoryOverlay = InMemoryFS;
729-
// TODO: we need to handle CAS/CASFS here.
730-
// if (Worker.CAS && !Worker.DepCASFS)
731-
// InMemoryOverlay = llvm::cas::createCASProvidingFileSystem(
732-
// Worker.CAS, std::move(InMemoryFS));
733-
OverlayFS->pushOverlay(InMemoryOverlay);
717+
std::tie(OverlayFS, CommandLine) = initVFSForByNameScanning(
718+
Worker.BaseFS, CommandLine, CWD, "ScanningByName");
734719

735-
// Augument the command line.
736-
CommandLine.emplace_back(FakeInputPath);
720+
DiagPrinterWithOS =
721+
std::make_unique<TextDiagnosticsPrinterWithOutput>(CommandLine);
722+
DiagEngineWithCmdAndOpts = std::make_unique<DignosticsEngineWithDiagOpts>(
723+
CommandLine, OverlayFS, DiagPrinterWithOS->DiagPrinter);
737724

738-
// Create the file manager, the diagnostics engine, and the source manager.
739-
FileMgr = std::make_unique<FileManager>(FileSystemOptions{}, OverlayFS);
740-
DiagnosticOutput.clear();
741-
auto DiagOpts = createDiagOptions(CommandLine);
742-
DiagPrinter = std::make_unique<TextDiagnosticPrinter>(DiagnosticsOS,
743-
*(DiagOpts.release()));
744-
std::vector<const char *> CCommandLine(CommandLine.size(), nullptr);
745-
llvm::transform(CommandLine, CCommandLine.begin(),
746-
[](const std::string &Str) { return Str.c_str(); });
747-
DiagOpts = CreateAndPopulateDiagOpts(CCommandLine);
748-
sanitizeDiagOpts(*DiagOpts);
749-
Diags = CompilerInstance::createDiagnostics(*OverlayFS, *(DiagOpts.release()),
750-
DiagPrinter.get(),
751-
/*ShouldOwnClient=*/false);
752-
SrcMgr = std::make_unique<SourceManager>(*Diags, *FileMgr);
753-
Diags->setSourceManager(SrcMgr.get());
754-
755-
// Create the compiler invocation.
756-
Driver = std::make_unique<driver::Driver>(
757-
CCommandLine[0], llvm::sys::getDefaultTargetTriple(), *Diags,
758-
"clang LLVM compiler", OverlayFS);
759-
Driver->setTitle("clang_based_tool");
760-
Compilation.reset(Driver->BuildCompilation(llvm::ArrayRef(CCommandLine)));
725+
std::tie(Driver, Compilation) = buildCompilation(
726+
CommandLine, *DiagEngineWithCmdAndOpts->DiagEngine, OverlayFS);
761727

762-
if (Compilation->containsError()) {
728+
if (!Compilation) {
763729
return llvm::make_error<llvm::StringError>("Failed to build compilation",
764730
llvm::inconvertibleErrorCode());
765731
}
@@ -776,8 +742,28 @@ llvm::Error CompilerInstanceWithContext::initialize() {
776742
Invocation = std::make_unique<CompilerInvocation>();
777743

778744
if (!CompilerInvocation::CreateFromArgs(*Invocation, Command.getArguments(),
779-
*Diags, Command.getExecutable())) {
780-
Diags->Report(diag::err_fe_expected_compiler_job)
745+
*DiagEngineWithCmdAndOpts->DiagEngine,
746+
Command.getExecutable())) {
747+
DiagEngineWithCmdAndOpts->DiagEngine->Report(
748+
diag::err_fe_expected_compiler_job)
749+
<< llvm::join(CommandLine, " ");
750+
return llvm::make_error<llvm::StringError>(
751+
"Cannot create CompilerInvocation from Args",
752+
llvm::inconvertibleErrorCode());
753+
}
754+
755+
// TODO: CMDArgsStrVector is making string copies. We should optimize later
756+
// and avoid the copies.
757+
std::vector<std::string> CMDArgsStrVector(ArgSize + 1);
758+
CMDArgsStrVector.push_back(Command.getExecutable());
759+
llvm::transform(CommandArgs, CMDArgsStrVector.begin() + 1,
760+
[](const char *s) { return std::string(s); });
761+
762+
Invocation = createCompilerInvocation(CMDArgsStrVector,
763+
*DiagEngineWithCmdAndOpts->DiagEngine);
764+
if (!Invocation) {
765+
DiagEngineWithCmdAndOpts->DiagEngine->Report(
766+
diag::err_fe_expected_compiler_job)
781767
<< llvm::join(CommandLine, " ");
782768
return llvm::make_error<llvm::StringError>(
783769
"Cannot create CompilerInvocation from Args",
@@ -798,69 +784,22 @@ llvm::Error CompilerInstanceWithContext::initialize() {
798784
ModCache.get());
799785
auto &CI = *CIPtr;
800786

801-
// TODO: the commented out code here should be un-commented when
802-
// we enable CAS.
803-
// CI.getInvocation().getCASOpts() = Worker.CASOpts;
804-
CI.setBuildingModule(false);
805-
CI.createVirtualFileSystem(OverlayFS, Diags->getClient());
806-
sanitizeDiagOpts(CI.getDiagnosticOpts());
807-
CI.createDiagnostics(DiagPrinter.get(), false);
808-
CI.getPreprocessorOpts().AllowPCHWithDifferentModulesCachePath = true;
809-
CI.getFrontendOpts().GenerateGlobalModuleIndex = false;
810-
CI.getFrontendOpts().UseGlobalModuleIndex = false;
811-
// CI.getFrontendOpts().ModulesShareFileManager = Worker.DepCASFS ? false :
812-
// true;
813-
CI.getHeaderSearchOpts().ModuleFormat = "raw";
814-
CI.getHeaderSearchOpts().ModulesIncludeVFSUsage =
815-
any(Worker.Service.getOptimizeArgs() & ScanningOptimizations::VFS);
816-
CI.getHeaderSearchOpts().ModulesStrictContextHash = true;
817-
CI.getHeaderSearchOpts().ModulesSerializeOnlyPreprocessor = true;
818-
CI.getHeaderSearchOpts().ModulesSkipDiagnosticOptions = true;
819-
CI.getHeaderSearchOpts().ModulesSkipHeaderSearchPaths = true;
820-
CI.getHeaderSearchOpts().ModulesSkipPragmaDiagnosticMappings = true;
821-
CI.getPreprocessorOpts().ModulesCheckRelocated = false;
822-
823-
if (CI.getHeaderSearchOpts().ModulesValidateOncePerBuildSession)
824-
CI.getHeaderSearchOpts().BuildSessionTimestamp =
825-
Worker.Service.getBuildSessionTimestamp();
826-
827-
CI.createFileManager();
828-
auto *FileMgr = CI.getFileManagerPtr().get();
829-
830-
if (Worker.DepFS) {
831-
Worker.DepFS->resetBypassedPathPrefix();
832-
if (!CI.getHeaderSearchOpts().ModuleCachePath.empty()) {
833-
SmallString<256> ModulesCachePath;
834-
normalizeModuleCachePath(
835-
*FileMgr, CI.getHeaderSearchOpts().ModuleCachePath, ModulesCachePath);
836-
Worker.DepFS->setBypassedPathPrefix(ModulesCachePath);
837-
}
838-
839-
CI.setDependencyDirectivesGetter(
840-
std::make_unique<ScanningDependencyDirectivesGetter>(*FileMgr));
787+
if (!initializeScanCompilerInstance(
788+
CI, OverlayFS, DiagEngineWithCmdAndOpts->DiagEngine->getClient(),
789+
Worker.Service, Worker.DepFS)) {
790+
return llvm::make_error<llvm::StringError>(
791+
"Cannot initialize scanning compiler instance",
792+
llvm::inconvertibleErrorCode());
841793
}
842794

843-
CI.createSourceManager();
795+
llvm::SmallVector<StringRef> StableDirs = getInitialStableDirs(CI);
796+
auto MaybePrebuiltModulesASTMap =
797+
computePrebuiltModulesASTMap(CI, StableDirs);
798+
if (!MaybePrebuiltModulesASTMap)
799+
return llvm::make_error<llvm::StringError>(
800+
"Prebuilt module scanning failed", llvm::inconvertibleErrorCode());
844801

845-
const StringRef Sysroot = CI.getHeaderSearchOpts().Sysroot;
846-
if (!Sysroot.empty() && (llvm::sys::path::root_directory(Sysroot) != Sysroot))
847-
StableDirs = {Sysroot, CI.getHeaderSearchOpts().ResourceDir};
848-
if (!CI.getPreprocessorOpts().ImplicitPCHInclude.empty())
849-
if (visitPrebuiltModule(CI.getPreprocessorOpts().ImplicitPCHInclude, CI,
850-
CI.getHeaderSearchOpts().PrebuiltModuleFiles,
851-
PrebuiltModuleVFSMap, CI.getDiagnostics(),
852-
StableDirs))
853-
return llvm::make_error<llvm::StringError>(
854-
"Prebuilt module scanning failed", llvm::inconvertibleErrorCode());
855-
856-
OutputOpts = std::make_unique<DependencyOutputOptions>();
857-
std::swap(*OutputOpts, CI.getInvocation().getDependencyOutputOpts());
858-
// We need at least one -MT equivalent for the generator of make dependency
859-
// files to work.
860-
if (OutputOpts->Targets.empty())
861-
OutputOpts->Targets = {deduceDepTarget(CI.getFrontendOpts().OutputFile,
862-
CI.getFrontendOpts().Inputs)};
863-
OutputOpts->IncludeSystemHeaders = true;
802+
OutputOpts = takeDependencyOutputOptionsFrom(CI);
864803

865804
CI.createTarget();
866805
// CI.initializeDelayedInputFileFromCAS();
@@ -886,9 +825,9 @@ llvm::Error CompilerInstanceWithContext::computeDependencies(
886825
std::make_unique<GetDependenciesByModuleNameAction>(ModuleName);
887826
auto InputFile = CI.getFrontendOpts().Inputs.begin();
888827

889-
if (!SrcLocOffset)
828+
if (!SrcLocOffset) {
890829
Action->BeginSourceFile(CI, *InputFile);
891-
else {
830+
} else {
892831
CI.getPreprocessor().removePPCallbacks();
893832
}
894833

@@ -943,6 +882,6 @@ llvm::Error CompilerInstanceWithContext::computeDependencies(
943882
}
944883

945884
llvm::Error CompilerInstanceWithContext::finalize() {
946-
DiagPrinter->finish();
885+
DiagPrinterWithOS->DiagPrinter.finish();
947886
return llvm::Error::success();
948887
}

0 commit comments

Comments
 (0)