18#include "llvm/Support/Allocator.h"
24std::pair<RawComment::CommentKind, bool> getCommentKind(StringRef Comment,
25 bool ParseAllComments) {
26 const size_t MinCommentLength = ParseAllComments ? 2 : 3;
27 if ((Comment.size() < MinCommentLength) || Comment[0] !=
'/')
31 if (Comment[1] ==
'/') {
32 if (Comment.size() < 3)
35 if (Comment[2] ==
'/')
37 else if (Comment[2] ==
'!')
42 assert(Comment.size() >= 4);
46 if (Comment[1] !=
'*' ||
47 Comment[Comment.size() - 2] !=
'*' ||
48 Comment[Comment.size() - 1] !=
'/')
51 if (Comment[2] ==
'*')
53 else if (Comment[2] ==
'!')
58 const bool TrailingComment = (Comment.size() > 3) && (Comment[3] ==
'<');
59 return std::make_pair(K, TrailingComment);
62bool mergedCommentIsTrailingComment(StringRef Comment) {
63 return (Comment.size() > 3) && (Comment[3] ==
'<');
73 unsigned C1 =
SM.getPresumedColumnNumber(L1, &
Invalid);
75 unsigned C2 =
SM.getPresumedColumnNumber(L2, &
Invalid);
91 for (
unsigned I = P; I != 0; --I) {
92 char C = Buffer[I - 1];
110 Range(SR), RawTextValid(
false), BriefTextValid(
false),
112 IsAlmostTrailingComment(
false) {
120 std::pair<CommentKind, bool> K =
126 unsigned BeginOffset;
127 std::tie(BeginFileID, BeginOffset) =
128 SourceMgr.getDecomposedLoc(Range.getBegin());
129 if (BeginOffset != 0) {
132 SourceMgr.getBufferData(BeginFileID, &
Invalid).data();
140 IsTrailingComment |= K.second;
142 IsAlmostTrailingComment =
143 RawText.starts_with(
"//<") || RawText.starts_with(
"/*<");
147 IsTrailingComment || mergedCommentIsTrailingComment(RawText);
151StringRef RawComment::getRawTextSlow(
const SourceManager &SourceMgr)
const {
154 unsigned BeginOffset;
157 std::tie(BeginFileID, BeginOffset) =
158 SourceMgr.getDecomposedLoc(Range.
getBegin());
159 std::tie(EndFileID, EndOffset) = SourceMgr.getDecomposedLoc(Range.
getEnd());
161 const unsigned Length = EndOffset - BeginOffset;
166 assert(BeginFileID == EndFileID);
169 const char *BufferStart = SourceMgr.getBufferData(BeginFileID,
174 return StringRef(BufferStart + BeginOffset, Length);
177const char *RawComment::extractBriefText(
const ASTContext &Context)
const {
184 llvm::BumpPtrAllocator Allocator;
187 Context.getCommentCommandTraits(),
189 RawText.begin(), RawText.end());
192 const std::string Result = P.Parse();
193 const unsigned BriefTextLength = Result.size();
194 char *BriefTextPtr =
new (Context)
char[BriefTextLength + 1];
195 memcpy(BriefTextPtr, Result.c_str(), BriefTextLength + 1);
196 BriefText = BriefTextPtr;
197 BriefTextValid =
true;
204 const Decl *D)
const {
212 Context.getCommentCommandTraits(),
214 RawText.begin(), RawText.end());
215 comments::Sema S(Context.getAllocator(), Context.getSourceManager(),
216 Context.getDiagnostics(),
217 Context.getCommentCommandTraits(),
220 comments::Parser P(L, S, Context.getAllocator(), Context.getSourceManager(),
221 Context.getDiagnostics(),
222 Context.getCommentCommandTraits());
229 unsigned MaxNewlinesAllowed) {
234 if (Loc1Info.first != Loc2Info.first)
238 const char *Buffer =
SM.getBufferData(Loc1Info.first, &
Invalid).data();
242 unsigned NumNewlines = 0;
243 assert(Loc1Info.second <= Loc2Info.second &&
"Loc1 after Loc2!");
245 for (
unsigned I = Loc1Info.second; I != Loc2Info.second; ++I) {
260 if (NumNewlines > MaxNewlinesAllowed)
264 if (I + 1 != Loc2Info.second &&
265 (Buffer[I + 1] ==
'\n' || Buffer[I + 1] ==
'\r') &&
266 Buffer[I] != Buffer[I + 1])
277 llvm::BumpPtrAllocator &Allocator) {
287 const FileID CommentFile = Loc.first;
288 const unsigned CommentOffset = Loc.second;
292 auto &OC = OrderedComments[CommentFile];
294 OC[CommentOffset] =
new (Allocator)
RawComment(RC);
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;
345 const unsigned Line = SourceMgr.getLineNumber(
File, Offset);
346 CommentBeginLine[
C] =
Line;
351 auto Cached = CommentEndOffset.find(
C);
352 if (Cached != CommentEndOffset.end())
353 return Cached->second;
354 const unsigned Offset =
355 SourceMgr.getDecomposedLoc(
C->getSourceRange().getEnd()).second;
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);
430 bool LocInvalid =
false;
432 SourceMgr.getSpellingColumnNumber(
Tok.getLocation(), &LocInvalid);
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);
457 SourceMgr.getPresumedLoc(
Tok.getLocation().getLocWithOffset(SkipLen));
464 if (End.
getLine() != PreviousLine) {
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 ...
Decl - This represents one declaration (or definition), e.g.
bool isInvalidDecl() const
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.
This class handles loading and caching of source files into memory.
A trivial tuple used to represent a source range.
SourceLocation getEnd() const
SourceLocation getBegin() const
The JSON file list parser is used to communicate input to InstallAPI.
LLVM_READONLY bool isVerticalWhitespace(unsigned char c)
Returns true if this character is vertical ASCII whitespace: '\n', '\r'.
std::pair< FileID, unsigned > FileIDAndOffset
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.