diff options
Diffstat (limited to 'clang')
6 files changed, 61 insertions, 21 deletions
diff --git a/clang/include/clang/Basic/DiagnosticLexKinds.td b/clang/include/clang/Basic/DiagnosticLexKinds.td index 286a7ef40ed..e0bf38c102a 100644 --- a/clang/include/clang/Basic/DiagnosticLexKinds.td +++ b/clang/include/clang/Basic/DiagnosticLexKinds.td @@ -395,8 +395,6 @@ def err_mmap_header_not_found : Error<    "%select{|umbrella }0header '%1' not found">;  def err_mmap_umbrella_header_conflict : Error<    "module '%0' already has an umbrella header ('%1')">; -def err_mmap_umbrella_header_submodule : Error< -  "submodule '%0' can not have an umbrella header">;  def err_mmap_umbrella_clash : Error<    "umbrella header for module '%0' already covers this directory">;  def err_mmap_export_module_id : Error< diff --git a/clang/lib/Lex/ModuleMap.cpp b/clang/lib/Lex/ModuleMap.cpp index 198544dd517..5f3379bf965 100644 --- a/clang/lib/Lex/ModuleMap.cpp +++ b/clang/lib/Lex/ModuleMap.cpp @@ -251,6 +251,8 @@ ModuleMap::inferFrameworkModule(StringRef ModuleName,    Result->InferSubmodules = true;    Result->InferExportWildcard = true; +  // FIXME: Look for subframeworks. +      Modules[ModuleName] = Result;    return Result;  } @@ -559,19 +561,21 @@ void ModuleMapParser::parseModuleDecl() {    assert(Tok.is(MMToken::ExplicitKeyword) || Tok.is(MMToken::ModuleKeyword) ||           Tok.is(MMToken::FrameworkKeyword)); -  // Parse 'framework' or 'explicit' keyword, if present. -  bool Framework = false; +  // Parse 'explicit' or 'framework' keyword, if present.    bool Explicit = false; +  bool Framework = false; -  if (Tok.is(MMToken::FrameworkKeyword)) { -    consumeToken(); -    Framework = true; -  }     // Parse 'explicit' keyword, if present. -  else if (Tok.is(MMToken::ExplicitKeyword)) { +  if (Tok.is(MMToken::ExplicitKeyword)) {      consumeToken();      Explicit = true;    } + +  // Parse 'framework' keyword, if present. +  if (Tok.is(MMToken::FrameworkKeyword)) { +    consumeToken(); +    Framework = true; +  }     // Parse 'module' keyword.    if (!Tok.is(MMToken::ModuleKeyword)) { @@ -640,6 +644,7 @@ void ModuleMapParser::parseModuleDecl() {        break;      case MMToken::ExplicitKeyword: +    case MMToken::FrameworkKeyword:      case MMToken::ModuleKeyword:        parseModuleDecl();        break; @@ -674,7 +679,27 @@ void ModuleMapParser::parseModuleDecl() {    // We're done parsing this module. Pop back to our parent scope.    ActiveModule = ActiveModule->Parent;  } -  + +/// \brief Append to \p Paths the set of paths needed to get to the  +/// subframework in which the given module lives. +void appendSubframeworkPaths(Module *Mod, llvm::SmallVectorImpl<char> &Path) { +  // Collect the framework names from the given module to the top-level module. +  llvm::SmallVector<StringRef, 2> Paths; +  for (; Mod; Mod = Mod->Parent) { +    if (Mod->IsFramework) +      Paths.push_back(Mod->Name); +  } +   +  if (Paths.empty()) +    return; +   +  // Add Frameworks/Name.framework for each subframework. +  for (unsigned I = Paths.size() - 1; I != 0; --I) { +    llvm::sys::path::append(Path, "Frameworks"); +    llvm::sys::path::append(Path, Paths[I-1] + ".framework"); +  } +} +  /// \brief Parse an umbrella header declaration.  ///  ///   umbrella-declaration: @@ -702,14 +727,6 @@ void ModuleMapParser::parseUmbrellaDecl() {      return;    } -  // Only top-level modules can have umbrella headers. -  if (ActiveModule->Parent) { -    Diags.Report(UmbrellaLoc, diag::err_mmap_umbrella_header_submodule) -      << ActiveModule->getFullModuleName(); -    HadError = true; -    return; -  } -      // Look for this file.    llvm::SmallString<128> PathName;    const FileEntry *File = 0; @@ -721,7 +738,10 @@ void ModuleMapParser::parseUmbrellaDecl() {      // Search for the header file within the search directory.      PathName += Directory->getName();      unsigned PathLength = PathName.size(); +          if (ActiveModule->isPartOfFramework()) { +      appendSubframeworkPaths(ActiveModule, PathName); +              // Check whether this file is in the public headers.        llvm::sys::path::append(PathName, "Headers");        llvm::sys::path::append(PathName, FileName); @@ -734,8 +754,6 @@ void ModuleMapParser::parseUmbrellaDecl() {          llvm::sys::path::append(PathName, FileName);          File = SourceMgr.getFileManager().getFile(PathName);        } -       -      // FIXME: Deal with subframeworks.      } else {        // Lookup for normal headers.        llvm::sys::path::append(PathName, FileName); @@ -797,8 +815,10 @@ void ModuleMapParser::parseHeaderDecl() {      // FIXME: Change this search to also look for private headers!      PathName += Directory->getName(); -    if (ActiveModule->isPartOfFramework()) +    if (ActiveModule->isPartOfFramework()) { +      appendSubframeworkPaths(ActiveModule, PathName);        llvm::sys::path::append(PathName, "Headers"); +    }    }    llvm::sys::path::append(PathName, FileName); diff --git a/clang/test/Modules/Inputs/DependsOnModule.framework/Frameworks/SubFramework.framework/Headers/Other.h b/clang/test/Modules/Inputs/DependsOnModule.framework/Frameworks/SubFramework.framework/Headers/Other.h new file mode 100644 index 00000000000..69f9e8e4d01 --- /dev/null +++ b/clang/test/Modules/Inputs/DependsOnModule.framework/Frameworks/SubFramework.framework/Headers/Other.h @@ -0,0 +1 @@ +double *sub_framework_other; diff --git a/clang/test/Modules/Inputs/DependsOnModule.framework/Frameworks/SubFramework.framework/Headers/SubFramework.h b/clang/test/Modules/Inputs/DependsOnModule.framework/Frameworks/SubFramework.framework/Headers/SubFramework.h new file mode 100644 index 00000000000..e6e835ecc48 --- /dev/null +++ b/clang/test/Modules/Inputs/DependsOnModule.framework/Frameworks/SubFramework.framework/Headers/SubFramework.h @@ -0,0 +1,2 @@ +#include "SubFramework/Other.h" +float *sub_framework; diff --git a/clang/test/Modules/Inputs/DependsOnModule.framework/module.map b/clang/test/Modules/Inputs/DependsOnModule.framework/module.map index d4c2a670617..d7712752854 100644 --- a/clang/test/Modules/Inputs/DependsOnModule.framework/module.map +++ b/clang/test/Modules/Inputs/DependsOnModule.framework/module.map @@ -4,4 +4,7 @@ framework module DependsOnModule {    module * {      export *    } +  explicit framework module SubFramework { +    umbrella "SubFramework.h" +  }  } diff --git a/clang/test/Modules/subframeworks.m b/clang/test/Modules/subframeworks.m new file mode 100644 index 00000000000..44b6746a4af --- /dev/null +++ b/clang/test/Modules/subframeworks.m @@ -0,0 +1,16 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -Wauto-import -fmodule-cache-path %t -fauto-module-import -F %S/Inputs %s -verify + +__import_module__ DependsOnModule; + +void testSubFramework() { +  float *sf1 = sub_framework; // expected-error{{use of undeclared identifier 'sub_framework'}} +} + +__import_module__ DependsOnModule.SubFramework; + +void testSubFrameworkAgain() { +  float *sf2 = sub_framework; +  double *sfo1 = sub_framework_other; +} +  | 

