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