Clean up and document code modification hints.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@65641 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Basic/TokenKinds.cpp b/lib/Basic/TokenKinds.cpp
index 3d47863..4afeaf0 100644
--- a/lib/Basic/TokenKinds.cpp
+++ b/lib/Basic/TokenKinds.cpp
@@ -28,9 +28,7 @@
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/lib/Lex/Preprocessor.cpp b/lib/Lex/Preprocessor.cpp
index ccb179d..26777d9 100644
--- a/lib/Lex/Preprocessor.cpp
+++ b/lib/Lex/Preprocessor.cpp
@@ -265,7 +265,6 @@
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 @@
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/lib/Parse/ParseTemplate.cpp b/lib/Parse/ParseTemplate.cpp
index 0209d7b..2aeb182 100644
--- a/lib/Parse/ParseTemplate.cpp
+++ b/lib/Parse/ParseTemplate.cpp
@@ -445,7 +445,8 @@
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/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp
index 134f477..4398ef8 100644
--- a/lib/Parse/Parser.cpp
+++ b/lib/Parse/Parser.cpp
@@ -76,18 +76,17 @@
/// \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 @@
}
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/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index 97eb9be..5b2e89e 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -1617,7 +1617,7 @@
// 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());