]> granicus.if.org Git - clang/commitdiff
Prevent outputting HeaderFileInfos for files not used as headers
authorBen Langmuir <blangmuir@apple.com>
Thu, 13 Mar 2014 16:46:36 +0000 (16:46 +0000)
committerBen Langmuir <blangmuir@apple.com>
Thu, 13 Mar 2014 16:46:36 +0000 (16:46 +0000)
When building an AST file, we don't want to output HeaderFileInfo
structures for files that are not actually used as headers in the
current context.  This can lead to assuming that unrelated files have
include counts of 0, defeating multiple-include prevention.

This is accomplished by adding an IsValid bit to the HFI.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@203813 91177308-0d34-0410-b5e6-96231b3b80d8

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

index d3b3193572afe0f171ed7669d016098b432f6bb5..e326db763c4021ce6ec7a3d83f6a814ef4744bdc 100644 (file)
@@ -73,6 +73,9 @@ struct HeaderFileInfo {
   /// provided via a header map. This bit indicates when this is one of
   /// those framework headers.
   unsigned IndexHeaderMapHeader : 1;
+
+  /// \brief Whether this file had been looked up as a header.
+  unsigned IsValid : 1;
   
   /// \brief The number of times the file has been included already.
   unsigned short NumIncludes;
@@ -102,7 +105,7 @@ struct HeaderFileInfo {
     : isImport(false), isPragmaOnce(false), DirInfo(SrcMgr::C_User), 
       External(false), isModuleHeader(false), isCompilingModuleHeader(false),
       HeaderRole(ModuleMap::NormalHeader),
-      Resolved(false), IndexHeaderMapHeader(false),
+      Resolved(false), IndexHeaderMapHeader(false), IsValid(0),
       NumIncludes(0), ControllingMacroID(0), ControllingMacro(0)  {}
 
   /// \brief Retrieve the controlling macro for this header file, if
@@ -557,16 +560,20 @@ private:
   /// of the given search directory.
   void loadSubdirectoryModuleMaps(DirectoryLookup &SearchDir);
 
+  /// \brief Return the HeaderFileInfo structure for the specified FileEntry.
+  const HeaderFileInfo &getFileInfo(const FileEntry *FE) const {
+    return const_cast<HeaderSearch*>(this)->getFileInfo(FE);
+  }
+
 public:
   /// \brief Retrieve the module map.
   ModuleMap &getModuleMap() { return ModMap; }
   
   unsigned header_file_size() const { return FileInfo.size(); }
 
-  /// \brief Return the HeaderFileInfo structure for the specified FileEntry.
-  const HeaderFileInfo &getFileInfo(const FileEntry *FE) const {
-    return const_cast<HeaderSearch*>(this)->getFileInfo(FE);
-  }
+  /// \brief Get a \c HeaderFileInfo structure for the specified \c FileEntry,
+  /// if one exists.
+  bool tryGetFileInfo(const FileEntry *FE, HeaderFileInfo &Result) const;
 
   // Used by external tools
   typedef std::vector<DirectoryLookup>::const_iterator search_dir_iterator;
index 97bff4f27739bff13ef8250544e882ce76f3e10d..46d4d41b9af3cdc71433310f8f8d9db08a5007a3 100644 (file)
@@ -988,9 +988,21 @@ HeaderFileInfo &HeaderSearch::getFileInfo(const FileEntry *FE) {
   HeaderFileInfo &HFI = FileInfo[FE->getUID()];
   if (ExternalSource && !HFI.Resolved)
     mergeHeaderFileInfo(HFI, ExternalSource->GetHeaderFileInfo(FE));
+  HFI.IsValid = 1;
   return HFI;
 }
 
+bool HeaderSearch::tryGetFileInfo(const FileEntry *FE, HeaderFileInfo &Result) const {
+  if (FE->getUID() >= FileInfo.size())
+    return false;
+  const HeaderFileInfo &HFI = FileInfo[FE->getUID()];
+  if (HFI.IsValid) {
+    Result = HFI;
+    return true;
+  }
+  return false;
+}
+
 bool HeaderSearch::isFileMultipleIncludeGuarded(const FileEntry *File) {
   // Check if we've ever seen this file as a header.
   if (File->getUID() >= FileInfo.size())
index fc1806fca68697ce5c1e049a011b8e716cca0c2b..95a470d922388a92d17f4c1cf3ef260be8c720b8 100644 (file)
@@ -1547,10 +1547,10 @@ void ASTWriter::WriteHeaderSearch(const HeaderSearch &HS, StringRef isysroot) {
 
     // Use HeaderSearch's getFileInfo to make sure we get the HeaderFileInfo
     // from the external source if it was not provided already.
-    const HeaderFileInfo &HFI = HS.getFileInfo(File);
-    if (HFI.External && Chain)
-      continue;
-    if (HFI.isModuleHeader && !HFI.isCompilingModuleHeader)
+    HeaderFileInfo HFI;
+    if (!HS.tryGetFileInfo(File, HFI) ||
+        (HFI.External && Chain) ||
+        (HFI.isModuleHeader && !HFI.isCompilingModuleHeader))
       continue;
 
     // Turn the file name into an absolute path, if it isn't already.