diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Basic/TokenKinds.cpp | 4 | ||||
-rw-r--r-- | clang/lib/Lex/Preprocessor.cpp | 20 | ||||
-rw-r--r-- | clang/lib/Parse/ParseTemplate.cpp | 3 | ||||
-rw-r--r-- | clang/lib/Parse/Parser.cpp | 20 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplate.cpp | 2 |
5 files changed, 32 insertions, 17 deletions
diff --git a/clang/lib/Basic/TokenKinds.cpp b/clang/lib/Basic/TokenKinds.cpp index 3d47863e857..4afeaf01b77 100644 --- a/clang/lib/Basic/TokenKinds.cpp +++ b/clang/lib/Basic/TokenKinds.cpp @@ -28,9 +28,7 @@ const char *tok::getTokenName(enum TokenKind Kind) { return TokNames[Kind]; } -/// \brief Determines the spelling of simple punctuation tokens like -/// '!' or '%', and returns NULL for literal and annotation tokens. -const char *tok::getTokenSpelling(enum TokenKind Kind) { +const char *tok::getTokenSimpleSpelling(enum TokenKind Kind) { switch (Kind) { case tok::l_square: return "["; case tok::r_square: return "]"; diff --git a/clang/lib/Lex/Preprocessor.cpp b/clang/lib/Lex/Preprocessor.cpp index ccb179d1e4c..26777d9170b 100644 --- a/clang/lib/Lex/Preprocessor.cpp +++ b/clang/lib/Lex/Preprocessor.cpp @@ -265,7 +265,6 @@ unsigned Preprocessor::getSpelling(const Token &Tok, return OutBuf-Buffer; } - /// CreateString - Plop the specified string into a scratch buffer and return a /// location for it. If specified, the source location provides a source /// location for the token. @@ -321,6 +320,25 @@ SourceLocation Preprocessor::AdvanceToTokenCharacter(SourceLocation TokStart, return TokStart.getFileLocWithOffset(PhysOffset); } +/// \brief Computes the source location just past the end of the +/// token at this source location. +/// +/// This routine can be used to produce a source location that +/// points just past the end of the token referenced by \p Loc, and +/// is generally used when a diagnostic needs to point just after a +/// token where it expected something different that it received. If +/// the returned source location would not be meaningful (e.g., if +/// it points into a macro), this routine returns an invalid +/// source location. +SourceLocation Preprocessor::getLocForEndOfToken(SourceLocation Loc) { + if (Loc.isInvalid() || !Loc.isFileID()) + return SourceLocation(); + + unsigned Len = Lexer::MeasureTokenLength(Loc, getSourceManager()); + return AdvanceToTokenCharacter(Loc, Len); +} + + //===----------------------------------------------------------------------===// // Preprocessor Initialization Methods diff --git a/clang/lib/Parse/ParseTemplate.cpp b/clang/lib/Parse/ParseTemplate.cpp index 0209d7b0ab5..2aeb182dbdf 100644 --- a/clang/lib/Parse/ParseTemplate.cpp +++ b/clang/lib/Parse/ParseTemplate.cpp @@ -445,7 +445,8 @@ Parser::ParseTemplateIdAfterTemplateName(DeclTy *Template, ReplaceStr = "> > "; Diag(Tok.getLocation(), diag::err_two_right_angle_brackets_need_space) - << CodeReplacementHint(SourceRange(Tok.getLocation()), ReplaceStr); + << CodeModificationHint::CreateReplacement( + SourceRange(Tok.getLocation()), ReplaceStr); } Tok.setKind(tok::greater); diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp index 134f477634d..4398ef8ea9c 100644 --- a/clang/lib/Parse/Parser.cpp +++ b/clang/lib/Parse/Parser.cpp @@ -76,18 +76,17 @@ DiagnosticBuilder Parser::Diag(const Token &Tok, unsigned DiagID) { /// \param ParenRange Source range enclosing code that should be parenthesized. void Parser::SuggestParentheses(SourceLocation Loc, unsigned DK, SourceRange ParenRange) { - if (!ParenRange.getEnd().isFileID()) { + SourceLocation EndLoc = PP.getLocForEndOfToken(ParenRange.getEnd()); + if (!ParenRange.getEnd().isFileID() || EndLoc.isInvalid()) { // We can't display the parentheses, so just dig the // warning/error and return. Diag(Loc, DK); return; } - unsigned Len = Lexer::MeasureTokenLength(ParenRange.getEnd(), - PP.getSourceManager()); Diag(Loc, DK) - << CodeInsertionHint(ParenRange.getBegin(), "(") - << CodeInsertionHint(ParenRange.getEnd().getFileLocWithOffset(Len), ")"); + << CodeModificationHint::CreateInsertion(ParenRange.getBegin(), "(") + << CodeModificationHint::CreateInsertion(EndLoc, ")"); } /// MatchRHSPunctuation - For punctuation with a LHS and RHS (e.g. '['/']'), @@ -131,14 +130,13 @@ bool Parser::ExpectAndConsume(tok::TokenKind ExpectedTok, unsigned DiagID, } const char *Spelling = 0; - if (PrevTokLocation.isValid() && PrevTokLocation.isFileID() && - (Spelling = tok::getTokenSpelling(ExpectedTok))) { + SourceLocation EndLoc = PP.getLocForEndOfToken(PrevTokLocation); + if (EndLoc.isValid() && + (Spelling = tok::getTokenSimpleSpelling(ExpectedTok))) { // Show what code to insert to fix this problem. - SourceLocation DiagLoc - = PrevTokLocation.getFileLocWithOffset(strlen(Spelling)); - Diag(DiagLoc, DiagID) + Diag(EndLoc, DiagID) << Msg - << CodeInsertionHint(DiagLoc, Spelling); + << CodeModificationHint::CreateInsertion(EndLoc, Spelling); } else Diag(Tok, DiagID) << Msg; diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 97eb9be36cc..5b2e89e8b0d 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -1617,7 +1617,7 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, TagKind TK, // template<> headers. if (TemplateParameterLists.size() == 0) Diag(KWLoc, diag::err_template_spec_needs_header) - << CodeInsertionHint(KWLoc, "template<> "); + << CodeModificationHint::CreateInsertion(KWLoc, "template<> "); else { TemplateParameterList *TemplateParams = static_cast<TemplateParameterList*>(*TemplateParameterLists.get()); |