[cfe-commits] r136331 - in /cfe/trunk: include/clang/Driver/CC1Options.td include/clang/Driver/Options.td include/clang/Frontend/HeaderSearchOptions.h include/clang/Lex/DirectoryLookup.h include/clang/Lex/HeaderSearch.h lib/Driver/Tools.cpp lib/Frontend/CompilerInvocation.cpp lib/Frontend/InitHeaderSearch.cpp lib/Lex/HeaderSearch.cpp test/Driver/index-header-map.c

Douglas Gregor dgregor at apple.com
Wed Jul 27 21:45:53 PDT 2011


Author: dgregor
Date: Wed Jul 27 23:45:53 2011
New Revision: 136331

URL: http://llvm.org/viewvc/llvm-project?rev=136331&view=rev
Log:
Introduce the "-index-header-map" option, to give special semantics
for quoted header lookup when dealing with not-yet-installed
frameworks. Fixes <rdar://problem/9824020>.

Added:
    cfe/trunk/test/Driver/index-header-map.c   (with props)
Modified:
    cfe/trunk/include/clang/Driver/CC1Options.td
    cfe/trunk/include/clang/Driver/Options.td
    cfe/trunk/include/clang/Frontend/HeaderSearchOptions.h
    cfe/trunk/include/clang/Lex/DirectoryLookup.h
    cfe/trunk/include/clang/Lex/HeaderSearch.h
    cfe/trunk/lib/Driver/Tools.cpp
    cfe/trunk/lib/Frontend/CompilerInvocation.cpp
    cfe/trunk/lib/Frontend/InitHeaderSearch.cpp
    cfe/trunk/lib/Lex/HeaderSearch.cpp

Modified: cfe/trunk/include/clang/Driver/CC1Options.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/CC1Options.td?rev=136331&r1=136330&r2=136331&view=diff
==============================================================================
--- cfe/trunk/include/clang/Driver/CC1Options.td (original)
+++ cfe/trunk/include/clang/Driver/CC1Options.td Wed Jul 27 23:45:53 2011
@@ -609,6 +609,8 @@
   HelpText<"Add directory to include search path">;
 def idirafter : JoinedOrSeparate<"-idirafter">, MetaVarName<"<directory>">,
   HelpText<"Add directory to AFTER include search path">;
+def index_header_map : Flag<"-index-header-map">, 
+  HelpText<"Make the next included directory (-I or -F) an indexer header map">;
 def iquote : JoinedOrSeparate<"-iquote">, MetaVarName<"<directory>">,
   HelpText<"Add directory to QUOTE include search path">;
 def cxx_isystem : JoinedOrSeparate<"-cxx-isystem">, MetaVarName<"<directory>">,

Modified: cfe/trunk/include/clang/Driver/Options.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Options.td?rev=136331&r1=136330&r2=136331&view=diff
==============================================================================
--- cfe/trunk/include/clang/Driver/Options.td (original)
+++ cfe/trunk/include/clang/Driver/Options.td Wed Jul 27 23:45:53 2011
@@ -500,6 +500,7 @@
 def g_Flag : Flag<"-g">, Group<g_Group>;
 def g_Joined : Joined<"-g">, Group<g_Group>;
 def headerpad__max__install__names : Joined<"-headerpad_max_install_names">;
+def index_header_map : Flag<"-index-header-map">;
 def idirafter : JoinedOrSeparate<"-idirafter">, Group<clang_i_Group>;
 def iframework : JoinedOrSeparate<"-iframework">, Group<clang_i_Group>;
 def imacros : JoinedOrSeparate<"-imacros">, Group<clang_i_Group>;

