vsapsai created this revision.
Herald added a subscriber: ributzka.
vsapsai requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Aggregated transitive includes are stored in SubmoduleState, includes
per submodule for subsequent serialization are stored in
IncludedFilesPerSubmodule.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D114051

Files:
  clang/include/clang/Lex/ExternalPreprocessorSource.h
  clang/include/clang/Lex/Preprocessor.h
  clang/include/clang/Serialization/ASTReader.h
  clang/include/clang/Serialization/ASTWriter.h
  clang/lib/Lex/PPLexerChange.cpp
  clang/lib/Lex/Preprocessor.cpp
  clang/lib/Serialization/ASTReader.cpp
  clang/lib/Serialization/ASTWriter.cpp

Index: clang/lib/Serialization/ASTWriter.cpp
===================================================================
--- clang/lib/Serialization/ASTWriter.cpp
+++ clang/lib/Serialization/ASTWriter.cpp
@@ -57,7 +57,6 @@
 #include "clang/Lex/MacroInfo.h"
 #include "clang/Lex/ModuleMap.h"
 #include "clang/Lex/PreprocessingRecord.h"
-#include "clang/Lex/Preprocessor.h"
 #include "clang/Lex/PreprocessorOptions.h"
 #include "clang/Lex/Token.h"
 #include "clang/Sema/IdentifierResolver.h"
@@ -2170,16 +2169,15 @@
   return false;
 }
 
-void ASTWriter::addIncludedFiles(
-    const llvm::DenseMap<const FileEntry *, unsigned> &Files,
-    RecordDataImpl &Record) {
+void ASTWriter::addIncludedFiles(const Preprocessor::IncludeInfoMap &Files,
+                                 RecordDataImpl &Record) {
   // Map the FileEntry map into an input file ID vector.
   llvm::SmallVector<std::pair<uint64_t, unsigned>> FileIDs;
   for (const auto &E : Files) {
     auto InputFileIt = InputFileIDs.find(E.first);
     assert(InputFileIt != InputFileIDs.end() &&
            "Included file is an known input file");
-    FileIDs.emplace_back(InputFileIt->second, E.second);
+    FileIDs.emplace_back(InputFileIt->second, E.second.NumIncludes);
   }
 
   // Ensure the order is stable.
@@ -2414,10 +2412,6 @@
                                        MacroOffsetsBase - ASTBlockStartOffset};
     Stream.EmitRecordWithBlob(MacroOffsetAbbrev, Record, bytes(MacroOffsets));
   }
-
-  addIncludedFiles(PP.getNullSubmoduleIncludes(), Record);
-  Stream.EmitRecord(PP_NUM_INCLUDES, Record);
-  Record.clear();
 }
 
 void ASTWriter::WritePreprocessorDetail(PreprocessingRecord &PPRec,
@@ -2814,7 +2808,8 @@
       Stream.EmitRecordWithBlob(ExportAsAbbrev, Record, Mod->ExportAsModule);
     }
 
-    if (const auto *Includes = PP->getLocalSubmoduleIncludes(Mod)) {
+    if (const Preprocessor::IncludeInfoMap *Includes =
+            PP->getLocalSubmoduleIncludes(Mod)) {
       RecordData Record;
       addIncludedFiles(*Includes, Record);
       Stream.EmitRecord(SUBMODULE_NUM_INCLUDES, Record);
Index: clang/lib/Serialization/ASTReader.cpp
===================================================================
--- clang/lib/Serialization/ASTReader.cpp
+++ clang/lib/Serialization/ASTReader.cpp
@@ -3702,7 +3702,8 @@
         break;
 
       for (const auto &E : readIncludedFiles(F, Record))
-        PP.incrementTransitiveIncludeCount(E.getFirst(), E.getSecond());
+        PP.incrementTransitiveIncludeCount(E.getFirst(),
+                                           E.getSecond().NumIncludes);
       break;
     }
 
@@ -8605,8 +8606,8 @@
   return LocalID + I->second;
 }
 
