clang: lib/DependencyScanning/DependencyScannerImpl.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

15#include "llvm/ADT/ScopeExit.h"

16#include "llvm/TargetParser/Host.h"

17

18using namespace clang;

20

21namespace {

22

24public:

25 DependencyConsumerForwarder(std::unique_ptr Opts,

26 StringRef WorkingDirectory, DependencyConsumer &C)

27 : DependencyFileGenerator(*Opts), WorkingDirectory(WorkingDirectory),

28 Opts(std::move(Opts)), C(C) {}

29

30 void finishedMainFile(DiagnosticsEngine &Diags) override {

31 C.handleDependencyOutputOpts(*Opts);

32 llvm::SmallString<256> CanonPath;

33 for (const auto &File : getDependencies()) {

34 CanonPath = File;

35 llvm::sys::path::remove_dots(CanonPath, true);

36 llvm::sys::path::make_absolute(WorkingDirectory, CanonPath);

37 C.handleFileDependency(CanonPath);

38 }

39 }

40

41private:

42 StringRef WorkingDirectory;

43 std::unique_ptr Opts;

44 DependencyConsumer &C;

45};

46

51 if (LangOpts.Modules) {

53 if (Diags) {

54 Diags->Report(diag::warn_pch_vfsoverlay_mismatch);

56 if (VFSOverlays.empty()) {

57 Diags->Report(diag::note_pch_vfsoverlay_empty) << Type;

58 } else {

59 std::string Files = llvm::join(VFSOverlays, "\n");

60 Diags->Report(diag::note_pch_vfsoverlay_files) << Type << Files;

61 }

62 };

65 }

66 }

67 }

68 return false;

69}

70

72

73

74

75

77public:

78 PrebuiltModuleListener(PrebuiltModuleFilesT &PrebuiltModuleFiles,

79 llvm::SmallVectorstd::string &NewModuleFiles,

81 const HeaderSearchOptions &HSOpts,

82 const LangOptions &LangOpts, DiagnosticsEngine &Diags,

83 const ArrayRef StableDirs)

84 : PrebuiltModuleFiles(PrebuiltModuleFiles),

85 NewModuleFiles(NewModuleFiles),

86 PrebuiltModulesASTMap(PrebuiltModulesASTMap), ExistingHSOpts(HSOpts),

87 ExistingLangOpts(LangOpts), Diags(Diags), StableDirs(StableDirs) {}

88

89 bool needsImportVisitation() const override { return true; }

90 bool needsInputFileVisitation() override { return true; }

91 bool needsSystemInputFileVisitation() override { return true; }

92

93

94

95 void visitImport(StringRef ModuleName, StringRef Filename) override {

96 if (PrebuiltModuleFiles.insert({ModuleName.str(), Filename.str()}).second)

97 NewModuleFiles.push_back(Filename.str());

98

99 auto PrebuiltMapEntry = PrebuiltModulesASTMap.try_emplace(Filename);

100 PrebuiltModuleASTAttrs &PrebuiltModule = PrebuiltMapEntry.first->second;

101 if (PrebuiltMapEntry.second)

103

104 if (auto It = PrebuiltModulesASTMap.find(CurrentFile);

105 It != PrebuiltModulesASTMap.end() && CurrentFile != Filename)

107 }

108

109

110

111

112 bool visitInputFileAsRequested(StringRef FilenameAsRequested,

113 StringRef Filename, bool isSystem,

114 bool isOverridden,

115 bool isExplicitModule) override {

116 if (StableDirs.empty())

117 return false;

118 auto PrebuiltEntryIt = PrebuiltModulesASTMap.find(CurrentFile);

119 if ((PrebuiltEntryIt == PrebuiltModulesASTMap.end()) ||

120 (!PrebuiltEntryIt->second.isInStableDir()))

121 return false;

122

123 PrebuiltEntryIt->second.setInStableDir(

125 return PrebuiltEntryIt->second.isInStableDir();

126 }

127

128

129 void visitModuleFile(StringRef Filename,

131

132

133 auto PrebuiltEntryIt = PrebuiltModulesASTMap.find(CurrentFile);

134 if ((PrebuiltEntryIt != PrebuiltModulesASTMap.end()) &&

135 !PrebuiltEntryIt->second.isInStableDir())

136 PrebuiltEntryIt->second.updateDependentsNotInStableDirs(

137 PrebuiltModulesASTMap);

138 CurrentFile = Filename;

139 }

140

141

142

143 bool ReadHeaderSearchOptions(const HeaderSearchOptions &HSOpts,

144 StringRef ModuleFilename,

145 StringRef SpecificModuleCachePath,

146 bool Complain) override {

147

148 auto PrebuiltMapEntry = PrebuiltModulesASTMap.try_emplace(CurrentFile);

149 PrebuiltModuleASTAttrs &PrebuiltModule = PrebuiltMapEntry.first->second;

150 if (PrebuiltMapEntry.second)

152

155

156 return false;

157 }

158

159

160 bool ReadHeaderSearchPaths(const HeaderSearchOptions &HSOpts,

161 bool Complain) override {

162

163 auto PrebuiltMapEntry = PrebuiltModulesASTMap.try_emplace(CurrentFile);

164 PrebuiltModuleASTAttrs &PrebuiltModule = PrebuiltMapEntry.first->second;

165 if (PrebuiltMapEntry.second)

167

168 PrebuiltModule.setVFS(

169 llvm::StringSet<>(llvm::from_range, HSOpts.VFSOverlayFiles));

170

171 return checkHeaderSearchPaths(

172 HSOpts, ExistingHSOpts, Complain ? &Diags : nullptr, ExistingLangOpts);

173 }

174

175private:

176 PrebuiltModuleFilesT &PrebuiltModuleFiles;

177 llvm::SmallVectorstd::string &NewModuleFiles;

179 const HeaderSearchOptions &ExistingHSOpts;

180 const LangOptions &ExistingLangOpts;

181 DiagnosticsEngine &Diags;

182 std::string CurrentFile;

183 const ArrayRef StableDirs;

184};

185

186

187

188static bool visitPrebuiltModule(StringRef PrebuiltModuleFilename,

190 PrebuiltModuleFilesT &ModuleFiles,

194

196

197 PrebuiltModuleListener Listener(ModuleFiles, Worklist, PrebuiltModulesASTMap,

199 Diags, StableDirs);

200

201 Listener.visitModuleFile(PrebuiltModuleFilename,

206 false, Listener,

208 return true;

209

210 while (!Worklist.empty()) {

215 false, Listener,

216 false))

217 return true;

218 }

219 return false;

220}

221

222

223static std::string makeObjFileName(StringRef FileName) {

225 llvm::sys::path::replace_extension(ObjFileName, "o");

226 return std::string(ObjFileName);

227}

228

229

230static std::string

231deduceDepTarget(const std::string &OutputFile,

233 if (OutputFile != "-")

234 return OutputFile;

235

236 if (InputFiles.empty() || !InputFiles.front().isFile())

237 return "clang-scan-deps\\ dependency";

238

239 return makeObjFileName(InputFiles.front().getFile());

240}

241

242

243

244

245

246

247

248

249

250

251

252static std::optional getSimpleMacroName(StringRef Macro) {

253 StringRef Name = Macro.split("=").first.ltrim(" \t");

254 std::size_t I = 0;

255

256 auto FinishName = [&]() -> std::optional {

257 StringRef SimpleName = Name.slice(0, I);

258 if (SimpleName.empty())

259 return std::nullopt;

260 return SimpleName;

261 };

262

263 for (; I != Name.size(); ++I) {

264 switch (Name[I]) {

265 case '(':

266 case ' ':

267 case '\t':

268 return FinishName();

269 case '_':

270 continue;

271 default:

272 if (llvm::isAlnum(Name[I]))

273 continue;

274 return std::nullopt;

275 }

276 }

277 return FinishName();

278}

279

281 using MacroOpt = std::pair<StringRef, std::size_t>;

282 std::vector SimpleNames;

283 SimpleNames.reserve(PPOpts.Macros.size());

284 std::size_t Index = 0;

285 for (const auto &M : PPOpts.Macros) {

286 auto SName = getSimpleMacroName(M.first);

287

288 if (!SName)

289 return;

290 SimpleNames.emplace_back(*SName, Index);

291 ++Index;

292 }

293

294 llvm::stable_sort(SimpleNames, llvm::less_first());

295

296 auto NewEnd = std::unique(

297 SimpleNames.rbegin(), SimpleNames.rend(),

298 [](const MacroOpt &A, const MacroOpt &B) { return A.first == B.first; });

299 SimpleNames.erase(SimpleNames.begin(), NewEnd.base());

300

301

302 decltype(PPOpts.Macros) NewMacros;

303 NewMacros.reserve(SimpleNames.size());

304 for (std::size_t I = 0, E = SimpleNames.size(); I != E; ++I) {

305 std::size_t OriginalIndex = SimpleNames[I].second;

306

307 NewMacros.push_back(std::move(PPOpts.Macros[OriginalIndex]));

308 }

