18#include "llvm/ADT/STLExtras.h"
19#include "llvm/ADT/StringExtras.h"
20#include "llvm/Support/Allocator.h"
26std::pair<RawComment::CommentKind, bool> getCommentKind(StringRef Comment,
27 bool ParseAllComments) {
28 const size_t MinCommentLength = ParseAllComments ? 2 : 3;
29 if ((Comment.size() < MinCommentLength) || Comment[0] !=
'/')
33 if (Comment[1] ==
'/') {
34 if (Comment.size() < 3)
37 if (Comment[2] ==
'/')
39 else if (Comment[2] ==
'!')
44 assert(Comment.size() >= 4);
48 if (Comment[1] !=
'*' ||
49 Comment[Comment.size() - 2] !=
'*' ||
50 Comment[Comment.size() - 1] !=
'/')
53 if (Comment[2] ==
'*')
55 else if (Comment[2] ==
'!')
60 const bool TrailingComment = (Comment.size() > 3) && (Comment[3] ==
'<');
61 return std::make_pair(K, TrailingComment);
64bool mergedCommentIsTrailingComment(StringRef Comment) {
65 return (Comment.size() > 3) && (Comment[3] ==
'<');
75 unsigned C1 =
SM.getPresumedColumnNumber(L1, &
Invalid);
77 unsigned C2 =
SM.getPresumedColumnNumber(L2, &
Invalid);
93 for (
unsigned I =
P; I != 0; --I) {
94 char C = Buffer[I - 1];
112 Range(SR), RawTextValid(
false), BriefTextValid(
false),
114 IsAlmostTrailingComment(
false) {
122 std::pair<CommentKind, bool> K =
128 unsigned BeginOffset;
129 std::tie(BeginFileID, BeginOffset) =
131 if (BeginOffset != 0) {
142 IsTrailingComment |= K.second;
144 IsAlmostTrailingComment = RawText.startswith(
"//<") ||
145 RawText.startswith(
"/*<");
149 IsTrailingComment || mergedCommentIsTrailingComment(RawText);
153StringRef RawComment::getRawTextSlow(
const SourceManager &SourceMgr)
const {
156 unsigned BeginOffset;
159 std::tie(BeginFileID, BeginOffset) =
163 const unsigned Length = EndOffset - BeginOffset;
168 assert(BeginFileID == EndFileID);
171 const char *BufferStart = SourceMgr.
getBufferData(BeginFileID,
176 return StringRef(BufferStart + BeginOffset, Length);
179const char *RawComment::extractBriefText(
const ASTContext &Context)
const {
186 llvm::BumpPtrAllocator Allocator;
191 RawText.begin(), RawText.end());
194 const std::string
Result =
P.Parse();
195 const unsigned BriefTextLength =
Result.size();
196 char *BriefTextPtr =
new (Context)
char[BriefTextLength + 1];
197 memcpy(BriefTextPtr,
Result.c_str(), BriefTextLength + 1);
198 BriefText = BriefTextPtr;
199 BriefTextValid =
true;
206 const Decl *D)
const {
213 RawText.begin(), RawText.end());
223 return P.parseFullComment();
228 unsigned MaxNewlinesAllowed) {
229 std::pair<FileID, unsigned> Loc1Info =
SM.getDecomposedLoc(Loc1);
230 std::pair<FileID, unsigned> Loc2Info =
SM.getDecomposedLoc(Loc2);
233 if (Loc1Info.first != Loc2Info.first)
237 const char *Buffer =
SM.getBufferData(Loc1Info.first, &
Invalid).data();
241 unsigned NumNewlines = 0;
242 assert(Loc1Info.second <= Loc2Info.second &&
"Loc1 after Loc2!");
244 for (
unsigned I = Loc1Info.second; I != Loc2Info.second; ++I) {
259 if (NumNewlines > MaxNewlinesAllowed)
263 if (I + 1 != Loc2Info.second &&
264 (Buffer[I + 1] ==
'\n' || Buffer[I + 1] ==
'\r') &&
265 Buffer[I] != Buffer[I + 1])
276 llvm::BumpPtrAllocator &Allocator) {
284 std::pair<FileID, unsigned> Loc =
287 const FileID CommentFile = Loc.first;
288 const unsigned CommentOffset = Loc.second;
292 if (OrderedComments[CommentFile].
empty()) {
293 OrderedComments[CommentFile][CommentOffset] =
298 const RawComment &C1 = *OrderedComments[CommentFile].rbegin()->second;
317 commentsStartOnSameColumn(SourceMgr, C1, C2))) &&
321 *OrderedComments[CommentFile].rbegin()->second =
322 RawComment(SourceMgr, MergedRange, CommentOpts,
true);
324 OrderedComments[CommentFile][CommentOffset] =
329const std::map<unsigned, RawComment *> *
331 auto CommentsInFile = OrderedComments.find(
File);
332 if (CommentsInFile == OrderedComments.end())
335 return &CommentsInFile->second;
341 unsigned Offset)
const {
342 auto Cached = CommentBeginLine.find(
C);
343 if (Cached != CommentBeginLine.end())
344 return Cached->second;
346 CommentBeginLine[
C] =
Line;
351 auto Cached = CommentEndOffset.find(
C);
352 if (Cached != CommentEndOffset.end())
353 return Cached->second;
354 const unsigned Offset =
356 CommentEndOffset[
C] = Offset;
362 llvm::StringRef CommentText =
getRawText(SourceMgr);
363 if (CommentText.empty())
371 auto LastChar =
Result.find_last_not_of(
'\n');
377std::vector<RawComment::CommentLine>
380 llvm::StringRef CommentText =
getRawText(SourceMgr);
381 if (CommentText.empty())
384 llvm::BumpPtrAllocator Allocator;
390 CommentText.begin(), CommentText.end(),
393 std::vector<RawComment::CommentLine>
Result;
398 unsigned IndentColumn = 0;
408 unsigned PreviousLine = 0;
413 auto LexLine = [&](
bool IsFirstLine) ->
bool {
422 if (Loc.
getLine() != PreviousLine) {
423 Result.emplace_back(
"", Loc, Loc);
429 llvm::StringRef TokText = L.
getSpelling(Tok, SourceMgr);
430 bool LocInvalid =
false;
433 assert(!LocInvalid &&
"getFormattedText for invalid location");
436 size_t WhitespaceLen = TokText.find_first_not_of(
" \t");
437 if (WhitespaceLen == StringRef::npos)
438 WhitespaceLen = TokText.size();
442 IndentColumn = TokColumn + WhitespaceLen;
452 std::max<int>(
static_cast<int>(IndentColumn) - TokColumn, 0));
453 llvm::StringRef Trimmed = TokText.drop_front(SkipLen);
464 if (End.getLine() != PreviousLine) {
466 PreviousLine = End.getLine();
482 while (LexLine(
false))
Defines the clang::ASTContext interface.
__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
SourceManager & getSourceManager()
comments::CommandTraits & getCommentCommandTraits() const
llvm::BumpPtrAllocator & getAllocator() const
DiagnosticsEngine & getDiagnostics() const
Decl - This represents one declaration (or definition), e.g.
Concrete class used by the front-end to report problems and issues.
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
Represents an unpacked "presumed" location which can be presented to the user.
unsigned getLine() const
Return the presumed line number of this location.
Encodes a location in the source.
SourceLocation getLocWithOffset(IntTy Offset) const
Return a source location with the specified offset from this SourceLocation.
This class handles loading and caching of source files into memory.
PresumedLoc getPresumedLoc(SourceLocation Loc, bool UseLineDirectives=true) const
Returns the "presumed" location of a SourceLocation specifies.
StringRef getBufferData(FileID FID, bool *Invalid=nullptr) const
Return a StringRef to the source buffer data for the specified FileID.
unsigned getLineNumber(FileID FID, unsigned FilePos, bool *Invalid=nullptr) const
Given a SourceLocation, return the spelling line number for the position indicated.
unsigned getSpellingColumnNumber(SourceLocation Loc, bool *Invalid=nullptr) const
std::pair< FileID, unsigned > getDecomposedLoc(SourceLocation Loc) const
Decompose the specified location into a raw FileID + Offset pair.
A trivial tuple used to represent a source range.
SourceLocation getEnd() const
SourceLocation getBegin() const
LLVM_READONLY bool isVerticalWhitespace(unsigned char c)
Returns true if this character is vertical ASCII whitespace: '\n', '\r'.
LLVM_READONLY bool isHorizontalWhitespace(unsigned char c)
Returns true if this character is horizontal ASCII whitespace: ' ', '\t', '\f', '\v'.
@ Result
The result type of a method or function.