diff options
| author | Dmitri Gribenko <gribozavr@gmail.com> | 2013-10-31 22:24:10 +0000 | 
|---|---|---|
| committer | Dmitri Gribenko <gribozavr@gmail.com> | 2013-10-31 22:24:10 +0000 | 
| commit | dc360d57393ce1d196800c4e9d61b598c35c9a7b (patch) | |
| tree | 97af23d41f1480a932f0b533a58368e662c65cd4 /clang/lib/Basic | |
| parent | e1bedf4e939995fc190700f4a8a7fa12410c8577 (diff) | |
| download | bcm5719-llvm-dc360d57393ce1d196800c4e9d61b598c35c9a7b.tar.gz bcm5719-llvm-dc360d57393ce1d196800c4e9d61b598c35c9a7b.zip  | |
Clang modules: collect exports recursively
This change makes Module::buildVisibleModulesCache() collect exported modules
recursively.
While computing a set of exports, getExportedModules() iterates over the set of
imported modules and filters it.  But it does not consider the set of exports
of those modules -- it is the responsibility of the caller to do this.
Here is a certain instance of this issue.  Module::isModuleVisible says that
CoreFoundation.CFArray submodule is not visible from Cocoa.  Why?
- Cocoa imports Foundation.
- Foundation has an export restriction: "export *".
- Foundation imports CoreFoundation.  (Just the top-level module.)
- CoreFoundation exports CoreFoundation.CFArray.
To decide which modules are visible from Cocoa, we collect all exported modules
from immediate imports in Cocoa:
> visibleModulesFro(Cocoa) = exported(Foundation) + exported(CoreData) + exported(AppKit)
To find out which modules are exported, we filter imports according to
restrictions:
> exported(Foundation) = filterByModuleMapRestrictions(imports(Foundation))
Because Foundation imports CoreFoundation (not CoreFoundation.CFArray), the
CFArray submodule is considered not exported from Foundation, and is not
visible from Cocoa (according to Module::isModuleVisible).
llvm-svn: 193815
Diffstat (limited to 'clang/lib/Basic')
| -rw-r--r-- | clang/lib/Basic/Module.cpp | 26 | 
1 files changed, 17 insertions, 9 deletions
diff --git a/clang/lib/Basic/Module.cpp b/clang/lib/Basic/Module.cpp index 481537788e9..ccf7077d6fb 100644 --- a/clang/lib/Basic/Module.cpp +++ b/clang/lib/Basic/Module.cpp @@ -252,15 +252,23 @@ void Module::buildVisibleModulesCache() const {    // This module is visible to itself.    VisibleModulesCache.insert(this); -  llvm::SmallVector<Module*, 4> Exported; -  for (unsigned I = 0, N = Imports.size(); I != N; ++I) { -    // Every imported module is visible. -    VisibleModulesCache.insert(Imports[I]); - -    // Every module exported by an imported module is visible. -    Imports[I]->getExportedModules(Exported); -    VisibleModulesCache.insert(Exported.begin(), Exported.end()); -    Exported.clear(); +  // Every imported module is visible. +  // Every module exported by an imported module is visible. +  llvm::SmallPtrSet<Module *, 4> Visited; +  llvm::SmallVector<Module *, 4> Exports; +  SmallVector<Module *, 4> Stack(Imports.begin(), Imports.end()); +  while (!Stack.empty()) { +    Module *CurrModule = Stack.pop_back_val(); +    VisibleModulesCache.insert(CurrModule); + +    CurrModule->getExportedModules(Exports); +    for (SmallVectorImpl<Module *>::iterator I = Exports.begin(), +                                             E = Exports.end(); +         I != E; ++I) { +      Module *Exported = *I; +      if (Visited.insert(Exported)) +        Stack.push_back(Exported); +    }    }  }  | 

