diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2015-06-10 20:30:23 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2015-06-10 20:30:23 +0000 |
commit | e7bd6defd71d24e9b58f18462bb32c92a355c05b (patch) | |
tree | a18f813183af339aafcaf6f24cc9cbcff597883c /clang/lib/Sema/SemaLookup.cpp | |
parent | ccb8d5cc573d3c8a24a5671b13971a4357dc914e (diff) | |
download | bcm5719-llvm-e7bd6defd71d24e9b58f18462bb32c92a355c05b.tar.gz bcm5719-llvm-e7bd6defd71d24e9b58f18462bb32c92a355c05b.zip |
[modules] Track all default template arguments for a given parameter across
modules, and allow use of a default template argument if any of the parameters
providing it is visible.
llvm-svn: 239485
Diffstat (limited to 'clang/lib/Sema/SemaLookup.cpp')
-rw-r--r-- | clang/lib/Sema/SemaLookup.cpp | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp index d0a55b57c61..147b81bc597 100644 --- a/clang/lib/Sema/SemaLookup.cpp +++ b/clang/lib/Sema/SemaLookup.cpp @@ -1228,6 +1228,8 @@ 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 @@ -1282,6 +1284,30 @@ bool Sema::hasVisibleMergedDefinition(NamedDecl *Def) { return false; } +template<typename ParmDecl> +static bool hasVisibleDefaultArgument(Sema &S, const ParmDecl *D) { + if (!D->hasDefaultArgument()) + return false; + + while (D) { + auto &DefaultArg = D->getDefaultArgStorage(); + if (!DefaultArg.isInherited() && S.isVisible(D)) + return true; + + // If there was a previous default argument, maybe its parameter is visible. + D = DefaultArg.getInheritedFrom(); + } + return false; +} + +bool Sema::hasVisibleDefaultArgument(const NamedDecl *D) { + if (auto *P = dyn_cast<TemplateTypeParmDecl>(D)) + return ::hasVisibleDefaultArgument(*this, P); + if (auto *P = dyn_cast<NonTypeTemplateParmDecl>(D)) + return ::hasVisibleDefaultArgument(*this, P); + return ::hasVisibleDefaultArgument(*this, cast<TemplateTemplateParmDecl>(D)); +} + /// \brief Determine whether a declaration is visible to name lookup. /// /// This routine determines whether the declaration D is visible in the current |