Refactor all diagnosing of TypoCorrections through a common function, in

preparation for teaching this function how to diagnose a correction that
includes importing a module.

llvm-svn: 188602
This commit is contained in:
Richard Smith 2013-08-17 00:46:16 +00:00
parent 15a2fccb78
commit f9b1510576
20 changed files with 318 additions and 410 deletions

View File

@ -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<

View File

@ -367,6 +367,27 @@ public:
return PD;
}
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));

View File

@ -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,

View File

@ -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());

View File

@ -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 (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()) {
Diag(ND->getLocation(), diag::note_previous_decl) << CorrectedQuotedStr;
if (NamedDecl *ND = Corrected.getCorrectionDecl())
Found.addDecl(ND);
}
Found.setLookupName(Corrected.getCorrection());
} else {
Found.setLookupName(&Identifier);

View File

@ -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,8 +644,6 @@ 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
@ -688,17 +661,14 @@ 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.
@ -706,17 +676,14 @@ Corrected:
// 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,58 +6006,54 @@ static NamedDecl *DiagnoseInvalidRedeclaration(
}
}
bool wasRedeclaration = ExtraArgs.D.isRedeclaration();
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++ declaraction and hopefully
// 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()) {
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;
}
// 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;
}
}
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();
}
bool NewFDisConst = false;
if (CXXMethodDecl *NewMD = dyn_cast<CXXMethodDecl>(NewFD))
@ -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();

View File

@ -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,11 +2429,12 @@ 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
const CXXBaseSpecifier *BaseSpec = DirectBaseSpec ? DirectBaseSpec
: VirtualBaseSpec;
Diag(BaseSpec->getLocStart(),
diag::note_base_class_specified_here)
@ -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,19 +7184,13 @@ 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)
diagnoseTypo(Corrected, PDiag(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;
<< SS.getRange());
} else {
Diag(IdentLoc, diag::err_no_member)
<< NameInfo.getName() << LookupContext << SS.getRange();

View File

@ -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,
@ -986,21 +981,16 @@ Decl *Sema::ActOnStartClassImplementation(
// 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;
}

View File

@ -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;
@ -1800,61 +1802,47 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R,
switch (OCS.BestViableFunction(*this, R.getNameLoc(), Best)) {
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)) {
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.
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;
}
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

View File

@ -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,13 +1198,9 @@ 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);

View File

@ -1610,14 +1610,9 @@ HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT,
if (TypoCorrection Corrected = CorrectTypo(
DeclarationNameInfo(MemberName, MemberLoc), LookupOrdinaryName, NULL,
NULL, Validator, IFace, false, OPT)) {
ObjCPropertyDecl *Property =
Corrected.getCorrectionDeclAs<ObjCPropertyDecl>();
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,21 +1850,15 @@ 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>()) {
// 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);

View File

@ -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(
if (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()));
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)

View File

@ -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);
}

View File

@ -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();
}
} else {
Diag(Id.getLoc(), diag::err_omp_expected_var_arg_suggest)
<< Id.getName() << Corrected.isResolved() << CorrectedQuotedStr
<< FixItHint::CreateReplacement(Id.getLoc(), CorrectedStr);
}
if (!Corrected.isResolved()) return ExprError();
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(), Lookup.empty() ? diag::err_undeclared_var_use
: diag::err_omp_expected_var_arg)
<< Id.getName();
return ExprError();
}
} 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();
}

View File

@ -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);

View File

@ -819,14 +819,10 @@ 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:

View File

@ -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}}

View File

@ -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'}}

View File

@ -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}}

View File

@ -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: