r313316 - [Module map] Introduce a private module re-export directive.

Douglas Gregor via cfe-commits cfe-commits at lists.llvm.org
Mon Sep 18 14:34:38 PDT 2017


> On Sep 18, 2017, at 1:45 PM, Galina Kistanova <gkistanova at gmail.com> wrote:
> 
> Hello Douglas,
> 
> Your r313316 commit broke one of our builders on Thursday, Sep-14th.
> http://lab.llvm.org:8011/builders/llvm-clang-lld-x86_64-scei-ps4-ubuntu-fast/builds/17506 <http://lab.llvm.org:8011/builders/llvm-clang-lld-x86_64-scei-ps4-ubuntu-fast/builds/17506>
> 
> Are you about to commit the fix, or shall I revert that commit to give you more time?

I’m unable to reproduce this issue, and it’s weirdly not hitting the other bots.

Is anyone able to reproduce this? The stack trace is… insufficient… to figure out what’s going on.

	- Doug

> 
> Thanks
> 
> Galina
> 
> On Thu, Sep 14, 2017 at 4:38 PM, Douglas Gregor via cfe-commits <cfe-commits at lists.llvm.org <mailto:cfe-commits at lists.llvm.org>> wrote:
> Author: dgregor
> Date: Thu Sep 14 16:38:44 2017
> New Revision: 313316
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=313316&view=rev <http://llvm.org/viewvc/llvm-project?rev=313316&view=rev>
> Log:
> [Module map] Introduce a private module re-export directive.
> 
> Introduce a new "export_as" directive for top-level modules, which
> indicates that the current module is a "private" module whose symbols
> will eventually be exported through the named "public" module. This is
> in support of a common pattern in the Darwin ecosystem where a single
> public framework is constructed of several private frameworks, with
> (currently) header duplication and some support from the linker.
> 
> Addresses rdar://problem/34438420.
> 
> Added:
>     cfe/trunk/test/Modules/Inputs/export_as_test.modulemap
>     cfe/trunk/test/Modules/export_as_test.c
> Modified:
>     cfe/trunk/docs/Modules.rst
>     cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td
>     cfe/trunk/include/clang/Basic/Module.h
>     cfe/trunk/include/clang/Serialization/ASTBitCodes.h
>     cfe/trunk/lib/Basic/Module.cpp
>     cfe/trunk/lib/Lex/ModuleMap.cpp
>     cfe/trunk/lib/Serialization/ASTReader.cpp
>     cfe/trunk/lib/Serialization/ASTWriter.cpp
> 
> Modified: cfe/trunk/docs/Modules.rst
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/Modules.rst?rev=313316&r1=313315&r2=313316&view=diff <http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/Modules.rst?rev=313316&r1=313315&r2=313316&view=diff>
> ==============================================================================
> --- cfe/trunk/docs/Modules.rst (original)
> +++ cfe/trunk/docs/Modules.rst Thu Sep 14 16:38:44 2017
> @@ -323,11 +323,12 @@ Module map files use a simplified form o
> 
>  .. parsed-literal::
> 
> -  ``config_macros`` ``export``     ``private``
> +  ``config_macros`` ``export_as``  ``private``
>    ``conflict``      ``framework``  ``requires``
>    ``exclude``       ``header``     ``textual``
>    ``explicit``      ``link``       ``umbrella``
>    ``extern``        ``module``     ``use``
> +  ``export``
> 
>  Module map file
>  ---------------
> @@ -387,6 +388,7 @@ Modules can have a number of different k
>      *umbrella-dir-declaration*
>      *submodule-declaration*
>      *export-declaration*
> +    *export-as-declaration*
>      *use-declaration*
>      *link-declaration*
>      *config-macros-declaration*
> @@ -666,6 +668,31 @@ Note that, if ``Derived.h`` includes ``B
>    compatibility for programs that rely on transitive inclusion (i.e.,
>    all of them).
> 
> +Re-export Declaration
> +~~~~~~~~~~~~~~~~~~
> +An *export-as-declaration* specifies that the current module is a private
> +module whose interface will be re-exported by the named public module.
> +
> +.. parsed-literal::
> +
> +  *export-as-declaration*:
> +    ``export_as`` *identifier*
> +
> +The *export-as-declaration* names the public module that the current
> +(private) module will be re-exported through. Only top-level modules
> +can be re-exported, and any given module may only be re-exported
> +through a single public module.
> +
> +**Example:** In the following example, the (private) module
> +``MyFrameworkCore`` will be re-exported via the public module
> +``MyFramework``:
> +
> +.. parsed-literal::
> +
> +  module MyFrameworkCore {
> +    export_as MyFramework
> +  }
> +
>  Use declaration
>  ~~~~~~~~~~~~~~~
>  A *use-declaration* specifies another module that the current top-level module
> 
> Modified: cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td?rev=313316&r1=313315&r2=313316&view=diff <http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td?rev=313316&r1=313315&r2=313316&view=diff>
> ==============================================================================
> --- cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td (original)
> +++ cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td Thu Sep 14 16:38:44 2017
> @@ -674,6 +674,13 @@ def err_mmap_invalid_header_attribute_va
>    "expected integer literal as value for header attribute '%0'">;
>  def err_mmap_expected_header_attribute : Error<
>    "expected a header attribute name ('size' or 'mtime')">;
> +def err_mmap_conflicting_export_as : Error<
> +  "conflicting re-export of module '%0' as '%1' or '%2'">;
> +def warn_mmap_redundant_export_as : Warning<
> +  "module '%0' already re-exported as '%1'">,
> +  InGroup<PrivateModule>;
> +def err_mmap_submodule_export_as : Error<
> +  "only top-level modules can be re-exported as public">;
> 
>  def warn_auto_module_import : Warning<
>    "treating #%select{include|import|include_next|__include_macros}0 as an "
> 
> Modified: cfe/trunk/include/clang/Basic/Module.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Module.h?rev=313316&r1=313315&r2=313316&view=diff <http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Module.h?rev=313316&r1=313315&r2=313316&view=diff>
> ==============================================================================
> --- cfe/trunk/include/clang/Basic/Module.h (original)
> +++ cfe/trunk/include/clang/Basic/Module.h Thu Sep 14 16:38:44 2017
> @@ -99,6 +99,10 @@ public:
> 
>    /// \brief The name of the umbrella entry, as written in the module map.
>    std::string UmbrellaAsWritten;
> +
> +  /// \brief The module through which entities defined in this module will
> +  /// eventually be exposed, for use in "private" modules.
> +  std::string ExportAsModule;
> 
>  private:
>    /// \brief The submodules of this module, indexed by name.
> 
> Modified: cfe/trunk/include/clang/Serialization/ASTBitCodes.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTBitCodes.h?rev=313316&r1=313315&r2=313316&view=diff <http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTBitCodes.h?rev=313316&r1=313315&r2=313316&view=diff>
> ==============================================================================
> --- cfe/trunk/include/clang/Serialization/ASTBitCodes.h (original)
> +++ cfe/trunk/include/clang/Serialization/ASTBitCodes.h Thu Sep 14 16:38:44 2017
> @@ -716,6 +716,9 @@ namespace clang {
>        /// \brief Specifies some declarations with initializers that must be
>        /// emitted to initialize the module.
>        SUBMODULE_INITIALIZERS = 16,
> +      /// \brief Specifies the name of the module that will eventually
> +      /// re-export the entities in this module.
> +      SUBMODULE_EXPORT_AS = 17,
>      };
> 
>      /// \brief Record types used within a comments block.
> 
> Modified: cfe/trunk/lib/Basic/Module.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/Module.cpp?rev=313316&r1=313315&r2=313316&view=diff <http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/Module.cpp?rev=313316&r1=313315&r2=313316&view=diff>
> ==============================================================================
> --- cfe/trunk/lib/Basic/Module.cpp (original)
> +++ cfe/trunk/lib/Basic/Module.cpp Thu Sep 14 16:38:44 2017
> @@ -440,6 +440,11 @@ void Module::print(raw_ostream &OS, unsi
>      }
>    }
> 
> +  if (!ExportAsModule.empty()) {
> +    OS.indent(Indent + 2);
> +    OS << "export_as" << ExportAsModule << "\n";
> +  }
> +
>    for (submodule_const_iterator MI = submodule_begin(), MIEnd = submodule_end();
>         MI != MIEnd; ++MI)
>      // Print inferred subframework modules so that we don't need to re-infer
> 
> Modified: cfe/trunk/lib/Lex/ModuleMap.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/ModuleMap.cpp?rev=313316&r1=313315&r2=313316&view=diff <http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/ModuleMap.cpp?rev=313316&r1=313315&r2=313316&view=diff>
> ==============================================================================
> --- cfe/trunk/lib/Lex/ModuleMap.cpp (original)
> +++ cfe/trunk/lib/Lex/ModuleMap.cpp Thu Sep 14 16:38:44 2017
> @@ -1201,6 +1201,7 @@ namespace clang {
>        ExcludeKeyword,
>        ExplicitKeyword,
>        ExportKeyword,
> +      ExportAsKeyword,
>        ExternKeyword,
>        FrameworkKeyword,
>        LinkKeyword,
> @@ -1312,6 +1313,7 @@ namespace clang {
>                           SourceLocation LeadingLoc);
>      void parseUmbrellaDirDecl(SourceLocation UmbrellaLoc);
>      void parseExportDecl();
> +    void parseExportAsDecl();
>      void parseUseDecl();
>      void parseLinkDecl();
>      void parseConfigMacros();
> @@ -1363,6 +1365,7 @@ retry:
>                   .Case("exclude", MMToken::ExcludeKeyword)
>                   .Case("explicit", MMToken::ExplicitKeyword)
>                   .Case("export", MMToken::ExportKeyword)
> +                 .Case("export_as", MMToken::ExportAsKeyword)
>                   .Case("extern", MMToken::ExternKeyword)
>                   .Case("framework", MMToken::FrameworkKeyword)
>                   .Case("header", MMToken::HeaderKeyword)
> @@ -1590,6 +1593,7 @@ namespace {
>  ///     header-declaration
>  ///     submodule-declaration
>  ///     export-declaration
> +///     export-as-declaration
>  ///     link-declaration
>  ///
>  ///   submodule-declaration:
> @@ -1824,6 +1828,10 @@ void ModuleMapParser::parseModuleDecl()
>        parseExportDecl();
>        break;
> 
> +    case MMToken::ExportAsKeyword:
> +      parseExportAsDecl();
> +      break;
> +
>      case MMToken::UseKeyword:
>        parseUseDecl();
>        break;
> @@ -2284,6 +2292,41 @@ void ModuleMapParser::parseExportDecl()
>    ActiveModule->UnresolvedExports.push_back(Unresolved);
>  }
> 
> +/// \brief Parse a module export_as declaration.
> +///
> +///   export-as-declaration:
> +///     'export_as' identifier
> +void ModuleMapParser::parseExportAsDecl() {
> +  assert(Tok.is(MMToken::ExportAsKeyword));
> +  consumeToken();
> +
> +  if (!Tok.is(MMToken::Identifier)) {
> +    Diags.Report(Tok.getLocation(), diag::err_mmap_module_id);
> +    HadError = true;
> +    return;
> +  }
> +
> +  if (ActiveModule->Parent) {
> +    Diags.Report(Tok.getLocation(), diag::err_mmap_submodule_export_as);
> +    consumeToken();
> +    return;
> +  }
> +
> +  if (!ActiveModule->ExportAsModule.empty()) {
> +    if (ActiveModule->ExportAsModule == Tok.getString()) {
> +      Diags.Report(Tok.getLocation(), diag::warn_mmap_redundant_export_as)
> +        << ActiveModule->Name << Tok.getString();
> +    } else {
> +      Diags.Report(Tok.getLocation(), diag::err_mmap_conflicting_export_as)
> +        << ActiveModule->Name << ActiveModule->ExportAsModule
> +        << Tok.getString();
> +    }
> +  }
> +
> +  ActiveModule->ExportAsModule = Tok.getString();
> +  consumeToken();
> +}
> +
>  /// \brief Parse a module use declaration.
>  ///
>  ///   use-declaration:
> @@ -2689,6 +2732,7 @@ bool ModuleMapParser::parseModuleMapFile
>      case MMToken::Exclaim:
>      case MMToken::ExcludeKeyword:
>      case MMToken::ExportKeyword:
> +    case MMToken::ExportAsKeyword:
>      case MMToken::HeaderKeyword:
>      case MMToken::Identifier:
>      case MMToken::LBrace:
> 
> Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=313316&r1=313315&r2=313316&view=diff <http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=313316&r1=313315&r2=313316&view=diff>
> ==============================================================================
> --- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
> +++ cfe/trunk/lib/Serialization/ASTReader.cpp Thu Sep 14 16:38:44 2017
> @@ -5123,7 +5123,7 @@ ASTReader::ReadSubmoduleBlock(ModuleFile
>        break;
>      }
> 
> -    case SUBMODULE_INITIALIZERS:
> +    case SUBMODULE_INITIALIZERS: {
>        if (!ContextObj)
>          break;
>        SmallVector<uint32_t, 16> Inits;
> @@ -5132,6 +5132,11 @@ ASTReader::ReadSubmoduleBlock(ModuleFile
>        ContextObj->addLazyModuleInitializers(CurrentModule, Inits);
>        break;
>      }
> +
> +    case SUBMODULE_EXPORT_AS:
> +      CurrentModule->ExportAsModule = Blob.str();
> +      break;
> +    }
>    }
>  }
> 
> 
> Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=313316&r1=313315&r2=313316&view=diff <http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=313316&r1=313315&r2=313316&view=diff>
> ==============================================================================
> --- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
> +++ cfe/trunk/lib/Serialization/ASTWriter.cpp Thu Sep 14 16:38:44 2017
> @@ -1130,6 +1130,7 @@ void ASTWriter::WriteBlockInfoBlock() {
>    RECORD(SUBMODULE_TEXTUAL_HEADER);
>    RECORD(SUBMODULE_PRIVATE_TEXTUAL_HEADER);
>    RECORD(SUBMODULE_INITIALIZERS);
> +  RECORD(SUBMODULE_EXPORT_AS);
> 
>    // Comments Block.
>    BLOCK(COMMENTS_BLOCK);
> @@ -2791,6 +2792,12 @@ void ASTWriter::WriteSubmodules(Module *
>    Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));    // Message
>    unsigned ConflictAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
> 
> +  Abbrev = std::make_shared<BitCodeAbbrev>();
> +  Abbrev->Add(BitCodeAbbrevOp(SUBMODULE_EXPORT_AS));
> +  Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob));    // Macro name
> +  unsigned ExportAsAbbrev = Stream.EmitAbbrev(std::move(Abbrev));
> +
> +
>    // Write the submodule metadata block.
>    RecordData::value_type Record[] = {
>        getNumberOfModules(WritingModule),
> @@ -2925,6 +2932,12 @@ void ASTWriter::WriteSubmodules(Module *
>      if (!Inits.empty())
>        Stream.EmitRecord(SUBMODULE_INITIALIZERS, Inits);
> 
> +    // Emit the name of the re-exported module, if any.
> +    if (!Mod->ExportAsModule.empty()) {
> +      RecordData::value_type Record[] = {SUBMODULE_EXPORT_AS};
> +      Stream.EmitRecordWithBlob(ExportAsAbbrev, Record, Mod->ExportAsModule);
> +    }
> +
>      // Queue up the submodules of this module.
>      for (auto *M : Mod->submodules())
>        Q.push(M);
> 
> Added: cfe/trunk/test/Modules/Inputs/export_as_test.modulemap
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/export_as_test.modulemap?rev=313316&view=auto <http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/export_as_test.modulemap?rev=313316&view=auto>
> ==============================================================================
> --- cfe/trunk/test/Modules/Inputs/export_as_test.modulemap (added)
> +++ cfe/trunk/test/Modules/Inputs/export_as_test.modulemap Thu Sep 14 16:38:44 2017
> @@ -0,0 +1,9 @@
> +module PrivateFoo {
> +  export_as Foo
> +  export_as Bar
> +  export_as Bar
> +
> +  module Sub {
> +    export_as Wibble
> +  }
> +}
> 
> Added: cfe/trunk/test/Modules/export_as_test.c
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/export_as_test.c?rev=313316&view=auto <http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/export_as_test.c?rev=313316&view=auto>
> ==============================================================================
> --- cfe/trunk/test/Modules/export_as_test.c (added)
> +++ cfe/trunk/test/Modules/export_as_test.c Thu Sep 14 16:38:44 2017
> @@ -0,0 +1,9 @@
> +// RUN: rm -rf %t
> +// RUN: not %clang_cc1 -fmodules -fmodules-cache-path=%t -fmodule-map-file=%S/Inputs/export_as_test.modulemap %s 2> %t.err
> +// RUN: FileCheck %s < %t.err
> +
> +// CHECK: export_as_test.modulemap:3:13: error: conflicting re-export of module 'PrivateFoo' as 'Foo' or 'Bar'
> +// CHECK: export_as_test.modulemap:4:13: warning: module 'PrivateFoo' already re-exported as 'Bar'
> +// CHECK: export_as_test.modulemap:7:15: error: only top-level modules can be re-exported as public
> +
> +
> 
> 
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org <mailto:cfe-commits at lists.llvm.org>
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits <http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits>
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20170918/542bbc12/attachment-0001.html>


More information about the cfe-commits mailing list