Module: emit initializers in submodules when importing the parent module.

When importing the parent module, module initializers in submodules should
be emitted.

rdar://28740482

llvm-svn: 284263
This commit is contained in:
Manman Ren 2016-10-14 18:55:44 +00:00
parent a22daa0fa6
commit 3b5dbf23a4
4 changed files with 41 additions and 4 deletions

View File

@ -3951,9 +3951,33 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) {
DI->EmitImportDecl(*Import);
}
// Emit the module initializers.
for (auto *D : Context.getModuleInitializers(Import->getImportedModule()))
EmitTopLevelDecl(D);
// Find all of the submodules and emit the module initializers.
llvm::SmallPtrSet<clang::Module *, 16> Visited;
SmallVector<clang::Module *, 16> Stack;
Visited.insert(Import->getImportedModule());
Stack.push_back(Import->getImportedModule());
while (!Stack.empty()) {
clang::Module *Mod = Stack.pop_back_val();
if (!EmittedModuleInitializers.insert(Mod).second)
continue;
for (auto *D : Context.getModuleInitializers(Mod))
EmitTopLevelDecl(D);
// Visit the submodules of this module.
for (clang::Module::submodule_iterator Sub = Mod->submodule_begin(),
SubEnd = Mod->submodule_end();
Sub != SubEnd; ++Sub) {
// Skip explicit children; they need to be explicitly imported to emit
// the initializers.
if ((*Sub)->IsExplicit)
continue;
if (Visited.insert(*Sub).second)
Stack.push_back(*Sub);
}
}
break;
}

View File

@ -420,6 +420,10 @@ private:
/// \brief The complete set of modules that has been imported.
llvm::SetVector<clang::Module *> ImportedModules;
/// \brief The set of modules for which the module initializers
/// have been emitted.
llvm::SmallPtrSet<clang::Module *, 16> EmittedModuleInitializers;
/// \brief A vector of metadata strings.
SmallVector<llvm::Metadata *, 16> LinkerOptionsMetadata;

View File

@ -1,4 +1,7 @@
module X {
header "X.h"
module T {
header "X.h"
export *
}
export *
}

View File

@ -1,8 +1,14 @@
// RUN: rm -rf %t
// RUN: %clang_cc1 -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -I %S/Inputs/objc-initializer %s -emit-llvm -o - -fobjc-arc | FileCheck %s
// RUN: %clang_cc1 -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -I %S/Inputs/objc-initializer %s -emit-llvm -o - -fobjc-arc -DIMPORT_TOP | FileCheck %s
// CHECK: kSimDeviceIOGetInterface = internal constant {{.*}} bitcast
#ifdef IMPORT_TOP
@import X;
#else
#import <X.h>
#endif
void test2(const NSString*);
void test() {
test2(kSimDeviceIOGetInterface);