- //===--- Comment.h - Comment AST nodes --------------------------*- C++ -*-===// 
- // 
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 
- // See https://llvm.org/LICENSE.txt for license information. 
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 
- // 
- //===----------------------------------------------------------------------===// 
- // 
- //  This file defines comment AST nodes. 
- // 
- //===----------------------------------------------------------------------===// 
-   
- #ifndef LLVM_CLANG_AST_COMMENT_H 
- #define LLVM_CLANG_AST_COMMENT_H 
-   
- #include "clang/AST/CommentCommandTraits.h" 
- #include "clang/AST/DeclObjC.h" 
- #include "clang/AST/Type.h" 
- #include "clang/Basic/SourceLocation.h" 
- #include "llvm/ADT/ArrayRef.h" 
- #include "llvm/ADT/StringRef.h" 
-   
- namespace clang { 
- class Decl; 
- class ParmVarDecl; 
- class TemplateParameterList; 
-   
- namespace comments { 
- class FullComment; 
-   
- /// Describes the syntax that was used in a documentation command. 
- /// 
- /// Exact values of this enumeration are important because they used to select 
- /// parts of diagnostic messages.  Audit diagnostics before changing or adding 
- /// a new value. 
- enum CommandMarkerKind { 
-   /// Command started with a backslash character: 
-   /// \code 
-   ///   \foo 
-   /// \endcode 
-   CMK_Backslash = 0, 
-   
-   /// Command started with an 'at' character: 
-   /// \code 
-   ///   @foo 
-   /// \endcode 
-   CMK_At = 1 
- }; 
-   
- /// Any part of the comment. 
- /// Abstract class. 
- class Comment { 
- protected: 
-   /// Preferred location to show caret. 
-   SourceLocation Loc; 
-   
-   /// Source range of this AST node. 
-   SourceRange Range; 
-   
-   class CommentBitfields { 
-     friend class Comment; 
-   
-     /// Type of this AST node. 
-     unsigned Kind : 8; 
-   }; 
-   enum { NumCommentBits = 8 }; 
-   
-   class InlineContentCommentBitfields { 
-     friend class InlineContentComment; 
-   
-     unsigned : NumCommentBits; 
-   
-     /// True if there is a newline after this inline content node. 
-     /// (There is no separate AST node for a newline.) 
-     unsigned HasTrailingNewline : 1; 
-   }; 
-   enum { NumInlineContentCommentBits = NumCommentBits + 1 }; 
-   
-   class TextCommentBitfields { 
-     friend class TextComment; 
-   
-     unsigned : NumInlineContentCommentBits; 
-   
-     /// True if \c IsWhitespace field contains a valid value. 
-     mutable unsigned IsWhitespaceValid : 1; 
-   
-     /// True if this comment AST node contains only whitespace. 
-     mutable unsigned IsWhitespace : 1; 
-   }; 
-   enum { NumTextCommentBits = NumInlineContentCommentBits + 2 }; 
-   
-   class InlineCommandCommentBitfields { 
-     friend class InlineCommandComment; 
-   
-     unsigned : NumInlineContentCommentBits; 
-   
-     unsigned RenderKind : 3; 
-   
-     unsigned CommandID : CommandInfo::NumCommandIDBits; 
-   }; 
-   enum { NumInlineCommandCommentBits = NumInlineContentCommentBits + 3 + 
-                                        CommandInfo::NumCommandIDBits }; 
-   
-   class HTMLTagCommentBitfields { 
-     friend class HTMLTagComment; 
-   
-     unsigned : NumInlineContentCommentBits; 
-   
-     /// True if we found that this tag is malformed in some way. 
-     unsigned IsMalformed : 1; 
-   }; 
-   enum { NumHTMLTagCommentBits = NumInlineContentCommentBits + 1 }; 
-   
-   class HTMLStartTagCommentBitfields { 
-     friend class HTMLStartTagComment; 
-   
-     unsigned : NumHTMLTagCommentBits; 
-   
-     /// True if this tag is self-closing (e. g., <br />).  This is based on tag 
-     /// spelling in comment (plain <br> would not set this flag). 
-     unsigned IsSelfClosing : 1; 
-   }; 
-   enum { NumHTMLStartTagCommentBits = NumHTMLTagCommentBits + 1 }; 
-   
-   class ParagraphCommentBitfields { 
-     friend class ParagraphComment; 
-   
-     unsigned : NumCommentBits; 
-   
-     /// True if \c IsWhitespace field contains a valid value. 
-     mutable unsigned IsWhitespaceValid : 1; 
-   
-     /// True if this comment AST node contains only whitespace. 
-     mutable unsigned IsWhitespace : 1; 
-   }; 
-   enum { NumParagraphCommentBits = NumCommentBits + 2 }; 
-   
-   class BlockCommandCommentBitfields { 
-     friend class BlockCommandComment; 
-   
-     unsigned : NumCommentBits; 
-   
-     unsigned CommandID : CommandInfo::NumCommandIDBits; 
-   
-     /// Describes the syntax that was used in a documentation command. 
-     /// Contains values from CommandMarkerKind enum. 
-     unsigned CommandMarker : 1; 
-   }; 
-   enum { NumBlockCommandCommentBits = NumCommentBits + 
-                                       CommandInfo::NumCommandIDBits + 1 }; 
-   
-   class ParamCommandCommentBitfields { 
-     friend class ParamCommandComment; 
-   
-     unsigned : NumBlockCommandCommentBits; 
-   
-     /// Parameter passing direction, see ParamCommandComment::PassDirection. 
-     unsigned Direction : 2; 
-   
-     /// True if direction was specified explicitly in the comment. 
-     unsigned IsDirectionExplicit : 1; 
-   }; 
-   enum { NumParamCommandCommentBits = NumBlockCommandCommentBits + 3 }; 
-   
-   union { 
-     CommentBitfields CommentBits; 
-     InlineContentCommentBitfields InlineContentCommentBits; 
-     TextCommentBitfields TextCommentBits; 
-     InlineCommandCommentBitfields InlineCommandCommentBits; 
-     HTMLTagCommentBitfields HTMLTagCommentBits; 
-     HTMLStartTagCommentBitfields HTMLStartTagCommentBits; 
-     ParagraphCommentBitfields ParagraphCommentBits; 
-     BlockCommandCommentBitfields BlockCommandCommentBits; 
-     ParamCommandCommentBitfields ParamCommandCommentBits; 
-   }; 
-   
-   void setSourceRange(SourceRange SR) { 
-     Range = SR; 
-   } 
-   
-   void setLocation(SourceLocation L) { 
-     Loc = L; 
-   } 
-   
- public: 
-   enum CommentKind { 
-     NoCommentKind = 0, 
- #define COMMENT(CLASS, PARENT) CLASS##Kind, 
- #define COMMENT_RANGE(BASE, FIRST, LAST) \ 
-     First##BASE##Constant=FIRST##Kind, Last##BASE##Constant=LAST##Kind, 
- #define LAST_COMMENT_RANGE(BASE, FIRST, LAST) \ 
-     First##BASE##Constant=FIRST##Kind, Last##BASE##Constant=LAST##Kind 
- #define ABSTRACT_COMMENT(COMMENT) 
- #include "clang/AST/CommentNodes.inc" 
-   }; 
-   
-   struct Argument { 
-     SourceRange Range; 
-     StringRef Text; 
-   }; 
-   
-   Comment(CommentKind K, 
-           SourceLocation LocBegin, 
-           SourceLocation LocEnd) : 
-       Loc(LocBegin), Range(SourceRange(LocBegin, LocEnd)) { 
-     CommentBits.Kind = K; 
-   } 
-   
-   CommentKind getCommentKind() const { 
-     return static_cast<CommentKind>(CommentBits.Kind); 
-   } 
-   
-   const char *getCommentKindName() const; 
-   
-   void dump() const; 
-   void dumpColor() const; 
-   void dump(raw_ostream &OS, const ASTContext &Context) const; 
-   
-   SourceRange getSourceRange() const LLVM_READONLY { return Range; } 
-   
-   SourceLocation getBeginLoc() const LLVM_READONLY { return Range.getBegin(); } 
-   
-   SourceLocation getEndLoc() const LLVM_READONLY { return Range.getEnd(); } 
-   
-   SourceLocation getLocation() const LLVM_READONLY { return Loc; } 
-   
-   typedef Comment * const *child_iterator; 
-   
-   child_iterator child_begin() const; 
-   child_iterator child_end() const; 
-   
-   // TODO: const child iterator 
-   
-   unsigned child_count() const { 
-     return child_end() - child_begin(); 
-   } 
- }; 
-   
- /// Inline content (contained within a block). 
- /// Abstract class. 
- class InlineContentComment : public Comment { 
- protected: 
-   InlineContentComment(CommentKind K, 
-                        SourceLocation LocBegin, 
-                        SourceLocation LocEnd) : 
-       Comment(K, LocBegin, LocEnd) { 
-     InlineContentCommentBits.HasTrailingNewline = 0; 
-   } 
-   
- public: 
-   static bool classof(const Comment *C) { 
-     return C->getCommentKind() >= FirstInlineContentCommentConstant && 
-            C->getCommentKind() <= LastInlineContentCommentConstant; 
-   } 
-   
-   void addTrailingNewline() { 
-     InlineContentCommentBits.HasTrailingNewline = 1; 
-   } 
-   
-   bool hasTrailingNewline() const { 
-     return InlineContentCommentBits.HasTrailingNewline; 
-   } 
- }; 
-   
- /// Plain text. 
- class TextComment : public InlineContentComment { 
-   StringRef Text; 
-   
- public: 
-   TextComment(SourceLocation LocBegin, 
-               SourceLocation LocEnd, 
-               StringRef Text) : 
-       InlineContentComment(TextCommentKind, LocBegin, LocEnd), 
-       Text(Text) { 
-     TextCommentBits.IsWhitespaceValid = false; 
-   } 
-   
-   static bool classof(const Comment *C) { 
-     return C->getCommentKind() == TextCommentKind; 
-   } 
-   
-   child_iterator child_begin() const { return nullptr; } 
-   
-   child_iterator child_end() const { return nullptr; } 
-   
-   StringRef getText() const LLVM_READONLY { return Text; } 
-   
-   bool isWhitespace() const { 
-     if (TextCommentBits.IsWhitespaceValid) 
-       return TextCommentBits.IsWhitespace; 
-   
-     TextCommentBits.IsWhitespace = isWhitespaceNoCache(); 
-     TextCommentBits.IsWhitespaceValid = true; 
-     return TextCommentBits.IsWhitespace; 
-   } 
-   
- private: 
-   bool isWhitespaceNoCache() const; 
- }; 
-   
- /// A command with word-like arguments that is considered inline content. 
- class InlineCommandComment : public InlineContentComment { 
- public: 
-   /// The most appropriate rendering mode for this command, chosen on command 
-   /// semantics in Doxygen. 
-   enum RenderKind { 
-     RenderNormal, 
-     RenderBold, 
-     RenderMonospaced, 
-     RenderEmphasized, 
-     RenderAnchor 
-   }; 
-   
- protected: 
-   /// Command arguments. 
-   ArrayRef<Argument> Args; 
-   
- public: 
-   InlineCommandComment(SourceLocation LocBegin, 
-                        SourceLocation LocEnd, 
-                        unsigned CommandID, 
-                        RenderKind RK, 
-                        ArrayRef<Argument> Args) : 
-       InlineContentComment(InlineCommandCommentKind, LocBegin, LocEnd), 
-       Args(Args) { 
-     InlineCommandCommentBits.RenderKind = RK; 
-     InlineCommandCommentBits.CommandID = CommandID; 
-   } 
-   
-   static bool classof(const Comment *C) { 
-     return C->getCommentKind() == InlineCommandCommentKind; 
-   } 
-   
-   child_iterator child_begin() const { return nullptr; } 
-   
-   child_iterator child_end() const { return nullptr; } 
-   
-   unsigned getCommandID() const { 
-     return InlineCommandCommentBits.CommandID; 
-   } 
-   
-   StringRef getCommandName(const CommandTraits &Traits) const { 
-     return Traits.getCommandInfo(getCommandID())->Name; 
-   } 
-   
-   SourceRange getCommandNameRange() const { 
-     return SourceRange(getBeginLoc().getLocWithOffset(-1), getEndLoc()); 
-   } 
-   
-   RenderKind getRenderKind() const { 
-     return static_cast<RenderKind>(InlineCommandCommentBits.RenderKind); 
-   } 
-   
-   unsigned getNumArgs() const { 
-     return Args.size(); 
-   } 
-   
-   StringRef getArgText(unsigned Idx) const { 
-     return Args[Idx].Text; 
-   } 
-   
-   SourceRange getArgRange(unsigned Idx) const { 
-     return Args[Idx].Range; 
-   } 
- }; 
-   
- /// Abstract class for opening and closing HTML tags.  HTML tags are always 
- /// treated as inline content (regardless HTML semantics). 
- class HTMLTagComment : public InlineContentComment { 
- protected: 
-   StringRef TagName; 
-   SourceRange TagNameRange; 
-   
-   HTMLTagComment(CommentKind K, 
-                  SourceLocation LocBegin, 
-                  SourceLocation LocEnd, 
-                  StringRef TagName, 
-                  SourceLocation TagNameBegin, 
-                  SourceLocation TagNameEnd) : 
-       InlineContentComment(K, LocBegin, LocEnd), 
-       TagName(TagName), 
-       TagNameRange(TagNameBegin, TagNameEnd) { 
-     setLocation(TagNameBegin); 
-     HTMLTagCommentBits.IsMalformed = 0; 
-   } 
-   
- public: 
-   static bool classof(const Comment *C) { 
-     return C->getCommentKind() >= FirstHTMLTagCommentConstant && 
-            C->getCommentKind() <= LastHTMLTagCommentConstant; 
-   } 
-   
-   StringRef getTagName() const LLVM_READONLY { return TagName; } 
-   
-   SourceRange getTagNameSourceRange() const LLVM_READONLY { 
-     SourceLocation L = getLocation(); 
-     return SourceRange(L.getLocWithOffset(1), 
-                        L.getLocWithOffset(1 + TagName.size())); 
-   } 
-   
-   bool isMalformed() const { 
-     return HTMLTagCommentBits.IsMalformed; 
-   } 
-   
-   void setIsMalformed() { 
-     HTMLTagCommentBits.IsMalformed = 1; 
-   } 
- }; 
-   
- /// An opening HTML tag with attributes. 
- class HTMLStartTagComment : public HTMLTagComment { 
- public: 
-   class Attribute { 
-   public: 
-     SourceLocation NameLocBegin; 
-     StringRef Name; 
-   
-     SourceLocation EqualsLoc; 
-   
-     SourceRange ValueRange; 
-     StringRef Value; 
-   
-     Attribute() { } 
-   
-     Attribute(SourceLocation NameLocBegin, StringRef Name) 
-         : NameLocBegin(NameLocBegin), Name(Name), EqualsLoc(SourceLocation()) {} 
-   
-     Attribute(SourceLocation NameLocBegin, StringRef Name, 
-               SourceLocation EqualsLoc, SourceRange ValueRange, StringRef Value) 
-         : NameLocBegin(NameLocBegin), Name(Name), EqualsLoc(EqualsLoc), 
-           ValueRange(ValueRange), Value(Value) {} 
-   
-     SourceLocation getNameLocEnd() const { 
-       return NameLocBegin.getLocWithOffset(Name.size()); 
-     } 
-   
-     SourceRange getNameRange() const { 
-       return SourceRange(NameLocBegin, getNameLocEnd()); 
-     } 
-   }; 
-   
- private: 
-   ArrayRef<Attribute> Attributes; 
-   
- public: 
-   HTMLStartTagComment(SourceLocation LocBegin, 
-                       StringRef TagName) : 
-       HTMLTagComment(HTMLStartTagCommentKind, 
-                      LocBegin, LocBegin.getLocWithOffset(1 + TagName.size()), 
-                      TagName, 
-                      LocBegin.getLocWithOffset(1), 
-                      LocBegin.getLocWithOffset(1 + TagName.size())) { 
-     HTMLStartTagCommentBits.IsSelfClosing = false; 
-   } 
-   
-   static bool classof(const Comment *C) { 
-     return C->getCommentKind() == HTMLStartTagCommentKind; 
-   } 
-   
-   child_iterator child_begin() const { return nullptr; } 
-   
-   child_iterator child_end() const { return nullptr; } 
-   
-   unsigned getNumAttrs() const { 
-     return Attributes.size(); 
-   } 
-   
-   const Attribute &getAttr(unsigned Idx) const { 
-     return Attributes[Idx]; 
-   } 
-   
-   void setAttrs(ArrayRef<Attribute> Attrs) { 
-     Attributes = Attrs; 
-     if (!Attrs.empty()) { 
-       const Attribute &Attr = Attrs.back(); 
-       SourceLocation L = Attr.ValueRange.getEnd(); 
-       if (L.isValid()) 
-         Range.setEnd(L); 
-       else { 
-         Range.setEnd(Attr.getNameLocEnd()); 
-       } 
-     } 
-   } 
-   
-   void setGreaterLoc(SourceLocation GreaterLoc) { 
-     Range.setEnd(GreaterLoc); 
-   } 
-   
-   bool isSelfClosing() const { 
-     return HTMLStartTagCommentBits.IsSelfClosing; 
-   } 
-   
-   void setSelfClosing() { 
-     HTMLStartTagCommentBits.IsSelfClosing = true; 
-   } 
- }; 
-   
- /// A closing HTML tag. 
- class HTMLEndTagComment : public HTMLTagComment { 
- public: 
-   HTMLEndTagComment(SourceLocation LocBegin, 
-                     SourceLocation LocEnd, 
-                     StringRef TagName) : 
-       HTMLTagComment(HTMLEndTagCommentKind, 
-                      LocBegin, LocEnd, 
-                      TagName, 
-                      LocBegin.getLocWithOffset(2), 
-                      LocBegin.getLocWithOffset(2 + TagName.size())) 
-   { } 
-   
-   static bool classof(const Comment *C) { 
-     return C->getCommentKind() == HTMLEndTagCommentKind; 
-   } 
-   
-   child_iterator child_begin() const { return nullptr; } 
-   
-   child_iterator child_end() const { return nullptr; } 
- }; 
-   
- /// Block content (contains inline content). 
- /// Abstract class. 
- class BlockContentComment : public Comment { 
- protected: 
-   BlockContentComment(CommentKind K, 
-                       SourceLocation LocBegin, 
-                       SourceLocation LocEnd) : 
-       Comment(K, LocBegin, LocEnd) 
-   { } 
-   
- public: 
-   static bool classof(const Comment *C) { 
-     return C->getCommentKind() >= FirstBlockContentCommentConstant && 
-            C->getCommentKind() <= LastBlockContentCommentConstant; 
-   } 
- }; 
-   
- /// A single paragraph that contains inline content. 
- class ParagraphComment : public BlockContentComment { 
-   ArrayRef<InlineContentComment *> Content; 
-   
- public: 
-   ParagraphComment(ArrayRef<InlineContentComment *> Content) : 
-       BlockContentComment(ParagraphCommentKind, 
-                           SourceLocation(), 
-                           SourceLocation()), 
-       Content(Content) { 
-     if (Content.empty()) { 
-       ParagraphCommentBits.IsWhitespace = true; 
-       ParagraphCommentBits.IsWhitespaceValid = true; 
-       return; 
-     } 
-   
-     ParagraphCommentBits.IsWhitespaceValid = false; 
-   
-     setSourceRange(SourceRange(Content.front()->getBeginLoc(), 
-                                Content.back()->getEndLoc())); 
-     setLocation(Content.front()->getBeginLoc()); 
-   } 
-   
-   static bool classof(const Comment *C) { 
-     return C->getCommentKind() == ParagraphCommentKind; 
-   } 
-   
-   child_iterator child_begin() const { 
-     return reinterpret_cast<child_iterator>(Content.begin()); 
-   } 
-   
-   child_iterator child_end() const { 
-     return reinterpret_cast<child_iterator>(Content.end()); 
-   } 
-   
-   bool isWhitespace() const { 
-     if (ParagraphCommentBits.IsWhitespaceValid) 
-       return ParagraphCommentBits.IsWhitespace; 
-   
-     ParagraphCommentBits.IsWhitespace = isWhitespaceNoCache(); 
-     ParagraphCommentBits.IsWhitespaceValid = true; 
-     return ParagraphCommentBits.IsWhitespace; 
-   } 
-   
- private: 
-   bool isWhitespaceNoCache() const; 
- }; 
-   
- /// A command that has zero or more word-like arguments (number of word-like 
- /// arguments depends on command name) and a paragraph as an argument 
- /// (e. g., \\brief). 
- class BlockCommandComment : public BlockContentComment { 
- protected: 
-   /// Word-like arguments. 
-   ArrayRef<Argument> Args; 
-   
-   /// Paragraph argument. 
-   ParagraphComment *Paragraph; 
-   
-   BlockCommandComment(CommentKind K, 
-                       SourceLocation LocBegin, 
-                       SourceLocation LocEnd, 
-                       unsigned CommandID, 
-                       CommandMarkerKind CommandMarker) : 
-       BlockContentComment(K, LocBegin, LocEnd), 
-       Paragraph(nullptr) { 
-     setLocation(getCommandNameBeginLoc()); 
-     BlockCommandCommentBits.CommandID = CommandID; 
-     BlockCommandCommentBits.CommandMarker = CommandMarker; 
-   } 
-   
- public: 
-   BlockCommandComment(SourceLocation LocBegin, 
-                       SourceLocation LocEnd, 
-                       unsigned CommandID, 
-                       CommandMarkerKind CommandMarker) : 
-       BlockContentComment(BlockCommandCommentKind, LocBegin, LocEnd), 
-       Paragraph(nullptr) { 
-     setLocation(getCommandNameBeginLoc()); 
-     BlockCommandCommentBits.CommandID = CommandID; 
-     BlockCommandCommentBits.CommandMarker = CommandMarker; 
-   } 
-   
-   static bool classof(const Comment *C) { 
-     return C->getCommentKind() >= FirstBlockCommandCommentConstant && 
-            C->getCommentKind() <= LastBlockCommandCommentConstant; 
-   } 
-   
-   child_iterator child_begin() const { 
-     return reinterpret_cast<child_iterator>(&Paragraph); 
-   } 
-   
-   child_iterator child_end() const { 
-     return reinterpret_cast<child_iterator>(&Paragraph + 1); 
-   } 
-   
-   unsigned getCommandID() const { 
-     return BlockCommandCommentBits.CommandID; 
-   } 
-   
-   StringRef getCommandName(const CommandTraits &Traits) const { 
-     return Traits.getCommandInfo(getCommandID())->Name; 
-   } 
-   
-   SourceLocation getCommandNameBeginLoc() const { 
-     return getBeginLoc().getLocWithOffset(1); 
-   } 
-   
-   SourceRange getCommandNameRange(const CommandTraits &Traits) const { 
-     StringRef Name = getCommandName(Traits); 
-     return SourceRange(getCommandNameBeginLoc(), 
-                        getBeginLoc().getLocWithOffset(1 + Name.size())); 
-   } 
-   
-   unsigned getNumArgs() const { 
-     return Args.size(); 
-   } 
-   
-   StringRef getArgText(unsigned Idx) const { 
-     return Args[Idx].Text; 
-   } 
-   
-   SourceRange getArgRange(unsigned Idx) const { 
-     return Args[Idx].Range; 
-   } 
-   
-   void setArgs(ArrayRef<Argument> A) { 
-     Args = A; 
-     if (Args.size() > 0) { 
-       SourceLocation NewLocEnd = Args.back().Range.getEnd(); 
-       if (NewLocEnd.isValid()) 
-         setSourceRange(SourceRange(getBeginLoc(), NewLocEnd)); 
-     } 
-   } 
-   
-   ParagraphComment *getParagraph() const LLVM_READONLY { 
-     return Paragraph; 
-   } 
-   
-   bool hasNonWhitespaceParagraph() const { 
-     return Paragraph && !Paragraph->isWhitespace(); 
-   } 
-   
-   void setParagraph(ParagraphComment *PC) { 
-     Paragraph = PC; 
-     SourceLocation NewLocEnd = PC->getEndLoc(); 
-     if (NewLocEnd.isValid()) 
-       setSourceRange(SourceRange(getBeginLoc(), NewLocEnd)); 
-   } 
-   
-   CommandMarkerKind getCommandMarker() const LLVM_READONLY { 
-     return static_cast<CommandMarkerKind>( 
-         BlockCommandCommentBits.CommandMarker); 
-   } 
- }; 
-   
- /// Doxygen \\param command. 
- class ParamCommandComment : public BlockCommandComment { 
- private: 
-   /// Parameter index in the function declaration. 
-   unsigned ParamIndex; 
-   
- public: 
-   enum : unsigned { 
-     InvalidParamIndex = ~0U, 
-     VarArgParamIndex = ~0U/*InvalidParamIndex*/ - 1U 
-   }; 
-   
-   ParamCommandComment(SourceLocation LocBegin, 
-                       SourceLocation LocEnd, 
-                       unsigned CommandID, 
-                       CommandMarkerKind CommandMarker) : 
-       BlockCommandComment(ParamCommandCommentKind, LocBegin, LocEnd, 
-                           CommandID, CommandMarker), 
-       ParamIndex(InvalidParamIndex) { 
-     ParamCommandCommentBits.Direction = In; 
-     ParamCommandCommentBits.IsDirectionExplicit = false; 
-   } 
-   
-   static bool classof(const Comment *C) { 
-     return C->getCommentKind() == ParamCommandCommentKind; 
-   } 
-   
-   enum PassDirection { 
-     In, 
-     Out, 
-     InOut 
-   }; 
-   
-   static const char *getDirectionAsString(PassDirection D); 
-   
-   PassDirection getDirection() const LLVM_READONLY { 
-     return static_cast<PassDirection>(ParamCommandCommentBits.Direction); 
-   } 
-   
-   bool isDirectionExplicit() const LLVM_READONLY { 
-     return ParamCommandCommentBits.IsDirectionExplicit; 
-   } 
-   
-   void setDirection(PassDirection Direction, bool Explicit) { 
-     ParamCommandCommentBits.Direction = Direction; 
-     ParamCommandCommentBits.IsDirectionExplicit = Explicit; 
-   } 
-   
-   bool hasParamName() const { 
-     return getNumArgs() > 0; 
-   } 
-   
-   StringRef getParamName(const FullComment *FC) const; 
-   
-   StringRef getParamNameAsWritten() const { 
-     return Args[0].Text; 
-   } 
-   
-   SourceRange getParamNameRange() const { 
-     return Args[0].Range; 
-   } 
-   
-   bool isParamIndexValid() const LLVM_READONLY { 
-     return ParamIndex != InvalidParamIndex; 
-   } 
-   
-   bool isVarArgParam() const LLVM_READONLY { 
-     return ParamIndex == VarArgParamIndex; 
-   } 
-   
-   void setIsVarArgParam() { 
-     ParamIndex = VarArgParamIndex; 
-     assert(isParamIndexValid()); 
-   } 
-   
-   unsigned getParamIndex() const LLVM_READONLY { 
-     assert(isParamIndexValid()); 
-     assert(!isVarArgParam()); 
-     return ParamIndex; 
-   } 
-   
-   void setParamIndex(unsigned Index) { 
-     ParamIndex = Index; 
-     assert(isParamIndexValid()); 
-     assert(!isVarArgParam()); 
-   } 
- }; 
-   
- /// Doxygen \\tparam command, describes a template parameter. 
- class TParamCommandComment : public BlockCommandComment { 
- private: 
-   /// If this template parameter name was resolved (found in template parameter 
-   /// list), then this stores a list of position indexes in all template 
-   /// parameter lists. 
-   /// 
-   /// For example: 
-   /// \verbatim 
-   ///     template<typename C, template<typename T> class TT> 
-   ///     void test(TT<int> aaa); 
-   /// \endverbatim 
-   /// For C:  Position = { 0 } 
-   /// For TT: Position = { 1 } 
-   /// For T:  Position = { 1, 0 } 
-   ArrayRef<unsigned> Position; 
-   
- public: 
-   TParamCommandComment(SourceLocation LocBegin, 
-                        SourceLocation LocEnd, 
-                        unsigned CommandID, 
-                        CommandMarkerKind CommandMarker) : 
-       BlockCommandComment(TParamCommandCommentKind, LocBegin, LocEnd, CommandID, 
-                           CommandMarker) 
-   { } 
-   
-   static bool classof(const Comment *C) { 
-     return C->getCommentKind() == TParamCommandCommentKind; 
-   } 
-   
-   bool hasParamName() const { 
-     return getNumArgs() > 0; 
-   } 
-   
-   StringRef getParamName(const FullComment *FC) const; 
-   
-   StringRef getParamNameAsWritten() const { 
-     return Args[0].Text; 
-   } 
-   
-   SourceRange getParamNameRange() const { 
-     return Args[0].Range; 
-   } 
-   
-   bool isPositionValid() const LLVM_READONLY { 
-     return !Position.empty(); 
-   } 
-   
-   unsigned getDepth() const { 
-     assert(isPositionValid()); 
-     return Position.size(); 
-   } 
-   
-   unsigned getIndex(unsigned Depth) const { 
-     assert(isPositionValid()); 
-     return Position[Depth]; 
-   } 
-   
-   void setPosition(ArrayRef<unsigned> NewPosition) { 
-     Position = NewPosition; 
-     assert(isPositionValid()); 
-   } 
- }; 
-   
- /// A line of text contained in a verbatim block. 
- class VerbatimBlockLineComment : public Comment { 
-   StringRef Text; 
-   
- public: 
-   VerbatimBlockLineComment(SourceLocation LocBegin, 
-                            StringRef Text) : 
-       Comment(VerbatimBlockLineCommentKind, 
-               LocBegin, 
-               LocBegin.getLocWithOffset(Text.size())), 
-       Text(Text) 
-   { } 
-   
-   static bool classof(const Comment *C) { 
-     return C->getCommentKind() == VerbatimBlockLineCommentKind; 
-   } 
-   
-   child_iterator child_begin() const { return nullptr; } 
-   
-   child_iterator child_end() const { return nullptr; } 
-   
-   StringRef getText() const LLVM_READONLY { 
-     return Text; 
-   } 
- }; 
-   
- /// A verbatim block command (e. g., preformatted code).  Verbatim block has an 
- /// opening and a closing command and contains multiple lines of text 
- /// (VerbatimBlockLineComment nodes). 
- class VerbatimBlockComment : public BlockCommandComment { 
- protected: 
-   StringRef CloseName; 
-   SourceLocation CloseNameLocBegin; 
-   ArrayRef<VerbatimBlockLineComment *> Lines; 
-   
- public: 
-   VerbatimBlockComment(SourceLocation LocBegin, 
-                        SourceLocation LocEnd, 
-                        unsigned CommandID) : 
-       BlockCommandComment(VerbatimBlockCommentKind, 
-                           LocBegin, LocEnd, CommandID, 
-                           CMK_At) // FIXME: improve source fidelity. 
-   { } 
-   
-   static bool classof(const Comment *C) { 
-     return C->getCommentKind() == VerbatimBlockCommentKind; 
-   } 
-   
-   child_iterator child_begin() const { 
-     return reinterpret_cast<child_iterator>(Lines.begin()); 
-   } 
-   
-   child_iterator child_end() const { 
-     return reinterpret_cast<child_iterator>(Lines.end()); 
-   } 
-   
-   void setCloseName(StringRef Name, SourceLocation LocBegin) { 
-     CloseName = Name; 
-     CloseNameLocBegin = LocBegin; 
-   } 
-   
-   void setLines(ArrayRef<VerbatimBlockLineComment *> L) { 
-     Lines = L; 
-   } 
-   
-   StringRef getCloseName() const { 
-     return CloseName; 
-   } 
-   
-   unsigned getNumLines() const { 
-     return Lines.size(); 
-   } 
-   
-   StringRef getText(unsigned LineIdx) const { 
-     return Lines[LineIdx]->getText(); 
-   } 
- }; 
-   
- /// A verbatim line command.  Verbatim line has an opening command, a single 
- /// line of text (up to the newline after the opening command) and has no 
- /// closing command. 
- class VerbatimLineComment : public BlockCommandComment { 
- protected: 
-   StringRef Text; 
-   SourceLocation TextBegin; 
-   
- public: 
-   VerbatimLineComment(SourceLocation LocBegin, 
-                       SourceLocation LocEnd, 
-                       unsigned CommandID, 
-                       SourceLocation TextBegin, 
-                       StringRef Text) : 
-       BlockCommandComment(VerbatimLineCommentKind, 
-                           LocBegin, LocEnd, 
-                           CommandID, 
-                           CMK_At), // FIXME: improve source fidelity. 
-       Text(Text), 
-       TextBegin(TextBegin) 
-   { } 
-   
-   static bool classof(const Comment *C) { 
-     return C->getCommentKind() == VerbatimLineCommentKind; 
-   } 
-   
-   child_iterator child_begin() const { return nullptr; } 
-   
-   child_iterator child_end() const { return nullptr; } 
-   
-   StringRef getText() const { 
-     return Text; 
-   } 
-   
-   SourceRange getTextRange() const { 
-     return SourceRange(TextBegin, getEndLoc()); 
-   } 
- }; 
-   
- /// Information about the declaration, useful to clients of FullComment. 
- struct DeclInfo { 
-   /// Declaration the comment is actually attached to (in the source). 
-   /// Should not be NULL. 
-   const Decl *CommentDecl; 
-   
-   /// CurrentDecl is the declaration with which the FullComment is associated. 
-   /// 
-   /// It can be different from \c CommentDecl.  It happens when we decide 
-   /// that the comment originally attached to \c CommentDecl is fine for 
-   /// \c CurrentDecl too (for example, for a redeclaration or an overrider of 
-   /// \c CommentDecl). 
-   /// 
-   /// The information in the DeclInfo corresponds to CurrentDecl. 
-   const Decl *CurrentDecl; 
-   
-   /// Parameters that can be referenced by \\param if \c CommentDecl is something 
-   /// that we consider a "function". 
-   ArrayRef<const ParmVarDecl *> ParamVars; 
-   
-   /// Function return type if \c CommentDecl is something that we consider 
-   /// a "function". 
-   QualType ReturnType; 
-   
-   /// Template parameters that can be referenced by \\tparam if \c CommentDecl is 
-   /// a template (\c IsTemplateDecl or \c IsTemplatePartialSpecialization is 
-   /// true). 
-   const TemplateParameterList *TemplateParameters; 
-   
-   /// A simplified description of \c CommentDecl kind that should be good enough 
-   /// for documentation rendering purposes. 
-   enum DeclKind { 
-     /// Everything else not explicitly mentioned below. 
-     OtherKind, 
-   
-     /// Something that we consider a "function": 
-     /// \li function, 
-     /// \li function template, 
-     /// \li function template specialization, 
-     /// \li member function, 
-     /// \li member function template, 
-     /// \li member function template specialization, 
-     /// \li ObjC method, 
-     FunctionKind, 
-   
-     /// Something that we consider a "class": 
-     /// \li class/struct, 
-     /// \li class template, 
-     /// \li class template (partial) specialization. 
-     ClassKind, 
-   
-     /// Something that we consider a "variable": 
-     /// \li namespace scope variables and variable templates; 
-     /// \li static and non-static class data members and member templates; 
-     /// \li enumerators. 
-     VariableKind, 
-   
-     /// A C++ namespace. 
-     NamespaceKind, 
-   
-     /// A C++ typedef-name (a 'typedef' decl specifier or alias-declaration), 
-     /// see \c TypedefNameDecl. 
-     TypedefKind, 
-   
-     /// An enumeration or scoped enumeration. 
-     EnumKind 
-   }; 
-   
-   /// What kind of template specialization \c CommentDecl is. 
-   enum TemplateDeclKind { 
-     NotTemplate, 
-     Template, 
-     TemplateSpecialization, 
-     TemplatePartialSpecialization 
-   }; 
-   
-   /// If false, only \c CommentDecl is valid. 
-   unsigned IsFilled : 1; 
-   
-   /// Simplified kind of \c CommentDecl, see \c DeclKind enum. 
-   unsigned Kind : 3; 
-   
-   /// Is \c CommentDecl a template declaration. 
-   unsigned TemplateKind : 2; 
-   
-   /// Is \c CommentDecl an ObjCMethodDecl. 
-   unsigned IsObjCMethod : 1; 
-   
-   /// Is \c CommentDecl a non-static member function of C++ class or 
-   /// instance method of ObjC class. 
-   /// Can be true only if \c IsFunctionDecl is true. 
-   unsigned IsInstanceMethod : 1; 
-   
-   /// Is \c CommentDecl a static member function of C++ class or 
-   /// class method of ObjC class. 
-   /// Can be true only if \c IsFunctionDecl is true. 
-   unsigned IsClassMethod : 1; 
-   
-   /// Is \c CommentDecl something we consider a "function" that's variadic. 
-   unsigned IsVariadic : 1; 
-   
-   void fill(); 
-   
-   DeclKind getKind() const LLVM_READONLY { 
-     return static_cast<DeclKind>(Kind); 
-   } 
-   
-   TemplateDeclKind getTemplateKind() const LLVM_READONLY { 
-     return static_cast<TemplateDeclKind>(TemplateKind); 
-   } 
-   
-   bool involvesFunctionType() const { return !ReturnType.isNull(); } 
- }; 
-   
- /// A full comment attached to a declaration, contains block content. 
- class FullComment : public Comment { 
-   ArrayRef<BlockContentComment *> Blocks; 
-   DeclInfo *ThisDeclInfo; 
-   
- public: 
-   FullComment(ArrayRef<BlockContentComment *> Blocks, DeclInfo *D) : 
-       Comment(FullCommentKind, SourceLocation(), SourceLocation()), 
-       Blocks(Blocks), ThisDeclInfo(D) { 
-     if (Blocks.empty()) 
-       return; 
-   
-     setSourceRange( 
-         SourceRange(Blocks.front()->getBeginLoc(), Blocks.back()->getEndLoc())); 
-     setLocation(Blocks.front()->getBeginLoc()); 
-   } 
-   
-   static bool classof(const Comment *C) { 
-     return C->getCommentKind() == FullCommentKind; 
-   } 
-   
-   child_iterator child_begin() const { 
-     return reinterpret_cast<child_iterator>(Blocks.begin()); 
-   } 
-   
-   child_iterator child_end() const { 
-     return reinterpret_cast<child_iterator>(Blocks.end()); 
-   } 
-   
-   const Decl *getDecl() const LLVM_READONLY { 
-     return ThisDeclInfo->CommentDecl; 
-   } 
-   
-   const DeclInfo *getDeclInfo() const LLVM_READONLY { 
-     if (!ThisDeclInfo->IsFilled) 
-       ThisDeclInfo->fill(); 
-     return ThisDeclInfo; 
-   } 
-   
-   ArrayRef<BlockContentComment *> getBlocks() const { return Blocks; } 
-   
- }; 
- } // end namespace comments 
- } // end namespace clang 
-   
- #endif 
-   
-