summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td13
-rw-r--r--include/clang/Basic/PartialDiagnostic.h21
-rw-r--r--include/clang/Sema/Sema.h9
-rw-r--r--include/clang/Sema/TypoCorrection.h4
-rw-r--r--lib/Sema/SemaCXXScopeSpec.cpp38
-rw-r--r--lib/Sema/SemaDecl.cpp215
-rw-r--r--lib/Sema/SemaDeclCXX.cpp61
-rw-r--r--lib/Sema/SemaDeclObjC.cpp44
-rw-r--r--lib/Sema/SemaExpr.cpp117
-rw-r--r--lib/Sema/SemaExprMember.cpp37
-rw-r--r--lib/Sema/SemaExprObjC.cpp31
-rw-r--r--lib/Sema/SemaInit.cpp23
-rw-r--r--lib/Sema/SemaLookup.cpp38
-rw-r--r--lib/Sema/SemaOpenMP.cpp33
-rw-r--r--lib/Sema/SemaTemplate.cpp20
-rw-r--r--lib/Sema/SemaTemplateVariadic.cpp12
-rw-r--r--test/OpenMP/threadprivate_messages.cpp2
-rw-r--r--test/Parser/recovery.cpp4
-rw-r--r--test/Sema/builtins.c2
-rw-r--r--test/SemaCXX/typo-correction-pt2.cpp8
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: