From 6b826f1364cd3e958157b82a2fc99603be3e8e48 Mon Sep 17 00:00:00 2001 From: Manman Ren Date: Fri, 14 Oct 2016 18:55:44 +0000 Subject: [PATCH] Module: emit initializers in submodules when importing the parent module. When importing the parent module, module initializers in submodules should be emitted. rdar://28740482 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@284263 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CodeGenModule.cpp | 30 +++++++++++++++++-- lib/CodeGen/CodeGenModule.h | 4 +++ .../Inputs/objc-initializer/module.modulemap | 5 +++- test/Modules/objc-initializer.m | 6 ++++ 4 files changed, 41 insertions(+), 4 deletions(-) diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index f4628fc0d3..21849590b1 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -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 Visited; + SmallVector 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; } diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h index e896b11a7a..7fb2402d34 100644 --- a/lib/CodeGen/CodeGenModule.h +++ b/lib/CodeGen/CodeGenModule.h @@ -420,6 +420,10 @@ private: /// \brief The complete set of modules that has been imported. llvm::SetVector ImportedModules; + /// \brief The set of modules for which the module initializers + /// have been emitted. + llvm::SmallPtrSet EmittedModuleInitializers; + /// \brief A vector of metadata strings. SmallVector LinkerOptionsMetadata; diff --git a/test/Modules/Inputs/objc-initializer/module.modulemap b/test/Modules/Inputs/objc-initializer/module.modulemap index 8fe4c92a17..bc76ace106 100644 --- a/test/Modules/Inputs/objc-initializer/module.modulemap +++ b/test/Modules/Inputs/objc-initializer/module.modulemap @@ -1,4 +1,7 @@ module X { - header "X.h" + module T { + header "X.h" + export * + } export * } diff --git a/test/Modules/objc-initializer.m b/test/Modules/objc-initializer.m index 90cc182471..adb7a06a2b 100644 --- a/test/Modules/objc-initializer.m +++ b/test/Modules/objc-initializer.m @@ -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 +#endif + void test2(const NSString*); void test() { test2(kSimDeviceIOGetInterface); -- 2.40.0