[cfe-commits] r146158 - in /cfe/trunk: include/clang/Basic/Module.h lib/Basic/Module.cpp lib/Frontend/FrontendActions.cpp lib/Lex/ModuleMap.cpp lib/Serialization/ASTReader.cpp lib/Serialization/ASTWriter.cpp

Douglas Gregor dgregor at apple.com
Thu Dec 8 09:39:04 PST 2011


Author: dgregor
Date: Thu Dec  8 11:39:04 2011
New Revision: 146158

URL: http://llvm.org/viewvc/llvm-project?rev=146158&view=rev
Log:
Within the module representation, generalize the notion of an umbrella
header to also support umbrella directories. The umbrella directory
for an umbrella header is the directory in which the umbrella header
resides.

No functionality change yet, but it's coming.

Modified:
    cfe/trunk/include/clang/Basic/Module.h
    cfe/trunk/lib/Basic/Module.cpp
    cfe/trunk/lib/Frontend/FrontendActions.cpp
    cfe/trunk/lib/Lex/ModuleMap.cpp
    cfe/trunk/lib/Serialization/ASTReader.cpp
    cfe/trunk/lib/Serialization/ASTWriter.cpp

Modified: cfe/trunk/include/clang/Basic/Module.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Module.h?rev=146158&r1=146157&r2=146158&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/Module.h (original)
+++ cfe/trunk/include/clang/Basic/Module.h Thu Dec  8 11:39:04 2011
@@ -16,6 +16,7 @@
 
 #include "clang/Basic/SourceLocation.h"
 #include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/PointerUnion.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringMap.h"
 #include "llvm/ADT/StringRef.h"
@@ -29,7 +30,8 @@
 namespace clang {
   
 class FileEntry;
-
+class DirectoryEntry;
+  
 /// \brief Describes the name of a module.
 typedef llvm::SmallVector<std::pair<std::string, SourceLocation>, 2>
   ModuleId;
@@ -47,10 +49,8 @@
   /// module.
   Module *Parent;
   
-  /// \brief The umbrella header, if any.
-  ///
-  /// Only the top-level module can have an umbrella header.
-  const FileEntry *UmbrellaHeader;
+  /// \brief The umbrella header or directory.
+  llvm::PointerUnion<const DirectoryEntry *, const FileEntry *> Umbrella;
   
   /// \brief The submodules of this module, indexed by name.
   llvm::StringMap<Module *> SubModules;
@@ -130,7 +130,7 @@
   /// \brief Construct a top-level module.
   explicit Module(StringRef Name, SourceLocation DefinitionLoc,
                   bool IsFramework)
-    : Name(Name), DefinitionLoc(DefinitionLoc), Parent(0), UmbrellaHeader(0),
+    : Name(Name), DefinitionLoc(DefinitionLoc), Parent(0), Umbrella(),
       IsFramework(IsFramework), IsExplicit(false), InferSubmodules(false),
       InferExplicitSubmodules(false), InferExportWildcard(false),
       NameVisibility(Hidden) { }
@@ -139,7 +139,7 @@
   Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent, 
          bool IsFramework, bool IsExplicit)
     : Name(Name), DefinitionLoc(DefinitionLoc), Parent(Parent), 
-      UmbrellaHeader(0), IsFramework(IsFramework), IsExplicit(IsExplicit), 
+      Umbrella(), IsFramework(IsFramework), IsExplicit(IsExplicit), 
       InferSubmodules(false), InferExplicitSubmodules(false), 
       InferExportWildcard(false),NameVisibility(Hidden) { }
   
@@ -184,6 +184,16 @@
     return getTopLevelModule()->Name;
   }
   
+  /// \brief Retrieve the directory for which this module serves as the
+  /// umbrella.
+  const DirectoryEntry *getUmbrellaDir() const;
+
+  /// \brief Retrieve the header that serves as the umbrella header for this
+  /// module.
+  const FileEntry *getUmbrellaHeader() const {
+    return Umbrella.dyn_cast<const FileEntry *>();
+  }
+
   /// \brief Print the module map for this module to the given stream. 
   ///
   void print(llvm::raw_ostream &OS, unsigned Indent = 0) const;

