1aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko//===--- RawCommentList.h - Classes for processing raw comments -*- C++ -*-===// 2aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko// 3aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko// The LLVM Compiler Infrastructure 4aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko// 5aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko// This file is distributed under the University of Illinois Open Source 6aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko// License. See LICENSE.TXT for details. 7aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko// 8aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko//===----------------------------------------------------------------------===// 9aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko 1027c0bb04bfdbf82b1d7e6670b8e806451e8ce2c3Dmitri Gribenko#ifndef LLVM_CLANG_AST_RAW_COMMENT_LIST_H 1127c0bb04bfdbf82b1d7e6670b8e806451e8ce2c3Dmitri Gribenko#define LLVM_CLANG_AST_RAW_COMMENT_LIST_H 12aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko 13aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko#include "clang/Basic/SourceManager.h" 14aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko#include "llvm/ADT/ArrayRef.h" 15aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko 16aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenkonamespace clang { 17aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko 182d44d77fed3200e2eff289f55493317e90d3398cDmitri Gribenkoclass ASTContext; 19aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenkoclass ASTReader; 20f50555eedef33fd5a67d369aa0ae8a6f1d201543Dmitri Gribenkoclass Decl; 211952354bd376062c3ab3d328c0fc6c36530c9309Dmitri Gribenkoclass Preprocessor; 22f50555eedef33fd5a67d369aa0ae8a6f1d201543Dmitri Gribenko 23f50555eedef33fd5a67d369aa0ae8a6f1d201543Dmitri Gribenkonamespace comments { 24f50555eedef33fd5a67d369aa0ae8a6f1d201543Dmitri Gribenko class FullComment; 25f50555eedef33fd5a67d369aa0ae8a6f1d201543Dmitri Gribenko} // end namespace comments 26aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko 27aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenkoclass RawComment { 28aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenkopublic: 29aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko enum CommentKind { 30c50a0e3900f1b44503be48457508af372f4dd05aAbramo Bagnara RCK_Invalid, ///< Invalid comment 31c50a0e3900f1b44503be48457508af372f4dd05aAbramo Bagnara RCK_OrdinaryBCPL, ///< Any normal BCPL comments 32c50a0e3900f1b44503be48457508af372f4dd05aAbramo Bagnara RCK_OrdinaryC, ///< Any normal C comment 33c50a0e3900f1b44503be48457508af372f4dd05aAbramo Bagnara RCK_BCPLSlash, ///< \code /// stuff \endcode 34c50a0e3900f1b44503be48457508af372f4dd05aAbramo Bagnara RCK_BCPLExcl, ///< \code //! stuff \endcode 35c50a0e3900f1b44503be48457508af372f4dd05aAbramo Bagnara RCK_JavaDoc, ///< \code /** stuff */ \endcode 36c50a0e3900f1b44503be48457508af372f4dd05aAbramo Bagnara RCK_Qt, ///< \code /*! stuff */ \endcode, also used by HeaderDoc 37c50a0e3900f1b44503be48457508af372f4dd05aAbramo Bagnara RCK_Merged ///< Two or more documentation comments merged together 38aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko }; 39aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko 40c50a0e3900f1b44503be48457508af372f4dd05aAbramo Bagnara RawComment() : Kind(RCK_Invalid), IsAlmostTrailingComment(false) { } 41aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko 42aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko RawComment(const SourceManager &SourceMgr, SourceRange SR, 43aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko bool Merged = false); 44aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko 45aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko CommentKind getKind() const LLVM_READONLY { 46aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko return (CommentKind) Kind; 47aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko } 48aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko 49aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko bool isInvalid() const LLVM_READONLY { 50c50a0e3900f1b44503be48457508af372f4dd05aAbramo Bagnara return Kind == RCK_Invalid; 51aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko } 52aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko 53aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko bool isMerged() const LLVM_READONLY { 54c50a0e3900f1b44503be48457508af372f4dd05aAbramo Bagnara return Kind == RCK_Merged; 55aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko } 56aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko 57f50555eedef33fd5a67d369aa0ae8a6f1d201543Dmitri Gribenko /// Is this comment attached to any declaration? 58a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko bool isAttached() const LLVM_READONLY { 59c41ace950dcf2254c9aa48e73647b89c35109f80Dmitri Gribenko return IsAttached; 60a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko } 61a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko 62c41ace950dcf2254c9aa48e73647b89c35109f80Dmitri Gribenko void setAttached() { 63c41ace950dcf2254c9aa48e73647b89c35109f80Dmitri Gribenko IsAttached = true; 64a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko } 65a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko 66aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko /// Returns true if it is a comment that should be put after a member: 67aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko /// \code ///< stuff \endcode 68aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko /// \code //!< stuff \endcode 69aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko /// \code /**< stuff */ \endcode 70aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko /// \code /*!< stuff */ \endcode 71aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko bool isTrailingComment() const LLVM_READONLY { 722d44d77fed3200e2eff289f55493317e90d3398cDmitri Gribenko assert(isDocumentation()); 73aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko return IsTrailingComment; 74aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko } 75aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko 76aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko /// Returns true if it is a probable typo: 77aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko /// \code //< stuff \endcode 78aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko /// \code /*< stuff */ \endcode 79aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko bool isAlmostTrailingComment() const LLVM_READONLY { 80aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko return IsAlmostTrailingComment; 81aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko } 82aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko 832d44d77fed3200e2eff289f55493317e90d3398cDmitri Gribenko /// Returns true if this comment is not a documentation comment. 84aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko bool isOrdinary() const LLVM_READONLY { 85c50a0e3900f1b44503be48457508af372f4dd05aAbramo Bagnara return (Kind == RCK_OrdinaryBCPL) || (Kind == RCK_OrdinaryC); 86aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko } 87aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko 882d44d77fed3200e2eff289f55493317e90d3398cDmitri Gribenko /// Returns true if this comment any kind of a documentation comment. 892d44d77fed3200e2eff289f55493317e90d3398cDmitri Gribenko bool isDocumentation() const LLVM_READONLY { 90aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko return !isInvalid() && !isOrdinary(); 91aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko } 92aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko 93aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko /// Returns raw comment text with comment markers. 94aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko StringRef getRawText(const SourceManager &SourceMgr) const { 95aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko if (RawTextValid) 96aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko return RawText; 97aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko 98aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko RawText = getRawTextSlow(SourceMgr); 99aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko RawTextValid = true; 100aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko return RawText; 101aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko } 102aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko 103aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko SourceRange getSourceRange() const LLVM_READONLY { 104aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko return Range; 105aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko } 106aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko 107aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko unsigned getBeginLine(const SourceManager &SM) const; 108aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko unsigned getEndLine(const SourceManager &SM) const; 109aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko 110d99ef536b241071b6f4c01db6525dc03242ac30bDmitri Gribenko const char *getBriefText(const ASTContext &Context) const { 1112d44d77fed3200e2eff289f55493317e90d3398cDmitri Gribenko if (BriefTextValid) 1122d44d77fed3200e2eff289f55493317e90d3398cDmitri Gribenko return BriefText; 1132d44d77fed3200e2eff289f55493317e90d3398cDmitri Gribenko 1142d44d77fed3200e2eff289f55493317e90d3398cDmitri Gribenko return extractBriefText(Context); 1152d44d77fed3200e2eff289f55493317e90d3398cDmitri Gribenko } 1162d44d77fed3200e2eff289f55493317e90d3398cDmitri Gribenko 117c41ace950dcf2254c9aa48e73647b89c35109f80Dmitri Gribenko /// Parse the comment, assuming it is attached to decl \c D. 1181952354bd376062c3ab3d328c0fc6c36530c9309Dmitri Gribenko comments::FullComment *parse(const ASTContext &Context, 1191952354bd376062c3ab3d328c0fc6c36530c9309Dmitri Gribenko const Preprocessor *PP, const Decl *D) const; 120f50555eedef33fd5a67d369aa0ae8a6f1d201543Dmitri Gribenko 121aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenkoprivate: 122aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko SourceRange Range; 123aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko 124aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko mutable StringRef RawText; 125d99ef536b241071b6f4c01db6525dc03242ac30bDmitri Gribenko mutable const char *BriefText; 1262d44d77fed3200e2eff289f55493317e90d3398cDmitri Gribenko 1272d44d77fed3200e2eff289f55493317e90d3398cDmitri Gribenko mutable bool RawTextValid : 1; ///< True if RawText is valid 1282d44d77fed3200e2eff289f55493317e90d3398cDmitri Gribenko mutable bool BriefTextValid : 1; ///< True if BriefText is valid 129aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko 130aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko unsigned Kind : 3; 131aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko 132c41ace950dcf2254c9aa48e73647b89c35109f80Dmitri Gribenko /// True if comment is attached to a declaration in ASTContext. 133c41ace950dcf2254c9aa48e73647b89c35109f80Dmitri Gribenko bool IsAttached : 1; 134c41ace950dcf2254c9aa48e73647b89c35109f80Dmitri Gribenko 135aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko bool IsTrailingComment : 1; 136aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko bool IsAlmostTrailingComment : 1; 137aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko 138aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko mutable bool BeginLineValid : 1; ///< True if BeginLine is valid 139aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko mutable bool EndLineValid : 1; ///< True if EndLine is valid 140aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko mutable unsigned BeginLine; ///< Cached line number 141aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko mutable unsigned EndLine; ///< Cached line number 142aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko 143aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko /// \brief Constructor for AST deserialization. 144aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko RawComment(SourceRange SR, CommentKind K, bool IsTrailingComment, 145aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko bool IsAlmostTrailingComment) : 146c2cda0284a3e80fa4b39b540f6c73782fa69fa6bDmitri Gribenko Range(SR), RawTextValid(false), BriefTextValid(false), Kind(K), 147c41ace950dcf2254c9aa48e73647b89c35109f80Dmitri Gribenko IsAttached(false), IsTrailingComment(IsTrailingComment), 148aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko IsAlmostTrailingComment(IsAlmostTrailingComment), 149aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko BeginLineValid(false), EndLineValid(false) 150aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko { } 151aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko 152aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko StringRef getRawTextSlow(const SourceManager &SourceMgr) const; 153aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko 154d99ef536b241071b6f4c01db6525dc03242ac30bDmitri Gribenko const char *extractBriefText(const ASTContext &Context) const; 1552d44d77fed3200e2eff289f55493317e90d3398cDmitri Gribenko 156aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko friend class ASTReader; 157aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko}; 158aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko 159aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko/// \brief Compare comments' source locations. 160aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenkotemplate<> 161aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenkoclass BeforeThanCompare<RawComment> { 162aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko const SourceManager &SM; 163aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko 164aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenkopublic: 165aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko explicit BeforeThanCompare(const SourceManager &SM) : SM(SM) { } 166aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko 1679530a8bf275f91f95147e1fb205dc85bea1ae45cDmitri Gribenko bool operator()(const RawComment &LHS, const RawComment &RHS) { 168aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko return SM.isBeforeInTranslationUnit(LHS.getSourceRange().getBegin(), 1699530a8bf275f91f95147e1fb205dc85bea1ae45cDmitri Gribenko RHS.getSourceRange().getBegin()); 170aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko } 171811c820257746b1799b790b6adc7804f44154011Dmitri Gribenko 172811c820257746b1799b790b6adc7804f44154011Dmitri Gribenko bool operator()(const RawComment *LHS, const RawComment *RHS) { 173811c820257746b1799b790b6adc7804f44154011Dmitri Gribenko return operator()(*LHS, *RHS); 174811c820257746b1799b790b6adc7804f44154011Dmitri Gribenko } 175aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko}; 176aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko 177aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko/// \brief This class represents all comments included in the translation unit, 178aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko/// sorted in order of appearance in the translation unit. 179aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenkoclass RawCommentList { 180aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenkopublic: 181aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko RawCommentList(SourceManager &SourceMgr) : 182aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko SourceMgr(SourceMgr), OnlyWhitespaceSeen(true) { } 183aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko 184811c820257746b1799b790b6adc7804f44154011Dmitri Gribenko void addComment(const RawComment &RC, llvm::BumpPtrAllocator &Allocator); 185aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko 186811c820257746b1799b790b6adc7804f44154011Dmitri Gribenko ArrayRef<RawComment *> getComments() const { 187aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko return Comments; 188aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko } 189aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko 190aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenkoprivate: 191aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko SourceManager &SourceMgr; 192811c820257746b1799b790b6adc7804f44154011Dmitri Gribenko std::vector<RawComment *> Comments; 1934a66557c297e1e5a71a3da4ceca1969800e7de70Dmitri Gribenko SourceLocation PrevCommentEndLoc; 194aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko bool OnlyWhitespaceSeen; 195aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko 196811c820257746b1799b790b6adc7804f44154011Dmitri Gribenko void addCommentsToFront(const std::vector<RawComment *> &C) { 197aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko size_t OldSize = Comments.size(); 198aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko Comments.resize(C.size() + OldSize); 199aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko std::copy_backward(Comments.begin(), Comments.begin() + OldSize, 200aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko Comments.end()); 201aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko std::copy(C.begin(), C.end(), Comments.begin()); 202aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko } 203aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko 204aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko friend class ASTReader; 205aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko}; 206aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko 207aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko} // end namespace clang 208aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko 209aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko#endif 210aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko 211