@@ -99,6 +99,7 @@ class IncludeTreeBuilder {
99
99
llvm::SmallBitVector HasIncludeChecks;
100
100
};
101
101
102
+ Error addModuleInputs (ASTReader &Reader);
102
103
Expected<cas::ObjectRef> getObjectForFile (Preprocessor &PP, FileID FID);
103
104
Expected<cas::ObjectRef>
104
105
getObjectForFileNonCached (FileManager &FM, const SrcMgr::FileInfo &FI);
@@ -128,7 +129,7 @@ class IncludeTreeBuilder {
128
129
// are recorded in the PCH, ordered by \p FileEntry::UID index.
129
130
SmallVector<StringRef> PreIncludedFileNames;
130
131
llvm::BitVector SeenIncludeFiles;
131
- SmallVector <cas::IncludeTree::FileList::FileEntry> IncludedFiles;
132
+ llvm::SetVector <cas::IncludeTree::FileList::FileEntry> IncludedFiles;
132
133
std::optional<cas::ObjectRef> PredefinesBufferRef;
133
134
std::optional<cas::ObjectRef> ModuleIncludesBufferRef;
134
135
std::optional<cas::ObjectRef> ModuleMapFileRef;
@@ -495,30 +496,8 @@ IncludeTreeBuilder::finishIncludeTree(CompilerInstance &ScanInstance,
495
496
return Error::success (); // no need for additional work.
496
497
497
498
// Go through all the recorded input files.
498
- SmallVector<const FileEntry *, 32 > NotSeenIncludes;
499
- for (serialization::ModuleFile &MF : Reader->getModuleManager ()) {
500
- if (hasErrorOccurred ())
501
- break ;
502
- Reader->visitInputFiles (
503
- MF, /* IncludeSystem=*/ true , /* Complain=*/ false ,
504
- [&](const serialization::InputFile &IF, bool isSystem) {
505
- OptionalFileEntryRef FE = IF.getFile ();
506
- assert (FE);
507
- if (FE->getUID () >= SeenIncludeFiles.size () ||
508
- !SeenIncludeFiles[FE->getUID ()])
509
- NotSeenIncludes.push_back (*FE);
510
- });
511
- }
512
- // Sort so we can visit the files in deterministic order.
513
- llvm::sort (NotSeenIncludes, [](const FileEntry *LHS, const FileEntry *RHS) {
514
- return LHS->getUID () < RHS->getUID ();
515
- });
516
-
517
- for (const FileEntry *FE : NotSeenIncludes) {
518
- auto FileNode = addToFileList (FM, FE);
519
- if (!FileNode)
520
- return FileNode.takeError ();
521
- }
499
+ if (Error E = addModuleInputs (*Reader))
500
+ return E;
522
501
523
502
PreprocessorOptions &PPOpts = NewInvocation.getPreprocessorOpts ();
524
503
if (PPOpts.ImplicitPCHInclude .empty ())
@@ -544,7 +523,8 @@ IncludeTreeBuilder::finishIncludeTree(CompilerInstance &ScanInstance,
544
523
getCASTreeForFileIncludes (IncludeStack.pop_back_val ());
545
524
if (!MainIncludeTree)
546
525
return MainIncludeTree.takeError ();
547
- auto FileList = cas::IncludeTree::FileList::create (DB, IncludedFiles);
526
+ auto FileList =
527
+ cas::IncludeTree::FileList::create (DB, IncludedFiles.getArrayRef ());
548
528
if (!FileList)
549
529
return FileList.takeError ();
550
530
@@ -553,6 +533,39 @@ IncludeTreeBuilder::finishIncludeTree(CompilerInstance &ScanInstance,
553
533
ModuleMapFileRef);
554
534
}
555
535
536
+ Error IncludeTreeBuilder::addModuleInputs (ASTReader &Reader) {
537
+ for (serialization::ModuleFile &MF : Reader.getModuleManager ()) {
538
+ // Only add direct imports to avoid duplication. Each include tree is a
539
+ // superset of its imported modules' include trees.
540
+ if (!MF.isDirectlyImported ())
541
+ continue ;
542
+
543
+ assert (!MF.IncludeTreeID .empty () && " missing include-tree for import" );
544
+
545
+ std::optional<cas::CASID> ID;
546
+ if (Error E = DB.parseID (MF.IncludeTreeID ).moveInto (ID))
547
+ return E;
548
+ std::optional<cas::ObjectRef> Ref = DB.getReference (*ID);
549
+ if (!Ref)
550
+ return DB.createUnknownObjectError (*ID);
551
+ std::optional<cas::IncludeTreeRoot> Root;
552
+ if (Error E = cas::IncludeTreeRoot::get (DB, *Ref).moveInto (Root))
553
+ return E;
554
+ std::optional<cas::IncludeTree::FileList> Files;
555
+ if (Error E = Root->getFileList ().moveInto (Files))
556
+ return E;
557
+
558
+ Error E = Files->forEachFile ([&](auto IF, auto Size ) -> Error {
559
+ IncludedFiles.insert ({IF.getRef (), Size });
560
+ return Error::success ();
561
+ });
562
+ if (E)
563
+ return E;
564
+ }
565
+
566
+ return Error::success ();
567
+ }
568
+
556
569
Expected<cas::ObjectRef> IncludeTreeBuilder::getObjectForFile (Preprocessor &PP,
557
570
FileID FID) {
558
571
SourceManager &SM = PP.getSourceManager ();
@@ -628,7 +641,7 @@ IncludeTreeBuilder::addToFileList(FileManager &FM, const FileEntry *FE) {
628
641
auto FileNode = createIncludeFile (Filename, **CASContents);
629
642
if (!FileNode)
630
643
return FileNode.takeError ();
631
- IncludedFiles.push_back (
644
+ IncludedFiles.insert (
632
645
{FileNode->getRef (),
633
646
static_cast <cas::IncludeTree::FileList::FileSizeTy>(FE->getSize ())});
634
647
return FileNode->getRef ();
0 commit comments