309 std::swap(PPOpts.Macros, NewMacros);

310}

311

313 DependencyScanningWorkerFilesystem *DepFS;

314

315public:

316 ScanningDependencyDirectivesGetter(FileManager &FileMgr) : DepFS(nullptr) {

318 auto *DFS = llvm::dyn_cast(&FS);

319 if (DFS) {

320 assert(!DepFS && "Found multiple scanning VFSs");

321 DepFS = DFS;

322 }

323 });

324 assert(DepFS && "Did not find scanning VFS");

325 }

326

327 std::unique_ptr

328 cloneFor(FileManager &FileMgr) override {

329 return std::make_unique(FileMgr);

330 }

331

332 std::optional<ArrayRef<dependency_directives_scan::Directive>>

333 operator()(FileEntryRef File) override {

334 return DepFS->getDirectiveTokens(File.getName());

335 }

336};

337

338

340

341 DiagOpts.ShowCarets = false;

342

344

345

346

347

348

349

350

351 llvm::erase_if(DiagOpts.Warnings, [](StringRef Warning) {

352 return llvm::StringSwitch(Warning)

353 .Cases({"pch-vfs-diff", "error=pch-vfs-diff"}, false)

354 .StartsWith("no-error=", false)

355 .Default(true);

356 });

357}

358}

359

360std::unique_ptr

362 std::vector<const char *> CLI;

363 for (const std::string &Arg : CommandLine)

364 CLI.push_back(Arg.c_str());

366 sanitizeDiagOpts(*DiagOpts);

367 return DiagOpts;

368}

369

373 std::vector<const char *> CCommandLine(CommandLine.size(), nullptr);

374 llvm::transform(CommandLine, CCommandLine.begin(),

375 [](const std::string &Str) { return Str.c_str(); });

379 false);

380}

381

382std::pair<std::unique_ptrdriver::Driver, std::unique_ptrdriver::Compilation>

386 llvm::BumpPtrAllocator &Alloc) {

388 Argv.reserve(ArgStrs.size());

389 for (const std::string &Arg : ArgStrs)

390 Argv.push_back(Arg.c_str());

391

392 std::unique_ptrdriver::Driver Driver = std::make_uniquedriver::Driver(

393 Argv[0], llvm::sys::getDefaultTargetTriple(), Diags,

394 "clang LLVM compiler", FS);

395 Driver->setTitle("clang_based_tool");

396

399

400 if (llvm::Error E =

402 Diags.Report(diag::err_drv_expand_response_file)

403 << llvm::toString(std::move(E));

404 return std::make_pair(nullptr, nullptr);

405 }

406

407 std::unique_ptrdriver::Compilation Compilation(

408 Driver->BuildCompilation(Argv));

409 if (!Compilation)

410 return std::make_pair(nullptr, nullptr);

411

412 if (Compilation->containsError())

413 return std::make_pair(nullptr, nullptr);

414

415 return std::make_pair(std::move(Driver), std::move(Compilation));

416}

417

418std::unique_ptr

421 llvm::opt::ArgStringList Argv;

422 for (const std::string &Str : ArrayRef(CommandLine).drop_front())

423 Argv.push_back(Str.c_str());

424

425 auto Invocation = std::make_unique();

427

428 return nullptr;

429 }

430 return Invocation;

431}

432

433std::pair<IntrusiveRefCntPtrllvm::vfs::OverlayFileSystem,

434 std::vectorstd::string>

438 llvm::MemoryBufferRef TUBuffer) {

439

440 BaseFS->setCurrentWorkingDirectory(WorkingDirectory);

441

442 auto OverlayFS =

443 llvm::makeIntrusiveRefCntllvm::vfs::OverlayFileSystem(BaseFS);

444 auto InMemoryFS = llvm::makeIntrusiveRefCntllvm::vfs::InMemoryFileSystem();

445 InMemoryFS->setCurrentWorkingDirectory(WorkingDirectory);

446 auto InputPath = TUBuffer.getBufferIdentifier();

447 InMemoryFS->addFile(

448 InputPath, 0, llvm::MemoryBuffer::getMemBufferCopy(TUBuffer.getBuffer()));

450

451 OverlayFS->pushOverlay(InMemoryOverlay);

452 std::vectorstd::string ModifiedCommandLine(CommandLine);

453 ModifiedCommandLine.emplace_back(InputPath);

454

455 return std::make_pair(OverlayFS, ModifiedCommandLine);

456}

457

458std::pair<IntrusiveRefCntPtrllvm::vfs::OverlayFileSystem,

459 std::vectorstd::string>

