diff options
| author | Douglas Gregor <dgregor@apple.com> | 2013-01-14 17:57:51 +0000 |
|---|---|---|
| committer | Douglas Gregor <dgregor@apple.com> | 2013-01-14 17:57:51 +0000 |
| commit | 11dfe6fe3d0736d46c9cfc9de79bef60c671c097 (patch) | |
| tree | fad6c005c4c6ac8677b70fa2f1549a705cb4d4f4 | |
| parent | 924c478827ee3a21b669c2f65f9a76b15567f852 (diff) | |
| download | bcm5719-llvm-11dfe6fe3d0736d46c9cfc9de79bef60c671c097.tar.gz bcm5719-llvm-11dfe6fe3d0736d46c9cfc9de79bef60c671c097.zip | |
Infer "link" lines for top-level frameworks. Essentially, a framework
will have a shared library with the same name as its framework (and no
suffix!) within its .framework directory. Detect this both when
inferring the whole top-level framework and when parsing a module map.
llvm-svn: 172439
| -rw-r--r-- | clang/include/clang/Basic/Module.h | 8 | ||||
| -rw-r--r-- | clang/lib/Lex/ModuleMap.cpp | 30 | ||||
| -rw-r--r-- | clang/test/Modules/Inputs/Module.framework/Module | 0 | ||||
| -rw-r--r-- | clang/test/Modules/Inputs/NoUmbrella.framework/NoUmbrella | 0 | ||||
| -rw-r--r-- | clang/test/Modules/autolink.m | 14 |
5 files changed, 50 insertions, 2 deletions
diff --git a/clang/include/clang/Basic/Module.h b/clang/include/clang/Basic/Module.h index 2bda801d188..6264c2db7b2 100644 --- a/clang/include/clang/Basic/Module.h +++ b/clang/include/clang/Basic/Module.h @@ -237,7 +237,13 @@ public: return false; } - + + /// \brief Determine whether this module is a subframework of another + /// framework. + bool isSubFramework() const { + return IsFramework && Parent && Parent->isPartOfFramework(); + } + /// \brief Retrieve the full name of this module, including the path from /// its top-level module. std::string getFullModuleName() const; diff --git a/clang/lib/Lex/ModuleMap.cpp b/clang/lib/Lex/ModuleMap.cpp index 6b0eb79a10a..72e79511eeb 100644 --- a/clang/lib/Lex/ModuleMap.cpp +++ b/clang/lib/Lex/ModuleMap.cpp @@ -383,6 +383,23 @@ bool ModuleMap::canInferFrameworkModule(const DirectoryEntry *ParentDir, return canInfer; } +/// \brief For a framework module, infer the framework against which we +/// should link. +static void inferFrameworkLink(Module *Mod, const DirectoryEntry *FrameworkDir, + FileManager &FileMgr) { + assert(Mod->IsFramework && "Can only infer linking for framework modules"); + assert(!Mod->isSubFramework() && + "Can only infer linking for top-level frameworks"); + + SmallString<128> LibName; + LibName += FrameworkDir->getName(); + llvm::sys::path::append(LibName, Mod->Name); + if (FileMgr.getFile(LibName)) { + Mod->LinkLibraries.push_back(Module::LinkLibrary(Mod->Name, + /*IsFramework=*/true)); + } +} + Module * ModuleMap::inferFrameworkModule(StringRef ModuleName, const DirectoryEntry *FrameworkDir, @@ -537,6 +554,12 @@ ModuleMap::inferFrameworkModule(StringRef ModuleName, } } + // If the module is a top-level framework, automatically link against the + // framework. + if (!Result->isSubFramework()) { + inferFrameworkLink(Result, FrameworkDir, FileMgr); + } + return Result; } @@ -1147,6 +1170,13 @@ void ModuleMapParser::parseModuleDecl() { HadError = true; } + // If the active module is a top-level framework, and there are no link + // libraries, automatically link against the framework. + if (ActiveModule->IsFramework && !ActiveModule->isSubFramework() && + ActiveModule->LinkLibraries.empty()) { + inferFrameworkLink(ActiveModule, Directory, SourceMgr.getFileManager()); + } + // We're done parsing this module. Pop back to the previous module. ActiveModule = PreviousActiveModule; } diff --git a/clang/test/Modules/Inputs/Module.framework/Module b/clang/test/Modules/Inputs/Module.framework/Module new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/clang/test/Modules/Inputs/Module.framework/Module diff --git a/clang/test/Modules/Inputs/NoUmbrella.framework/NoUmbrella b/clang/test/Modules/Inputs/NoUmbrella.framework/NoUmbrella new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/clang/test/Modules/Inputs/NoUmbrella.framework/NoUmbrella diff --git a/clang/test/Modules/autolink.m b/clang/test/Modules/autolink.m index e4db6991fca..3c6998f7bf3 100644 --- a/clang/test/Modules/autolink.m +++ b/clang/test/Modules/autolink.m @@ -13,6 +13,18 @@ int g() { return autolink; } -// CHECK: !llvm.link.libraries = !{![[AUTOLINK:[0-9]+]], ![[AUTOLINK_FRAMEWORK:[0-9]+]]} +@import Module.SubFramework; +const char *get_module_subframework() { + return module_subframework; +} + +@import NoUmbrella; +int use_no_umbrella() { + return no_umbrella_A; +} + +// CHECK: !llvm.link.libraries = !{![[AUTOLINK:[0-9]+]], ![[AUTOLINK_FRAMEWORK:[0-9]+]], ![[MODULE:[0-9]+]], ![[NOUMBRELLA:[0-9]+]]} // CHECK: ![[AUTOLINK]] = metadata !{metadata !"autolink", i1 false} // CHECK: ![[AUTOLINK_FRAMEWORK]] = metadata !{metadata !"autolink_framework", i1 true} +// CHECK: ![[MODULE]] = metadata !{metadata !"Module", i1 true} +// CHECK: ![[NOUMBRELLA]] = metadata !{metadata !"NoUmbrella", i1 true} |