Modified: cfe/trunk/include/clang/Frontend/HeaderSearchOptions.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/HeaderSearchOptions.h?rev=136331&r1=136330&r2=136331&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/HeaderSearchOptions.h (original)
+++ cfe/trunk/include/clang/Frontend/HeaderSearchOptions.h Wed Jul 27 23:45:53 2011
@@ -23,6 +23,8 @@
   enum IncludeDirGroup {
     Quoted = 0,     ///< '#include ""' paths, added by'gcc -iquote'.
     Angled,         ///< Paths for '#include <>' added by '-I'.
+    IndexHeaderMap, ///< Like Angled, but marks header maps used when
+                       ///  building frameworks.
     System,         ///< Like Angled, but marks system directories.
     CXXSystem,      ///< Like System, but only used for C++.
     After           ///< Like System, but searched after the system directories.

Modified: cfe/trunk/include/clang/Lex/DirectoryLookup.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/DirectoryLookup.h?rev=136331&r1=136330&r2=136331&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/DirectoryLookup.h (original)
+++ cfe/trunk/include/clang/Lex/DirectoryLookup.h Wed Jul 27 23:45:53 2011
@@ -56,21 +56,27 @@
   /// LookupType - This indicates whether this DirectoryLookup object is a
   /// normal directory, a framework, or a headermap.
   unsigned LookupType : 2;
+  
+  /// \brief Whether this is a header map used when building a framework.
+  unsigned IsIndexHeaderMap : 1;
+  
 public:
   /// DirectoryLookup ctor - Note that this ctor *does not take ownership* of
   /// 'dir'.
   DirectoryLookup(const DirectoryEntry *dir, SrcMgr::CharacteristicKind DT,
                   bool isUser, bool isFramework)
-    : DirCharacteristic(DT), UserSupplied(isUser),
-     LookupType(isFramework ? LT_Framework : LT_NormalDir) {
+    : DirCharacteristic(DT), UserSupplied(isUser), 
+      LookupType(isFramework ? LT_Framework : LT_NormalDir),
+      IsIndexHeaderMap(false) {
     u.Dir = dir;
   }
 
   /// DirectoryLookup ctor - Note that this ctor *does not take ownership* of
   /// 'map'.
   DirectoryLookup(const HeaderMap *map, SrcMgr::CharacteristicKind DT,
-                  bool isUser)
-    : DirCharacteristic(DT), UserSupplied(isUser), LookupType(LT_HeaderMap) {
+                  bool isUser, bool isIndexHeaderMap)
+    : DirCharacteristic(DT), UserSupplied(isUser), LookupType(LT_HeaderMap),
+      IsIndexHeaderMap(isIndexHeaderMap) {
     u.Map = map;
   }
 
@@ -116,7 +122,11 @@
   ///
   bool isUserSupplied() const { return UserSupplied; }
 
-
+  /// \brief Whether this header map is building a framework or not.
+  bool isIndexHeaderMap() const { 
+    return isHeaderMap() && IsIndexHeaderMap; 
+  }
+  
   /// LookupFile - Lookup the specified file in this search path, returning it
   /// if it exists or returning null if not.
   ///

Modified: cfe/trunk/include/clang/Lex/HeaderSearch.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/HeaderSearch.h?rev=136331&r1=136330&r2=136331&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/HeaderSearch.h (original)
+++ cfe/trunk/include/clang/Lex/HeaderSearch.h Wed Jul 27 23:45:53 2011
@@ -16,6 +16,7 @@
 
 #include "clang/Lex/DirectoryLookup.h"
 #include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringSet.h"
 #include "llvm/Support/Allocator.h"
 #include <vector>
 
@@ -48,6 +49,15 @@
   /// "resolved", meaning that it was loaded from the external source.
   unsigned Resolved : 1;
   
+  /// \brief Whether this is a header inside a framework that is currently
+  /// being built. 
+  ///
+  /// When a framework is being built, the headers have not yet been placed
+  /// into the appropriate framework subdirectories, and therefore are
+  /// provided via a header map. This bit indicates when this is one of
+  /// those framework headers.
+  unsigned IndexHeaderMapHeader : 1;
+  
   /// NumIncludes - This is the number of times the file has been included
   /// already.
   unsigned short NumIncludes;
@@ -69,10 +79,14 @@
   /// external storage.
   const IdentifierInfo *ControllingMacro;
 
+  /// \brief If this header came from a framework include, this is the name
+  /// of the framework.
+  StringRef Framework;
+  
   HeaderFileInfo()
     : isImport(false), isPragmaOnce(false), DirInfo(SrcMgr::C_User), 
-      External(false), Resolved(false), NumIncludes(0), ControllingMacroID(0), 
-      ControllingMacro(0)  {}
+      External(false), Resolved(false), IndexHeaderMapHeader(false),
+      NumIncludes(0), ControllingMacroID(0), ControllingMacro(0)  {}
 
   /// \brief Retrieve the controlling macro for this header file, if
   /// any.
@@ -139,6 +153,10 @@
   /// headermaps.  This vector owns the headermap.
   std::vector<std::pair<const FileEntry*, const HeaderMap*> > HeaderMaps;
 
+  /// \brief Uniqued set of framework names, which is used to track which 
+  /// headers were included as framework headers.
+  llvm::StringSet<llvm::BumpPtrAllocator> FrameworkNames;
+  
   /// \brief Entity used to resolve the identifier IDs of controlling
   /// macros into IdentifierInfo pointers, as needed.
   ExternalIdentifierLookup *ExternalLookup;
@@ -325,6 +343,9 @@
   }
   search_dir_iterator system_dir_end() const { return SearchDirs.end(); }
 
+  /// \brief Retrieve a uniqued framework name.
+  StringRef getUniqueFrameworkName(StringRef Framework);
+  
   void PrintStats();
   
   size_t getTotalMemory() const;

Modified: cfe/trunk/lib/Driver/Tools.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Tools.cpp?rev=136331&r1=136330&r2=136331&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/Tools.cpp (original)
+++ cfe/trunk/lib/Driver/Tools.cpp Wed Jul 27 23:45:53 2011
@@ -341,7 +341,8 @@
   }
 
   Args.AddAllArgs(CmdArgs, options::OPT_D, options::OPT_U);
