bool ClangCommentPrinter::shouldPrintNewLineBefore(ClangNode Node) const { assert(Node); const auto &Ctx = ClangLoader.getClangASTContext(); const auto &SM = Ctx.getSourceManager(); clang::SourceLocation NodeLoc = SM.getFileLoc(Node.getSourceRange().getBegin()); if (NodeLoc.isInvalid()) return false; unsigned NodeLineNo = SM.getSpellingLineNumber(NodeLoc); clang::FileID FID = SM.getFileID(NodeLoc); if (FID.isInvalid()) return false; unsigned LastEntiyLine = 0; auto It = LastEntityLines.find(FID); if (It != LastEntityLines.end()) LastEntiyLine = It->second; return (NodeLineNo > LastEntiyLine) && NodeLineNo - LastEntiyLine > 1; }
void ClangCommentPrinter::printCommentsUntil(ClangNode Node) { const auto &Ctx = ClangLoader.getClangASTContext(); const auto &SM = Ctx.getSourceManager(); clang::SourceLocation NodeLoc = SM.getFileLoc(Node.getSourceRange().getBegin()); if (NodeLoc.isInvalid()) return; unsigned NodeLineNo = SM.getSpellingLineNumber(NodeLoc); clang::FileID FID = SM.getFileID(NodeLoc); if (FID.isInvalid()) return; clang::SourceLocation FileLoc = SM.getLocForStartOfFile(FID); StringRef Text = SM.getBufferData(FID); if (Text.empty()) return; const char *BufStart = Text.data(); const char *BufPtr = BufStart + getResumeOffset(FID); const char *BufEnd = BufStart + Text.size(); assert(BufPtr <= BufEnd); if (BufPtr == BufEnd) return; // nothing left. clang::Lexer Lex(FileLoc, Ctx.getLangOpts(), BufStart, BufPtr, BufEnd); Lex.SetCommentRetentionState(true); unsigned &LastPrintedLineNo = LastEntityLines[FID]; clang::Token Tok; do { BufPtr = Lex.getBufferLocation(); Lex.LexFromRawLexer(Tok); if (Tok.is(clang::tok::eof)) break; if (Tok.isNot(clang::tok::comment)) continue; // Reached a comment. clang::SourceLocation CommentLoc = Tok.getLocation(); std::pair<clang::FileID, unsigned> LocInfo = SM.getDecomposedLoc(CommentLoc); assert(LocInfo.first == FID); unsigned LineNo = SM.getLineNumber(LocInfo.first, LocInfo.second); if (LineNo > NodeLineNo) break; // Comment is past the clang node. bool IsDocComment = isDocumentationComment(CommentLoc, Node); // Print out the comment. StringRef CommentText(BufStart + LocInfo.second, Tok.getLength()); // Check if comment is on same line but after the declaration. if (SM.isBeforeInTranslationUnit(NodeLoc, Tok.getLocation())) { if (!IsDocComment) PendingComments.push_back(CommentText); continue; } if (LastPrintedLineNo && LineNo - LastPrintedLineNo > 1) { *this << "\n"; printIndent(); } if (!IsDocComment) { unsigned StartLocCol = SM.getSpellingColumnNumber(Tok.getLocation()); printComment(CommentText, StartLocCol); } LastPrintedLineNo = SM.getLineNumber(LocInfo.first, LocInfo.second + Tok.getLength()); } while (true); // Resume printing comments from this point. setResumeOffset(FID, BufPtr - BufStart); }