-llvm::DenseMap<const FileEntry *, unsigned>
-ASTReader::readIncludedFiles(ModuleFile &F, RecordData &Record) {
+Preprocessor::IncludeInfoMap ASTReader::readIncludedFiles(ModuleFile &F,
+                                                          RecordData &Record) {
   unsigned Idx = 0;
   unsigned TotalCount = Record[Idx++];
   unsigned IncludedOnceCount = Record[Idx++];
@@ -8617,25 +8618,25 @@
     return FileMgr.getOptionalFileRef(InputFileInfo.Filename);
   };
 
-  llvm::DenseMap<const FileEntry *, unsigned> Result;
+  Preprocessor::IncludeInfoMap Result;
   for (unsigned I = 0; I < IncludedOnceCount; ++I)
     if (const FileEntry *File = ReadFile())
-      Result.insert({File, 1});
+      Result.insert({File, {1}});
   for (unsigned I = 0; I < TotalCount - IncludedOnceCount; ++I)
     if (const FileEntry *File = ReadFile())
-      Result.insert({File, 2}); // squash "more than one" include into exactly 2
+      Result.insert(
+          {File, {2}}); // squash "more than one" include into exactly 2
   return Result;
 }
 
-const llvm::DenseMap<const FileEntry *, unsigned> *
-ASTReader::getIncludedFiles(Module *M) {
+const Preprocessor::IncludeInfoMap *ASTReader::getIncludedFiles(Module *M) {
   ModuleFile *F = getModuleManager().lookup(M->getASTFile());
   if (!F)
     return nullptr;
 
-  auto ResultIt = SubmoduleIncludedFiles.insert(
-      {M, llvm::DenseMap<const FileEntry *, unsigned>{}});
-  auto &Result = ResultIt.first->second;
+  auto ResultIt =
+      SubmoduleIncludedFiles.insert({M, Preprocessor::IncludeInfoMap{}});
+  Preprocessor::IncludeInfoMap &Result = ResultIt.first->second;
   if (!ResultIt.second)
     return &Result;
 
Index: clang/lib/Lex/Preprocessor.cpp
===================================================================
--- clang/lib/Lex/Preprocessor.cpp
+++ clang/lib/Lex/Preprocessor.cpp
@@ -91,8 +91,7 @@
       // deferred to Preprocessor::Initialize().
       Identifiers(IILookup), PragmaHandlers(new PragmaNamespace(StringRef())),
       TUKind(TUKind), SkipMainFilePreamble(0, true),
-      CurSubmoduleState(&NullSubmoduleState),
-      CurSubmoduleIncludeState(&NullSubmoduleIncludeState) {
+      CurSubmoduleState(&NullSubmoduleState) {
   OwnsHeaderSearch = OwnsHeaders;
 
   // Default to discarding comments.
@@ -287,11 +286,12 @@
              << " token paste (##) operations performed, "
              << NumFastTokenPaste << " on the fast path.\n";
 
+  // FIXME: List information for all submodules.
   unsigned NumSingleIncludedFiles = 0, MaxNumIncludes = 0;
-  for (const auto &Include : IncludedFiles) {
-    if (MaxNumIncludes < Include.second)
-      MaxNumIncludes = Include.second;
-    NumSingleIncludedFiles += Include.second == 1;
+  for (const auto &IncludePair : CurSubmoduleState->IncludedFiles) {
+    if (MaxNumIncludes < IncludePair.second.NumIncludes)
+      MaxNumIncludes = IncludePair.second.NumIncludes;
+    NumSingleIncludedFiles += IncludePair.second.NumIncludes == 1;
   }
   llvm::errs() << NumSingleIncludedFiles << " files included exactly once.\n"
                << MaxNumIncludes << " max times a file is included.\n";
@@ -564,9 +564,6 @@
     }
   }
 
-  if (Module *M = getCurrentModule())
-    CurSubmoduleIncludeState = &SubmoduleIncludeStates[M];
-
   // Preprocess Predefines to populate the initial preprocessor state.
   std::unique_ptr<llvm::MemoryBuffer> SB =
     llvm::MemoryBuffer::getMemBufferCopy(Predefines, "<built-in>");
@@ -1320,7 +1317,16 @@
 
 void Preprocessor::makeModuleVisible(Module *M, SourceLocation Loc) {
   CurSubmoduleState->VisibleModules.setVisible(
-      M, Loc, [](Module *) {},
+      M, Loc,
+      [&](Module *M) {
+        const IncludeInfoMap *Includes = getLocalSubmoduleIncludes(M);
+        if (!Includes)
+          Includes = getExternalSubmoduleIncludes(M);
+        if (Includes)
+          for (const auto &E : *Includes)
+            incrementTransitiveIncludeCount(E.getFirst(),
+                                            E.getSecond().NumIncludes);
+      },
       [&](ArrayRef<Module *> Path, Module *Conflict, StringRef Message) {
         // FIXME: Include the path in the diagnostic.
         // FIXME: Include the import location for the conflicting module.
@@ -1330,18 +1336,6 @@
             << Message;
       });
 
-  CurSubmoduleIncludeState->VisibleModules.setVisible(
-      M, Loc,
-      [&](Module *M) {
-        const auto *Includes = getLocalSubmoduleIncludes(M);
-        if (!Includes)
-          Includes = getExternalSubmoduleIncludes(M);
-        if (Includes)
-          for (const auto &E : *Includes)
-            incrementTransitiveIncludeCount(E.getFirst(), E.getSecond());
-      },
-      [](ArrayRef<Module *>, Module *, StringRef) {});
-
   // Add this module to the imports list of the currently-built submodule.
   if (!BuildingSubmoduleStack.empty() && M != BuildingSubmoduleStack.back().M)
     BuildingSubmoduleStack.back().M->Imports.insert(M);
@@ -1495,17 +1489,17 @@
 }
 
 bool Preprocessor::includedAtLeastOnce(const FileEntry *File) const {
-  auto It = IncludedFiles.find(File);
-  if (It == IncludedFiles.end())
+  auto It = CurSubmoduleState->IncludedFiles.find(File);
+  if (It == CurSubmoduleState->IncludedFiles.end())
     return false;
-  return It->second >= 1;
+  return It->second.NumIncludes >= 1;
 }
 
 bool Preprocessor::firstTimeLexingFile(const FileEntry *File) const {
-  auto It = IncludedFiles.find(File);
-  if (It == IncludedFiles.end())
+  auto It = CurSubmoduleState->IncludedFiles.find(File);
+  if (It == CurSubmoduleState->IncludedFiles.end())
     return false;
-  return It->second == 1;
+  return It->second.NumIncludes == 1;
 }
 
 void Preprocessor::incrementTransitiveIncludeCount(const FileEntry *File,
@@ -1513,23 +1507,25 @@
   // Compared to `incrementIncludeCount`, we're not incrementing the count in
   // CurSubmoduleIncludeState`. This is to ensure it always only contains
   // **locally** included files and not transitively included ones.
-  IncludedFiles[File] += Count;
+  CurSubmoduleState->IncludedFiles[File].NumIncludes += Count;
 }
 
 void Preprocessor::incrementIncludeCount(const FileEntry *File) {
-  CurSubmoduleIncludeState->IncludedFiles[File] += 1;
-  IncludedFiles[File] += 1;
+  if (!BuildingSubmoduleStack.empty())
+    IncludedFilesPerSubmodule[BuildingSubmoduleStack.back().M][File]
+        .NumIncludes += 1;
+  CurSubmoduleState->IncludedFiles[File].NumIncludes += 1;
 }
 
-const llvm::DenseMap<const FileEntry *, unsigned> *
+const Preprocessor::IncludeInfoMap *
 Preprocessor::getLocalSubmoduleIncludes(Module *M) const {
-  auto It = SubmoduleIncludeStates.find(M);
-  if (It != SubmoduleIncludeStates.end())
-    return &It->second.IncludedFiles;
+  auto It = IncludedFilesPerSubmodule.find(M);
+  if (It != IncludedFilesPerSubmodule.end())
+    return &It->second;
   return nullptr;
 }
 
-const llvm::DenseMap<const FileEntry *, unsigned> *
+const Preprocessor::IncludeInfoMap *
 Preprocessor::getExternalSubmoduleIncludes(Module *M) const {
   if (ExternalSource)
     return ExternalSource->getIncludedFiles(M);
Index: clang/lib/Lex/PPLexerChange.cpp
===================================================================
--- clang/lib/Lex/PPLexerChange.cpp
+++ clang/lib/Lex/PPLexerChange.cpp
@@ -687,11 +687,9 @@
                                   bool ForPragma) {
   if (!getLangOpts().ModulesLocalVisibility) {
     // Just track that we entered this submodule.
-    BuildingSubmoduleStack.push_back(BuildingSubmoduleInfo(
-        M, ImportLoc, ForPragma, CurSubmoduleState,
-        PendingModuleMacroNames.size(), CurSubmoduleIncludeState));
-
-    CurSubmoduleIncludeState = &SubmoduleIncludeStates[M];
+    BuildingSubmoduleStack.push_back(
+        BuildingSubmoduleInfo(M, ImportLoc, ForPragma, CurSubmoduleState,
+                              PendingModuleMacroNames.size()));
 
     if (Callbacks)
       Callbacks->EnteredSubmodule(M, ImportLoc, ForPragma);
@@ -735,16 +733,15 @@
   }
 
   // Track that we entered this module.
-  BuildingSubmoduleStack.push_back(BuildingSubmoduleInfo(
-      M, ImportLoc, ForPragma, CurSubmoduleState,
-      PendingModuleMacroNames.size(), CurSubmoduleIncludeState));
+  BuildingSubmoduleStack.push_back(
+      BuildingSubmoduleInfo(M, ImportLoc, ForPragma, CurSubmoduleState,
+                            PendingModuleMacroNames.size()));
 
   if (Callbacks)
     Callbacks->EnteredSubmodule(M, ImportLoc, ForPragma);
 
   // Switch to this submodule as the current submodule.
   CurSubmoduleState = &State;
-  CurSubmoduleIncludeState = &SubmoduleIncludeStates[M];
 
   // This module is visible to itself.
   if (FirstTime)
@@ -776,8 +773,6 @@
   Module *LeavingMod = Info.M;
   SourceLocation ImportLoc = Info.ImportLoc;
 
-  CurSubmoduleIncludeState = Info.OuterSubmoduleIncludeState;
-
   if (!needModuleMacros() ||
       (!getLangOpts().ModulesLocalVisibility &&
        LeavingMod->getTopLevelModuleName() != getLangOpts().CurrentModule)) {
Index: clang/include/clang/Serialization/ASTWriter.h
===================================================================
--- clang/include/clang/Serialization/ASTWriter.h
+++ clang/include/clang/Serialization/ASTWriter.h
@@ -19,6 +19,7 @@
 #include "clang/AST/Type.h"
 #include "clang/Basic/LLVM.h"
 #include "clang/Basic/SourceLocation.h"
+#include "clang/Lex/Preprocessor.h"
 #include "clang/Sema/Sema.h"
 #include "clang/Sema/SemaConsumer.h"
 #include "clang/Serialization/ASTBitCodes.h"
@@ -593,9 +594,8 @@
                         RecordDataImpl &Record);
 
   /// Emit included files information.
-  void
-  addIncludedFiles(const llvm::DenseMap<const FileEntry *, unsigned> &Files,
-                   RecordDataImpl &Record);
+  void addIncludedFiles(const Preprocessor::IncludeInfoMap &Files,
+                        RecordDataImpl &Record);
 
   /// Emit a source location.
   void AddSourceLocation(SourceLocation Loc, RecordDataImpl &Record);
Index: clang/include/clang/Serialization/ASTReader.h
===================================================================
--- clang/include/clang/Serialization/ASTReader.h
+++ clang/include/clang/Serialization/ASTReader.h
@@ -929,8 +929,7 @@
   SmallVector<ImportedSubmodule, 2> ImportedModules;
 
   /// Mapping between a read (sub)module and the file include information.
-  llvm::DenseMap<Module *, llvm::DenseMap<const FileEntry *, unsigned>>
-      SubmoduleIncludedFiles;
+  llvm::DenseMap<Module *, Preprocessor::IncludeInfoMap> SubmoduleIncludedFiles;
   //@}
 
   /// The system include root to be used when loading the
@@ -1385,8 +1384,8 @@
   uint64_t getGlobalBitOffset(ModuleFile &M, uint64_t LocalOffset);
 
   /// Read the record containing files included in a (sub)module.
-  llvm::DenseMap<const FileEntry *, unsigned>
-  readIncludedFiles(ModuleFile &F, RecordData &Record);
+  Preprocessor::IncludeInfoMap readIncludedFiles(ModuleFile &F,
+                                                 RecordData &Record);
 
   /// Returns the first preprocessed entity ID that begins or ends after
   /// \arg Loc.
@@ -2108,8 +2107,7 @@
   Module *getSubmodule(serialization::SubmoduleID GlobalID);
 
   /// Return the files directly included in the given (sub)module.
-  const llvm::DenseMap<const FileEntry *, unsigned> *
-  getIncludedFiles(Module *M) override;
+  const Preprocessor::IncludeInfoMap *getIncludedFiles(Module *M) override;
 
   /// Retrieve the module that corresponds to the given module ID.
   ///
Index: clang/include/clang/Lex/Preprocessor.h
===================================================================
--- clang/include/clang/Lex/Preprocessor.h
+++ clang/include/clang/Lex/Preprocessor.h
@@ -450,6 +450,11 @@
           ElseLoc(ElseLoc) {}
   };
 
+  struct IncludeInfo {
+    unsigned NumIncludes;
+  };
+  using IncludeInfoMap = llvm::DenseMap<const FileEntry *, IncludeInfo>;
+
 private:
   friend class ASTReader;
   friend class MacroArgs;
@@ -718,7 +723,6 @@
   using MacroMap = llvm::DenseMap<const IdentifierInfo *, MacroState>;
 
   struct SubmoduleState;
-  struct SubmoduleIncludeState;
 
   /// Information about a submodule that we're currently building.
   struct BuildingSubmoduleInfo {
@@ -737,17 +741,12 @@
     /// The number of pending module macro names when we started building this.
     unsigned OuterPendingModuleMacroNames;
 
-    /// The previous SubmoduleIncludeState.
-    SubmoduleIncludeState *OuterSubmoduleIncludeState;
-
     BuildingSubmoduleInfo(Module *M, SourceLocation ImportLoc, bool IsPragma,
                           SubmoduleState *OuterSubmoduleState,
-                          unsigned OuterPendingModuleMacroNames,
-                          SubmoduleIncludeState *OuterSubmoduleIncludeState)
+                          unsigned OuterPendingModuleMacroNames)
         : M(M), ImportLoc(ImportLoc), IsPragma(IsPragma),
           OuterSubmoduleState(OuterSubmoduleState),
-          OuterPendingModuleMacroNames(OuterPendingModuleMacroNames),
-          OuterSubmoduleIncludeState(OuterSubmoduleIncludeState) {}
+          OuterPendingModuleMacroNames(OuterPendingModuleMacroNames) {}
   };
   SmallVector<BuildingSubmoduleInfo, 8> BuildingSubmoduleStack;
 
@@ -759,6 +758,8 @@
     /// The set of modules that are visible within the submodule.
     VisibleModuleSet VisibleModules;
 
+    IncludeInfoMap IncludedFiles;
+
     // FIXME: CounterValue?
     // FIXME: PragmaPushMacroInfo?
   };
@@ -771,25 +772,8 @@
   /// in a submodule.
   SubmoduleState *CurSubmoduleState;
 
-  /// Information about a (sub)module's preprocessor include state.
-  struct SubmoduleIncludeState {
-    /// For each included file, we track the number of includes.
-    llvm::DenseMap<const FileEntry *, unsigned> IncludedFiles;
-
-    /// The set of modules that are visible within the submodule.
-    VisibleModuleSet VisibleModules;
-  };
   /// The include state for each (sub)module.
-  std::map<Module *, SubmoduleIncludeState> SubmoduleIncludeStates;
-
-  /// The include state outside of any (sub)module.
-  SubmoduleIncludeState NullSubmoduleIncludeState;
-
-  /// The current include state.
-  SubmoduleIncludeState *CurSubmoduleIncludeState;
-
-  /// For each included file, we track the number of includes.
-  llvm::DenseMap<const FileEntry *, unsigned> IncludedFiles;
+  std::map<Module *, IncludeInfoMap> IncludedFilesPerSubmodule;
 
   /// The set of known macros exported from modules.
   llvm::FoldingSet<ModuleMacro> ModuleMacros;
@@ -947,8 +931,7 @@
   void updateOutOfDateIdentifier(IdentifierInfo &II) const;
 
   /// Get the external include information for the given (sub)module.
-  const llvm::DenseMap<const FileEntry *, unsigned> *
-  getExternalSubmoduleIncludes(Module *M) const;
+  const IncludeInfoMap *getExternalSubmoduleIncludes(Module *M) const;
 
 public:
   Preprocessor(std::shared_ptr<PreprocessorOptions> PPOpts,
@@ -1266,15 +1249,8 @@
   /// Increment the include counter for a file transitively included file.
   void incrementTransitiveIncludeCount(const FileEntry *File, unsigned Count);
 
-  /// Get the include information outside of any (sub)module.
-  const llvm::DenseMap<const FileEntry *, unsigned> &
-  getNullSubmoduleIncludes() const {
-    return NullSubmoduleIncludeState.IncludedFiles;
-  }
-
   /// Get the include information for the given local (sub)module.
-  const llvm::DenseMap<const FileEntry *, unsigned> *
-  getLocalSubmoduleIncludes(Module *M) const;
+  const IncludeInfoMap *getLocalSubmoduleIncludes(Module *M) const;
 
   /// Return the name of the macro defined before \p Loc that has
   /// spelling \p Tokens.  If there are multiple macros with same spelling,
Index: clang/include/clang/Lex/ExternalPreprocessorSource.h
===================================================================
--- clang/include/clang/Lex/ExternalPreprocessorSource.h
+++ clang/include/clang/Lex/ExternalPreprocessorSource.h
@@ -13,6 +13,8 @@
 #ifndef LLVM_CLANG_LEX_EXTERNALPREPROCESSORSOURCE_H
 #define LLVM_CLANG_LEX_EXTERNALPREPROCESSORSOURCE_H
 
+#include "clang/Lex/Preprocessor.h"
+
 namespace clang {
 
 class IdentifierInfo;
@@ -42,8 +44,7 @@
   virtual Module *getModule(unsigned ModuleID) = 0;
 
   /// Return the files directly included in the given (sub)module.
-  virtual const llvm::DenseMap<const FileEntry *, unsigned> *
-  getIncludedFiles(Module *M) = 0;
+  virtual const Preprocessor::IncludeInfoMap *getIncludedFiles(Module *M) = 0;
 };
 
 }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D114051: Illustra... Volodymyr Sapsai via Phabricator via cfe-commits

Reply via email to