463 StringRef ModuleName) {

464

465 BaseFS->setCurrentWorkingDirectory(WorkingDirectory);

466

467

468

469

470 auto OverlayFS =

471 llvm::makeIntrusiveRefCntllvm::vfs::OverlayFileSystem(BaseFS);

472 auto InMemoryFS = llvm::makeIntrusiveRefCntllvm::vfs::InMemoryFileSystem();

473 InMemoryFS->setCurrentWorkingDirectory(WorkingDirectory);

475

476 llvm::sys::fs::createUniquePath(ModuleName + "-%%%%%%%%.input", FakeInputPath,

477 false);

478 InMemoryFS->addFile(FakeInputPath, 0, llvm::MemoryBuffer::getMemBuffer(""));

480 OverlayFS->pushOverlay(InMemoryOverlay);

481

482 std::vectorstd::string ModifiedCommandLine(CommandLine);

483 ModifiedCommandLine.emplace_back(FakeInputPath);

484

485 return std::make_pair(OverlayFS, ModifiedCommandLine);

486}

487

495 ScanInstance.createDiagnostics(DiagConsumer, false);

498

499

501 DepFS->resetBypassedPathPrefix();

505 ModulesCachePath);

506 if (!ModulesCachePath.empty())

507 DepFS->setBypassedPathPrefix(ModulesCachePath);

508

510 std::make_unique(

512 }

513}

514

515

516static std::shared_ptr

519 auto ScanInvocation = std::make_shared(Invocation);

520

521 sanitizeDiagOpts(ScanInvocation->getDiagnosticOpts());

522

523 ScanInvocation->getPreprocessorOpts().AllowPCHWithDifferentModulesCachePath =

524 true;

525

526 if (ScanInvocation->getHeaderSearchOpts().ModulesValidateOncePerBuildSession)

527 ScanInvocation->getHeaderSearchOpts().BuildSessionTimestamp =

529

530 ScanInvocation->getFrontendOpts().DisableFree = false;

531 ScanInvocation->getFrontendOpts().GenerateGlobalModuleIndex = false;

532 ScanInvocation->getFrontendOpts().UseGlobalModuleIndex = false;

533 ScanInvocation->getFrontendOpts().GenReducedBMI = false;

534 ScanInvocation->getFrontendOpts().ModuleOutputPath.clear();

535

536

537 ScanInvocation->getFrontendOpts().ModulesShareFileManager = true;

538 ScanInvocation->getHeaderSearchOpts().ModuleFormat = "raw";

539 ScanInvocation->getHeaderSearchOpts().ModulesIncludeVFSUsage =

541

542

543

544

545

546

547 ScanInvocation->getHeaderSearchOpts().ModulesStrictContextHash = true;

548 ScanInvocation->getHeaderSearchOpts().ModulesSerializeOnlyPreprocessor = true;

549 ScanInvocation->getHeaderSearchOpts().ModulesSkipDiagnosticOptions = true;

550 ScanInvocation->getHeaderSearchOpts().ModulesSkipHeaderSearchPaths = true;

551 ScanInvocation->getHeaderSearchOpts().ModulesSkipPragmaDiagnosticMappings =

552 true;

553 ScanInvocation->getHeaderSearchOpts().ModulesForceValidateUserHeaders = false;

554

555

556 ScanInvocation->getPreprocessorOpts().ModulesCheckRelocated = false;

557

558

559

560 ScanInvocation->getDependencyOutputOpts() = {};

561

562 return ScanInvocation;

563}

564

565llvm::SmallVector

567

568

569

572 if (!Sysroot.empty() && (llvm::sys::path::root_directory(Sysroot) != Sysroot))

574 return StableDirs;

575}

576

577std::optional

580

581

582

583

585

587 if (visitPrebuiltModule(

590 PrebuiltModulesASTMap, ScanInstance.getDiagnostics(), StableDirs))

591 return {};

592

593 return PrebuiltModulesASTMap;

594}

595

596

597

598static std::unique_ptr

600 auto Opts = std::make_unique(

602

603

604 if (Opts->Targets.empty())

607 Opts->IncludeSystemHeaders = true;

608

609 return Opts;

610}

611

612std::shared_ptr

615 std::unique_ptr DepOutputOpts,

621 std::shared_ptr MDC;

625 std::make_shared(

626 std::move(DepOutputOpts), WorkingDirectory, Consumer));

627 break;

630 MDC = std::make_shared(

631 Service, std::move(DepOutputOpts), ScanInstance, Consumer, Controller,

632 Inv, std::move(PrebuiltModulesASTMap), StableDirs);

634 break;

635 }

