diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2015-09-11 22:39:35 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2015-09-11 22:39:35 +0000 |
commit | 535ff8035458d859e3d309067a9ce45623daf269 (patch) | |
tree | 61e5cada703333dac07c344e6695b2312f59ff3c /clang/lib/Sema/SemaLookup.cpp | |
parent | 2681e7dcd0ce403b998e1166a0188bbffd34f077 (diff) | |
download | bcm5719-llvm-535ff8035458d859e3d309067a9ce45623daf269.tar.gz bcm5719-llvm-535ff8035458d859e3d309067a9ce45623daf269.zip |
[modules] When picking one of two template declarations as a lookup result,
it's not sufficient to prefer the declaration with more default arguments, or
the one that's visible; they might both be visible, but one of them might have
a visible default argument where the other has a hidden default argument.
llvm-svn: 247486
Diffstat (limited to 'clang/lib/Sema/SemaLookup.cpp')
-rw-r--r-- | clang/lib/Sema/SemaLookup.cpp | 17 |
1 files changed, 16 insertions, 1 deletions
diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp index 923da4e06b6..bda535bc654 100644 --- a/clang/lib/Sema/SemaLookup.cpp +++ b/clang/lib/Sema/SemaLookup.cpp @@ -387,6 +387,8 @@ static bool isPreferredLookupResult(Sema &S, Sema::LookupNameKind Kind, // If D has more default arguments, it is preferred. if (DMin != EMin) return DMin < EMin; + // FIXME: When we track visibility for default function arguments, check + // that we pick the declaration with more visible default arguments. } // Pick the template with more default template arguments. @@ -394,9 +396,22 @@ static bool isPreferredLookupResult(Sema &S, Sema::LookupNameKind Kind, auto *ETD = cast<TemplateDecl>(EUnderlying); unsigned DMin = DTD->getTemplateParameters()->getMinRequiredArguments(); unsigned EMin = ETD->getTemplateParameters()->getMinRequiredArguments(); - // If D has more default arguments, it is preferred. + // If D has more default arguments, it is preferred. Note that default + // arguments (and their visibility) is monotonically increasing across the + // redeclaration chain, so this is a quick proxy for "is more recent". if (DMin != EMin) return DMin < EMin; + // If D has more *visible* default arguments, it is preferred. Note, an + // earlier default argument being visible does not imply that a later + // default argument is visible, so we can't just check the first one. + for (unsigned I = DMin, N = DTD->getTemplateParameters()->size(); + I != N; ++I) { + if (!S.hasVisibleDefaultArgument( + ETD->getTemplateParameters()->getParam(I)) && + S.hasVisibleDefaultArgument( + DTD->getTemplateParameters()->getParam(I))) + return true; + } } // For most kinds of declaration, it doesn't really matter which one we pick. |