aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/clang/lib/AST/RawCommentList.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/clang/lib/AST/RawCommentList.cpp')
-rw-r--r--contrib/llvm-project/clang/lib/AST/RawCommentList.cpp69
1 files changed, 53 insertions, 16 deletions
diff --git a/contrib/llvm-project/clang/lib/AST/RawCommentList.cpp b/contrib/llvm-project/clang/lib/AST/RawCommentList.cpp
index a8d15036cab9..dffa007b6588 100644
--- a/contrib/llvm-project/clang/lib/AST/RawCommentList.cpp
+++ b/contrib/llvm-project/clang/lib/AST/RawCommentList.cpp
@@ -16,6 +16,7 @@
#include "clang/AST/CommentSema.h"
#include "clang/Basic/CharInfo.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/Allocator.h"
using namespace clang;
@@ -140,8 +141,8 @@ RawComment::RawComment(const SourceManager &SourceMgr, SourceRange SR,
Kind = K.first;
IsTrailingComment |= K.second;
- IsAlmostTrailingComment = RawText.startswith("//<") ||
- RawText.startswith("/*<");
+ IsAlmostTrailingComment =
+ RawText.starts_with("//<") || RawText.starts_with("/*<");
} else {
Kind = RCK_Merged;
IsTrailingComment =
@@ -362,6 +363,24 @@ std::string RawComment::getFormattedText(const SourceManager &SourceMgr,
if (CommentText.empty())
return "";
+ std::string Result;
+ for (const RawComment::CommentLine &Line :
+ getFormattedLines(SourceMgr, Diags))
+ Result += Line.Text + "\n";
+
+ auto LastChar = Result.find_last_not_of('\n');
+ Result.erase(LastChar + 1, Result.size());
+
+ return Result;
+}
+
+std::vector<RawComment::CommentLine>
+RawComment::getFormattedLines(const SourceManager &SourceMgr,
+ DiagnosticsEngine &Diags) const {
+ llvm::StringRef CommentText = getRawText(SourceMgr);
+ if (CommentText.empty())
+ return {};
+
llvm::BumpPtrAllocator Allocator;
// We do not parse any commands, so CommentOptions are ignored by
// comments::Lexer. Therefore, we just use default-constructed options.
@@ -371,13 +390,23 @@ std::string RawComment::getFormattedText(const SourceManager &SourceMgr,
CommentText.begin(), CommentText.end(),
/*ParseCommands=*/false);
- std::string Result;
+ std::vector<RawComment::CommentLine> Result;
// A column number of the first non-whitespace token in the comment text.
// We skip whitespace up to this column, but keep the whitespace after this
// column. IndentColumn is calculated when lexing the first line and reused
// for the rest of lines.
unsigned IndentColumn = 0;
+ // Record the line number of the last processed comment line.
+ // For block-style comments, an extra newline token will be produced after
+ // the end-comment marker, e.g.:
+ // /** This is a multi-line comment block.
+ // The lexer will produce two newline tokens here > */
+ // previousLine will record the line number when we previously saw a newline
+ // token and recorded a comment line. If we see another newline token on the
+ // same line, don't record anything in between.
+ unsigned PreviousLine = 0;
+
// Processes one line of the comment and adds it to the result.
// Handles skipping the indent at the start of the line.
// Returns false when eof is reached and true otherwise.
@@ -389,9 +418,14 @@ std::string RawComment::getFormattedText(const SourceManager &SourceMgr,
if (Tok.is(comments::tok::eof))
return false;
if (Tok.is(comments::tok::newline)) {
- Result += "\n";
+ PresumedLoc Loc = SourceMgr.getPresumedLoc(Tok.getLocation());
+ if (Loc.getLine() != PreviousLine) {
+ Result.emplace_back("", Loc, Loc);
+ PreviousLine = Loc.getLine();
+ }
return true;
}
+ SmallString<124> Line;
llvm::StringRef TokText = L.getSpelling(Tok, SourceMgr);
bool LocInvalid = false;
unsigned TokColumn =
@@ -417,32 +451,35 @@ std::string RawComment::getFormattedText(const SourceManager &SourceMgr,
WhitespaceLen,
std::max<int>(static_cast<int>(IndentColumn) - TokColumn, 0));
llvm::StringRef Trimmed = TokText.drop_front(SkipLen);
- Result += Trimmed;
+ Line += Trimmed;
+ // Get the beginning location of the adjusted comment line.
+ PresumedLoc Begin =
+ SourceMgr.getPresumedLoc(Tok.getLocation().getLocWithOffset(SkipLen));
+
// Lex all tokens in the rest of the line.
for (L.lex(Tok); Tok.isNot(comments::tok::eof); L.lex(Tok)) {
if (Tok.is(comments::tok::newline)) {
- Result += "\n";
+ // Get the ending location of the comment line.
+ PresumedLoc End = SourceMgr.getPresumedLoc(Tok.getLocation());
+ if (End.getLine() != PreviousLine) {
+ Result.emplace_back(Line, Begin, End);
+ PreviousLine = End.getLine();
+ }
return true;
}
- Result += L.getSpelling(Tok, SourceMgr);
+ Line += L.getSpelling(Tok, SourceMgr);
}
+ PresumedLoc End = SourceMgr.getPresumedLoc(Tok.getLocation());
+ Result.emplace_back(Line, Begin, End);
// We've reached the end of file token.
return false;
};
- auto DropTrailingNewLines = [](std::string &Str) {
- while (!Str.empty() && Str.back() == '\n')
- Str.pop_back();
- };
-
// Process first line separately to remember indent for the following lines.
- if (!LexLine(/*IsFirstLine=*/true)) {
- DropTrailingNewLines(Result);
+ if (!LexLine(/*IsFirstLine=*/true))
return Result;
- }
// Process the rest of the lines.
while (LexLine(/*IsFirstLine=*/false))
;
- DropTrailingNewLines(Result);
return Result;
}