636

637 return MDC;

638}

639

641 std::string Executable,

642 std::unique_ptr OriginalInvocation,

644 std::shared_ptr PCHContainerOps,

646

647

649 canonicalizeDefines(OriginalInvocation->getPreprocessorOpts());

650

651 if (Scanned) {

652

653

654

655

656 if (MDC)

657 MDC->applyDiscoveredDependencies(*OriginalInvocation);

658 Consumer.handleBuildCommand(

659 {Executable, OriginalInvocation->getCC1CommandLine()});

660 return true;

661 }

662

663 Scanned = true;

664

665

666 auto ScanInvocation =

669 ScanInstanceStorage.emplace(std::move(ScanInvocation),

670 std::move(PCHContainerOps), ModCache.get());

672

673 assert(!DiagConsumerFinished && "attempt to reuse finished consumer");

675 DepFS);

676

678 auto MaybePrebuiltModulesASTMap =

680 if (!MaybePrebuiltModulesASTMap)

681 return false;

682

684

686 ScanInstance, std::move(DepOutputOpts), WorkingDirectory, Consumer,

687 Service, *OriginalInvocation, Controller, *MaybePrebuiltModulesASTMap,

688 StableDirs);

689

690 std::unique_ptr Action;

691

693 Action = std::make_unique();

694 else

695 Action = std::make_unique();

696

698 return false;

699

701

702

703 DiagConsumerFinished = true;

704

706 if (MDC)

707 MDC->applyDiscoveredDependencies(*OriginalInvocation);

708 Consumer.handleBuildCommand(

709 {Executable, OriginalInvocation->getCC1CommandLine()});

710 }

711

713}

714

716 std::unique_ptr DiagEngineWithDiagOpts,

718 assert(DiagEngineWithDiagOpts && "Valid diagnostics engine required!");

719 DiagEngineWithCmdAndOpts = std::move(DiagEngineWithDiagOpts);

720 DiagConsumer = DiagEngineWithCmdAndOpts->DiagEngine->getClient();

721

722#ifndef NDEBUG

723 assert(OverlayFS && "OverlayFS required!");

724 bool SawDepFS = false;

725 OverlayFS->visit([&](llvm::vfs::FileSystem &VFS) {

726 SawDepFS |= &VFS == Worker.DepFS.get();

727 });

728 assert(SawDepFS && "OverlayFS not based on DepFS");

729#endif

730

732 CommandLine, *DiagEngineWithCmdAndOpts->DiagEngine);

733 if (!OriginalInvocation) {

734 DiagEngineWithCmdAndOpts->DiagEngine->Report(

735 diag::err_fe_expected_compiler_job)

736 << llvm::join(CommandLine, " ");

737 return false;

738 }

739

741 canonicalizeDefines(OriginalInvocation->getPreprocessorOpts());

742

743

746 CIPtr = std::make_unique(

748 Worker.PCHContainerOps, ModCache.get());

749 auto &CI = *CIPtr;

750

752 CI, OverlayFS, DiagEngineWithCmdAndOpts->DiagEngine->getClient(),

753 Worker.Service, Worker.DepFS);

754

756 auto MaybePrebuiltModulesASTMap =

758 if (!MaybePrebuiltModulesASTMap)

759 return false;

760

761 PrebuiltModuleASTMap = std::move(*MaybePrebuiltModulesASTMap);

763

764

765

766

767

768

770

771 return true;

772}

773

777 assert(CIPtr && "CIPtr must be initialized before calling this method");

778 auto &CI = *CIPtr;

779

780

781

782 auto CleanUp = llvm::make_scope_exit([&]() {

784

785

786

788 });

789

791 CI, std::make_unique(*OutputOpts), CWD, Consumer,

792 Worker.Service,

793

794

795

796 *OriginalInvocation, Controller, PrebuiltModuleASTMap, StableDirs);

797

798 if (!SrcLocOffset) {

799

800

801 std::unique_ptr Action =

802 std::make_unique();

804 bool ActionBeginSucceeded = Action->BeginSourceFile(CI, *InputFile);

805 assert(ActionBeginSucceeded && "Action BeginSourceFile must succeed");

806 (void)ActionBeginSucceeded;

807 }

808

811 FileID MainFileID = SM.getMainFileID();

812 SourceLocation FileStart = SM.getLocForStartOfFile(MainFileID);

815 if (!SrcLocOffset) {

816

817

819 assert(!PPFailed && "Preprocess must be able to enter the main file.");

820 (void)PPFailed;

821 CB = MDC->getPPCallbacks();

822 } else {

823

824

825

826 MDC->attachToPreprocessor(PP);

827 CB = MDC->getPPCallbacks();

828

833 FileType, PrevFID, IDLocation);

