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:
parent
a22daa0fa6
commit
3b5dbf23a4
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
module X {
|
||||
header "X.h"
|
||||
module T {
|
||||
header "X.h"
|
||||
export *
|
||||
}
|
||||
export *
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue