]> granicus.if.org Git - clang/commitdiff
[modules] Remove unnecessary deserialization of fully-external HeaderFileInfos for...
authorRichard Smith <richard-llvm@metafoo.co.uk>
Mon, 24 Aug 2015 21:59:32 +0000 (21:59 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Mon, 24 Aug 2015 21:59:32 +0000 (21:59 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@245881 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Lex/HeaderSearch.h
include/clang/Lex/ModuleMap.h
lib/Lex/HeaderSearch.cpp
lib/Lex/ModuleMap.cpp
lib/Serialization/ASTReader.cpp
lib/Serialization/ASTWriter.cpp

index cb61c1436ea55c6f967af1a0b532f3b13ad60786..60bc3a7394e60fc8ab66897cb1979da9e0b6a29b 100644 (file)
@@ -570,11 +570,16 @@ public:
   
   unsigned header_file_size() const { return FileInfo.size(); }
 
-  /// \brief Return the HeaderFileInfo structure for the specified FileEntry.
+  /// \brief Return the HeaderFileInfo structure for the specified FileEntry,
+  /// in preparation for updating it in some way.
   HeaderFileInfo &getFileInfo(const FileEntry *FE);
 
-  /// \brief Return the HeaderFileInfo structure for the specified FileEntry.
-  const HeaderFileInfo *getExistingFileInfo(const FileEntry *FE) const;
+  /// \brief Return the HeaderFileInfo structure for the specified FileEntry,
+  /// if it has ever been filled in.
+  /// \param WantExternal Whether the caller wants purely-external header file
+  ///        info (where \p External is true).
+  const HeaderFileInfo *getExistingFileInfo(const FileEntry *FE,
+                                            bool WantExternal = true) const;
 
   // Used by external tools
   typedef std::vector<DirectoryLookup>::const_iterator search_dir_iterator;
index a4300553a3b4896c9c96febfbf14bff723a49f31..155943e5453c8de431700cc25a2d29abd3712297 100644 (file)
@@ -478,7 +478,7 @@ public:
   /// \brief Adds this header to the given module.
   /// \param Role The role of the header wrt the module.
   void addHeader(Module *Mod, Module::Header Header,
-                 ModuleHeaderRole Role);
+                 ModuleHeaderRole Role, bool Imported = false);
 
   /// \brief Marks this header as being excluded from the given module.
   void excludeHeader(Module *Mod, Module::Header Header);
index e1c8fa21a688972711434ab35b09c0a9b79a3e4a..dccedea64409ec93af1d4d474aee67074de79ac0 100644 (file)
@@ -963,21 +963,22 @@ LookupSubframeworkHeader(StringRef Filename,
 /// header file info (\p HFI)
 static void mergeHeaderFileInfo(HeaderFileInfo &HFI, 
                                 const HeaderFileInfo &OtherHFI) {
+  assert(OtherHFI.External && "expected to merge external HFI");
+
   HFI.isImport |= OtherHFI.isImport;
   HFI.isPragmaOnce |= OtherHFI.isPragmaOnce;
   HFI.isModuleHeader |= OtherHFI.isModuleHeader;
   HFI.NumIncludes += OtherHFI.NumIncludes;
-  
+
   if (!HFI.ControllingMacro && !HFI.ControllingMacroID) {
     HFI.ControllingMacro = OtherHFI.ControllingMacro;
     HFI.ControllingMacroID = OtherHFI.ControllingMacroID;
   }
-  
-  if (OtherHFI.External) {
-    HFI.DirInfo = OtherHFI.DirInfo;
-    HFI.External = OtherHFI.External && (!HFI.IsValid || HFI.External);
-    HFI.IndexHeaderMapHeader = OtherHFI.IndexHeaderMapHeader;
-  }
+
+  HFI.DirInfo = OtherHFI.DirInfo;
+  HFI.External = (!HFI.IsValid || HFI.External);
+  HFI.IsValid = true;
+  HFI.IndexHeaderMapHeader = OtherHFI.IndexHeaderMapHeader;
 
   if (HFI.Framework.empty())
     HFI.Framework = OtherHFI.Framework;
@@ -989,42 +990,58 @@ HeaderFileInfo &HeaderSearch::getFileInfo(const FileEntry *FE) {
   if (FE->getUID() >= FileInfo.size())
     FileInfo.resize(FE->getUID() + 1);
 
-  HeaderFileInfo &HFI = FileInfo[FE->getUID()];
+  HeaderFileInfo *HFI = &FileInfo[FE->getUID()];
   // FIXME: Use a generation count to check whether this is really up to date.
-  if (ExternalSource && !HFI.Resolved) {
-    HFI.Resolved = true;
-    mergeHeaderFileInfo(HFI, ExternalSource->GetHeaderFileInfo(FE));
+  if (ExternalSource && !HFI->Resolved) {
+    HFI->Resolved = true;
+    auto ExternalHFI = ExternalSource->GetHeaderFileInfo(FE);
+
+    HFI = &FileInfo[FE->getUID()];
+    if (ExternalHFI.External)
+      mergeHeaderFileInfo(*HFI, ExternalHFI);
   }
 
-  HFI.IsValid = true;
+  HFI->IsValid = true;
   // We have local information about this header file, so it's no longer
   // strictly external.
-  HFI.External = false;
-  return HFI;
+  HFI->External = false;
+  return *HFI;
 }
 
 const HeaderFileInfo *
-HeaderSearch::getExistingFileInfo(const FileEntry *FE) const {
+HeaderSearch::getExistingFileInfo(const FileEntry *FE,
+                                  bool WantExternal) const {
   // If we have an external source, ensure we have the latest information.
   // FIXME: Use a generation count to check whether this is really up to date.
-  if (ExternalSource &&
-      (FE->getUID() >= FileInfo.size() || !FileInfo[FE->getUID()].Resolved)) {
-    auto ExternalHFI = ExternalSource->GetHeaderFileInfo(FE);
-    if (ExternalHFI.External) {
-      if (FE->getUID() >= FileInfo.size())
-        FileInfo.resize(FE->getUID() + 1);
-      mergeHeaderFileInfo(FileInfo[FE->getUID()], ExternalHFI);
+  HeaderFileInfo *HFI;
+  if (ExternalSource) {
+    if (FE->getUID() >= FileInfo.size()) {
+      if (!WantExternal)
+        return nullptr;
+      FileInfo.resize(FE->getUID() + 1);
     }
-  }
 
-  if (FE->getUID() >= FileInfo.size())
+    HFI = &FileInfo[FE->getUID()];
+    if (!WantExternal && (!HFI->IsValid || HFI->External))
+      return nullptr;
+    if (!HFI->Resolved) {
+      HFI->Resolved = true;
+      auto ExternalHFI = ExternalSource->GetHeaderFileInfo(FE);
+
+      HFI = &FileInfo[FE->getUID()];
+      if (ExternalHFI.External)
+        mergeHeaderFileInfo(*HFI, ExternalHFI);
+    }
+  } else if (FE->getUID() >= FileInfo.size()) {
     return nullptr;
+  } else {
+    HFI = &FileInfo[FE->getUID()];
+  }
 
-  HeaderFileInfo &HFI = FileInfo[FE->getUID()];
-  if (!HFI.IsValid)
+  if (!HFI->IsValid || (HFI->External && !WantExternal))
     return nullptr;
 
-  return &HFI;
+  return HFI;
 }
 
 bool HeaderSearch::isFileMultipleIncludeGuarded(const FileEntry *File) {
@@ -1038,8 +1055,19 @@ bool HeaderSearch::isFileMultipleIncludeGuarded(const FileEntry *File) {
 void HeaderSearch::MarkFileModuleHeader(const FileEntry *FE,
                                         ModuleMap::ModuleHeaderRole Role,
                                         bool isCompilingModuleHeader) {
+  bool isModularHeader = !(Role & ModuleMap::TextualHeader);
+
+  // Don't mark the file info as non-external if there's nothing to change.
+  if (!isCompilingModuleHeader) {
+    if (!isModularHeader)
+      return;
+    auto *HFI = getExistingFileInfo(FE);
+    if (HFI && HFI->isModuleHeader)
+      return;
+  }
+
   auto &HFI = getFileInfo(FE);
-  HFI.isModuleHeader |= !(Role & ModuleMap::TextualHeader);
+  HFI.isModuleHeader |= isModularHeader;
   HFI.isCompilingModuleHeader |= isCompilingModuleHeader;
 }
 
index d619b52bef5cc3bddcc268a6437700b3ccd72fa4..e1594eee3686975b47c82b10df26ed816c576553 100644 (file)
@@ -796,7 +796,7 @@ static Module::HeaderKind headerRoleToKind(ModuleMap::ModuleHeaderRole Role) {
 }
 
 void ModuleMap::addHeader(Module *Mod, Module::Header Header,
-                          ModuleHeaderRole Role) {
+                          ModuleHeaderRole Role, bool Imported) {
   KnownHeader KH(Mod, Role);
 
   // Only add each header to the headers list once.
@@ -811,7 +811,12 @@ void ModuleMap::addHeader(Module *Mod, Module::Header Header,
   Mod->Headers[headerRoleToKind(Role)].push_back(std::move(Header));
 
   bool isCompilingModuleHeader = Mod->getTopLevelModule() == CompilingModule;
-  HeaderInfo.MarkFileModuleHeader(Header.Entry, Role, isCompilingModuleHeader);
+  if (!Imported || isCompilingModuleHeader) {
+    // When we import HeaderFileInfo, the external source is expected to
+    // set the isModuleHeader flag itself.
+    HeaderInfo.MarkFileModuleHeader(Header.Entry, Role,
+                                    isCompilingModuleHeader);
+  }
 }
 
 void ModuleMap::excludeHeader(Module *Mod, Module::Header Header) {
index 8e19c708f733d17e7ee010d5019951c1f0d9ead7..7c94ca435deb8c5b0cac902691860a78faba635a 100644 (file)
@@ -1603,11 +1603,13 @@ HeaderFileInfoTrait::ReadData(internal_key_ref key, const unsigned char *d,
     // going to use this information to rebuild the module, so it doesn't make
     // a lot of difference.
     Module::Header H = { key.Filename, FileMgr.getFile(Filename) };
-    ModMap.addHeader(Mod, H, HeaderRole);
+    ModMap.addHeader(Mod, H, HeaderRole, /*Imported*/true);
+    HFI.isModuleHeader |= !(HeaderRole & ModuleMap::TextualHeader);
   }
 
   // This HeaderFileInfo was externally loaded.
   HFI.External = true;
+  HFI.IsValid = true;
   return HFI;
 }
 
@@ -2790,7 +2792,7 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) {
       RemapBuilder DeclRemap(F.DeclRemap);
       RemapBuilder TypeRemap(F.TypeRemap);
 
-      while(Data < DataEnd) {
+      while (Data < DataEnd) {
         using namespace llvm::support;
         uint16_t Len = endian::readNext<uint16_t, little, unaligned>(Data);
         StringRef Name = StringRef((const char*)Data, Len);
index 678258eb44f589120ce599028a0b90d9bf622f69..7058ba3eb9b2a9d0fea64b94e4ebfa9b3a489650 100644 (file)
@@ -1736,9 +1736,9 @@ void ASTWriter::WriteHeaderSearch(const HeaderSearch &HS) {
     // changed since it was loaded. Also skip it if it's for a modular header
     // from a different module; in that case, we rely on the module(s)
     // containing the header to provide this information.
-    const HeaderFileInfo *HFI = HS.getExistingFileInfo(File);
-    if (!HFI || (HFI->External && Chain) ||
-        (HFI->isModuleHeader && !HFI->isCompilingModuleHeader))
+    const HeaderFileInfo *HFI =
+        HS.getExistingFileInfo(File, /*WantExternal*/!Chain);
+    if (!HFI || (HFI->isModuleHeader && !HFI->isCompilingModuleHeader))
       continue;
 
     // Massage the file path into an appropriate form.