834 }

835

836 SrcLocOffset++;

839 Path.emplace_back(IDLocation, ModuleID);

841

842 assert(CB && "Must have PPCallbacks after module loading");

844

845

846

848

849 if (!ModResult)

850 return false;

851

853 MDC->applyDiscoveredDependencies(ModuleInvocation);

856

857 return true;

858}

859

861 DiagConsumer->finish();

862 return true;

863}

static std::unique_ptr< DependencyOutputOptions > createDependencyOutputOptions(const CompilerInvocation &Invocation)

Creates dependency output options to be reported to the dependency consumer, deducing missing informa...

Definition DependencyScannerImpl.cpp:599

static std::shared_ptr< CompilerInvocation > createScanCompilerInvocation(const CompilerInvocation &Invocation, const DependencyScanningService &Service)

Creates a CompilerInvocation suitable for the dependency scanner.

Definition DependencyScannerImpl.cpp:517

Abstract interface for callback invocations by the ASTReader.

@ ARR_OutOfDate

The client can handle an AST file that cannot load because it is out-of-date relative to its input fi...

static bool readASTFileControlBlock(StringRef Filename, FileManager &FileMgr, const ModuleCache &ModCache, const PCHContainerReader &PCHContainerRdr, bool FindModuleFileExtensions, ASTReaderListener &Listener, bool ValidateDiagnosticOptions, unsigned ClientLoadCapabilities=ARR_ConfigurationMismatch|ARR_OutOfDate)

Read the control block for the named AST file.

CompilerInstance - Helper class for managing a single instance of the Clang compiler.

void clearDependencyCollectors()

void createDiagnostics(DiagnosticConsumer *Client=nullptr, bool ShouldOwnClient=true)

Create the diagnostics engine using the invocation's diagnostic options and replace any existing one ...

const PCHContainerReader & getPCHContainerReader() const

Return the appropriate PCHContainerReader depending on the current CodeGenOptions.

DiagnosticsEngine & getDiagnostics() const

Get the current diagnostics engine.

ModuleLoadResult loadModule(SourceLocation ImportLoc, ModuleIdPath Path, Module::NameVisibilityKind Visibility, bool IsInclusionDirective) override

Attempt to load the given module.

void createFileManager()

Create the file manager and replace any existing one with it.

FileManager & getFileManager() const

Return the current file manager to the caller.

ModuleCache & getModuleCache() const

void addDependencyCollector(std::shared_ptr< DependencyCollector > Listener)

Preprocessor & getPreprocessor() const

Return the current preprocessor.

void createVirtualFileSystem(IntrusiveRefCntPtr< llvm::vfs::FileSystem > BaseFS=llvm::vfs::getRealFileSystem(), DiagnosticConsumer *DC=nullptr)

Create a virtual file system instance based on the invocation.

FrontendOptions & getFrontendOpts()

HeaderSearchOptions & getHeaderSearchOpts()

void createSourceManager()

Create the source manager and replace any existing one with it.

PreprocessorOptions & getPreprocessorOpts()

bool ExecuteAction(FrontendAction &Act)

ExecuteAction - Execute the provided action against the compiler's CompilerInvocation object.

LangOptions & getLangOpts()

void setDependencyDirectivesGetter(std::unique_ptr< DependencyDirectivesGetter > Getter)

std::vector< std::string > getCC1CommandLine() const

Generate cc1-compatible command line arguments from this instance, wrapping the result as a std::vect...

Helper class for holding the data necessary to invoke the compiler.

static bool CreateFromArgs(CompilerInvocation &Res, ArrayRef< const char * > CommandLineArgs, DiagnosticsEngine &Diags, const char *Argv0=nullptr)

Create a compiler invocation from a list of input options.

DependencyOutputOptions & getDependencyOutputOpts()

FrontendOptions & getFrontendOpts()

Functor that returns the dependency directives for a given file.

Builds a dependency file when attached to a Preprocessor (for includes) and ASTReader (for module imp...

Abstract interface, implemented by clients of the front-end, which formats and prints fully processed...

Options for controlling the compiler diagnostics engine.

std::vector< std::string > Warnings

The list of -W... options used to alter the diagnostic mappings, with the prefixes removed.

std::string DiagnosticSerializationFile

The file to serialize diagnostics to (non-appending).

Concrete class used by the front-end to report problems and issues.

DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)

Issue the message to the client.

bool hasErrorOccurred() const

An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...

