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