r193815 - Clang modules: collect exports recursively
Dmitri Gribenko
gribozavr at gmail.com
Thu Oct 31 15:24:10 PDT 2013
Author: gribozavr
Date: Thu Oct 31 17:24:10 2013
New Revision: 193815
URL: http://llvm.org/viewvc/llvm-project?rev=193815&view=rev
Log:
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).
Modified:
cfe/trunk/include/clang/Basic/Module.h
cfe/trunk/lib/Basic/Module.cpp
Modified: cfe/trunk/include/clang/Basic/Module.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Module.h?rev=193815&r1=193814&r2=193815&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/Module.h (original)
+++ cfe/trunk/include/clang/Basic/Module.h Thu Oct 31 17:24:10 2013
@@ -404,6 +404,9 @@ public:
submodule_const_iterator submodule_end() const { return SubModules.end(); }
/// \brief Returns the exported modules based on the wildcard restrictions.
+ ///
+ /// This returns a subset of immediately imported modules (the ones that are
+ /// exported), not the complete set of exported modules.
void getExportedModules(SmallVectorImpl<Module *> &Exported) const;
static StringRef getModuleInputBufferName() {
Modified: cfe/trunk/lib/Basic/Module.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/Module.cpp?rev=193815&r1=193814&r2=193815&view=diff
==============================================================================
--- cfe/trunk/lib/Basic/Module.cpp (original)
+++ cfe/trunk/lib/Basic/Module.cpp Thu Oct 31 17:24:10 2013
@@ -252,15 +252,23 @@ void Module::buildVisibleModulesCache()
// 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 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);
- // Every module exported by an imported module is visible.
- Imports[I]->getExportedModules(Exported);
- VisibleModulesCache.insert(Exported.begin(), Exported.end());
- Exported.clear();
+ 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);
+ }
}
}
More information about the cfe-commits
mailing list