clang API Documentation

RawCommentList.h
Go to the documentation of this file.
00001 //===--- RawCommentList.h - Classes for processing raw comments -*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 
00010 #ifndef LLVM_CLANG_AST_RAWCOMMENTLIST_H
00011 #define LLVM_CLANG_AST_RAWCOMMENTLIST_H
00012 
00013 #include "clang/Basic/CommentOptions.h"
00014 #include "clang/Basic/SourceManager.h"
00015 #include "llvm/ADT/ArrayRef.h"
00016 
00017 namespace clang {
00018 
00019 class ASTContext;
00020 class ASTReader;
00021 class Decl;
00022 class Preprocessor;
00023 
00024 namespace comments {
00025   class FullComment;
00026 } // end namespace comments
00027 
00028 class RawComment {
00029 public:
00030   enum CommentKind {
00031     RCK_Invalid,      ///< Invalid comment
00032     RCK_OrdinaryBCPL, ///< Any normal BCPL comments
00033     RCK_OrdinaryC,    ///< Any normal C comment
00034     RCK_BCPLSlash,    ///< \code /// stuff \endcode
00035     RCK_BCPLExcl,     ///< \code //! stuff \endcode
00036     RCK_JavaDoc,      ///< \code /** stuff */ \endcode
00037     RCK_Qt,           ///< \code /*! stuff */ \endcode, also used by HeaderDoc
00038     RCK_Merged        ///< Two or more documentation comments merged together
00039   };
00040 
00041   RawComment() : Kind(RCK_Invalid), IsAlmostTrailingComment(false) { }
00042 
00043   RawComment(const SourceManager &SourceMgr, SourceRange SR,
00044              bool Merged, bool ParseAllComments);
00045 
00046   CommentKind getKind() const LLVM_READONLY {
00047     return (CommentKind) Kind;
00048   }
00049 
00050   bool isInvalid() const LLVM_READONLY {
00051     return Kind == RCK_Invalid;
00052   }
00053 
00054   bool isMerged() const LLVM_READONLY {
00055     return Kind == RCK_Merged;
00056   }
00057 
00058   /// Is this comment attached to any declaration?
00059   bool isAttached() const LLVM_READONLY {
00060     return IsAttached;
00061   }
00062 
00063   void setAttached() {
00064     IsAttached = true;
00065   }
00066 
00067   /// Returns true if it is a comment that should be put after a member:
00068   /// \code ///< stuff \endcode
00069   /// \code //!< stuff \endcode
00070   /// \code /**< stuff */ \endcode
00071   /// \code /*!< stuff */ \endcode
00072   bool isTrailingComment() const LLVM_READONLY {
00073     assert(isDocumentation());
00074     return IsTrailingComment;
00075   }
00076 
00077   /// Returns true if it is a probable typo:
00078   /// \code //< stuff \endcode
00079   /// \code /*< stuff */ \endcode
00080   bool isAlmostTrailingComment() const LLVM_READONLY {
00081     return IsAlmostTrailingComment;
00082   }
00083 
00084   /// Returns true if this comment is not a documentation comment.
00085   bool isOrdinary() const LLVM_READONLY {
00086     return ((Kind == RCK_OrdinaryBCPL) || (Kind == RCK_OrdinaryC)) &&
00087         !ParseAllComments;
00088   }
00089 
00090   /// Returns true if this comment any kind of a documentation comment.
00091   bool isDocumentation() const LLVM_READONLY {
00092     return !isInvalid() && !isOrdinary();
00093   }
00094 
00095   /// Returns whether we are parsing all comments.
00096   bool isParseAllComments() const LLVM_READONLY {
00097     return ParseAllComments;
00098   }
00099 
00100   /// Returns raw comment text with comment markers.
00101   StringRef getRawText(const SourceManager &SourceMgr) const {
00102     if (RawTextValid)
00103       return RawText;
00104 
00105     RawText = getRawTextSlow(SourceMgr);
00106     RawTextValid = true;
00107     return RawText;
00108   }
00109 
00110   SourceRange getSourceRange() const LLVM_READONLY { return Range; }
00111   SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); }
00112   SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); }
00113 
00114   const char *getBriefText(const ASTContext &Context) const {
00115     if (BriefTextValid)
00116       return BriefText;
00117 
00118     return extractBriefText(Context);
00119   }
00120 
00121   /// Parse the comment, assuming it is attached to decl \c D.
00122   comments::FullComment *parse(const ASTContext &Context,
00123                                const Preprocessor *PP, const Decl *D) const;
00124 
00125 private:
00126   SourceRange Range;
00127 
00128   mutable StringRef RawText;
00129   mutable const char *BriefText;
00130 
00131   mutable bool RawTextValid : 1;   ///< True if RawText is valid
00132   mutable bool BriefTextValid : 1; ///< True if BriefText is valid
00133 
00134   unsigned Kind : 3;
00135 
00136   /// True if comment is attached to a declaration in ASTContext.
00137   bool IsAttached : 1;
00138 
00139   bool IsTrailingComment : 1;
00140   bool IsAlmostTrailingComment : 1;
00141 
00142   /// When true, ordinary comments starting with "//" and "/*" will be
00143   /// considered as documentation comments.
00144   bool ParseAllComments : 1;
00145 
00146   /// \brief Constructor for AST deserialization.
00147   RawComment(SourceRange SR, CommentKind K, bool IsTrailingComment,
00148              bool IsAlmostTrailingComment,
00149              bool ParseAllComments) :
00150     Range(SR), RawTextValid(false), BriefTextValid(false), Kind(K),
00151     IsAttached(false), IsTrailingComment(IsTrailingComment),
00152     IsAlmostTrailingComment(IsAlmostTrailingComment),
00153     ParseAllComments(ParseAllComments)
00154   { }
00155 
00156   StringRef getRawTextSlow(const SourceManager &SourceMgr) const;
00157 
00158   const char *extractBriefText(const ASTContext &Context) const;
00159 
00160   friend class ASTReader;
00161 };
00162 
00163 /// \brief Compare comments' source locations.
00164 template<>
00165 class BeforeThanCompare<RawComment> {
00166   const SourceManager &SM;
00167 
00168 public:
00169   explicit BeforeThanCompare(const SourceManager &SM) : SM(SM) { }
00170 
00171   bool operator()(const RawComment &LHS, const RawComment &RHS) {
00172     return SM.isBeforeInTranslationUnit(LHS.getLocStart(), RHS.getLocStart());
00173   }
00174 
00175   bool operator()(const RawComment *LHS, const RawComment *RHS) {
00176     return operator()(*LHS, *RHS);
00177   }
00178 };
00179 
00180 /// \brief This class represents all comments included in the translation unit,
00181 /// sorted in order of appearance in the translation unit.
00182 class RawCommentList {
00183 public:
00184   RawCommentList(SourceManager &SourceMgr) : SourceMgr(SourceMgr) {}
00185 
00186   void addComment(const RawComment &RC, llvm::BumpPtrAllocator &Allocator);
00187 
00188   ArrayRef<RawComment *> getComments() const {
00189     return Comments;
00190   }
00191 
00192 private:
00193   SourceManager &SourceMgr;
00194   std::vector<RawComment *> Comments;
00195 
00196   void addDeserializedComments(ArrayRef<RawComment *> DeserializedComments);
00197 
00198   friend class ASTReader;
00199 };
00200 
00201 } // end namespace clang
00202 
00203 #endif