RawCommentList.h revision d99ef536b241071b6f4c01db6525dc03242ac30b
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 CK_Invalid, ///< Invalid comment 25 CK_OrdinaryBCPL, ///< Any normal BCPL comments 26 CK_OrdinaryC, ///< Any normal C comment 27 CK_BCPLSlash, ///< \code /// stuff \endcode 28 CK_BCPLExcl, ///< \code //! stuff \endcode 29 CK_JavaDoc, ///< \code /** stuff */ \endcode 30 CK_Qt, ///< \code /*! stuff */ \endcode, also used by HeaderDoc 31 CK_Merged ///< Two or more documentation comments merged together 32 }; 33 34 RawComment() : Kind(CK_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 == CK_Invalid; 45 } 46 47 bool isMerged() const LLVM_READONLY { 48 return Kind == CK_Merged; 49 } 50 51 /// Returns true if it is a comment that should be put after a member: 52 /// \code ///< stuff \endcode 53 /// \code //!< stuff \endcode 54 /// \code /**< stuff */ \endcode 55 /// \code /*!< stuff */ \endcode 56 bool isTrailingComment() const LLVM_READONLY { 57 assert(isDocumentation()); 58 return IsTrailingComment; 59 } 60 61 /// Returns true if it is a probable typo: 62 /// \code //< stuff \endcode 63 /// \code /*< stuff */ \endcode 64 bool isAlmostTrailingComment() const LLVM_READONLY { 65 return IsAlmostTrailingComment; 66 } 67 68 /// Returns true if this comment is not a documentation comment. 69 bool isOrdinary() const LLVM_READONLY { 70 return (Kind == CK_OrdinaryBCPL) || (Kind == CK_OrdinaryC); 71 } 72 73 /// Returns true if this comment any kind of a documentation comment. 74 bool isDocumentation() const LLVM_READONLY { 75 return !isInvalid() && !isOrdinary(); 76 } 77 78 /// Returns raw comment text with comment markers. 79 StringRef getRawText(const SourceManager &SourceMgr) const { 80 if (RawTextValid) 81 return RawText; 82 83 RawText = getRawTextSlow(SourceMgr); 84 RawTextValid = true; 85 return RawText; 86 } 87 88 SourceRange getSourceRange() const LLVM_READONLY { 89 return Range; 90 } 91 92 unsigned getBeginLine(const SourceManager &SM) const; 93 unsigned getEndLine(const SourceManager &SM) const; 94 95 const char *getBriefText(const ASTContext &Context) const { 96 if (BriefTextValid) 97 return BriefText; 98 99 return extractBriefText(Context); 100 } 101 102private: 103 SourceRange Range; 104 105 mutable StringRef RawText; 106 mutable const char *BriefText; 107 108 mutable bool RawTextValid : 1; ///< True if RawText is valid 109 mutable bool BriefTextValid : 1; ///< True if BriefText is valid 110 111 unsigned Kind : 3; 112 113 bool IsTrailingComment : 1; 114 bool IsAlmostTrailingComment : 1; 115 116 mutable bool BeginLineValid : 1; ///< True if BeginLine is valid 117 mutable bool EndLineValid : 1; ///< True if EndLine is valid 118 mutable unsigned BeginLine; ///< Cached line number 119 mutable unsigned EndLine; ///< Cached line number 120 121 /// \brief Constructor for AST deserialization. 122 RawComment(SourceRange SR, CommentKind K, bool IsTrailingComment, 123 bool IsAlmostTrailingComment) : 124 Range(SR), RawTextValid(false), BriefTextValid(false), Kind(K), 125 IsTrailingComment(IsTrailingComment), 126 IsAlmostTrailingComment(IsAlmostTrailingComment), 127 BeginLineValid(false), EndLineValid(false) 128 { } 129 130 StringRef getRawTextSlow(const SourceManager &SourceMgr) const; 131 132 const char *extractBriefText(const ASTContext &Context) const; 133 134 friend class ASTReader; 135}; 136 137/// \brief Compare comments' source locations. 138template<> 139class BeforeThanCompare<RawComment> { 140 const SourceManager &SM; 141 142public: 143 explicit BeforeThanCompare(const SourceManager &SM) : SM(SM) { } 144 145 bool operator()(const RawComment &LHS, const RawComment &RHS) { 146 return SM.isBeforeInTranslationUnit(LHS.getSourceRange().getBegin(), 147 RHS.getSourceRange().getBegin()); 148 } 149}; 150 151/// \brief This class represents all comments included in the translation unit, 152/// sorted in order of appearance in the translation unit. 153class RawCommentList { 154public: 155 RawCommentList(SourceManager &SourceMgr) : 156 SourceMgr(SourceMgr), OnlyWhitespaceSeen(true) { } 157 158 void addComment(const RawComment &RC); 159 160 ArrayRef<RawComment> getComments() const { 161 return Comments; 162 } 163 164private: 165 SourceManager &SourceMgr; 166 std::vector<RawComment> Comments; 167 RawComment LastComment; 168 bool OnlyWhitespaceSeen; 169 170 void addCommentsToFront(const std::vector<RawComment> &C) { 171 size_t OldSize = Comments.size(); 172 Comments.resize(C.size() + OldSize); 173 std::copy_backward(Comments.begin(), Comments.begin() + OldSize, 174 Comments.end()); 175 std::copy(C.begin(), C.end(), Comments.begin()); 176 } 177 178 friend class ASTReader; 179}; 180 181} // end namespace clang 182 183#endif 184 185