-  Args.AddAllArgs(CmdArgs, options::OPT_I_Group, options::OPT_F);
+  Args.AddAllArgs(CmdArgs, options::OPT_I_Group, options::OPT_F,
+                  options::OPT_index_header_map);
 
   // Add C++ include arguments, if needed.
   types::ID InputType = Inputs[0].getType();

Modified: cfe/trunk/lib/Frontend/CompilerInvocation.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInvocation.cpp?rev=136331&r1=136330&r2=136331&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/CompilerInvocation.cpp (original)
+++ cfe/trunk/lib/Frontend/CompilerInvocation.cpp Wed Jul 27 23:45:53 2011
@@ -520,17 +520,31 @@
     if (E.IsFramework && (E.Group != frontend::Angled || !E.IsUserSupplied))
       llvm::report_fatal_error("Invalid option set!");
     if (E.IsUserSupplied) {
-      if (E.Group == frontend::After) {
+      switch (E.Group) {
+      case frontend::After:
         Res.push_back("-idirafter");
-      } else if (E.Group == frontend::Quoted) {
+        break;
+        
+      case frontend::Quoted:
         Res.push_back("-iquote");
-      } else if (E.Group == frontend::System) {
+        break;
+        
+      case frontend::System:
         Res.push_back("-isystem");
-      } else if (E.Group == frontend::CXXSystem) {
+        break;
+        
+      case frontend::IndexHeaderMap:
+        Res.push_back("-index-header-map");
+        Res.push_back(E.IsFramework? "-F" : "-I");
+        break;
+        
+      case frontend::CXXSystem:
         Res.push_back("-cxx-isystem");
-      } else {
-        assert(E.Group == frontend::Angled && "Invalid group!");
+        break;
+        
+      case frontend::Angled:
         Res.push_back(E.IsFramework ? "-F" : "-I");
+        break;
       }
     } else {
       if (E.Group != frontend::Angled && E.Group != frontend::System)
@@ -1364,11 +1378,24 @@
     Opts.UseLibcxx = (strcmp(A->getValue(Args), "libc++") == 0);
   Opts.ResourceDir = Args.getLastArgValue(OPT_resource_dir);
 
-  // Add -I... and -F... options in order.
-  for (arg_iterator it = Args.filtered_begin(OPT_I, OPT_F),
-         ie = Args.filtered_end(); it != ie; ++it)
-    Opts.AddPath((*it)->getValue(Args), frontend::Angled, true,
+  // Add -I..., -F..., and -index-header-map options in order.
+  bool IsIndexHeaderMap = false;
+  for (arg_iterator it = Args.filtered_begin(OPT_I, OPT_F, 
+                                             OPT_index_header_map),
+       ie = Args.filtered_end(); it != ie; ++it) {
+    if ((*it)->getOption().matches(OPT_index_header_map)) {
+      // -index-header-map applies to the next -I or -F.
+      IsIndexHeaderMap = true;
+      continue;
+    }
+        
+    frontend::IncludeDirGroup Group 
+      = IsIndexHeaderMap? frontend::IndexHeaderMap : frontend::Angled;
+    
+    Opts.AddPath((*it)->getValue(Args), Group, true,
                  /*IsFramework=*/ (*it)->getOption().matches(OPT_F), false);
+    IsIndexHeaderMap = false;
+  }
 
   // Add -iprefix/-iwith-prefix/-iwithprefixbefore options.
   StringRef Prefix = ""; // FIXME: This isn't the correct default prefix.

Modified: cfe/trunk/lib/Frontend/InitHeaderSearch.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/InitHeaderSearch.cpp?rev=136331&r1=136330&r2=136331&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/InitHeaderSearch.cpp (original)
+++ cfe/trunk/lib/Frontend/InitHeaderSearch.cpp Wed Jul 27 23:45:53 2011
@@ -134,7 +134,7 @@
 
   // Compute the DirectoryLookup type.
   SrcMgr::CharacteristicKind Type;
-  if (Group == Quoted || Group == Angled)
+  if (Group == Quoted || Group == Angled || Group == IndexHeaderMap)
     Type = SrcMgr::C_User;
   else if (isCXXAware)
     Type = SrcMgr::C_System;
@@ -156,7 +156,7 @@
       if (const HeaderMap *HM = Headers.CreateHeaderMap(FE)) {
         // It is a headermap, add it to the search path.
         IncludePath.push_back(std::make_pair(Group, DirectoryLookup(HM, Type,
-                              isUserSupplied)));
+                              isUserSupplied, Group == IndexHeaderMap)));
         return;
       }
     }
@@ -1054,7 +1054,7 @@
 
   for (path_iterator it = IncludePath.begin(), ie = IncludePath.end();
        it != ie; ++it) {
-    if (it->first == Angled)
+    if (it->first == Angled || it->first == IndexHeaderMap)
       SearchList.push_back(it->second);
   }
 

Modified: cfe/trunk/lib/Lex/HeaderSearch.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/HeaderSearch.cpp?rev=136331&r1=136330&r2=136331&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/HeaderSearch.cpp (original)
+++ cfe/trunk/lib/Lex/HeaderSearch.cpp Wed Jul 27 23:45:53 2011
@@ -280,7 +280,23 @@
     return FileMgr.getFile(Filename, /*openFile=*/true);
   }
 
-  // Step #0, unless disabled, check to see if the file is in the #includer's
+  // If we are including a file with a quoted include "foo.h" from inside
+  // a header in a framework that is currently being built, change the include
+  // to <Foo/foo.h>, where "Foo" is the name of the framework in which the
+  // including header was found.
+  llvm::SmallString<128> ScratchFilename;
+  if (CurFileEnt && !isAngled && Filename.find('/') == StringRef::npos) {
+    HeaderFileInfo &IncludingHFI = getFileInfo(CurFileEnt);
+    if (IncludingHFI.IndexHeaderMapHeader) {
+      isAngled = true;
+      ScratchFilename += IncludingHFI.Framework;
+      ScratchFilename += '/';
+      ScratchFilename += Filename;
+      Filename = ScratchFilename;
+    }
+  }
+
+  // Unless disabled, check to see if the file is in the #includer's
   // directory.  This has to be based on CurFileEnt, not CurDir, because
   // CurFileEnt could be a #include of a subdirectory (#include "foo/bar.h") and
   // a subsequent include of "baz.h" should resolve to "whatever/foo/baz.h".
@@ -353,8 +369,20 @@
     CurDir = &SearchDirs[i];
 
     // This file is a system header or C++ unfriendly if the dir is.
-    getFileInfo(FE).DirInfo = CurDir->getDirCharacteristic();
+    HeaderFileInfo &HFI = getFileInfo(FE);
+    HFI.DirInfo = CurDir->getDirCharacteristic();
 
+    // If this file is found in a header map and uses the framework style of
+    // includes, then this header is part of a framework we're building.
+    if (CurDir->isIndexHeaderMap()) {
+      size_t SlashPos = Filename.find('/');
+      if (SlashPos != StringRef::npos) {
+        HFI.IndexHeaderMapHeader = 1;
+        HFI.Framework = getUniqueFrameworkName(StringRef(Filename.begin(), 
+                                                         SlashPos));
+      }
+    }
+    
     // Remember this location for the next lookup we do.
     CacheLookup.second = i;
     return FE;
@@ -550,3 +578,7 @@
     + LookupFileCache.getAllocator().getTotalMemory()
     + FrameworkMap.getAllocator().getTotalMemory();
 }
+
+StringRef HeaderSearch::getUniqueFrameworkName(StringRef Framework) {
+  return FrameworkNames.GetOrCreateValue(Framework).getKey();
+}

Added: cfe/trunk/test/Driver/index-header-map.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/index-header-map.c?rev=136331&view=auto
==============================================================================
--- cfe/trunk/test/Driver/index-header-map.c (added)
+++ cfe/trunk/test/Driver/index-header-map.c Wed Jul 27 23:45:53 2011
@@ -0,0 +1,4 @@
+// RUN: %clang -I%S/Before -index-header-map -I%S/Index -I%S/After %s -### 2>> %t.log
+// RUN: FileCheck %s < %t.log
+
+// CHECK: {{-I.*Before.*-index-header-map.*-I.*Index.*-I.*After}}

Propchange: cfe/trunk/test/Driver/index-header-map.c
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cfe/trunk/test/Driver/index-header-map.c
------------------------------------------------------------------------------
    svn:keywords = Id

Propchange: cfe/trunk/test/Driver/index-header-map.c
------------------------------------------------------------------------------
    svn:mime-type = text/plain





More information about the cfe-commits mailing list