RawCommentList.h revision 2d44d77fed3200e2eff289f55493317e90d3398c
12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//===--- RawCommentList.h - Classes for processing raw comments -*- C++ -*-===//
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//                     The LLVM Compiler Infrastructure
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// This file is distributed under the University of Illinois Open Source
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// License. See LICENSE.TXT for details.
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//
8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)//===----------------------------------------------------------------------===//
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef LLVM_CLANG_AST_RAW_COMMENT_LIST_H
11f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#define LLVM_CLANG_AST_RAW_COMMENT_LIST_H
12d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "clang/Basic/SourceManager.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "llvm/ADT/ArrayRef.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace clang {
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class ASTContext;
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class ASTReader;
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class RawComment {
22a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)public:
23a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  enum CommentKind {
247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    CK_Invalid,      ///< Invalid comment
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CK_OrdinaryBCPL, ///< Any normal BCPL comments
263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    CK_OrdinaryC,    ///< Any normal C comment
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    CK_BCPLSlash,    ///< \code /// stuff \endcode
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CK_BCPLExcl,     ///< \code //! stuff \endcode
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CK_JavaDoc,      ///< \code /** stuff */ \endcode
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CK_Qt,           ///< \code /*! stuff */ \endcode, also used by HeaderDoc
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CK_Merged        ///< Two or more documentation comments merged together
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RawComment() : Kind(CK_Invalid), IsAlmostTrailingComment(false) { }
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RawComment(const SourceManager &SourceMgr, SourceRange SR,
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)             bool Merged = false);
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CommentKind getKind() const LLVM_READONLY {
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return (CommentKind) Kind;
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool isInvalid() const LLVM_READONLY {
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return Kind == CK_Invalid;
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
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  StringRef 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 StringRef 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), Kind(K),
125    IsTrailingComment(IsTrailingComment),
126    IsAlmostTrailingComment(IsAlmostTrailingComment),
127    BeginLineValid(false), EndLineValid(false)
128  { }
129
130  StringRef getRawTextSlow(const SourceManager &SourceMgr) const;
131
132  StringRef 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