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