forked from OSchip/llvm-project
Recover when correcting an unknown type name to a keyword like "struct".
llvm-svn: 158573
This commit is contained in:
parent
237c7d33b9
commit
b5b17fe9fc
|
@ -1124,7 +1124,7 @@ public:
|
|||
IdentifierInfo **CorrectedII = 0);
|
||||
TypeSpecifierType isTagName(IdentifierInfo &II, Scope *S);
|
||||
bool isMicrosoftMissingTypename(const CXXScopeSpec *SS, Scope *S);
|
||||
bool DiagnoseUnknownTypeName(const IdentifierInfo &II,
|
||||
bool DiagnoseUnknownTypeName(IdentifierInfo *&II,
|
||||
SourceLocation IILoc,
|
||||
Scope *S,
|
||||
CXXScopeSpec *SS,
|
||||
|
|
|
@ -1751,8 +1751,8 @@ bool Parser::ParseImplicitInt(DeclSpec &DS, CXXScopeSpec *SS,
|
|||
// This is almost certainly an invalid type name. Let the action emit a
|
||||
// diagnostic and attempt to recover.
|
||||
ParsedType T;
|
||||
if (Actions.DiagnoseUnknownTypeName(*Tok.getIdentifierInfo(), Loc,
|
||||
getCurScope(), SS, T)) {
|
||||
IdentifierInfo *II = Tok.getIdentifierInfo();
|
||||
if (Actions.DiagnoseUnknownTypeName(II, Loc, getCurScope(), SS, T)) {
|
||||
// The action emitted a diagnostic, so we don't have to.
|
||||
if (T) {
|
||||
// The action has suggested that the type T could be used. Set that as
|
||||
|
@ -1763,7 +1763,11 @@ bool Parser::ParseImplicitInt(DeclSpec &DS, CXXScopeSpec *SS,
|
|||
DS.SetTypeSpecType(DeclSpec::TST_typename, Loc, PrevSpec, DiagID, T);
|
||||
DS.SetRangeEnd(Tok.getLocation());
|
||||
ConsumeToken();
|
||||
|
||||
// There may be other declaration specifiers after this.
|
||||
return true;
|
||||
} else if (II != Tok.getIdentifierInfo()) {
|
||||
// If no type was suggested, the correction is to a keyword
|
||||
Tok.setKind(II->getTokenID());
|
||||
// There may be other declaration specifiers after this.
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -395,7 +395,7 @@ bool Sema::isMicrosoftMissingTypename(const CXXScopeSpec *SS, Scope *S) {
|
|||
return CurContext->isFunctionOrMethod() || S->isFunctionPrototypeScope();
|
||||
}
|
||||
|
||||
bool Sema::DiagnoseUnknownTypeName(const IdentifierInfo &II,
|
||||
bool Sema::DiagnoseUnknownTypeName(IdentifierInfo *&II,
|
||||
SourceLocation IILoc,
|
||||
Scope *S,
|
||||
CXXScopeSpec *SS,
|
||||
|
@ -406,7 +406,7 @@ bool Sema::DiagnoseUnknownTypeName(const IdentifierInfo &II,
|
|||
// There may have been a typo in the name of the type. Look up typo
|
||||
// results, in case we have something that we can suggest.
|
||||
TypeNameValidatorCCC Validator(false);
|
||||
if (TypoCorrection Corrected = CorrectTypo(DeclarationNameInfo(&II, IILoc),
|
||||
if (TypoCorrection Corrected = CorrectTypo(DeclarationNameInfo(II, IILoc),
|
||||
LookupOrdinaryName, S, SS,
|
||||
Validator)) {
|
||||
std::string CorrectedStr(Corrected.getAsString(getLangOpts()));
|
||||
|
@ -414,19 +414,23 @@ bool Sema::DiagnoseUnknownTypeName(const IdentifierInfo &II,
|
|||
|
||||
if (Corrected.isKeyword()) {
|
||||
// We corrected to a keyword.
|
||||
// FIXME: Actually recover with the keyword we suggest, and emit a fix-it.
|
||||
IdentifierInfo *NewII = Corrected.getCorrectionAsIdentifierInfo();
|
||||
if (!isSimpleTypeSpecifier(NewII->getTokenID()))
|
||||
CorrectedQuotedStr = "the keyword " + CorrectedQuotedStr;
|
||||
Diag(IILoc, diag::err_unknown_typename_suggest)
|
||||
<< &II << CorrectedQuotedStr;
|
||||
<< II << CorrectedQuotedStr
|
||||
<< FixItHint::CreateReplacement(SourceRange(IILoc), CorrectedStr);
|
||||
II = NewII;
|
||||
} 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
|
||||
<< II << CorrectedQuotedStr
|
||||
<< FixItHint::CreateReplacement(SourceRange(IILoc), CorrectedStr);
|
||||
else if (DeclContext *DC = computeDeclContext(*SS, false))
|
||||
Diag(IILoc, diag::err_unknown_nested_typename_suggest)
|
||||
<< &II << DC << CorrectedQuotedStr << SS->getRange()
|
||||
<< II << DC << CorrectedQuotedStr << SS->getRange()
|
||||
<< FixItHint::CreateReplacement(SourceRange(IILoc), CorrectedStr);
|
||||
else
|
||||
llvm_unreachable("could not have corrected a typo here");
|
||||
|
@ -445,7 +449,7 @@ bool Sema::DiagnoseUnknownTypeName(const IdentifierInfo &II,
|
|||
if (getLangOpts().CPlusPlus) {
|
||||
// See if II is a class template that the user forgot to pass arguments to.
|
||||
UnqualifiedId Name;
|
||||
Name.setIdentifier(&II, IILoc);
|
||||
Name.setIdentifier(II, IILoc);
|
||||
CXXScopeSpec EmptySS;
|
||||
TemplateTy TemplateResult;
|
||||
bool MemberOfUnknownSpecialization;
|
||||
|
@ -466,21 +470,21 @@ bool Sema::DiagnoseUnknownTypeName(const IdentifierInfo &II,
|
|||
// (struct, union, enum) from Parser::ParseImplicitInt here, instead?
|
||||
|
||||
if (!SS || (!SS->isSet() && !SS->isInvalid()))
|
||||
Diag(IILoc, diag::err_unknown_typename) << &II;
|
||||
Diag(IILoc, diag::err_unknown_typename) << II;
|
||||
else if (DeclContext *DC = computeDeclContext(*SS, false))
|
||||
Diag(IILoc, diag::err_typename_nested_not_found)
|
||||
<< &II << DC << SS->getRange();
|
||||
<< II << DC << SS->getRange();
|
||||
else if (isDependentScopeSpecifier(*SS)) {
|
||||
unsigned DiagID = diag::err_typename_missing;
|
||||
if (getLangOpts().MicrosoftMode && isMicrosoftMissingTypename(SS, S))
|
||||
DiagID = diag::warn_typename_missing;
|
||||
|
||||
Diag(SS->getRange().getBegin(), DiagID)
|
||||
<< (NestedNameSpecifier *)SS->getScopeRep() << II.getName()
|
||||
<< (NestedNameSpecifier *)SS->getScopeRep() << II->getName()
|
||||
<< SourceRange(SS->getRange().getBegin(), IILoc)
|
||||
<< FixItHint::CreateInsertion(SS->getRange().getBegin(), "typename ");
|
||||
SuggestedType = ActOnTypenameType(S, SourceLocation(), *SS, II, IILoc)
|
||||
.get();
|
||||
SuggestedType = ActOnTypenameType(S, SourceLocation(),
|
||||
*SS, *II, IILoc).get();
|
||||
} else {
|
||||
assert(SS && SS->isInvalid() &&
|
||||
"Invalid scope specifier has already been diagnosed");
|
||||
|
|
|
@ -12,13 +12,12 @@ inline namespace Std { // expected-error {{cannot be reopened as inline}}
|
|||
int x;
|
||||
Std::Important y;
|
||||
|
||||
// FIXME: Recover as if the typo correction were applied.
|
||||
extenr "C" { // expected-error {{did you mean 'extern'}} expected-error {{unqualified-id}}
|
||||
extenr "C" { // expected-error {{did you mean the keyword 'extern'}}
|
||||
void f();
|
||||
}
|
||||
void g() {
|
||||
z = 1; // expected-error {{undeclared}}
|
||||
f(); // expected-error {{undeclared}}
|
||||
f();
|
||||
}
|
||||
|
||||
struct S {
|
||||
|
@ -37,6 +36,7 @@ namespace N {
|
|||
int
|
||||
} // expected-error {{unqualified-id}}
|
||||
|
||||
// FIXME: Recover as if the typo correction were applied.
|
||||
strcut U { // expected-error {{did you mean 'struct'}}
|
||||
} *u[3]; // expected-error {{expected ';'}}
|
||||
strcut Uuuu { // expected-error {{did you mean the keyword 'struct'}} \
|
||||
// expected-note {{'Uuuu' declared here}}
|
||||
} *u[3];
|
||||
uuuu v; // expected-error {{did you mean 'Uuuu'}}
|
||||
|
|
Loading…
Reference in New Issue