llvm::vfs::FileSystem & getVirtualFileSystem() const

std::string OutputFile

The output file, if any.

SmallVector< FrontendInputFile, 0 > Inputs

The input files and their types.

One of these records is kept for each identifier that is lexed.

Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...

void setBuildingModule(bool BuildingModuleFlag)

Flag indicating whether this instance is building a module.

@ Hidden

All of the names in this module are hidden.

This interface provides a way to observe the actions of the preprocessor as it does its thing.

virtual void EndOfMainFile()

Callback invoked when the end of the main file is reached.

virtual void LexedFileChanged(FileID FID, LexedFileChangeReason Reason, SrcMgr::CharacteristicKind FileType, FileID PrevFID, SourceLocation Loc)

Callback invoked whenever the Lexer moves to a different file for lexing.

virtual void moduleImport(SourceLocation ImportLoc, ModuleIdPath Path, const Module *Imported)

Callback invoked whenever there was an explicit module-import syntax.

PreprocessorOptions - This class is used for passing the various options used in preprocessor initial...

std::string ImplicitPCHInclude

The implicit PCH included at the start of the translation unit, or empty.

std::vector< std::pair< std::string, bool > > Macros

Engages in a tight little dance with the lexer to efficiently preprocess tokens.

bool EnterSourceFile(FileID FID, ConstSearchDirIterator Dir, SourceLocation Loc, bool IsFirstIncludeOfFile=true)

Add a source file to the top of the include stack and start lexing tokens from it instead of the curr...

IdentifierInfo * getIdentifierInfo(StringRef Name) const

Return information about the specified preprocessor identifier token.

SourceManager & getSourceManager() const

Encodes a location in the source.

SourceLocation getLocWithOffset(IntTy Offset) const

Return a source location with the specified offset from this SourceLocation.

This class handles loading and caching of source files into memory.

The base class of the type hierarchy.

bool initialize(std::unique_ptr< DiagnosticsEngineWithDiagOpts > DiagEngineWithDiagOpts, IntrusiveRefCntPtr< llvm::vfs::OverlayFileSystem > OverlayFS)

Definition DependencyScannerImpl.cpp:715

bool computeDependencies(StringRef ModuleName, DependencyConsumer &Consumer, DependencyActionController &Controller)

Definition DependencyScannerImpl.cpp:774

bool finalize()

Definition DependencyScannerImpl.cpp:860

Dependency scanner callbacks that are used during scanning to influence the behaviour of the scan - f...

virtual void handleBuildCommand(Command Cmd)

bool runInvocation(std::string Executable, std::unique_ptr< CompilerInvocation > Invocation, IntrusiveRefCntPtr< llvm::vfs::FileSystem > FS, std::shared_ptr< PCHContainerOperations > PCHContainerOps, DiagnosticConsumer *DiagConsumer)

Definition DependencyScannerImpl.cpp:640

The dependency scanning service contains shared configuration and state that is used by the individua...

std::time_t getBuildSessionTimestamp() const

ScanningOptimizations getOptimizeArgs() const

ScanningMode getMode() const

ScanningOutputFormat getFormat() const

void setVFS(llvm::StringSet<> &&VFS)

Update the VFSMap to the one discovered from serializing the AST file.

bool isInStableDir() const

Read-only access to whether the module is made up of dependencies in stable directories.

void addDependent(StringRef ModuleFile)

Add a direct dependent module file, so it can be updated if the current module is from stable directo...

void setInStableDir(bool V=false)

Update whether the prebuilt module resolves entirely in a stable directories.

CharacteristicKind

Indicates whether a file or directory holds normal user code, system code, or system code which is im...

SmallVector< StringRef > getInitialStableDirs(const CompilerInstance &ScanInstance)

Definition DependencyScannerImpl.cpp:566

bool areOptionsInStableDir(const ArrayRef< StringRef > Directories, const HeaderSearchOptions &HSOpts)

Determine if options collected from a module's compilation can safely be considered as stable.

@ VFS

Remove unused -ivfsoverlay arguments.

@ Macros

Canonicalize -D and -U options.

std::pair< IntrusiveRefCntPtr< llvm::vfs::OverlayFileSystem >, std::vector< std::string > > initVFSForTUBufferScanning(IntrusiveRefCntPtr< llvm::vfs::FileSystem > BaseFS, ArrayRef< std::string > CommandLine, StringRef WorkingDirectory, llvm::MemoryBufferRef TUBuffer)

Definition DependencyScannerImpl.cpp:435

void initializeScanCompilerInstance(CompilerInstance &ScanInstance, IntrusiveRefCntPtr< llvm::vfs::FileSystem > FS, DiagnosticConsumer *DiagConsumer, DependencyScanningService &Service, IntrusiveRefCntPtr< DependencyScanningWorkerFilesystem > DepFS)

Definition DependencyScannerImpl.cpp:488

llvm::StringMap< PrebuiltModuleASTAttrs > PrebuiltModulesAttrsMap

Attributes loaded from AST files of prebuilt modules collected prior to ModuleDepCollector creation.

std::unique_ptr< CompilerInvocation > createCompilerInvocation(ArrayRef< std::string > CommandLine, DiagnosticsEngine &Diags)

Definition DependencyScannerImpl.cpp:419

std::optional< PrebuiltModulesAttrsMap > computePrebuiltModulesASTMap(CompilerInstance &ScanInstance, SmallVector< StringRef > &StableDirs)

Definition DependencyScannerImpl.cpp:578

std::pair< IntrusiveRefCntPtr< llvm::vfs::OverlayFileSystem >, std::vector< std::string > > initVFSForByNameScanning(IntrusiveRefCntPtr< llvm::vfs::FileSystem > BaseFS, ArrayRef< std::string > CommandLine, StringRef WorkingDirectory, StringRef ModuleName)

Definition DependencyScannerImpl.cpp:460

std::pair< std::unique_ptr< driver::Driver >, std::unique_ptr< driver::Compilation > > buildCompilation(ArrayRef< std::string > ArgStrs, DiagnosticsEngine &Diags, IntrusiveRefCntPtr< llvm::vfs::FileSystem > FS, llvm::BumpPtrAllocator &Alloc)

Definition DependencyScannerImpl.cpp:383

std::shared_ptr< ModuleDepCollector > initializeScanInstanceDependencyCollector(CompilerInstance &ScanInstance, std::unique_ptr< DependencyOutputOptions > DepOutputOpts, StringRef WorkingDirectory, DependencyConsumer &Consumer, DependencyScanningService &Service, CompilerInvocation &Inv, DependencyActionController &Controller, PrebuiltModulesAttrsMap PrebuiltModulesASTMap, llvm::SmallVector< StringRef > &StableDirs)

Create the dependency collector that will collect the produced dependencies.

Definition DependencyScannerImpl.cpp:613

std::unique_ptr< DiagnosticOptions > createDiagOptions(ArrayRef< std::string > CommandLine)

Definition DependencyScannerImpl.cpp:361

bool isPathInStableDir(const ArrayRef< StringRef > Directories, const StringRef Input)

Determine if Input can be resolved within a stable directory.

@ Make

This is the Makefile compatible dep format.

@ Full

This outputs the full clang module dependency graph suitable for use for explicitly building modules.

@ P1689

This outputs the dependency graph for standard c++ modules in P1689R5 format.

@ DependencyDirectivesScan

This mode is used to compute the dependencies by running the preprocessor with special kind of lexing...

IntrusiveRefCntPtr< ModuleCache > makeInProcessModuleCache(ModuleCacheEntries &Entries)

llvm::StringRef getDriverMode(StringRef ProgName, ArrayRef< const char * > Args)

Returns the driver mode option's value, i.e.

llvm::Error expandResponseFiles(SmallVectorImpl< const char * > &Args, bool ClangCLMode, llvm::BumpPtrAllocator &Alloc, llvm::vfs::FileSystem *FS=nullptr)

Expand response files from a clang driver or cc1 invocation.

bool IsClangCL(StringRef DriverMode)

Checks whether the value produced by getDriverMode is for CL mode.

ModuleKind

Specifies the kind of module that has been loaded.

@ MK_ExplicitModule

File is an explicitly-loaded module.

The JSON file list parser is used to communicate input to InstallAPI.

std::unique_ptr< DiagnosticOptions > CreateAndPopulateDiagOpts(ArrayRef< const char * > Argv)

nullptr

This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...

@ Result

The result type of a method or function.

void normalizeModuleCachePath(FileManager &FileMgr, StringRef Path, SmallVectorImpl< char > &NormalizedPath)

int __ovld __cnfn any(char)

Returns 1 if the most significant bit in any component of x is set; otherwise returns 0.

IntrusiveRefCntPtr< DiagnosticsEngine > DiagEngine

DiagnosticsEngineWithDiagOpts(ArrayRef< std::string > CommandLine, IntrusiveRefCntPtr< llvm::vfs::FileSystem > FS, DiagnosticConsumer &DC)

Definition DependencyScannerImpl.cpp:370

std::unique_ptr< DiagnosticOptions > DiagOpts

This is used to identify a specific module.