diff options
-rw-r--r-- | include/clang/Basic/DiagnosticSemaKinds.td | 13 | ||||
-rw-r--r-- | include/clang/Basic/PartialDiagnostic.h | 21 | ||||
-rw-r--r-- | include/clang/Sema/Sema.h | 9 | ||||
-rw-r--r-- | include/clang/Sema/TypoCorrection.h | 4 | ||||
-rw-r--r-- | lib/Sema/SemaCXXScopeSpec.cpp | 38 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 215 | ||||
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 61 | ||||
-rw-r--r-- | lib/Sema/SemaDeclObjC.cpp | 44 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 117 | ||||
-rw-r--r-- | lib/Sema/SemaExprMember.cpp | 37 | ||||
-rw-r--r-- | lib/Sema/SemaExprObjC.cpp | 31 | ||||
-rw-r--r-- | lib/Sema/SemaInit.cpp | 23 | ||||
-rw-r--r-- | lib/Sema/SemaLookup.cpp | 38 | ||||
-rw-r--r-- | lib/Sema/SemaOpenMP.cpp | 33 | ||||
-rw-r--r-- | lib/Sema/SemaTemplate.cpp | 20 | ||||
-rw-r--r-- | lib/Sema/SemaTemplateVariadic.cpp | 12 | ||||
-rw-r--r-- | test/OpenMP/threadprivate_messages.cpp | 2 | ||||
-rw-r--r-- | test/Parser/recovery.cpp | 4 | ||||
-rw-r--r-- | test/Sema/builtins.c | 2 | ||||
-rw-r--r-- | test/SemaCXX/typo-correction-pt2.cpp | 8 |
20 files changed, 320 insertions, 412 deletions
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index d50b7fca1b..e954eb6bc3 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -895,7 +895,7 @@ def err_tagless_friend_type_template : Error< def err_no_matching_local_friend : Error< "no matching function found in local scope">; def err_no_matching_local_friend_suggest : Error< - "no matching function %0 found in local scope; did you mean %2?">; + "no matching function %0 found in local scope; did you mean %3?">; def err_partial_specialization_friend : Error< "partial specialization cannot be declared as a friend">; def err_qualified_friend_def : Error< @@ -4345,8 +4345,8 @@ def err_friend_decl_with_def_arg_redeclared : Error< def err_friend_decl_does_not_match : Error< "friend declaration of %0 does not match any declaration in %1">; def err_member_decl_does_not_match_suggest : Error< - "out-of-line %select{declaration|definition}3 of %0 " - "does not match any declaration in %1; did you mean %2?">; + "out-of-line %select{declaration|definition}2 of %0 " + "does not match any declaration in %1; did you mean %3?">; def err_member_def_does_not_match_ret_type : Error< "out-of-line definition of %q0 differs from the declaration in the return type">; def err_nonstatic_member_out_of_line : Error< @@ -6464,7 +6464,7 @@ def warn_direct_ivar_access : Warning<"instance variable %0 is being " // Spell-checking diagnostics def err_unknown_type_or_class_name_suggest : Error< - "unknown %select{type|class}2 name %0; did you mean %1?">; + "unknown %select{type|class}1 name %0; did you mean %2?">; def err_unknown_typename_suggest : Error< "unknown type name %0; did you mean %1?">; def err_unknown_nested_typename_suggest : Error< @@ -6576,8 +6576,11 @@ def err_opencl_global_invalid_addr_space : Error< let CategoryName = "OpenMP Issue" in { // OpenMP support. +def err_omp_expected_var_arg : Error< + "%0 is not a global variable, static local variable or static data member">; def err_omp_expected_var_arg_suggest : Error< - "%0 is not a global variable, static local variable or static data member%select{|; did you mean %2?}1">; + "%0 is not a global variable, static local variable or static data member; " + "did you mean %1">; def err_omp_global_var_arg : Error< "arguments of '#pragma omp %0' must have %select{global storage|static storage duration}1">; def err_omp_ref_type_arg : Error< diff --git a/include/clang/Basic/PartialDiagnostic.h b/include/clang/Basic/PartialDiagnostic.h index 3f68160f69..dd29926fce 100644 --- a/include/clang/Basic/PartialDiagnostic.h +++ b/include/clang/Basic/PartialDiagnostic.h @@ -368,6 +368,27 @@ public: } friend inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD, + const IdentifierInfo *II) { + PD.AddTaggedVal(reinterpret_cast<intptr_t>(II), + DiagnosticsEngine::ak_identifierinfo); + return PD; + } + + // Adds a DeclContext to the diagnostic. The enable_if template magic is here + // so that we only match those arguments that are (statically) DeclContexts; + // other arguments that derive from DeclContext (e.g., RecordDecls) will not + // match. + template<typename T> + friend inline + typename llvm::enable_if<llvm::is_same<T, DeclContext>, + const PartialDiagnostic &>::type + operator<<(const PartialDiagnostic &PD, T *DC) { + PD.AddTaggedVal(reinterpret_cast<intptr_t>(DC), + DiagnosticsEngine::ak_declcontext); + return PD; + } + + friend inline const PartialDiagnostic &operator<<(const PartialDiagnostic &PD, const SourceRange &R) { PD.AddSourceRange(CharSourceRange::getTokenRange(R)); return PD; diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index e66c388b6b..f7d5b6ba18 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -2487,6 +2487,15 @@ public: bool EnteringContext = false, const ObjCObjectPointerType *OPT = 0); + void diagnoseTypo(const TypoCorrection &Correction, + const PartialDiagnostic &TypoDiag, + bool ErrorRecovery = true); + + void diagnoseTypo(const TypoCorrection &Correction, + const PartialDiagnostic &TypoDiag, + const PartialDiagnostic &PrevNote, + bool ErrorRecovery = true); + void FindAssociatedClassesAndNamespaces(SourceLocation InstantiationLoc, ArrayRef<Expr *> Args, AssociatedNamespaceSet &AssociatedNamespaces, diff --git a/include/clang/Sema/TypoCorrection.h b/include/clang/Sema/TypoCorrection.h index 7a4a43ef2b..b4065be743 100644 --- a/include/clang/Sema/TypoCorrection.h +++ b/include/clang/Sema/TypoCorrection.h @@ -183,9 +183,9 @@ public: return CorrectionDecls.size() > 1; } - void setCorrectionRange(CXXScopeSpec* SS, + void setCorrectionRange(CXXScopeSpec *SS, const DeclarationNameInfo &TypoName) { - CorrectionRange.setBegin(ForceSpecifierReplacement && SS + CorrectionRange.setBegin(ForceSpecifierReplacement && SS && !SS->isEmpty() ? SS->getBeginLoc() : TypoName.getLoc()); CorrectionRange.setEnd(TypoName.getLoc()); diff --git a/lib/Sema/SemaCXXScopeSpec.cpp b/lib/Sema/SemaCXXScopeSpec.cpp index 9701f7d751..327d55f0b3 100644 --- a/lib/Sema/SemaCXXScopeSpec.cpp +++ b/lib/Sema/SemaCXXScopeSpec.cpp @@ -489,31 +489,23 @@ bool Sema::BuildCXXNestedNameSpecifier(Scope *S, // different kind of error, so look for typos. DeclarationName Name = Found.getLookupName(); NestedNameSpecifierValidatorCCC Validator(*this); - TypoCorrection Corrected; Found.clear(); - if ((Corrected = CorrectTypo(Found.getLookupNameInfo(), - Found.getLookupKind(), S, &SS, Validator, - LookupCtx, EnteringContext))) { - std::string CorrectedStr(Corrected.getAsString(getLangOpts())); - std::string CorrectedQuotedStr(Corrected.getQuoted(getLangOpts())); - bool droppedSpecifier = Corrected.WillReplaceSpecifier() && - Name.getAsString() == CorrectedStr; - if (LookupCtx) - Diag(Found.getNameLoc(), diag::err_no_member_suggest) - << Name << LookupCtx << droppedSpecifier << CorrectedQuotedStr - << SS.getRange() - << FixItHint::CreateReplacement(Corrected.getCorrectionRange(), - CorrectedStr); - else - Diag(Found.getNameLoc(), diag::err_undeclared_var_use_suggest) - << Name << CorrectedQuotedStr - << FixItHint::CreateReplacement(Corrected.getCorrectionRange(), - CorrectedStr); - - if (NamedDecl *ND = Corrected.getCorrectionDecl()) { - Diag(ND->getLocation(), diag::note_previous_decl) << CorrectedQuotedStr; + if (TypoCorrection Corrected = + CorrectTypo(Found.getLookupNameInfo(), Found.getLookupKind(), S, + &SS, Validator, LookupCtx, EnteringContext)) { + if (LookupCtx) { + bool DroppedSpecifier = + Corrected.WillReplaceSpecifier() && + Name.getAsString() == Corrected.getAsString(getLangOpts()); + diagnoseTypo(Corrected, PDiag(diag::err_no_member_suggest) + << Name << LookupCtx << DroppedSpecifier + << SS.getRange()); + } else + diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) + << Name); + + if (NamedDecl *ND = Corrected.getCorrectionDecl()) Found.addDecl(ND); - } Found.setLookupName(Corrected.getCorrection()); } else { Found.setLookupName(&Identifier); diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index e07d332d52..9dad47fb8f 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -237,17 +237,9 @@ ParsedType Sema::getTypeName(const IdentifierInfo &II, SourceLocation NameLoc, IsCtorOrDtorName, WantNontrivialTypeSourceInfo); if (Ty) { - std::string CorrectedStr(Correction.getAsString(getLangOpts())); - std::string CorrectedQuotedStr( - Correction.getQuoted(getLangOpts())); - Diag(NameLoc, diag::err_unknown_type_or_class_name_suggest) - << Result.getLookupName() << CorrectedQuotedStr << isClassName - << FixItHint::CreateReplacement(SourceRange(NameLoc), - CorrectedStr); - if (NamedDecl *FirstDecl = Correction.getCorrectionDecl()) - Diag(FirstDecl->getLocation(), diag::note_previous_decl) - << CorrectedQuotedStr; - + diagnoseTypo(Correction, + PDiag(diag::err_unknown_type_or_class_name_suggest) + << Result.getLookupName() << isClassName); if (SS && NNS) SS->MakeTrivial(Context, NNS, SourceRange(NameLoc)); *CorrectedII = NewII; @@ -412,45 +404,28 @@ bool Sema::DiagnoseUnknownTypeName(IdentifierInfo *&II, if (TypoCorrection Corrected = CorrectTypo(DeclarationNameInfo(II, IILoc), LookupOrdinaryName, S, SS, Validator)) { - std::string CorrectedStr(Corrected.getAsString(getLangOpts())); - std::string CorrectedQuotedStr(Corrected.getQuoted(getLangOpts())); - if (Corrected.isKeyword()) { // We corrected to a keyword. - IdentifierInfo *NewII = Corrected.getCorrectionAsIdentifierInfo(); - if (!isSimpleTypeSpecifier(NewII->getTokenID())) - CorrectedQuotedStr = "the keyword " + CorrectedQuotedStr; - Diag(IILoc, diag::err_unknown_typename_suggest) - << II << CorrectedQuotedStr - << FixItHint::CreateReplacement(Corrected.getCorrectionRange(), - CorrectedStr); - II = NewII; + diagnoseTypo(Corrected, PDiag(diag::err_unknown_typename_suggest) << II); + II = Corrected.getCorrectionAsIdentifierInfo(); } else { - NamedDecl *Result = Corrected.getCorrectionDecl(); // We found a similarly-named type or interface; suggest that. if (!SS || !SS->isSet()) { - Diag(IILoc, diag::err_unknown_typename_suggest) - << II << CorrectedQuotedStr - << FixItHint::CreateReplacement(Corrected.getCorrectionRange(), - CorrectedStr); + diagnoseTypo(Corrected, + PDiag(diag::err_unknown_typename_suggest) << II); } else if (DeclContext *DC = computeDeclContext(*SS, false)) { - bool droppedSpecifier = Corrected.WillReplaceSpecifier() && + std::string CorrectedStr(Corrected.getAsString(getLangOpts())); + bool DroppedSpecifier = Corrected.WillReplaceSpecifier() && II->getName().equals(CorrectedStr); - Diag(IILoc, diag::err_unknown_nested_typename_suggest) - << II << DC << droppedSpecifier << CorrectedQuotedStr - << SS->getRange() - << FixItHint::CreateReplacement(Corrected.getCorrectionRange(), - CorrectedStr); - } - else { + diagnoseTypo(Corrected, + PDiag(diag::err_unknown_nested_typename_suggest) + << II << DC << DroppedSpecifier << SS->getRange()); + } else { llvm_unreachable("could not have corrected a typo here"); } - Diag(Result->getLocation(), diag::note_previous_decl) - << CorrectedQuotedStr; - - SuggestedType = getTypeName(*Result->getIdentifier(), IILoc, S, SS, - false, false, ParsedType(), + SuggestedType = getTypeName(*Corrected.getCorrectionAsIdentifierInfo(), + IILoc, S, SS, false, false, ParsedType(), /*IsCtorOrDtorName=*/false, /*NonTrivialTypeSourceInfo=*/true); } @@ -669,9 +644,7 @@ Corrected: &SS, *CCC)) { unsigned UnqualifiedDiag = diag::err_undeclared_var_use_suggest; unsigned QualifiedDiag = diag::err_no_member_suggest; - std::string CorrectedStr(Corrected.getAsString(getLangOpts())); - std::string CorrectedQuotedStr(Corrected.getQuoted(getLangOpts())); - + NamedDecl *FirstDecl = Corrected.getCorrectionDecl(); NamedDecl *UnderlyingFirstDecl = FirstDecl? FirstDecl->getUnderlyingDecl() : 0; @@ -688,35 +661,29 @@ Corrected: } if (SS.isEmpty()) { - Diag(NameLoc, UnqualifiedDiag) - << Name << CorrectedQuotedStr - << FixItHint::CreateReplacement(NameLoc, CorrectedStr); + diagnoseTypo(Corrected, PDiag(UnqualifiedDiag) << Name); } else {// FIXME: is this even reachable? Test it. - bool droppedSpecifier = Corrected.WillReplaceSpecifier() && + std::string CorrectedStr(Corrected.getAsString(getLangOpts())); + bool DroppedSpecifier = Corrected.WillReplaceSpecifier() && Name->getName().equals(CorrectedStr); - Diag(NameLoc, QualifiedDiag) - << Name << computeDeclContext(SS, false) << droppedSpecifier - << CorrectedQuotedStr << SS.getRange() - << FixItHint::CreateReplacement(Corrected.getCorrectionRange(), - CorrectedStr); + diagnoseTypo(Corrected, PDiag(QualifiedDiag) + << Name << computeDeclContext(SS, false) + << DroppedSpecifier << SS.getRange()); } // Update the name, so that the caller has the new name. Name = Corrected.getCorrectionAsIdentifierInfo(); - + // Typo correction corrected to a keyword. if (Corrected.isKeyword()) - return Corrected.getCorrectionAsIdentifierInfo(); + return Name; // Also update the LookupResult... // FIXME: This should probably go away at some point Result.clear(); Result.setLookupName(Corrected.getCorrection()); - if (FirstDecl) { + if (FirstDecl) Result.addDecl(FirstDecl); - Diag(FirstDecl->getLocation(), diag::note_previous_decl) - << CorrectedQuotedStr; - } // If we found an Objective-C instance variable, let // LookupInObjCMethod build the appropriate expression to @@ -1451,13 +1418,8 @@ ObjCInterfaceDecl *Sema::getObjCInterfaceDecl(IdentifierInfo *&Id, if (TypoCorrection C = CorrectTypo(DeclarationNameInfo(Id, IdLoc), LookupOrdinaryName, TUScope, NULL, Validator)) { + diagnoseTypo(C, PDiag(diag::err_undef_interface_suggest) << Id); IDecl = C.getCorrectionDeclAs<ObjCInterfaceDecl>(); - Diag(IdLoc, diag::err_undef_interface_suggest) - << Id << IDecl->getDeclName() - << FixItHint::CreateReplacement(IdLoc, IDecl->getNameAsString()); - Diag(IDecl->getLocation(), diag::note_previous_decl) - << IDecl->getDeclName(); - Id = IDecl->getIdentifier(); } } @@ -5988,12 +5950,12 @@ class DifferentNameValidatorCCC : public CorrectionCandidateCallback { static NamedDecl *DiagnoseInvalidRedeclaration( Sema &SemaRef, LookupResult &Previous, FunctionDecl *NewFD, ActOnFDArgs &ExtraArgs, bool IsLocalFriend, Scope *S) { - NamedDecl *Result = NULL; DeclarationName Name = NewFD->getDeclName(); DeclContext *NewDC = NewFD->getDeclContext(); SmallVector<unsigned, 1> MismatchedParams; SmallVector<std::pair<FunctionDecl *, unsigned>, 1> NearMatches; TypoCorrection Correction; + bool IsDefinition = ExtraArgs.D.isFunctionDefinition(); unsigned DiagMsg = IsLocalFriend ? diag::err_no_matching_local_friend : diag::err_member_decl_does_not_match; LookupResult Prev(SemaRef, Name, NewFD->getLocation(), @@ -6026,11 +5988,9 @@ static NamedDecl *DiagnoseInvalidRedeclaration( } // If the qualified name lookup yielded nothing, try typo correction } else if ((Correction = SemaRef.CorrectTypo( - Prev.getLookupNameInfo(), Prev.getLookupKind(), S, 0, - Validator, IsLocalFriend ? 0 : NewDC))) { - // Trap errors. - Sema::SFINAETrap Trap(SemaRef); - + Prev.getLookupNameInfo(), Prev.getLookupKind(), S, + &ExtraArgs.D.getCXXScopeSpec(), Validator, + IsLocalFriend ? 0 : NewDC))) { // Set up everything for the call to ActOnFunctionDeclarator ExtraArgs.D.SetIdentifier(Correction.getCorrectionAsIdentifierInfo(), ExtraArgs.D.getIdentifierLoc()); @@ -6046,59 +6006,55 @@ static NamedDecl *DiagnoseInvalidRedeclaration( } } bool wasRedeclaration = ExtraArgs.D.isRedeclaration(); - // TODO: Refactor ActOnFunctionDeclarator so that we can call only the - // pieces need to verify the typo-corrected C++ declaraction and hopefully - // eliminate the need for the parameter pack ExtraArgs. - Result = SemaRef.ActOnFunctionDeclarator( - ExtraArgs.S, ExtraArgs.D, - Correction.getCorrectionDecl()->getDeclContext(), - NewFD->getTypeSourceInfo(), Previous, ExtraArgs.TemplateParamLists, - ExtraArgs.AddToScope); - if (Trap.hasErrorOccurred()) { - // Pretend the typo correction never occurred - ExtraArgs.D.SetIdentifier(Name.getAsIdentifierInfo(), - ExtraArgs.D.getIdentifierLoc()); - ExtraArgs.D.setRedeclaration(wasRedeclaration); - Previous.clear(); - Previous.setLookupName(Name); - Result = NULL; - } else { - for (LookupResult::iterator Func = Previous.begin(), - FuncEnd = Previous.end(); - Func != FuncEnd; ++Func) { - if (FunctionDecl *FD = dyn_cast<FunctionDecl>(*Func)) - NearMatches.push_back(std::make_pair(FD, 0)); - } - } - if (NearMatches.empty()) { - // Ignore the correction if it didn't yield any close FunctionDecl matches - Correction = TypoCorrection(); - } else { - DiagMsg = IsLocalFriend ? diag::err_no_matching_local_friend_suggest - : diag::err_member_decl_does_not_match_suggest; + + NamedDecl *Result; + // Retry building the function declaration with the new previous + // declarations, and with errors suppressed. + { + // Trap errors. + Sema::SFINAETrap Trap(SemaRef); + + // TODO: Refactor ActOnFunctionDeclarator so that we can call only the + // pieces need to verify the typo-corrected C++ declaration and hopefully + // eliminate the need for the parameter pack ExtraArgs. + Result = SemaRef.ActOnFunctionDeclarator( + ExtraArgs.S, ExtraArgs.D, + Correction.getCorrectionDecl()->getDeclContext(), + NewFD->getTypeSourceInfo(), Previous, ExtraArgs.TemplateParamLists, + ExtraArgs.AddToScope); + + if (Trap.hasErrorOccurred()) + Result = 0; + } + + if (Result) { + // Determine which correction we picked. + Decl *Canonical = Result->getCanonicalDecl(); + for (LookupResult::iterator I = Previous.begin(), E = Previous.end(); + I != E; ++I) + if ((*I)->getCanonicalDecl() == Canonical) + Correction.setCorrectionDecl(*I); + + SemaRef.diagnoseTypo( + Correction, + SemaRef.PDiag(IsLocalFriend + ? diag::err_no_matching_local_friend_suggest + : diag::err_member_decl_does_not_match_suggest) + << Name << NewDC << IsDefinition); + return Result; } - } - 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 - // turn causes the correction to fully qualify the name. If we fix - // CorrectTypo to minimally qualify then this change should be good. - SourceRange FixItLoc(NewFD->getLocation()); - CXXScopeSpec &SS = ExtraArgs.D.getCXXScopeSpec(); - if (Correction.getCorrectionSpecifier() && SS.isValid()) - 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 << IsDefinition << NewFD->getLocation(); + // Pretend the typo correction never occurred + ExtraArgs.D.SetIdentifier(Name.getAsIdentifierInfo(), + ExtraArgs.D.getIdentifierLoc()); + ExtraArgs.D.setRedeclaration(wasRedeclaration); + Previous.clear(); + Previous.setLookupName(Name); } + SemaRef.Diag(NewFD->getLocation(), DiagMsg) + << Name << NewDC << IsDefinition << NewFD->getLocation(); + bool NewFDisConst = false; if (CXXMethodDecl *NewMD = dyn_cast<CXXMethodDecl>(NewFD)) NewFDisConst = NewMD->isConst(); @@ -6119,9 +6075,6 @@ static NamedDecl *DiagnoseInvalidRedeclaration( : 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()); } else if (FDisConst != NewFDisConst) { SemaRef.Diag(FD->getLocation(), diag::note_member_def_close_const_match) << NewFDisConst << FD->getSourceRange().getEnd(); @@ -6130,7 +6083,7 @@ static NamedDecl *DiagnoseInvalidRedeclaration( IsMember ? diag::note_member_def_close_match : diag::note_local_decl_close_match); } - return Result; + return 0; } static FunctionDecl::StorageClass getFunctionStorageClass(Sema &SemaRef, @@ -9745,19 +9698,9 @@ NamedDecl *Sema::ImplicitlyDefineFunction(SourceLocation Loc, TypoCorrection Corrected; DeclFilterCCC<FunctionDecl> Validator; if (S && (Corrected = CorrectTypo(DeclarationNameInfo(&II, Loc), - LookupOrdinaryName, S, 0, Validator))) { - std::string CorrectedStr = Corrected.getAsString(getLangOpts()); - std::string CorrectedQuotedStr = Corrected.getQuoted(getLangOpts()); - FunctionDecl *Func = Corrected.getCorrectionDeclAs<FunctionDecl>(); - - Diag(Loc, diag::note_function_suggestion) << CorrectedQuotedStr - << FixItHint::CreateReplacement(Loc, CorrectedStr); - - if (Func->getLocation().isValid() - && !II.getName().startswith("__builtin_")) - Diag(Func->getLocation(), diag::note_previous_decl) - << CorrectedQuotedStr; - } + LookupOrdinaryName, S, 0, Validator))) + diagnoseTypo(Corrected, PDiag(diag::note_function_suggestion), + /*ErrorRecovery*/false); } // Set a Declarator for the implicit definition: int foo(); diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 0d7efe836b..b4b834021a 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -2412,18 +2412,13 @@ Sema::BuildMemInitializer(Decl *ConstructorD, if (R.empty() && BaseType.isNull() && (Corr = CorrectTypo(R.getLookupNameInfo(), R.getLookupKind(), S, &SS, Validator, ClassDecl))) { - std::string CorrectedStr(Corr.getAsString(getLangOpts())); - std::string CorrectedQuotedStr(Corr.getQuoted(getLangOpts())); if (FieldDecl *Member = Corr.getCorrectionDeclAs<FieldDecl>()) { // We have found a non-static data member with a similar // name to what was typed; complain and initialize that // member. - Diag(R.getNameLoc(), diag::err_mem_init_not_member_or_class_suggest) - << MemberOrBase << true << CorrectedQuotedStr - << FixItHint::CreateReplacement(R.getNameLoc(), CorrectedStr); - Diag(Member->getLocation(), diag::note_previous_decl) - << CorrectedQuotedStr; - + diagnoseTypo(Corr, + PDiag(diag::err_mem_init_not_member_or_class_suggest) + << MemberOrBase << true); return BuildMemberInitializer(Member, Init, IdLoc); } else if (TypeDecl *Type = Corr.getCorrectionDeclAs<TypeDecl>()) { const CXXBaseSpecifier *DirectBaseSpec; @@ -2434,12 +2429,13 @@ Sema::BuildMemInitializer(Decl *ConstructorD, // We have found a direct or virtual base class with a // similar name to what was typed; complain and initialize // that base class. - Diag(R.getNameLoc(), diag::err_mem_init_not_member_or_class_suggest) - << MemberOrBase << false << CorrectedQuotedStr - << FixItHint::CreateReplacement(R.getNameLoc(), CorrectedStr); + diagnoseTypo(Corr, + PDiag(diag::err_mem_init_not_member_or_class_suggest) + << MemberOrBase << false, + PDiag() /*Suppress note, we provide our own.*/); - const CXXBaseSpecifier *BaseSpec = DirectBaseSpec? DirectBaseSpec - : VirtualBaseSpec; + const CXXBaseSpecifier *BaseSpec = DirectBaseSpec ? DirectBaseSpec + : VirtualBaseSpec; Diag(BaseSpec->getLocStart(), diag::note_base_class_specified_here) << BaseSpec->getType() @@ -6628,24 +6624,19 @@ static bool TryNamespaceTypoCorrection(Sema &S, LookupResult &R, Scope *Sc, if (TypoCorrection Corrected = S.CorrectTypo(R.getLookupNameInfo(), R.getLookupKind(), Sc, &SS, Validator)) { - std::string CorrectedStr(Corrected.getAsString(S.getLangOpts())); - std::string CorrectedQuotedStr(Corrected.getQuoted(S.getLangOpts())); if (DeclContext *DC = S.computeDeclContext(SS, false)) { - bool droppedSpecifier = Corrected.WillReplaceSpecifier() && + std::string CorrectedStr(Corrected.getAsString(S.getLangOpts())); + bool DroppedSpecifier = Corrected.WillReplaceSpecifier() && Ident->getName().equals(CorrectedStr); - S.Diag(IdentLoc, diag::err_using_directive_member_suggest) - << Ident << DC << droppedSpecifier << CorrectedQuotedStr - << SS.getRange() << FixItHint::CreateReplacement( - Corrected.getCorrectionRange(), CorrectedStr); + S.diagnoseTypo(Corrected, + S.PDiag(diag::err_using_directive_member_suggest) + << Ident << DC << DroppedSpecifier << SS.getRange(), + S.PDiag(diag::note_namespace_defined_here)); } else { - S.Diag(IdentLoc, diag::err_using_directive_suggest) - << Ident << CorrectedQuotedStr - << FixItHint::CreateReplacement(IdentLoc, CorrectedStr); + S.diagnoseTypo(Corrected, + S.PDiag(diag::err_using_directive_suggest) << Ident, + S.PDiag(diag::note_namespace_defined_here)); } - - S.Diag(Corrected.getCorrectionDecl()->getLocation(), - diag::note_namespace_defined_here) << CorrectedQuotedStr; - R.addDecl(Corrected.getCorrectionDecl()); return true; } @@ -7193,21 +7184,15 @@ NamedDecl *Sema::BuildUsingDeclaration(Scope *S, AccessSpecifier AS, R.getLookupKind(), S, &SS, CCC)){ // We reject any correction for which ND would be NULL. NamedDecl *ND = Corrected.getCorrectionDecl(); - std::string CorrectedStr(Corrected.getAsString(getLangOpts())); - std::string CorrectedQuotedStr(Corrected.getQuoted(getLangOpts())); R.setLookupName(Corrected.getCorrection()); R.addDecl(ND); - // We reject candidates where droppedSpecifier == true, hence the + // We reject candidates where DroppedSpecifier == true, hence the // literal '0' below. - Diag(R.getNameLoc(), diag::err_no_member_suggest) - << NameInfo.getName() << LookupContext << 0 - << CorrectedQuotedStr << SS.getRange() - << FixItHint::CreateReplacement(Corrected.getCorrectionRange(), - CorrectedStr); - Diag(ND->getLocation(), diag::note_previous_decl) - << CorrectedQuotedStr; + diagnoseTypo(Corrected, PDiag(diag::err_no_member_suggest) + << NameInfo.getName() << LookupContext << 0 + << SS.getRange()); } else { - Diag(IdentLoc, diag::err_no_member) + Diag(IdentLoc, diag::err_no_member) << NameInfo.getName() << LookupContext << SS.getRange(); UD->setInvalidDecl(); return UD; diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp index aa6eff700d..b4fcce7fa7 100644 --- a/lib/Sema/SemaDeclObjC.cpp +++ b/lib/Sema/SemaDeclObjC.cpp @@ -513,11 +513,9 @@ ActOnStartClassInterface(SourceLocation AtInterfaceLoc, if (TypoCorrection Corrected = CorrectTypo( DeclarationNameInfo(SuperName, SuperLoc), LookupOrdinaryName, TUScope, NULL, Validator)) { + diagnoseTypo(Corrected, PDiag(diag::err_undef_superclass_suggest) + << SuperName << ClassName); PrevDecl = Corrected.getCorrectionDeclAs<ObjCInterfaceDecl>(); - Diag(SuperLoc, diag::err_undef_superclass_suggest) - << SuperName << ClassName << PrevDecl->getDeclName(); - Diag(PrevDecl->getLocation(), diag::note_previous_decl) - << PrevDecl->getDeclName(); } } @@ -748,12 +746,9 @@ Sema::FindProtocolDeclaration(bool WarnOnDeclarations, TypoCorrection Corrected = CorrectTypo( DeclarationNameInfo(ProtocolId[i].first, ProtocolId[i].second), LookupObjCProtocolName, TUScope, NULL, Validator); - if ((PDecl = Corrected.getCorrectionDeclAs<ObjCProtocolDecl>())) { - Diag(ProtocolId[i].second, diag::err_undeclared_protocol_suggest) - << ProtocolId[i].first << Corrected.getCorrection(); - Diag(PDecl->getLocation(), diag::note_previous_decl) - << PDecl->getDeclName(); - } + if ((PDecl = Corrected.getCorrectionDeclAs<ObjCProtocolDecl>())) + diagnoseTypo(Corrected, PDiag(diag::err_undeclared_protocol_suggest) + << ProtocolId[i].first); } if (!PDecl) { @@ -971,7 +966,7 @@ Decl *Sema::ActOnStartClassImplementation( IdentifierInfo *ClassName, SourceLocation ClassLoc, IdentifierInfo *SuperClassname, SourceLocation SuperClassLoc) { - ObjCInterfaceDecl* IDecl = 0; + ObjCInterfaceDecl *IDecl = 0; // Check for another declaration kind with the same name. NamedDecl *PrevDecl = LookupSingleName(TUScope, ClassName, ClassLoc, LookupOrdinaryName, @@ -983,24 +978,19 @@ Decl *Sema::ActOnStartClassImplementation( RequireCompleteType(ClassLoc, Context.getObjCInterfaceType(IDecl), diag::warn_undef_interface); } else { - // We did not find anything with the name ClassName; try to correct for + // We did not find anything with the name ClassName; try to correct for // typos in the class name. ObjCInterfaceValidatorCCC Validator; - if (TypoCorrection Corrected = CorrectTypo( - DeclarationNameInfo(ClassName, ClassLoc), LookupOrdinaryName, TUScope, - NULL, Validator)) { - // Suggest the (potentially) correct interface name. However, put the - // fix-it hint itself in a separate note, since changing the name in - // the warning would make the fix-it change semantics.However, don't - // provide a code-modification hint or use the typo name for recovery, - // because this is just a warning. The program may actually be correct. - IDecl = Corrected.getCorrectionDeclAs<ObjCInterfaceDecl>(); - DeclarationName CorrectedName = Corrected.getCorrection(); - Diag(ClassLoc, diag::warn_undef_interface_suggest) - << ClassName << CorrectedName; - Diag(IDecl->getLocation(), diag::note_previous_decl) << CorrectedName - << FixItHint::CreateReplacement(ClassLoc, CorrectedName.getAsString()); - IDecl = 0; + TypoCorrection Corrected = + CorrectTypo(DeclarationNameInfo(ClassName, ClassLoc), + LookupOrdinaryName, TUScope, NULL, Validator); + if (Corrected.getCorrectionDeclAs<ObjCInterfaceDecl>()) { + // Suggest the (potentially) correct interface name. Don't provide a + // code-modification hint or use the typo name for recovery, because + // this is just a warning. The program may actually be correct. + diagnoseTypo(Corrected, + PDiag(diag::warn_undef_interface_suggest) << ClassName, + /*ErrorRecovery*/false); } else { Diag(ClassLoc, diag::warn_undef_interface) << ClassName; } diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index aaa8287438..67bfffcd41 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -1775,12 +1775,14 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R, if (S && (Corrected = CorrectTypo(R.getLookupNameInfo(), R.getLookupKind(), S, &SS, CCC))) { std::string CorrectedStr(Corrected.getAsString(getLangOpts())); - std::string CorrectedQuotedStr(Corrected.getQuoted(getLangOpts())); - bool droppedSpecifier = + bool DroppedSpecifier = Corrected.WillReplaceSpecifier() && Name.getAsString() == CorrectedStr; R.setLookupName(Corrected.getCorrection()); - if (NamedDecl *ND = Corrected.getCorrectionDecl()) { + bool AcceptableWithRecovery = false; + bool AcceptableWithoutRecovery = false; + NamedDecl *ND = Corrected.getCorrectionDecl(); + if (ND) { if (Corrected.isOverloaded()) { OverloadCandidateSet OCS(R.getNameLoc()); OverloadCandidateSet::iterator Best; @@ -1798,63 +1800,49 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R, Args, OCS); } switch (OCS.BestViableFunction(*this, R.getNameLoc(), Best)) { - case OR_Success: - ND = Best->Function; - break; - default: - break; + case OR_Success: + ND = Best->Function; + Corrected.setCorrectionDecl(ND); + break; + default: + // FIXME: Arbitrarily pick the first declaration for the note. + Corrected.setCorrectionDecl(ND); + break; } } R.addDecl(ND); - if (isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND)) { - if (SS.isEmpty()) - Diag(R.getNameLoc(), diagnostic_suggest) << Name << CorrectedQuotedStr - << FixItHint::CreateReplacement(R.getNameLoc(), CorrectedStr); - else - Diag(R.getNameLoc(), diag::err_no_member_suggest) - << Name << computeDeclContext(SS, false) << droppedSpecifier - << CorrectedQuotedStr << SS.getRange() - << FixItHint::CreateReplacement(Corrected.getCorrectionRange(), - CorrectedStr); - - unsigned diag = isa<ImplicitParamDecl>(ND) - ? diag::note_implicit_param_decl - : diag::note_previous_decl; - - Diag(ND->getLocation(), diag) - << CorrectedQuotedStr; - // Tell the callee to try to recover. - return false; - } - - if (isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND)) { - // FIXME: If we ended up with a typo for a type name or - // Objective-C class name, we're in trouble because the parser - // is in the wrong place to recover. Suggest the typo - // correction, but don't make it a fix-it since we're not going - // to recover well anyway. - if (SS.isEmpty()) - Diag(R.getNameLoc(), diagnostic_suggest) - << Name << CorrectedQuotedStr; - else - Diag(R.getNameLoc(), diag::err_no_member_suggest) - << Name << computeDeclContext(SS, false) << droppedSpecifier - << CorrectedQuotedStr << SS.getRange(); - - // Don't try to recover; it won't work. - return true; - } + AcceptableWithRecovery = + isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND); + // FIXME: If we ended up with a typo for a type name or + // Objective-C class name, we're in trouble because the parser + // is in the wrong place to recover. Suggest the typo + // correction, but don't make it a fix-it since we're not going + // to recover well anyway. + AcceptableWithoutRecovery = + isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND); } else { // FIXME: We found a keyword. Suggest it, but don't provide a fix-it // because we aren't able to recover. + AcceptableWithoutRecovery = true; + } + + if (AcceptableWithRecovery || AcceptableWithoutRecovery) { + unsigned NoteID = (Corrected.getCorrectionDecl() && + isa<ImplicitParamDecl>(Corrected.getCorrectionDecl())) + ? diag::note_implicit_param_decl + : diag::note_previous_decl; if (SS.isEmpty()) - Diag(R.getNameLoc(), diagnostic_suggest) << Name << CorrectedQuotedStr; + diagnoseTypo(Corrected, PDiag(diagnostic_suggest) << Name, + PDiag(NoteID), AcceptableWithRecovery); else - Diag(R.getNameLoc(), diag::err_no_member_suggest) - << Name << computeDeclContext(SS, false) << droppedSpecifier - << CorrectedQuotedStr << SS.getRange(); - return true; + diagnoseTypo(Corrected, PDiag(diag::err_no_member_suggest) + << Name << computeDeclContext(SS, false) + << DroppedSpecifier << SS.getRange(), + PDiag(NoteID), AcceptableWithRecovery); + + // Tell the callee whether to try to recover. + return !AcceptableWithRecovery; } } R.clear(); @@ -3988,19 +3976,13 @@ Sema::ConvertArgumentsForCall(CallExpr *Call, Expr *Fn, *this, DeclarationNameInfo(FDecl->getDeclName(), Fn->getLocStart()), Args))) { - std::string CorrectedStr(TC.getAsString(getLangOpts())); - std::string CorrectedQuotedStr(TC.getQuoted(getLangOpts())); unsigned diag_id = MinArgs == NumArgsInProto && !Proto->isVariadic() ? diag::err_typecheck_call_too_few_args_suggest : diag::err_typecheck_call_too_few_args_at_least_suggest; - Diag(RParenLoc, diag_id) - << FnKind << MinArgs << static_cast<unsigned>(Args.size()) - << Fn->getSourceRange() << CorrectedQuotedStr - << FixItHint::CreateReplacement(TC.getCorrectionRange(), - CorrectedStr); - Diag(TC.getCorrectionDecl()->getLocStart(), - diag::note_previous_decl) << CorrectedQuotedStr; + diagnoseTypo(TC, PDiag(diag_id) << FnKind << MinArgs + << static_cast<unsigned>(Args.size()) + << Fn->getSourceRange()); } else if (MinArgs == 1 && FDecl && FDecl->getParamDecl(0)->getDeclName()) Diag(RParenLoc, MinArgs == NumArgsInProto && !Proto->isVariadic() ? diag::err_typecheck_call_too_few_args_one @@ -4034,20 +4016,15 @@ Sema::ConvertArgumentsForCall(CallExpr *Call, Expr *Fn, *this, DeclarationNameInfo(FDecl->getDeclName(), Fn->getLocStart()), Args))) { - std::string CorrectedStr(TC.getAsString(getLangOpts())); - std::string CorrectedQuotedStr(TC.getQuoted(getLangOpts())); unsigned diag_id = MinArgs == NumArgsInProto && !Proto->isVariadic() ? diag::err_typecheck_call_too_many_args_suggest : diag::err_typecheck_call_too_many_args_at_most_suggest; - Diag(Args[NumArgsInProto]->getLocStart(), diag_id) - << FnKind << NumArgsInProto << static_cast<unsigned>(Args.size()) - << Fn->getSourceRange() << CorrectedQuotedStr - << FixItHint::CreateReplacement(TC.getCorrectionRange(), - CorrectedStr); - Diag(TC.getCorrectionDecl()->getLocStart(), - diag::note_previous_decl) << CorrectedQuotedStr; - } else if (NumArgsInProto == 1 && FDecl && FDecl->getParamDecl(0)->getDeclName()) + diagnoseTypo(TC, PDiag(diag_id) << FnKind << NumArgsInProto + << static_cast<unsigned>(Args.size()) + << Fn->getSourceRange()); + } else if (NumArgsInProto == 1 && FDecl && + FDecl->getParamDecl(0)->getDeclName()) Diag(Args[NumArgsInProto]->getLocStart(), MinArgs == NumArgsInProto ? diag::err_typecheck_call_too_many_args_one diff --git a/lib/Sema/SemaExprMember.cpp b/lib/Sema/SemaExprMember.cpp index b0e69e6cc7..5970120d01 100644 --- a/lib/Sema/SemaExprMember.cpp +++ b/lib/Sema/SemaExprMember.cpp @@ -606,13 +606,6 @@ LookupMemberExprInRecord(Sema &SemaRef, LookupResult &R, &SS, Validator, DC); R.clear(); if (Corrected.isResolved() && !Corrected.isKeyword()) { - std::string CorrectedStr( - Corrected.getAsString(SemaRef.getLangOpts())); - std::string CorrectedQuotedStr( - Corrected.getQuoted(SemaRef.getLangOpts())); - bool droppedSpecifier = - Corrected.WillReplaceSpecifier() && Name.getAsString() == CorrectedStr; - R.setLookupName(Corrected.getCorrection()); for (TypoCorrection::decl_iterator DI = Corrected.begin(), DIEnd = Corrected.end(); @@ -621,19 +614,17 @@ LookupMemberExprInRecord(Sema &SemaRef, LookupResult &R, } R.resolveKind(); - SemaRef.Diag(R.getNameLoc(), diag::err_no_member_suggest) - << Name << DC << droppedSpecifier << CorrectedQuotedStr << SS.getRange() - << FixItHint::CreateReplacement(Corrected.getCorrectionRange(), - CorrectedStr); - // If we're typo-correcting to an overloaded name, we don't yet have enough // information to do overload resolution, so we don't know which previous // declaration to point to. - if (!Corrected.isOverloaded()) { - NamedDecl *ND = Corrected.getCorrectionDecl(); - SemaRef.Diag(ND->getLocation(), diag::note_previous_decl) - << ND->getDeclName(); - } + if (Corrected.isOverloaded()) + Corrected.setCorrectionDecl(0); + bool DroppedSpecifier = + Corrected.WillReplaceSpecifier() && + Name.getAsString() == Corrected.getAsString(SemaRef.getLangOpts()); + SemaRef.diagnoseTypo(Corrected, + SemaRef.PDiag(diag::err_no_member_suggest) + << Name << DC << DroppedSpecifier << SS.getRange()); } return false; @@ -1207,14 +1198,10 @@ Sema::LookupMemberExpr(LookupResult &R, ExprResult &BaseExpr, LookupMemberName, NULL, NULL, Validator, IDecl)) { IV = Corrected.getCorrectionDeclAs<ObjCIvarDecl>(); - Diag(R.getNameLoc(), - diag::err_typecheck_member_reference_ivar_suggest) - << IDecl->getDeclName() << MemberName << IV->getDeclName() - << FixItHint::CreateReplacement(R.getNameLoc(), - IV->getNameAsString()); - Diag(IV->getLocation(), diag::note_previous_decl) - << IV->getDeclName(); - + diagnoseTypo(Corrected, + PDiag(diag::err_typecheck_member_reference_ivar_suggest) + << IDecl->getDeclName() << MemberName); + // Figure out the class that declares the ivar. assert(!ClassDeclared); Decl *D = cast<Decl>(IV->getDeclContext()); diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp index e3e91d140a..39c2ec4186 100644 --- a/lib/Sema/SemaExprObjC.cpp +++ b/lib/Sema/SemaExprObjC.cpp @@ -1608,16 +1608,11 @@ HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT, // Attempt to correct for typos in property names. DeclFilterCCC<ObjCPropertyDecl> Validator; if (TypoCorrection Corrected = CorrectTypo( - DeclarationNameInfo(MemberName, MemberLoc), LookupOrdinaryName, NULL, - NULL, Validator, IFace, false, OPT)) { - ObjCPropertyDecl *Property = - Corrected.getCorrectionDeclAs<ObjCPropertyDecl>(); + DeclarationNameInfo(MemberName, MemberLoc), LookupOrdinaryName, NULL, + NULL, Validator, IFace, false, OPT)) { + diagnoseTypo(Corrected, PDiag(diag::err_property_not_found_suggest) + << MemberName << QualType(OPT, 0)); DeclarationName TypoResult = Corrected.getCorrection(); - Diag(MemberLoc, diag::err_property_not_found_suggest) - << MemberName << QualType(OPT, 0) << TypoResult - << FixItHint::CreateReplacement(MemberLoc, TypoResult.getAsString()); - Diag(Property->getLocation(), diag::note_previous_decl) - << Property->getDeclName(); return HandleExprPropertyRefExpr(OPT, BaseExpr, OpLoc, TypoResult, MemberLoc, SuperLoc, SuperType, Super); @@ -1855,28 +1850,22 @@ Sema::ObjCMessageKind Sema::getObjCMessageKind(Scope *S, if (Corrected.isKeyword()) { // If we've found the keyword "super" (the only keyword that would be // returned by CorrectTypo), this is a send to super. - Diag(NameLoc, diag::err_unknown_receiver_suggest) - << Name << Corrected.getCorrection() - << FixItHint::CreateReplacement(SourceRange(NameLoc), "super"); + diagnoseTypo(Corrected, + PDiag(diag::err_unknown_receiver_suggest) << Name); return ObjCSuperMessage; } else if (ObjCInterfaceDecl *Class = - Corrected.getCorrectionDeclAs<ObjCInterfaceDecl>()) { + Corrected.getCorrectionDeclAs<ObjCInterfaceDecl>()) { // If we found a declaration, correct when it refers to an Objective-C // class. - Diag(NameLoc, diag::err_unknown_receiver_suggest) - << Name << Corrected.getCorrection() - << FixItHint::CreateReplacement(SourceRange(NameLoc), - Class->getNameAsString()); - Diag(Class->getLocation(), diag::note_previous_decl) - << Corrected.getCorrection(); - + diagnoseTypo(Corrected, + PDiag(diag::err_unknown_receiver_suggest) << Name); QualType T = Context.getObjCInterfaceType(Class); TypeSourceInfo *TSInfo = Context.getTrivialTypeSourceInfo(T, NameLoc); ReceiverType = CreateParsedType(T, TSInfo); return ObjCClassMessage; } } - + // Fall back: let the parser try to parse it as an instance message. return ObjCInstanceMessage; } diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index 407255077d..2844351e51 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -1809,22 +1809,15 @@ InitListChecker::CheckDesignatedInitializer(const InitializedEntity &Entity, // Name lookup didn't find anything. Determine whether this // was a typo for another field name. FieldInitializerValidatorCCC Validator(RT->getDecl()); - TypoCorrection Corrected = SemaRef.CorrectTypo( - DeclarationNameInfo(FieldName, D->getFieldLoc()), - Sema::LookupMemberName, /*Scope=*/0, /*SS=*/0, Validator, - RT->getDecl()); - if (Corrected) { - std::string CorrectedStr( - Corrected.getAsString(SemaRef.getLangOpts())); - std::string CorrectedQuotedStr( - Corrected.getQuoted(SemaRef.getLangOpts())); + if (TypoCorrection Corrected = SemaRef.CorrectTypo( + DeclarationNameInfo(FieldName, D->getFieldLoc()), + Sema::LookupMemberName, /*Scope=*/ 0, /*SS=*/ 0, Validator, + RT->getDecl())) { + SemaRef.diagnoseTypo( + Corrected, + SemaRef.PDiag(diag::err_field_designator_unknown_suggest) + << FieldName << CurrentObjectType); ReplacementField = Corrected.getCorrectionDeclAs<FieldDecl>(); - SemaRef.Diag(D->getFieldLoc(), - diag::err_field_designator_unknown_suggest) - << FieldName << CurrentObjectType << CorrectedQuotedStr - << FixItHint::CreateReplacement(D->getFieldLoc(), CorrectedStr); - SemaRef.Diag(ReplacementField->getLocation(), - diag::note_previous_decl) << CorrectedQuotedStr; hadError = true; } else { SemaRef.Diag(D->getFieldLoc(), diag::err_field_designator_unknown) diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp index 3ad596c6b2..adda1b9479 100644 --- a/lib/Sema/SemaLookup.cpp +++ b/lib/Sema/SemaLookup.cpp @@ -4377,3 +4377,41 @@ bool FunctionCallFilterCCC::ValidateCandidate(const TypoCorrection &candidate) { } return false; } + +void Sema::diagnoseTypo(const TypoCorrection &Correction, + const PartialDiagnostic &TypoDiag, + bool ErrorRecovery) { + diagnoseTypo(Correction, TypoDiag, PDiag(diag::note_previous_decl), + ErrorRecovery); +} + +/// \brief Diagnose a successfully-corrected typo. Separated from the correction +/// itself to allow external validation of the result, etc. +/// +/// \param Correction The result of performing typo correction. +/// \param TypoDiag The diagnostic to produce. This will have the corrected +/// string added to it (and usually also a fixit). +/// \param PrevNote A note to use when indicating the location of the entity to +/// which we are correcting. Will have the correction string added to it. +/// \param ErrorRecovery If \c true (the default), the caller is going to +/// recover from the typo as if the corrected string had been typed. +/// In this case, \c PDiag must be an error, and we will attach a fixit +/// to it. +void Sema::diagnoseTypo(const TypoCorrection &Correction, + const PartialDiagnostic &TypoDiag, + const PartialDiagnostic &PrevNote, + bool ErrorRecovery) { + std::string CorrectedStr = Correction.getAsString(getLangOpts()); + std::string CorrectedQuotedStr = Correction.getQuoted(getLangOpts()); + FixItHint FixTypo = FixItHint::CreateReplacement( + Correction.getCorrectionRange(), CorrectedStr); + + Diag(Correction.getCorrectionRange().getBegin(), TypoDiag) + << CorrectedQuotedStr << (ErrorRecovery ? FixTypo : FixItHint()); + + NamedDecl *ChosenDecl = + Correction.isKeyword() ? 0 : Correction.getCorrectionDecl(); + if (PrevNote.getDiagID() && ChosenDecl) + Diag(ChosenDecl->getLocation(), PrevNote) + << CorrectedQuotedStr << (ErrorRecovery ? FixItHint() : FixTypo); +} diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp index 993eaba86e..09ecfe0909 100644 --- a/lib/Sema/SemaOpenMP.cpp +++ b/lib/Sema/SemaOpenMP.cpp @@ -58,30 +58,23 @@ ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, VarDecl *VD; if (!Lookup.isSingleResult()) { VarDeclFilterCCC Validator(*this); - TypoCorrection Corrected = CorrectTypo(Id, LookupOrdinaryName, CurScope, - 0, Validator); - std::string CorrectedStr = Corrected.getAsString(getLangOpts()); - std::string CorrectedQuotedStr = Corrected.getQuoted(getLangOpts()); - if (Lookup.empty()) { - if (Corrected.isResolved()) { - Diag(Id.getLoc(), diag::err_undeclared_var_use_suggest) - << Id.getName() << CorrectedQuotedStr - << FixItHint::CreateReplacement(Id.getLoc(), CorrectedStr); - } else { - Diag(Id.getLoc(), diag::err_undeclared_var_use) - << Id.getName(); - } + if (TypoCorrection Corrected = CorrectTypo(Id, LookupOrdinaryName, CurScope, + 0, Validator)) { + diagnoseTypo(Corrected, + PDiag(Lookup.empty()? diag::err_undeclared_var_use_suggest + : diag::err_omp_expected_var_arg_suggest) + << Id.getName()); + VD = Corrected.getCorrectionDeclAs<VarDecl>(); } else { - Diag(Id.getLoc(), diag::err_omp_expected_var_arg_suggest) - << Id.getName() << Corrected.isResolved() << CorrectedQuotedStr - << FixItHint::CreateReplacement(Id.getLoc(), CorrectedStr); + Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use + : diag::err_omp_expected_var_arg) + << Id.getName(); + return ExprError(); } - if (!Corrected.isResolved()) return ExprError(); - VD = Corrected.getCorrectionDeclAs<VarDecl>(); } else { if (!(VD = Lookup.getAsSingle<VarDecl>())) { - Diag(Id.getLoc(), diag::err_omp_expected_var_arg_suggest) - << Id.getName() << 0; + Diag(Id.getLoc(), diag::err_omp_expected_var_arg) + << Id.getName(); Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at); return ExprError(); } diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index c8298a93ba..e461eab777 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -331,24 +331,16 @@ void Sema::LookupTemplateName(LookupResult &Found, Found.addDecl(Corrected.getCorrectionDecl()); FilterAcceptableTemplateNames(Found); if (!Found.empty()) { - std::string CorrectedStr(Corrected.getAsString(getLangOpts())); - std::string CorrectedQuotedStr(Corrected.getQuoted(getLangOpts())); if (LookupCtx) { - bool droppedSpecifier = Corrected.WillReplaceSpecifier() && + std::string CorrectedStr(Corrected.getAsString(getLangOpts())); + bool DroppedSpecifier = Corrected.WillReplaceSpecifier() && Name.getAsString() == CorrectedStr; - Diag(Found.getNameLoc(), diag::err_no_member_template_suggest) - << Name << LookupCtx << droppedSpecifier << CorrectedQuotedStr - << SS.getRange() - << FixItHint::CreateReplacement(Corrected.getCorrectionRange(), - CorrectedStr); + diagnoseTypo(Corrected, PDiag(diag::err_no_member_template_suggest) + << Name << LookupCtx << DroppedSpecifier + << SS.getRange()); } else { - Diag(Found.getNameLoc(), diag::err_no_template_suggest) - << Name << CorrectedQuotedStr - << FixItHint::CreateReplacement(Found.getNameLoc(), CorrectedStr); + diagnoseTypo(Corrected, PDiag(diag::err_no_template_suggest) << Name); } - if (TemplateDecl *Template = Found.getAsSingle<TemplateDecl>()) - Diag(Template->getLocation(), diag::note_previous_decl) - << CorrectedQuotedStr; } } else { Found.setLookupName(Name); diff --git a/lib/Sema/SemaTemplateVariadic.cpp b/lib/Sema/SemaTemplateVariadic.cpp index 6298332dc1..78aa7f893a 100644 --- a/lib/Sema/SemaTemplateVariadic.cpp +++ b/lib/Sema/SemaTemplateVariadic.cpp @@ -819,16 +819,12 @@ ExprResult Sema::ActOnSizeofParameterPackExpr(Scope *S, if (TypoCorrection Corrected = CorrectTypo(R.getLookupNameInfo(), R.getLookupKind(), S, 0, Validator)) { - std::string CorrectedQuotedStr(Corrected.getQuoted(getLangOpts())); + diagnoseTypo(Corrected, + PDiag(diag::err_sizeof_pack_no_pack_name_suggest) << &Name, + PDiag(diag::note_parameter_pack_here)); ParameterPack = Corrected.getCorrectionDecl(); - Diag(NameLoc, diag::err_sizeof_pack_no_pack_name_suggest) - << &Name << CorrectedQuotedStr - << FixItHint::CreateReplacement( - NameLoc, Corrected.getAsString(getLangOpts())); - Diag(ParameterPack->getLocation(), diag::note_parameter_pack_here) - << CorrectedQuotedStr; } - + case LookupResult::FoundOverloaded: case LookupResult::FoundUnresolvedValue: break; diff --git a/test/OpenMP/threadprivate_messages.cpp b/test/OpenMP/threadprivate_messages.cpp index bfa596db34..a188a0b05d 100644 --- a/test/OpenMP/threadprivate_messages.cpp +++ b/test/OpenMP/threadprivate_messages.cpp @@ -33,7 +33,7 @@ int x, y; #pragma omp threadprivate(a,d) // expected-error {{'#pragma omp threadprivate' must precede all references to variable 'a'}} expected-error {{'#pragma omp threadprivate' must precede all references to variable 'd'}} #pragma omp threadprivate(d.a) // expected-error {{expected identifier}} #pragma omp threadprivate((float)a) // expected-error {{expected unqualified-id}} -int foa; +int foa; // expected-note {{'foa' declared here}} #pragma omp threadprivate(faa) // expected-error {{use of undeclared identifier 'faa'; did you mean 'foa'?}} #pragma omp threadprivate(foo) // expected-error {{'foo' is not a global variable, static local variable or static data member}} #pragma omp threadprivate (int a=2) // expected-error {{expected unqualified-id}} diff --git a/test/Parser/recovery.cpp b/test/Parser/recovery.cpp index 41845fb291..ac1be6a571 100644 --- a/test/Parser/recovery.cpp +++ b/test/Parser/recovery.cpp @@ -12,7 +12,7 @@ inline namespace Std { // expected-error {{cannot be reopened as inline}} int x; Std::Important y; -extenr "C" { // expected-error {{did you mean the keyword 'extern'}} +extenr "C" { // expected-error {{did you mean 'extern'}} void f(); } void g() { @@ -39,7 +39,7 @@ namespace N { int } // expected-error {{unqualified-id}} -strcut Uuuu { // expected-error {{did you mean the keyword 'struct'}} \ +strcut Uuuu { // expected-error {{did you mean 'struct'}} \ // expected-note {{'Uuuu' declared here}} } *u[3]; uuuu v; // expected-error {{did you mean 'Uuuu'}} diff --git a/test/Sema/builtins.c b/test/Sema/builtins.c index d525ac012e..33b0954381 100644 --- a/test/Sema/builtins.c +++ b/test/Sema/builtins.c @@ -2,7 +2,7 @@ // This test needs to set the target because it uses __builtin_ia32_vec_ext_v4si int test1(float a, int b) { - return __builtin_isless(a, b); + return __builtin_isless(a, b); // expected-note {{declared here}} } int test2(int a, int b) { return __builtin_islessequal(a, b); // expected-error {{floating point type}} diff --git a/test/SemaCXX/typo-correction-pt2.cpp b/test/SemaCXX/typo-correction-pt2.cpp index c79a869b5a..06f69d7186 100644 --- a/test/SemaCXX/typo-correction-pt2.cpp +++ b/test/SemaCXX/typo-correction-pt2.cpp @@ -16,11 +16,11 @@ void zif::nab(int) { } namespace TemplateFunction { -template <class T> // expected-note {{'::TemplateFunction::A' declared here}} -void A(T) { } +template <class T> +void A(T) { } // expected-note {{'::TemplateFunction::A' declared here}} -template <class T> // expected-note {{'::TemplateFunction::B' declared here}} -void B(T) { } +template <class T> +void B(T) { } // expected-note {{'::TemplateFunction::B' declared here}} class Foo { public: |