clang  8.0.0svn
Comment.h
Go to the documentation of this file.
1 //===--- Comment.h - Comment AST nodes --------------------------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines comment AST nodes.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_CLANG_AST_COMMENT_H
15 #define LLVM_CLANG_AST_COMMENT_H
16 
18 #include "clang/AST/DeclObjC.h"
19 #include "clang/AST/Type.h"
21 #include "llvm/ADT/ArrayRef.h"
22 #include "llvm/ADT/StringRef.h"
23 
24 namespace clang {
25 class Decl;
26 class ParmVarDecl;
27 class TemplateParameterList;
28 
29 namespace comments {
30 class FullComment;
31 
32 /// Describes the syntax that was used in a documentation command.
33 ///
34 /// Exact values of this enumeration are important because they used to select
35 /// parts of diagnostic messages. Audit diagnostics before changing or adding
36 /// a new value.
38  /// Command started with a backslash character:
39  /// \code
40  /// \foo
41  /// \endcode
43 
44  /// Command started with an 'at' character:
45  /// \code
46  /// @foo
47  /// \endcode
48  CMK_At = 1
49 };
50 
51 /// Any part of the comment.
52 /// Abstract class.
53 class Comment {
54 protected:
55  /// Preferred location to show caret.
57 
58  /// Source range of this AST node.
60 
62  friend class Comment;
63 
64  /// Type of this AST node.
65  unsigned Kind : 8;
66  };
67  enum { NumCommentBits = 8 };
68 
70  friend class InlineContentComment;
71 
72  unsigned : NumCommentBits;
73 
74  /// True if there is a newline after this inline content node.
75  /// (There is no separate AST node for a newline.)
76  unsigned HasTrailingNewline : 1;
77  };
79 
81  friend class TextComment;
82 
83  unsigned : NumInlineContentCommentBits;
84 
85  /// True if \c IsWhitespace field contains a valid value.
86  mutable unsigned IsWhitespaceValid : 1;
87 
88  /// True if this comment AST node contains only whitespace.
89  mutable unsigned IsWhitespace : 1;
90  };
92 
94  friend class InlineCommandComment;
95 
96  unsigned : NumInlineContentCommentBits;
97 
98  unsigned RenderKind : 2;
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 {
314  RenderEmphasized
315  };
316 
317 protected:
318  /// Command arguments.
320 
321 public:
323  SourceLocation LocEnd,
324  unsigned CommandID,
325  RenderKind RK,
326  ArrayRef<Argument> Args) :
327  InlineContentComment(InlineCommandCommentKind, LocBegin, LocEnd),
328  Args(Args) {
329  InlineCommandCommentBits.RenderKind = RK;
330  InlineCommandCommentBits.CommandID = CommandID;
331  }
332 
333  static bool classof(const Comment *C) {
334  return C->getCommentKind() == InlineCommandCommentKind;
335  }
336 
337  child_iterator child_begin() const { return nullptr; }
338 
339  child_iterator child_end() const { return nullptr; }
340 
341  unsigned getCommandID() const {
342  return InlineCommandCommentBits.CommandID;
343  }
344 
345  StringRef getCommandName(const CommandTraits &Traits) const {
346  return Traits.getCommandInfo(getCommandID())->Name;
347  }
348 
350  return SourceRange(getBeginLoc().getLocWithOffset(-1), getEndLoc());
351  }
352 
354  return static_cast<RenderKind>(InlineCommandCommentBits.RenderKind);
355  }
356 
357  unsigned getNumArgs() const {
358  return Args.size();
359  }
360 
361  StringRef getArgText(unsigned Idx) const {
362  return Args[Idx].Text;
363  }
364 
365  SourceRange getArgRange(unsigned Idx) const {
366  return Args[Idx].Range;
367  }
368 };
369 
370 /// Abstract class for opening and closing HTML tags. HTML tags are always
371 /// treated as inline content (regardless HTML semantics).
373 protected:
374  StringRef TagName;
376 
378  SourceLocation LocBegin,
379  SourceLocation LocEnd,
380  StringRef TagName,
381  SourceLocation TagNameBegin,
382  SourceLocation TagNameEnd) :
383  InlineContentComment(K, LocBegin, LocEnd),
384  TagName(TagName),
385  TagNameRange(TagNameBegin, TagNameEnd) {
386  setLocation(TagNameBegin);
387  HTMLTagCommentBits.IsMalformed = 0;
388  }
389 
390 public:
391  static bool classof(const Comment *C) {
392  return C->getCommentKind() >= FirstHTMLTagCommentConstant &&
393  C->getCommentKind() <= LastHTMLTagCommentConstant;
394  }
395 
396  StringRef getTagName() const LLVM_READONLY { return TagName; }
397 
398  SourceRange getTagNameSourceRange() const LLVM_READONLY {
400  return SourceRange(L.getLocWithOffset(1),
401  L.getLocWithOffset(1 + TagName.size()));
402  }
403 
404  bool isMalformed() const {
405  return HTMLTagCommentBits.IsMalformed;
406  }
407 
408  void setIsMalformed() {
409  HTMLTagCommentBits.IsMalformed = 1;
410  }
411 };
412 
413 /// An opening HTML tag with attributes.
415 public:
416  class Attribute {
417  public:
419  StringRef Name;
420 
422 
424  StringRef Value;
425 
426  Attribute() { }
427 
428  Attribute(SourceLocation NameLocBegin, StringRef Name) :
429  NameLocBegin(NameLocBegin), Name(Name),
430  EqualsLoc(SourceLocation()),
431  ValueRange(SourceRange()), Value(StringRef())
432  { }
433 
434  Attribute(SourceLocation NameLocBegin, StringRef Name,
435  SourceLocation EqualsLoc,
436  SourceRange ValueRange, StringRef Value) :
437  NameLocBegin(NameLocBegin), Name(Name),
438  EqualsLoc(EqualsLoc),
439  ValueRange(ValueRange), Value(Value)
440  { }
441 
443  return NameLocBegin.getLocWithOffset(Name.size());
444  }
445 
447  return SourceRange(NameLocBegin, getNameLocEnd());
448  }
449  };
450 
451 private:
452  ArrayRef<Attribute> Attributes;
453 
454 public:
456  StringRef TagName) :
457  HTMLTagComment(HTMLStartTagCommentKind,
458  LocBegin, LocBegin.getLocWithOffset(1 + TagName.size()),
459  TagName,
460  LocBegin.getLocWithOffset(1),
461  LocBegin.getLocWithOffset(1 + TagName.size())) {
462  HTMLStartTagCommentBits.IsSelfClosing = false;
463  }
464 
465  static bool classof(const Comment *C) {
466  return C->getCommentKind() == HTMLStartTagCommentKind;
467  }
468 
469  child_iterator child_begin() const { return nullptr; }
470 
471  child_iterator child_end() const { return nullptr; }
472 
473  unsigned getNumAttrs() const {
474  return Attributes.size();
475  }
476 
477  const Attribute &getAttr(unsigned Idx) const {
478  return Attributes[Idx];
479  }
480 
482  Attributes = Attrs;
483  if (!Attrs.empty()) {
484  const Attribute &Attr = Attrs.back();
485  SourceLocation L = Attr.ValueRange.getEnd();
486  if (L.isValid())
487  Range.setEnd(L);
488  else {
489  Range.setEnd(Attr.getNameLocEnd());
490  }
491  }
492  }
493 
494  void setGreaterLoc(SourceLocation GreaterLoc) {
495  Range.setEnd(GreaterLoc);
496  }
497 
498  bool isSelfClosing() const {
499  return HTMLStartTagCommentBits.IsSelfClosing;
500  }
501 
502  void setSelfClosing() {
503  HTMLStartTagCommentBits.IsSelfClosing = true;
504  }
505 };
506 
507 /// A closing HTML tag.
509 public:
511  SourceLocation LocEnd,
512  StringRef TagName) :
513  HTMLTagComment(HTMLEndTagCommentKind,
514  LocBegin, LocEnd,
515  TagName,
516  LocBegin.getLocWithOffset(2),
517  LocBegin.getLocWithOffset(2 + TagName.size()))
518  { }
519 
520  static bool classof(const Comment *C) {
521  return C->getCommentKind() == HTMLEndTagCommentKind;
522  }
523 
524  child_iterator child_begin() const { return nullptr; }
525 
526  child_iterator child_end() const { return nullptr; }
527 };
528 
529 /// Block content (contains inline content).
530 /// Abstract class.
531 class BlockContentComment : public Comment {
532 protected:
534  SourceLocation LocBegin,
535  SourceLocation LocEnd) :
536  Comment(K, LocBegin, LocEnd)
537  { }
538 
539 public:
540  static bool classof(const Comment *C) {
541  return C->getCommentKind() >= FirstBlockContentCommentConstant &&
542  C->getCommentKind() <= LastBlockContentCommentConstant;
543  }
544 };
545 
546 /// A single paragraph that contains inline content.
549 
550 public:
552  BlockContentComment(ParagraphCommentKind,
553  SourceLocation(),
554  SourceLocation()),
555  Content(Content) {
556  if (Content.empty()) {
557  ParagraphCommentBits.IsWhitespace = true;
558  ParagraphCommentBits.IsWhitespaceValid = true;
559  return;
560  }
561 
562  ParagraphCommentBits.IsWhitespaceValid = false;
563 
564  setSourceRange(SourceRange(Content.front()->getBeginLoc(),
565  Content.back()->getEndLoc()));
566  setLocation(Content.front()->getBeginLoc());
567  }
568 
569  static bool classof(const Comment *C) {
570  return C->getCommentKind() == ParagraphCommentKind;
571  }
572 
574  return reinterpret_cast<child_iterator>(Content.begin());
575  }
576 
578  return reinterpret_cast<child_iterator>(Content.end());
579  }
580 
581  bool isWhitespace() const {
582  if (ParagraphCommentBits.IsWhitespaceValid)
583  return ParagraphCommentBits.IsWhitespace;
584 
585  ParagraphCommentBits.IsWhitespace = isWhitespaceNoCache();
586  ParagraphCommentBits.IsWhitespaceValid = true;
587  return ParagraphCommentBits.IsWhitespace;
588  }
589 
590 private:
591  bool isWhitespaceNoCache() const;
592 };
593 
594 /// A command that has zero or more word-like arguments (number of word-like
595 /// arguments depends on command name) and a paragraph as an argument
596 /// (e. g., \\brief).
598 public:
599  struct Argument {
601  StringRef Text;
602 
603  Argument() { }
604  Argument(SourceRange Range, StringRef Text) : Range(Range), Text(Text) { }
605  };
606 
607 protected:
608  /// Word-like arguments.
610 
611  /// Paragraph argument.
613 
615  SourceLocation LocBegin,
616  SourceLocation LocEnd,
617  unsigned CommandID,
618  CommandMarkerKind CommandMarker) :
619  BlockContentComment(K, LocBegin, LocEnd),
620  Paragraph(nullptr) {
621  setLocation(getCommandNameBeginLoc());
622  BlockCommandCommentBits.CommandID = CommandID;
623  BlockCommandCommentBits.CommandMarker = CommandMarker;
624  }
625 
626 public:
628  SourceLocation LocEnd,
629  unsigned CommandID,
630  CommandMarkerKind CommandMarker) :
631  BlockContentComment(BlockCommandCommentKind, LocBegin, LocEnd),
632  Paragraph(nullptr) {
633  setLocation(getCommandNameBeginLoc());
634  BlockCommandCommentBits.CommandID = CommandID;
635  BlockCommandCommentBits.CommandMarker = CommandMarker;
636  }
637 
638  static bool classof(const Comment *C) {
639  return C->getCommentKind() >= FirstBlockCommandCommentConstant &&
640  C->getCommentKind() <= LastBlockCommandCommentConstant;
641  }
642 
644  return reinterpret_cast<child_iterator>(&Paragraph);
645  }
646 
648  return reinterpret_cast<child_iterator>(&Paragraph + 1);
649  }
650 
651  unsigned getCommandID() const {
652  return BlockCommandCommentBits.CommandID;
653  }
654 
655  StringRef getCommandName(const CommandTraits &Traits) const {
656  return Traits.getCommandInfo(getCommandID())->Name;
657  }
658 
660  return getBeginLoc().getLocWithOffset(1);
661  }
662 
664  StringRef Name = getCommandName(Traits);
665  return SourceRange(getCommandNameBeginLoc(),
666  getBeginLoc().getLocWithOffset(1 + Name.size()));
667  }
668 
669  unsigned getNumArgs() const {
670  return Args.size();
671  }
672 
673  StringRef getArgText(unsigned Idx) const {
674  return Args[Idx].Text;
675  }
676 
677  SourceRange getArgRange(unsigned Idx) const {
678  return Args[Idx].Range;
679  }
680 
682  Args = A;
683  if (Args.size() > 0) {
684  SourceLocation NewLocEnd = Args.back().Range.getEnd();
685  if (NewLocEnd.isValid())
686  setSourceRange(SourceRange(getBeginLoc(), NewLocEnd));
687  }
688  }
689 
690  ParagraphComment *getParagraph() const LLVM_READONLY {
691  return Paragraph;
692  }
693 
695  return Paragraph && !Paragraph->isWhitespace();
696  }
697 
699  Paragraph = PC;
700  SourceLocation NewLocEnd = PC->getEndLoc();
701  if (NewLocEnd.isValid())
702  setSourceRange(SourceRange(getBeginLoc(), NewLocEnd));
703  }
704 
705  CommandMarkerKind getCommandMarker() const LLVM_READONLY {
706  return static_cast<CommandMarkerKind>(
707  BlockCommandCommentBits.CommandMarker);
708  }
709 };
710 
711 /// Doxygen \\param command.
713 private:
714  /// Parameter index in the function declaration.
715  unsigned ParamIndex;
716 
717 public:
718  enum : unsigned {
719  InvalidParamIndex = ~0U,
720  VarArgParamIndex = ~0U/*InvalidParamIndex*/ - 1U
721  };
722 
724  SourceLocation LocEnd,
725  unsigned CommandID,
726  CommandMarkerKind CommandMarker) :
727  BlockCommandComment(ParamCommandCommentKind, LocBegin, LocEnd,
728  CommandID, CommandMarker),
729  ParamIndex(InvalidParamIndex) {
730  ParamCommandCommentBits.Direction = In;
731  ParamCommandCommentBits.IsDirectionExplicit = false;
732  }
733 
734  static bool classof(const Comment *C) {
735  return C->getCommentKind() == ParamCommandCommentKind;
736  }
737 
739  In,
741  InOut
742  };
743 
744  static const char *getDirectionAsString(PassDirection D);
745 
746  PassDirection getDirection() const LLVM_READONLY {
747  return static_cast<PassDirection>(ParamCommandCommentBits.Direction);
748  }
749 
750  bool isDirectionExplicit() const LLVM_READONLY {
751  return ParamCommandCommentBits.IsDirectionExplicit;
752  }
753 
754  void setDirection(PassDirection Direction, bool Explicit) {
755  ParamCommandCommentBits.Direction = Direction;
756  ParamCommandCommentBits.IsDirectionExplicit = Explicit;
757  }
758 
759  bool hasParamName() const {
760  return getNumArgs() > 0;
761  }
762 
763  StringRef getParamName(const FullComment *FC) const;
764 
765  StringRef getParamNameAsWritten() const {
766  return Args[0].Text;
767  }
768 
770  return Args[0].Range;
771  }
772 
773  bool isParamIndexValid() const LLVM_READONLY {
774  return ParamIndex != InvalidParamIndex;
775  }
776 
777  bool isVarArgParam() const LLVM_READONLY {
778  return ParamIndex == VarArgParamIndex;
779  }
780 
782  ParamIndex = VarArgParamIndex;
783  assert(isParamIndexValid());
784  }
785 
786  unsigned getParamIndex() const LLVM_READONLY {
787  assert(isParamIndexValid());
788  assert(!isVarArgParam());
789  return ParamIndex;
790  }
791 
792  void setParamIndex(unsigned Index) {
793  ParamIndex = Index;
794  assert(isParamIndexValid());
795  assert(!isVarArgParam());
796  }
797 };
798 
799 /// Doxygen \\tparam command, describes a template parameter.
801 private:
802  /// If this template parameter name was resolved (found in template parameter
803  /// list), then this stores a list of position indexes in all template
804  /// parameter lists.
805  ///
806  /// For example:
807  /// \verbatim
808  /// template<typename C, template<typename T> class TT>
809  /// void test(TT<int> aaa);
810  /// \endverbatim
811  /// For C: Position = { 0 }
812  /// For TT: Position = { 1 }
813  /// For T: Position = { 1, 0 }
814  ArrayRef<unsigned> Position;
815 
816 public:
818  SourceLocation LocEnd,
819  unsigned CommandID,
820  CommandMarkerKind CommandMarker) :
821  BlockCommandComment(TParamCommandCommentKind, LocBegin, LocEnd, CommandID,
822  CommandMarker)
823  { }
824 
825  static bool classof(const Comment *C) {
826  return C->getCommentKind() == TParamCommandCommentKind;
827  }
828 
829  bool hasParamName() const {
830  return getNumArgs() > 0;
831  }
832 
833  StringRef getParamName(const FullComment *FC) const;
834 
835  StringRef getParamNameAsWritten() const {
836  return Args[0].Text;
837  }
838 
840  return Args[0].Range;
841  }
842 
843  bool isPositionValid() const LLVM_READONLY {
844  return !Position.empty();
845  }
846 
847  unsigned getDepth() const {
848  assert(isPositionValid());
849  return Position.size();
850  }
851 
852  unsigned getIndex(unsigned Depth) const {
853  assert(isPositionValid());
854  return Position[Depth];
855  }
856 
857  void setPosition(ArrayRef<unsigned> NewPosition) {
858  Position = NewPosition;
859  assert(isPositionValid());
860  }
861 };
862 
863 /// A line of text contained in a verbatim block.
865  StringRef Text;
866 
867 public:
869  StringRef Text) :
870  Comment(VerbatimBlockLineCommentKind,
871  LocBegin,
872  LocBegin.getLocWithOffset(Text.size())),
873  Text(Text)
874  { }
875 
876  static bool classof(const Comment *C) {
877  return C->getCommentKind() == VerbatimBlockLineCommentKind;
878  }
879 
880  child_iterator child_begin() const { return nullptr; }
881 
882  child_iterator child_end() const { return nullptr; }
883 
884  StringRef getText() const LLVM_READONLY {
885  return Text;
886  }
887 };
888 
889 /// A verbatim block command (e. g., preformatted code). Verbatim block has an
890 /// opening and a closing command and contains multiple lines of text
891 /// (VerbatimBlockLineComment nodes).
893 protected:
894  StringRef CloseName;
897 
898 public:
900  SourceLocation LocEnd,
901  unsigned CommandID) :
902  BlockCommandComment(VerbatimBlockCommentKind,
903  LocBegin, LocEnd, CommandID,
904  CMK_At) // FIXME: improve source fidelity.
905  { }
906 
907  static bool classof(const Comment *C) {
908  return C->getCommentKind() == VerbatimBlockCommentKind;
909  }
910 
912  return reinterpret_cast<child_iterator>(Lines.begin());
913  }
914 
916  return reinterpret_cast<child_iterator>(Lines.end());
917  }
918 
919  void setCloseName(StringRef Name, SourceLocation LocBegin) {
920  CloseName = Name;
921  CloseNameLocBegin = LocBegin;
922  }
923 
925  Lines = L;
926  }
927 
928  StringRef getCloseName() const {
929  return CloseName;
930  }
931 
932  unsigned getNumLines() const {
933  return Lines.size();
934  }
935 
936  StringRef getText(unsigned LineIdx) const {
937  return Lines[LineIdx]->getText();
938  }
939 };
940 
941 /// A verbatim line command. Verbatim line has an opening command, a single
942 /// line of text (up to the newline after the opening command) and has no
943 /// closing command.
945 protected:
946  StringRef Text;
948 
949 public:
951  SourceLocation LocEnd,
952  unsigned CommandID,
953  SourceLocation TextBegin,
954  StringRef Text) :
955  BlockCommandComment(VerbatimLineCommentKind,
956  LocBegin, LocEnd,
957  CommandID,
958  CMK_At), // FIXME: improve source fidelity.
959  Text(Text),
960  TextBegin(TextBegin)
961  { }
962 
963  static bool classof(const Comment *C) {
964  return C->getCommentKind() == VerbatimLineCommentKind;
965  }
966 
967  child_iterator child_begin() const { return nullptr; }
968 
969  child_iterator child_end() const { return nullptr; }
970 
971  StringRef getText() const {
972  return Text;
973  }
974 
976  return SourceRange(TextBegin, getEndLoc());
977  }
978 };
979 
980 /// Information about the declaration, useful to clients of FullComment.
981 struct DeclInfo {
982  /// Declaration the comment is actually attached to (in the source).
983  /// Should not be NULL.
985 
986  /// CurrentDecl is the declaration with which the FullComment is associated.
987  ///
988  /// It can be different from \c CommentDecl. It happens when we decide
989  /// that the comment originally attached to \c CommentDecl is fine for
990  /// \c CurrentDecl too (for example, for a redeclaration or an overrider of
991  /// \c CommentDecl).
992  ///
993  /// The information in the DeclInfo corresponds to CurrentDecl.
995 
996  /// Parameters that can be referenced by \\param if \c CommentDecl is something
997  /// that we consider a "function".
999 
1000  /// Function return type if \c CommentDecl is something that we consider
1001  /// a "function".
1003 
1004  /// Template parameters that can be referenced by \\tparam if \c CommentDecl is
1005  /// a template (\c IsTemplateDecl or \c IsTemplatePartialSpecialization is
1006  /// true).
1008 
1009  /// A simplified description of \c CommentDecl kind that should be good enough
1010  /// for documentation rendering purposes.
1011  enum DeclKind {
1012  /// Everything else not explicitly mentioned below.
1014 
1015  /// Something that we consider a "function":
1016  /// \li function,
1017  /// \li function template,
1018  /// \li function template specialization,
1019  /// \li member function,
1020  /// \li member function template,
1021  /// \li member function template specialization,
1022  /// \li ObjC method,
1023  /// \li a typedef for a function pointer, member function pointer,
1024  /// ObjC block.
1026 
1027  /// Something that we consider a "class":
1028  /// \li class/struct,
1029  /// \li class template,
1030  /// \li class template (partial) specialization.
1032 
1033  /// Something that we consider a "variable":
1034  /// \li namespace scope variables;
1035  /// \li static and non-static class data members;
1036  /// \li enumerators.
1038 
1039  /// A C++ namespace.
1041 
1042  /// A C++ typedef-name (a 'typedef' decl specifier or alias-declaration),
1043  /// see \c TypedefNameDecl.
1045 
1046  /// An enumeration or scoped enumeration.
1047  EnumKind
1048  };
1049 
1050  /// What kind of template specialization \c CommentDecl is.
1055  TemplatePartialSpecialization
1056  };
1057 
1058  /// If false, only \c CommentDecl is valid.
1059  unsigned IsFilled : 1;
1060 
1061  /// Simplified kind of \c CommentDecl, see \c DeclKind enum.
1062  unsigned Kind : 3;
1063 
1064  /// Is \c CommentDecl a template declaration.
1065  unsigned TemplateKind : 2;
1066 
1067  /// Is \c CommentDecl an ObjCMethodDecl.
1068  unsigned IsObjCMethod : 1;
1069 
1070  /// Is \c CommentDecl a non-static member function of C++ class or
1071  /// instance method of ObjC class.
1072  /// Can be true only if \c IsFunctionDecl is true.
1073  unsigned IsInstanceMethod : 1;
1074 
1075  /// Is \c CommentDecl a static member function of C++ class or
1076  /// class method of ObjC class.
1077  /// Can be true only if \c IsFunctionDecl is true.
1078  unsigned IsClassMethod : 1;
1079 
1080  void fill();
1081 
1082  DeclKind getKind() const LLVM_READONLY {
1083  return static_cast<DeclKind>(Kind);
1084  }
1085 
1086  TemplateDeclKind getTemplateKind() const LLVM_READONLY {
1087  return static_cast<TemplateDeclKind>(TemplateKind);
1088  }
1089 };
1090 
1091 /// A full comment attached to a declaration, contains block content.
1092 class FullComment : public Comment {
1094  DeclInfo *ThisDeclInfo;
1095 
1096 public:
1098  Comment(FullCommentKind, SourceLocation(), SourceLocation()),
1099  Blocks(Blocks), ThisDeclInfo(D) {
1100  if (Blocks.empty())
1101  return;
1102 
1104  SourceRange(Blocks.front()->getBeginLoc(), Blocks.back()->getEndLoc()));
1105  setLocation(Blocks.front()->getBeginLoc());
1106  }
1107 
1108  static bool classof(const Comment *C) {
1109  return C->getCommentKind() == FullCommentKind;
1110  }
1111 
1113  return reinterpret_cast<child_iterator>(Blocks.begin());
1114  }
1115 
1117  return reinterpret_cast<child_iterator>(Blocks.end());
1118  }
1119 
1120  const Decl *getDecl() const LLVM_READONLY {
1121  return ThisDeclInfo->CommentDecl;
1122  }
1123 
1124  const DeclInfo *getDeclInfo() const LLVM_READONLY {
1125  if (!ThisDeclInfo->IsFilled)
1126  ThisDeclInfo->fill();
1127  return ThisDeclInfo;
1128  }
1129 
1130  ArrayRef<BlockContentComment *> getBlocks() const { return Blocks; }
1131 
1132 };
1133 } // end namespace comments
1134 } // end namespace clang
1135 
1136 #endif
1137 
Attribute(SourceLocation NameLocBegin, StringRef Name)
Definition: Comment.h:428
void setDirection(PassDirection Direction, bool Explicit)
Definition: Comment.h:754
bool isVarArgParam() const LLVM_READONLY
Definition: Comment.h:777
const Decl * CommentDecl
Declaration the comment is actually attached to (in the source).
Definition: Comment.h:984
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:540
StringRef getArgText(unsigned Idx) const
Definition: Comment.h:673
A (possibly-)qualified type.
Definition: Type.h:642
BlockCommandComment(CommentKind K, SourceLocation LocBegin, SourceLocation LocEnd, unsigned CommandID, CommandMarkerKind CommandMarker)
Definition: Comment.h:614
child_iterator child_end() const
Definition: Comment.h:526
void setLines(ArrayRef< VerbatimBlockLineComment *> L)
Definition: Comment.h:924
bool isPositionValid() const LLVM_READONLY
Definition: Comment.h:843
static bool classof(const Comment *C)
Definition: Comment.h:520
unsigned IsObjCMethod
Is CommentDecl an ObjCMethodDecl.
Definition: Comment.h:1068
InlineCommandCommentBitfields InlineCommandCommentBits
Definition: Comment.h:169
C Language Family Type Representation.
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:87
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:455
BlockCommandCommentBitfields BlockCommandCommentBits
Definition: Comment.h:173
child_iterator child_begin() const
Definition: Comment.cpp:68
DeclKind
A simplified description of CommentDecl kind that should be good enough for documentation rendering p...
Definition: Comment.h:1011
void setLocation(SourceLocation L)
Definition: Comment.h:181
StringRef getArgText(unsigned Idx) const
Definition: Comment.h:361
Stores a list of template parameters for a TemplateDecl and its derived classes.
Definition: DeclTemplate.h:68
Something that we consider a "variable":
Definition: Comment.h:1037
Something that we consider a "function":
Definition: Comment.h:1025
unsigned getIndex(unsigned Depth) const
Definition: Comment.h:852
TemplateDeclKind
What kind of template specialization CommentDecl is.
Definition: Comment.h:1051
SourceRange getTagNameSourceRange() const LLVM_READONLY
Definition: Comment.h:398
child_iterator child_end() const
Definition: Comment.h:915
TextCommentBitfields TextCommentBits
Definition: Comment.h:168
ParagraphComment * getParagraph() const LLVM_READONLY
Definition: Comment.h:690
StringRef getCommandName(const CommandTraits &Traits) const
Definition: Comment.h:655
Comment(CommentKind K, SourceLocation LocBegin, SourceLocation LocEnd)
Definition: Comment.h:197
BlockContentComment(CommentKind K, SourceLocation LocBegin, SourceLocation LocEnd)
Definition: Comment.h:533
Argument(SourceRange Range, StringRef Text)
Definition: Comment.h:305
static bool classof(const Comment *C)
Definition: Comment.h:963
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:1116
RenderKind getRenderKind() const
Definition: Comment.h:353
static bool classof(const Comment *C)
Definition: Comment.h:569
SourceRange getTextRange() const
Definition: Comment.h:975
StringRef getText() const LLVM_READONLY
Definition: Comment.h:884
HTMLTagCommentBitfields HTMLTagCommentBits
Definition: Comment.h:170
const Decl * CurrentDecl
CurrentDecl is the declaration with which the FullComment is associated.
Definition: Comment.h:994
SourceRange getArgRange(unsigned Idx) const
Definition: Comment.h:365
unsigned IsFilled
If false, only CommentDecl is valid.
Definition: Comment.h:1059
SourceRange getParamNameRange() const
Definition: Comment.h:839
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:864
child_iterator child_begin() const
Definition: Comment.h:643
A verbatim line command.
Definition: Comment.h:944
Something that we consider a "class":
Definition: Comment.h:1031
ArrayRef< Argument > Args
Word-like arguments.
Definition: Comment.h:609
Any part of the comment.
Definition: Comment.h:53
SourceRange getCommandNameRange() const
Definition: Comment.h:349
FullComment(ArrayRef< BlockContentComment *> Blocks, DeclInfo *D)
Definition: Comment.h:1097
unsigned getParamIndex() const LLVM_READONLY
Definition: Comment.h:786
child_iterator child_begin() const
Definition: Comment.h:469
child_iterator child_begin() const
Definition: Comment.h:880
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:434
A verbatim block command (e.
Definition: Comment.h:892
StringRef getText() const LLVM_READONLY
Definition: Comment.h:283
unsigned TemplateKind
Is CommentDecl a template declaration.
Definition: Comment.h:1065
child_iterator child_end() const
Definition: Comment.h:882
child_iterator child_end() const
Definition: Comment.cpp:82
void setAttrs(ArrayRef< Attribute > Attrs)
Definition: Comment.h:481
SourceLocation getEndLoc() const LLVM_READONLY
Definition: Comment.h:220
void setPosition(ArrayRef< unsigned > NewPosition)
Definition: Comment.h:857
child_iterator child_begin() const
Definition: Comment.h:337
QualType ReturnType
Function return type if CommentDecl is something that we consider a "function".
Definition: Comment.h:1002
child_iterator child_end() const
Definition: Comment.h:339
Command started with an &#39;at&#39; character:
Definition: Comment.h:48
unsigned child_count() const
Definition: Comment.h:231
child_iterator child_begin() const
Definition: Comment.h:1112
static bool classof(const Comment *C)
Definition: Comment.h:638
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: Comment.h:218
InlineCommandComment(SourceLocation LocBegin, SourceLocation LocEnd, unsigned CommandID, RenderKind RK, ArrayRef< Argument > Args)
Definition: Comment.h:322
const Decl * getDecl() const LLVM_READONLY
Definition: Comment.h:1120
CommandMarkerKind
Describes the syntax that was used in a documentation command.
Definition: Comment.h:37
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:597
static bool classof(const Comment *C)
Definition: Comment.h:391
BlockCommandComment(SourceLocation LocBegin, SourceLocation LocEnd, unsigned CommandID, CommandMarkerKind CommandMarker)
Definition: Comment.h:627
CommandMarkerKind getCommandMarker() const LLVM_READONLY
Definition: Comment.h:705
int Depth
Definition: ASTDiff.cpp:191
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:1007
ArrayRef< Argument > Args
Command arguments.
Definition: Comment.h:319
SourceRange Range
Source range of this AST node.
Definition: Comment.h:59
CommentKind getCommentKind() const
Definition: Comment.h:204
bool isDirectionExplicit() const LLVM_READONLY
Definition: Comment.h:750
SourceRange getParamNameRange() const
Definition: Comment.h:769
SourceLocation getEnd() const
An opening HTML tag with attributes.
Definition: Comment.h:414
ParagraphComment(ArrayRef< InlineContentComment *> Content)
Definition: Comment.h:551
static bool classof(const Comment *C)
Definition: Comment.h:333
const SourceManager & SM
Definition: Format.cpp:1490
static bool classof(const Comment *C)
Definition: Comment.h:465
ParagraphComment * Paragraph
Paragraph argument.
Definition: Comment.h:612
This class provides information about commands that can be used in comments.
void setCloseName(StringRef Name, SourceLocation LocBegin)
Definition: Comment.h:919
Kind
static bool classof(const Comment *C)
Definition: Comment.h:825
Encodes a location in the source.
ArrayRef< VerbatimBlockLineComment * > Lines
Definition: Comment.h:896
static bool classof(const Comment *C)
Definition: Comment.h:907
bool isWhitespace() const
Definition: Comment.h:285
SourceRange getSourceRange() const LLVM_READONLY
Definition: Comment.h:216
bool isParamIndexValid() const LLVM_READONLY
Definition: Comment.h:773
ParagraphCommentBitfields ParagraphCommentBits
Definition: Comment.h:172
const CommandInfo * getCommandInfo(StringRef Name) const
TemplateDeclKind getTemplateKind() const LLVM_READONLY
Definition: Comment.h:1086
Argument(SourceRange Range, StringRef Text)
Definition: Comment.h:604
Block content (contains inline content).
Definition: Comment.h:531
Comment *const * child_iterator
Definition: Comment.h:224
StringRef getParamNameAsWritten() const
Definition: Comment.h:835
unsigned Kind
Simplified kind of CommentDecl, see DeclKind enum.
Definition: Comment.h:1062
SourceRange getCommandNameRange(const CommandTraits &Traits) const
Definition: Comment.h:663
PassDirection getDirection() const LLVM_READONLY
Definition: Comment.h:746
static bool classof(const Comment *C)
Definition: Comment.h:734
A closing HTML tag.
Definition: Comment.h:508
Everything else not explicitly mentioned below.
Definition: Comment.h:1013
child_iterator child_begin() const
Definition: Comment.h:524
Doxygen \tparam command, describes a template parameter.
Definition: Comment.h:800
VerbatimBlockLineComment(SourceLocation LocBegin, StringRef Text)
Definition: Comment.h:868
Dataflow Directional Tag Classes.
bool isValid() const
Return true if this is a valid SourceLocation object.
SourceLocation getCommandNameBeginLoc() const
Definition: Comment.h:659
ParamCommandComment(SourceLocation LocBegin, SourceLocation LocEnd, unsigned CommandID, CommandMarkerKind CommandMarker)
Definition: Comment.h:723
VerbatimLineComment(SourceLocation LocBegin, SourceLocation LocEnd, unsigned CommandID, SourceLocation TextBegin, StringRef Text)
Definition: Comment.h:950
Command started with a backslash character:
Definition: Comment.h:42
HTMLEndTagComment(SourceLocation LocBegin, SourceLocation LocEnd, StringRef TagName)
Definition: Comment.h:510
Information about the declaration, useful to clients of FullComment.
Definition: Comment.h:981
SourceLocation Loc
Preferred location to show caret.
Definition: Comment.h:56
A single paragraph that contains inline content.
Definition: Comment.h:547
DeclKind getKind() const LLVM_READONLY
Definition: Comment.h:1082
unsigned IsInstanceMethod
Is CommentDecl a non-static member function of C++ class or instance method of ObjC class...
Definition: Comment.h:1073
TextComment(SourceLocation LocBegin, SourceLocation LocEnd, StringRef Text)
Definition: Comment.h:267
StringRef getText(unsigned LineIdx) const
Definition: Comment.h:936
StringRef getTagName() const LLVM_READONLY
Definition: Comment.h:396
void setParamIndex(unsigned Index)
Definition: Comment.h:792
A C++ typedef-name (a &#39;typedef&#39; decl specifier or alias-declaration), see TypedefNameDecl.
Definition: Comment.h:1044
InlineContentCommentBitfields InlineContentCommentBits
Definition: Comment.h:167
child_iterator child_end() const
Definition: Comment.h:471
HTMLTagComment(CommentKind K, SourceLocation LocBegin, SourceLocation LocEnd, StringRef TagName, SourceLocation TagNameBegin, SourceLocation TagNameEnd)
Definition: Comment.h:377
void setParagraph(ParagraphComment *PC)
Definition: Comment.h:698
static bool classof(const Comment *C)
Definition: Comment.h:248
static bool classof(const Comment *C)
Definition: Comment.h:876
Defines the clang::SourceLocation class and associated facilities.
void setEnd(SourceLocation e)
Abstract class for opening and closing HTML tags.
Definition: Comment.h:372
const char * getCommentKindName() const
Definition: Comment.cpp:21
child_iterator child_end() const
Definition: Comment.h:647
VerbatimBlockComment(SourceLocation LocBegin, SourceLocation LocEnd, unsigned CommandID)
Definition: Comment.h:899
static bool classof(const Comment *C)
Definition: Comment.h:1108
const Attribute & getAttr(unsigned Idx) const
Definition: Comment.h:477
StringRef getCommandName(const CommandTraits &Traits) const
Definition: Comment.h:345
StringRef getParamNameAsWritten() const
Definition: Comment.h:765
child_iterator child_end() const
Definition: Comment.h:577
void setArgs(ArrayRef< Argument > A)
Definition: Comment.h:681
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:1078
Doxygen \param command.
Definition: Comment.h:712
child_iterator child_end() const
Definition: Comment.h:969
const DeclInfo * getDeclInfo() const LLVM_READONLY
Definition: Comment.h:1124
StringRef Text
Definition: Format.cpp:1621
ArrayRef< const ParmVarDecl * > ParamVars
Parameters that can be referenced by \param if CommentDecl is something that we consider a "function"...
Definition: Comment.h:998
child_iterator child_begin() const
Definition: Comment.h:911
A trivial tuple used to represent a source range.
ArrayRef< BlockContentComment * > getBlocks() const
Definition: Comment.h:1130
void setGreaterLoc(SourceLocation GreaterLoc)
Definition: Comment.h:494
SourceRange getArgRange(unsigned Idx) const
Definition: Comment.h:677
TParamCommandComment(SourceLocation LocBegin, SourceLocation LocEnd, unsigned CommandID, CommandMarkerKind CommandMarker)
Definition: Comment.h:817
static bool classof(const Comment *C)
Definition: Comment.h:275
child_iterator child_begin() const
Definition: Comment.h:573
ParamCommandCommentBitfields ParamCommandCommentBits
Definition: Comment.h:174
child_iterator child_begin() const
Definition: Comment.h:967
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:1092
HTMLStartTagCommentBitfields HTMLStartTagCommentBits
Definition: Comment.h:171