1239313Sdim//===--- RawCommentList.h - Classes for processing raw comments -*- C++ -*-===// 2239313Sdim// 3239313Sdim// The LLVM Compiler Infrastructure 4239313Sdim// 5239313Sdim// This file is distributed under the University of Illinois Open Source 6239313Sdim// License. See LICENSE.TXT for details. 7239313Sdim// 8239313Sdim//===----------------------------------------------------------------------===// 9239313Sdim 10239313Sdim#ifndef LLVM_CLANG_AST_RAW_COMMENT_LIST_H 11239313Sdim#define LLVM_CLANG_AST_RAW_COMMENT_LIST_H 12239313Sdim 13252723Sdim#include "clang/Basic/CommentOptions.h" 14239313Sdim#include "clang/Basic/SourceManager.h" 15239313Sdim#include "llvm/ADT/ArrayRef.h" 16239313Sdim 17239313Sdimnamespace clang { 18239313Sdim 19239313Sdimclass ASTContext; 20239313Sdimclass ASTReader; 21239313Sdimclass Decl; 22245431Sdimclass Preprocessor; 23239313Sdim 24239313Sdimnamespace comments { 25239313Sdim class FullComment; 26239313Sdim} // end namespace comments 27239313Sdim 28239313Sdimclass RawComment { 29239313Sdimpublic: 30239313Sdim enum CommentKind { 31239313Sdim RCK_Invalid, ///< Invalid comment 32239313Sdim RCK_OrdinaryBCPL, ///< Any normal BCPL comments 33239313Sdim RCK_OrdinaryC, ///< Any normal C comment 34239313Sdim RCK_BCPLSlash, ///< \code /// stuff \endcode 35239313Sdim RCK_BCPLExcl, ///< \code //! stuff \endcode 36239313Sdim RCK_JavaDoc, ///< \code /** stuff */ \endcode 37239313Sdim RCK_Qt, ///< \code /*! stuff */ \endcode, also used by HeaderDoc 38239313Sdim RCK_Merged ///< Two or more documentation comments merged together 39239313Sdim }; 40239313Sdim 41239313Sdim RawComment() : Kind(RCK_Invalid), IsAlmostTrailingComment(false) { } 42239313Sdim 43239313Sdim RawComment(const SourceManager &SourceMgr, SourceRange SR, 44252723Sdim bool Merged, bool ParseAllComments); 45239313Sdim 46239313Sdim CommentKind getKind() const LLVM_READONLY { 47239313Sdim return (CommentKind) Kind; 48239313Sdim } 49239313Sdim 50239313Sdim bool isInvalid() const LLVM_READONLY { 51239313Sdim return Kind == RCK_Invalid; 52239313Sdim } 53239313Sdim 54239313Sdim bool isMerged() const LLVM_READONLY { 55239313Sdim return Kind == RCK_Merged; 56239313Sdim } 57239313Sdim 58239313Sdim /// Is this comment attached to any declaration? 59239313Sdim bool isAttached() const LLVM_READONLY { 60239462Sdim return IsAttached; 61239313Sdim } 62239313Sdim 63239462Sdim void setAttached() { 64239462Sdim IsAttached = true; 65239313Sdim } 66239313Sdim 67239313Sdim /// Returns true if it is a comment that should be put after a member: 68239313Sdim /// \code ///< stuff \endcode 69239313Sdim /// \code //!< stuff \endcode 70239313Sdim /// \code /**< stuff */ \endcode 71239313Sdim /// \code /*!< stuff */ \endcode 72239313Sdim bool isTrailingComment() const LLVM_READONLY { 73239313Sdim assert(isDocumentation()); 74239313Sdim return IsTrailingComment; 75239313Sdim } 76239313Sdim 77239313Sdim /// Returns true if it is a probable typo: 78239313Sdim /// \code //< stuff \endcode 79239313Sdim /// \code /*< stuff */ \endcode 80239313Sdim bool isAlmostTrailingComment() const LLVM_READONLY { 81239313Sdim return IsAlmostTrailingComment; 82239313Sdim } 83239313Sdim 84239313Sdim /// Returns true if this comment is not a documentation comment. 85239313Sdim bool isOrdinary() const LLVM_READONLY { 86252723Sdim return ((Kind == RCK_OrdinaryBCPL) || (Kind == RCK_OrdinaryC)) && 87252723Sdim !ParseAllComments; 88239313Sdim } 89239313Sdim 90239313Sdim /// Returns true if this comment any kind of a documentation comment. 91239313Sdim bool isDocumentation() const LLVM_READONLY { 92239313Sdim return !isInvalid() && !isOrdinary(); 93239313Sdim } 94239313Sdim 95252723Sdim /// Returns whether we are parsing all comments. 96252723Sdim bool isParseAllComments() const LLVM_READONLY { 97252723Sdim return ParseAllComments; 98252723Sdim } 99252723Sdim 100239313Sdim /// Returns raw comment text with comment markers. 101239313Sdim StringRef getRawText(const SourceManager &SourceMgr) const { 102239313Sdim if (RawTextValid) 103239313Sdim return RawText; 104239313Sdim 105239313Sdim RawText = getRawTextSlow(SourceMgr); 106239313Sdim RawTextValid = true; 107239313Sdim return RawText; 108239313Sdim } 109239313Sdim 110263509Sdim SourceRange getSourceRange() const LLVM_READONLY { return Range; } 111263509Sdim SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); } 112263509Sdim SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); } 113239313Sdim 114239313Sdim const char *getBriefText(const ASTContext &Context) const { 115239313Sdim if (BriefTextValid) 116239313Sdim return BriefText; 117239313Sdim 118239313Sdim return extractBriefText(Context); 119239313Sdim } 120239313Sdim 121239462Sdim /// Parse the comment, assuming it is attached to decl \c D. 122245431Sdim comments::FullComment *parse(const ASTContext &Context, 123245431Sdim const Preprocessor *PP, const Decl *D) const; 124239313Sdim 125239313Sdimprivate: 126239313Sdim SourceRange Range; 127239313Sdim 128239313Sdim mutable StringRef RawText; 129239313Sdim mutable const char *BriefText; 130239313Sdim 131239313Sdim mutable bool RawTextValid : 1; ///< True if RawText is valid 132239313Sdim mutable bool BriefTextValid : 1; ///< True if BriefText is valid 133239313Sdim 134239313Sdim unsigned Kind : 3; 135239313Sdim 136239462Sdim /// True if comment is attached to a declaration in ASTContext. 137239462Sdim bool IsAttached : 1; 138239462Sdim 139239313Sdim bool IsTrailingComment : 1; 140239313Sdim bool IsAlmostTrailingComment : 1; 141239313Sdim 142252723Sdim /// When true, ordinary comments starting with "//" and "/*" will be 143252723Sdim /// considered as documentation comments. 144252723Sdim bool ParseAllComments : 1; 145252723Sdim 146239313Sdim /// \brief Constructor for AST deserialization. 147239313Sdim RawComment(SourceRange SR, CommentKind K, bool IsTrailingComment, 148252723Sdim bool IsAlmostTrailingComment, 149252723Sdim bool ParseAllComments) : 150239313Sdim Range(SR), RawTextValid(false), BriefTextValid(false), Kind(K), 151239462Sdim IsAttached(false), IsTrailingComment(IsTrailingComment), 152239313Sdim IsAlmostTrailingComment(IsAlmostTrailingComment), 153263509Sdim ParseAllComments(ParseAllComments) 154239313Sdim { } 155239313Sdim 156239313Sdim StringRef getRawTextSlow(const SourceManager &SourceMgr) const; 157239313Sdim 158239313Sdim const char *extractBriefText(const ASTContext &Context) const; 159239313Sdim 160239313Sdim friend class ASTReader; 161239313Sdim}; 162239313Sdim 163239313Sdim/// \brief Compare comments' source locations. 164239313Sdimtemplate<> 165239313Sdimclass BeforeThanCompare<RawComment> { 166239313Sdim const SourceManager &SM; 167239313Sdim 168239313Sdimpublic: 169239313Sdim explicit BeforeThanCompare(const SourceManager &SM) : SM(SM) { } 170239313Sdim 171239313Sdim bool operator()(const RawComment &LHS, const RawComment &RHS) { 172263509Sdim return SM.isBeforeInTranslationUnit(LHS.getLocStart(), RHS.getLocStart()); 173239313Sdim } 174239313Sdim 175239313Sdim bool operator()(const RawComment *LHS, const RawComment *RHS) { 176239313Sdim return operator()(*LHS, *RHS); 177239313Sdim } 178239313Sdim}; 179239313Sdim 180239313Sdim/// \brief This class represents all comments included in the translation unit, 181239313Sdim/// sorted in order of appearance in the translation unit. 182239313Sdimclass RawCommentList { 183239313Sdimpublic: 184263509Sdim RawCommentList(SourceManager &SourceMgr) : SourceMgr(SourceMgr) {} 185239313Sdim 186239313Sdim void addComment(const RawComment &RC, llvm::BumpPtrAllocator &Allocator); 187239313Sdim 188239313Sdim ArrayRef<RawComment *> getComments() const { 189239313Sdim return Comments; 190239313Sdim } 191239313Sdim 192239313Sdimprivate: 193239313Sdim SourceManager &SourceMgr; 194239313Sdim std::vector<RawComment *> Comments; 195239313Sdim 196239313Sdim void addCommentsToFront(const std::vector<RawComment *> &C) { 197263509Sdim Comments.insert(Comments.begin(), C.begin(), C.end()); 198239313Sdim } 199239313Sdim 200239313Sdim friend class ASTReader; 201239313Sdim}; 202239313Sdim 203239313Sdim} // end namespace clang 204239313Sdim 205239313Sdim#endif 206