forked from OSchip/llvm-project
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
This commit is contained in:
parent
e1bedf4e93
commit
dc360d5739
|
@ -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() {
|
||||
|
|
|
@ -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 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue