diff options
author | John McCall <rjmccall@apple.com> | 2010-06-16 08:42:20 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2010-06-16 08:42:20 +0000 |
commit | ad00b7705f9bbee81beeac428e7c6587734ab5a6 (patch) | |
tree | cd68ed597dabc2870e71dd62cdf287859b1019e3 /lib/Sema/SemaTemplate.cpp | |
parent | bd409d040bffef3e7ba862941dd706b1f7021141 (diff) |
Fix a point of semantics with using declaration hiding: method templates
introduced by using decls are hidden even if their template parameter lists
or return types differ from the "overriding" declaration.
Propagate using shadow declarations around more effectively when looking up
template-ids. Reperform lookup for template-ids in member expressions so that
access control is properly set up.
Fix some number of latent bugs involving template-ids with totally invalid
base types. You can only actually get these with a scope specifier, since
otherwise the template-id won't parse as a template-id.
Fixes PR7384.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@106093 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaTemplate.cpp')
-rw-r--r-- | lib/Sema/SemaTemplate.cpp | 17 |
1 files changed, 8 insertions, 9 deletions
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index a2d4de5b1f..f5f4853fb0 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -27,12 +27,12 @@ using namespace clang; /// \brief Determine whether the declaration found is acceptable as the name /// of a template and, if so, return that template declaration. Otherwise, /// returns NULL. -static NamedDecl *isAcceptableTemplateName(ASTContext &Context, NamedDecl *D) { - if (!D) - return 0; +static NamedDecl *isAcceptableTemplateName(ASTContext &Context, + NamedDecl *Orig) { + NamedDecl *D = Orig->getUnderlyingDecl(); if (isa<TemplateDecl>(D)) - return D; + return Orig; if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(D)) { // C++ [temp.local]p1: @@ -68,7 +68,7 @@ static void FilterAcceptableTemplateNames(ASTContext &C, LookupResult &R) { LookupResult::Filter filter = R.makeFilter(); while (filter.hasNext()) { NamedDecl *Orig = filter.next(); - NamedDecl *Repl = isAcceptableTemplateName(C, Orig->getUnderlyingDecl()); + NamedDecl *Repl = isAcceptableTemplateName(C, Orig); if (!Repl) filter.erase(); else if (Repl != Orig) { @@ -260,7 +260,7 @@ void Sema::LookupTemplateName(LookupResult &Found, if (DeclarationName Corrected = CorrectTypo(Found, S, &SS, LookupCtx, false, CTC_CXXCasts)) { FilterAcceptableTemplateNames(Context, Found); - if (!Found.empty() && isa<TemplateDecl>(*Found.begin())) { + if (!Found.empty()) { if (LookupCtx) Diag(Found.getNameLoc(), diag::err_no_member_template_suggest) << Name << LookupCtx << Found.getLookupName() << SS.getRange() @@ -274,8 +274,7 @@ void Sema::LookupTemplateName(LookupResult &Found, if (TemplateDecl *Template = Found.getAsSingle<TemplateDecl>()) Diag(Template->getLocation(), diag::note_previous_decl) << Template->getDeclName(); - } else - Found.clear(); + } } else { Found.clear(); } @@ -303,7 +302,7 @@ void Sema::LookupTemplateName(LookupResult &Found, // - if the name is found in the context of the entire // postfix-expression and does not name a class template, the name // found in the class of the object expression is used, otherwise - } else { + } else if (!Found.isSuppressingDiagnostics()) { // - if the name found is a class template, it must refer to the same // entity as the one found in the class of the object expression, // otherwise the program is ill-formed. |