File indexing completed on 2026-05-10 08:36:29
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef LLVM_CLANG_AST_COMMENT_H
0014 #define LLVM_CLANG_AST_COMMENT_H
0015
0016 #include "clang/AST/CommentCommandTraits.h"
0017 #include "clang/AST/DeclObjC.h"
0018 #include "clang/AST/Type.h"
0019 #include "clang/Basic/SourceLocation.h"
0020 #include "llvm/ADT/ArrayRef.h"
0021 #include "llvm/ADT/StringRef.h"
0022
0023 namespace clang {
0024 class Decl;
0025 class ParmVarDecl;
0026 class TemplateParameterList;
0027
0028 namespace comments {
0029 class FullComment;
0030 enum class InlineCommandRenderKind;
0031 enum class ParamCommandPassDirection;
0032
0033
0034
0035
0036
0037
0038 enum CommandMarkerKind {
0039
0040
0041
0042
0043 CMK_Backslash = 0,
0044
0045
0046
0047
0048
0049 CMK_At = 1
0050 };
0051
0052 enum class CommentKind {
0053 None = 0,
0054 #define COMMENT(CLASS, PARENT) CLASS,
0055 #define COMMENT_RANGE(BASE, FIRST, LAST) \
0056 First##BASE##Constant = FIRST, Last##BASE##Constant = LAST,
0057 #define LAST_COMMENT_RANGE(BASE, FIRST, LAST) \
0058 First##BASE##Constant = FIRST, Last##BASE##Constant = LAST
0059 #define ABSTRACT_COMMENT(COMMENT)
0060 #include "clang/AST/CommentNodes.inc"
0061 };
0062
0063
0064
0065 class Comment {
0066 protected:
0067
0068 SourceLocation Loc;
0069
0070
0071 SourceRange Range;
0072
0073 class CommentBitfields {
0074 friend class Comment;
0075
0076
0077 LLVM_PREFERRED_TYPE(CommentKind)
0078 unsigned Kind : 8;
0079 };
0080 enum { NumCommentBits = 8 };
0081
0082 class InlineContentCommentBitfields {
0083 friend class InlineContentComment;
0084
0085 LLVM_PREFERRED_TYPE(CommentBitfields)
0086 unsigned : NumCommentBits;
0087
0088
0089
0090 LLVM_PREFERRED_TYPE(bool)
0091 unsigned HasTrailingNewline : 1;
0092 };
0093 enum { NumInlineContentCommentBits = NumCommentBits + 1 };
0094
0095 class TextCommentBitfields {
0096 friend class TextComment;
0097
0098 LLVM_PREFERRED_TYPE(InlineContentCommentBitfields)
0099 unsigned : NumInlineContentCommentBits;
0100
0101
0102 LLVM_PREFERRED_TYPE(bool)
0103 mutable unsigned IsWhitespaceValid : 1;
0104
0105
0106 LLVM_PREFERRED_TYPE(bool)
0107 mutable unsigned IsWhitespace : 1;
0108 };
0109 enum { NumTextCommentBits = NumInlineContentCommentBits + 2 };
0110
0111 class InlineCommandCommentBitfields {
0112 friend class InlineCommandComment;
0113
0114 LLVM_PREFERRED_TYPE(InlineContentCommentBitfields)
0115 unsigned : NumInlineContentCommentBits;
0116
0117 LLVM_PREFERRED_TYPE(InlineCommandRenderKind)
0118 unsigned RenderKind : 3;
0119
0120 LLVM_PREFERRED_TYPE(CommandTraits::KnownCommandIDs)
0121 unsigned CommandID : CommandInfo::NumCommandIDBits;
0122 };
0123 enum { NumInlineCommandCommentBits = NumInlineContentCommentBits + 3 +
0124 CommandInfo::NumCommandIDBits };
0125
0126 class HTMLTagCommentBitfields {
0127 friend class HTMLTagComment;
0128
0129 LLVM_PREFERRED_TYPE(InlineContentCommentBitfields)
0130 unsigned : NumInlineContentCommentBits;
0131
0132
0133 LLVM_PREFERRED_TYPE(bool)
0134 unsigned IsMalformed : 1;
0135 };
0136 enum { NumHTMLTagCommentBits = NumInlineContentCommentBits + 1 };
0137
0138 class HTMLStartTagCommentBitfields {
0139 friend class HTMLStartTagComment;
0140
0141 LLVM_PREFERRED_TYPE(HTMLTagCommentBitfields)
0142 unsigned : NumHTMLTagCommentBits;
0143
0144
0145
0146 LLVM_PREFERRED_TYPE(bool)
0147 unsigned IsSelfClosing : 1;
0148 };
0149 enum { NumHTMLStartTagCommentBits = NumHTMLTagCommentBits + 1 };
0150
0151 class ParagraphCommentBitfields {
0152 friend class ParagraphComment;
0153
0154 LLVM_PREFERRED_TYPE(CommentBitfields)
0155 unsigned : NumCommentBits;
0156
0157
0158 LLVM_PREFERRED_TYPE(bool)
0159 mutable unsigned IsWhitespaceValid : 1;
0160
0161
0162 LLVM_PREFERRED_TYPE(bool)
0163 mutable unsigned IsWhitespace : 1;
0164 };
0165 enum { NumParagraphCommentBits = NumCommentBits + 2 };
0166
0167 class BlockCommandCommentBitfields {
0168 friend class BlockCommandComment;
0169
0170 LLVM_PREFERRED_TYPE(CommentBitfields)
0171 unsigned : NumCommentBits;
0172
0173 LLVM_PREFERRED_TYPE(CommandTraits::KnownCommandIDs)
0174 unsigned CommandID : CommandInfo::NumCommandIDBits;
0175
0176
0177
0178 LLVM_PREFERRED_TYPE(CommandMarkerKind)
0179 unsigned CommandMarker : 1;
0180 };
0181 enum { NumBlockCommandCommentBits = NumCommentBits +
0182 CommandInfo::NumCommandIDBits + 1 };
0183
0184 class ParamCommandCommentBitfields {
0185 friend class ParamCommandComment;
0186
0187 LLVM_PREFERRED_TYPE(BlockCommandCommentBitfields)
0188 unsigned : NumBlockCommandCommentBits;
0189
0190
0191 LLVM_PREFERRED_TYPE(ParamCommandPassDirection)
0192 unsigned Direction : 2;
0193
0194
0195 LLVM_PREFERRED_TYPE(bool)
0196 unsigned IsDirectionExplicit : 1;
0197 };
0198 enum { NumParamCommandCommentBits = NumBlockCommandCommentBits + 3 };
0199
0200 union {
0201 CommentBitfields CommentBits;
0202 InlineContentCommentBitfields InlineContentCommentBits;
0203 TextCommentBitfields TextCommentBits;
0204 InlineCommandCommentBitfields InlineCommandCommentBits;
0205 HTMLTagCommentBitfields HTMLTagCommentBits;
0206 HTMLStartTagCommentBitfields HTMLStartTagCommentBits;
0207 ParagraphCommentBitfields ParagraphCommentBits;
0208 BlockCommandCommentBitfields BlockCommandCommentBits;
0209 ParamCommandCommentBitfields ParamCommandCommentBits;
0210 };
0211
0212 void setSourceRange(SourceRange SR) {
0213 Range = SR;
0214 }
0215
0216 void setLocation(SourceLocation L) {
0217 Loc = L;
0218 }
0219
0220 public:
0221 struct Argument {
0222 SourceRange Range;
0223 StringRef Text;
0224 };
0225
0226 Comment(CommentKind K,
0227 SourceLocation LocBegin,
0228 SourceLocation LocEnd) :
0229 Loc(LocBegin), Range(SourceRange(LocBegin, LocEnd)) {
0230 CommentBits.Kind = llvm::to_underlying(K);
0231 }
0232
0233 CommentKind getCommentKind() const {
0234 return static_cast<CommentKind>(CommentBits.Kind);
0235 }
0236
0237 const char *getCommentKindName() const;
0238
0239 void dump() const;
0240 void dumpColor() const;
0241 void dump(raw_ostream &OS, const ASTContext &Context) const;
0242
0243 SourceRange getSourceRange() const LLVM_READONLY { return Range; }
0244
0245 SourceLocation getBeginLoc() const LLVM_READONLY { return Range.getBegin(); }
0246
0247 SourceLocation getEndLoc() const LLVM_READONLY { return Range.getEnd(); }
0248
0249 SourceLocation getLocation() const LLVM_READONLY { return Loc; }
0250
0251 typedef Comment * const *child_iterator;
0252
0253 child_iterator child_begin() const;
0254 child_iterator child_end() const;
0255
0256
0257
0258 unsigned child_count() const {
0259 return child_end() - child_begin();
0260 }
0261 };
0262
0263
0264
0265 class InlineContentComment : public Comment {
0266 protected:
0267 InlineContentComment(CommentKind K,
0268 SourceLocation LocBegin,
0269 SourceLocation LocEnd) :
0270 Comment(K, LocBegin, LocEnd) {
0271 InlineContentCommentBits.HasTrailingNewline = 0;
0272 }
0273
0274 public:
0275 static bool classof(const Comment *C) {
0276 return C->getCommentKind() >=
0277 CommentKind::FirstInlineContentCommentConstant &&
0278 C->getCommentKind() <= CommentKind::LastInlineContentCommentConstant;
0279 }
0280
0281 void addTrailingNewline() {
0282 InlineContentCommentBits.HasTrailingNewline = 1;
0283 }
0284
0285 bool hasTrailingNewline() const {
0286 return InlineContentCommentBits.HasTrailingNewline;
0287 }
0288 };
0289
0290
0291 class TextComment : public InlineContentComment {
0292 StringRef Text;
0293
0294 public:
0295 TextComment(SourceLocation LocBegin, SourceLocation LocEnd, StringRef Text)
0296 : InlineContentComment(CommentKind::TextComment, LocBegin, LocEnd),
0297 Text(Text) {
0298 TextCommentBits.IsWhitespaceValid = false;
0299 }
0300
0301 static bool classof(const Comment *C) {
0302 return C->getCommentKind() == CommentKind::TextComment;
0303 }
0304
0305 child_iterator child_begin() const { return nullptr; }
0306
0307 child_iterator child_end() const { return nullptr; }
0308
0309 StringRef getText() const LLVM_READONLY { return Text; }
0310
0311 bool isWhitespace() const {
0312 if (TextCommentBits.IsWhitespaceValid)
0313 return TextCommentBits.IsWhitespace;
0314
0315 TextCommentBits.IsWhitespace = isWhitespaceNoCache();
0316 TextCommentBits.IsWhitespaceValid = true;
0317 return TextCommentBits.IsWhitespace;
0318 }
0319
0320 private:
0321 bool isWhitespaceNoCache() const;
0322 };
0323
0324
0325
0326 enum class InlineCommandRenderKind {
0327 Normal,
0328 Bold,
0329 Monospaced,
0330 Emphasized,
0331 Anchor
0332 };
0333
0334
0335 class InlineCommandComment : public InlineContentComment {
0336 protected:
0337
0338 ArrayRef<Argument> Args;
0339
0340 public:
0341 InlineCommandComment(SourceLocation LocBegin, SourceLocation LocEnd,
0342 unsigned CommandID, InlineCommandRenderKind RK,
0343 ArrayRef<Argument> Args)
0344 : InlineContentComment(CommentKind::InlineCommandComment, LocBegin,
0345 LocEnd),
0346 Args(Args) {
0347 InlineCommandCommentBits.RenderKind = llvm::to_underlying(RK);
0348 InlineCommandCommentBits.CommandID = CommandID;
0349 }
0350
0351 static bool classof(const Comment *C) {
0352 return C->getCommentKind() == CommentKind::InlineCommandComment;
0353 }
0354
0355 child_iterator child_begin() const { return nullptr; }
0356
0357 child_iterator child_end() const { return nullptr; }
0358
0359 unsigned getCommandID() const {
0360 return InlineCommandCommentBits.CommandID;
0361 }
0362
0363 StringRef getCommandName(const CommandTraits &Traits) const {
0364 return Traits.getCommandInfo(getCommandID())->Name;
0365 }
0366
0367 SourceRange getCommandNameRange() const {
0368 return SourceRange(getBeginLoc().getLocWithOffset(-1), getEndLoc());
0369 }
0370
0371 InlineCommandRenderKind getRenderKind() const {
0372 return static_cast<InlineCommandRenderKind>(
0373 InlineCommandCommentBits.RenderKind);
0374 }
0375
0376 unsigned getNumArgs() const {
0377 return Args.size();
0378 }
0379
0380 StringRef getArgText(unsigned Idx) const {
0381 return Args[Idx].Text;
0382 }
0383
0384 SourceRange getArgRange(unsigned Idx) const {
0385 return Args[Idx].Range;
0386 }
0387 };
0388
0389
0390
0391 class HTMLTagComment : public InlineContentComment {
0392 protected:
0393 StringRef TagName;
0394 SourceRange TagNameRange;
0395
0396 HTMLTagComment(CommentKind K,
0397 SourceLocation LocBegin,
0398 SourceLocation LocEnd,
0399 StringRef TagName,
0400 SourceLocation TagNameBegin,
0401 SourceLocation TagNameEnd) :
0402 InlineContentComment(K, LocBegin, LocEnd),
0403 TagName(TagName),
0404 TagNameRange(TagNameBegin, TagNameEnd) {
0405 setLocation(TagNameBegin);
0406 HTMLTagCommentBits.IsMalformed = 0;
0407 }
0408
0409 public:
0410 static bool classof(const Comment *C) {
0411 return C->getCommentKind() >= CommentKind::FirstHTMLTagCommentConstant &&
0412 C->getCommentKind() <= CommentKind::LastHTMLTagCommentConstant;
0413 }
0414
0415 StringRef getTagName() const LLVM_READONLY { return TagName; }
0416
0417 SourceRange getTagNameSourceRange() const LLVM_READONLY {
0418 SourceLocation L = getLocation();
0419 return SourceRange(L.getLocWithOffset(1),
0420 L.getLocWithOffset(1 + TagName.size()));
0421 }
0422
0423 bool isMalformed() const {
0424 return HTMLTagCommentBits.IsMalformed;
0425 }
0426
0427 void setIsMalformed() {
0428 HTMLTagCommentBits.IsMalformed = 1;
0429 }
0430 };
0431
0432
0433 class HTMLStartTagComment : public HTMLTagComment {
0434 public:
0435 class Attribute {
0436 public:
0437 SourceLocation NameLocBegin;
0438 StringRef Name;
0439
0440 SourceLocation EqualsLoc;
0441
0442 SourceRange ValueRange;
0443 StringRef Value;
0444
0445 Attribute() { }
0446
0447 Attribute(SourceLocation NameLocBegin, StringRef Name)
0448 : NameLocBegin(NameLocBegin), Name(Name), EqualsLoc(SourceLocation()) {}
0449
0450 Attribute(SourceLocation NameLocBegin, StringRef Name,
0451 SourceLocation EqualsLoc, SourceRange ValueRange, StringRef Value)
0452 : NameLocBegin(NameLocBegin), Name(Name), EqualsLoc(EqualsLoc),
0453 ValueRange(ValueRange), Value(Value) {}
0454
0455 SourceLocation getNameLocEnd() const {
0456 return NameLocBegin.getLocWithOffset(Name.size());
0457 }
0458
0459 SourceRange getNameRange() const {
0460 return SourceRange(NameLocBegin, getNameLocEnd());
0461 }
0462 };
0463
0464 private:
0465 ArrayRef<Attribute> Attributes;
0466
0467 public:
0468 HTMLStartTagComment(SourceLocation LocBegin, StringRef TagName)
0469 : HTMLTagComment(CommentKind::HTMLStartTagComment, LocBegin,
0470 LocBegin.getLocWithOffset(1 + TagName.size()), TagName,
0471 LocBegin.getLocWithOffset(1),
0472 LocBegin.getLocWithOffset(1 + TagName.size())) {
0473 HTMLStartTagCommentBits.IsSelfClosing = false;
0474 }
0475
0476 static bool classof(const Comment *C) {
0477 return C->getCommentKind() == CommentKind::HTMLStartTagComment;
0478 }
0479
0480 child_iterator child_begin() const { return nullptr; }
0481
0482 child_iterator child_end() const { return nullptr; }
0483
0484 unsigned getNumAttrs() const {
0485 return Attributes.size();
0486 }
0487
0488 const Attribute &getAttr(unsigned Idx) const {
0489 return Attributes[Idx];
0490 }
0491
0492 void setAttrs(ArrayRef<Attribute> Attrs) {
0493 Attributes = Attrs;
0494 if (!Attrs.empty()) {
0495 const Attribute &Attr = Attrs.back();
0496 SourceLocation L = Attr.ValueRange.getEnd();
0497 if (L.isValid())
0498 Range.setEnd(L);
0499 else {
0500 Range.setEnd(Attr.getNameLocEnd());
0501 }
0502 }
0503 }
0504
0505 void setGreaterLoc(SourceLocation GreaterLoc) {
0506 Range.setEnd(GreaterLoc);
0507 }
0508
0509 bool isSelfClosing() const {
0510 return HTMLStartTagCommentBits.IsSelfClosing;
0511 }
0512
0513 void setSelfClosing() {
0514 HTMLStartTagCommentBits.IsSelfClosing = true;
0515 }
0516 };
0517
0518
0519 class HTMLEndTagComment : public HTMLTagComment {
0520 public:
0521 HTMLEndTagComment(SourceLocation LocBegin, SourceLocation LocEnd,
0522 StringRef TagName)
0523 : HTMLTagComment(CommentKind::HTMLEndTagComment, LocBegin, LocEnd,
0524 TagName, LocBegin.getLocWithOffset(2),
0525 LocBegin.getLocWithOffset(2 + TagName.size())) {}
0526
0527 static bool classof(const Comment *C) {
0528 return C->getCommentKind() == CommentKind::HTMLEndTagComment;
0529 }
0530
0531 child_iterator child_begin() const { return nullptr; }
0532
0533 child_iterator child_end() const { return nullptr; }
0534 };
0535
0536
0537
0538 class BlockContentComment : public Comment {
0539 protected:
0540 BlockContentComment(CommentKind K,
0541 SourceLocation LocBegin,
0542 SourceLocation LocEnd) :
0543 Comment(K, LocBegin, LocEnd)
0544 { }
0545
0546 public:
0547 static bool classof(const Comment *C) {
0548 return C->getCommentKind() >=
0549 CommentKind::FirstBlockContentCommentConstant &&
0550 C->getCommentKind() <= CommentKind::LastBlockContentCommentConstant;
0551 }
0552 };
0553
0554
0555 class ParagraphComment : public BlockContentComment {
0556 ArrayRef<InlineContentComment *> Content;
0557
0558 public:
0559 ParagraphComment(ArrayRef<InlineContentComment *> Content)
0560 : BlockContentComment(CommentKind::ParagraphComment, SourceLocation(),
0561 SourceLocation()),
0562 Content(Content) {
0563 if (Content.empty()) {
0564 ParagraphCommentBits.IsWhitespace = true;
0565 ParagraphCommentBits.IsWhitespaceValid = true;
0566 return;
0567 }
0568
0569 ParagraphCommentBits.IsWhitespaceValid = false;
0570
0571 setSourceRange(SourceRange(Content.front()->getBeginLoc(),
0572 Content.back()->getEndLoc()));
0573 setLocation(Content.front()->getBeginLoc());
0574 }
0575
0576 static bool classof(const Comment *C) {
0577 return C->getCommentKind() == CommentKind::ParagraphComment;
0578 }
0579
0580 child_iterator child_begin() const {
0581 return reinterpret_cast<child_iterator>(Content.begin());
0582 }
0583
0584 child_iterator child_end() const {
0585 return reinterpret_cast<child_iterator>(Content.end());
0586 }
0587
0588 bool isWhitespace() const {
0589 if (ParagraphCommentBits.IsWhitespaceValid)
0590 return ParagraphCommentBits.IsWhitespace;
0591
0592 ParagraphCommentBits.IsWhitespace = isWhitespaceNoCache();
0593 ParagraphCommentBits.IsWhitespaceValid = true;
0594 return ParagraphCommentBits.IsWhitespace;
0595 }
0596
0597 private:
0598 bool isWhitespaceNoCache() const;
0599 };
0600
0601
0602
0603
0604 class BlockCommandComment : public BlockContentComment {
0605 protected:
0606
0607 ArrayRef<Argument> Args;
0608
0609
0610 ParagraphComment *Paragraph;
0611
0612 BlockCommandComment(CommentKind K,
0613 SourceLocation LocBegin,
0614 SourceLocation LocEnd,
0615 unsigned CommandID,
0616 CommandMarkerKind CommandMarker) :
0617 BlockContentComment(K, LocBegin, LocEnd),
0618 Paragraph(nullptr) {
0619 setLocation(getCommandNameBeginLoc());
0620 BlockCommandCommentBits.CommandID = CommandID;
0621 BlockCommandCommentBits.CommandMarker = CommandMarker;
0622 }
0623
0624 public:
0625 BlockCommandComment(SourceLocation LocBegin, SourceLocation LocEnd,
0626 unsigned CommandID, CommandMarkerKind CommandMarker)
0627 : BlockContentComment(CommentKind::BlockCommandComment, LocBegin, LocEnd),
0628 Paragraph(nullptr) {
0629 setLocation(getCommandNameBeginLoc());
0630 BlockCommandCommentBits.CommandID = CommandID;
0631 BlockCommandCommentBits.CommandMarker = CommandMarker;
0632 }
0633
0634 static bool classof(const Comment *C) {
0635 return C->getCommentKind() >=
0636 CommentKind::FirstBlockCommandCommentConstant &&
0637 C->getCommentKind() <= CommentKind::LastBlockCommandCommentConstant;
0638 }
0639
0640 child_iterator child_begin() const {
0641 return reinterpret_cast<child_iterator>(&Paragraph);
0642 }
0643
0644 child_iterator child_end() const {
0645 return reinterpret_cast<child_iterator>(&Paragraph + 1);
0646 }
0647
0648 unsigned getCommandID() const {
0649 return BlockCommandCommentBits.CommandID;
0650 }
0651
0652 StringRef getCommandName(const CommandTraits &Traits) const {
0653 return Traits.getCommandInfo(getCommandID())->Name;
0654 }
0655
0656 SourceLocation getCommandNameBeginLoc() const {
0657 return getBeginLoc().getLocWithOffset(1);
0658 }
0659
0660 SourceRange getCommandNameRange(const CommandTraits &Traits) const {
0661 StringRef Name = getCommandName(Traits);
0662 return SourceRange(getCommandNameBeginLoc(),
0663 getBeginLoc().getLocWithOffset(1 + Name.size()));
0664 }
0665
0666 unsigned getNumArgs() const {
0667 return Args.size();
0668 }
0669
0670 StringRef getArgText(unsigned Idx) const {
0671 return Args[Idx].Text;
0672 }
0673
0674 SourceRange getArgRange(unsigned Idx) const {
0675 return Args[Idx].Range;
0676 }
0677
0678 void setArgs(ArrayRef<Argument> A) {
0679 Args = A;
0680 if (Args.size() > 0) {
0681 SourceLocation NewLocEnd = Args.back().Range.getEnd();
0682 if (NewLocEnd.isValid())
0683 setSourceRange(SourceRange(getBeginLoc(), NewLocEnd));
0684 }
0685 }
0686
0687 ParagraphComment *getParagraph() const LLVM_READONLY {
0688 return Paragraph;
0689 }
0690
0691 bool hasNonWhitespaceParagraph() const {
0692 return Paragraph && !Paragraph->isWhitespace();
0693 }
0694
0695 void setParagraph(ParagraphComment *PC) {
0696 Paragraph = PC;
0697 SourceLocation NewLocEnd = PC->getEndLoc();
0698 if (NewLocEnd.isValid())
0699 setSourceRange(SourceRange(getBeginLoc(), NewLocEnd));
0700 }
0701
0702 CommandMarkerKind getCommandMarker() const LLVM_READONLY {
0703 return static_cast<CommandMarkerKind>(
0704 BlockCommandCommentBits.CommandMarker);
0705 }
0706 };
0707
0708 enum class ParamCommandPassDirection { In, Out, InOut };
0709
0710
0711 class ParamCommandComment : public BlockCommandComment {
0712 private:
0713
0714 unsigned ParamIndex;
0715
0716 public:
0717 enum : unsigned {
0718 InvalidParamIndex = ~0U,
0719 VarArgParamIndex = ~0U - 1U
0720 };
0721
0722 ParamCommandComment(SourceLocation LocBegin, SourceLocation LocEnd,
0723 unsigned CommandID, CommandMarkerKind CommandMarker)
0724 : BlockCommandComment(CommentKind::ParamCommandComment, LocBegin, LocEnd,
0725 CommandID, CommandMarker),
0726 ParamIndex(InvalidParamIndex) {
0727 ParamCommandCommentBits.Direction =
0728 llvm::to_underlying(ParamCommandPassDirection::In);
0729 ParamCommandCommentBits.IsDirectionExplicit = false;
0730 }
0731
0732 static bool classof(const Comment *C) {
0733 return C->getCommentKind() == CommentKind::ParamCommandComment;
0734 }
0735
0736 static const char *getDirectionAsString(ParamCommandPassDirection D);
0737
0738 ParamCommandPassDirection getDirection() const LLVM_READONLY {
0739 return static_cast<ParamCommandPassDirection>(
0740 ParamCommandCommentBits.Direction);
0741 }
0742
0743 bool isDirectionExplicit() const LLVM_READONLY {
0744 return ParamCommandCommentBits.IsDirectionExplicit;
0745 }
0746
0747 void setDirection(ParamCommandPassDirection Direction, bool Explicit) {
0748 ParamCommandCommentBits.Direction = llvm::to_underlying(Direction);
0749 ParamCommandCommentBits.IsDirectionExplicit = Explicit;
0750 }
0751
0752 bool hasParamName() const {
0753 return getNumArgs() > 0;
0754 }
0755
0756 StringRef getParamName(const FullComment *FC) const;
0757
0758 StringRef getParamNameAsWritten() const {
0759 return Args[0].Text;
0760 }
0761
0762 SourceRange getParamNameRange() const {
0763 return Args[0].Range;
0764 }
0765
0766 bool isParamIndexValid() const LLVM_READONLY {
0767 return ParamIndex != InvalidParamIndex;
0768 }
0769
0770 bool isVarArgParam() const LLVM_READONLY {
0771 return ParamIndex == VarArgParamIndex;
0772 }
0773
0774 void setIsVarArgParam() {
0775 ParamIndex = VarArgParamIndex;
0776 assert(isParamIndexValid());
0777 }
0778
0779 unsigned getParamIndex() const LLVM_READONLY {
0780 assert(isParamIndexValid());
0781 assert(!isVarArgParam());
0782 return ParamIndex;
0783 }
0784
0785 void setParamIndex(unsigned Index) {
0786 ParamIndex = Index;
0787 assert(isParamIndexValid());
0788 assert(!isVarArgParam());
0789 }
0790 };
0791
0792
0793 class TParamCommandComment : public BlockCommandComment {
0794 private:
0795
0796
0797
0798
0799
0800
0801
0802
0803
0804
0805
0806
0807 ArrayRef<unsigned> Position;
0808
0809 public:
0810 TParamCommandComment(SourceLocation LocBegin, SourceLocation LocEnd,
0811 unsigned CommandID, CommandMarkerKind CommandMarker)
0812 : BlockCommandComment(CommentKind::TParamCommandComment, LocBegin, LocEnd,
0813 CommandID, CommandMarker) {}
0814
0815 static bool classof(const Comment *C) {
0816 return C->getCommentKind() == CommentKind::TParamCommandComment;
0817 }
0818
0819 bool hasParamName() const {
0820 return getNumArgs() > 0;
0821 }
0822
0823 StringRef getParamName(const FullComment *FC) const;
0824
0825 StringRef getParamNameAsWritten() const {
0826 return Args[0].Text;
0827 }
0828
0829 SourceRange getParamNameRange() const {
0830 return Args[0].Range;
0831 }
0832
0833 bool isPositionValid() const LLVM_READONLY {
0834 return !Position.empty();
0835 }
0836
0837 unsigned getDepth() const {
0838 assert(isPositionValid());
0839 return Position.size();
0840 }
0841
0842 unsigned getIndex(unsigned Depth) const {
0843 assert(isPositionValid());
0844 return Position[Depth];
0845 }
0846
0847 void setPosition(ArrayRef<unsigned> NewPosition) {
0848 Position = NewPosition;
0849 assert(isPositionValid());
0850 }
0851 };
0852
0853
0854 class VerbatimBlockLineComment : public Comment {
0855 StringRef Text;
0856
0857 public:
0858 VerbatimBlockLineComment(SourceLocation LocBegin, StringRef Text)
0859 : Comment(CommentKind::VerbatimBlockLineComment, LocBegin,
0860 LocBegin.getLocWithOffset(Text.size())),
0861 Text(Text) {}
0862
0863 static bool classof(const Comment *C) {
0864 return C->getCommentKind() == CommentKind::VerbatimBlockLineComment;
0865 }
0866
0867 child_iterator child_begin() const { return nullptr; }
0868
0869 child_iterator child_end() const { return nullptr; }
0870
0871 StringRef getText() const LLVM_READONLY {
0872 return Text;
0873 }
0874 };
0875
0876
0877
0878
0879 class VerbatimBlockComment : public BlockCommandComment {
0880 protected:
0881 StringRef CloseName;
0882 SourceLocation CloseNameLocBegin;
0883 ArrayRef<VerbatimBlockLineComment *> Lines;
0884
0885 public:
0886 VerbatimBlockComment(SourceLocation LocBegin, SourceLocation LocEnd,
0887 unsigned CommandID)
0888 : BlockCommandComment(CommentKind::VerbatimBlockComment, LocBegin, LocEnd,
0889 CommandID,
0890 CMK_At)
0891 {}
0892
0893 static bool classof(const Comment *C) {
0894 return C->getCommentKind() == CommentKind::VerbatimBlockComment;
0895 }
0896
0897 child_iterator child_begin() const {
0898 return reinterpret_cast<child_iterator>(Lines.begin());
0899 }
0900
0901 child_iterator child_end() const {
0902 return reinterpret_cast<child_iterator>(Lines.end());
0903 }
0904
0905 void setCloseName(StringRef Name, SourceLocation LocBegin) {
0906 CloseName = Name;
0907 CloseNameLocBegin = LocBegin;
0908 }
0909
0910 void setLines(ArrayRef<VerbatimBlockLineComment *> L) {
0911 Lines = L;
0912 }
0913
0914 StringRef getCloseName() const {
0915 return CloseName;
0916 }
0917
0918 unsigned getNumLines() const {
0919 return Lines.size();
0920 }
0921
0922 StringRef getText(unsigned LineIdx) const {
0923 return Lines[LineIdx]->getText();
0924 }
0925 };
0926
0927
0928
0929
0930 class VerbatimLineComment : public BlockCommandComment {
0931 protected:
0932 StringRef Text;
0933 SourceLocation TextBegin;
0934
0935 public:
0936 VerbatimLineComment(SourceLocation LocBegin, SourceLocation LocEnd,
0937 unsigned CommandID, SourceLocation TextBegin,
0938 StringRef Text)
0939 : BlockCommandComment(CommentKind::VerbatimLineComment, LocBegin, LocEnd,
0940 CommandID,
0941 CMK_At),
0942 Text(Text), TextBegin(TextBegin) {}
0943
0944 static bool classof(const Comment *C) {
0945 return C->getCommentKind() == CommentKind::VerbatimLineComment;
0946 }
0947
0948 child_iterator child_begin() const { return nullptr; }
0949
0950 child_iterator child_end() const { return nullptr; }
0951
0952 StringRef getText() const {
0953 return Text;
0954 }
0955
0956 SourceRange getTextRange() const {
0957 return SourceRange(TextBegin, getEndLoc());
0958 }
0959 };
0960
0961
0962 struct DeclInfo {
0963
0964
0965 const Decl *CommentDecl;
0966
0967
0968
0969
0970
0971
0972
0973
0974
0975 const Decl *CurrentDecl;
0976
0977
0978
0979 ArrayRef<const ParmVarDecl *> ParamVars;
0980
0981
0982
0983 QualType ReturnType;
0984
0985
0986
0987
0988 const TemplateParameterList *TemplateParameters;
0989
0990
0991
0992 enum DeclKind {
0993
0994 OtherKind,
0995
0996
0997
0998
0999
1000
1001
1002
1003
1004 FunctionKind,
1005
1006
1007
1008
1009
1010 ClassKind,
1011
1012
1013
1014
1015
1016 VariableKind,
1017
1018
1019 NamespaceKind,
1020
1021
1022
1023 TypedefKind,
1024
1025
1026 EnumKind
1027 };
1028
1029
1030 enum TemplateDeclKind {
1031 NotTemplate,
1032 Template,
1033 TemplateSpecialization,
1034 TemplatePartialSpecialization
1035 };
1036
1037
1038 LLVM_PREFERRED_TYPE(bool)
1039 unsigned IsFilled : 1;
1040
1041
1042 LLVM_PREFERRED_TYPE(DeclKind)
1043 unsigned Kind : 3;
1044
1045
1046 LLVM_PREFERRED_TYPE(TemplateDeclKind)
1047 unsigned TemplateKind : 2;
1048
1049
1050 LLVM_PREFERRED_TYPE(bool)
1051 unsigned IsObjCMethod : 1;
1052
1053
1054
1055
1056 LLVM_PREFERRED_TYPE(bool)
1057 unsigned IsInstanceMethod : 1;
1058
1059
1060
1061
1062 LLVM_PREFERRED_TYPE(bool)
1063 unsigned IsClassMethod : 1;
1064
1065
1066 LLVM_PREFERRED_TYPE(bool)
1067 unsigned IsVariadic : 1;
1068
1069 void fill();
1070
1071 DeclKind getKind() const LLVM_READONLY {
1072 return static_cast<DeclKind>(Kind);
1073 }
1074
1075 TemplateDeclKind getTemplateKind() const LLVM_READONLY {
1076 return static_cast<TemplateDeclKind>(TemplateKind);
1077 }
1078
1079 bool involvesFunctionType() const { return !ReturnType.isNull(); }
1080 };
1081
1082
1083 class FullComment : public Comment {
1084 ArrayRef<BlockContentComment *> Blocks;
1085 DeclInfo *ThisDeclInfo;
1086
1087 public:
1088 FullComment(ArrayRef<BlockContentComment *> Blocks, DeclInfo *D)
1089 : Comment(CommentKind::FullComment, SourceLocation(), SourceLocation()),
1090 Blocks(Blocks), ThisDeclInfo(D) {
1091 if (Blocks.empty())
1092 return;
1093
1094 setSourceRange(
1095 SourceRange(Blocks.front()->getBeginLoc(), Blocks.back()->getEndLoc()));
1096 setLocation(Blocks.front()->getBeginLoc());
1097 }
1098
1099 static bool classof(const Comment *C) {
1100 return C->getCommentKind() == CommentKind::FullComment;
1101 }
1102
1103 child_iterator child_begin() const {
1104 return reinterpret_cast<child_iterator>(Blocks.begin());
1105 }
1106
1107 child_iterator child_end() const {
1108 return reinterpret_cast<child_iterator>(Blocks.end());
1109 }
1110
1111 const Decl *getDecl() const LLVM_READONLY {
1112 return ThisDeclInfo->CommentDecl;
1113 }
1114
1115 const DeclInfo *getDeclInfo() const LLVM_READONLY {
1116 if (!ThisDeclInfo->IsFilled)
1117 ThisDeclInfo->fill();
1118 return ThisDeclInfo;
1119 }
1120
1121 ArrayRef<BlockContentComment *> getBlocks() const { return Blocks; }
1122
1123 };
1124 }
1125 }
1126
1127 #endif
1128