Comment.h revision 88815f3f81361692dd281000e3e46bf163b2f28b
15f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===--- Comment.h - Comment AST nodes --------------------------*- C++ -*-===//
25f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
35f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//                     The LLVM Compiler Infrastructure
45f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// This file is distributed under the University of Illinois Open Source
60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// License. See LICENSE.TXT for details.
75f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
85f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
95f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//  This file defines comment AST nodes.
115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//
125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===//
135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#ifndef LLVM_CLANG_AST_COMMENT_H
15bdc601b196c48d4cd56a5ceb45d41ae4e87371abKen Dyck#define LLVM_CLANG_AST_COMMENT_H
161abee64ad71519ea9d91f1fe76441b9cdb75b6c0Dmitri Gribenko
178d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko#include "clang/Basic/SourceLocation.h"
188d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko#include "clang/AST/Type.h"
198d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko#include "llvm/ADT/ArrayRef.h"
2049aa7ff1245abd03e6e998e01302df31e4c6f8f6Argyrios Kyrtzidis#include "llvm/ADT/StringRef.h"
21980e508ca70d6de75d2abfd96b4681fc98bb2698Steve Naroff
22aaba5e346dffdbad5d1c42765a89e4a7afb0da67Douglas Gregornamespace clang {
23b17166c8077cd900cca83a895c43b30ea6660598Argyrios Kyrtzidisclass Decl;
24e91593ef084479340582b2ba177b44be50a717b7Daniel Dunbarclass ParmVarDecl;
25ea1471e0e967548c596a71469702f8846dbaf3c0John McCallclass TemplateParameterList;
262cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
277b90340c9c7d07aef4e301e72b5e8a30d5f4f0c8Argyrios Kyrtzidisnamespace comments {
2819cc4abea06a9b49e0e16a50d335c064cd723572Anders Carlsson
2914110477887e3dc168ffc6c191e72d705051f99ePeter Collingbourne/// Any part of the comment.
301b63e4f732dbc73d90abf886b4d21f8e3a165f6dChris Lattner/// Abstract class.
31a9376d470ccb0eac74fe09a6b2a18a890f1d17c4Chris Lattnerclass Comment {
325f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerprotected:
33f5942a44880be26878592eb052b737579349411eBenjamin Kramer  /// Preferred location to show caret.
3485f9bceab1542aafff012d4d28e998f4ba16e362Anders Carlsson  SourceLocation Loc;
356fe7c8aa8c7546743ecd0ac0138c2cf5d8155386Nate Begeman
36f5942a44880be26878592eb052b737579349411eBenjamin Kramer  /// Source range of this AST node.
370c8cd1ac55720276ad41fa7b4f8785bead5afd32Ted Kremenek  SourceRange Range;
38071cc7deffad608165b1ddd5263e8bf181861520Charles Davis
392636197098e02fd7c90f9496056b8ab886dcbff0Argyrios Kyrtzidis  class CommentBitfields {
4029445a0542d128cd7ee587ee52229670b9b54a12Anders Carlsson    friend class Comment;
415f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
425f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    /// Type of this AST node.
431827403a7138946305c0058f262e02b595cf882fDouglas Gregor    unsigned Kind : 8;
441827403a7138946305c0058f262e02b595cf882fDouglas Gregor  };
45225843186e3972ce798d3de00f86da9008b15a0eDouglas Gregor  enum { NumCommentBits = 8 };
46225843186e3972ce798d3de00f86da9008b15a0eDouglas Gregor
47ffe37fdda5b4b4f162a45155c30d9f60ce110c12Sean Hunt  class InlineContentCommentBitfields {
48ffe37fdda5b4b4f162a45155c30d9f60ce110c12Sean Hunt    friend class InlineContentComment;
49a376d10acfacf19d6dfa41069f7929739a18dd7aDouglas Gregor
50a376d10acfacf19d6dfa41069f7929739a18dd7aDouglas Gregor    unsigned : NumCommentBits;
51ffe37fdda5b4b4f162a45155c30d9f60ce110c12Sean Hunt
52ffe37fdda5b4b4f162a45155c30d9f60ce110c12Sean Hunt    /// True if there is a newline after this inline content node.
534923aa25eb39d64106a5817c02d560a3aecf8b2cDouglas Gregor    /// (There is no separate AST node for a newline.)
544923aa25eb39d64106a5817c02d560a3aecf8b2cDouglas Gregor    unsigned HasTrailingNewline : 1;
554923aa25eb39d64106a5817c02d560a3aecf8b2cDouglas Gregor  };
565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  enum { NumInlineContentCommentBits = NumCommentBits + 1 };
57aa4a99b4a62615db243f7a5c433169f2fc704420Anton Korobeynikov
585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  class TextCommentBitfields {
595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    friend class TextComment;
60a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko
61aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko    unsigned : NumInlineContentCommentBits;
62aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko
63aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko    /// True if \c IsWhitespace field contains a valid value.
64aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko    mutable unsigned IsWhitespaceValid : 1;
65aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko
66aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko    /// True if this comment AST node contains only whitespace.
67aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko    mutable unsigned IsWhitespace : 1;
68c3fee3539fd00a6ce21dc1f574baf76686640072Dmitri Gribenko  };
69c3fee3539fd00a6ce21dc1f574baf76686640072Dmitri Gribenko  enum { NumTextCommentBits = NumInlineContentCommentBits + 2 };
70c3fee3539fd00a6ce21dc1f574baf76686640072Dmitri Gribenko
71c3fee3539fd00a6ce21dc1f574baf76686640072Dmitri Gribenko  class InlineCommandCommentBitfields {
72aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko    friend class InlineCommandComment;
73aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko
74aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko    unsigned : NumInlineContentCommentBits;
75aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko
7696b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko    unsigned RenderKind : 2;
7796b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko  };
7896b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko  enum { NumInlineCommandCommentBits = NumInlineContentCommentBits + 1 };
7996b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko
8096b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko  class HTMLStartTagCommentBitfields {
8196b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko    friend class HTMLStartTagComment;
8296b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko
83811c820257746b1799b790b6adc7804f44154011Dmitri Gribenko    unsigned : NumInlineContentCommentBits;
84aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko
85aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko    /// True if this tag is self-closing (e. g., <br />).  This is based on tag
86aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko    /// spelling in comment (plain <br> would not set this flag).
87aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko    unsigned IsSelfClosing : 1;
88aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko  };
89abd56c816e9164b17bb3e7154a511b0c9896ffdbDmitri Gribenko  enum { NumHTMLStartTagCommentBits = NumInlineContentCommentBits + 1 };
90abd56c816e9164b17bb3e7154a511b0c9896ffdbDmitri Gribenko
91abd56c816e9164b17bb3e7154a511b0c9896ffdbDmitri Gribenko  class ParagraphCommentBitfields {
92abd56c816e9164b17bb3e7154a511b0c9896ffdbDmitri Gribenko    friend class ParagraphComment;
93abd56c816e9164b17bb3e7154a511b0c9896ffdbDmitri Gribenko
94abd56c816e9164b17bb3e7154a511b0c9896ffdbDmitri Gribenko    unsigned : NumCommentBits;
95abd56c816e9164b17bb3e7154a511b0c9896ffdbDmitri Gribenko
96abd56c816e9164b17bb3e7154a511b0c9896ffdbDmitri Gribenko    /// True if \c IsWhitespace field contains a valid value.
9796b098674908eaa59a9128f3305cda6fbbdad563Dmitri Gribenko    mutable unsigned IsWhitespaceValid : 1;
98c27bc80a98b9558513b50956c930eedc9e461ae0Dmitri Gribenko
99c27bc80a98b9558513b50956c930eedc9e461ae0Dmitri Gribenko    /// True if this comment AST node contains only whitespace.
100abd56c816e9164b17bb3e7154a511b0c9896ffdbDmitri Gribenko    mutable unsigned IsWhitespace : 1;
101abd56c816e9164b17bb3e7154a511b0c9896ffdbDmitri Gribenko  };
102abd56c816e9164b17bb3e7154a511b0c9896ffdbDmitri Gribenko  enum { NumParagraphCommentBits = NumCommentBits + 2 };
103abd56c816e9164b17bb3e7154a511b0c9896ffdbDmitri Gribenko
104aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko  class ParamCommandCommentBitfields {
105aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko    friend class ParamCommandComment;
106aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko
107aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko    unsigned : NumCommentBits;
108aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko
109aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko    /// Parameter passing direction, see ParamCommandComment::PassDirection.
110a444f1856459130bd3a1bb8995331c9e367db04fDmitri Gribenko    unsigned Direction : 2;
111a444f1856459130bd3a1bb8995331c9e367db04fDmitri Gribenko
112a444f1856459130bd3a1bb8995331c9e367db04fDmitri Gribenko    /// True if direction was specified explicitly in the comment.
113a444f1856459130bd3a1bb8995331c9e367db04fDmitri Gribenko    unsigned IsDirectionExplicit : 1;
114a444f1856459130bd3a1bb8995331c9e367db04fDmitri Gribenko  };
115a444f1856459130bd3a1bb8995331c9e367db04fDmitri Gribenko  enum { NumParamCommandCommentBits = 11 };
116a444f1856459130bd3a1bb8995331c9e367db04fDmitri Gribenko
117a444f1856459130bd3a1bb8995331c9e367db04fDmitri Gribenko  union {
118a444f1856459130bd3a1bb8995331c9e367db04fDmitri Gribenko    CommentBitfields CommentBits;
119a444f1856459130bd3a1bb8995331c9e367db04fDmitri Gribenko    InlineContentCommentBitfields InlineContentCommentBits;
120a444f1856459130bd3a1bb8995331c9e367db04fDmitri Gribenko    TextCommentBitfields TextCommentBits;
121a444f1856459130bd3a1bb8995331c9e367db04fDmitri Gribenko    InlineCommandCommentBitfields InlineCommandCommentBits;
122a444f1856459130bd3a1bb8995331c9e367db04fDmitri Gribenko    HTMLStartTagCommentBitfields HTMLStartTagCommentBits;
123a444f1856459130bd3a1bb8995331c9e367db04fDmitri Gribenko    ParagraphCommentBitfields ParagraphCommentBits;
124a444f1856459130bd3a1bb8995331c9e367db04fDmitri Gribenko    ParamCommandCommentBitfields ParamCommandCommentBits;
125a444f1856459130bd3a1bb8995331c9e367db04fDmitri Gribenko  };
126a444f1856459130bd3a1bb8995331c9e367db04fDmitri Gribenko
127a444f1856459130bd3a1bb8995331c9e367db04fDmitri Gribenko  void setSourceRange(SourceRange SR) {
128a444f1856459130bd3a1bb8995331c9e367db04fDmitri Gribenko    Range = SR;
129a444f1856459130bd3a1bb8995331c9e367db04fDmitri Gribenko  }
130a444f1856459130bd3a1bb8995331c9e367db04fDmitri Gribenko
131a444f1856459130bd3a1bb8995331c9e367db04fDmitri Gribenko  void setLocation(SourceLocation L) {
132a444f1856459130bd3a1bb8995331c9e367db04fDmitri Gribenko    Loc = L;
133a444f1856459130bd3a1bb8995331c9e367db04fDmitri Gribenko  }
134aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko
135aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenkopublic:
136aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko  enum CommentKind {
137aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko    NoCommentKind = 0,
138aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko#define COMMENT(CLASS, PARENT) CLASS##Kind,
139aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko#define COMMENT_RANGE(BASE, FIRST, LAST) \
140aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko    First##BASE##Constant=FIRST##Kind, Last##BASE##Constant=LAST##Kind,
141811c820257746b1799b790b6adc7804f44154011Dmitri Gribenko#define LAST_COMMENT_RANGE(BASE, FIRST, LAST) \
1429c00676f2393335dc60c61faf944d4f8f622fac6Dmitri Gribenko    First##BASE##Constant=FIRST##Kind, Last##BASE##Constant=LAST##Kind
143aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko#define ABSTRACT_COMMENT(COMMENT)
144811c820257746b1799b790b6adc7804f44154011Dmitri Gribenko#include "clang/AST/CommentNodes.inc"
145aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko  };
146aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko
147aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko  Comment(CommentKind K,
148aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko          SourceLocation LocBegin,
149aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko          SourceLocation LocEnd) :
150aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko      Loc(LocBegin), Range(SourceRange(LocBegin, LocEnd)) {
151811c820257746b1799b790b6adc7804f44154011Dmitri Gribenko    CommentBits.Kind = K;
152aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko  }
153aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko
154aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko  CommentKind getCommentKind() const {
155aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko    return static_cast<CommentKind>(CommentBits.Kind);
156aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko  }
157aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko
158aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko  const char *getCommentKindName() const;
159aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko
160aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko  LLVM_ATTRIBUTE_USED void dump() const;
161aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko  LLVM_ATTRIBUTE_USED void dump(SourceManager &SM) const;
162811c820257746b1799b790b6adc7804f44154011Dmitri Gribenko  void dump(llvm::raw_ostream &OS, SourceManager *SM) const;
163aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko
164aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko  static bool classof(const Comment *) { return true; }
165aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko
166aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko  SourceRange getSourceRange() const LLVM_READONLY { return Range; }
167811c820257746b1799b790b6adc7804f44154011Dmitri Gribenko
168aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko  SourceLocation getLocStart() const LLVM_READONLY {
169aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko    return Range.getBegin();
170aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko  }
171aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko
172aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko  SourceLocation getLocEnd() const LLVM_READONLY {
173aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko    return Range.getEnd();
174aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko  }
175aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko
176aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko  SourceLocation getLocation() const LLVM_READONLY { return Loc; }
177aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko
178aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko  typedef Comment * const *child_iterator;
179aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko
180aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko  child_iterator child_begin() const;
181aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko  child_iterator child_end() const;
182aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko
183aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko  // TODO: const child iterator
184aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko
1858bdb58a7835a9a90dd9b9791fccf269cbc1dcef3Dmitri Gribenko  unsigned child_count() const {
1868bdb58a7835a9a90dd9b9791fccf269cbc1dcef3Dmitri Gribenko    return child_end() - child_begin();
187abd56c816e9164b17bb3e7154a511b0c9896ffdbDmitri Gribenko  }
188aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko};
189aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko
190811c820257746b1799b790b6adc7804f44154011Dmitri Gribenko/// Inline content (contained within a block).
191aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko/// Abstract class.
192aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenkoclass InlineContentComment : public Comment {
193aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenkoprotected:
194aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko  InlineContentComment(CommentKind K,
195aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko                       SourceLocation LocBegin,
1968d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko                       SourceLocation LocEnd) :
197aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko      Comment(K, LocBegin, LocEnd) {
1988d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko    InlineContentCommentBits.HasTrailingNewline = 0;
1998d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko  }
2008d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko
2018d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenkopublic:
202aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko  static bool classof(const Comment *C) {
203a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko    return C->getCommentKind() >= FirstInlineContentCommentConstant &&
2048376f5934a18b950ac7323d8a38ed231623010faDmitri Gribenko           C->getCommentKind() <= LastInlineContentCommentConstant;
2058376f5934a18b950ac7323d8a38ed231623010faDmitri Gribenko  }
2069bf997e63d4e4004588b374e702a5e64da5ebb49Dmitri Gribenko
2079bf997e63d4e4004588b374e702a5e64da5ebb49Dmitri Gribenko  static bool classof(const InlineContentComment *) { return true; }
208a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko
209a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko  void addTrailingNewline() {
210aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko    InlineContentCommentBits.HasTrailingNewline = 1;
211aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko  }
212aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko
2138d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko  bool hasTrailingNewline() const {
2148d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko    return InlineContentCommentBits.HasTrailingNewline;
2158d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko  }
2168d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko};
2178d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko
2188d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko/// Plain text.
2198d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenkoclass TextComment : public InlineContentComment {
2208d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko  StringRef Text;
2218d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko
2228d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenkopublic:
2238d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko  TextComment(SourceLocation LocBegin,
2248d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko              SourceLocation LocEnd,
2258d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko              StringRef Text) :
2268d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko      InlineContentComment(TextCommentKind, LocBegin, LocEnd),
2278d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko      Text(Text) {
2288d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko    TextCommentBits.IsWhitespaceValid = false;
229477a9f58c1b197f315befd03b42a8a0b3a2f0ff9Dmitri Gribenko  }
230477a9f58c1b197f315befd03b42a8a0b3a2f0ff9Dmitri Gribenko
2318d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko  static bool classof(const Comment *C) {
2328d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko    return C->getCommentKind() == TextCommentKind;
233a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko  }
234a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko
235a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko  static bool classof(const TextComment *) { return true; }
236a5ef44ff5d93a3be6ca67782828157a71894cf0cDmitri Gribenko
2378d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko  child_iterator child_begin() const { return NULL; }
2388d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko
2398d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko  child_iterator child_end() const { return NULL; }
2408d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko
2418d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko  StringRef getText() const LLVM_READONLY { return Text; }
2428d3ba23f2d9e6c87794d059412a0808c9cbacb25Dmitri Gribenko
2433e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor  bool isWhitespace() const {
2443e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor    if (TextCommentBits.IsWhitespaceValid)
2453e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor      return TextCommentBits.IsWhitespace;
2463e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor
2473e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor    TextCommentBits.IsWhitespace = isWhitespaceNoCache();
24861c4d28e36cd3f1be392cb77f07436d1fa6b0f9fDouglas Gregor    TextCommentBits.IsWhitespaceValid = true;
2493e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor    return TextCommentBits.IsWhitespace;
2503e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor  }
2513e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor
2523e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregorprivate:
2533e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor  bool isWhitespaceNoCache() const;
2543e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor};
2553e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor
2563e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor/// A command with word-like arguments that is considered inline content.
2573e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregorclass InlineCommandComment : public InlineContentComment {
2583e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregorpublic:
2593e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor  struct Argument {
2603e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor    SourceRange Range;
2613e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor    StringRef Text;
2623e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor
26361c4d28e36cd3f1be392cb77f07436d1fa6b0f9fDouglas Gregor    Argument(SourceRange Range, StringRef Text) : Range(Range), Text(Text) { }
2649e9c454b12671a624f666fc6fbf132fdf183effcEli Friedman  };
2656952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor
2666952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// The most appropriate rendering mode for this command, chosen on command
2676952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  /// semantics in Doxygen.
2689e9c454b12671a624f666fc6fbf132fdf183effcEli Friedman  enum RenderKind {
2699e9c454b12671a624f666fc6fbf132fdf183effcEli Friedman    RenderNormal,
2709e9c454b12671a624f666fc6fbf132fdf183effcEli Friedman    RenderBold,
2719e9c454b12671a624f666fc6fbf132fdf183effcEli Friedman    RenderMonospaced,
2726952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor    RenderEmphasized
2736952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  };
2743e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor
2753e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregorprotected:
2763e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor  /// Command name.
2773e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor  StringRef Name;
2783e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor
2793e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor  /// Command arguments.
2803e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor  llvm::ArrayRef<Argument> Args;
2813e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor
2823e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregorpublic:
2833e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor  InlineCommandComment(SourceLocation LocBegin,
2843e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor                       SourceLocation LocEnd,
2854ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad                       StringRef Name,
2863e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor                       RenderKind RK,
2873e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor                       llvm::ArrayRef<Argument> Args) :
2883e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor      InlineContentComment(InlineCommandCommentKind, LocBegin, LocEnd),
2893e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor      Name(Name), Args(Args) {
2903e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor    InlineCommandCommentBits.RenderKind = RK;
2913e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor  }
2923e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor
2933e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor  static bool classof(const Comment *C) {
2943e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor    return C->getCommentKind() == InlineCommandCommentKind;
2953e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor  }
2963e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor
2975f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  static bool classof(const InlineCommandComment *) { return true; }
2983e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor
2993e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor  child_iterator child_begin() const { return NULL; }
3003e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor
3013e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor  child_iterator child_end() const { return NULL; }
3023e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor
3033e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor  StringRef getCommandName() const {
3043e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor    return Name;
305344577e6b58f42d18dc8118c8903b49a85dc005eAbramo Bagnara  }
306344577e6b58f42d18dc8118c8903b49a85dc005eAbramo Bagnara
307344577e6b58f42d18dc8118c8903b49a85dc005eAbramo Bagnara  SourceRange getCommandNameRange() const {
3083e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor    return SourceRange(getLocStart().getLocWithOffset(-1),
3093e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor                       getLocEnd());
3103e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor  }
3116952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor
3126952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  RenderKind getRenderKind() const {
3136952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor    return static_cast<RenderKind>(InlineCommandCommentBits.RenderKind);
3146952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  }
3156952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor
3165f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner  unsigned getNumArgs() const {
3175f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner    return Args.size();
3186952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  }
3196952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor
3206952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  StringRef getArgText(unsigned Idx) const {
3216952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor    return Args[Idx].Text;
3226952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  }
3236952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor
3246952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  SourceRange getArgRange(unsigned Idx) const {
325ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara    return Args[Idx].Range;
326ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara  }
3276952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor};
3286952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor
3296952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor/// Abstract class for opening and closing HTML tags.  HTML tags are always
3306952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor/// treated as inline content (regardless HTML semantics); opening and closing
3316952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor/// tags are not matched.
3326952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregorclass HTMLTagComment : public InlineContentComment {
3336952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregorprotected:
3346952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  StringRef TagName;
3356952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor  SourceRange TagNameRange;
336ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara
337ff676cb48fe8bf7be2feaa251dc7c5fb15af4730Abramo Bagnara  HTMLTagComment(CommentKind K,
3386952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor                 SourceLocation LocBegin,
3396952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor                 SourceLocation LocEnd,
3406952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor                 StringRef TagName,
3416952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor                 SourceLocation TagNameBegin,
3426952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor                 SourceLocation TagNameEnd) :
3436952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor      InlineContentComment(K, LocBegin, LocEnd),
3446952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor      TagName(TagName),
3456952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor      TagNameRange(TagNameBegin, TagNameEnd) {
3466952f1e4256c5b43aee5e98cea4e9b663bd1d413Douglas Gregor    setLocation(TagNameBegin);
3473e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor  }
3483e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor
3493e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregorpublic:
3503e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor  static bool classof(const Comment *C) {
3513e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor    return C->getCommentKind() >= FirstHTMLTagCommentConstant &&
3523e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor           C->getCommentKind() <= LastHTMLTagCommentConstant;
3533e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor  }
35461c4d28e36cd3f1be392cb77f07436d1fa6b0f9fDouglas Gregor
35561c4d28e36cd3f1be392cb77f07436d1fa6b0f9fDouglas Gregor  static bool classof(const HTMLTagComment *) { return true; }
35661c4d28e36cd3f1be392cb77f07436d1fa6b0f9fDouglas Gregor
3573e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor  StringRef getTagName() const LLVM_READONLY { return TagName; }
3583e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor
3593e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor  SourceRange getTagNameSourceRange() const LLVM_READONLY {
3603e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor    SourceLocation L = getLocation();
3613e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor    return SourceRange(L.getLocWithOffset(1),
3623e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor                       L.getLocWithOffset(1 + TagName.size()));
3633e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor  }
3643e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor};
3653e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor
3663e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor/// An opening HTML tag with attributes.
3673e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregorclass HTMLStartTagComment : public HTMLTagComment {
3683e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregorpublic:
3693e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor  class Attribute {
3703e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor  public:
3713e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor    SourceLocation NameLocBegin;
3723e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor    StringRef Name;
3733e1274f2b99cb99c03cc8e2c6517c37d330b597aDouglas Gregor
374071cc7deffad608165b1ddd5263e8bf181861520Charles Davis    SourceLocation EqualsLoc;
375ee79a4c30e5d1c5285551c9a25b8ec6d45d46aa7John McCall
376ee79a4c30e5d1c5285551c9a25b8ec6d45d46aa7John McCall    SourceRange ValueRange;
37720cf717034ba1f20fc47c025ecb72ed9b631ad13Charles Davis    StringRef Value;
378ee79a4c30e5d1c5285551c9a25b8ec6d45d46aa7John McCall
379ee79a4c30e5d1c5285551c9a25b8ec6d45d46aa7John McCall    Attribute() { }
380ee79a4c30e5d1c5285551c9a25b8ec6d45d46aa7John McCall
381071cc7deffad608165b1ddd5263e8bf181861520Charles Davis    Attribute(SourceLocation NameLocBegin, StringRef Name) :
38220cf717034ba1f20fc47c025ecb72ed9b631ad13Charles Davis        NameLocBegin(NameLocBegin), Name(Name),
38320cf717034ba1f20fc47c025ecb72ed9b631ad13Charles Davis        EqualsLoc(SourceLocation()),
38420cf717034ba1f20fc47c025ecb72ed9b631ad13Charles Davis        ValueRange(SourceRange()), Value(StringRef())
3857530c034c0c71a64c5a9173206d9742ae847af8bDavid Blaikie    { }
386071cc7deffad608165b1ddd5263e8bf181861520Charles Davis
387071cc7deffad608165b1ddd5263e8bf181861520Charles Davis    Attribute(SourceLocation NameLocBegin, StringRef Name,
388bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor              SourceLocation EqualsLoc,
389207f4d8543529221932af82836016a2ef066c917Peter Collingbourne              SourceRange ValueRange, StringRef Value) :
390207f4d8543529221932af82836016a2ef066c917Peter Collingbourne        NameLocBegin(NameLocBegin), Name(Name),
391207f4d8543529221932af82836016a2ef066c917Peter Collingbourne        EqualsLoc(EqualsLoc),
392207f4d8543529221932af82836016a2ef066c917Peter Collingbourne        ValueRange(ValueRange), Value(Value)
393207f4d8543529221932af82836016a2ef066c917Peter Collingbourne    { }
394207f4d8543529221932af82836016a2ef066c917Peter Collingbourne
395207f4d8543529221932af82836016a2ef066c917Peter Collingbourne    SourceLocation getNameLocEnd() const {
3964dc34ebf2a0716bf77ba110dab6777a3fc4397ddPeter Collingbourne      return NameLocBegin.getLocWithOffset(Name.size());
3974dc34ebf2a0716bf77ba110dab6777a3fc4397ddPeter Collingbourne    }
3984dc34ebf2a0716bf77ba110dab6777a3fc4397ddPeter Collingbourne
3994dc34ebf2a0716bf77ba110dab6777a3fc4397ddPeter Collingbourne    SourceRange getNameRange() const {
400207f4d8543529221932af82836016a2ef066c917Peter Collingbourne      return SourceRange(NameLocBegin, getNameLocEnd());
401bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor    }
402207f4d8543529221932af82836016a2ef066c917Peter Collingbourne  };
403bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor
404207f4d8543529221932af82836016a2ef066c917Peter Collingbourneprivate:
405207f4d8543529221932af82836016a2ef066c917Peter Collingbourne  ArrayRef<Attribute> Attributes;
406207f4d8543529221932af82836016a2ef066c917Peter Collingbourne
4073e3cd93b2fd9644e970c389e715c13883faf68b6Douglas Gregorpublic:
408bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  HTMLStartTagComment(SourceLocation LocBegin,
409e91593ef084479340582b2ba177b44be50a717b7Daniel Dunbar                      StringRef TagName) :
4101b63e4f732dbc73d90abf886b4d21f8e3a165f6dChris Lattner      HTMLTagComment(HTMLStartTagCommentKind,
411bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor                     LocBegin, LocBegin.getLocWithOffset(1 + TagName.size()),
412bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor                     TagName,
413bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor                     LocBegin.getLocWithOffset(1),
414bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor                     LocBegin.getLocWithOffset(1 + TagName.size())) {
415bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor    HTMLStartTagCommentBits.IsSelfClosing = false;
416bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  }
417bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor
418bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  static bool classof(const Comment *C) {
419c5613b26a24a33d7450e3d0bf315c6ccc920ce7bMeador Inge    return C->getCommentKind() == HTMLStartTagCommentKind;
420a6ea10e22b600d92e084f6b11b9b9a92d0eb2412Douglas Gregor  }
421e97179c675b341927807c718be215c8d1aab8acbDouglas Gregor
422bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  static bool classof(const HTMLStartTagComment *) { return true; }
423e2d4f4ed44a32f179c6d48cd1dba8346ab2129d9Rafael Espindola
424e2d4f4ed44a32f179c6d48cd1dba8346ab2129d9Rafael Espindola  child_iterator child_begin() const { return NULL; }
425e2d4f4ed44a32f179c6d48cd1dba8346ab2129d9Rafael Espindola
426e664977aca2a05a77abab5a06dc0fb69e870cfb9Douglas Gregor  child_iterator child_end() const { return NULL; }
427e664977aca2a05a77abab5a06dc0fb69e870cfb9Douglas Gregor
428bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  unsigned getNumAttrs() const {
42930c42404202d2e2512e51efc6066bd614cfdb5a4Douglas Gregor    return Attributes.size();
430bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  }
431bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor
432bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  const Attribute &getAttr(unsigned Idx) const {
43330c42404202d2e2512e51efc6066bd614cfdb5a4Douglas Gregor    return Attributes[Idx];
434aa0cd85838f2a024e589ea4e8c2094130065af21Dmitri Gribenko  }
435bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor
436bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  void setAttrs(ArrayRef<Attribute> Attrs) {
437bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor    Attributes = Attrs;
4381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    if (!Attrs.empty()) {
439e91593ef084479340582b2ba177b44be50a717b7Daniel Dunbar      const Attribute &Attr = Attrs.back();
440bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      SourceLocation L = Attr.ValueRange.getEnd();
441bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      if (L.isValid())
442bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor        Range.setEnd(L);
443bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      else {
444bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor        Range.setEnd(Attr.getNameLocEnd());
445e91593ef084479340582b2ba177b44be50a717b7Daniel Dunbar      }
446e91593ef084479340582b2ba177b44be50a717b7Daniel Dunbar    }
4475f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
4483478eb6872d836600caf45b0f81c2065d685d6e0Ted Kremenek
4493478eb6872d836600caf45b0f81c2065d685d6e0Ted Kremenek  void setGreaterLoc(SourceLocation GreaterLoc) {
4503478eb6872d836600caf45b0f81c2065d685d6e0Ted Kremenek    Range.setEnd(GreaterLoc);
4517d10b7eb670b821741b4c96f6cf7afbc3bb39abeDouglas Gregor  }
45263fe86bee66fc145942c56b2cc564ea0b9b9ea12Douglas Gregor
45363fe86bee66fc145942c56b2cc564ea0b9b9ea12Douglas Gregor  bool isSelfClosing() const {
45463fe86bee66fc145942c56b2cc564ea0b9b9ea12Douglas Gregor    return HTMLStartTagCommentBits.IsSelfClosing;
4550054531488928a424666ac11fcdc6bcc5112de52Douglas Gregor  }
456dcfcfbec478f7ed96cd8d92f30c29bd4e30d5b9cTed Kremenek
45763fe86bee66fc145942c56b2cc564ea0b9b9ea12Douglas Gregor  void setSelfClosing() {
45863fe86bee66fc145942c56b2cc564ea0b9b9ea12Douglas Gregor    HTMLStartTagCommentBits.IsSelfClosing = true;
45963fe86bee66fc145942c56b2cc564ea0b9b9ea12Douglas Gregor  }
46063fe86bee66fc145942c56b2cc564ea0b9b9ea12Douglas Gregor};
46163fe86bee66fc145942c56b2cc564ea0b9b9ea12Douglas Gregor
46263fe86bee66fc145942c56b2cc564ea0b9b9ea12Douglas Gregor/// A closing HTML tag.
46363fe86bee66fc145942c56b2cc564ea0b9b9ea12Douglas Gregorclass HTMLEndTagComment : public HTMLTagComment {
46463fe86bee66fc145942c56b2cc564ea0b9b9ea12Douglas Gregorpublic:
465dcfcfbec478f7ed96cd8d92f30c29bd4e30d5b9cTed Kremenek  HTMLEndTagComment(SourceLocation LocBegin,
466dcfcfbec478f7ed96cd8d92f30c29bd4e30d5b9cTed Kremenek                    SourceLocation LocEnd,
467dcfcfbec478f7ed96cd8d92f30c29bd4e30d5b9cTed Kremenek                    StringRef TagName) :
468dcfcfbec478f7ed96cd8d92f30c29bd4e30d5b9cTed Kremenek      HTMLTagComment(HTMLEndTagCommentKind,
469dcfcfbec478f7ed96cd8d92f30c29bd4e30d5b9cTed Kremenek                     LocBegin, LocEnd,
470dcfcfbec478f7ed96cd8d92f30c29bd4e30d5b9cTed Kremenek                     TagName,
4716320064d0c60fa8683f5623881c9394fd4aa7689Douglas Gregor                     LocBegin.getLocWithOffset(2),
4726320064d0c60fa8683f5623881c9394fd4aa7689Douglas Gregor                     LocBegin.getLocWithOffset(2 + TagName.size()))
4736320064d0c60fa8683f5623881c9394fd4aa7689Douglas Gregor  { }
4746320064d0c60fa8683f5623881c9394fd4aa7689Douglas Gregor
4756320064d0c60fa8683f5623881c9394fd4aa7689Douglas Gregor  static bool classof(const Comment *C) {
4766320064d0c60fa8683f5623881c9394fd4aa7689Douglas Gregor    return C->getCommentKind() == HTMLEndTagCommentKind;
477ab452ba8323d1985e08bade2bced588cddf2cc28Douglas Gregor  }
4780054531488928a424666ac11fcdc6bcc5112de52Douglas Gregor
4790054531488928a424666ac11fcdc6bcc5112de52Douglas Gregor  static bool classof(const HTMLEndTagComment *) { return true; }
4800054531488928a424666ac11fcdc6bcc5112de52Douglas Gregor
4810054531488928a424666ac11fcdc6bcc5112de52Douglas Gregor  child_iterator child_begin() const { return NULL; }
4821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4836f42b62b6194f53bcbc349f5d17388e1936535d7Dylan Noblesmith  child_iterator child_end() const { return NULL; }
4842cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor};
4852cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
4862cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor/// Block content (contains inline content).
4875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// Abstract class.
488cd92a65edc7cbbbb7e3aee8d31008594de90fa51Chandler Carruthclass BlockContentComment : public Comment {
489cd92a65edc7cbbbb7e3aee8d31008594de90fa51Chandler Carruthprotected:
4907c80bd64032e610c0dbd74fc0ef6ea334447f2fdSebastian Redl  BlockContentComment(CommentKind K,
491dbe833da54e1b6192991b64fc453cd50b5ee7909Douglas Gregor                      SourceLocation LocBegin,
4921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                      SourceLocation LocEnd) :
493dbe833da54e1b6192991b64fc453cd50b5ee7909Douglas Gregor      Comment(K, LocBegin, LocEnd)
494dbe833da54e1b6192991b64fc453cd50b5ee7909Douglas Gregor  { }
495dbe833da54e1b6192991b64fc453cd50b5ee7909Douglas Gregor
496dbe833da54e1b6192991b64fc453cd50b5ee7909Douglas Gregorpublic:
497c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor  static bool classof(const Comment *C) {
4985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return C->getCommentKind() >= FirstBlockContentCommentConstant &&
4995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer           C->getCommentKind() <= LastBlockContentCommentConstant;
500dbe833da54e1b6192991b64fc453cd50b5ee7909Douglas Gregor  }
5015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
5025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static bool classof(const BlockContentComment *) { return true; }
503dbe833da54e1b6192991b64fc453cd50b5ee7909Douglas Gregor};
504dbe833da54e1b6192991b64fc453cd50b5ee7909Douglas Gregor
505dbe833da54e1b6192991b64fc453cd50b5ee7909Douglas Gregor/// A single paragraph that contains inline content.
506dbe833da54e1b6192991b64fc453cd50b5ee7909Douglas Gregorclass ParagraphComment : public BlockContentComment {
507cd92a65edc7cbbbb7e3aee8d31008594de90fa51Chandler Carruth  llvm::ArrayRef<InlineContentComment *> Content;
508cd92a65edc7cbbbb7e3aee8d31008594de90fa51Chandler Carruth
509dbe833da54e1b6192991b64fc453cd50b5ee7909Douglas Gregorpublic:
510dbe833da54e1b6192991b64fc453cd50b5ee7909Douglas Gregor  ParagraphComment(llvm::ArrayRef<InlineContentComment *> Content) :
511dbe833da54e1b6192991b64fc453cd50b5ee7909Douglas Gregor      BlockContentComment(ParagraphCommentKind,
512dbe833da54e1b6192991b64fc453cd50b5ee7909Douglas Gregor                          SourceLocation(),
5131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump                          SourceLocation()),
514cd92a65edc7cbbbb7e3aee8d31008594de90fa51Chandler Carruth      Content(Content) {
515cd92a65edc7cbbbb7e3aee8d31008594de90fa51Chandler Carruth    if (Content.empty()) {
5164923aa25eb39d64106a5817c02d560a3aecf8b2cDouglas Gregor      ParagraphCommentBits.IsWhitespace = true;
517cd92a65edc7cbbbb7e3aee8d31008594de90fa51Chandler Carruth      ParagraphCommentBits.IsWhitespaceValid = true;
518cd92a65edc7cbbbb7e3aee8d31008594de90fa51Chandler Carruth      return;
519cd92a65edc7cbbbb7e3aee8d31008594de90fa51Chandler Carruth    }
520cd92a65edc7cbbbb7e3aee8d31008594de90fa51Chandler Carruth
521cd92a65edc7cbbbb7e3aee8d31008594de90fa51Chandler Carruth    ParagraphCommentBits.IsWhitespaceValid = false;
522cd92a65edc7cbbbb7e3aee8d31008594de90fa51Chandler Carruth
5234e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie    setSourceRange(SourceRange(Content.front()->getLocStart(),
524cd92a65edc7cbbbb7e3aee8d31008594de90fa51Chandler Carruth                               Content.back()->getLocEnd()));
525cd92a65edc7cbbbb7e3aee8d31008594de90fa51Chandler Carruth    setLocation(Content.front()->getLocStart());
526cd92a65edc7cbbbb7e3aee8d31008594de90fa51Chandler Carruth  }
527cd92a65edc7cbbbb7e3aee8d31008594de90fa51Chandler Carruth
528cd92a65edc7cbbbb7e3aee8d31008594de90fa51Chandler Carruth  static bool classof(const Comment *C) {
529cd92a65edc7cbbbb7e3aee8d31008594de90fa51Chandler Carruth    return C->getCommentKind() == ParagraphCommentKind;
5304e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie  }
531cd92a65edc7cbbbb7e3aee8d31008594de90fa51Chandler Carruth
532cd92a65edc7cbbbb7e3aee8d31008594de90fa51Chandler Carruth  static bool classof(const ParagraphComment *) { return true; }
533cd92a65edc7cbbbb7e3aee8d31008594de90fa51Chandler Carruth
534cd92a65edc7cbbbb7e3aee8d31008594de90fa51Chandler Carruth  child_iterator child_begin() const {
535cd92a65edc7cbbbb7e3aee8d31008594de90fa51Chandler Carruth    return reinterpret_cast<child_iterator>(Content.begin());
536cd92a65edc7cbbbb7e3aee8d31008594de90fa51Chandler Carruth  }
537cd92a65edc7cbbbb7e3aee8d31008594de90fa51Chandler Carruth
5382cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  child_iterator child_end() const {
539cd92a65edc7cbbbb7e3aee8d31008594de90fa51Chandler Carruth    return reinterpret_cast<child_iterator>(Content.end());
5402cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  }
5412cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
542cd92a65edc7cbbbb7e3aee8d31008594de90fa51Chandler Carruth  bool isWhitespace() const {
54363fe86bee66fc145942c56b2cc564ea0b9b9ea12Douglas Gregor    if (ParagraphCommentBits.IsWhitespaceValid)
5445f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      return ParagraphCommentBits.IsWhitespace;
5455f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
546772eeaefef2c883aabe35caf4543e7e32d290183Douglas Gregor    ParagraphCommentBits.IsWhitespace = isWhitespaceNoCache();
547772eeaefef2c883aabe35caf4543e7e32d290183Douglas Gregor    ParagraphCommentBits.IsWhitespaceValid = true;
548772eeaefef2c883aabe35caf4543e7e32d290183Douglas Gregor    return ParagraphCommentBits.IsWhitespace;
549772eeaefef2c883aabe35caf4543e7e32d290183Douglas Gregor  }
550772eeaefef2c883aabe35caf4543e7e32d290183Douglas Gregor
551772eeaefef2c883aabe35caf4543e7e32d290183Douglas Gregorprivate:
552772eeaefef2c883aabe35caf4543e7e32d290183Douglas Gregor  bool isWhitespaceNoCache() const;
553772eeaefef2c883aabe35caf4543e7e32d290183Douglas Gregor};
554772eeaefef2c883aabe35caf4543e7e32d290183Douglas Gregor
555772eeaefef2c883aabe35caf4543e7e32d290183Douglas Gregor/// A command that has zero or more word-like arguments (number of word-like
556772eeaefef2c883aabe35caf4543e7e32d290183Douglas Gregor/// arguments depends on command name) and a paragraph as an argument
557772eeaefef2c883aabe35caf4543e7e32d290183Douglas Gregor/// (e. g., \\brief).
558772eeaefef2c883aabe35caf4543e7e32d290183Douglas Gregorclass BlockCommandComment : public BlockContentComment {
559772eeaefef2c883aabe35caf4543e7e32d290183Douglas Gregorpublic:
560772eeaefef2c883aabe35caf4543e7e32d290183Douglas Gregor  struct Argument {
561772eeaefef2c883aabe35caf4543e7e32d290183Douglas Gregor    SourceRange Range;
562772eeaefef2c883aabe35caf4543e7e32d290183Douglas Gregor    StringRef Text;
563772eeaefef2c883aabe35caf4543e7e32d290183Douglas Gregor
564772eeaefef2c883aabe35caf4543e7e32d290183Douglas Gregor    Argument() { }
565772eeaefef2c883aabe35caf4543e7e32d290183Douglas Gregor    Argument(SourceRange Range, StringRef Text) : Range(Range), Text(Text) { }
566772eeaefef2c883aabe35caf4543e7e32d290183Douglas Gregor  };
567772eeaefef2c883aabe35caf4543e7e32d290183Douglas Gregor
568772eeaefef2c883aabe35caf4543e7e32d290183Douglas Gregorprotected:
569772eeaefef2c883aabe35caf4543e7e32d290183Douglas Gregor  /// Command name.
570772eeaefef2c883aabe35caf4543e7e32d290183Douglas Gregor  StringRef Name;
571772eeaefef2c883aabe35caf4543e7e32d290183Douglas Gregor
572772eeaefef2c883aabe35caf4543e7e32d290183Douglas Gregor  /// Word-like arguments.
5735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  llvm::ArrayRef<Argument> Args;
574e27ec8ad56dbf1efb2de004b90fbbb86f740e3f1John McCall
5756b304a0254a13f42390b865ff5ba668a49cc58aeJohn McCall  /// Paragraph argument.
576e27ec8ad56dbf1efb2de004b90fbbb86f740e3f1John McCall  ParagraphComment *Paragraph;
5776b304a0254a13f42390b865ff5ba668a49cc58aeJohn McCall
5785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  BlockCommandComment(CommentKind K,
5795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                      SourceLocation LocBegin,
580bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor                      SourceLocation LocEnd,
581bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor                      StringRef Name) :
582bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor      BlockContentComment(K, LocBegin, LocEnd),
5835f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      Name(Name),
5841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      Paragraph(NULL) {
585bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor    setLocation(getCommandNameRange().getBegin());
586bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  }
587bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor
588bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregorpublic:
589bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  BlockCommandComment(SourceLocation LocBegin,
5905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                      SourceLocation LocEnd,
5915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer                      StringRef Name) :
5921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      BlockContentComment(BlockCommandCommentKind, LocBegin, LocEnd),
5935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      Name(Name),
5945f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer      Paragraph(NULL) {
5955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    setLocation(getCommandNameRange().getBegin());
59615b91764d08e886391c865c4a444d7b51141c284Eli Friedman  }
5975f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
5985f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static bool classof(const Comment *C) {
5995f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return C->getCommentKind() >= FirstBlockCommandCommentConstant &&
6005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer           C->getCommentKind() <= LastBlockCommandCommentConstant;
6015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
6025f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6035f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  static bool classof(const BlockCommandComment *) { return true; }
6045f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6055f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  child_iterator child_begin() const {
6061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    return reinterpret_cast<child_iterator>(&Paragraph);
6075f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
6085f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6095f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  child_iterator child_end() const {
6105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return reinterpret_cast<child_iterator>(&Paragraph + 1);
6115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
6125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  StringRef getCommandName() const {
6145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return Name;
6155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
6165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  SourceRange getCommandNameRange() const {
61864c438a4be2a871fa43c78264663ba1e9788b94dArgyrios Kyrtzidis    return SourceRange(getLocStart().getLocWithOffset(1),
6192df9ced9fd1e8c7d7b38443db07e0e811de22571Chris Lattner                       getLocStart().getLocWithOffset(1 + Name.size()));
6202df9ced9fd1e8c7d7b38443db07e0e811de22571Chris Lattner  }
6212df9ced9fd1e8c7d7b38443db07e0e811de22571Chris Lattner
6222df9ced9fd1e8c7d7b38443db07e0e811de22571Chris Lattner  unsigned getNumArgs() const {
6233f59c975aa5d047f7edd1b900b5e885c38af0ef7Chris Lattner    return Args.size();
624d3d77cd138f8e830f6547b6f83fcd5721ccf5f5dEli Friedman  }
6253f59c975aa5d047f7edd1b900b5e885c38af0ef7Chris Lattner
6263f59c975aa5d047f7edd1b900b5e885c38af0ef7Chris Lattner  StringRef getArgText(unsigned Idx) const {
6273f59c975aa5d047f7edd1b900b5e885c38af0ef7Chris Lattner    return Args[Idx].Text;
6283f59c975aa5d047f7edd1b900b5e885c38af0ef7Chris Lattner  }
6293a2503227c3db04a3619735127483263c1075ef7Chris Lattner
63064c438a4be2a871fa43c78264663ba1e9788b94dArgyrios Kyrtzidis  SourceRange getArgRange(unsigned Idx) const {
631392da48160bd92ceb486792780467cbfdb2d0e8cJames Molloy    return Args[Idx].Range;
632392da48160bd92ceb486792780467cbfdb2d0e8cJames Molloy  }
633f5c209d23b20ada4a9b6235db50317239cbf6ae1Alisdair Meredith
634f5c209d23b20ada4a9b6235db50317239cbf6ae1Alisdair Meredith  void setArgs(llvm::ArrayRef<Argument> A) {
635f5c209d23b20ada4a9b6235db50317239cbf6ae1Alisdair Meredith    Args = A;
636f5c209d23b20ada4a9b6235db50317239cbf6ae1Alisdair Meredith    if (Args.size() > 0) {
637f5c209d23b20ada4a9b6235db50317239cbf6ae1Alisdair Meredith      SourceLocation NewLocEnd = Args.back().Range.getEnd();
638f5c209d23b20ada4a9b6235db50317239cbf6ae1Alisdair Meredith      if (NewLocEnd.isValid())
639f5c209d23b20ada4a9b6235db50317239cbf6ae1Alisdair Meredith        setSourceRange(SourceRange(getLocStart(), NewLocEnd));
640f5c209d23b20ada4a9b6235db50317239cbf6ae1Alisdair Meredith    }
641f5c209d23b20ada4a9b6235db50317239cbf6ae1Alisdair Meredith  }
642f5c209d23b20ada4a9b6235db50317239cbf6ae1Alisdair Meredith
643898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor  ParagraphComment *getParagraph() const LLVM_READONLY {
644898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor    return Paragraph;
645898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor  }
646898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor
647898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor  bool hasNonWhitespaceParagraph() const {
648898574e7496ba8fd76290079d3a9d06954992734Douglas Gregor    return Paragraph && !Paragraph->isWhitespace();
6498e9bebdea69c590dedfbf27374114cb76fe12fbdDouglas Gregor  }
6502a984cad5ac3fdceeff2bd99daa7b90979313475John McCall
6512a984cad5ac3fdceeff2bd99daa7b90979313475John McCall  void setParagraph(ParagraphComment *PC) {
6522a984cad5ac3fdceeff2bd99daa7b90979313475John McCall    Paragraph = PC;
653864c041e118155c2b1ce0ba36942a3da5a4a055eJohn McCall    SourceLocation NewLocEnd = PC->getLocEnd();
654864c041e118155c2b1ce0ba36942a3da5a4a055eJohn McCall    if (NewLocEnd.isValid())
655864c041e118155c2b1ce0ba36942a3da5a4a055eJohn McCall      setSourceRange(SourceRange(getLocStart(), NewLocEnd));
6563c3b7f90a863af43fa63043d396553ecf205351cJohn McCall  }
6573c3b7f90a863af43fa63043d396553ecf205351cJohn McCall};
6583c3b7f90a863af43fa63043d396553ecf205351cJohn McCall
6591de4d4e8cb2e9c88809fea8092bc6e835a5473d2John McCall/// Doxygen \\param command.
6601de4d4e8cb2e9c88809fea8092bc6e835a5473d2John McCallclass ParamCommandComment : public BlockCommandComment {
6611de4d4e8cb2e9c88809fea8092bc6e835a5473d2John McCallprivate:
6620ddaeb9b031070ec64afe92d9892875ac44df427John McCall  /// Parameter index in the function declaration.
6630ddaeb9b031070ec64afe92d9892875ac44df427John McCall  unsigned ParamIndex;
6640ddaeb9b031070ec64afe92d9892875ac44df427John McCall
6655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerpublic:
6665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  enum { InvalidParamIndex = ~0U };
6675f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer
6685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  ParamCommandComment(SourceLocation LocBegin,
6698e9bebdea69c590dedfbf27374114cb76fe12fbdDouglas Gregor                      SourceLocation LocEnd,
67013dcd00615de5c4279d97bdf63cd5f0a14fd9dccFariborz Jahanian                      StringRef Name) :
671de2e22d33afec98324a66a358dfe0951b3c7259aSteve Naroff      BlockCommandComment(ParamCommandCommentKind, LocBegin, LocEnd, Name),
672de2e22d33afec98324a66a358dfe0951b3c7259aSteve Naroff      ParamIndex(InvalidParamIndex) {
67313dcd00615de5c4279d97bdf63cd5f0a14fd9dccFariborz Jahanian    ParamCommandCommentBits.Direction = In;
674ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    ParamCommandCommentBits.IsDirectionExplicit = false;
675ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek  }
67693a49944e0e68e32bc22d45d44ee136b34beffb3Fariborz Jahanian
67793a49944e0e68e32bc22d45d44ee136b34beffb3Fariborz Jahanian  static bool classof(const Comment *C) {
678ebcb57a8d298862c65043e88b2429591ab3c58d3Ted Kremenek    return C->getCommentKind() == ParamCommandCommentKind;
679a526c5c67e5a0473c340903ee542ce570119665fTed Kremenek  }
6801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
68133e1d64ab5cd5d27f8530ccd056191fe2c9f3f2eFariborz Jahanian  static bool classof(const ParamCommandComment *) { return true; }
68233e1d64ab5cd5d27f8530ccd056191fe2c9f3f2eFariborz Jahanian
6836e8ed16ffef02b82995a90bdcf10ffff7d63839aSebastian Redl  enum PassDirection {
6846e8ed16ffef02b82995a90bdcf10ffff7d63839aSebastian Redl    In,
6856e8ed16ffef02b82995a90bdcf10ffff7d63839aSebastian Redl    Out,
686aa4a99b4a62615db243f7a5c433169f2fc704420Anton Korobeynikov    InOut
687aa4a99b4a62615db243f7a5c433169f2fc704420Anton Korobeynikov  };
688aa4a99b4a62615db243f7a5c433169f2fc704420Anton Korobeynikov
689fb40e3f10ccef93c4f8fb6bd4fe5a108fa6cd369Meador Inge  static const char *getDirectionAsString(PassDirection D);
690fb40e3f10ccef93c4f8fb6bd4fe5a108fa6cd369Meador Inge
691fb40e3f10ccef93c4f8fb6bd4fe5a108fa6cd369Meador Inge  PassDirection getDirection() const LLVM_READONLY {
6925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer    return static_cast<PassDirection>(ParamCommandCommentBits.Direction);
6935f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer  }
694d6471f7c1921c7802804ce3ff6fe9768310f72b9David Blaikie
69578a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis  bool isDirectionExplicit() const LLVM_READONLY {
69678a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis    return ParamCommandCommentBits.IsDirectionExplicit;
69778a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis  }
6986320064d0c60fa8683f5623881c9394fd4aa7689Douglas Gregor
6996320064d0c60fa8683f5623881c9394fd4aa7689Douglas Gregor  void setDirection(PassDirection Direction, bool Explicit) {
7006320064d0c60fa8683f5623881c9394fd4aa7689Douglas Gregor    ParamCommandCommentBits.Direction = Direction;
7016320064d0c60fa8683f5623881c9394fd4aa7689Douglas Gregor    ParamCommandCommentBits.IsDirectionExplicit = Explicit;
7026320064d0c60fa8683f5623881c9394fd4aa7689Douglas Gregor  }
7036320064d0c60fa8683f5623881c9394fd4aa7689Douglas Gregor
7046320064d0c60fa8683f5623881c9394fd4aa7689Douglas Gregor  bool hasParamName() const {
7056320064d0c60fa8683f5623881c9394fd4aa7689Douglas Gregor    return getNumArgs() > 0;
7066320064d0c60fa8683f5623881c9394fd4aa7689Douglas Gregor  }
7076320064d0c60fa8683f5623881c9394fd4aa7689Douglas Gregor
7086320064d0c60fa8683f5623881c9394fd4aa7689Douglas Gregor  StringRef getParamName() const {
7096320064d0c60fa8683f5623881c9394fd4aa7689Douglas Gregor    return Args[0].Text;
7106320064d0c60fa8683f5623881c9394fd4aa7689Douglas Gregor  }
7116320064d0c60fa8683f5623881c9394fd4aa7689Douglas Gregor
7126320064d0c60fa8683f5623881c9394fd4aa7689Douglas Gregor  SourceRange getParamNameRange() const {
7136320064d0c60fa8683f5623881c9394fd4aa7689Douglas Gregor    return Args[0].Range;
7146320064d0c60fa8683f5623881c9394fd4aa7689Douglas Gregor  }
7156320064d0c60fa8683f5623881c9394fd4aa7689Douglas Gregor
7166320064d0c60fa8683f5623881c9394fd4aa7689Douglas Gregor  bool isParamIndexValid() const LLVM_READONLY {
717251b4ff2578e26959a4c036140ccd61c5e9292f2Douglas Gregor    return ParamIndex != InvalidParamIndex;
718663b5a0be7261c29bc4c526a71cffcfa02d4153eDouglas Gregor  }
7197caa6825f42a0f7e97d6fc06233133c42b218e46Douglas Gregor
720663b5a0be7261c29bc4c526a71cffcfa02d4153eDouglas Gregor  unsigned getParamIndex() const LLVM_READONLY {
7217caa6825f42a0f7e97d6fc06233133c42b218e46Douglas Gregor    assert(isParamIndexValid());
7227caa6825f42a0f7e97d6fc06233133c42b218e46Douglas Gregor    return ParamIndex;
7237caa6825f42a0f7e97d6fc06233133c42b218e46Douglas Gregor  }
7241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
7257caa6825f42a0f7e97d6fc06233133c42b218e46Douglas Gregor  void setParamIndex(unsigned Index) {
7267caa6825f42a0f7e97d6fc06233133c42b218e46Douglas Gregor    ParamIndex = Index;
7277caa6825f42a0f7e97d6fc06233133c42b218e46Douglas Gregor    assert(isParamIndexValid());
7281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  }
729251b4ff2578e26959a4c036140ccd61c5e9292f2Douglas Gregor};
7309421adc43891e272156fab640e5d5ee5054b779cArgyrios Kyrtzidis
7319421adc43891e272156fab640e5d5ee5054b779cArgyrios Kyrtzidis/// Doxygen \\tparam command, describes a template parameter.
7327caa6825f42a0f7e97d6fc06233133c42b218e46Douglas Gregorclass TParamCommandComment : public BlockCommandComment {
7337caa6825f42a0f7e97d6fc06233133c42b218e46Douglas Gregorprivate:
7347caa6825f42a0f7e97d6fc06233133c42b218e46Douglas Gregor  /// If this template parameter name was resolved (found in template parameter
7357caa6825f42a0f7e97d6fc06233133c42b218e46Douglas Gregor  /// list), then this stores a list of position indexes in all template
736251b4ff2578e26959a4c036140ccd61c5e9292f2Douglas Gregor  /// parameter lists.
7379421adc43891e272156fab640e5d5ee5054b779cArgyrios Kyrtzidis  ///
7387caa6825f42a0f7e97d6fc06233133c42b218e46Douglas Gregor  /// For example:
7397caa6825f42a0f7e97d6fc06233133c42b218e46Douglas Gregor  /// \verbatim
740af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet  ///     template<typename C, template<typename T> class TT>
741af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet  ///     void test(TT<int> aaa);
742af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet  /// \endverbatim
743af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet  /// For C:  Position = { 0 }
7440d95f0d7b81110f77e99e833f766d19be7b7e072Francois Pichet  /// For TT: Position = { 1 }
7450d95f0d7b81110f77e99e833f766d19be7b7e072Francois Pichet  /// For T:  Position = { 1, 0 }
746af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet  llvm::ArrayRef<unsigned> Position;
747af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet
748af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichetpublic:
749af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet  TParamCommandComment(SourceLocation LocBegin,
750af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet                       SourceLocation LocEnd,
751af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet                       StringRef Name) :
752af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet      BlockCommandComment(TParamCommandCommentKind, LocBegin, LocEnd, Name)
753af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet  { }
754af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet
7550d95f0d7b81110f77e99e833f766d19be7b7e072Francois Pichet  static bool classof(const Comment *C) {
756af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet    return C->getCommentKind() == TParamCommandCommentKind;
757af0f4d0b2e38c810effc8b024ad2fb6604eec5d3Francois Pichet  }
7587ba107a1863ddfa1664555854f0d7bdb3c491c92John McCall
759ed97649e9574b9d854fa4d6109c9333ae0993554John McCall  static bool classof(const TParamCommandComment *) { return true; }
7607ba107a1863ddfa1664555854f0d7bdb3c491c92John McCall
761ed97649e9574b9d854fa4d6109c9333ae0993554John McCall  bool hasParamName() const {
762ed97649e9574b9d854fa4d6109c9333ae0993554John McCall    return getNumArgs() > 0;
7630d8df780aef1acda5962347a32591efc629b6748Anders Carlsson  }
7641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
7650d8df780aef1acda5962347a32591efc629b6748Anders Carlsson  StringRef getParamName() const {
7660d8df780aef1acda5962347a32591efc629b6748Anders Carlsson    return Args[0].Text;
7670d8df780aef1acda5962347a32591efc629b6748Anders Carlsson  }
7680d8df780aef1acda5962347a32591efc629b6748Anders Carlsson
769ed97649e9574b9d854fa4d6109c9333ae0993554John McCall  SourceRange getParamNameRange() const {
770ed97649e9574b9d854fa4d6109c9333ae0993554John McCall    return Args[0].Range;
771ed97649e9574b9d854fa4d6109c9333ae0993554John McCall  }
772ed97649e9574b9d854fa4d6109c9333ae0993554John McCall
773ed97649e9574b9d854fa4d6109c9333ae0993554John McCall  bool isPositionValid() const LLVM_READONLY {
774ed97649e9574b9d854fa4d6109c9333ae0993554John McCall    return !Position.empty();
775ed97649e9574b9d854fa4d6109c9333ae0993554John McCall  }
776ed97649e9574b9d854fa4d6109c9333ae0993554John McCall
777ed97649e9574b9d854fa4d6109c9333ae0993554John McCall  unsigned getDepth() const {
778ed97649e9574b9d854fa4d6109c9333ae0993554John McCall    assert(isPositionValid());
779ed97649e9574b9d854fa4d6109c9333ae0993554John McCall    return Position.size();
780ed97649e9574b9d854fa4d6109c9333ae0993554John McCall  }
781ed97649e9574b9d854fa4d6109c9333ae0993554John McCall
782ed97649e9574b9d854fa4d6109c9333ae0993554John McCall  unsigned getIndex(unsigned Depth) const {
783ed97649e9574b9d854fa4d6109c9333ae0993554John McCall    assert(isPositionValid());
784ed97649e9574b9d854fa4d6109c9333ae0993554John McCall    return Position[Depth];
785ed97649e9574b9d854fa4d6109c9333ae0993554John McCall  }
786ed97649e9574b9d854fa4d6109c9333ae0993554John McCall
787ed97649e9574b9d854fa4d6109c9333ae0993554John McCall  void setPosition(ArrayRef<unsigned> NewPosition) {
788ed97649e9574b9d854fa4d6109c9333ae0993554John McCall    Position = NewPosition;
789ed97649e9574b9d854fa4d6109c9333ae0993554John McCall    assert(isPositionValid());
790ed97649e9574b9d854fa4d6109c9333ae0993554John McCall  }
791ed97649e9574b9d854fa4d6109c9333ae0993554John McCall};
792ed97649e9574b9d854fa4d6109c9333ae0993554John McCall
7930d8df780aef1acda5962347a32591efc629b6748Anders Carlsson/// A line of text contained in a verbatim block.
7940d8df780aef1acda5962347a32591efc629b6748Anders Carlssonclass VerbatimBlockLineComment : public Comment {
795d8b285fee4471f393da8ee30f552ceacdc362afaAnders Carlsson  StringRef Text;
796d8b285fee4471f393da8ee30f552ceacdc362afaAnders Carlsson
797d8b285fee4471f393da8ee30f552ceacdc362afaAnders Carlssonpublic:
798d8b285fee4471f393da8ee30f552ceacdc362afaAnders Carlsson  VerbatimBlockLineComment(SourceLocation LocBegin,
799d8b285fee4471f393da8ee30f552ceacdc362afaAnders Carlsson                           StringRef Text) :
8001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      Comment(VerbatimBlockLineCommentKind,
801d8b285fee4471f393da8ee30f552ceacdc362afaAnders Carlsson              LocBegin,
802d8b285fee4471f393da8ee30f552ceacdc362afaAnders Carlsson              LocBegin.getLocWithOffset(Text.size())),
803d8b285fee4471f393da8ee30f552ceacdc362afaAnders Carlsson      Text(Text)
804d8b285fee4471f393da8ee30f552ceacdc362afaAnders Carlsson  { }
805d8b285fee4471f393da8ee30f552ceacdc362afaAnders Carlsson
806d8b285fee4471f393da8ee30f552ceacdc362afaAnders Carlsson  static bool classof(const Comment *C) {
807d8b285fee4471f393da8ee30f552ceacdc362afaAnders Carlsson    return C->getCommentKind() == VerbatimBlockLineCommentKind;
808d8b285fee4471f393da8ee30f552ceacdc362afaAnders Carlsson  }
809d8b285fee4471f393da8ee30f552ceacdc362afaAnders Carlsson
8101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  static bool classof(const VerbatimBlockLineComment *) { return true; }
811d8b285fee4471f393da8ee30f552ceacdc362afaAnders Carlsson
812d8b285fee4471f393da8ee30f552ceacdc362afaAnders Carlsson  child_iterator child_begin() const { return NULL; }
813d8b285fee4471f393da8ee30f552ceacdc362afaAnders Carlsson
81414d56ef43ff4921c6749f7340212fbb743fdbb9bFariborz Jahanian  child_iterator child_end() const { return NULL; }
81514d56ef43ff4921c6749f7340212fbb743fdbb9bFariborz Jahanian
81614d56ef43ff4921c6749f7340212fbb743fdbb9bFariborz Jahanian  StringRef getText() const LLVM_READONLY {
817a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith    return Text;
81814d56ef43ff4921c6749f7340212fbb743fdbb9bFariborz Jahanian  }
81914d56ef43ff4921c6749f7340212fbb743fdbb9bFariborz Jahanian};
820340fa242130c2d8d74c83edca0952e771aebe0e6Fariborz Jahanian
821340fa242130c2d8d74c83edca0952e771aebe0e6Fariborz Jahanian/// A verbatim block command (e. g., preformatted code).  Verbatim block has an
822340fa242130c2d8d74c83edca0952e771aebe0e6Fariborz Jahanian/// opening and a closing command and contains multiple lines of text
823a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith/// (VerbatimBlockLineComment nodes).
824a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smithclass VerbatimBlockComment : public BlockCommandComment {
825340fa242130c2d8d74c83edca0952e771aebe0e6Fariborz Jahanianprotected:
826340fa242130c2d8d74c83edca0952e771aebe0e6Fariborz Jahanian  StringRef CloseName;
8279b3acaa32548d0ce78b9c39a3911397f6738a47cFariborz Jahanian  SourceLocation CloseNameLocBegin;
8289b3acaa32548d0ce78b9c39a3911397f6738a47cFariborz Jahanian  llvm::ArrayRef<VerbatimBlockLineComment *> Lines;
8299b3acaa32548d0ce78b9c39a3911397f6738a47cFariborz Jahanian
830a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smithpublic:
831a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith  VerbatimBlockComment(SourceLocation LocBegin,
8329b3acaa32548d0ce78b9c39a3911397f6738a47cFariborz Jahanian                       SourceLocation LocEnd,
8339b3acaa32548d0ce78b9c39a3911397f6738a47cFariborz Jahanian                       StringRef Name) :
834dd7fddb5b6883326e52b278a9b7e9cefea29aae0Chad Rosier      BlockCommandComment(VerbatimBlockCommentKind,
83552bbe7a1133c3cb57e9246f1b96c12940ea3821aFariborz Jahanian                          LocBegin, LocEnd, Name)
83652bbe7a1133c3cb57e9246f1b96c12940ea3821aFariborz Jahanian  { }
837a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith
83852bbe7a1133c3cb57e9246f1b96c12940ea3821aFariborz Jahanian  static bool classof(const Comment *C) {
83952bbe7a1133c3cb57e9246f1b96c12940ea3821aFariborz Jahanian    return C->getCommentKind() == VerbatimBlockCommentKind;
840dd7fddb5b6883326e52b278a9b7e9cefea29aae0Chad Rosier  }
84152bbe7a1133c3cb57e9246f1b96c12940ea3821aFariborz Jahanian
84252bbe7a1133c3cb57e9246f1b96c12940ea3821aFariborz Jahanian  static bool classof(const VerbatimBlockComment *) { return true; }
843a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith
84452bbe7a1133c3cb57e9246f1b96c12940ea3821aFariborz Jahanian  child_iterator child_begin() const {
84552bbe7a1133c3cb57e9246f1b96c12940ea3821aFariborz Jahanian    return reinterpret_cast<child_iterator>(Lines.begin());
8467d10b7eb670b821741b4c96f6cf7afbc3bb39abeDouglas Gregor  }
8477d10b7eb670b821741b4c96f6cf7afbc3bb39abeDouglas Gregor
8487d10b7eb670b821741b4c96f6cf7afbc3bb39abeDouglas Gregor  child_iterator child_end() const {
8497d10b7eb670b821741b4c96f6cf7afbc3bb39abeDouglas Gregor    return reinterpret_cast<child_iterator>(Lines.end());
8507d10b7eb670b821741b4c96f6cf7afbc3bb39abeDouglas Gregor  }
8517d10b7eb670b821741b4c96f6cf7afbc3bb39abeDouglas Gregor
8527d10b7eb670b821741b4c96f6cf7afbc3bb39abeDouglas Gregor  void setCloseName(StringRef Name, SourceLocation LocBegin) {
8537d10b7eb670b821741b4c96f6cf7afbc3bb39abeDouglas Gregor    CloseName = Name;
8547d10b7eb670b821741b4c96f6cf7afbc3bb39abeDouglas Gregor    CloseNameLocBegin = LocBegin;
8557d10b7eb670b821741b4c96f6cf7afbc3bb39abeDouglas Gregor  }
8567d10b7eb670b821741b4c96f6cf7afbc3bb39abeDouglas Gregor
8577d10b7eb670b821741b4c96f6cf7afbc3bb39abeDouglas Gregor  void setLines(llvm::ArrayRef<VerbatimBlockLineComment *> L) {
8587d10b7eb670b821741b4c96f6cf7afbc3bb39abeDouglas Gregor    Lines = L;
8597d10b7eb670b821741b4c96f6cf7afbc3bb39abeDouglas Gregor  }
8607d10b7eb670b821741b4c96f6cf7afbc3bb39abeDouglas Gregor
8617d10b7eb670b821741b4c96f6cf7afbc3bb39abeDouglas Gregor  StringRef getCloseName() const {
8627d10b7eb670b821741b4c96f6cf7afbc3bb39abeDouglas Gregor    return CloseName;
8637d10b7eb670b821741b4c96f6cf7afbc3bb39abeDouglas Gregor  }
8647d10b7eb670b821741b4c96f6cf7afbc3bb39abeDouglas Gregor
8657d10b7eb670b821741b4c96f6cf7afbc3bb39abeDouglas Gregor  unsigned getNumLines() const {
866c91e9f439ae85d5f79a6b65672f1d7d1b55ccda0Argyrios Kyrtzidis    return Lines.size();
867c91e9f439ae85d5f79a6b65672f1d7d1b55ccda0Argyrios Kyrtzidis  }
868c91e9f439ae85d5f79a6b65672f1d7d1b55ccda0Argyrios Kyrtzidis
869c91e9f439ae85d5f79a6b65672f1d7d1b55ccda0Argyrios Kyrtzidis  StringRef getText(unsigned LineIdx) const {
870c91e9f439ae85d5f79a6b65672f1d7d1b55ccda0Argyrios Kyrtzidis    return Lines[LineIdx]->getText();
871c91e9f439ae85d5f79a6b65672f1d7d1b55ccda0Argyrios Kyrtzidis  }
872c91e9f439ae85d5f79a6b65672f1d7d1b55ccda0Argyrios Kyrtzidis};
873c91e9f439ae85d5f79a6b65672f1d7d1b55ccda0Argyrios Kyrtzidis
874c91e9f439ae85d5f79a6b65672f1d7d1b55ccda0Argyrios Kyrtzidis/// A verbatim line command.  Verbatim line has an opening command, a single
875c91e9f439ae85d5f79a6b65672f1d7d1b55ccda0Argyrios Kyrtzidis/// line of text (up to the newline after the opening command) and has no
8767d10b7eb670b821741b4c96f6cf7afbc3bb39abeDouglas Gregor/// closing command.
8777d10b7eb670b821741b4c96f6cf7afbc3bb39abeDouglas Gregorclass VerbatimLineComment : public BlockCommandComment {
8787d10b7eb670b821741b4c96f6cf7afbc3bb39abeDouglas Gregorprotected:
8797d10b7eb670b821741b4c96f6cf7afbc3bb39abeDouglas Gregor  StringRef Text;
8807d10b7eb670b821741b4c96f6cf7afbc3bb39abeDouglas Gregor  SourceLocation TextBegin;
881e664977aca2a05a77abab5a06dc0fb69e870cfb9Douglas Gregor
882e664977aca2a05a77abab5a06dc0fb69e870cfb9Douglas Gregorpublic:
883e664977aca2a05a77abab5a06dc0fb69e870cfb9Douglas Gregor  VerbatimLineComment(SourceLocation LocBegin,
884e664977aca2a05a77abab5a06dc0fb69e870cfb9Douglas Gregor                      SourceLocation LocEnd,
885e664977aca2a05a77abab5a06dc0fb69e870cfb9Douglas Gregor                      StringRef Name,
886e664977aca2a05a77abab5a06dc0fb69e870cfb9Douglas Gregor                      SourceLocation TextBegin,
887e664977aca2a05a77abab5a06dc0fb69e870cfb9Douglas Gregor                      StringRef Text) :
888e664977aca2a05a77abab5a06dc0fb69e870cfb9Douglas Gregor      BlockCommandComment(VerbatimLineCommentKind,
889e664977aca2a05a77abab5a06dc0fb69e870cfb9Douglas Gregor                          LocBegin, LocEnd,
890e664977aca2a05a77abab5a06dc0fb69e870cfb9Douglas Gregor                          Name),
891e664977aca2a05a77abab5a06dc0fb69e870cfb9Douglas Gregor      Text(Text),
892e664977aca2a05a77abab5a06dc0fb69e870cfb9Douglas Gregor      TextBegin(TextBegin)
893e664977aca2a05a77abab5a06dc0fb69e870cfb9Douglas Gregor  { }
894464175bba1318bef7905122e9fda20cff926df78Chris Lattner
895464175bba1318bef7905122e9fda20cff926df78Chris Lattner  static bool classof(const Comment *C) {
896464175bba1318bef7905122e9fda20cff926df78Chris Lattner    return C->getCommentKind() == VerbatimLineCommentKind;
897a7674d8a9a69f3f6fe16e70cf2a3b2b15fb7c43dChris Lattner  }
898b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner
899b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner  static bool classof(const VerbatimLineComment *) { return true; }
900b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner
901183700f494ec9b6701b6efe82bcb25f4c79ba561John McCall  child_iterator child_begin() const { return NULL; }
902b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner
903b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner  child_iterator child_end() const { return NULL; }
904b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie
905aa4a99b4a62615db243f7a5c433169f2fc704420Anton Korobeynikov  StringRef getText() const {
906bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor    return Text;
907bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor  }
908bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor
909b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner  SourceRange getTextRange() const {
910b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner    return SourceRange(TextBegin, getLocEnd());
911b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner  }
9128b752f10c394b140f9ef89e049cbad1a7676fc25Ken Dyck};
913af707ab8fbb9451e8febb8d766f6c043628125c4Chris Lattner
914af707ab8fbb9451e8febb8d766f6c043628125c4Chris Lattner/// Information about the declaration, useful to clients of FullComment.
9155d484e8cf710207010720589d89602233de61d01Sebastian Redlstruct DeclInfo {
9165d484e8cf710207010720589d89602233de61d01Sebastian Redl  /// Declaration the comment is attached to.  Should not be NULL.
9174ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad  const Decl *ThisDecl;
918bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor
919dcdafb6a701aa9d81edcb088915f58933315dc05Eli Friedman  /// Parameters that can be referenced by \\param if \c ThisDecl is something
9204081a5c5f1381c4ec77f8ab3866693917e4329c4John McCall  /// that we consider a "function".
9214081a5c5f1381c4ec77f8ab3866693917e4329c4John McCall  ArrayRef<const ParmVarDecl *> ParamVars;
9224081a5c5f1381c4ec77f8ab3866693917e4329c4John McCall
9234081a5c5f1381c4ec77f8ab3866693917e4329c4John McCall  /// Function result type if \c ThisDecl is something that we consider
9244081a5c5f1381c4ec77f8ab3866693917e4329c4John McCall  /// a "function".
9254081a5c5f1381c4ec77f8ab3866693917e4329c4John McCall  QualType ResultType;
9264081a5c5f1381c4ec77f8ab3866693917e4329c4John McCall
9274081a5c5f1381c4ec77f8ab3866693917e4329c4John McCall  /// Template parameters that can be referenced by \\tparam if \c ThisDecl is
92882d0b0aab9088e977c2a44c4a5a90479c63149fePeter Collingbourne  /// a template.
9294081a5c5f1381c4ec77f8ab3866693917e4329c4John McCall  const TemplateParameterList *TemplateParameters;
9304081a5c5f1381c4ec77f8ab3866693917e4329c4John McCall
9314081a5c5f1381c4ec77f8ab3866693917e4329c4John McCall  /// A simplified description of \c ThisDecl kind that should be good enough
9324081a5c5f1381c4ec77f8ab3866693917e4329c4John McCall  /// for documentation rendering purposes.
9334081a5c5f1381c4ec77f8ab3866693917e4329c4John McCall  enum DeclKind {
9344081a5c5f1381c4ec77f8ab3866693917e4329c4John McCall    /// Everything else not explicitly mentioned below.
9354081a5c5f1381c4ec77f8ab3866693917e4329c4John McCall    OtherKind,
9364081a5c5f1381c4ec77f8ab3866693917e4329c4John McCall
93778a7d7d79964119a3f35b262eb154b5cbf1001edFariborz Jahanian    /// Something that we consider a "function":
93878a7d7d79964119a3f35b262eb154b5cbf1001edFariborz Jahanian    /// \li function,
93978a7d7d79964119a3f35b262eb154b5cbf1001edFariborz Jahanian    /// \li function template,
94078a7d7d79964119a3f35b262eb154b5cbf1001edFariborz Jahanian    /// \li function template specialization,
941dcdafb6a701aa9d81edcb088915f58933315dc05Eli Friedman    /// \li member function,
942ba4f5d5754c8291690d01ca9581926673d69b24cJohn McCall    /// \li member function template,
943ba4f5d5754c8291690d01ca9581926673d69b24cJohn McCall    /// \li member function template specialization,
9444081a5c5f1381c4ec77f8ab3866693917e4329c4John McCall    /// \li ObjC method.
945ba4f5d5754c8291690d01ca9581926673d69b24cJohn McCall    FunctionKind,
946ba4f5d5754c8291690d01ca9581926673d69b24cJohn McCall
9474081a5c5f1381c4ec77f8ab3866693917e4329c4John McCall    /// Something that we consider a "class":
948af707ab8fbb9451e8febb8d766f6c043628125c4Chris Lattner    /// \li class/struct,
9496217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek    /// \li class template,
9505d484e8cf710207010720589d89602233de61d01Sebastian Redl    /// \li class template (partial) specialization.
9515d484e8cf710207010720589d89602233de61d01Sebastian Redl    ClassKind,
9525d484e8cf710207010720589d89602233de61d01Sebastian Redl
9535d484e8cf710207010720589d89602233de61d01Sebastian Redl    /// Something that we consider a "variable":
9545d484e8cf710207010720589d89602233de61d01Sebastian Redl    /// \li namespace scope variables;
9555d484e8cf710207010720589d89602233de61d01Sebastian Redl    /// \li static and non-static class data members.
9563b6575108a5b6d8b92ac3a9a7794bf6c3a210907John McCall    VariableKind,
9573b6575108a5b6d8b92ac3a9a7794bf6c3a210907John McCall
958bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor    /// A C++ namespace.
9593b6575108a5b6d8b92ac3a9a7794bf6c3a210907John McCall    NamespaceKind,
9603b6575108a5b6d8b92ac3a9a7794bf6c3a210907John McCall
9613b6575108a5b6d8b92ac3a9a7794bf6c3a210907John McCall    /// A C++ typedef-name (a 'typedef' decl specifier or alias-declaration),
962bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor    /// see \c TypedefNameDecl.
9633b6575108a5b6d8b92ac3a9a7794bf6c3a210907John McCall    TypedefKind
9643b6575108a5b6d8b92ac3a9a7794bf6c3a210907John McCall  };
965bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor
9663b6575108a5b6d8b92ac3a9a7794bf6c3a210907John McCall  /// If false, only \c ThisDecl is valid.
9673b6575108a5b6d8b92ac3a9a7794bf6c3a210907John McCall  unsigned IsFilled : 1;
9683b6575108a5b6d8b92ac3a9a7794bf6c3a210907John McCall
9696deecb0d46bcfd048e651d2db7c4fb0d6407da96Rafael Espindola  /// Simplified kind of \c ThisDecl, see\c DeclKind enum.
9709f1210c3280104417a4ad30f0a00825ac8fa718aChad Rosier  unsigned Kind : 3;
971dcdafb6a701aa9d81edcb088915f58933315dc05Eli Friedman
972ba4f5d5754c8291690d01ca9581926673d69b24cJohn McCall  /// Is \c ThisDecl a template declaration.
973ba4f5d5754c8291690d01ca9581926673d69b24cJohn McCall  unsigned IsTemplateDecl : 1;
974ba4f5d5754c8291690d01ca9581926673d69b24cJohn McCall
975ba4f5d5754c8291690d01ca9581926673d69b24cJohn McCall  /// Is \c ThisDecl a template specialization.
976ba4f5d5754c8291690d01ca9581926673d69b24cJohn McCall  unsigned IsTemplateSpecialization : 1;
977ba4f5d5754c8291690d01ca9581926673d69b24cJohn McCall
978ba4f5d5754c8291690d01ca9581926673d69b24cJohn McCall  /// Is \c ThisDecl a template partial specialization.
979ba4f5d5754c8291690d01ca9581926673d69b24cJohn McCall  /// Never true if \c IsFunctionDecl is true.
980ba4f5d5754c8291690d01ca9581926673d69b24cJohn McCall  unsigned IsTemplatePartialSpecialization : 1;
981ba4f5d5754c8291690d01ca9581926673d69b24cJohn McCall
982ba4f5d5754c8291690d01ca9581926673d69b24cJohn McCall  /// Is \c ThisDecl an ObjCMethodDecl.
983dac54c124e302d6f028ea5723c425b7f66fc7c71Ken Dyck  unsigned IsObjCMethod : 1;
984ba4f5d5754c8291690d01ca9581926673d69b24cJohn McCall
985ba4f5d5754c8291690d01ca9581926673d69b24cJohn McCall  /// Is \c ThisDecl a non-static member function of C++ class or
986ba4f5d5754c8291690d01ca9581926673d69b24cJohn McCall  /// instance method of ObjC class.
987ba4f5d5754c8291690d01ca9581926673d69b24cJohn McCall  /// Can be true only if \c IsFunctionDecl is true.
988ba4f5d5754c8291690d01ca9581926673d69b24cJohn McCall  unsigned IsInstanceMethod : 1;
989ba4f5d5754c8291690d01ca9581926673d69b24cJohn McCall
990ba4f5d5754c8291690d01ca9581926673d69b24cJohn McCall  /// Is \c ThisDecl a static member function of C++ class or
991ba4f5d5754c8291690d01ca9581926673d69b24cJohn McCall  /// class method of ObjC class.
992ba4f5d5754c8291690d01ca9581926673d69b24cJohn McCall  /// Can be true only if \c IsFunctionDecl is true.
993ba4f5d5754c8291690d01ca9581926673d69b24cJohn McCall  unsigned IsClassMethod : 1;
994ba4f5d5754c8291690d01ca9581926673d69b24cJohn McCall
995ba4f5d5754c8291690d01ca9581926673d69b24cJohn McCall  void fill();
99605f62474dd2b0f1cb69adbe0787f2868788aa949Charles Davis
997af707ab8fbb9451e8febb8d766f6c043628125c4Chris Lattner  DeclKind getKind() const LLVM_READONLY {
998dcdafb6a701aa9d81edcb088915f58933315dc05Eli Friedman    return static_cast<DeclKind>(Kind);
999eb6f5dc86531f794ba7746a2da4d28e37cf5da7eKen Dyck  }
1000af707ab8fbb9451e8febb8d766f6c043628125c4Chris Lattner};
1001b7cfe88e88cb4f46308de89cf3f0c81bfe624128Chris Lattner
1002ea1471e0e967548c596a71469702f8846dbaf3c0John McCall/// A full comment attached to a declaration, contains block content.
1003bee5a79fc95e3003d755031e3d2bb4410a71e1c1Ken Dyckclass FullComment : public Comment {
1004ea1471e0e967548c596a71469702f8846dbaf3c0John McCall  llvm::ArrayRef<BlockContentComment *> Blocks;
1005eb6f5dc86531f794ba7746a2da4d28e37cf5da7eKen Dyck
1006eb6f5dc86531f794ba7746a2da4d28e37cf5da7eKen Dyck  DeclInfo *ThisDeclInfo;
1007ea1471e0e967548c596a71469702f8846dbaf3c0John McCall
1008ea1471e0e967548c596a71469702f8846dbaf3c0John McCallpublic:
1009ea1471e0e967548c596a71469702f8846dbaf3c0John McCall  FullComment(llvm::ArrayRef<BlockContentComment *> Blocks, DeclInfo *D) :
1010bee5a79fc95e3003d755031e3d2bb4410a71e1c1Ken Dyck      Comment(FullCommentKind, SourceLocation(), SourceLocation()),
1011ea1471e0e967548c596a71469702f8846dbaf3c0John McCall      Blocks(Blocks), ThisDeclInfo(D) {
1012ea1471e0e967548c596a71469702f8846dbaf3c0John McCall    if (Blocks.empty())
1013ea1471e0e967548c596a71469702f8846dbaf3c0John McCall      return;
1014bc5419a2edc4030d1a623576fe339fbd3eed17a6Daniel Dunbar
1015bc5419a2edc4030d1a623576fe339fbd3eed17a6Daniel Dunbar    setSourceRange(SourceRange(Blocks.front()->getLocStart(),
1016bc5419a2edc4030d1a623576fe339fbd3eed17a6Daniel Dunbar                               Blocks.back()->getLocEnd()));
1017bc5419a2edc4030d1a623576fe339fbd3eed17a6Daniel Dunbar    setLocation(Blocks.front()->getLocStart());
1018bc5419a2edc4030d1a623576fe339fbd3eed17a6Daniel Dunbar  }
1019bc5419a2edc4030d1a623576fe339fbd3eed17a6Daniel Dunbar
1020bc5419a2edc4030d1a623576fe339fbd3eed17a6Daniel Dunbar  static bool classof(const Comment *C) {
1021bc5419a2edc4030d1a623576fe339fbd3eed17a6Daniel Dunbar    return C->getCommentKind() == FullCommentKind;
1022bc5419a2edc4030d1a623576fe339fbd3eed17a6Daniel Dunbar  }
1023bc5419a2edc4030d1a623576fe339fbd3eed17a6Daniel Dunbar
1024bc5419a2edc4030d1a623576fe339fbd3eed17a6Daniel Dunbar  static bool classof(const FullComment *) { return true; }
1025bc5419a2edc4030d1a623576fe339fbd3eed17a6Daniel Dunbar
10260953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  child_iterator child_begin() const {
10270953e767ff7817f97b3ab20896b229891eeff45bJohn McCall    return reinterpret_cast<child_iterator>(Blocks.begin());
10280953e767ff7817f97b3ab20896b229891eeff45bJohn McCall  }
10290953e767ff7817f97b3ab20896b229891eeff45bJohn McCall
1030d2d2a11a91d7ddf468bfb70f66362d24806ed601Chris Lattner  child_iterator child_end() const {
1031bc5419a2edc4030d1a623576fe339fbd3eed17a6Daniel Dunbar    return reinterpret_cast<child_iterator>(Blocks.end());
10325e301007e31e14c8ff647288e1b8bd8dbf8a5fe4Mike Stump  }
10335e301007e31e14c8ff647288e1b8bd8dbf8a5fe4Mike Stump
1034a7674d8a9a69f3f6fe16e70cf2a3b2b15fb7c43dChris Lattner  const Decl *getDecl() const LLVM_READONLY {
103572564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    return ThisDeclInfo->ThisDecl;
103672564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor  }
103718857644059c45da6776f1a288eec7b4cf3a844aDouglas Gregor
103872564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor  const DeclInfo *getDeclInfo() const LLVM_READONLY {
103972564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    if (!ThisDeclInfo->IsFilled)
1040d3d49bb27c7ffd9accc0a6c00e887111c0348845John McCall      ThisDeclInfo->fill();
104172564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor    return ThisDeclInfo;
10425d2a6303467184b1f159bb6556efc434e50e3c28Chris Lattner  }
10435d2a6303467184b1f159bb6556efc434e50e3c28Chris Lattner};
104418857644059c45da6776f1a288eec7b4cf3a844aDouglas Gregor
104518857644059c45da6776f1a288eec7b4cf3a844aDouglas Gregor} // end namespace comments
104618857644059c45da6776f1a288eec7b4cf3a844aDouglas Gregor} // end namespace clang
104718857644059c45da6776f1a288eec7b4cf3a844aDouglas Gregor
104818857644059c45da6776f1a288eec7b4cf3a844aDouglas Gregor#endif
104972564e73277e29f6db3305d1f27ba408abb7ed88Douglas Gregor
1050fb22d96692c5240fb8d611290dbf7eeed3759c73Steve Naroff