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