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 10176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines#ifndef LLVM_CLANG_AST_RAWCOMMENTLIST_H 11176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines#define LLVM_CLANG_AST_RAWCOMMENTLIST_H 12aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko 136fd7d3067dd06584ef3940e88e31fea1a0e83588Dmitri Gribenko#include "clang/Basic/CommentOptions.h" 14aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko#include "clang/Basic/SourceManager.h" 15aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko#include "llvm/ADT/ArrayRef.h" 16aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko 17aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenkonamespace clang { 18aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko 192d44d77fed3200e2eff289f55493317e90d3398cDmitri Gribenkoclass ASTContext; 20aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenkoclass ASTReader; 21f50555eedef33fd5a67d369aa0ae8a6f1d201543Dmitri Gribenkoclass Decl; 221952354bd376062c3ab3d328c0fc6c36530c9309Dmitri Gribenkoclass Preprocessor; 23f50555eedef33fd5a67d369aa0ae8a6f1d201543Dmitri Gribenko 24f50555eedef33fd5a67d369aa0ae8a6f1d201543Dmitri Gribenkonamespace comments { 25f50555eedef33fd5a67d369aa0ae8a6f1d201543Dmitri Gribenko class FullComment; 26f50555eedef33fd5a67d369aa0ae8a6f1d201543Dmitri Gribenko} // end namespace comments 27aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko 28aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenkoclass RawComment { 29aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenkopublic: 30aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko enum CommentKind { 31c50a0e3900f1b44503be48457508af372f4dd05aAbramo Bagnara RCK_Invalid, ///< Invalid comment 32c50a0e3900f1b44503be48457508af372f4dd05aAbramo Bagnara RCK_OrdinaryBCPL, ///< Any normal BCPL comments 33c50a0e3900f1b44503be48457508af372f4dd05aAbramo Bagnara RCK_OrdinaryC, ///< Any normal C comment 34c50a0e3900f1b44503be48457508af372f4dd05aAbramo Bagnara RCK_BCPLSlash, ///< \code /// stuff \endcode 35c50a0e3900f1b44503be48457508af372f4dd05aAbramo Bagnara RCK_BCPLExcl, ///< \code //! stuff \endcode 36c50a0e3900f1b44503be48457508af372f4dd05aAbramo Bagnara RCK_JavaDoc, ///< \code /** stuff */ \endcode 37c50a0e3900f1b44503be48457508af372f4dd05aAbramo Bagnara RCK_Qt, ///< \code /*! stuff */ \endcode, also used by HeaderDoc 38c50a0e3900f1b44503be48457508af372f4dd05aAbramo Bagnara RCK_Merged ///< Two or more documentation comments merged together 39aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko }; 40aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko 41c50a0e3900f1b44503be48457508af372f4dd05aAbramo Bagnara RawComment() : Kind(RCK_Invalid), IsAlmostTrailingComment(false) { } 42aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko 43aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko RawComment(const SourceManager &SourceMgr, SourceRange SR, 446fd7d3067dd06584ef3940e88e31fea1a0e83588Dmitri Gribenko bool Merged, bool ParseAllComments); 45aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko 46aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko CommentKind getKind() const LLVM_READONLY { 47aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko return (CommentKind) Kind; 48aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko } 49aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko 50aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko bool isInvalid() const LLVM_READONLY { 51c50a0e3900f1b44503be48457508af372f4dd05aAbramo Bagnara return Kind == RCK_Invalid; 52aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko } 53aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko 54aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko bool isMerged() const LLVM_READONLY { 55c50a0e3900f1b44503be48457508af372f4dd05aAbramo Bagnara return Kind == RCK_Merged; 56aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko } 57aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko 58f50555eedef33fd5a67d369aa0ae8a6f1d201543Dmitri Gribenko /// Is this comment attached to any declaration? 59a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko bool isAttached() const LLVM_READONLY { 60c41ace950dcf2254c9aa48e73647b89c35109f80Dmitri Gribenko return IsAttached; 61a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko } 62a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko 63c41ace950dcf2254c9aa48e73647b89c35109f80Dmitri Gribenko void setAttached() { 64c41ace950dcf2254c9aa48e73647b89c35109f80Dmitri Gribenko IsAttached = true; 65a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko } 66a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko 67aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko /// Returns true if it is a comment that should be put after a member: 68aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko /// \code ///< stuff \endcode 69aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko /// \code //!< stuff \endcode 70aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko /// \code /**< stuff */ \endcode 71aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko /// \code /*!< stuff */ \endcode 72aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko bool isTrailingComment() const LLVM_READONLY { 732d44d77fed3200e2eff289f55493317e90d3398cDmitri Gribenko assert(isDocumentation()); 74aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko return IsTrailingComment; 75aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko } 76aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko 77aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko /// Returns true if it is a probable typo: 78aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko /// \code //< stuff \endcode 79aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko /// \code /*< stuff */ \endcode 80aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko bool isAlmostTrailingComment() const LLVM_READONLY { 81aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko return IsAlmostTrailingComment; 82aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko } 83aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko 842d44d77fed3200e2eff289f55493317e90d3398cDmitri Gribenko /// Returns true if this comment is not a documentation comment. 85aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko bool isOrdinary() const LLVM_READONLY { 866fd7d3067dd06584ef3940e88e31fea1a0e83588Dmitri Gribenko return ((Kind == RCK_OrdinaryBCPL) || (Kind == RCK_OrdinaryC)) && 876fd7d3067dd06584ef3940e88e31fea1a0e83588Dmitri Gribenko !ParseAllComments; 88aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko } 89aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko 902d44d77fed3200e2eff289f55493317e90d3398cDmitri Gribenko /// Returns true if this comment any kind of a documentation comment. 912d44d77fed3200e2eff289f55493317e90d3398cDmitri Gribenko bool isDocumentation() const LLVM_READONLY { 920e7f2bb1810a4e5e62a8e247460cd26f981d0827Dmitri Gribenko return !isInvalid() && !isOrdinary(); 936fd7d3067dd06584ef3940e88e31fea1a0e83588Dmitri Gribenko } 946fd7d3067dd06584ef3940e88e31fea1a0e83588Dmitri Gribenko 956fd7d3067dd06584ef3940e88e31fea1a0e83588Dmitri Gribenko /// Returns whether we are parsing all comments. 966fd7d3067dd06584ef3940e88e31fea1a0e83588Dmitri Gribenko bool isParseAllComments() const LLVM_READONLY { 976fd7d3067dd06584ef3940e88e31fea1a0e83588Dmitri Gribenko return ParseAllComments; 98aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko } 99aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko 100aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko /// Returns raw comment text with comment markers. 101aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko StringRef getRawText(const SourceManager &SourceMgr) const { 102aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko if (RawTextValid) 103aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko return RawText; 104aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko 105aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko RawText = getRawTextSlow(SourceMgr); 106aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko RawTextValid = true; 107aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko return RawText; 108aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko } 109aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko 11042572f532b99230bf7aa3e3593a0fbb1174bce7cBenjamin Kramer SourceRange getSourceRange() const LLVM_READONLY { return Range; } 11142572f532b99230bf7aa3e3593a0fbb1174bce7cBenjamin Kramer SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); } 11242572f532b99230bf7aa3e3593a0fbb1174bce7cBenjamin Kramer SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); } 113aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko 114d99ef536b241071b6f4c01db6525dc03242ac30bDmitri Gribenko const char *getBriefText(const ASTContext &Context) const { 1152d44d77fed3200e2eff289f55493317e90d3398cDmitri Gribenko if (BriefTextValid) 1162d44d77fed3200e2eff289f55493317e90d3398cDmitri Gribenko return BriefText; 1172d44d77fed3200e2eff289f55493317e90d3398cDmitri Gribenko 1182d44d77fed3200e2eff289f55493317e90d3398cDmitri Gribenko return extractBriefText(Context); 1192d44d77fed3200e2eff289f55493317e90d3398cDmitri Gribenko } 1202d44d77fed3200e2eff289f55493317e90d3398cDmitri Gribenko 121c41ace950dcf2254c9aa48e73647b89c35109f80Dmitri Gribenko /// Parse the comment, assuming it is attached to decl \c D. 1221952354bd376062c3ab3d328c0fc6c36530c9309Dmitri Gribenko comments::FullComment *parse(const ASTContext &Context, 1231952354bd376062c3ab3d328c0fc6c36530c9309Dmitri Gribenko const Preprocessor *PP, const Decl *D) const; 124f50555eedef33fd5a67d369aa0ae8a6f1d201543Dmitri Gribenko 125aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenkoprivate: 126aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko SourceRange Range; 127aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko 128aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko mutable StringRef RawText; 129d99ef536b241071b6f4c01db6525dc03242ac30bDmitri Gribenko mutable const char *BriefText; 1302d44d77fed3200e2eff289f55493317e90d3398cDmitri Gribenko 1312d44d77fed3200e2eff289f55493317e90d3398cDmitri Gribenko mutable bool RawTextValid : 1; ///< True if RawText is valid 1322d44d77fed3200e2eff289f55493317e90d3398cDmitri Gribenko mutable bool BriefTextValid : 1; ///< True if BriefText is valid 133aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko 134aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko unsigned Kind : 3; 135aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko 136c41ace950dcf2254c9aa48e73647b89c35109f80Dmitri Gribenko /// True if comment is attached to a declaration in ASTContext. 137c41ace950dcf2254c9aa48e73647b89c35109f80Dmitri Gribenko bool IsAttached : 1; 138c41ace950dcf2254c9aa48e73647b89c35109f80Dmitri Gribenko 139aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko bool IsTrailingComment : 1; 140aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko bool IsAlmostTrailingComment : 1; 141aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko 1426fd7d3067dd06584ef3940e88e31fea1a0e83588Dmitri Gribenko /// When true, ordinary comments starting with "//" and "/*" will be 1436fd7d3067dd06584ef3940e88e31fea1a0e83588Dmitri Gribenko /// considered as documentation comments. 1446fd7d3067dd06584ef3940e88e31fea1a0e83588Dmitri Gribenko bool ParseAllComments : 1; 1456fd7d3067dd06584ef3940e88e31fea1a0e83588Dmitri Gribenko 146aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko /// \brief Constructor for AST deserialization. 147aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko RawComment(SourceRange SR, CommentKind K, bool IsTrailingComment, 1486fd7d3067dd06584ef3940e88e31fea1a0e83588Dmitri Gribenko bool IsAlmostTrailingComment, 1496fd7d3067dd06584ef3940e88e31fea1a0e83588Dmitri Gribenko bool ParseAllComments) : 150c2cda0284a3e80fa4b39b540f6c73782fa69fa6bDmitri Gribenko Range(SR), RawTextValid(false), BriefTextValid(false), Kind(K), 151c41ace950dcf2254c9aa48e73647b89c35109f80Dmitri Gribenko IsAttached(false), IsTrailingComment(IsTrailingComment), 152aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko IsAlmostTrailingComment(IsAlmostTrailingComment), 15342572f532b99230bf7aa3e3593a0fbb1174bce7cBenjamin Kramer ParseAllComments(ParseAllComments) 154aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko { } 155aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko 156aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko StringRef getRawTextSlow(const SourceManager &SourceMgr) const; 157aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko 158d99ef536b241071b6f4c01db6525dc03242ac30bDmitri Gribenko const char *extractBriefText(const ASTContext &Context) const; 1592d44d77fed3200e2eff289f55493317e90d3398cDmitri Gribenko 160aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko friend class ASTReader; 161aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko}; 162aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko 163aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko/// \brief Compare comments' source locations. 164aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenkotemplate<> 165aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenkoclass BeforeThanCompare<RawComment> { 166aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko const SourceManager &SM; 167aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko 168aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenkopublic: 169aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko explicit BeforeThanCompare(const SourceManager &SM) : SM(SM) { } 170aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko 1719530a8bf275f91f95147e1fb205dc85bea1ae45cDmitri Gribenko bool operator()(const RawComment &LHS, const RawComment &RHS) { 17242572f532b99230bf7aa3e3593a0fbb1174bce7cBenjamin Kramer return SM.isBeforeInTranslationUnit(LHS.getLocStart(), RHS.getLocStart()); 173aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko } 174811c820257746b1799b790b6adc7804f44154011Dmitri Gribenko 175811c820257746b1799b790b6adc7804f44154011Dmitri Gribenko bool operator()(const RawComment *LHS, const RawComment *RHS) { 176811c820257746b1799b790b6adc7804f44154011Dmitri Gribenko return operator()(*LHS, *RHS); 177811c820257746b1799b790b6adc7804f44154011Dmitri Gribenko } 178aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko}; 179aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko 180aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko/// \brief This class represents all comments included in the translation unit, 181aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko/// sorted in order of appearance in the translation unit. 182aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenkoclass RawCommentList { 183aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenkopublic: 18442572f532b99230bf7aa3e3593a0fbb1174bce7cBenjamin Kramer RawCommentList(SourceManager &SourceMgr) : SourceMgr(SourceMgr) {} 185aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko 186811c820257746b1799b790b6adc7804f44154011Dmitri Gribenko void addComment(const RawComment &RC, llvm::BumpPtrAllocator &Allocator); 187aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko 188811c820257746b1799b790b6adc7804f44154011Dmitri Gribenko ArrayRef<RawComment *> getComments() const { 189aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko return Comments; 190aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko } 191aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko 192aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenkoprivate: 193aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko SourceManager &SourceMgr; 194811c820257746b1799b790b6adc7804f44154011Dmitri Gribenko std::vector<RawComment *> Comments; 195aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko 196651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines void addDeserializedComments(ArrayRef<RawComment *> DeserializedComments); 197aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko 198aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko friend class ASTReader; 199aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko}; 200aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko 201aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko} // end namespace clang 202aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko 203aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko#endif 204