RawCommentList.h revision a5ef44ff5d93a3be6ca67782828157a71894cf0c
1//===--- RawCommentList.h - Classes for processing raw comments -*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9 10#ifndef LLVM_CLANG_AST_RAW_COMMENT_LIST_H 11#define LLVM_CLANG_AST_RAW_COMMENT_LIST_H 12 13#include "clang/Basic/SourceManager.h" 14#include "llvm/ADT/ArrayRef.h" 15 16namespace clang { 17 18class ASTContext; 19class ASTReader; 20 21class RawComment { 22public: 23 enum CommentKind { 24 RCK_Invalid, ///< Invalid comment 25 RCK_OrdinaryBCPL, ///< Any normal BCPL comments 26 RCK_OrdinaryC, ///< Any normal C comment 27 RCK_BCPLSlash, ///< \code /// stuff \endcode 28 RCK_BCPLExcl, ///< \code //! stuff \endcode 29 RCK_JavaDoc, ///< \code /** stuff */ \endcode 30 RCK_Qt, ///< \code /*! stuff */ \endcode, also used by HeaderDoc 31 RCK_Merged ///< Two or more documentation comments merged together 32 }; 33 34 RawComment() : Kind(RCK_Invalid), IsAlmostTrailingComment(false) { } 35 36 RawComment(const SourceManager &SourceMgr, SourceRange SR, 37 bool Merged = false); 38 39 CommentKind getKind() const LLVM_READONLY { 40 return (CommentKind) Kind; 41 } 42 43 bool isInvalid() const LLVM_READONLY { 44 return Kind == RCK_Invalid; 45 } 46 47 bool isMerged() const LLVM_READONLY { 48 return Kind == RCK_Merged; 49 } 50 51 bool isAttached() const LLVM_READONLY { 52 return IsAttached; 53 } 54 55 void setAttached() { 56 IsAttached = true; 57 } 58 59 /// Returns true if it is a comment that should be put after a member: 60 /// \code ///< stuff \endcode 61 /// \code //!< stuff \endcode 62 /// \code /**< stuff */ \endcode 63 /// \code /*!< stuff */ \endcode 64 bool isTrailingComment() const LLVM_READONLY { 65 assert(isDocumentation()); 66 return IsTrailingComment; 67 } 68 69 /// Returns true if it is a probable typo: 70 /// \code //< stuff \endcode 71 /// \code /*< stuff */ \endcode 72 bool isAlmostTrailingComment() const LLVM_READONLY { 73 return IsAlmostTrailingComment; 74 } 75 76 /// Returns true if this comment is not a documentation comment. 77 bool isOrdinary() const LLVM_READONLY { 78 return (Kind == RCK_OrdinaryBCPL) || (Kind == RCK_OrdinaryC); 79 } 80 81 /// Returns true if this comment any kind of a documentation comment. 82 bool isDocumentation() const LLVM_READONLY { 83 return !isInvalid() && !isOrdinary(); 84 } 85 86 /// Returns raw comment text with comment markers. 87 StringRef getRawText(const SourceManager &SourceMgr) const { 88 if (RawTextValid) 89 return RawText; 90 91 RawText = getRawTextSlow(SourceMgr); 92 RawTextValid = true; 93 return RawText; 94 } 95 96 SourceRange getSourceRange() const LLVM_READONLY { 97 return Range; 98 } 99 100 unsigned getBeginLine(const SourceManager &SM) const; 101 unsigned getEndLine(const SourceManager &SM) const; 102 103 const char *getBriefText(const ASTContext &Context) const { 104 if (BriefTextValid) 105 return BriefText; 106 107 return extractBriefText(Context); 108 } 109 110private: 111 SourceRange Range; 112 113 mutable StringRef RawText; 114 mutable const char *BriefText; 115 116 mutable bool RawTextValid : 1; ///< True if RawText is valid 117 mutable bool BriefTextValid : 1; ///< True if BriefText is valid 118 119 unsigned Kind : 3; 120 121 /// True if comment is attached to a declaration in ASTContext. 122 bool IsAttached : 1; 123 124 bool IsTrailingComment : 1; 125 bool IsAlmostTrailingComment : 1; 126 127 mutable bool BeginLineValid : 1; ///< True if BeginLine is valid 128 mutable bool EndLineValid : 1; ///< True if EndLine is valid 129 mutable unsigned BeginLine; ///< Cached line number 130 mutable unsigned EndLine; ///< Cached line number 131 132 /// \brief Constructor for AST deserialization. 133 RawComment(SourceRange SR, CommentKind K, bool IsTrailingComment, 134 bool IsAlmostTrailingComment) : 135 Range(SR), RawTextValid(false), BriefTextValid(false), Kind(K), 136 IsAttached(false), IsTrailingComment(IsTrailingComment), 137 IsAlmostTrailingComment(IsAlmostTrailingComment), 138 BeginLineValid(false), EndLineValid(false) 139 { } 140 141 StringRef getRawTextSlow(const SourceManager &SourceMgr) const; 142 143 const char *extractBriefText(const ASTContext &Context) const; 144 145 friend class ASTReader; 146}; 147 148/// \brief Compare comments' source locations. 149template<> 150class BeforeThanCompare<RawComment> { 151 const SourceManager &SM; 152 153public: 154 explicit BeforeThanCompare(const SourceManager &SM) : SM(SM) { } 155 156 bool operator()(const RawComment &LHS, const RawComment &RHS) { 157 return SM.isBeforeInTranslationUnit(LHS.getSourceRange().getBegin(), 158 RHS.getSourceRange().getBegin()); 159 } 160 161 bool operator()(const RawComment *LHS, const RawComment *RHS) { 162 return operator()(*LHS, *RHS); 163 } 164}; 165 166/// \brief This class represents all comments included in the translation unit, 167/// sorted in order of appearance in the translation unit. 168class RawCommentList { 169public: 170 RawCommentList(SourceManager &SourceMgr) : 171 SourceMgr(SourceMgr), OnlyWhitespaceSeen(true) { } 172 173 void addComment(const RawComment &RC, llvm::BumpPtrAllocator &Allocator); 174 175 ArrayRef<RawComment *> getComments() const { 176 return Comments; 177 } 178 179private: 180 SourceManager &SourceMgr; 181 std::vector<RawComment *> Comments; 182 RawComment LastComment; 183 bool OnlyWhitespaceSeen; 184 185 void addCommentsToFront(const std::vector<RawComment *> &C) { 186 size_t OldSize = Comments.size(); 187 Comments.resize(C.size() + OldSize); 188 std::copy_backward(Comments.begin(), Comments.begin() + OldSize, 189 Comments.end()); 190 std::copy(C.begin(), C.end(), Comments.begin()); 191 } 192 193 friend class ASTReader; 194}; 195 196} // end namespace clang 197 198#endif 199 200