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/Basic/SourceLocation.h"
18 #include "clang/AST/Type.h"
19 #include "clang/AST/CommentCommandTraits.h"
20 #include "clang/AST/DeclObjC.h"
21 #include "llvm/ADT/ArrayRef.h"
22 #include "llvm/ADT/StringRef.h"
27 class TemplateParameterList;
31 /// Any part of the comment.
35 /// Preferred location to show caret.
38 /// Source range of this AST node.
41 class CommentBitfields {
44 /// Type of this AST node.
47 enum { NumCommentBits = 8 };
49 class InlineContentCommentBitfields {
50 friend class InlineContentComment;
52 unsigned : NumCommentBits;
54 /// True if there is a newline after this inline content node.
55 /// (There is no separate AST node for a newline.)
56 unsigned HasTrailingNewline : 1;
58 enum { NumInlineContentCommentBits = NumCommentBits + 1 };
60 class TextCommentBitfields {
61 friend class TextComment;
63 unsigned : NumInlineContentCommentBits;
65 /// True if \c IsWhitespace field contains a valid value.
66 mutable unsigned IsWhitespaceValid : 1;
68 /// True if this comment AST node contains only whitespace.
69 mutable unsigned IsWhitespace : 1;
71 enum { NumTextCommentBits = NumInlineContentCommentBits + 2 };
73 class InlineCommandCommentBitfields {
74 friend class InlineCommandComment;
76 unsigned : NumInlineContentCommentBits;
78 unsigned RenderKind : 2;
79 unsigned CommandID : 8;
81 enum { NumInlineCommandCommentBits = NumInlineContentCommentBits + 10 };
83 class HTMLStartTagCommentBitfields {
84 friend class HTMLStartTagComment;
86 unsigned : NumInlineContentCommentBits;
88 /// True if this tag is self-closing (e. g., <br />). This is based on tag
89 /// spelling in comment (plain <br> would not set this flag).
90 unsigned IsSelfClosing : 1;
92 enum { NumHTMLStartTagCommentBits = NumInlineContentCommentBits + 1 };
94 class ParagraphCommentBitfields {
95 friend class ParagraphComment;
97 unsigned : NumCommentBits;
99 /// True if \c IsWhitespace field contains a valid value.
100 mutable unsigned IsWhitespaceValid : 1;
102 /// True if this comment AST node contains only whitespace.
103 mutable unsigned IsWhitespace : 1;
105 enum { NumParagraphCommentBits = NumCommentBits + 2 };
107 class BlockCommandCommentBitfields {
108 friend class BlockCommandComment;
110 unsigned : NumCommentBits;
112 unsigned CommandID : 8;
114 enum { NumBlockCommandCommentBits = NumCommentBits + 8 };
116 class ParamCommandCommentBitfields {
117 friend class ParamCommandComment;
119 unsigned : NumBlockCommandCommentBits;
121 /// Parameter passing direction, see ParamCommandComment::PassDirection.
122 unsigned Direction : 2;
124 /// True if direction was specified explicitly in the comment.
125 unsigned IsDirectionExplicit : 1;
127 enum { NumParamCommandCommentBits = NumBlockCommandCommentBits + 3 };
130 CommentBitfields CommentBits;
131 InlineContentCommentBitfields InlineContentCommentBits;
132 TextCommentBitfields TextCommentBits;
133 InlineCommandCommentBitfields InlineCommandCommentBits;
134 HTMLStartTagCommentBitfields HTMLStartTagCommentBits;
135 ParagraphCommentBitfields ParagraphCommentBits;
136 BlockCommandCommentBitfields BlockCommandCommentBits;
137 ParamCommandCommentBitfields ParamCommandCommentBits;
140 void setSourceRange(SourceRange SR) {
144 void setLocation(SourceLocation L) {
151 #define COMMENT(CLASS, PARENT) CLASS##Kind,
152 #define COMMENT_RANGE(BASE, FIRST, LAST) \
153 First##BASE##Constant=FIRST##Kind, Last##BASE##Constant=LAST##Kind,
154 #define LAST_COMMENT_RANGE(BASE, FIRST, LAST) \
155 First##BASE##Constant=FIRST##Kind, Last##BASE##Constant=LAST##Kind
156 #define ABSTRACT_COMMENT(COMMENT)
157 #include "clang/AST/CommentNodes.inc"
160 Comment(CommentKind K,
161 SourceLocation LocBegin,
162 SourceLocation LocEnd) :
163 Loc(LocBegin), Range(SourceRange(LocBegin, LocEnd)) {
164 CommentBits.Kind = K;
167 CommentKind getCommentKind() const {
168 return static_cast<CommentKind>(CommentBits.Kind);
171 const char *getCommentKindName() const;
173 LLVM_ATTRIBUTE_USED void dump() const;
174 LLVM_ATTRIBUTE_USED void dump(const ASTContext &Context) const;
175 void dump(llvm::raw_ostream &OS, const CommandTraits *Traits,
176 const SourceManager *SM) const;
178 SourceRange getSourceRange() const LLVM_READONLY { return Range; }
180 SourceLocation getLocStart() const LLVM_READONLY {
181 return Range.getBegin();
184 SourceLocation getLocEnd() const LLVM_READONLY {
185 return Range.getEnd();
188 SourceLocation getLocation() const LLVM_READONLY { return Loc; }
190 typedef Comment * const *child_iterator;
192 child_iterator child_begin() const;
193 child_iterator child_end() const;
195 // TODO: const child iterator
197 unsigned child_count() const {
198 return child_end() - child_begin();
202 /// Inline content (contained within a block).
204 class InlineContentComment : public Comment {
206 InlineContentComment(CommentKind K,
207 SourceLocation LocBegin,
208 SourceLocation LocEnd) :
209 Comment(K, LocBegin, LocEnd) {
210 InlineContentCommentBits.HasTrailingNewline = 0;
214 static bool classof(const Comment *C) {
215 return C->getCommentKind() >= FirstInlineContentCommentConstant &&
216 C->getCommentKind() <= LastInlineContentCommentConstant;
219 void addTrailingNewline() {
220 InlineContentCommentBits.HasTrailingNewline = 1;
223 bool hasTrailingNewline() const {
224 return InlineContentCommentBits.HasTrailingNewline;
229 class TextComment : public InlineContentComment {
233 TextComment(SourceLocation LocBegin,
234 SourceLocation LocEnd,
236 InlineContentComment(TextCommentKind, LocBegin, LocEnd),
238 TextCommentBits.IsWhitespaceValid = false;
241 static bool classof(const Comment *C) {
242 return C->getCommentKind() == TextCommentKind;
245 child_iterator child_begin() const { return NULL; }
247 child_iterator child_end() const { return NULL; }
249 StringRef getText() const LLVM_READONLY { return Text; }
251 bool isWhitespace() const {
252 if (TextCommentBits.IsWhitespaceValid)
253 return TextCommentBits.IsWhitespace;
255 TextCommentBits.IsWhitespace = isWhitespaceNoCache();
256 TextCommentBits.IsWhitespaceValid = true;
257 return TextCommentBits.IsWhitespace;
261 bool isWhitespaceNoCache() const;
264 /// A command with word-like arguments that is considered inline content.
265 class InlineCommandComment : public InlineContentComment {
271 Argument(SourceRange Range, StringRef Text) : Range(Range), Text(Text) { }
274 /// The most appropriate rendering mode for this command, chosen on command
275 /// semantics in Doxygen.
284 /// Command arguments.
285 llvm::ArrayRef<Argument> Args;
288 InlineCommandComment(SourceLocation LocBegin,
289 SourceLocation LocEnd,
292 llvm::ArrayRef<Argument> Args) :
293 InlineContentComment(InlineCommandCommentKind, LocBegin, LocEnd),
295 InlineCommandCommentBits.RenderKind = RK;
296 InlineCommandCommentBits.CommandID = CommandID;
299 static bool classof(const Comment *C) {
300 return C->getCommentKind() == InlineCommandCommentKind;
303 child_iterator child_begin() const { return NULL; }
305 child_iterator child_end() const { return NULL; }
307 unsigned getCommandID() const {
308 return InlineCommandCommentBits.CommandID;
311 StringRef getCommandName(const CommandTraits &Traits) const {
312 return Traits.getCommandInfo(getCommandID())->Name;
315 SourceRange getCommandNameRange() const {
316 return SourceRange(getLocStart().getLocWithOffset(-1),
320 RenderKind getRenderKind() const {
321 return static_cast<RenderKind>(InlineCommandCommentBits.RenderKind);
324 unsigned getNumArgs() const {
328 StringRef getArgText(unsigned Idx) const {
329 return Args[Idx].Text;
332 SourceRange getArgRange(unsigned Idx) const {
333 return Args[Idx].Range;
337 /// Abstract class for opening and closing HTML tags. HTML tags are always
338 /// treated as inline content (regardless HTML semantics); opening and closing
339 /// tags are not matched.
340 class HTMLTagComment : public InlineContentComment {
343 SourceRange TagNameRange;
345 HTMLTagComment(CommentKind K,
346 SourceLocation LocBegin,
347 SourceLocation LocEnd,
349 SourceLocation TagNameBegin,
350 SourceLocation TagNameEnd) :
351 InlineContentComment(K, LocBegin, LocEnd),
353 TagNameRange(TagNameBegin, TagNameEnd) {
354 setLocation(TagNameBegin);
358 static bool classof(const Comment *C) {
359 return C->getCommentKind() >= FirstHTMLTagCommentConstant &&
360 C->getCommentKind() <= LastHTMLTagCommentConstant;
363 StringRef getTagName() const LLVM_READONLY { return TagName; }
365 SourceRange getTagNameSourceRange() const LLVM_READONLY {
366 SourceLocation L = getLocation();
367 return SourceRange(L.getLocWithOffset(1),
368 L.getLocWithOffset(1 + TagName.size()));
372 /// An opening HTML tag with attributes.
373 class HTMLStartTagComment : public HTMLTagComment {
377 SourceLocation NameLocBegin;
380 SourceLocation EqualsLoc;
382 SourceRange ValueRange;
387 Attribute(SourceLocation NameLocBegin, StringRef Name) :
388 NameLocBegin(NameLocBegin), Name(Name),
389 EqualsLoc(SourceLocation()),
390 ValueRange(SourceRange()), Value(StringRef())
393 Attribute(SourceLocation NameLocBegin, StringRef Name,
394 SourceLocation EqualsLoc,
395 SourceRange ValueRange, StringRef Value) :
396 NameLocBegin(NameLocBegin), Name(Name),
397 EqualsLoc(EqualsLoc),
398 ValueRange(ValueRange), Value(Value)
401 SourceLocation getNameLocEnd() const {
402 return NameLocBegin.getLocWithOffset(Name.size());
405 SourceRange getNameRange() const {
406 return SourceRange(NameLocBegin, getNameLocEnd());
411 ArrayRef<Attribute> Attributes;
414 HTMLStartTagComment(SourceLocation LocBegin,
416 HTMLTagComment(HTMLStartTagCommentKind,
417 LocBegin, LocBegin.getLocWithOffset(1 + TagName.size()),
419 LocBegin.getLocWithOffset(1),
420 LocBegin.getLocWithOffset(1 + TagName.size())) {
421 HTMLStartTagCommentBits.IsSelfClosing = false;
424 static bool classof(const Comment *C) {
425 return C->getCommentKind() == HTMLStartTagCommentKind;
428 child_iterator child_begin() const { return NULL; }
430 child_iterator child_end() const { return NULL; }
432 unsigned getNumAttrs() const {
433 return Attributes.size();
436 const Attribute &getAttr(unsigned Idx) const {
437 return Attributes[Idx];
440 void setAttrs(ArrayRef<Attribute> Attrs) {
442 if (!Attrs.empty()) {
443 const Attribute &Attr = Attrs.back();
444 SourceLocation L = Attr.ValueRange.getEnd();
448 Range.setEnd(Attr.getNameLocEnd());
453 void setGreaterLoc(SourceLocation GreaterLoc) {
454 Range.setEnd(GreaterLoc);
457 bool isSelfClosing() const {
458 return HTMLStartTagCommentBits.IsSelfClosing;
461 void setSelfClosing() {
462 HTMLStartTagCommentBits.IsSelfClosing = true;
466 /// A closing HTML tag.
467 class HTMLEndTagComment : public HTMLTagComment {
469 HTMLEndTagComment(SourceLocation LocBegin,
470 SourceLocation LocEnd,
472 HTMLTagComment(HTMLEndTagCommentKind,
475 LocBegin.getLocWithOffset(2),
476 LocBegin.getLocWithOffset(2 + TagName.size()))
479 static bool classof(const Comment *C) {
480 return C->getCommentKind() == HTMLEndTagCommentKind;
483 child_iterator child_begin() const { return NULL; }
485 child_iterator child_end() const { return NULL; }
488 /// Block content (contains inline content).
490 class BlockContentComment : public Comment {
492 BlockContentComment(CommentKind K,
493 SourceLocation LocBegin,
494 SourceLocation LocEnd) :
495 Comment(K, LocBegin, LocEnd)
499 static bool classof(const Comment *C) {
500 return C->getCommentKind() >= FirstBlockContentCommentConstant &&
501 C->getCommentKind() <= LastBlockContentCommentConstant;
505 /// A single paragraph that contains inline content.
506 class ParagraphComment : public BlockContentComment {
507 llvm::ArrayRef<InlineContentComment *> Content;
510 ParagraphComment(llvm::ArrayRef<InlineContentComment *> Content) :
511 BlockContentComment(ParagraphCommentKind,
515 if (Content.empty()) {
516 ParagraphCommentBits.IsWhitespace = true;
517 ParagraphCommentBits.IsWhitespaceValid = true;
521 ParagraphCommentBits.IsWhitespaceValid = false;
523 setSourceRange(SourceRange(Content.front()->getLocStart(),
524 Content.back()->getLocEnd()));
525 setLocation(Content.front()->getLocStart());
528 static bool classof(const Comment *C) {
529 return C->getCommentKind() == ParagraphCommentKind;
532 child_iterator child_begin() const {
533 return reinterpret_cast<child_iterator>(Content.begin());
536 child_iterator child_end() const {
537 return reinterpret_cast<child_iterator>(Content.end());
540 bool isWhitespace() const {
541 if (ParagraphCommentBits.IsWhitespaceValid)
542 return ParagraphCommentBits.IsWhitespace;
544 ParagraphCommentBits.IsWhitespace = isWhitespaceNoCache();
545 ParagraphCommentBits.IsWhitespaceValid = true;
546 return ParagraphCommentBits.IsWhitespace;
550 bool isWhitespaceNoCache() const;
553 /// A command that has zero or more word-like arguments (number of word-like
554 /// arguments depends on command name) and a paragraph as an argument
555 /// (e. g., \\brief).
556 class BlockCommandComment : public BlockContentComment {
563 Argument(SourceRange Range, StringRef Text) : Range(Range), Text(Text) { }
567 /// Word-like arguments.
568 llvm::ArrayRef<Argument> Args;
570 /// Paragraph argument.
571 ParagraphComment *Paragraph;
573 BlockCommandComment(CommentKind K,
574 SourceLocation LocBegin,
575 SourceLocation LocEnd,
576 unsigned CommandID) :
577 BlockContentComment(K, LocBegin, LocEnd),
579 setLocation(getCommandNameBeginLoc());
580 BlockCommandCommentBits.CommandID = CommandID;
584 BlockCommandComment(SourceLocation LocBegin,
585 SourceLocation LocEnd,
586 unsigned CommandID) :
587 BlockContentComment(BlockCommandCommentKind, LocBegin, LocEnd),
589 setLocation(getCommandNameBeginLoc());
590 BlockCommandCommentBits.CommandID = CommandID;
593 static bool classof(const Comment *C) {
594 return C->getCommentKind() >= FirstBlockCommandCommentConstant &&
595 C->getCommentKind() <= LastBlockCommandCommentConstant;
598 child_iterator child_begin() const {
599 return reinterpret_cast<child_iterator>(&Paragraph);
602 child_iterator child_end() const {
603 return reinterpret_cast<child_iterator>(&Paragraph + 1);
606 unsigned getCommandID() const {
607 return BlockCommandCommentBits.CommandID;
610 StringRef getCommandName(const CommandTraits &Traits) const {
611 return Traits.getCommandInfo(getCommandID())->Name;
614 SourceLocation getCommandNameBeginLoc() const {
615 return getLocStart().getLocWithOffset(1);
618 SourceRange getCommandNameRange(const CommandTraits &Traits) const {
619 StringRef Name = getCommandName(Traits);
620 return SourceRange(getCommandNameBeginLoc(),
621 getLocStart().getLocWithOffset(1 + Name.size()));
624 unsigned getNumArgs() const {
628 StringRef getArgText(unsigned Idx) const {
629 return Args[Idx].Text;
632 SourceRange getArgRange(unsigned Idx) const {
633 return Args[Idx].Range;
636 void setArgs(llvm::ArrayRef<Argument> A) {
638 if (Args.size() > 0) {
639 SourceLocation NewLocEnd = Args.back().Range.getEnd();
640 if (NewLocEnd.isValid())
641 setSourceRange(SourceRange(getLocStart(), NewLocEnd));
645 ParagraphComment *getParagraph() const LLVM_READONLY {
649 bool hasNonWhitespaceParagraph() const {
650 return Paragraph && !Paragraph->isWhitespace();
653 void setParagraph(ParagraphComment *PC) {
655 SourceLocation NewLocEnd = PC->getLocEnd();
656 if (NewLocEnd.isValid())
657 setSourceRange(SourceRange(getLocStart(), NewLocEnd));
661 /// Doxygen \\param command.
662 class ParamCommandComment : public BlockCommandComment {
664 /// Parameter index in the function declaration.
668 enum { InvalidParamIndex = ~0U };
670 ParamCommandComment(SourceLocation LocBegin,
671 SourceLocation LocEnd,
672 unsigned CommandID) :
673 BlockCommandComment(ParamCommandCommentKind, LocBegin, LocEnd,
675 ParamIndex(InvalidParamIndex) {
676 ParamCommandCommentBits.Direction = In;
677 ParamCommandCommentBits.IsDirectionExplicit = false;
680 static bool classof(const Comment *C) {
681 return C->getCommentKind() == ParamCommandCommentKind;
690 static const char *getDirectionAsString(PassDirection D);
692 PassDirection getDirection() const LLVM_READONLY {
693 return static_cast<PassDirection>(ParamCommandCommentBits.Direction);
696 bool isDirectionExplicit() const LLVM_READONLY {
697 return ParamCommandCommentBits.IsDirectionExplicit;
700 void setDirection(PassDirection Direction, bool Explicit) {
701 ParamCommandCommentBits.Direction = Direction;
702 ParamCommandCommentBits.IsDirectionExplicit = Explicit;
705 bool hasParamName() const {
706 return getNumArgs() > 0;
709 StringRef getParamName(const FullComment *FC) const;
711 StringRef getParamNameAsWritten() const {
715 SourceRange getParamNameRange() const {
716 return Args[0].Range;
719 bool isParamIndexValid() const LLVM_READONLY {
720 return ParamIndex != InvalidParamIndex;
723 unsigned getParamIndex() const LLVM_READONLY {
724 assert(isParamIndexValid());
728 void setParamIndex(unsigned Index) {
730 assert(isParamIndexValid());
734 /// Doxygen \\tparam command, describes a template parameter.
735 class TParamCommandComment : public BlockCommandComment {
737 /// If this template parameter name was resolved (found in template parameter
738 /// list), then this stores a list of position indexes in all template
743 /// template<typename C, template<typename T> class TT>
744 /// void test(TT<int> aaa);
746 /// For C: Position = { 0 }
747 /// For TT: Position = { 1 }
748 /// For T: Position = { 1, 0 }
749 llvm::ArrayRef<unsigned> Position;
752 TParamCommandComment(SourceLocation LocBegin,
753 SourceLocation LocEnd,
754 unsigned CommandID) :
755 BlockCommandComment(TParamCommandCommentKind, LocBegin, LocEnd, CommandID)
758 static bool classof(const Comment *C) {
759 return C->getCommentKind() == TParamCommandCommentKind;
762 bool hasParamName() const {
763 return getNumArgs() > 0;
766 StringRef getParamName(const FullComment *FC) const;
768 StringRef getParamNameAsWritten() const {
772 SourceRange getParamNameRange() const {
773 return Args[0].Range;
776 bool isPositionValid() const LLVM_READONLY {
777 return !Position.empty();
780 unsigned getDepth() const {
781 assert(isPositionValid());
782 return Position.size();
785 unsigned getIndex(unsigned Depth) const {
786 assert(isPositionValid());
787 return Position[Depth];
790 void setPosition(ArrayRef<unsigned> NewPosition) {
791 Position = NewPosition;
792 assert(isPositionValid());
796 /// A line of text contained in a verbatim block.
797 class VerbatimBlockLineComment : public Comment {
801 VerbatimBlockLineComment(SourceLocation LocBegin,
803 Comment(VerbatimBlockLineCommentKind,
805 LocBegin.getLocWithOffset(Text.size())),
809 static bool classof(const Comment *C) {
810 return C->getCommentKind() == VerbatimBlockLineCommentKind;
813 child_iterator child_begin() const { return NULL; }
815 child_iterator child_end() const { return NULL; }
817 StringRef getText() const LLVM_READONLY {
822 /// A verbatim block command (e. g., preformatted code). Verbatim block has an
823 /// opening and a closing command and contains multiple lines of text
824 /// (VerbatimBlockLineComment nodes).
825 class VerbatimBlockComment : public BlockCommandComment {
828 SourceLocation CloseNameLocBegin;
829 llvm::ArrayRef<VerbatimBlockLineComment *> Lines;
832 VerbatimBlockComment(SourceLocation LocBegin,
833 SourceLocation LocEnd,
834 unsigned CommandID) :
835 BlockCommandComment(VerbatimBlockCommentKind,
836 LocBegin, LocEnd, CommandID)
839 static bool classof(const Comment *C) {
840 return C->getCommentKind() == VerbatimBlockCommentKind;
843 child_iterator child_begin() const {
844 return reinterpret_cast<child_iterator>(Lines.begin());
847 child_iterator child_end() const {
848 return reinterpret_cast<child_iterator>(Lines.end());
851 void setCloseName(StringRef Name, SourceLocation LocBegin) {
853 CloseNameLocBegin = LocBegin;
856 void setLines(llvm::ArrayRef<VerbatimBlockLineComment *> L) {
860 StringRef getCloseName() const {
864 unsigned getNumLines() const {
868 StringRef getText(unsigned LineIdx) const {
869 return Lines[LineIdx]->getText();
873 /// A verbatim line command. Verbatim line has an opening command, a single
874 /// line of text (up to the newline after the opening command) and has no
876 class VerbatimLineComment : public BlockCommandComment {
879 SourceLocation TextBegin;
882 VerbatimLineComment(SourceLocation LocBegin,
883 SourceLocation LocEnd,
885 SourceLocation TextBegin,
887 BlockCommandComment(VerbatimLineCommentKind,
894 static bool classof(const Comment *C) {
895 return C->getCommentKind() == VerbatimLineCommentKind;
898 child_iterator child_begin() const { return NULL; }
900 child_iterator child_end() const { return NULL; }
902 StringRef getText() const {
906 SourceRange getTextRange() const {
907 return SourceRange(TextBegin, getLocEnd());
911 /// Information about the declaration, useful to clients of FullComment.
913 /// Declaration the comment is actually attached to (in the source).
914 /// Should not be NULL.
915 const Decl *CommentDecl;
917 /// CurrentDecl is the declaration with which the FullComment is associated.
919 /// It can be different from \c CommentDecl. It happens when we we decide
920 /// that the comment originally attached to \c CommentDecl is fine for
921 /// \c CurrentDecl too (for example, for a redeclaration or an overrider of
924 /// The information in the DeclInfo corresponds to CurrentDecl.
925 const Decl *CurrentDecl;
927 /// Parameters that can be referenced by \\param if \c CommentDecl is something
928 /// that we consider a "function".
929 ArrayRef<const ParmVarDecl *> ParamVars;
931 /// Function result type if \c CommentDecl is something that we consider
935 /// Template parameters that can be referenced by \\tparam if \c CommentDecl is
936 /// a template (\c IsTemplateDecl or \c IsTemplatePartialSpecialization is
938 const TemplateParameterList *TemplateParameters;
940 /// A simplified description of \c CommentDecl kind that should be good enough
941 /// for documentation rendering purposes.
943 /// Everything else not explicitly mentioned below.
946 /// Something that we consider a "function":
948 /// \li function template,
949 /// \li function template specialization,
950 /// \li member function,
951 /// \li member function template,
952 /// \li member function template specialization,
954 /// \li a typedef for a function pointer, member function pointer,
958 /// Something that we consider a "class":
959 /// \li class/struct,
960 /// \li class template,
961 /// \li class template (partial) specialization.
964 /// Something that we consider a "variable":
965 /// \li namespace scope variables;
966 /// \li static and non-static class data members;
973 /// A C++ typedef-name (a 'typedef' decl specifier or alias-declaration),
974 /// see \c TypedefNameDecl.
977 /// An enumeration or scoped enumeration.
981 /// What kind of template specialization \c CommentDecl is.
982 enum TemplateDeclKind {
985 TemplateSpecialization,
986 TemplatePartialSpecialization
989 /// If false, only \c CommentDecl is valid.
990 unsigned IsFilled : 1;
992 /// Simplified kind of \c CommentDecl, see \c DeclKind enum.
995 /// Is \c CommentDecl a template declaration.
996 unsigned TemplateKind : 2;
998 /// Is \c CommentDecl an ObjCMethodDecl.
999 unsigned IsObjCMethod : 1;
1001 /// Is \c CommentDecl a non-static member function of C++ class or
1002 /// instance method of ObjC class.
1003 /// Can be true only if \c IsFunctionDecl is true.
1004 unsigned IsInstanceMethod : 1;
1006 /// Is \c CommentDecl a static member function of C++ class or
1007 /// class method of ObjC class.
1008 /// Can be true only if \c IsFunctionDecl is true.
1009 unsigned IsClassMethod : 1;
1013 DeclKind getKind() const LLVM_READONLY {
1014 return static_cast<DeclKind>(Kind);
1017 TemplateDeclKind getTemplateKind() const LLVM_READONLY {
1018 return static_cast<TemplateDeclKind>(TemplateKind);
1022 /// A full comment attached to a declaration, contains block content.
1023 class FullComment : public Comment {
1024 llvm::ArrayRef<BlockContentComment *> Blocks;
1025 DeclInfo *ThisDeclInfo;
1028 FullComment(llvm::ArrayRef<BlockContentComment *> Blocks, DeclInfo *D) :
1029 Comment(FullCommentKind, SourceLocation(), SourceLocation()),
1030 Blocks(Blocks), ThisDeclInfo(D) {
1034 setSourceRange(SourceRange(Blocks.front()->getLocStart(),
1035 Blocks.back()->getLocEnd()));
1036 setLocation(Blocks.front()->getLocStart());
1039 static bool classof(const Comment *C) {
1040 return C->getCommentKind() == FullCommentKind;
1043 child_iterator child_begin() const {
1044 return reinterpret_cast<child_iterator>(Blocks.begin());
1047 child_iterator child_end() const {
1048 return reinterpret_cast<child_iterator>(Blocks.end());
1051 const Decl *getDecl() const LLVM_READONLY {
1052 return ThisDeclInfo->CommentDecl;
1055 const DeclInfo *getDeclInfo() const LLVM_READONLY {
1056 if (!ThisDeclInfo->IsFilled)
1057 ThisDeclInfo->fill();
1058 return ThisDeclInfo;
1061 DeclInfo *getThisDeclInfo() const LLVM_READONLY {
1062 return ThisDeclInfo;
1065 llvm::ArrayRef<BlockContentComment *> getBlocks() const { return Blocks; }
1068 } // end namespace comments
1069 } // end namespace clang