19 #include "llvm/ADT/STLExtras.h" 21 using namespace clang;
25 std::pair<RawComment::CommentKind, bool> getCommentKind(StringRef Comment,
26 bool ParseAllComments) {
27 const size_t MinCommentLength = ParseAllComments ? 2 : 3;
28 if ((Comment.size() < MinCommentLength) || Comment[0] !=
'/')
32 if (Comment[1] ==
'/') {
33 if (Comment.size() < 3)
36 if (Comment[2] ==
'/')
38 else if (Comment[2] ==
'!')
43 assert(Comment.size() >= 4);
47 if (Comment[1] !=
'*' ||
48 Comment[Comment.size() - 2] !=
'*' ||
49 Comment[Comment.size() - 1] !=
'/')
52 if (Comment[2] ==
'*')
54 else if (Comment[2] ==
'!')
59 const bool TrailingComment = (Comment.size() > 3) && (Comment[3] ==
'<');
60 return std::make_pair(K, TrailingComment);
63 bool mergedCommentIsTrailingComment(StringRef Comment) {
64 return (Comment.size() > 3) && (Comment[3] ==
'<');
77 return !Invalid && (C1 == C2);
92 for (
unsigned I = P; I != 0; --I) {
93 char C = Buffer[I - 1];
111 Range(SR), RawTextValid(
false), BriefTextValid(
false),
113 IsAlmostTrailingComment(
false) {
121 std::pair<CommentKind, bool> K =
127 unsigned BeginOffset;
128 std::tie(BeginFileID, BeginOffset) =
130 if (BeginOffset != 0) {
131 bool Invalid =
false;
141 IsTrailingComment |= K.second;
143 IsAlmostTrailingComment = RawText.startswith(
"//<") ||
144 RawText.startswith(
"/*<");
148 IsTrailingComment || mergedCommentIsTrailingComment(RawText);
152 StringRef RawComment::getRawTextSlow(
const SourceManager &SourceMgr)
const {
155 unsigned BeginOffset;
158 std::tie(BeginFileID, BeginOffset) =
162 const unsigned Length = EndOffset - BeginOffset;
167 assert(BeginFileID == EndFileID);
169 bool Invalid =
false;
170 const char *BufferStart = SourceMgr.
getBufferData(BeginFileID,
175 return StringRef(BufferStart + BeginOffset, Length);
178 const char *RawComment::extractBriefText(
const ASTContext &Context)
const {
185 llvm::BumpPtrAllocator Allocator;
190 RawText.begin(), RawText.end());
193 const std::string
Result =
P.Parse();
194 const unsigned BriefTextLength = Result.size();
195 char *BriefTextPtr =
new (Context)
char[BriefTextLength + 1];
196 memcpy(BriefTextPtr, Result.c_str(), BriefTextLength + 1);
197 BriefText = BriefTextPtr;
198 BriefTextValid =
true;
205 const Decl *D)
const {
212 RawText.begin(), RawText.end());
222 return P.parseFullComment();
227 unsigned MaxNewlinesAllowed) {
232 if (Loc1Info.first != Loc2Info.first)
235 bool Invalid =
false;
236 const char *Buffer = SM.
getBufferData(Loc1Info.first, &Invalid).data();
240 unsigned NumNewlines = 0;
241 assert(Loc1Info.second <= Loc2Info.second &&
"Loc1 after Loc2!");
243 for (
unsigned I = Loc1Info.second; I != Loc2Info.second; ++I) {
258 if (NumNewlines > MaxNewlinesAllowed)
262 if (I + 1 != Loc2Info.second &&
263 (Buffer[I + 1] ==
'\n' || Buffer[I + 1] ==
'\r') &&
264 Buffer[I] != Buffer[I + 1])
275 llvm::BumpPtrAllocator &Allocator) {
280 while (!Comments.empty() &&
294 if (Comments.empty()) {
295 Comments.push_back(
new (Allocator)
RawComment(RC));
318 commentsStartOnSameColumn(SourceMgr, C1, C2))) &&
322 *Comments.back() =
RawComment(SourceMgr, MergedRange, CommentOpts,
true);
324 Comments.push_back(
new (Allocator)
RawComment(RC));
329 std::vector<RawComment *> MergedComments;
330 MergedComments.reserve(Comments.size() + DeserializedComments.size());
332 std::merge(Comments.begin(), Comments.end(),
333 DeserializedComments.begin(), DeserializedComments.end(),
334 std::back_inserter(MergedComments),
336 std::swap(Comments, MergedComments);
339 std::string RawComment::getFormattedText(
const SourceManager &SourceMgr,
341 llvm::StringRef CommentText =
getRawText(SourceMgr);
342 if (CommentText.empty())
345 llvm::BumpPtrAllocator Allocator;
351 CommentText.begin(), CommentText.end(),
359 unsigned IndentColumn = 0;
364 auto LexLine = [&](
bool IsFirstLine) ->
bool {
375 llvm::StringRef TokText = L.getSpelling(Tok, SourceMgr);
376 bool LocInvalid =
false;
379 assert(!LocInvalid &&
"getFormattedText for invalid location");
382 size_t WhitespaceLen = TokText.find_first_not_of(
" \t");
383 if (WhitespaceLen == StringRef::npos)
384 WhitespaceLen = TokText.size();
388 IndentColumn = TokColumn + WhitespaceLen;
398 std::max<int>(
static_cast<int>(IndentColumn) - TokColumn, 0));
399 llvm::StringRef Trimmed = TokText.drop_front(SkipLen);
407 Result += L.getSpelling(Tok, SourceMgr);
413 auto DropTrailingNewLines = [](std::string &Str) {
414 while (Str.back() ==
'\n')
419 if (!LexLine(
true)) {
420 DropTrailingNewLines(Result);
424 while (LexLine(
false))
426 DropTrailingNewLines(Result);
Defines the clang::ASTContext interface.
Decl - This represents one declaration (or definition), e.g.
unsigned getPresumedColumnNumber(SourceLocation Loc, bool *Invalid=nullptr) const
bool isBeforeInTranslationUnit(SourceLocation LHS, SourceLocation RHS) const
Determines the order of 2 source locations in the translation unit.
DiagnosticsEngine & getDiagnostics() const
StringRef getBufferData(FileID FID, bool *Invalid=nullptr) const
Return a StringRef to the source buffer data for the specified FileID.
LLVM_READONLY bool isHorizontalWhitespace(unsigned char c)
Returns true if this character is horizontal ASCII whitespace: ' ', '\t', '\f', '\v'.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Concrete class used by the front-end to report problems and issues.
comments::CommandTraits & getCommentCommandTraits() const
SourceLocation getEnd() const
The result type of a method or function.
Encodes a location in the source.
__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)
unsigned getSpellingColumnNumber(SourceLocation Loc, bool *Invalid=nullptr) const
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
Dataflow Directional Tag Classes.
LLVM_READONLY bool isVerticalWhitespace(unsigned char c)
Returns true if this character is vertical ASCII whitespace: '\n', '\r'.
llvm::BumpPtrAllocator & getAllocator() const
SourceManager & getSourceManager()
A trivial tuple used to represent a source range.
SourceLocation getBegin() const
This class handles loading and caching of source files into memory.
std::pair< FileID, unsigned > getDecomposedLoc(SourceLocation Loc) const
Decompose the specified location into a raw FileID + Offset pair.
Engages in a tight little dance with the lexer to efficiently preprocess tokens.