diff options
Diffstat (limited to 'clang/lib/Sema/SemaDecl.cpp')
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 66 |
1 files changed, 37 insertions, 29 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 15e6a492725..330d0cbb587 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -5033,8 +5033,9 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, // the template out-of-line. if (!D.getCXXScopeSpec().isInvalid() && !Invalid && !PrevVarTemplate) { - Diag(D.getIdentifierLoc(), diag::err_member_def_does_not_match) - << Name << DC << D.getCXXScopeSpec().getRange(); + Diag(D.getIdentifierLoc(), diag::err_member_decl_does_not_match) + << Name << DC << /*IsDefinition*/true + << D.getCXXScopeSpec().getRange(); Invalid = true; } } @@ -5914,24 +5915,27 @@ class DifferentNameValidatorCCC : public CorrectionCandidateCallback { /// /// Returns a NamedDecl iff typo correction was performed and substituting in /// the new declaration name does not cause new errors. -static NamedDecl* DiagnoseInvalidRedeclaration( +static NamedDecl *DiagnoseInvalidRedeclaration( Sema &SemaRef, LookupResult &Previous, FunctionDecl *NewFD, - ActOnFDArgs &ExtraArgs) { + ActOnFDArgs &ExtraArgs, bool IsLocalFriend, Scope *S) { NamedDecl *Result = NULL; DeclarationName Name = NewFD->getDeclName(); DeclContext *NewDC = NewFD->getDeclContext(); - LookupResult Prev(SemaRef, Name, NewFD->getLocation(), - Sema::LookupOrdinaryName, Sema::ForRedeclaration); SmallVector<unsigned, 1> MismatchedParams; SmallVector<std::pair<FunctionDecl *, unsigned>, 1> NearMatches; TypoCorrection Correction; - bool isFriendDecl = (SemaRef.getLangOpts().CPlusPlus && - ExtraArgs.D.getDeclSpec().isFriendSpecified()); - unsigned DiagMsg = isFriendDecl ? diag::err_no_matching_local_friend - : diag::err_member_def_does_not_match; + unsigned DiagMsg = IsLocalFriend ? diag::err_no_matching_local_friend + : diag::err_member_decl_does_not_match; + LookupResult Prev(SemaRef, Name, NewFD->getLocation(), + IsLocalFriend ? Sema::LookupLocalFriendName + : Sema::LookupOrdinaryName, + Sema::ForRedeclaration); NewFD->setInvalidDecl(); - SemaRef.LookupQualifiedName(Prev, NewDC); + if (IsLocalFriend) + SemaRef.LookupName(Prev, S); + else + SemaRef.LookupQualifiedName(Prev, NewDC); assert(!Prev.isAmbiguous() && "Cannot have an ambiguity in previous-declaration lookup"); CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(NewFD); @@ -5951,9 +5955,9 @@ static NamedDecl* DiagnoseInvalidRedeclaration( } } // If the qualified name lookup yielded nothing, try typo correction - } else if ((Correction = SemaRef.CorrectTypo(Prev.getLookupNameInfo(), - Prev.getLookupKind(), 0, 0, - Validator, NewDC))) { + } else if ((Correction = SemaRef.CorrectTypo( + Prev.getLookupNameInfo(), Prev.getLookupKind(), S, 0, + Validator, IsLocalFriend ? 0 : NewDC))) { // Trap errors. Sema::SFINAETrap Trap(SemaRef); @@ -6000,11 +6004,12 @@ static NamedDecl* DiagnoseInvalidRedeclaration( // Ignore the correction if it didn't yield any close FunctionDecl matches Correction = TypoCorrection(); } else { - DiagMsg = isFriendDecl ? diag::err_no_matching_local_friend_suggest - : diag::err_member_def_does_not_match_suggest; + DiagMsg = IsLocalFriend ? diag::err_no_matching_local_friend_suggest + : diag::err_member_decl_does_not_match_suggest; } } + bool IsDefinition = ExtraArgs.D.isFunctionDefinition(); if (Correction) { // FIXME: use Correction.getCorrectionRange() instead of computing the range // here. This requires passing in the CXXScopeSpec to CorrectTypo which in @@ -6016,11 +6021,12 @@ static NamedDecl* DiagnoseInvalidRedeclaration( FixItLoc.setBegin(SS.getBeginLoc()); SemaRef.Diag(NewFD->getLocStart(), DiagMsg) << Name << NewDC << Correction.getQuoted(SemaRef.getLangOpts()) + << IsDefinition << FixItHint::CreateReplacement( FixItLoc, Correction.getAsString(SemaRef.getLangOpts())); } else { SemaRef.Diag(NewFD->getLocation(), DiagMsg) - << Name << NewDC << NewFD->getLocation(); + << Name << NewDC << IsDefinition << NewFD->getLocation(); } bool NewFDisConst = false; @@ -6031,16 +6037,18 @@ static NamedDecl* DiagnoseInvalidRedeclaration( NearMatch = NearMatches.begin(), NearMatchEnd = NearMatches.end(); NearMatch != NearMatchEnd; ++NearMatch) { FunctionDecl *FD = NearMatch->first; - bool FDisConst = false; - if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) - FDisConst = MD->isConst(); + CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD); + bool FDisConst = MD && MD->isConst(); + bool IsMember = MD || !IsLocalFriend; if (unsigned Idx = NearMatch->second) { ParmVarDecl *FDParam = FD->getParamDecl(Idx-1); SourceLocation Loc = FDParam->getTypeSpecStartLoc(); if (Loc.isInvalid()) Loc = FD->getLocation(); - SemaRef.Diag(Loc, diag::note_member_def_close_param_match) - << Idx << FDParam->getType() << NewFD->getParamDecl(Idx-1)->getType(); + SemaRef.Diag(Loc, IsMember ? diag::note_member_def_close_param_match + : diag::note_local_decl_close_param_match) + << Idx << FDParam->getType() + << NewFD->getParamDecl(Idx - 1)->getType(); } else if (Correction) { SemaRef.Diag(FD->getLocation(), diag::note_previous_decl) << Correction.getQuoted(SemaRef.getLangOpts()); @@ -6048,7 +6056,9 @@ static NamedDecl* DiagnoseInvalidRedeclaration( SemaRef.Diag(FD->getLocation(), diag::note_member_def_close_const_match) << NewFDisConst << FD->getSourceRange().getEnd(); } else - SemaRef.Diag(FD->getLocation(), diag::note_member_def_close_match); + SemaRef.Diag(FD->getLocation(), + IsMember ? diag::note_member_def_close_match + : diag::note_local_decl_close_match); } return Result; } @@ -7063,9 +7073,8 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, // matches (e.g., those that differ only in cv-qualifiers and // whether the parameter types are references). - if (NamedDecl *Result = DiagnoseInvalidRedeclaration(*this, Previous, - NewFD, - ExtraArgs)) { + if (NamedDecl *Result = DiagnoseInvalidRedeclaration( + *this, Previous, NewFD, ExtraArgs, false, 0)) { AddToScope = ExtraArgs.AddToScope; return Result; } @@ -7074,9 +7083,8 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, // Unqualified local friend declarations are required to resolve // to something. } else if (isFriend && cast<CXXRecordDecl>(CurContext)->isLocalClass()) { - if (NamedDecl *Result = DiagnoseInvalidRedeclaration(*this, Previous, - NewFD, - ExtraArgs)) { + if (NamedDecl *Result = DiagnoseInvalidRedeclaration( + *this, Previous, NewFD, ExtraArgs, true, S)) { AddToScope = ExtraArgs.AddToScope; return Result; } |