diff options
Diffstat (limited to 'lib/Parse/ParseStmt.cpp')
-rw-r--r-- | lib/Parse/ParseStmt.cpp | 105 |
1 files changed, 24 insertions, 81 deletions
diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp index df9b996aa3..0716f6f901 100644 --- a/lib/Parse/ParseStmt.cpp +++ b/lib/Parse/ParseStmt.cpp @@ -17,6 +17,7 @@ #include "clang/Sema/DeclSpec.h" #include "clang/Sema/PrettyDeclStackTrace.h" #include "clang/Sema/Scope.h" +#include "clang/Sema/TypoCorrection.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/PrettyStackTrace.h" #include "clang/Basic/SourceManager.h" @@ -130,96 +131,38 @@ Retry: return ParseLabeledStatement(Attrs); } + // Look up the identifier, and typo-correct it to a keyword if it's not + // found. if (Next.isNot(tok::coloncolon)) { - CXXScopeSpec SS; - IdentifierInfo *Name = Tok.getIdentifierInfo(); - SourceLocation NameLoc = Tok.getLocation(); - - if (getLangOpts().CPlusPlus) - CheckForTemplateAndDigraph(Next, ParsedType(), - /*EnteringContext=*/false, *Name, SS); - - Sema::NameClassification Classification - = Actions.ClassifyName(getCurScope(), SS, Name, NameLoc, Next); - switch (Classification.getKind()) { - case Sema::NC_Keyword: - // The identifier was corrected to a keyword. Update the token - // to this keyword, and try again. - if (Name->getTokenID() != tok::identifier) { - Tok.setIdentifierInfo(Name); - Tok.setKind(Name->getTokenID()); - goto Retry; - } - - // Fall through via the normal error path. - // FIXME: This seems like it could only happen for context-sensitive - // keywords. - - case Sema::NC_Error: + // Try to limit which sets of keywords should be included in typo + // correction based on what the next token is. + // FIXME: Pass the next token into the CorrectionCandidateCallback and + // do this filtering in a more fine-grained manner. + CorrectionCandidateCallback DefaultValidator; + DefaultValidator.WantTypeSpecifiers = + Next.is(tok::l_paren) || Next.is(tok::less) || + Next.is(tok::identifier) || Next.is(tok::star) || + Next.is(tok::amp) || Next.is(tok::l_square); + DefaultValidator.WantExpressionKeywords = + Next.is(tok::l_paren) || Next.is(tok::identifier) || + Next.is(tok::arrow) || Next.is(tok::period); + DefaultValidator.WantRemainingKeywords = + Next.is(tok::l_paren) || Next.is(tok::semi) || + Next.is(tok::identifier) || Next.is(tok::l_brace); + DefaultValidator.WantCXXNamedCasts = false; + if (TryAnnotateName(/*IsAddressOfOperand*/false, &DefaultValidator) + == ANK_Error) { // Handle errors here by skipping up to the next semicolon or '}', and // eat the semicolon if that's what stopped us. SkipUntil(tok::r_brace, /*StopAtSemi=*/true, /*DontConsume=*/true); if (Tok.is(tok::semi)) ConsumeToken(); return StmtError(); - - case Sema::NC_Unknown: - // Either we don't know anything about this identifier, or we know that - // we're in a syntactic context we haven't handled yet. - break; - - case Sema::NC_Type: - Tok.setKind(tok::annot_typename); - setTypeAnnotation(Tok, Classification.getType()); - Tok.setAnnotationEndLoc(NameLoc); - PP.AnnotateCachedTokens(Tok); - break; - - case Sema::NC_Expression: - Tok.setKind(tok::annot_primary_expr); - setExprAnnotation(Tok, Classification.getExpression()); - Tok.setAnnotationEndLoc(NameLoc); - PP.AnnotateCachedTokens(Tok); - break; - - case Sema::NC_TypeTemplate: - case Sema::NC_FunctionTemplate: { - ConsumeToken(); // the identifier - UnqualifiedId Id; - Id.setIdentifier(Name, NameLoc); - if (AnnotateTemplateIdToken( - TemplateTy::make(Classification.getTemplateName()), - Classification.getTemplateNameKind(), - SS, SourceLocation(), Id, - /*AllowTypeAnnotation=*/false)) { - // Handle errors here by skipping up to the next semicolon or '}', and - // eat the semicolon if that's what stopped us. - SkipUntil(tok::r_brace, /*StopAtSemi=*/true, /*DontConsume=*/true); - if (Tok.is(tok::semi)) - ConsumeToken(); - return StmtError(); - } - - // If the next token is '::', jump right into parsing a - // nested-name-specifier. We don't want to leave the template-id - // hanging. - if (NextToken().is(tok::coloncolon) && TryAnnotateCXXScopeToken(false)){ - // Handle errors here by skipping up to the next semicolon or '}', and - // eat the semicolon if that's what stopped us. - SkipUntil(tok::r_brace, /*StopAtSemi=*/true, /*DontConsume=*/true); - if (Tok.is(tok::semi)) - ConsumeToken(); - return StmtError(); - } - - // We've annotated a template-id, so try again now. - goto Retry; } - case Sema::NC_NestedNameSpecifier: - // FIXME: Implement this! - break; - } + // If the identifier was typo-corrected, try again. + if (Tok.isNot(tok::identifier)) + goto Retry; } // Fall through |