[cfe-commits] r145811 - in /cfe/trunk: include/clang/Basic/ lib/Basic/ lib/Lex/ lib/Serialization/ test/Modules/ test/Modules/Inputs/ test/Modules/Inputs/wildcard-submodule-exports/

Douglas Gregor dgregor at apple.com
Mon Dec 5 09:28:07 PST 2011


Author: dgregor
Date: Mon Dec  5 11:28:06 2011
New Revision: 145811

URL: http://llvm.org/viewvc/llvm-project?rev=145811&view=rev
Log:
Implement support for wildcard exports in modules, allowing a module
to re-export anything that it imports. This opt-in feature makes a
module behave more like a header, because it can be used to re-export
the transitive closure of a (sub)module's dependencies.

Added:
    cfe/trunk/test/Modules/Inputs/wildcard-submodule-exports/
    cfe/trunk/test/Modules/Inputs/wildcard-submodule-exports/A_one.h
    cfe/trunk/test/Modules/Inputs/wildcard-submodule-exports/A_two.h
    cfe/trunk/test/Modules/Inputs/wildcard-submodule-exports/B_one.h
    cfe/trunk/test/Modules/Inputs/wildcard-submodule-exports/B_two.h
    cfe/trunk/test/Modules/Inputs/wildcard-submodule-exports/C_one.h
    cfe/trunk/test/Modules/Inputs/wildcard-submodule-exports/C_two.h
    cfe/trunk/test/Modules/Inputs/wildcard-submodule-exports/module.map
    cfe/trunk/test/Modules/wildcard-submodule-exports.cpp
Modified:
    cfe/trunk/include/clang/Basic/Module.h
    cfe/trunk/lib/Basic/Module.cpp
    cfe/trunk/lib/Lex/ModuleMap.cpp
    cfe/trunk/lib/Serialization/ASTReader.cpp
    cfe/trunk/lib/Serialization/ASTWriter.cpp
    cfe/trunk/test/Modules/Inputs/module.map

Modified: cfe/trunk/include/clang/Basic/Module.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Module.h?rev=145811&r1=145810&r2=145811&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/Module.h (original)
+++ cfe/trunk/include/clang/Basic/Module.h Mon Dec  5 11:28:06 2011
@@ -128,6 +128,10 @@
   /// \brief Determine whether this module is a submodule.
   bool isSubModule() const { return Parent != 0; }
   
+  /// \brief Determine whether this module is a submodule of the given other
+  /// module.
+  bool isSubModuleOf(Module *Other) const;
+  
   /// \brief Determine whether this module is a part of a framework,
   /// either because it is a framework module or because it is a submodule
   /// of a framework module.

Modified: cfe/trunk/lib/Basic/Module.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/Module.cpp?rev=145811&r1=145810&r2=145811&view=diff
==============================================================================
--- cfe/trunk/lib/Basic/Module.cpp (original)
+++ cfe/trunk/lib/Basic/Module.cpp Mon Dec  5 11:28:06 2011
@@ -25,6 +25,18 @@
   
 }
 
