summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorManman Ren <manman.ren@gmail.com>2016-10-14 18:55:44 +0000
committerManman Ren <manman.ren@gmail.com>2016-10-14 18:55:44 +0000
commit3b5dbf23a4025fc2c66fcb9dc662b148fa56a12e (patch)
tree5e61e3756058630ada8f0cba8c9707f923a6990b /clang
parenta22daa0fa65561a65ba4949cf66315202db45d87 (diff)
downloadbcm5719-llvm-3b5dbf23a4025fc2c66fcb9dc662b148fa56a12e.tar.gz
bcm5719-llvm-3b5dbf23a4025fc2c66fcb9dc662b148fa56a12e.zip
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
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp30
-rw-r--r--clang/lib/CodeGen/CodeGenModule.h4
-rw-r--r--clang/test/Modules/Inputs/objc-initializer/module.modulemap5
-rw-r--r--clang/test/Modules/objc-initializer.m6
4 files changed, 41 insertions, 4 deletions
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index f4628fc0d33..21849590b11 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/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<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;
}
diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h
index e896b11a7ae..7fb2402d34a 100644
--- a/clang/lib/CodeGen/CodeGenModule.h
+++ b/clang/lib/CodeGen/CodeGenModule.h
@@ -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;
diff --git a/clang/test/Modules/Inputs/objc-initializer/module.modulemap b/clang/test/Modules/Inputs/objc-initializer/module.modulemap
index 8fe4c92a173..bc76ace1065 100644
--- a/clang/test/Modules/Inputs/objc-initializer/module.modulemap
+++ b/clang/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/clang/test/Modules/objc-initializer.m b/clang/test/Modules/objc-initializer.m
index 90cc1824717..adb7a06a2bf 100644
--- a/clang/test/Modules/objc-initializer.m
+++ b/clang/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 <X.h>
+#endif
+
void test2(const NSString*);
void test() {
test2(kSimDeviceIOGetInterface);
OpenPOWER on IntegriCloud