From: Richard Smith Date: Wed, 17 Jun 2015 20:39:41 +0000 (+0000) Subject: [modules] If we merge a template, also track that its parameters are merged so X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=078478a40aed8bc50b994b393f03615e3092a521;p=clang [modules] If we merge a template, also track that its parameters are merged so that we know when its default arguments should be visible. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@239936 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp index 75d4709e19..3fd1f21ba3 100644 --- a/lib/Sema/SemaLookup.cpp +++ b/lib/Sema/SemaLookup.cpp @@ -1228,13 +1228,17 @@ Module *Sema::getOwningModule(Decl *Entity) { } void Sema::makeMergedDefinitionVisible(NamedDecl *ND, SourceLocation Loc) { - // FIXME: If ND is a template declaration, make the template parameters - // visible too. They're not (necessarily) within its DeclContext. if (auto *M = PP.getModuleContainingLocation(Loc)) Context.mergeDefinitionIntoModule(ND, M); else // We're not building a module; just make the definition visible. ND->setHidden(false); + + // If ND is a template declaration, make the template parameters + // visible too. They're not (necessarily) within a mergeable DeclContext. + if (auto *TD = dyn_cast(ND)) + for (auto *Param : *TD->getTemplateParameters()) + makeMergedDefinitionVisible(Param, Loc); } /// \brief Find the module in which the given declaration was defined. @@ -1296,8 +1300,12 @@ hasVisibleDefaultArgument(Sema &S, const ParmDecl *D, if (!DefaultArg.isInherited() && S.isVisible(D)) return true; - if (!DefaultArg.isInherited() && Modules) - Modules->push_back(S.getOwningModule(const_cast(D))); + if (!DefaultArg.isInherited() && Modules) { + auto *NonConstD = const_cast(D); + Modules->push_back(S.getOwningModule(NonConstD)); + const auto &Merged = S.Context.getModulesWithMergedDefinition(NonConstD); + Modules->insert(Modules->end(), Merged.begin(), Merged.end()); + } // If there was a previous default argument, maybe its parameter is visible. D = DefaultArg.getInheritedFrom(); diff --git a/test/Modules/submodules-merge-defs.cpp b/test/Modules/submodules-merge-defs.cpp index a11ae46aef..ee5e4fe1bf 100644 --- a/test/Modules/submodules-merge-defs.cpp +++ b/test/Modules/submodules-merge-defs.cpp @@ -50,12 +50,11 @@ int pre_fg = F().g(); // expected-error +{{must be imported}} J<> pre_j; // expected-error {{declaration of 'J' must be imported}} #ifdef IMPORT_USE_2 -// FIXME-error-re@-2 {{default argument of 'J' must be imported from one of {{.*}}stuff.use{{.*}}stuff.use-2}} -// expected-error@-3 {{default argument of 'J' must be imported from module 'stuff.use'}} +// expected-error-re@-2 {{default argument of 'J' must be imported from one of {{.*}}stuff.use{{.*}}stuff.use-2}} #elif EARLY_INDIRECT_INCLUDE -// expected-error@-5 {{default argument of 'J' must be imported from module 'merged-defs'}} +// expected-error@-4 {{default argument of 'J' must be imported from module 'merged-defs'}} #else -// expected-error@-7 {{default argument of 'J' must be imported from module 'stuff.use'}} +// expected-error@-6 {{default argument of 'J' must be imported from module 'stuff.use'}} #endif // expected-note@defs.h:49 +{{here}}