<div dir="ltr">Thanks for the awesome testcase, taking a look now.</div><div class="gmail_extra"><br><div class="gmail_quote">On 18 May 2017 at 07:15, Raphael Isemann <span dir="ltr"><<a href="mailto:teemperor@gmail.com" target="_blank">teemperor@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi,<br>
<br>
this is breaking our STL module builds. Can we revert this?<br>
<br>
We also have a minimal reproducer for our crash here<br>
<a href="http://teemperor.de/pub/stl_merging_issue.zip" rel="noreferrer" target="_blank">http://teemperor.de/pub/stl_<wbr>merging_issue.zip</a><br>
<br>
- Raphael<br>
<br>
2017-05-17 2:24 GMT+02:00 Richard Smith via cfe-commits<br>
<<a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a>>:<br>
<div class="HOEnZb"><div class="h5">> Author: rsmith<br>
> Date: Tue May 16 19:24:14 2017<br>
> New Revision: 303224<br>
><br>
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=303224&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project?rev=303224&view=rev</a><br>
> Log:<br>
> [modules] When creating a declaration, cache its owning module immediately<br>
> rather than waiting until it's queried.<br>
><br>
> Currently this is only applied to local submodule visibility mode, as we don't<br>
> yet allocate storage for the owning module in non-local-visibility modules<br>
> compilations.<br>
><br>
><br>
> This reinstates r302965, reverted in r303037, with a fix for the reported<br>
> crash, which occurred when reparenting a local declaration to be a child of<br>
> a hidden imported declaration (specifically during template instantiation).<br>
><br>
> Modified:<br>
>     cfe/trunk/include/clang/AST/<wbr>Decl.h<br>
>     cfe/trunk/include/clang/AST/<wbr>DeclBase.h<br>
>     cfe/trunk/include/clang/Basic/<wbr>LangOptions.h<br>
>     cfe/trunk/include/clang/Sema/<wbr>Sema.h<br>
>     cfe/trunk/lib/AST/ASTDumper.<wbr>cpp<br>
>     cfe/trunk/lib/AST/Decl.cpp<br>
>     cfe/trunk/lib/AST/DeclBase.cpp<br>
>     cfe/trunk/lib/Sema/Sema.cpp<br>
>     cfe/trunk/lib/Sema/SemaDecl.<wbr>cpp<br>
>     cfe/trunk/lib/Sema/SemaLookup.<wbr>cpp<br>
>     cfe/trunk/test/Modules/Inputs/<wbr>submodule-visibility/b.h<br>
>     cfe/trunk/test/Modules/Inputs/<wbr>submodule-visibility/other.h<br>
>     cfe/trunk/test/Modules/<wbr>submodule-visibility.cpp<br>
><br>
> Modified: cfe/trunk/include/clang/AST/<wbr>Decl.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=303224&r1=303223&r2=303224&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/include/<wbr>clang/AST/Decl.h?rev=303224&<wbr>r1=303223&r2=303224&view=diff</a><br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- cfe/trunk/include/clang/AST/<wbr>Decl.h (original)<br>
> +++ cfe/trunk/include/clang/AST/<wbr>Decl.h Tue May 16 19:24:14 2017<br>
> @@ -301,16 +301,6 @@ public:<br>
>    using Decl::isModulePrivate;<br>
>    using Decl::setModulePrivate;<br>
><br>
> -  /// \brief Determine whether this declaration is hidden from name lookup.<br>
> -  bool isHidden() const { return Hidden; }<br>
> -<br>
> -  /// \brief Set whether this declaration is hidden from name lookup.<br>
> -  void setHidden(bool Hide) {<br>
> -    assert((!Hide || isFromASTFile() || hasLocalOwningModuleStorage()) &&<br>
> -           "declaration with no owning module can't be hidden");<br>
> -    Hidden = Hide;<br>
> -  }<br>
> -<br>
>    /// \brief Determine whether this declaration is a C++ class member.<br>
>    bool isCXXClassMember() const {<br>
>      const DeclContext *DC = getDeclContext();<br>
><br>
> Modified: cfe/trunk/include/clang/AST/<wbr>DeclBase.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclBase.h?rev=303224&r1=303223&r2=303224&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/include/<wbr>clang/AST/DeclBase.h?rev=<wbr>303224&r1=303223&r2=303224&<wbr>view=diff</a><br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- cfe/trunk/include/clang/AST/<wbr>DeclBase.h (original)<br>
> +++ cfe/trunk/include/clang/AST/<wbr>DeclBase.h Tue May 16 19:24:14 2017<br>
> @@ -706,6 +706,20 @@ public:<br>
>      reinterpret_cast<Module **>(this)[-1] = M;<br>
>    }<br>
><br>
> +  Module *getOwningModule() const {<br>
> +    return isFromASTFile() ? getImportedOwningModule() : getLocalOwningModule();<br>
> +  }<br>
> +<br>
> +  /// \brief Determine whether this declaration is hidden from name lookup.<br>
> +  bool isHidden() const { return Hidden; }<br>
> +<br>
> +  /// \brief Set whether this declaration is hidden from name lookup.<br>
> +  void setHidden(bool Hide) {<br>
> +    assert((!Hide || isFromASTFile() || hasLocalOwningModuleStorage()) &&<br>
> +           "declaration with no owning module can't be hidden");<br>
> +    Hidden = Hide;<br>
> +  }<br>
> +<br>
>    unsigned getIdentifierNamespace() const {<br>
>      return IdentifierNamespace;<br>
>    }<br>
><br>
> Modified: cfe/trunk/include/clang/Basic/<wbr>LangOptions.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/LangOptions.h?rev=303224&r1=303223&r2=303224&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/include/<wbr>clang/Basic/LangOptions.h?rev=<wbr>303224&r1=303223&r2=303224&<wbr>view=diff</a><br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- cfe/trunk/include/clang/Basic/<wbr>LangOptions.h (original)<br>
> +++ cfe/trunk/include/clang/Basic/<wbr>LangOptions.h Tue May 16 19:24:14 2017<br>
> @@ -166,6 +166,11 @@ public:<br>
>      return getCompilingModule() != CMK_None;<br>
>    }<br>
><br>
> +  /// Do we need to track the owning module for a local declaration?<br>
> +  bool trackLocalOwningModule() const {<br>
> +    return ModulesLocalVisibility;<br>
> +  }<br>
> +<br>
>    bool isSignedOverflowDefined() const {<br>
>      return getSignedOverflowBehavior() == SOB_Defined;<br>
>    }<br>
><br>
> Modified: cfe/trunk/include/clang/Sema/<wbr>Sema.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=303224&r1=303223&r2=303224&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/include/<wbr>clang/Sema/Sema.h?rev=303224&<wbr>r1=303223&r2=303224&view=diff</a><br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- cfe/trunk/include/clang/Sema/<wbr>Sema.h (original)<br>
> +++ cfe/trunk/include/clang/Sema/<wbr>Sema.h Tue May 16 19:24:14 2017<br>
> @@ -1467,11 +1467,9 @@ private:<br>
><br>
>    VisibleModuleSet VisibleModules;<br>
><br>
> -  Module *CachedFakeTopLevelModule;<br>
> -<br>
>  public:<br>
>    /// \brief Get the module owning an entity.<br>
> -  Module *getOwningModule(Decl *Entity);<br>
> +  Module *getOwningModule(Decl *Entity) { return Entity->getOwningModule(); }<br>
><br>
>    /// \brief Make a merged definition of an existing hidden definition \p ND<br>
>    /// visible at the specified location.<br>
><br>
> Modified: cfe/trunk/lib/AST/ASTDumper.<wbr>cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTDumper.cpp?rev=303224&r1=303223&r2=303224&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/AST/<wbr>ASTDumper.cpp?rev=303224&r1=<wbr>303223&r2=303224&view=diff</a><br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- cfe/trunk/lib/AST/ASTDumper.<wbr>cpp (original)<br>
> +++ cfe/trunk/lib/AST/ASTDumper.<wbr>cpp Tue May 16 19:24:14 2017<br>
> @@ -1038,10 +1038,10 @@ void ASTDumper::dumpDecl(const Decl *D)<br>
>      dumpSourceRange(D-><wbr>getSourceRange());<br>
>      OS << ' ';<br>
>      dumpLocation(D->getLocation())<wbr>;<br>
> -    if (Module *M = D->getImportedOwningModule())<br>
> +    if (D->isFromASTFile())<br>
> +      OS << " imported";<br>
> +    if (Module *M = D->getOwningModule())<br>
>        OS << " in " << M->getFullModuleName();<br>
> -    else if (Module *M = D->getLocalOwningModule())<br>
> -      OS << " in (local) " << M->getFullModuleName();<br>
>      if (auto *ND = dyn_cast<NamedDecl>(D))<br>
>        for (Module *M : D->getASTContext().<wbr>getModulesWithMergedDefinition<wbr>(<br>
>                 const_cast<NamedDecl *>(ND)))<br>
><br>
> Modified: cfe/trunk/lib/AST/Decl.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=303224&r1=303223&r2=303224&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/AST/<wbr>Decl.cpp?rev=303224&r1=303223&<wbr>r2=303224&view=diff</a><br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- cfe/trunk/lib/AST/Decl.cpp (original)<br>
> +++ cfe/trunk/lib/AST/Decl.cpp Tue May 16 19:24:14 2017<br>
> @@ -47,9 +47,7 @@ bool Decl::isOutOfLine() const {<br>
><br>
>  TranslationUnitDecl::<wbr>TranslationUnitDecl(ASTContext &ctx)<br>
>      : Decl(TranslationUnit, nullptr, SourceLocation()),<br>
> -      DeclContext(TranslationUnit), Ctx(ctx), AnonymousNamespace(nullptr) {<br>
> -  Hidden = Ctx.getLangOpts().<wbr>ModulesLocalVisibility;<br>
> -}<br>
> +      DeclContext(TranslationUnit), Ctx(ctx), AnonymousNamespace(nullptr) {}<br>
><br>
>  //===-------------------------<wbr>------------------------------<wbr>---------------===//<br>
>  // NamedDecl Implementation<br>
><br>
> Modified: cfe/trunk/lib/AST/DeclBase.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclBase.cpp?rev=303224&r1=303223&r2=303224&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/AST/<wbr>DeclBase.cpp?rev=303224&r1=<wbr>303223&r2=303224&view=diff</a><br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- cfe/trunk/lib/AST/DeclBase.cpp (original)<br>
> +++ cfe/trunk/lib/AST/DeclBase.cpp Tue May 16 19:24:14 2017<br>
> @@ -75,7 +75,7 @@ void *Decl::operator new(std::size_t Siz<br>
>    assert(!Parent || &Parent->getParentASTContext() == &Ctx);<br>
>    // With local visibility enabled, we track the owning module even for local<br>
>    // declarations.<br>
> -  if (Ctx.getLangOpts().<wbr>ModulesLocalVisibility) {<br>
> +  if (Ctx.getLangOpts().<wbr>trackLocalOwningModule()) {<br>
>      // Ensure required alignment of the resulting object by adding extra<br>
>      // padding at the start if required.<br>
>      size_t ExtraAlign =<br>
> @@ -83,7 +83,9 @@ void *Decl::operator new(std::size_t Siz<br>
>      char *Buffer = reinterpret_cast<char *>(<br>
>          ::operator new(ExtraAlign + sizeof(Module *) + Size + Extra, Ctx));<br>
>      Buffer += ExtraAlign;<br>
> -    return new (Buffer) Module*(nullptr) + 1;<br>
> +    auto *ParentModule =<br>
> +        Parent ? cast<Decl>(Parent)-><wbr>getOwningModule() : nullptr;<br>
> +    return new (Buffer) Module*(ParentModule) + 1;<br>
>    }<br>
>    return ::operator new(Size + Extra, Ctx);<br>
>  }<br>
> @@ -94,7 +96,7 @@ Module *Decl::getOwningModuleSlow() cons<br>
>  }<br>
><br>
>  bool Decl::<wbr>hasLocalOwningModuleStorage() const {<br>
> -  return getASTContext().getLangOpts().<wbr>ModulesLocalVisibility;<br>
> +  return getASTContext().getLangOpts().<wbr>trackLocalOwningModule();<br>
>  }<br>
><br>
>  const char *Decl::getDeclKindName() const {<br>
> @@ -273,6 +275,8 @@ void Decl::setLexicalDeclContext(<wbr>DeclCon<br>
>      getMultipleDC()->LexicalDC = DC;<br>
>    }<br>
>    Hidden = cast<Decl>(DC)->Hidden;<br>
> +  if (Hidden && !isFromASTFile() && hasLocalOwningModuleStorage())<br>
> +    setLocalOwningModule(cast<<wbr>Decl>(DC)->getOwningModule());<br>
>  }<br>
><br>
>  void Decl::setDeclContextsImpl(<wbr>DeclContext *SemaDC, DeclContext *LexicalDC,<br>
><br>
> Modified: cfe/trunk/lib/Sema/Sema.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.cpp?rev=303224&r1=303223&r2=303224&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/Sema/<wbr>Sema.cpp?rev=303224&r1=303223&<wbr>r2=303224&view=diff</a><br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- cfe/trunk/lib/Sema/Sema.cpp (original)<br>
> +++ cfe/trunk/lib/Sema/Sema.cpp Tue May 16 19:24:14 2017<br>
> @@ -93,11 +93,10 @@ Sema::Sema(Preprocessor &pp, ASTContext<br>
>        ValueWithBytesObjCTypeMethod(<wbr>nullptr), NSArrayDecl(nullptr),<br>
>        ArrayWithObjectsMethod(<wbr>nullptr), NSDictionaryDecl(nullptr),<br>
>        DictionaryWithObjectsMethod(<wbr>nullptr), GlobalNewDeleteDeclared(false)<wbr>,<br>
> -      TUKind(TUKind), NumSFINAEErrors(0), CachedFakeTopLevelModule(<wbr>nullptr),<br>
> -      AccessCheckingSFINAE(false), InNonInstantiationSFINAEContex<wbr>t(false),<br>
> -      NonInstantiationEntries(0), ArgumentPackSubstitutionIndex(<wbr>-1),<br>
> -      CurrentInstantiationScope(<wbr>nullptr), DisableTypoCorrection(false),<br>
> -      TyposCorrected(0), AnalysisWarnings(*this),<br>
> +      TUKind(TUKind), NumSFINAEErrors(0), AccessCheckingSFINAE(false),<br>
> +      InNonInstantiationSFINAEContex<wbr>t(false), NonInstantiationEntries(0),<br>
> +      ArgumentPackSubstitutionIndex(<wbr>-1), CurrentInstantiationScope(<wbr>nullptr),<br>
> +      DisableTypoCorrection(false), TyposCorrected(0), AnalysisWarnings(*this),<br>
>        ThreadSafetyDeclCache(nullptr)<wbr>, VarDataSharingAttributesStack(<wbr>nullptr),<br>
>        CurScope(nullptr), Ident_super(nullptr), Ident___float128(nullptr) {<br>
>    TUScope = nullptr;<br>
><br>
> Modified: cfe/trunk/lib/Sema/SemaDecl.<wbr>cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=303224&r1=303223&r2=303224&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/Sema/<wbr>SemaDecl.cpp?rev=303224&r1=<wbr>303223&r2=303224&view=diff</a><br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- cfe/trunk/lib/Sema/SemaDecl.<wbr>cpp (original)<br>
> +++ cfe/trunk/lib/Sema/SemaDecl.<wbr>cpp Tue May 16 19:24:14 2017<br>
> @@ -16047,6 +16047,14 @@ void Sema::ActOnModuleBegin(<wbr>SourceLocati<br>
>      ModuleScopes.back().<wbr>OuterVisibleModules = std::move(VisibleModules);<br>
><br>
>    VisibleModules.setVisible(Mod, DirectiveLoc);<br>
> +<br>
> +  // The enclosing context is now part of this module.<br>
> +  // FIXME: Consider creating a child DeclContext to hold the entities<br>
> +  // lexically within the module.<br>
> +  if (getLangOpts().<wbr>trackLocalOwningModule()) {<br>
> +    cast<Decl>(CurContext)-><wbr>setHidden(true);<br>
> +    cast<Decl>(CurContext)-><wbr>setLocalOwningModule(Mod);<br>
> +  }<br>
>  }<br>
><br>
>  void Sema::ActOnModuleEnd(<wbr>SourceLocation EomLoc, Module *Mod) {<br>
> @@ -16075,6 +16083,13 @@ void Sema::ActOnModuleEnd(<wbr>SourceLocation<br>
>      DirectiveLoc = EomLoc;<br>
>    }<br>
>    BuildModuleInclude(<wbr>DirectiveLoc, Mod);<br>
> +<br>
> +  // Any further declarations are in whatever module we returned to.<br>
> +  if (getLangOpts().<wbr>trackLocalOwningModule()) {<br>
> +    cast<Decl>(CurContext)-><wbr>setLocalOwningModule(<wbr>getCurrentModule());<br>
> +    if (!getCurrentModule())<br>
> +      cast<Decl>(CurContext)-><wbr>setHidden(false);<br>
> +  }<br>
>  }<br>
><br>
>  void Sema::<wbr>createImplicitModuleImportForE<wbr>rrorRecovery(SourceLocation Loc,<br>
><br>
> Modified: cfe/trunk/lib/Sema/SemaLookup.<wbr>cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLookup.cpp?rev=303224&r1=303223&r2=303224&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/Sema/<wbr>SemaLookup.cpp?rev=303224&r1=<wbr>303223&r2=303224&view=diff</a><br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- cfe/trunk/lib/Sema/SemaLookup.<wbr>cpp (original)<br>
> +++ cfe/trunk/lib/Sema/SemaLookup.<wbr>cpp Tue May 16 19:24:14 2017<br>
> @@ -1326,62 +1326,6 @@ bool Sema::CppLookupName(<wbr>LookupResult &R<br>
>    return !R.empty();<br>
>  }<br>
><br>
> -Module *Sema::getOwningModule(Decl *Entity) {<br>
> -  // If it's imported, grab its owning module.<br>
> -  Module *M = Entity-><wbr>getImportedOwningModule();<br>
> -  if (M || !isa<NamedDecl>(Entity) || !cast<NamedDecl>(Entity)-><wbr>isHidden())<br>
> -    return M;<br>
> -  assert(!Entity->isFromASTFile(<wbr>) &&<br>
> -         "hidden entity from AST file has no owning module");<br>
> -<br>
> -  if (!getLangOpts().<wbr>ModulesLocalVisibility) {<br>
> -    // If we're not tracking visibility locally, the only way a declaration<br>
> -    // can be hidden and local is if it's hidden because it's parent is (for<br>
> -    // instance, maybe this is a lazily-declared special member of an imported<br>
> -    // class).<br>
> -    auto *Parent = cast<NamedDecl>(Entity-><wbr>getDeclContext());<br>
> -    assert(Parent->isHidden() && "unexpectedly hidden decl");<br>
> -    return getOwningModule(Parent);<br>
> -  }<br>
> -<br>
> -  // It's local and hidden; grab or compute its owning module.<br>
> -  M = Entity->getLocalOwningModule()<wbr>;<br>
> -  if (M)<br>
> -    return M;<br>
> -<br>
> -  if (auto *Containing =<br>
> -          PP.<wbr>getModuleContainingLocation(<wbr>Entity->getLocation())) {<br>
> -    M = Containing;<br>
> -  } else if (Entity->isInvalidDecl() || Entity->getLocation().<wbr>isInvalid()) {<br>
> -    // Don't bother tracking visibility for invalid declarations with broken<br>
> -    // locations.<br>
> -    cast<NamedDecl>(Entity)-><wbr>setHidden(false);<br>
> -  } else {<br>
> -    // We need to assign a module to an entity that exists outside of any<br>
> -    // module, so that we can hide it from modules that we textually enter.<br>
> -    // Invent a fake module for all such entities.<br>
> -    if (!CachedFakeTopLevelModule) {<br>
> -      CachedFakeTopLevelModule =<br>
> -          PP.getHeaderSearchInfo().<wbr>getModuleMap().<wbr>findOrCreateModule(<br>
> -              "<top-level>", nullptr, false, false).first;<br>
> -<br>
> -      auto &SrcMgr = PP.getSourceManager();<br>
> -      SourceLocation StartLoc =<br>
> -          SrcMgr.getLocForStartOfFile(<wbr>SrcMgr.getMainFileID());<br>
> -      auto &TopLevel = ModuleScopes.empty()<br>
> -                           ? VisibleModules<br>
> -                           : ModuleScopes[0].<wbr>OuterVisibleModules;<br>
> -      TopLevel.setVisible(<wbr>CachedFakeTopLevelModule, StartLoc);<br>
> -    }<br>
> -<br>
> -    M = CachedFakeTopLevelModule;<br>
> -  }<br>
> -<br>
> -  if (M)<br>
> -    Entity->setLocalOwningModule(<wbr>M);<br>
> -  return M;<br>
> -}<br>
> -<br>
>  void Sema::<wbr>makeMergedDefinitionVisible(<wbr>NamedDecl *ND) {<br>
>    if (auto *M = getCurrentModule())<br>
>      Context.<wbr>mergeDefinitionIntoModule(ND, M);<br>
> @@ -1520,7 +1464,6 @@ bool LookupResult::isVisibleSlow(<wbr>Sema &S<br>
>    if (SemaRef.getLangOpts().<wbr>ModulesLocalVisibility) {<br>
>      DeclModule = SemaRef.getOwningModule(D);<br>
>      if (!DeclModule) {<br>
> -      // getOwningModule() may have decided the declaration should not be hidden.<br>
>        assert(!D->isHidden() && "hidden decl not from a module");<br>
>        return true;<br>
>      }<br>
><br>
> Modified: cfe/trunk/test/Modules/Inputs/<wbr>submodule-visibility/b.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/submodule-visibility/b.h?rev=303224&r1=303223&r2=303224&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/test/<wbr>Modules/Inputs/submodule-<wbr>visibility/b.h?rev=303224&r1=<wbr>303223&r2=303224&view=diff</a><br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- cfe/trunk/test/Modules/Inputs/<wbr>submodule-visibility/b.h (original)<br>
> +++ cfe/trunk/test/Modules/Inputs/<wbr>submodule-visibility/b.h Tue May 16 19:24:14 2017<br>
> @@ -4,7 +4,11 @@ int m = n;<br>
>  #include "c.h"<br>
><br>
>  #if defined(A) && !defined(ALLOW_NAME_LEAKAGE)<br>
> -#error A is defined<br>
> +#warning A is defined<br>
>  #endif<br>
><br>
>  #define B<br>
> +<br>
> +template<typename T> void b_template() {<br>
> +  N::C::f(0);<br>
> +}<br>
><br>
> Modified: cfe/trunk/test/Modules/Inputs/<wbr>submodule-visibility/other.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/submodule-visibility/other.h?rev=303224&r1=303223&r2=303224&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/test/<wbr>Modules/Inputs/submodule-<wbr>visibility/other.h?rev=303224&<wbr>r1=303223&r2=303224&view=diff</a><br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- cfe/trunk/test/Modules/Inputs/<wbr>submodule-visibility/other.h (original)<br>
> +++ cfe/trunk/test/Modules/Inputs/<wbr>submodule-visibility/other.h Tue May 16 19:24:14 2017<br>
> @@ -1 +1,10 @@<br>
>  #include "c.h"<br>
> +<br>
> +#ifndef OTHER_H<br>
> +#define OTHER_H<br>
> +namespace N {<br>
> +  struct C {<br>
> +    template<typename U> static void f(U) {}<br>
> +  };<br>
> +}<br>
> +#endif<br>
><br>
> Modified: cfe/trunk/test/Modules/<wbr>submodule-visibility.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/submodule-visibility.cpp?rev=303224&r1=303223&r2=303224&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/test/<wbr>Modules/submodule-visibility.<wbr>cpp?rev=303224&r1=303223&r2=<wbr>303224&view=diff</a><br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- cfe/trunk/test/Modules/<wbr>submodule-visibility.cpp (original)<br>
> +++ cfe/trunk/test/Modules/<wbr>submodule-visibility.cpp Tue May 16 19:24:14 2017<br>
> @@ -3,6 +3,11 @@<br>
>  // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-local-submodule-<wbr>visibility -fmodules-cache-path=%t -I%S/Inputs/submodule-<wbr>visibility -verify %s -DIMPORT<br>
>  // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-local-submodule-<wbr>visibility -fmodules-cache-path=%t -fmodule-name=x -I%S/Inputs/submodule-<wbr>visibility -verify %s<br>
>  // RUN: %clang_cc1 -fimplicit-module-maps -fmodules-local-submodule-<wbr>visibility -fmodules-cache-path=%t -I%S/Inputs/submodule-<wbr>visibility -verify %s<br>
> +//<br>
> +// Explicit module builds.<br>
> +// RUN: %clang_cc1 -fmodules -fmodules-local-submodule-<wbr>visibility -emit-module -x c++-module-map %S/Inputs/submodule-<wbr>visibility/module.modulemap -fmodule-name=other -o %t/other.pcm<br>
> +// RUN: %clang_cc1 -fmodules -fmodule-map-file=%S/Inputs/<wbr>submodule-visibility/module.<wbr>modulemap -fmodules-local-submodule-<wbr>visibility -fmodule-file=%t/other.pcm -verify -fmodule-name=x -I%S/Inputs/submodule-<wbr>visibility %s<br>
> +// RUN: %clang_cc1 -fmodules -fmodule-map-file=%S/Inputs/<wbr>submodule-visibility/module.<wbr>modulemap -fmodule-file=%t/other.pcm -verify -fmodule-name=x -I%S/Inputs/submodule-<wbr>visibility %s -DALLOW_TEXTUAL_NAME_LEAKAGE<br>
><br>
>  #include "a.h"<br>
>  #include "b.h"<br>
> @@ -11,6 +16,8 @@<br>
>  // expected-no-diagnostics<br>
>  #elif IMPORT<br>
>  // expected-error@-6 {{could not build module 'x'}}<br>
> +#elif ALLOW_TEXTUAL_NAME_LEAKAGE<br>
> +// expected-warning@b.h:7 {{A is defined}}<br>
>  #else<br>
>  // The use of -fmodule-name=x causes us to textually include the above headers.<br>
>  // The submodule visibility rules are still applied in this case.<br>
> @@ -35,3 +42,5 @@ typedef struct {<br>
>    int p;<br>
>    void (*f)(int p);<br>
>  } name_for_linkage;<br>
> +<br>
> +void g() { b_template<int>(); }<br>
><br>
><br>
> ______________________________<wbr>_________________<br>
> cfe-commits mailing list<br>
> <a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a><br>
> <a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/cfe-commits</a><br>
</div></div></blockquote></div><br></div>