+bool Module::isSubModuleOf(Module *Other) const {
+  const Module *This = this;
+  do {
+    if (This == Other)
+      return true;
+    
+    This = This->Parent;
+  } while (This);
+  
+  return false;
+}
+
 std::string Module::getFullModuleName() const {
   llvm::SmallVector<StringRef, 2> Names;
   

Modified: cfe/trunk/lib/Lex/ModuleMap.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/ModuleMap.cpp?rev=145811&r1=145810&r2=145811&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/ModuleMap.cpp (original)
+++ cfe/trunk/lib/Lex/ModuleMap.cpp Mon Dec  5 11:28:06 2011
@@ -31,6 +31,12 @@
 ModuleMap::resolveExport(Module *Mod, 
                          const Module::UnresolvedExportDecl &Unresolved,
                          bool Complain) {
+  // We may have just a wildcard.
+  if (Unresolved.Id.empty()) {
+    assert(Unresolved.Wildcard && "Invalid unresolved export");
+    return Module::ExportDecl(0, true);
+  }
+  
   // Find the starting module.
   Module *Context = lookupModuleUnqualified(Unresolved.Id[0].first, Mod);
   if (!Context) {
@@ -229,7 +235,7 @@
   for (unsigned I = 0, N = Mod->UnresolvedExports.size(); I != N; ++I) {
     Module::ExportDecl Export = resolveExport(Mod, Mod->UnresolvedExports[I], 
                                               Complain);
-    if (Export.getPointer())
+    if (Export.getPointer() || Export.getInt())
       Mod->Exports.push_back(Export);
     else
       HadError = true;
@@ -764,6 +770,7 @@
     
     if(Tok.is(MMToken::Star)) {
       Wildcard = true;
+      consumeToken();
       break;
     }
     

Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=145811&r1=145810&r2=145811&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Mon Dec  5 11:28:06 2011
@@ -2520,15 +2520,60 @@
     }
     
     // Push any exported modules onto the stack to be marked as visible.
+    bool AnyWildcard = false;
+    bool UnrestrictedWildcard = false;
+    llvm::SmallVector<Module *, 4> WildcardRestrictions;
     for (unsigned I = 0, N = Mod->Exports.size(); I != N; ++I) {
       Module *Exported = Mod->Exports[I].getPointer();
-      if (Visited.insert(Exported)) {
-        // FIXME: The intent of wildcards is to re-export any imported modules.
-        // However, we don't yet have the module-dependency information to do
-        // this, so we ignore wildcards for now.
-        if (!Mod->Exports[I].getInt())
+      if (!Mod->Exports[I].getInt()) {
+        // Export a named module directly; no wildcards involved.
+        if (Visited.insert(Exported))
           Stack.push_back(Exported);
+        
+        continue;
+      }
+      
+      // Wildcard export: export all of the imported modules that match
+      // the given pattern.
+      AnyWildcard = true;
+      if (UnrestrictedWildcard)
+        continue;
+
+      if (Module *Restriction = Mod->Exports[I].getPointer())
+        WildcardRestrictions.push_back(Restriction);
+      else {
+        WildcardRestrictions.clear();
+        UnrestrictedWildcard = true;
+      }
+    }
+    
+    // If there were any wildcards, push any imported modules that were
+    // re-exported by the wildcard restriction.
+    if (!AnyWildcard)
+      continue;
+    
+    for (unsigned I = 0, N = Mod->Imports.size(); I != N; ++I) {
+      Module *Imported = Mod->Imports[I];
+      if (Visited.count(Imported))
+        continue;
+      
+      bool Acceptable = UnrestrictedWildcard;
+      if (!Acceptable) {
+        // Check whether this module meets one of the restrictions.
+        for (unsigned R = 0, NR = WildcardRestrictions.size(); R != NR; ++R) {
+          Module *Restriction = WildcardRestrictions[R];
+          if (Imported == Restriction || Imported->isSubModuleOf(Restriction)) {
+            Acceptable = true;
+            break;
+          }
+        }
       }
+      
+      if (!Acceptable)
+        continue;
+      
+      Visited.insert(Imported);
+      Stack.push_back(Imported);
     }
   }
 }
@@ -2563,13 +2608,17 @@
   for (unsigned I = 0, N = UnresolvedModuleImportExports.size(); I != N; ++I) {
     UnresolvedModuleImportExport &Unresolved = UnresolvedModuleImportExports[I];
     SubmoduleID GlobalID = getGlobalSubmoduleID(*Unresolved.File,Unresolved.ID);
-    if (Module *ResolvedMod = getSubmodule(GlobalID)) {
-      if (Unresolved.IsImport)
+    Module *ResolvedMod = getSubmodule(GlobalID);
+    
+    if (Unresolved.IsImport) {
+      if (ResolvedMod)
         Unresolved.Mod->Imports.push_back(ResolvedMod);
-      else
-        Unresolved.Mod->Exports.push_back(
-          Module::ExportDecl(ResolvedMod, Unresolved.IsWildcard));
+      continue;
     }
+
+    if (ResolvedMod || Unresolved.IsWildcard)
+      Unresolved.Mod->Exports.push_back(
+        Module::ExportDecl(ResolvedMod, Unresolved.IsWildcard));
   }
   UnresolvedModuleImportExports.clear();
   

Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=145811&r1=145810&r2=145811&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriter.cpp Mon Dec  5 11:28:06 2011
@@ -1957,7 +1957,8 @@
       Record.clear();
       for (unsigned I = 0, N = Mod->Exports.size(); I != N; ++I) {
         unsigned ExportedID = SubmoduleIDs[Mod->Exports[I].getPointer()];
-        assert(ExportedID && "Unknown submodule!");                                           
+        assert((ExportedID || !Mod->Exports[I].getPointer()) &&
+               "Unknown submodule!");                                           
         Record.push_back(ExportedID);
         Record.push_back(Mod->Exports[I].getInt());
       }

Modified: cfe/trunk/test/Modules/Inputs/module.map
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/module.map?rev=145811&r1=145810&r2=145811&view=diff
==============================================================================
--- cfe/trunk/test/Modules/Inputs/module.map (original)
+++ cfe/trunk/test/Modules/Inputs/module.map Mon Dec  5 11:28:06 2011
@@ -9,8 +9,7 @@
 }
 module diamond_bottom { 
   header "diamond_bottom.h" 
-  export diamond_left
-  export diamond_right
+  export *
 }
 module irgen { header "irgen.h" }
 module lookup_left_objc { header "lookup_left.h" }

Added: cfe/trunk/test/Modules/Inputs/wildcard-submodule-exports/A_one.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/wildcard-submodule-exports/A_one.h?rev=145811&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/wildcard-submodule-exports/A_one.h (added)
+++ cfe/trunk/test/Modules/Inputs/wildcard-submodule-exports/A_one.h Mon Dec  5 11:28:06 2011
@@ -0,0 +1 @@
+int *A1;

Added: cfe/trunk/test/Modules/Inputs/wildcard-submodule-exports/A_two.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/wildcard-submodule-exports/A_two.h?rev=145811&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/wildcard-submodule-exports/A_two.h (added)
+++ cfe/trunk/test/Modules/Inputs/wildcard-submodule-exports/A_two.h Mon Dec  5 11:28:06 2011
@@ -0,0 +1 @@
+unsigned int *A2;

Added: cfe/trunk/test/Modules/Inputs/wildcard-submodule-exports/B_one.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/wildcard-submodule-exports/B_one.h?rev=145811&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/wildcard-submodule-exports/B_one.h (added)
+++ cfe/trunk/test/Modules/Inputs/wildcard-submodule-exports/B_one.h Mon Dec  5 11:28:06 2011
@@ -0,0 +1 @@
+short *B1;

Added: cfe/trunk/test/Modules/Inputs/wildcard-submodule-exports/B_two.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/wildcard-submodule-exports/B_two.h?rev=145811&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/wildcard-submodule-exports/B_two.h (added)
+++ cfe/trunk/test/Modules/Inputs/wildcard-submodule-exports/B_two.h Mon Dec  5 11:28:06 2011
@@ -0,0 +1 @@
+unsigned short *B2;

Added: cfe/trunk/test/Modules/Inputs/wildcard-submodule-exports/C_one.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/wildcard-submodule-exports/C_one.h?rev=145811&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/wildcard-submodule-exports/C_one.h (added)
+++ cfe/trunk/test/Modules/Inputs/wildcard-submodule-exports/C_one.h Mon Dec  5 11:28:06 2011
@@ -0,0 +1,4 @@
+__import_module__ A.One;
+__import_module__ B.One;
+
+long *C1;

Added: cfe/trunk/test/Modules/Inputs/wildcard-submodule-exports/C_two.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/wildcard-submodule-exports/C_two.h?rev=145811&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/wildcard-submodule-exports/C_two.h (added)
+++ cfe/trunk/test/Modules/Inputs/wildcard-submodule-exports/C_two.h Mon Dec  5 11:28:06 2011
@@ -0,0 +1,4 @@
+__import_module__ A.Two;
+__import_module__ B.Two;
+
+unsigned long *C2;

Added: cfe/trunk/test/Modules/Inputs/wildcard-submodule-exports/module.map
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/wildcard-submodule-exports/module.map?rev=145811&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/wildcard-submodule-exports/module.map (added)
+++ cfe/trunk/test/Modules/Inputs/wildcard-submodule-exports/module.map Mon Dec  5 11:28:06 2011
@@ -0,0 +1,20 @@
+module A {
+  module One { header "A_one.h" }
+  module Two { header "A_two.h" }
+}
+
+module B {
+  module One { header "B_one.h" }
+  module Two { header "B_two.h" }
+}
+
+module C {
+  module One { 
+    header "C_one.h" 
+    export A.*
+  }
+  module Two { 
+    header "C_two.h"
+    export * 
+  }
+}

Added: cfe/trunk/test/Modules/wildcard-submodule-exports.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/wildcard-submodule-exports.cpp?rev=145811&view=auto
==============================================================================
--- cfe/trunk/test/Modules/wildcard-submodule-exports.cpp (added)
+++ cfe/trunk/test/Modules/wildcard-submodule-exports.cpp Mon Dec  5 11:28:06 2011
@@ -0,0 +1,25 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodule-cache-path %t -fauto-module-import -I %S/Inputs/wildcard-submodule-exports %s -verify
+
+__import_module__ C.One;
+
+void test_C_One() {
+  int *A1_ptr = A1;
+  long *C1_ptr = C1;
+  (void)B1; // expected-error{{use of undeclared identifier 'B1'}}
+}
+
+__import_module__ C.Two;
+
+void test_C_Two() {
+  unsigned int *A2_ptr = A2;
+  unsigned short *B2_ptr = B2;
+  unsigned long *C2_ptr = C2;
+}
+
+__import_module__ B.One;
+
+void test_B_One() {
+  short *B1_ptr = B1;
+}
+





More information about the cfe-commits mailing list