Modified: cfe/trunk/lib/Basic/Module.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/Module.cpp?rev=146158&r1=146157&r2=146158&view=diff
==============================================================================
--- cfe/trunk/lib/Basic/Module.cpp (original)
+++ cfe/trunk/lib/Basic/Module.cpp Thu Dec  8 11:39:04 2011
@@ -65,6 +65,13 @@
   return Result;
 }
 
+const DirectoryEntry *Module::getUmbrellaDir() const {
+  if (const FileEntry *Header = getUmbrellaHeader())
+    return Header->getDir();
+  
+  return Umbrella.dyn_cast<const DirectoryEntry *>();
+}
+
 static void printModuleId(llvm::raw_ostream &OS, const ModuleId &Id) {
   for (unsigned I = 0, N = Id.size(); I != N; ++I) {
     if (I)
@@ -81,7 +88,7 @@
     OS << "explicit ";
   OS << "module " << Name << " {\n";
   
-  if (UmbrellaHeader) {
+  if (const FileEntry *UmbrellaHeader = getUmbrellaHeader()) {
     OS.indent(Indent + 2);
     OS << "umbrella \"";
     OS.write_escaped(UmbrellaHeader->getName());

Modified: cfe/trunk/lib/Frontend/FrontendActions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/FrontendActions.cpp?rev=146158&r1=146157&r2=146158&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/FrontendActions.cpp (original)
+++ cfe/trunk/lib/Frontend/FrontendActions.cpp Thu Dec  8 11:39:04 2011
@@ -145,14 +145,16 @@
     Includes += "\"\n";
   }
 
-  if (Module->UmbrellaHeader && Module->Parent) {
-    // Include the umbrella header for submodules.
-    if (LangOpts.ObjC1)
-      Includes += "#import \"";
-    else
-      Includes += "#include \"";
-    Includes += Module->UmbrellaHeader->getName();
-    Includes += "\"\n";    
+  if (const FileEntry *UmbrellaHeader = Module->getUmbrellaHeader()) {
+    if (Module->Parent) {
+      // Include the umbrella header for submodules.
+      if (LangOpts.ObjC1)
+        Includes += "#import \"";
+      else
+        Includes += "#include \"";
+      Includes += UmbrellaHeader->getName();
+      Includes += "\"\n";
+    }
   }
   
   // Recurse into submodules.
@@ -197,29 +199,32 @@
     return false;
   }
   
+  // Do we have an umbrella header for this module?
+  const FileEntry *UmbrellaHeader = Module->getUmbrellaHeader();
+  
   // Collect the set of #includes we need to build the module.
   llvm::SmallString<256> HeaderContents;
   collectModuleHeaderIncludes(CI.getLangOpts(), Module, HeaderContents);
-  if (Module->UmbrellaHeader && HeaderContents.empty()) {
+  if (UmbrellaHeader && HeaderContents.empty()) {
     // Simple case: we have an umbrella header and there are no additional
     // includes, we can just parse the umbrella header directly.
-    setCurrentFile(Module->UmbrellaHeader->getName(), getCurrentFileKind());
+    setCurrentFile(UmbrellaHeader->getName(), getCurrentFileKind());
     return true;
   }
   
   FileManager &FileMgr = CI.getFileManager();
   llvm::SmallString<128> HeaderName;
   time_t ModTime;
-  if (Module->UmbrellaHeader) {
+  if (UmbrellaHeader) {
     // Read in the umbrella header.
     // FIXME: Go through the source manager; the umbrella header may have
     // been overridden.
     std::string ErrorStr;
     llvm::MemoryBuffer *UmbrellaContents
-      = FileMgr.getBufferForFile(Module->UmbrellaHeader, &ErrorStr);
+      = FileMgr.getBufferForFile(UmbrellaHeader, &ErrorStr);
     if (!UmbrellaContents) {
       CI.getDiagnostics().Report(diag::err_missing_umbrella_header)
-        << Module->UmbrellaHeader->getName() << ErrorStr;
+        << UmbrellaHeader->getName() << ErrorStr;
       return false;
     }
     
@@ -232,8 +237,8 @@
     HeaderContents += OldContents;
 
     // Pretend that we're parsing the umbrella header.
-    HeaderName = Module->UmbrellaHeader->getName();
-    ModTime = Module->UmbrellaHeader->getModificationTime();
+    HeaderName = UmbrellaHeader->getName();
+    ModTime = UmbrellaHeader->getModificationTime();
     
     delete UmbrellaContents;
   } else {

Modified: cfe/trunk/lib/Lex/ModuleMap.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/ModuleMap.cpp?rev=146158&r1=146157&r2=146158&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/ModuleMap.cpp (original)
+++ cfe/trunk/lib/Lex/ModuleMap.cpp Thu Dec  8 11:39:04 2011
@@ -106,9 +106,9 @@
       Module *Result = KnownDir->second;
       
       // Search up the module stack until we find a module with an umbrella
-      // header.
+      // directory.
       Module *UmbrellaModule = Result;
-      while (!UmbrellaModule->UmbrellaHeader && UmbrellaModule->Parent)
+      while (!UmbrellaModule->getUmbrellaDir() && UmbrellaModule->Parent)
         UmbrellaModule = UmbrellaModule->Parent;
       
       if (UmbrellaModule->InferSubmodules) {
@@ -260,7 +260,7 @@
     Modules[ModuleName] = Result;
 
   // umbrella "umbrella-header-name"
-  Result->UmbrellaHeader = UmbrellaHeader;
+  Result->Umbrella = UmbrellaHeader;
   Headers[UmbrellaHeader] = Result;
   UmbrellaDirs[FrameworkDir] = Result;
   
@@ -336,7 +336,7 @@
 
 void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader){
   Headers[UmbrellaHeader] = Mod;
-  Mod->UmbrellaHeader = UmbrellaHeader;
+  Mod->Umbrella = UmbrellaHeader;
   
   const DirectoryEntry *UmbrellaDir = UmbrellaHeader->getDir();
   if (Mod->IsFramework)
@@ -864,10 +864,10 @@
   SourceLocation FileNameLoc = consumeToken();
 
   // Check whether we already have an umbrella header.
-  if (ActiveModule->UmbrellaHeader) {
+  if (ActiveModule->getUmbrellaHeader()) {
     Diags.Report(FileNameLoc, diag::err_mmap_umbrella_header_conflict)
       << ActiveModule->getFullModuleName() 
-      << ActiveModule->UmbrellaHeader->getName();
+      << ActiveModule->getUmbrellaHeader()->getName();
     HadError = true;
     return;
   }
@@ -1064,7 +1064,7 @@
   }
   
   // Inferred modules must have umbrella headers.
-  if (!Failed && !ActiveModule->UmbrellaHeader) {
+  if (!Failed && !ActiveModule->getUmbrellaHeader()) {
     Diags.Report(StarLoc, diag::err_mmap_inferred_no_umbrella);
     Failed = true;
   }

Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=146158&r1=146157&r2=146158&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Thu Dec  8 11:39:04 2011
@@ -3099,9 +3099,9 @@
       
       StringRef FileName(BlobStart, BlobLen);
       if (const FileEntry *Umbrella = PP.getFileManager().getFile(FileName)) {
-        if (!CurrentModule->UmbrellaHeader)
+        if (!CurrentModule->getUmbrellaHeader())
           ModMap.setUmbrellaHeader(CurrentModule, Umbrella);
-        else if (CurrentModule->UmbrellaHeader != Umbrella) {
+        else if (CurrentModule->getUmbrellaHeader() != Umbrella) {
           Error("mismatched umbrella headers in submodule");
           return Failure;
         }

Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=146158&r1=146157&r2=146158&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriter.cpp Thu Dec  8 11:39:04 2011
@@ -1941,11 +1941,11 @@
     Stream.EmitRecordWithBlob(DefinitionAbbrev, Record, Mod->Name);
     
     // Emit the umbrella header, if there is one.
-    if (Mod->UmbrellaHeader) {
+    if (const FileEntry *UmbrellaHeader = Mod->getUmbrellaHeader()) {
       Record.clear();
       Record.push_back(SUBMODULE_UMBRELLA);
       Stream.EmitRecordWithBlob(UmbrellaAbbrev, Record, 
-                                Mod->UmbrellaHeader->getName());
+                                UmbrellaHeader->getName());
     }
     
     // Emit the headers.





More information about the cfe-commits mailing list