1 //===--- Comment.h - Comment AST nodes --------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines comment AST nodes.
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_CLANG_AST_COMMENT_H
15 #define LLVM_CLANG_AST_COMMENT_H
17 #include "clang/AST/CommentCommandTraits.h"
18 #include "clang/AST/DeclObjC.h"
19 #include "clang/AST/Type.h"
20 #include "clang/Basic/SourceLocation.h"
21 #include "llvm/ADT/ArrayRef.h"
22 #include "llvm/ADT/StringRef.h"
27 class TemplateParameterList;
32 /// Describes the syntax that was used in a documentation command.
34 /// Exact values of this enumeration are important because they used to select
35 /// parts of diagnostic messages. Audit diagnostics before changing or adding
37 enum CommandMarkerKind {
38 /// Command started with a backslash character:
44 /// Command started with an 'at' character:
51 /// Any part of the comment.
55 /// Preferred location to show caret.
58 /// Source range of this AST node.
61 class CommentBitfields {
64 /// Type of this AST node.
67 enum { NumCommentBits = 8 };
69 class InlineContentCommentBitfields {
70 friend class InlineContentComment;
72 unsigned : NumCommentBits;
74 /// True if there is a newline after this inline content node.
75 /// (There is no separate AST node for a newline.)
76 unsigned HasTrailingNewline : 1;
78 enum { NumInlineContentCommentBits = NumCommentBits + 1 };
80 class TextCommentBitfields {
81 friend class TextComment;
83 unsigned : NumInlineContentCommentBits;
85 /// True if \c IsWhitespace field contains a valid value.
86 mutable unsigned IsWhitespaceValid : 1;
88 /// True if this comment AST node contains only whitespace.
89 mutable unsigned IsWhitespace : 1;
91 enum { NumTextCommentBits = NumInlineContentCommentBits + 2 };
93 class InlineCommandCommentBitfields {
94 friend class InlineCommandComment;
96 unsigned : NumInlineContentCommentBits;
98 unsigned RenderKind : 2;
99 unsigned CommandID : 8;
101 enum { NumInlineCommandCommentBits = NumInlineContentCommentBits + 10 };
103 class HTMLStartTagCommentBitfields {
104 friend class HTMLStartTagComment;
106 unsigned : NumInlineContentCommentBits;
108 /// True if this tag is self-closing (e. g., <br />). This is based on tag
109 /// spelling in comment (plain <br> would not set this flag).
110 unsigned IsSelfClosing : 1;
112 enum { NumHTMLStartTagCommentBits = NumInlineContentCommentBits + 1 };
114 class ParagraphCommentBitfields {
115 friend class ParagraphComment;
117 unsigned : NumCommentBits;
119 /// True if \c IsWhitespace field contains a valid value.
120 mutable unsigned IsWhitespaceValid : 1;
122 /// True if this comment AST node contains only whitespace.
123 mutable unsigned IsWhitespace : 1;
125 enum { NumParagraphCommentBits = NumCommentBits + 2 };
127 class BlockCommandCommentBitfields {
128 friend class BlockCommandComment;
130 unsigned : NumCommentBits;
132 unsigned CommandID : 8;
134 /// Describes the syntax that was used in a documentation command.
135 /// Contains values from CommandMarkerKind enum.
136 unsigned CommandMarker : 1;
138 enum { NumBlockCommandCommentBits = NumCommentBits + 9 };
140 class ParamCommandCommentBitfields {
141 friend class ParamCommandComment;
143 unsigned : NumBlockCommandCommentBits;
145 /// Parameter passing direction, see ParamCommandComment::PassDirection.
146 unsigned Direction : 2;
148 /// True if direction was specified explicitly in the comment.
149 unsigned IsDirectionExplicit : 1;
151 enum { NumParamCommandCommentBits = NumBlockCommandCommentBits + 3 };
154 CommentBitfields CommentBits;
155 InlineContentCommentBitfields InlineContentCommentBits;
156 TextCommentBitfields TextCommentBits;
157 InlineCommandCommentBitfields InlineCommandCommentBits;
158 HTMLStartTagCommentBitfields HTMLStartTagCommentBits;
159 ParagraphCommentBitfields ParagraphCommentBits;
160 BlockCommandCommentBitfields BlockCommandCommentBits;
161 ParamCommandCommentBitfields ParamCommandCommentBits;
164 void setSourceRange(SourceRange SR) {
168 void setLocation(SourceLocation L) {
175 #define COMMENT(CLASS, PARENT) CLASS##Kind,
176 #define COMMENT_RANGE(BASE, FIRST, LAST) \
177 First##BASE##Constant=FIRST##Kind, Last##BASE##Constant=LAST##Kind,
178 #define LAST_COMMENT_RANGE(BASE, FIRST, LAST) \
179 First##BASE##Constant=FIRST##Kind, Last##BASE##Constant=LAST##Kind
180 #define ABSTRACT_COMMENT(COMMENT)
181 #include "clang/AST/CommentNodes.inc"
184 Comment(CommentKind K,
185 SourceLocation LocBegin,
186 SourceLocation LocEnd) :
187 Loc(LocBegin), Range(SourceRange(LocBegin, LocEnd)) {
188 CommentBits.Kind = K;
191 CommentKind getCommentKind() const {
192 return static_cast<CommentKind>(CommentBits.Kind);
195 const char *getCommentKindName() const;
197 LLVM_ATTRIBUTE_USED void dump() const;
198 LLVM_ATTRIBUTE_USED void dumpColor() const;
199 LLVM_ATTRIBUTE_USED void dump(const ASTContext &Context) const;
200 void dump(raw_ostream &OS, const CommandTraits *Traits,
201 const SourceManager *SM) const;
203 SourceRange getSourceRange() const LLVM_READONLY { return Range; }
205 SourceLocation getLocStart() const LLVM_READONLY {
206 return Range.getBegin();
209 SourceLocation getLocEnd() const LLVM_READONLY {
210 return Range.getEnd();
213 SourceLocation getLocation() const LLVM_READONLY { return Loc; }
215 typedef Comment * const *child_iterator;
217 child_iterator child_begin() const;
218 child_iterator child_end() const;
220 // TODO: const child iterator
222 unsigned child_count() const {
223 return child_end() - child_begin();
227 /// Inline content (contained within a block).
229 class InlineContentComment : public Comment {
231 InlineContentComment(CommentKind K,
232 SourceLocation LocBegin,
233 SourceLocation LocEnd) :
234 Comment(K, LocBegin, LocEnd) {
235 InlineContentCommentBits.HasTrailingNewline = 0;
239 static bool classof(const Comment *C) {
240 return C->getCommentKind() >= FirstInlineContentCommentConstant &&
241 C->getCommentKind() <= LastInlineContentCommentConstant;
244 void addTrailingNewline() {
245 InlineContentCommentBits.HasTrailingNewline = 1;
248 bool hasTrailingNewline() const {
249 return InlineContentCommentBits.HasTrailingNewline;
254 class TextComment : public InlineContentComment {
258 TextComment(SourceLocation LocBegin,
259 SourceLocation LocEnd,
261 InlineContentComment(TextCommentKind, LocBegin, LocEnd),
263 TextCommentBits.IsWhitespaceValid = false;
266 static bool classof(const Comment *C) {
267 return C->getCommentKind() == TextCommentKind;
270 child_iterator child_begin() const { return NULL; }
272 child_iterator child_end() const { return NULL; }
274 StringRef getText() const LLVM_READONLY { return Text; }
276 bool isWhitespace() const {
277 if (TextCommentBits.IsWhitespaceValid)
278 return TextCommentBits.IsWhitespace;
280 TextCommentBits.IsWhitespace = isWhitespaceNoCache();
281 TextCommentBits.IsWhitespaceValid = true;
282 return TextCommentBits.IsWhitespace;
286 bool isWhitespaceNoCache() const;
289 /// A command with word-like arguments that is considered inline content.
290 class InlineCommandComment : public InlineContentComment {
296 Argument(SourceRange Range, StringRef Text) : Range(Range), Text(Text) { }
299 /// The most appropriate rendering mode for this command, chosen on command
300 /// semantics in Doxygen.
309 /// Command arguments.
310 ArrayRef<Argument> Args;
313 InlineCommandComment(SourceLocation LocBegin,
314 SourceLocation LocEnd,
317 ArrayRef<Argument> Args) :
318 InlineContentComment(InlineCommandCommentKind, LocBegin, LocEnd),
320 InlineCommandCommentBits.RenderKind = RK;
321 InlineCommandCommentBits.CommandID = CommandID;
324 static bool classof(const Comment *C) {
325 return C->getCommentKind() == InlineCommandCommentKind;
328 child_iterator child_begin() const { return NULL; }
330 child_iterator child_end() const { return NULL; }
332 unsigned getCommandID() const {
333 return InlineCommandCommentBits.CommandID;
336 StringRef getCommandName(const CommandTraits &Traits) const {
337 return Traits.getCommandInfo(getCommandID())->Name;
340 SourceRange getCommandNameRange() const {
341 return SourceRange(getLocStart().getLocWithOffset(-1),
345 RenderKind getRenderKind() const {
346 return static_cast<RenderKind>(InlineCommandCommentBits.RenderKind);
349 unsigned getNumArgs() const {
353 StringRef getArgText(unsigned Idx) const {
354 return Args[Idx].Text;
357 SourceRange getArgRange(unsigned Idx) const {
358 return Args[Idx].Range;
362 /// Abstract class for opening and closing HTML tags. HTML tags are always
363 /// treated as inline content (regardless HTML semantics); opening and closing
364 /// tags are not matched.
365 class HTMLTagComment : public InlineContentComment {
368 SourceRange TagNameRange;
370 HTMLTagComment(CommentKind K,
371 SourceLocation LocBegin,
372 SourceLocation LocEnd,
374 SourceLocation TagNameBegin,
375 SourceLocation TagNameEnd) :
376 InlineContentComment(K, LocBegin, LocEnd),
378 TagNameRange(TagNameBegin, TagNameEnd) {
379 setLocation(TagNameBegin);
383 static bool classof(const Comment *C) {
384 return C->getCommentKind() >= FirstHTMLTagCommentConstant &&
385 C->getCommentKind() <= LastHTMLTagCommentConstant;
388 StringRef getTagName() const LLVM_READONLY { return TagName; }
390 SourceRange getTagNameSourceRange() const LLVM_READONLY {
391 SourceLocation L = getLocation();
392 return SourceRange(L.getLocWithOffset(1),
393 L.getLocWithOffset(1 + TagName.size()));
397 /// An opening HTML tag with attributes.
398 class HTMLStartTagComment : public HTMLTagComment {
402 SourceLocation NameLocBegin;
405 SourceLocation EqualsLoc;
407 SourceRange ValueRange;
412 Attribute(SourceLocation NameLocBegin, StringRef Name) :
413 NameLocBegin(NameLocBegin), Name(Name),
414 EqualsLoc(SourceLocation()),
415 ValueRange(SourceRange()), Value(StringRef())
418 Attribute(SourceLocation NameLocBegin, StringRef Name,
419 SourceLocation EqualsLoc,
420 SourceRange ValueRange, StringRef Value) :
421 NameLocBegin(NameLocBegin), Name(Name),
422 EqualsLoc(EqualsLoc),
423 ValueRange(ValueRange), Value(Value)
426 SourceLocation getNameLocEnd() const {
427 return NameLocBegin.getLocWithOffset(Name.size());
430 SourceRange getNameRange() const {
431 return SourceRange(NameLocBegin, getNameLocEnd());
436 ArrayRef<Attribute> Attributes;
439 HTMLStartTagComment(SourceLocation LocBegin,
441 HTMLTagComment(HTMLStartTagCommentKind,
442 LocBegin, LocBegin.getLocWithOffset(1 + TagName.size()),
444 LocBegin.getLocWithOffset(1),
445 LocBegin.getLocWithOffset(1 + TagName.size())) {
446 HTMLStartTagCommentBits.IsSelfClosing = false;
449 static bool classof(const Comment *C) {
450 return C->getCommentKind() == HTMLStartTagCommentKind;
453 child_iterator child_begin() const { return NULL; }
455 child_iterator child_end() const { return NULL; }
457 unsigned getNumAttrs() const {
458 return Attributes.size();
461 const Attribute &getAttr(unsigned Idx) const {
462 return Attributes[Idx];
465 void setAttrs(ArrayRef<Attribute> Attrs) {
467 if (!Attrs.empty()) {
468 const Attribute &Attr = Attrs.back();
469 SourceLocation L = Attr.ValueRange.getEnd();
473 Range.setEnd(Attr.getNameLocEnd());
478 void setGreaterLoc(SourceLocation GreaterLoc) {
479 Range.setEnd(GreaterLoc);
482 bool isSelfClosing() const {
483 return HTMLStartTagCommentBits.IsSelfClosing;
486 void setSelfClosing() {
487 HTMLStartTagCommentBits.IsSelfClosing = true;
491 /// A closing HTML tag.
492 class HTMLEndTagComment : public HTMLTagComment {
494 HTMLEndTagComment(SourceLocation LocBegin,
495 SourceLocation LocEnd,
497 HTMLTagComment(HTMLEndTagCommentKind,
500 LocBegin.getLocWithOffset(2),
501 LocBegin.getLocWithOffset(2 + TagName.size()))
504 static bool classof(const Comment *C) {
505 return C->getCommentKind() == HTMLEndTagCommentKind;
508 child_iterator child_begin() const { return NULL; }
510 child_iterator child_end() const { return NULL; }
513 /// Block content (contains inline content).
515 class BlockContentComment : public Comment {
517 BlockContentComment(CommentKind K,
518 SourceLocation LocBegin,
519 SourceLocation LocEnd) :
520 Comment(K, LocBegin, LocEnd)
524 static bool classof(const Comment *C) {
525 return C->getCommentKind() >= FirstBlockContentCommentConstant &&
526 C->getCommentKind() <= LastBlockContentCommentConstant;
530 /// A single paragraph that contains inline content.
531 class ParagraphComment : public BlockContentComment {
532 ArrayRef<InlineContentComment *> Content;
535 ParagraphComment(ArrayRef<InlineContentComment *> Content) :
536 BlockContentComment(ParagraphCommentKind,
540 if (Content.empty()) {
541 ParagraphCommentBits.IsWhitespace = true;
542 ParagraphCommentBits.IsWhitespaceValid = true;
546 ParagraphCommentBits.IsWhitespaceValid = false;
548 setSourceRange(SourceRange(Content.front()->getLocStart(),
549 Content.back()->getLocEnd()));
550 setLocation(Content.front()->getLocStart());
553 static bool classof(const Comment *C) {
554 return C->getCommentKind() == ParagraphCommentKind;
557 child_iterator child_begin() const {
558 return reinterpret_cast<child_iterator>(Content.begin());
561 child_iterator child_end() const {
562 return reinterpret_cast<child_iterator>(Content.end());
565 bool isWhitespace() const {
566 if (ParagraphCommentBits.IsWhitespaceValid)
567 return ParagraphCommentBits.IsWhitespace;
569 ParagraphCommentBits.IsWhitespace = isWhitespaceNoCache();
570 ParagraphCommentBits.IsWhitespaceValid = true;
571 return ParagraphCommentBits.IsWhitespace;
575 bool isWhitespaceNoCache() const;
578 /// A command that has zero or more word-like arguments (number of word-like
579 /// arguments depends on command name) and a paragraph as an argument
580 /// (e. g., \\brief).
581 class BlockCommandComment : public BlockContentComment {
588 Argument(SourceRange Range, StringRef Text) : Range(Range), Text(Text) { }
592 /// Word-like arguments.
593 ArrayRef<Argument> Args;
595 /// Paragraph argument.
596 ParagraphComment *Paragraph;
598 BlockCommandComment(CommentKind K,
599 SourceLocation LocBegin,
600 SourceLocation LocEnd,
602 CommandMarkerKind CommandMarker) :
603 BlockContentComment(K, LocBegin, LocEnd),
605 setLocation(getCommandNameBeginLoc());
606 BlockCommandCommentBits.CommandID = CommandID;
607 BlockCommandCommentBits.CommandMarker = CommandMarker;
611 BlockCommandComment(SourceLocation LocBegin,
612 SourceLocation LocEnd,
614 CommandMarkerKind CommandMarker) :
615 BlockContentComment(BlockCommandCommentKind, LocBegin, LocEnd),
617 setLocation(getCommandNameBeginLoc());
618 BlockCommandCommentBits.CommandID = CommandID;
619 BlockCommandCommentBits.CommandMarker = CommandMarker;
622 static bool classof(const Comment *C) {
623 return C->getCommentKind() >= FirstBlockCommandCommentConstant &&
624 C->getCommentKind() <= LastBlockCommandCommentConstant;
627 child_iterator child_begin() const {
628 return reinterpret_cast<child_iterator>(&Paragraph);
631 child_iterator child_end() const {
632 return reinterpret_cast<child_iterator>(&Paragraph + 1);
635 unsigned getCommandID() const {
636 return BlockCommandCommentBits.CommandID;
639 StringRef getCommandName(const CommandTraits &Traits) const {
640 return Traits.getCommandInfo(getCommandID())->Name;
643 SourceLocation getCommandNameBeginLoc() const {
644 return getLocStart().getLocWithOffset(1);
647 SourceRange getCommandNameRange(const CommandTraits &Traits) const {
648 StringRef Name = getCommandName(Traits);
649 return SourceRange(getCommandNameBeginLoc(),
650 getLocStart().getLocWithOffset(1 + Name.size()));
653 unsigned getNumArgs() const {
657 StringRef getArgText(unsigned Idx) const {
658 return Args[Idx].Text;
661 SourceRange getArgRange(unsigned Idx) const {
662 return Args[Idx].Range;
665 void setArgs(ArrayRef<Argument> A) {
667 if (Args.size() > 0) {
668 SourceLocation NewLocEnd = Args.back().Range.getEnd();
669 if (NewLocEnd.isValid())
670 setSourceRange(SourceRange(getLocStart(), NewLocEnd));
674 ParagraphComment *getParagraph() const LLVM_READONLY {
678 bool hasNonWhitespaceParagraph() const {
679 return Paragraph && !Paragraph->isWhitespace();
682 void setParagraph(ParagraphComment *PC) {
684 SourceLocation NewLocEnd = PC->getLocEnd();
685 if (NewLocEnd.isValid())
686 setSourceRange(SourceRange(getLocStart(), NewLocEnd));
689 CommandMarkerKind getCommandMarker() const LLVM_READONLY {
690 return static_cast<CommandMarkerKind>(
691 BlockCommandCommentBits.CommandMarker);
695 /// Doxygen \\param command.
696 class ParamCommandComment : public BlockCommandComment {
698 /// Parameter index in the function declaration.
702 enum LLVM_ENUM_INT_TYPE(unsigned) {
703 InvalidParamIndex = ~0U,
704 VarArgParamIndex = ~0U/*InvalidParamIndex*/ - 1U
707 ParamCommandComment(SourceLocation LocBegin,
708 SourceLocation LocEnd,
710 CommandMarkerKind CommandMarker) :
711 BlockCommandComment(ParamCommandCommentKind, LocBegin, LocEnd,
712 CommandID, CommandMarker),
713 ParamIndex(InvalidParamIndex) {
714 ParamCommandCommentBits.Direction = In;
715 ParamCommandCommentBits.IsDirectionExplicit = false;
718 static bool classof(const Comment *C) {
719 return C->getCommentKind() == ParamCommandCommentKind;
728 static const char *getDirectionAsString(PassDirection D);
730 PassDirection getDirection() const LLVM_READONLY {
731 return static_cast<PassDirection>(ParamCommandCommentBits.Direction);
734 bool isDirectionExplicit() const LLVM_READONLY {
735 return ParamCommandCommentBits.IsDirectionExplicit;
738 void setDirection(PassDirection Direction, bool Explicit) {
739 ParamCommandCommentBits.Direction = Direction;
740 ParamCommandCommentBits.IsDirectionExplicit = Explicit;
743 bool hasParamName() const {
744 return getNumArgs() > 0;
747 StringRef getParamName(const FullComment *FC) const;
749 StringRef getParamNameAsWritten() const {
753 SourceRange getParamNameRange() const {
754 return Args[0].Range;
757 bool isParamIndexValid() const LLVM_READONLY {
758 return ParamIndex != InvalidParamIndex;
761 bool isVarArgParam() const LLVM_READONLY {
762 return ParamIndex == VarArgParamIndex;
765 void setIsVarArgParam() {
766 ParamIndex = VarArgParamIndex;
767 assert(isParamIndexValid());
770 unsigned getParamIndex() const LLVM_READONLY {
771 assert(isParamIndexValid());
772 assert(!isVarArgParam());
776 void setParamIndex(unsigned Index) {
778 assert(isParamIndexValid());
779 assert(!isVarArgParam());
783 /// Doxygen \\tparam command, describes a template parameter.
784 class TParamCommandComment : public BlockCommandComment {
786 /// If this template parameter name was resolved (found in template parameter
787 /// list), then this stores a list of position indexes in all template
792 /// template<typename C, template<typename T> class TT>
793 /// void test(TT<int> aaa);
795 /// For C: Position = { 0 }
796 /// For TT: Position = { 1 }
797 /// For T: Position = { 1, 0 }
798 ArrayRef<unsigned> Position;
801 TParamCommandComment(SourceLocation LocBegin,
802 SourceLocation LocEnd,
804 CommandMarkerKind CommandMarker) :
805 BlockCommandComment(TParamCommandCommentKind, LocBegin, LocEnd, CommandID,
809 static bool classof(const Comment *C) {
810 return C->getCommentKind() == TParamCommandCommentKind;
813 bool hasParamName() const {
814 return getNumArgs() > 0;
817 StringRef getParamName(const FullComment *FC) const;
819 StringRef getParamNameAsWritten() const {
823 SourceRange getParamNameRange() const {
824 return Args[0].Range;
827 bool isPositionValid() const LLVM_READONLY {
828 return !Position.empty();
831 unsigned getDepth() const {
832 assert(isPositionValid());
833 return Position.size();
836 unsigned getIndex(unsigned Depth) const {
837 assert(isPositionValid());
838 return Position[Depth];
841 void setPosition(ArrayRef<unsigned> NewPosition) {
842 Position = NewPosition;
843 assert(isPositionValid());
847 /// A line of text contained in a verbatim block.
848 class VerbatimBlockLineComment : public Comment {
852 VerbatimBlockLineComment(SourceLocation LocBegin,
854 Comment(VerbatimBlockLineCommentKind,
856 LocBegin.getLocWithOffset(Text.size())),
860 static bool classof(const Comment *C) {
861 return C->getCommentKind() == VerbatimBlockLineCommentKind;
864 child_iterator child_begin() const { return NULL; }
866 child_iterator child_end() const { return NULL; }
868 StringRef getText() const LLVM_READONLY {
873 /// A verbatim block command (e. g., preformatted code). Verbatim block has an
874 /// opening and a closing command and contains multiple lines of text
875 /// (VerbatimBlockLineComment nodes).
876 class VerbatimBlockComment : public BlockCommandComment {
879 SourceLocation CloseNameLocBegin;
880 ArrayRef<VerbatimBlockLineComment *> Lines;
883 VerbatimBlockComment(SourceLocation LocBegin,
884 SourceLocation LocEnd,
885 unsigned CommandID) :
886 BlockCommandComment(VerbatimBlockCommentKind,
887 LocBegin, LocEnd, CommandID,
888 CMK_At) // FIXME: improve source fidelity.
891 static bool classof(const Comment *C) {
892 return C->getCommentKind() == VerbatimBlockCommentKind;
895 child_iterator child_begin() const {
896 return reinterpret_cast<child_iterator>(Lines.begin());
899 child_iterator child_end() const {
900 return reinterpret_cast<child_iterator>(Lines.end());
903 void setCloseName(StringRef Name, SourceLocation LocBegin) {
905 CloseNameLocBegin = LocBegin;
908 void setLines(ArrayRef<VerbatimBlockLineComment *> L) {
912 StringRef getCloseName() const {
916 unsigned getNumLines() const {
920 StringRef getText(unsigned LineIdx) const {
921 return Lines[LineIdx]->getText();
925 /// A verbatim line command. Verbatim line has an opening command, a single
926 /// line of text (up to the newline after the opening command) and has no
928 class VerbatimLineComment : public BlockCommandComment {
931 SourceLocation TextBegin;
934 VerbatimLineComment(SourceLocation LocBegin,
935 SourceLocation LocEnd,
937 SourceLocation TextBegin,
939 BlockCommandComment(VerbatimLineCommentKind,
942 CMK_At), // FIXME: improve source fidelity.
947 static bool classof(const Comment *C) {
948 return C->getCommentKind() == VerbatimLineCommentKind;
951 child_iterator child_begin() const { return NULL; }
953 child_iterator child_end() const { return NULL; }
955 StringRef getText() const {
959 SourceRange getTextRange() const {
960 return SourceRange(TextBegin, getLocEnd());
964 /// Information about the declaration, useful to clients of FullComment.
966 /// Declaration the comment is actually attached to (in the source).
967 /// Should not be NULL.
968 const Decl *CommentDecl;
970 /// CurrentDecl is the declaration with which the FullComment is associated.
972 /// It can be different from \c CommentDecl. It happens when we we decide
973 /// that the comment originally attached to \c CommentDecl is fine for
974 /// \c CurrentDecl too (for example, for a redeclaration or an overrider of
977 /// The information in the DeclInfo corresponds to CurrentDecl.
978 const Decl *CurrentDecl;
980 /// Parameters that can be referenced by \\param if \c CommentDecl is something
981 /// that we consider a "function".
982 ArrayRef<const ParmVarDecl *> ParamVars;
984 /// Function result type if \c CommentDecl is something that we consider
988 /// Template parameters that can be referenced by \\tparam if \c CommentDecl is
989 /// a template (\c IsTemplateDecl or \c IsTemplatePartialSpecialization is
991 const TemplateParameterList *TemplateParameters;
993 /// A simplified description of \c CommentDecl kind that should be good enough
994 /// for documentation rendering purposes.
996 /// Everything else not explicitly mentioned below.
999 /// Something that we consider a "function":
1001 /// \li function template,
1002 /// \li function template specialization,
1003 /// \li member function,
1004 /// \li member function template,
1005 /// \li member function template specialization,
1006 /// \li ObjC method,
1007 /// \li a typedef for a function pointer, member function pointer,
1011 /// Something that we consider a "class":
1012 /// \li class/struct,
1013 /// \li class template,
1014 /// \li class template (partial) specialization.
1017 /// Something that we consider a "variable":
1018 /// \li namespace scope variables;
1019 /// \li static and non-static class data members;
1020 /// \li enumerators.
1023 /// A C++ namespace.
1026 /// A C++ typedef-name (a 'typedef' decl specifier or alias-declaration),
1027 /// see \c TypedefNameDecl.
1030 /// An enumeration or scoped enumeration.
1034 /// What kind of template specialization \c CommentDecl is.
1035 enum TemplateDeclKind {
1038 TemplateSpecialization,
1039 TemplatePartialSpecialization
1042 /// If false, only \c CommentDecl is valid.
1043 unsigned IsFilled : 1;
1045 /// Simplified kind of \c CommentDecl, see \c DeclKind enum.
1048 /// Is \c CommentDecl a template declaration.
1049 unsigned TemplateKind : 2;
1051 /// Is \c CommentDecl an ObjCMethodDecl.
1052 unsigned IsObjCMethod : 1;
1054 /// Is \c CommentDecl a non-static member function of C++ class or
1055 /// instance method of ObjC class.
1056 /// Can be true only if \c IsFunctionDecl is true.
1057 unsigned IsInstanceMethod : 1;
1059 /// Is \c CommentDecl a static member function of C++ class or
1060 /// class method of ObjC class.
1061 /// Can be true only if \c IsFunctionDecl is true.
1062 unsigned IsClassMethod : 1;
1066 DeclKind getKind() const LLVM_READONLY {
1067 return static_cast<DeclKind>(Kind);
1070 TemplateDeclKind getTemplateKind() const LLVM_READONLY {
1071 return static_cast<TemplateDeclKind>(TemplateKind);
1075 /// A full comment attached to a declaration, contains block content.
1076 class FullComment : public Comment {
1077 ArrayRef<BlockContentComment *> Blocks;
1078 DeclInfo *ThisDeclInfo;
1081 FullComment(ArrayRef<BlockContentComment *> Blocks, DeclInfo *D) :
1082 Comment(FullCommentKind, SourceLocation(), SourceLocation()),
1083 Blocks(Blocks), ThisDeclInfo(D) {
1087 setSourceRange(SourceRange(Blocks.front()->getLocStart(),
1088 Blocks.back()->getLocEnd()));
1089 setLocation(Blocks.front()->getLocStart());
1092 static bool classof(const Comment *C) {
1093 return C->getCommentKind() == FullCommentKind;
1096 child_iterator child_begin() const {
1097 return reinterpret_cast<child_iterator>(Blocks.begin());
1100 child_iterator child_end() const {
1101 return reinterpret_cast<child_iterator>(Blocks.end());
1104 const Decl *getDecl() const LLVM_READONLY {
1105 return ThisDeclInfo->CommentDecl;
1108 const DeclInfo *getDeclInfo() const LLVM_READONLY {
1109 if (!ThisDeclInfo->IsFilled)
1110 ThisDeclInfo->fill();
1111 return ThisDeclInfo;
1114 ArrayRef<BlockContentComment *> getBlocks() const { return Blocks; }
1117 } // end namespace comments
1118 } // end namespace clang