clang  19.0.0git
Comment.h
Go to the documentation of this file.
1 //===--- Comment.h - Comment AST nodes --------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines comment AST nodes.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef LLVM_CLANG_AST_COMMENT_H
14 #define LLVM_CLANG_AST_COMMENT_H
15 
17 #include "clang/AST/DeclObjC.h"
18 #include "clang/AST/Type.h"
20 #include "llvm/ADT/ArrayRef.h"
21 #include "llvm/ADT/StringRef.h"
22 
23 namespace clang {
24 class Decl;
25 class ParmVarDecl;
26 class TemplateParameterList;
27 
28 namespace comments {
29 class FullComment;
30 enum class InlineCommandRenderKind;
31 enum class ParamCommandPassDirection;
32 
33 /// Describes the syntax that was used in a documentation command.
34 ///
35 /// Exact values of this enumeration are important because they used to select
36 /// parts of diagnostic messages. Audit diagnostics before changing or adding
37 /// a new value.
39  /// Command started with a backslash character:
40  /// \code
41  /// \foo
42  /// \endcode
44 
45  /// Command started with an 'at' character:
46  /// \code
47  /// @foo
48  /// \endcode
49  CMK_At = 1
50 };
51 
52 enum class CommentKind {
53  None = 0,
54 #define COMMENT(CLASS, PARENT) CLASS,
55 #define COMMENT_RANGE(BASE, FIRST, LAST) \
56  First##BASE##Constant = FIRST, Last##BASE##Constant = LAST,
57 #define LAST_COMMENT_RANGE(BASE, FIRST, LAST) \
58  First##BASE##Constant = FIRST, Last##BASE##Constant = LAST
59 #define ABSTRACT_COMMENT(COMMENT)
60 #include "clang/AST/CommentNodes.inc"
61 };
62 
63 /// Any part of the comment.
64 /// Abstract class.
65 class Comment {
66 protected:
67  /// Preferred location to show caret.
69 
70  /// Source range of this AST node.
72 
74  friend class Comment;
75 
76  /// Type of this AST node.
77  LLVM_PREFERRED_TYPE(CommentKind)
78  unsigned Kind : 8;
79  };
80  enum { NumCommentBits = 8 };
81 
83  friend class InlineContentComment;
84 
85  LLVM_PREFERRED_TYPE(CommentBitfields)
87 
88  /// True if there is a newline after this inline content node.
89  /// (There is no separate AST node for a newline.)
90  LLVM_PREFERRED_TYPE(bool)
91  unsigned HasTrailingNewline : 1;
92  };
94 
96  friend class TextComment;
97 
98  LLVM_PREFERRED_TYPE(InlineContentCommentBitfields)
100 
101  /// True if \c IsWhitespace field contains a valid value.
102  LLVM_PREFERRED_TYPE(bool)
103  mutable unsigned IsWhitespaceValid : 1;
104 
105  /// True if this comment AST node contains only whitespace.
106  LLVM_PREFERRED_TYPE(bool)
107  mutable unsigned IsWhitespace : 1;
108  };
110 
112  friend class InlineCommandComment;
113 
114  LLVM_PREFERRED_TYPE(InlineContentCommentBitfields)
116 
117  LLVM_PREFERRED_TYPE(InlineCommandRenderKind)
118  unsigned RenderKind : 3;
119 
120  LLVM_PREFERRED_TYPE(CommandTraits::KnownCommandIDs)
121  unsigned CommandID : CommandInfo::NumCommandIDBits;
122  };
125 
127  friend class HTMLTagComment;
128 
129  LLVM_PREFERRED_TYPE(InlineContentCommentBitfields)
131 
132  /// True if we found that this tag is malformed in some way.
133  LLVM_PREFERRED_TYPE(bool)
134  unsigned IsMalformed : 1;
135  };
137 
139  friend class HTMLStartTagComment;
140 
141  LLVM_PREFERRED_TYPE(HTMLTagCommentBitfields)
143 
144  /// True if this tag is self-closing (e. g., <br />). This is based on tag
145  /// spelling in comment (plain <br> would not set this flag).
146  LLVM_PREFERRED_TYPE(bool)
147  unsigned IsSelfClosing : 1;
148  };
150 
152  friend class ParagraphComment;
153 
154  LLVM_PREFERRED_TYPE(CommentBitfields)
156 
157  /// True if \c IsWhitespace field contains a valid value.
158  LLVM_PREFERRED_TYPE(bool)
159  mutable unsigned IsWhitespaceValid : 1;
160 
161  /// True if this comment AST node contains only whitespace.
162  LLVM_PREFERRED_TYPE(bool)
163  mutable unsigned IsWhitespace : 1;
164  };
166 
168  friend class BlockCommandComment;
169 
170  LLVM_PREFERRED_TYPE(CommentBitfields)
172 
173  LLVM_PREFERRED_TYPE(CommandTraits::KnownCommandIDs)
174  unsigned CommandID : CommandInfo::NumCommandIDBits;
175 
176  /// Describes the syntax that was used in a documentation command.
177  /// Contains values from CommandMarkerKind enum.
178  LLVM_PREFERRED_TYPE(CommandMarkerKind)
179  unsigned CommandMarker : 1;
180  };
183 
185  friend class ParamCommandComment;
186 
187  LLVM_PREFERRED_TYPE(BlockCommandCommentBitfields)
189 
190  /// Parameter passing direction.
191  LLVM_PREFERRED_TYPE(ParamCommandPassDirection)
192  unsigned Direction : 2;
193 
194  /// True if direction was specified explicitly in the comment.
195  LLVM_PREFERRED_TYPE(bool)
196  unsigned IsDirectionExplicit : 1;
197  };
199 
200  union {
210  };
211 
213  Range = SR;
214  }
215 
217  Loc = L;
218  }
219 
220 public:
221  struct Argument {
223  StringRef Text;
224  };
225 
227  SourceLocation LocBegin,
228  SourceLocation LocEnd) :
229  Loc(LocBegin), Range(SourceRange(LocBegin, LocEnd)) {
230  CommentBits.Kind = llvm::to_underlying(K);
231  }
232 
234  return static_cast<CommentKind>(CommentBits.Kind);
235  }
236 
237  const char *getCommentKindName() const;
238 
239  void dump() const;
240  void dumpColor() const;
241  void dump(raw_ostream &OS, const ASTContext &Context) const;
242 
243  SourceRange getSourceRange() const LLVM_READONLY { return Range; }
244 
245  SourceLocation getBeginLoc() const LLVM_READONLY { return Range.getBegin(); }
246 
247  SourceLocation getEndLoc() const LLVM_READONLY { return Range.getEnd(); }
248 
249  SourceLocation getLocation() const LLVM_READONLY { return Loc; }
250 
251  typedef Comment * const *child_iterator;
252 
253  child_iterator child_begin() const;
254  child_iterator child_end() const;
255 
256  // TODO: const child iterator
257 
258  unsigned child_count() const {
259  return child_end() - child_begin();
260  }
261 };
262 
263 /// Inline content (contained within a block).
264 /// Abstract class.
266 protected:
268  SourceLocation LocBegin,
269  SourceLocation LocEnd) :
270  Comment(K, LocBegin, LocEnd) {
271  InlineContentCommentBits.HasTrailingNewline = 0;
272  }
273 
274 public:
275  static bool classof(const Comment *C) {
276  return C->getCommentKind() >=
277  CommentKind::FirstInlineContentCommentConstant &&
278  C->getCommentKind() <= CommentKind::LastInlineContentCommentConstant;
279  }
280 
282  InlineContentCommentBits.HasTrailingNewline = 1;
283  }
284 
285  bool hasTrailingNewline() const {
286  return InlineContentCommentBits.HasTrailingNewline;
287  }
288 };
289 
290 /// Plain text.
292  StringRef Text;
293 
294 public:
295  TextComment(SourceLocation LocBegin, SourceLocation LocEnd, StringRef Text)
296  : InlineContentComment(CommentKind::TextComment, LocBegin, LocEnd),
297  Text(Text) {
298  TextCommentBits.IsWhitespaceValid = false;
299  }
300 
301  static bool classof(const Comment *C) {
302  return C->getCommentKind() == CommentKind::TextComment;
303  }
304 
305  child_iterator child_begin() const { return nullptr; }
306 
307  child_iterator child_end() const { return nullptr; }
308 
309  StringRef getText() const LLVM_READONLY { return Text; }
310 
311  bool isWhitespace() const {
312  if (TextCommentBits.IsWhitespaceValid)
313  return TextCommentBits.IsWhitespace;
314 
315  TextCommentBits.IsWhitespace = isWhitespaceNoCache();
316  TextCommentBits.IsWhitespaceValid = true;
317  return TextCommentBits.IsWhitespace;
318  }
319 
320 private:
321  bool isWhitespaceNoCache() const;
322 };
323 
324 /// The most appropriate rendering mode for this command, chosen on command
325 /// semantics in Doxygen.
327  Normal,
328  Bold,
329  Monospaced,
330  Emphasized,
331  Anchor
332 };
333 
334 /// A command with word-like arguments that is considered inline content.
336 protected:
337  /// Command arguments.
339 
340 public:
342  unsigned CommandID, InlineCommandRenderKind RK,
345  LocEnd),
346  Args(Args) {
347  InlineCommandCommentBits.RenderKind = llvm::to_underlying(RK);
348  InlineCommandCommentBits.CommandID = CommandID;
349  }
350 
351  static bool classof(const Comment *C) {
352  return C->getCommentKind() == CommentKind::InlineCommandComment;
353  }
354 
355  child_iterator child_begin() const { return nullptr; }
356 
357  child_iterator child_end() const { return nullptr; }
358 
359  unsigned getCommandID() const {
360  return InlineCommandCommentBits.CommandID;
361  }
362 
363  StringRef getCommandName(const CommandTraits &Traits) const {
364  return Traits.getCommandInfo(getCommandID())->Name;
365  }
366 
368  return SourceRange(getBeginLoc().getLocWithOffset(-1), getEndLoc());
369  }
370 
372  return static_cast<InlineCommandRenderKind>(
373  InlineCommandCommentBits.RenderKind);
374  }
375 
376  unsigned getNumArgs() const {
377  return Args.size();
378  }
379 
380  StringRef getArgText(unsigned Idx) const {
381  return Args[Idx].Text;
382  }
383 
384  SourceRange getArgRange(unsigned Idx) const {
385  return Args[Idx].Range;
386  }
387 };
388 
389 /// Abstract class for opening and closing HTML tags. HTML tags are always
390 /// treated as inline content (regardless HTML semantics).
392 protected:
393  StringRef TagName;
395 
397  SourceLocation LocBegin,
398  SourceLocation LocEnd,
399  StringRef TagName,
400  SourceLocation TagNameBegin,
401  SourceLocation TagNameEnd) :
402  InlineContentComment(K, LocBegin, LocEnd),
403  TagName(TagName),
404  TagNameRange(TagNameBegin, TagNameEnd) {
405  setLocation(TagNameBegin);
406  HTMLTagCommentBits.IsMalformed = 0;
407  }
408 
409 public:
410  static bool classof(const Comment *C) {
411  return C->getCommentKind() >= CommentKind::FirstHTMLTagCommentConstant &&
412  C->getCommentKind() <= CommentKind::LastHTMLTagCommentConstant;
413  }
414 
415  StringRef getTagName() const LLVM_READONLY { return TagName; }
416 
417  SourceRange getTagNameSourceRange() const LLVM_READONLY {
419  return SourceRange(L.getLocWithOffset(1),
420  L.getLocWithOffset(1 + TagName.size()));
421  }
422 
423  bool isMalformed() const {
424  return HTMLTagCommentBits.IsMalformed;
425  }
426 
427  void setIsMalformed() {
428  HTMLTagCommentBits.IsMalformed = 1;
429  }
430 };
431 
432 /// An opening HTML tag with attributes.
434 public:
435  class Attribute {
436  public:
438  StringRef Name;
439 
441 
443  StringRef Value;
444 
445  Attribute() { }
446 
449 
454 
456  return NameLocBegin.getLocWithOffset(Name.size());
457  }
458 
461  }
462  };
463 
464 private:
465  ArrayRef<Attribute> Attributes;
466 
467 public:
470  LocBegin.getLocWithOffset(1 + TagName.size()), TagName,
471  LocBegin.getLocWithOffset(1),
472  LocBegin.getLocWithOffset(1 + TagName.size())) {
473  HTMLStartTagCommentBits.IsSelfClosing = false;
474  }
475 
476  static bool classof(const Comment *C) {
477  return C->getCommentKind() == CommentKind::HTMLStartTagComment;
478  }
479 
480  child_iterator child_begin() const { return nullptr; }
481 
482  child_iterator child_end() const { return nullptr; }
483 
484  unsigned getNumAttrs() const {
485  return Attributes.size();
486  }
487 
488  const Attribute &getAttr(unsigned Idx) const {
489  return Attributes[Idx];
490  }
491 
493  Attributes = Attrs;
494  if (!Attrs.empty()) {
495  const Attribute &Attr = Attrs.back();
496  SourceLocation L = Attr.ValueRange.getEnd();
497  if (L.isValid())
498  Range.setEnd(L);
499  else {
500  Range.setEnd(Attr.getNameLocEnd());
501  }
502  }
503  }
504 
505  void setGreaterLoc(SourceLocation GreaterLoc) {
506  Range.setEnd(GreaterLoc);
507  }
508 
509  bool isSelfClosing() const {
510  return HTMLStartTagCommentBits.IsSelfClosing;
511  }
512 
513  void setSelfClosing() {
514  HTMLStartTagCommentBits.IsSelfClosing = true;
515  }
516 };
517 
518 /// A closing HTML tag.
520 public:
522  StringRef TagName)
523  : HTMLTagComment(CommentKind::HTMLEndTagComment, LocBegin, LocEnd,
524  TagName, LocBegin.getLocWithOffset(2),
525  LocBegin.getLocWithOffset(2 + TagName.size())) {}
526 
527  static bool classof(const Comment *C) {
528  return C->getCommentKind() == CommentKind::HTMLEndTagComment;
529  }
530 
531  child_iterator child_begin() const { return nullptr; }
532 
533  child_iterator child_end() const { return nullptr; }
534 };
535 
536 /// Block content (contains inline content).
537 /// Abstract class.
538 class BlockContentComment : public Comment {
539 protected:
541  SourceLocation LocBegin,
542  SourceLocation LocEnd) :
543  Comment(K, LocBegin, LocEnd)
544  { }
545 
546 public:
547  static bool classof(const Comment *C) {
548  return C->getCommentKind() >=
549  CommentKind::FirstBlockContentCommentConstant &&
550  C->getCommentKind() <= CommentKind::LastBlockContentCommentConstant;
551  }
552 };
553 
554 /// A single paragraph that contains inline content.
557 
558 public:
561  SourceLocation()),
562  Content(Content) {
563  if (Content.empty()) {
564  ParagraphCommentBits.IsWhitespace = true;
565  ParagraphCommentBits.IsWhitespaceValid = true;
566  return;
567  }
568 
569  ParagraphCommentBits.IsWhitespaceValid = false;
570 
571  setSourceRange(SourceRange(Content.front()->getBeginLoc(),
572  Content.back()->getEndLoc()));
573  setLocation(Content.front()->getBeginLoc());
574  }
575 
576  static bool classof(const Comment *C) {
577  return C->getCommentKind() == CommentKind::ParagraphComment;
578  }
579 
581  return reinterpret_cast<child_iterator>(Content.begin());
582  }
583 
585  return reinterpret_cast<child_iterator>(Content.end());
586  }
587 
588  bool isWhitespace() const {
589  if (ParagraphCommentBits.IsWhitespaceValid)
590  return ParagraphCommentBits.IsWhitespace;
591 
592  ParagraphCommentBits.IsWhitespace = isWhitespaceNoCache();
593  ParagraphCommentBits.IsWhitespaceValid = true;
594  return ParagraphCommentBits.IsWhitespace;
595  }
596 
597 private:
598  bool isWhitespaceNoCache() const;
599 };
600 
601 /// A command that has zero or more word-like arguments (number of word-like
602 /// arguments depends on command name) and a paragraph as an argument
603 /// (e. g., \\brief).
605 protected:
606  /// Word-like arguments.
608 
609  /// Paragraph argument.
611 
613  SourceLocation LocBegin,
614  SourceLocation LocEnd,
615  unsigned CommandID,
616  CommandMarkerKind CommandMarker) :
617  BlockContentComment(K, LocBegin, LocEnd),
618  Paragraph(nullptr) {
620  BlockCommandCommentBits.CommandID = CommandID;
621  BlockCommandCommentBits.CommandMarker = CommandMarker;
622  }
623 
624 public:
626  unsigned CommandID, CommandMarkerKind CommandMarker)
628  Paragraph(nullptr) {
630  BlockCommandCommentBits.CommandID = CommandID;
631  BlockCommandCommentBits.CommandMarker = CommandMarker;
632  }
633 
634  static bool classof(const Comment *C) {
635  return C->getCommentKind() >=
636  CommentKind::FirstBlockCommandCommentConstant &&
637  C->getCommentKind() <= CommentKind::LastBlockCommandCommentConstant;
638  }
639 
641  return reinterpret_cast<child_iterator>(&Paragraph);
642  }
643 
645  return reinterpret_cast<child_iterator>(&Paragraph + 1);
646  }
647 
648  unsigned getCommandID() const {
649  return BlockCommandCommentBits.CommandID;
650  }
651 
652  StringRef getCommandName(const CommandTraits &Traits) const {
653  return Traits.getCommandInfo(getCommandID())->Name;
654  }
655 
657  return getBeginLoc().getLocWithOffset(1);
658  }
659 
661  StringRef Name = getCommandName(Traits);
663  getBeginLoc().getLocWithOffset(1 + Name.size()));
664  }
665 
666  unsigned getNumArgs() const {
667  return Args.size();
668  }
669 
670  StringRef getArgText(unsigned Idx) const {
671  return Args[Idx].Text;
672  }
673 
674  SourceRange getArgRange(unsigned Idx) const {
675  return Args[Idx].Range;
676  }
677 
679  Args = A;
680  if (Args.size() > 0) {
681  SourceLocation NewLocEnd = Args.back().Range.getEnd();
682  if (NewLocEnd.isValid())
683  setSourceRange(SourceRange(getBeginLoc(), NewLocEnd));
684  }
685  }
686 
687  ParagraphComment *getParagraph() const LLVM_READONLY {
688  return Paragraph;
689  }
690 
692  return Paragraph && !Paragraph->isWhitespace();
693  }
694 
696  Paragraph = PC;
697  SourceLocation NewLocEnd = PC->getEndLoc();
698  if (NewLocEnd.isValid())
699  setSourceRange(SourceRange(getBeginLoc(), NewLocEnd));
700  }
701 
702  CommandMarkerKind getCommandMarker() const LLVM_READONLY {
703  return static_cast<CommandMarkerKind>(
704  BlockCommandCommentBits.CommandMarker);
705  }
706 };
707 
709 
710 /// Doxygen \\param command.
712 private:
713  /// Parameter index in the function declaration.
714  unsigned ParamIndex;
715 
716 public:
717  enum : unsigned {
719  VarArgParamIndex = ~0U/*InvalidParamIndex*/ - 1U
720  };
721 
723  unsigned CommandID, CommandMarkerKind CommandMarker)
725  CommandID, CommandMarker),
726  ParamIndex(InvalidParamIndex) {
727  ParamCommandCommentBits.Direction =
728  llvm::to_underlying(ParamCommandPassDirection::In);
729  ParamCommandCommentBits.IsDirectionExplicit = false;
730  }
731 
732  static bool classof(const Comment *C) {
733  return C->getCommentKind() == CommentKind::ParamCommandComment;
734  }
735 
736  static const char *getDirectionAsString(ParamCommandPassDirection D);
737 
738  ParamCommandPassDirection getDirection() const LLVM_READONLY {
739  return static_cast<ParamCommandPassDirection>(
740  ParamCommandCommentBits.Direction);
741  }
742 
743  bool isDirectionExplicit() const LLVM_READONLY {
744  return ParamCommandCommentBits.IsDirectionExplicit;
745  }
746 
747  void setDirection(ParamCommandPassDirection Direction, bool Explicit) {
748  ParamCommandCommentBits.Direction = llvm::to_underlying(Direction);
749  ParamCommandCommentBits.IsDirectionExplicit = Explicit;
750  }
751 
752  bool hasParamName() const {
753  return getNumArgs() > 0;
754  }
755 
756  StringRef getParamName(const FullComment *FC) const;
757 
758  StringRef getParamNameAsWritten() const {
759  return Args[0].Text;
760  }
761 
763  return Args[0].Range;
764  }
765 
766  bool isParamIndexValid() const LLVM_READONLY {
767  return ParamIndex != InvalidParamIndex;
768  }
769 
770  bool isVarArgParam() const LLVM_READONLY {
771  return ParamIndex == VarArgParamIndex;
772  }
773 
775  ParamIndex = VarArgParamIndex;
776  assert(isParamIndexValid());
777  }
778 
779  unsigned getParamIndex() const LLVM_READONLY {
780  assert(isParamIndexValid());
781  assert(!isVarArgParam());
782  return ParamIndex;
783  }
784 
785  void setParamIndex(unsigned Index) {
786  ParamIndex = Index;
787  assert(isParamIndexValid());
788  assert(!isVarArgParam());
789  }
790 };
791 
792 /// Doxygen \\tparam command, describes a template parameter.
794 private:
795  /// If this template parameter name was resolved (found in template parameter
796  /// list), then this stores a list of position indexes in all template
797  /// parameter lists.
798  ///
799  /// For example:
800  /// \verbatim
801  /// template<typename C, template<typename T> class TT>
802  /// void test(TT<int> aaa);
803  /// \endverbatim
804  /// For C: Position = { 0 }
805  /// For TT: Position = { 1 }
806  /// For T: Position = { 1, 0 }
807  ArrayRef<unsigned> Position;
808 
809 public:
811  unsigned CommandID, CommandMarkerKind CommandMarker)
813  CommandID, CommandMarker) {}
814 
815  static bool classof(const Comment *C) {
816  return C->getCommentKind() == CommentKind::TParamCommandComment;
817  }
818 
819  bool hasParamName() const {
820  return getNumArgs() > 0;
821  }
822 
823  StringRef getParamName(const FullComment *FC) const;
824 
825  StringRef getParamNameAsWritten() const {
826  return Args[0].Text;
827  }
828 
830  return Args[0].Range;
831  }
832 
833  bool isPositionValid() const LLVM_READONLY {
834  return !Position.empty();
835  }
836 
837  unsigned getDepth() const {
838  assert(isPositionValid());
839  return Position.size();
840  }
841 
842  unsigned getIndex(unsigned Depth) const {
843  assert(isPositionValid());
844  return Position[Depth];
845  }
846 
847  void setPosition(ArrayRef<unsigned> NewPosition) {
848  Position = NewPosition;
849  assert(isPositionValid());
850  }
851 };
852 
853 /// A line of text contained in a verbatim block.
855  StringRef Text;
856 
857 public:
858  VerbatimBlockLineComment(SourceLocation LocBegin, StringRef Text)
860  LocBegin.getLocWithOffset(Text.size())),
861  Text(Text) {}
862 
863  static bool classof(const Comment *C) {
864  return C->getCommentKind() == CommentKind::VerbatimBlockLineComment;
865  }
866 
867  child_iterator child_begin() const { return nullptr; }
868 
869  child_iterator child_end() const { return nullptr; }
870 
871  StringRef getText() const LLVM_READONLY {
872  return Text;
873  }
874 };
875 
876 /// A verbatim block command (e. g., preformatted code). Verbatim block has an
877 /// opening and a closing command and contains multiple lines of text
878 /// (VerbatimBlockLineComment nodes).
880 protected:
881  StringRef CloseName;
884 
885 public:
887  unsigned CommandID)
889  CommandID,
890  CMK_At) // FIXME: improve source fidelity.
891  {}
892 
893  static bool classof(const Comment *C) {
894  return C->getCommentKind() == CommentKind::VerbatimBlockComment;
895  }
896 
898  return reinterpret_cast<child_iterator>(Lines.begin());
899  }
900 
902  return reinterpret_cast<child_iterator>(Lines.end());
903  }
904 
905  void setCloseName(StringRef Name, SourceLocation LocBegin) {
906  CloseName = Name;
907  CloseNameLocBegin = LocBegin;
908  }
909 
911  Lines = L;
912  }
913 
914  StringRef getCloseName() const {
915  return CloseName;
916  }
917 
918  unsigned getNumLines() const {
919  return Lines.size();
920  }
921 
922  StringRef getText(unsigned LineIdx) const {
923  return Lines[LineIdx]->getText();
924  }
925 };
926 
927 /// A verbatim line command. Verbatim line has an opening command, a single
928 /// line of text (up to the newline after the opening command) and has no
929 /// closing command.
931 protected:
932  StringRef Text;
934 
935 public:
937  unsigned CommandID, SourceLocation TextBegin,
938  StringRef Text)
940  CommandID,
941  CMK_At), // FIXME: improve source fidelity.
943 
944  static bool classof(const Comment *C) {
945  return C->getCommentKind() == CommentKind::VerbatimLineComment;
946  }
947 
948  child_iterator child_begin() const { return nullptr; }
949 
950  child_iterator child_end() const { return nullptr; }
951 
952  StringRef getText() const {
953  return Text;
954  }
955 
957  return SourceRange(TextBegin, getEndLoc());
958  }
959 };
960 
961 /// Information about the declaration, useful to clients of FullComment.
962 struct DeclInfo {
963  /// Declaration the comment is actually attached to (in the source).
964  /// Should not be NULL.
966 
967  /// CurrentDecl is the declaration with which the FullComment is associated.
968  ///
969  /// It can be different from \c CommentDecl. It happens when we decide
970  /// that the comment originally attached to \c CommentDecl is fine for
971  /// \c CurrentDecl too (for example, for a redeclaration or an overrider of
972  /// \c CommentDecl).
973  ///
974  /// The information in the DeclInfo corresponds to CurrentDecl.
976 
977  /// Parameters that can be referenced by \\param if \c CommentDecl is something
978  /// that we consider a "function".
980 
981  /// Function return type if \c CommentDecl is something that we consider
982  /// a "function".
984 
985  /// Template parameters that can be referenced by \\tparam if \c CommentDecl is
986  /// a template (\c IsTemplateDecl or \c IsTemplatePartialSpecialization is
987  /// true).
989 
990  /// A simplified description of \c CommentDecl kind that should be good enough
991  /// for documentation rendering purposes.
992  enum DeclKind {
993  /// Everything else not explicitly mentioned below.
995 
996  /// Something that we consider a "function":
997  /// \li function,
998  /// \li function template,
999  /// \li function template specialization,
1000  /// \li member function,
1001  /// \li member function template,
1002  /// \li member function template specialization,
1003  /// \li ObjC method,
1005 
1006  /// Something that we consider a "class":
1007  /// \li class/struct,
1008  /// \li class template,
1009  /// \li class template (partial) specialization.
1011 
1012  /// Something that we consider a "variable":
1013  /// \li namespace scope variables and variable templates;
1014  /// \li static and non-static class data members and member templates;
1015  /// \li enumerators.
1017 
1018  /// A C++ namespace.
1020 
1021  /// A C++ typedef-name (a 'typedef' decl specifier or alias-declaration),
1022  /// see \c TypedefNameDecl.
1024 
1025  /// An enumeration or scoped enumeration.
1026  EnumKind
1027  };
1028 
1029  /// What kind of template specialization \c CommentDecl is.
1035  };
1036 
1037  /// If false, only \c CommentDecl is valid.
1038  LLVM_PREFERRED_TYPE(bool)
1040 
1041  /// Simplified kind of \c CommentDecl, see \c DeclKind enum.
1042  LLVM_PREFERRED_TYPE(DeclKind)
1043  unsigned Kind : 3;
1044 
1045  /// Is \c CommentDecl a template declaration.
1046  LLVM_PREFERRED_TYPE(TemplateDeclKind)
1047  unsigned TemplateKind : 2;
1048 
1049  /// Is \c CommentDecl an ObjCMethodDecl.
1050  LLVM_PREFERRED_TYPE(bool)
1051  unsigned IsObjCMethod : 1;
1052 
1053  /// Is \c CommentDecl a non-static member function of C++ class or
1054  /// instance method of ObjC class.
1055  /// Can be true only if \c IsFunctionDecl is true.
1056  LLVM_PREFERRED_TYPE(bool)
1057  unsigned IsInstanceMethod : 1;
1058 
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  LLVM_PREFERRED_TYPE(bool)
1063  unsigned IsClassMethod : 1;
1064 
1065  /// Is \c CommentDecl something we consider a "function" that's variadic.
1066  LLVM_PREFERRED_TYPE(bool)
1067  unsigned IsVariadic : 1;
1068 
1069  void fill();
1070 
1071  DeclKind getKind() const LLVM_READONLY {
1072  return static_cast<DeclKind>(Kind);
1073  }
1074 
1075  TemplateDeclKind getTemplateKind() const LLVM_READONLY {
1076  return static_cast<TemplateDeclKind>(TemplateKind);
1077  }
1078 
1079  bool involvesFunctionType() const { return !ReturnType.isNull(); }
1080 };
1081 
1082 /// A full comment attached to a declaration, contains block content.
1083 class FullComment : public Comment {
1085  DeclInfo *ThisDeclInfo;
1086 
1087 public:
1090  Blocks(Blocks), ThisDeclInfo(D) {
1091  if (Blocks.empty())
1092  return;
1093 
1095  SourceRange(Blocks.front()->getBeginLoc(), Blocks.back()->getEndLoc()));
1096  setLocation(Blocks.front()->getBeginLoc());
1097  }
1098 
1099  static bool classof(const Comment *C) {
1100  return C->getCommentKind() == CommentKind::FullComment;
1101  }
1102 
1104  return reinterpret_cast<child_iterator>(Blocks.begin());
1105  }
1106 
1108  return reinterpret_cast<child_iterator>(Blocks.end());
1109  }
1110 
1111  const Decl *getDecl() const LLVM_READONLY {
1112  return ThisDeclInfo->CommentDecl;
1113  }
1114 
1115  const DeclInfo *getDeclInfo() const LLVM_READONLY {
1116  if (!ThisDeclInfo->IsFilled)
1117  ThisDeclInfo->fill();
1118  return ThisDeclInfo;
1119  }
1120 
1121  ArrayRef<BlockContentComment *> getBlocks() const { return Blocks; }
1122 
1123 };
1124 } // end namespace comments
1125 } // end namespace clang
1126 
1127 #endif
1128 
int Depth
Definition: ASTDiff.cpp:190
StringRef Text
Definition: Format.cpp:2977
Defines the clang::SourceLocation class and associated facilities.
C Language Family Type Representation.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:185
Attr - This represents one attribute.
Definition: Attr.h:46
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
A (possibly-)qualified type.
Definition: Type.h:940
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition: Type.h:1007
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
SourceLocation getLocWithOffset(IntTy Offset) const
Return a source location with the specified offset from this SourceLocation.
A trivial tuple used to represent a source range.
SourceLocation getEnd() const
SourceLocation getBegin() const
void setEnd(SourceLocation e)
Stores a list of template parameters for a TemplateDecl and its derived classes.
Definition: DeclTemplate.h:73
A command that has zero or more word-like arguments (number of word-like arguments depends on command...
Definition: Comment.h:604
child_iterator child_begin() const
Definition: Comment.h:640
ArrayRef< Argument > Args
Word-like arguments.
Definition: Comment.h:607
static bool classof(const Comment *C)
Definition: Comment.h:634
BlockCommandComment(CommentKind K, SourceLocation LocBegin, SourceLocation LocEnd, unsigned CommandID, CommandMarkerKind CommandMarker)
Definition: Comment.h:612
SourceLocation getCommandNameBeginLoc() const
Definition: Comment.h:656
child_iterator child_end() const
Definition: Comment.h:644
SourceRange getCommandNameRange(const CommandTraits &Traits) const
Definition: Comment.h:660
void setParagraph(ParagraphComment *PC)
Definition: Comment.h:695
ParagraphComment * Paragraph
Paragraph argument.
Definition: Comment.h:610
StringRef getCommandName(const CommandTraits &Traits) const
Definition: Comment.h:652
void setArgs(ArrayRef< Argument > A)
Definition: Comment.h:678
BlockCommandComment(SourceLocation LocBegin, SourceLocation LocEnd, unsigned CommandID, CommandMarkerKind CommandMarker)
Definition: Comment.h:625
StringRef getArgText(unsigned Idx) const
Definition: Comment.h:670
SourceRange getArgRange(unsigned Idx) const
Definition: Comment.h:674
CommandMarkerKind getCommandMarker() const LLVM_READONLY
Definition: Comment.h:702
ParagraphComment * getParagraph() const LLVM_READONLY
Definition: Comment.h:687
Block content (contains inline content).
Definition: Comment.h:538
BlockContentComment(CommentKind K, SourceLocation LocBegin, SourceLocation LocEnd)
Definition: Comment.h:540
static bool classof(const Comment *C)
Definition: Comment.h:547
This class provides information about commands that can be used in comments.
const CommandInfo * getCommandInfo(StringRef Name) const
Any part of the comment.
Definition: Comment.h:65
InlineContentCommentBitfields InlineContentCommentBits
Definition: Comment.h:202
SourceRange Range
Source range of this AST node.
Definition: Comment.h:71
HTMLTagCommentBitfields HTMLTagCommentBits
Definition: Comment.h:205
Comment *const * child_iterator
Definition: Comment.h:251
TextCommentBitfields TextCommentBits
Definition: Comment.h:203
child_iterator child_end() const
Definition: Comment.cpp:98
child_iterator child_begin() const
Definition: Comment.cpp:83
Comment(CommentKind K, SourceLocation LocBegin, SourceLocation LocEnd)
Definition: Comment.h:226
CommentBitfields CommentBits
Definition: Comment.h:201
const char * getCommentKindName() const
Definition: Comment.cpp:35
HTMLStartTagCommentBitfields HTMLStartTagCommentBits
Definition: Comment.h:206
InlineCommandCommentBitfields InlineCommandCommentBits
Definition: Comment.h:204
SourceLocation getLocation() const LLVM_READONLY
Definition: Comment.h:249
ParagraphCommentBitfields ParagraphCommentBits
Definition: Comment.h:207
ParamCommandCommentBitfields ParamCommandCommentBits
Definition: Comment.h:209
BlockCommandCommentBitfields BlockCommandCommentBits
Definition: Comment.h:208
SourceLocation Loc
Preferred location to show caret.
Definition: Comment.h:68
void setSourceRange(SourceRange SR)
Definition: Comment.h:212
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: Comment.h:245
SourceLocation getEndLoc() const LLVM_READONLY
Definition: Comment.h:247
unsigned child_count() const
Definition: Comment.h:258
SourceRange getSourceRange() const LLVM_READONLY
Definition: Comment.h:243
CommentKind getCommentKind() const
Definition: Comment.h:233
void setLocation(SourceLocation L)
Definition: Comment.h:216
A full comment attached to a declaration, contains block content.
Definition: Comment.h:1083
const Decl * getDecl() const LLVM_READONLY
Definition: Comment.h:1111
child_iterator child_end() const
Definition: Comment.h:1107
FullComment(ArrayRef< BlockContentComment * > Blocks, DeclInfo *D)
Definition: Comment.h:1088
const DeclInfo * getDeclInfo() const LLVM_READONLY
Definition: Comment.h:1115
static bool classof(const Comment *C)
Definition: Comment.h:1099
child_iterator child_begin() const
Definition: Comment.h:1103
ArrayRef< BlockContentComment * > getBlocks() const
Definition: Comment.h:1121
HTMLEndTagComment(SourceLocation LocBegin, SourceLocation LocEnd, StringRef TagName)
Definition: Comment.h:521
child_iterator child_end() const
Definition: Comment.h:533
static bool classof(const Comment *C)
Definition: Comment.h:527
child_iterator child_begin() const
Definition: Comment.h:531
Attribute(SourceLocation NameLocBegin, StringRef Name)
Definition: Comment.h:447
Attribute(SourceLocation NameLocBegin, StringRef Name, SourceLocation EqualsLoc, SourceRange ValueRange, StringRef Value)
Definition: Comment.h:450
An opening HTML tag with attributes.
Definition: Comment.h:433
child_iterator child_begin() const
Definition: Comment.h:480
child_iterator child_end() const
Definition: Comment.h:482
HTMLStartTagComment(SourceLocation LocBegin, StringRef TagName)
Definition: Comment.h:468
const Attribute & getAttr(unsigned Idx) const
Definition: Comment.h:488
void setGreaterLoc(SourceLocation GreaterLoc)
Definition: Comment.h:505
void setAttrs(ArrayRef< Attribute > Attrs)
Definition: Comment.h:492
static bool classof(const Comment *C)
Definition: Comment.h:476
Abstract class for opening and closing HTML tags.
Definition: Comment.h:391
static bool classof(const Comment *C)
Definition: Comment.h:410
StringRef getTagName() const LLVM_READONLY
Definition: Comment.h:415
HTMLTagComment(CommentKind K, SourceLocation LocBegin, SourceLocation LocEnd, StringRef TagName, SourceLocation TagNameBegin, SourceLocation TagNameEnd)
Definition: Comment.h:396
SourceRange getTagNameSourceRange() const LLVM_READONLY
Definition: Comment.h:417
A command with word-like arguments that is considered inline content.
Definition: Comment.h:335
StringRef getCommandName(const CommandTraits &Traits) const
Definition: Comment.h:363
SourceRange getArgRange(unsigned Idx) const
Definition: Comment.h:384
child_iterator child_begin() const
Definition: Comment.h:355
StringRef getArgText(unsigned Idx) const
Definition: Comment.h:380
static bool classof(const Comment *C)
Definition: Comment.h:351
InlineCommandComment(SourceLocation LocBegin, SourceLocation LocEnd, unsigned CommandID, InlineCommandRenderKind RK, ArrayRef< Argument > Args)
Definition: Comment.h:341
child_iterator child_end() const
Definition: Comment.h:357
InlineCommandRenderKind getRenderKind() const
Definition: Comment.h:371
ArrayRef< Argument > Args
Command arguments.
Definition: Comment.h:338
SourceRange getCommandNameRange() const
Definition: Comment.h:367
Inline content (contained within a block).
Definition: Comment.h:265
InlineContentComment(CommentKind K, SourceLocation LocBegin, SourceLocation LocEnd)
Definition: Comment.h:267
static bool classof(const Comment *C)
Definition: Comment.h:275
A single paragraph that contains inline content.
Definition: Comment.h:555
static bool classof(const Comment *C)
Definition: Comment.h:576
child_iterator child_begin() const
Definition: Comment.h:580
ParagraphComment(ArrayRef< InlineContentComment * > Content)
Definition: Comment.h:559
child_iterator child_end() const
Definition: Comment.h:584
Doxygen \param command.
Definition: Comment.h:711
ParamCommandPassDirection getDirection() const LLVM_READONLY
Definition: Comment.h:738
static bool classof(const Comment *C)
Definition: Comment.h:732
bool isDirectionExplicit() const LLVM_READONLY
Definition: Comment.h:743
unsigned getParamIndex() const LLVM_READONLY
Definition: Comment.h:779
static const char * getDirectionAsString(ParamCommandPassDirection D)
Definition: Comment.cpp:191
StringRef getParamName(const FullComment *FC) const
Definition: Comment.cpp:368
SourceRange getParamNameRange() const
Definition: Comment.h:762
bool isParamIndexValid() const LLVM_READONLY
Definition: Comment.h:766
void setDirection(ParamCommandPassDirection Direction, bool Explicit)
Definition: Comment.h:747
StringRef getParamNameAsWritten() const
Definition: Comment.h:758
void setParamIndex(unsigned Index)
Definition: Comment.h:785
bool isVarArgParam() const LLVM_READONLY
Definition: Comment.h:770
ParamCommandComment(SourceLocation LocBegin, SourceLocation LocEnd, unsigned CommandID, CommandMarkerKind CommandMarker)
Definition: Comment.h:722
Doxygen \tparam command, describes a template parameter.
Definition: Comment.h:793
void setPosition(ArrayRef< unsigned > NewPosition)
Definition: Comment.h:847
bool isPositionValid() const LLVM_READONLY
Definition: Comment.h:833
StringRef getParamNameAsWritten() const
Definition: Comment.h:825
StringRef getParamName(const FullComment *FC) const
Definition: Comment.cpp:375
static bool classof(const Comment *C)
Definition: Comment.h:815
unsigned getIndex(unsigned Depth) const
Definition: Comment.h:842
TParamCommandComment(SourceLocation LocBegin, SourceLocation LocEnd, unsigned CommandID, CommandMarkerKind CommandMarker)
Definition: Comment.h:810
SourceRange getParamNameRange() const
Definition: Comment.h:829
static bool classof(const Comment *C)
Definition: Comment.h:301
TextComment(SourceLocation LocBegin, SourceLocation LocEnd, StringRef Text)
Definition: Comment.h:295
bool isWhitespace() const
Definition: Comment.h:311
StringRef getText() const LLVM_READONLY
Definition: Comment.h:309
child_iterator child_begin() const
Definition: Comment.h:305
child_iterator child_end() const
Definition: Comment.h:307
A verbatim block command (e.
Definition: Comment.h:879
ArrayRef< VerbatimBlockLineComment * > Lines
Definition: Comment.h:883
void setLines(ArrayRef< VerbatimBlockLineComment * > L)
Definition: Comment.h:910
static bool classof(const Comment *C)
Definition: Comment.h:893
child_iterator child_end() const
Definition: Comment.h:901
child_iterator child_begin() const
Definition: Comment.h:897
StringRef getText(unsigned LineIdx) const
Definition: Comment.h:922
void setCloseName(StringRef Name, SourceLocation LocBegin)
Definition: Comment.h:905
VerbatimBlockComment(SourceLocation LocBegin, SourceLocation LocEnd, unsigned CommandID)
Definition: Comment.h:886
A line of text contained in a verbatim block.
Definition: Comment.h:854
StringRef getText() const LLVM_READONLY
Definition: Comment.h:871
static bool classof(const Comment *C)
Definition: Comment.h:863
child_iterator child_end() const
Definition: Comment.h:869
VerbatimBlockLineComment(SourceLocation LocBegin, StringRef Text)
Definition: Comment.h:858
child_iterator child_begin() const
Definition: Comment.h:867
A verbatim line command.
Definition: Comment.h:930
child_iterator child_begin() const
Definition: Comment.h:948
VerbatimLineComment(SourceLocation LocBegin, SourceLocation LocEnd, unsigned CommandID, SourceLocation TextBegin, StringRef Text)
Definition: Comment.h:936
child_iterator child_end() const
Definition: Comment.h:950
SourceRange getTextRange() const
Definition: Comment.h:956
static bool classof(const Comment *C)
Definition: Comment.h:944
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
ParamCommandPassDirection
Definition: Comment.h:708
InlineCommandRenderKind
The most appropriate rendering mode for this command, chosen on command semantics in Doxygen.
Definition: Comment.h:326
CommandMarkerKind
Describes the syntax that was used in a documentation command.
Definition: Comment.h:38
@ CMK_Backslash
Command started with a backslash character:
Definition: Comment.h:43
@ CMK_At
Command started with an 'at' character:
Definition: Comment.h:49
The JSON file list parser is used to communicate input to InstallAPI.
Information about the declaration, useful to clients of FullComment.
Definition: Comment.h:962
unsigned TemplateKind
Is CommentDecl a template declaration.
Definition: Comment.h:1047
unsigned IsClassMethod
Is CommentDecl a static member function of C++ class or class method of ObjC class.
Definition: Comment.h:1063
DeclKind
A simplified description of CommentDecl kind that should be good enough for documentation rendering p...
Definition: Comment.h:992
@ FunctionKind
Something that we consider a "function":
Definition: Comment.h:1004
@ EnumKind
An enumeration or scoped enumeration.
Definition: Comment.h:1026
@ OtherKind
Everything else not explicitly mentioned below.
Definition: Comment.h:994
@ NamespaceKind
A C++ namespace.
Definition: Comment.h:1019
@ VariableKind
Something that we consider a "variable":
Definition: Comment.h:1016
@ ClassKind
Something that we consider a "class":
Definition: Comment.h:1010
@ TypedefKind
A C++ typedef-name (a 'typedef' decl specifier or alias-declaration), see TypedefNameDecl.
Definition: Comment.h:1023
unsigned Kind
Simplified kind of CommentDecl, see DeclKind enum.
Definition: Comment.h:1043
unsigned IsObjCMethod
Is CommentDecl an ObjCMethodDecl.
Definition: Comment.h:1051
const TemplateParameterList * TemplateParameters
Template parameters that can be referenced by \tparam if CommentDecl is a template (IsTemplateDecl or...
Definition: Comment.h:988
ArrayRef< const ParmVarDecl * > ParamVars
Parameters that can be referenced by \param if CommentDecl is something that we consider a "function"...
Definition: Comment.h:979
DeclKind getKind() const LLVM_READONLY
Definition: Comment.h:1071
unsigned IsInstanceMethod
Is CommentDecl a non-static member function of C++ class or instance method of ObjC class.
Definition: Comment.h:1057
TemplateDeclKind getTemplateKind() const LLVM_READONLY
Definition: Comment.h:1075
bool involvesFunctionType() const
Definition: Comment.h:1079
unsigned IsFilled
If false, only CommentDecl is valid.
Definition: Comment.h:1039
const Decl * CommentDecl
Declaration the comment is actually attached to (in the source).
Definition: Comment.h:965
unsigned IsVariadic
Is CommentDecl something we consider a "function" that's variadic.
Definition: Comment.h:1067
TemplateDeclKind
What kind of template specialization CommentDecl is.
Definition: Comment.h:1030
const Decl * CurrentDecl
CurrentDecl is the declaration with which the FullComment is associated.
Definition: Comment.h:975
QualType ReturnType
Function return type if CommentDecl is something that we consider a "function".
Definition: Comment.h:983