1885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org//===--- Comment.h - Comment AST nodes --------------------------*- C++ -*-===// 2885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org// 3885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org// The LLVM Compiler Infrastructure 4885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org// 5885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org// This file is distributed under the University of Illinois Open Source 6885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org// License. See LICENSE.TXT for details. 7885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org// 8885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org//===----------------------------------------------------------------------===// 9885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org// 10885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org// This file defines comment AST nodes. 11885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org// 12885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org//===----------------------------------------------------------------------===// 13885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 14885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifndef LLVM_CLANG_AST_COMMENT_H 15885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#define LLVM_CLANG_AST_COMMENT_H 16885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 17885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "clang/AST/CommentCommandTraits.h" 18885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "clang/AST/DeclObjC.h" 19885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "clang/AST/Type.h" 20885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "clang/Basic/SourceLocation.h" 21885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "llvm/ADT/ArrayRef.h" 22885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "llvm/ADT/StringRef.h" 23885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 24885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgnamespace clang { 25885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgclass Decl; 26885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgclass ParmVarDecl; 27885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgclass TemplateParameterList; 28885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 29885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgnamespace comments { 30885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgclass FullComment; 31885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 32885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/// Describes the syntax that was used in a documentation command. 33885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/// 34885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/// Exact values of this enumeration are important because they used to select 35885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/// parts of diagnostic messages. Audit diagnostics before changing or adding 36885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/// a new value. 37885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgenum CommandMarkerKind { 38885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /// Command started with a backslash character: 39885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /// \code 40885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /// \foo 41885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /// \endcode 42885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org CMK_Backslash = 0, 43885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 44885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /// Command started with an 'at' character: 45885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /// \code 46885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /// @foo 47885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /// \endcode 48885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org CMK_At = 1 49885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org}; 50885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 51885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/// Any part of the comment. 52885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/// Abstract class. 53885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgclass Comment { 54885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgprotected: 55885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /// Preferred location to show caret. 56885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org SourceLocation Loc; 57885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 58885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /// Source range of this AST node. 59885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org SourceRange Range; 60885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 61885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org class CommentBitfields { 62885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org friend class Comment; 63885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 64885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /// Type of this AST node. 65885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org unsigned Kind : 8; 66885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org }; 67885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org enum { NumCommentBits = 8 }; 68885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 69885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org class InlineContentCommentBitfields { 70885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org friend class InlineContentComment; 71885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 72885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org unsigned : NumCommentBits; 73885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 74885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /// True if there is a newline after this inline content node. 75885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /// (There is no separate AST node for a newline.) 76885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org unsigned HasTrailingNewline : 1; 77885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org }; 78885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org enum { NumInlineContentCommentBits = NumCommentBits + 1 }; 79885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 80885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org class TextCommentBitfields { 81885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org friend class TextComment; 82885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 83885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org unsigned : NumInlineContentCommentBits; 843c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com 853c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com /// True if \c IsWhitespace field contains a valid value. 863c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com mutable unsigned IsWhitespaceValid : 1; 873c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com 883c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com /// True if this comment AST node contains only whitespace. 89885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org mutable unsigned IsWhitespace : 1; 90885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org }; 91885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org enum { NumTextCommentBits = NumInlineContentCommentBits + 2 }; 92885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 93885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org class InlineCommandCommentBitfields { 94885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org friend class InlineCommandComment; 95885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 96885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org unsigned : NumInlineContentCommentBits; 97885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 98885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org unsigned RenderKind : 2; 99885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org unsigned CommandID : 8; 100885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org }; 101885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org enum { NumInlineCommandCommentBits = NumInlineContentCommentBits + 10 }; 102885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 103885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org class HTMLTagCommentBitfields { 104885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org friend class HTMLTagComment; 105885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 106885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org unsigned : NumInlineContentCommentBits; 107885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 108885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /// True if we found that this tag is malformed in some way. 109885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org unsigned IsMalformed : 1; 110885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org }; 111885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org enum { NumHTMLTagCommentBits = NumInlineContentCommentBits + 1 }; 112885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 113885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org class HTMLStartTagCommentBitfields { 114885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org friend class HTMLStartTagComment; 115885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 116885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org unsigned : NumHTMLTagCommentBits; 117885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 118885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /// True if this tag is self-closing (e. g., <br />). This is based on tag 119885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /// spelling in comment (plain <br> would not set this flag). 120885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org unsigned IsSelfClosing : 1; 121885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org }; 122885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org enum { NumHTMLStartTagCommentBits = NumHTMLTagCommentBits + 1 }; 123885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 124885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org class ParagraphCommentBitfields { 125885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org friend class ParagraphComment; 126885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 127885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org unsigned : NumCommentBits; 128885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 129885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /// True if \c IsWhitespace field contains a valid value. 130885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org mutable unsigned IsWhitespaceValid : 1; 131885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 132885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /// True if this comment AST node contains only whitespace. 133885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org mutable unsigned IsWhitespace : 1; 134885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org }; 135885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org enum { NumParagraphCommentBits = NumCommentBits + 2 }; 136885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 137885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org class BlockCommandCommentBitfields { 138885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org friend class BlockCommandComment; 139885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 140885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org unsigned : NumCommentBits; 141885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 142885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org unsigned CommandID : 8; 143885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 144885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /// Describes the syntax that was used in a documentation command. 145885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /// Contains values from CommandMarkerKind enum. 146885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org unsigned CommandMarker : 1; 147885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org }; 148885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org enum { NumBlockCommandCommentBits = NumCommentBits + 9 }; 149885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 150885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org class ParamCommandCommentBitfields { 151885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org friend class ParamCommandComment; 152885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 153885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org unsigned : NumBlockCommandCommentBits; 154885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 155885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /// Parameter passing direction, see ParamCommandComment::PassDirection. 156885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org unsigned Direction : 2; 157885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 158885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org /// True if direction was specified explicitly in the comment. 159885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org unsigned IsDirectionExplicit : 1; 160885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org }; 161885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org enum { NumParamCommandCommentBits = NumBlockCommandCommentBits + 3 }; 162885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 163885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org union { 164885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org CommentBitfields CommentBits; 165885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org InlineContentCommentBitfields InlineContentCommentBits; 166885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org TextCommentBitfields TextCommentBits; 167885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org InlineCommandCommentBitfields InlineCommandCommentBits; 168885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org HTMLTagCommentBitfields HTMLTagCommentBits; 169885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org HTMLStartTagCommentBitfields HTMLStartTagCommentBits; 170885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org ParagraphCommentBitfields ParagraphCommentBits; 171885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org BlockCommandCommentBitfields BlockCommandCommentBits; 172885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org ParamCommandCommentBitfields ParamCommandCommentBits; 173885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org }; 174885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 175885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org void setSourceRange(SourceRange SR) { 176885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Range = SR; 177885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 178885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 179885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org void setLocation(SourceLocation L) { 180885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Loc = L; 181885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 182885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 183885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgpublic: 184885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org enum CommentKind { 185885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org NoCommentKind = 0, 186885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#define COMMENT(CLASS, PARENT) CLASS##Kind, 187885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#define COMMENT_RANGE(BASE, FIRST, LAST) \ 188885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org First##BASE##Constant=FIRST##Kind, Last##BASE##Constant=LAST##Kind, 189885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#define LAST_COMMENT_RANGE(BASE, FIRST, LAST) \ 190885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org First##BASE##Constant=FIRST##Kind, Last##BASE##Constant=LAST##Kind 191885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#define ABSTRACT_COMMENT(COMMENT) 192885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "clang/AST/CommentNodes.inc" 193885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org }; 194885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 195885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Comment(CommentKind K, 196885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org SourceLocation LocBegin, 197885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org SourceLocation LocEnd) : 198885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org Loc(LocBegin), Range(SourceRange(LocBegin, LocEnd)) { 199885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org CommentBits.Kind = K; 200885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 201885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 202885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org CommentKind getCommentKind() const { 203885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org return static_cast<CommentKind>(CommentBits.Kind); 204885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org } 205885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 206885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org const char *getCommentKindName() const; 207885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 208885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org void dump() const; 209885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org void dumpColor() const; 210885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org void dump(const ASTContext &Context) const; 211885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org void dump(raw_ostream &OS, const CommandTraits *Traits, 212885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org const SourceManager *SM) const; 213885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 214885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org SourceRange getSourceRange() const LLVM_READONLY { return Range; } 215885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org 216885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org SourceLocation getLocStart() const LLVM_READONLY { 217885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org return Range.getBegin(); 218 } 219 220 SourceLocation getLocEnd() const LLVM_READONLY { 221 return Range.getEnd(); 222 } 223 224 SourceLocation getLocation() const LLVM_READONLY { return Loc; } 225 226 typedef Comment * const *child_iterator; 227 228 child_iterator child_begin() const; 229 child_iterator child_end() const; 230 231 // TODO: const child iterator 232 233 unsigned child_count() const { 234 return child_end() - child_begin(); 235 } 236}; 237 238/// Inline content (contained within a block). 239/// Abstract class. 240class InlineContentComment : public Comment { 241protected: 242 InlineContentComment(CommentKind K, 243 SourceLocation LocBegin, 244 SourceLocation LocEnd) : 245 Comment(K, LocBegin, LocEnd) { 246 InlineContentCommentBits.HasTrailingNewline = 0; 247 } 248 249public: 250 static bool classof(const Comment *C) { 251 return C->getCommentKind() >= FirstInlineContentCommentConstant && 252 C->getCommentKind() <= LastInlineContentCommentConstant; 253 } 254 255 void addTrailingNewline() { 256 InlineContentCommentBits.HasTrailingNewline = 1; 257 } 258 259 bool hasTrailingNewline() const { 260 return InlineContentCommentBits.HasTrailingNewline; 261 } 262}; 263 264/// Plain text. 265class TextComment : public InlineContentComment { 266 StringRef Text; 267 268public: 269 TextComment(SourceLocation LocBegin, 270 SourceLocation LocEnd, 271 StringRef Text) : 272 InlineContentComment(TextCommentKind, LocBegin, LocEnd), 273 Text(Text) { 274 TextCommentBits.IsWhitespaceValid = false; 275 } 276 277 static bool classof(const Comment *C) { 278 return C->getCommentKind() == TextCommentKind; 279 } 280 281 child_iterator child_begin() const { return nullptr; } 282 283 child_iterator child_end() const { return nullptr; } 284 285 StringRef getText() const LLVM_READONLY { return Text; } 286 287 bool isWhitespace() const { 288 if (TextCommentBits.IsWhitespaceValid) 289 return TextCommentBits.IsWhitespace; 290 291 TextCommentBits.IsWhitespace = isWhitespaceNoCache(); 292 TextCommentBits.IsWhitespaceValid = true; 293 return TextCommentBits.IsWhitespace; 294 } 295 296private: 297 bool isWhitespaceNoCache() const; 298}; 299 300/// A command with word-like arguments that is considered inline content. 301class InlineCommandComment : public InlineContentComment { 302public: 303 struct Argument { 304 SourceRange Range; 305 StringRef Text; 306 307 Argument(SourceRange Range, StringRef Text) : Range(Range), Text(Text) { } 308 }; 309 310 /// The most appropriate rendering mode for this command, chosen on command 311 /// semantics in Doxygen. 312 enum RenderKind { 313 RenderNormal, 314 RenderBold, 315 RenderMonospaced, 316 RenderEmphasized 317 }; 318 319protected: 320 /// Command arguments. 321 ArrayRef<Argument> Args; 322 323public: 324 InlineCommandComment(SourceLocation LocBegin, 325 SourceLocation LocEnd, 326 unsigned CommandID, 327 RenderKind RK, 328 ArrayRef<Argument> Args) : 329 InlineContentComment(InlineCommandCommentKind, LocBegin, LocEnd), 330 Args(Args) { 331 InlineCommandCommentBits.RenderKind = RK; 332 InlineCommandCommentBits.CommandID = CommandID; 333 } 334 335 static bool classof(const Comment *C) { 336 return C->getCommentKind() == InlineCommandCommentKind; 337 } 338 339 child_iterator child_begin() const { return nullptr; } 340 341 child_iterator child_end() const { return nullptr; } 342 343 unsigned getCommandID() const { 344 return InlineCommandCommentBits.CommandID; 345 } 346 347 StringRef getCommandName(const CommandTraits &Traits) const { 348 return Traits.getCommandInfo(getCommandID())->Name; 349 } 350 351 SourceRange getCommandNameRange() const { 352 return SourceRange(getLocStart().getLocWithOffset(-1), 353 getLocEnd()); 354 } 355 356 RenderKind getRenderKind() const { 357 return static_cast<RenderKind>(InlineCommandCommentBits.RenderKind); 358 } 359 360 unsigned getNumArgs() const { 361 return Args.size(); 362 } 363 364 StringRef getArgText(unsigned Idx) const { 365 return Args[Idx].Text; 366 } 367 368 SourceRange getArgRange(unsigned Idx) const { 369 return Args[Idx].Range; 370 } 371}; 372 373/// Abstract class for opening and closing HTML tags. HTML tags are always 374/// treated as inline content (regardless HTML semantics). 375class HTMLTagComment : public InlineContentComment { 376protected: 377 StringRef TagName; 378 SourceRange TagNameRange; 379 380 HTMLTagComment(CommentKind K, 381 SourceLocation LocBegin, 382 SourceLocation LocEnd, 383 StringRef TagName, 384 SourceLocation TagNameBegin, 385 SourceLocation TagNameEnd) : 386 InlineContentComment(K, LocBegin, LocEnd), 387 TagName(TagName), 388 TagNameRange(TagNameBegin, TagNameEnd) { 389 setLocation(TagNameBegin); 390 HTMLTagCommentBits.IsMalformed = 0; 391 } 392 393public: 394 static bool classof(const Comment *C) { 395 return C->getCommentKind() >= FirstHTMLTagCommentConstant && 396 C->getCommentKind() <= LastHTMLTagCommentConstant; 397 } 398 399 StringRef getTagName() const LLVM_READONLY { return TagName; } 400 401 SourceRange getTagNameSourceRange() const LLVM_READONLY { 402 SourceLocation L = getLocation(); 403 return SourceRange(L.getLocWithOffset(1), 404 L.getLocWithOffset(1 + TagName.size())); 405 } 406 407 bool isMalformed() const { 408 return HTMLTagCommentBits.IsMalformed; 409 } 410 411 void setIsMalformed() { 412 HTMLTagCommentBits.IsMalformed = 1; 413 } 414}; 415 416/// An opening HTML tag with attributes. 417class HTMLStartTagComment : public HTMLTagComment { 418public: 419 class Attribute { 420 public: 421 SourceLocation NameLocBegin; 422 StringRef Name; 423 424 SourceLocation EqualsLoc; 425 426 SourceRange ValueRange; 427 StringRef Value; 428 429 Attribute() { } 430 431 Attribute(SourceLocation NameLocBegin, StringRef Name) : 432 NameLocBegin(NameLocBegin), Name(Name), 433 EqualsLoc(SourceLocation()), 434 ValueRange(SourceRange()), Value(StringRef()) 435 { } 436 437 Attribute(SourceLocation NameLocBegin, StringRef Name, 438 SourceLocation EqualsLoc, 439 SourceRange ValueRange, StringRef Value) : 440 NameLocBegin(NameLocBegin), Name(Name), 441 EqualsLoc(EqualsLoc), 442 ValueRange(ValueRange), Value(Value) 443 { } 444 445 SourceLocation getNameLocEnd() const { 446 return NameLocBegin.getLocWithOffset(Name.size()); 447 } 448 449 SourceRange getNameRange() const { 450 return SourceRange(NameLocBegin, getNameLocEnd()); 451 } 452 }; 453 454private: 455 ArrayRef<Attribute> Attributes; 456 457public: 458 HTMLStartTagComment(SourceLocation LocBegin, 459 StringRef TagName) : 460 HTMLTagComment(HTMLStartTagCommentKind, 461 LocBegin, LocBegin.getLocWithOffset(1 + TagName.size()), 462 TagName, 463 LocBegin.getLocWithOffset(1), 464 LocBegin.getLocWithOffset(1 + TagName.size())) { 465 HTMLStartTagCommentBits.IsSelfClosing = false; 466 } 467 468 static bool classof(const Comment *C) { 469 return C->getCommentKind() == HTMLStartTagCommentKind; 470 } 471 472 child_iterator child_begin() const { return nullptr; } 473 474 child_iterator child_end() const { return nullptr; } 475 476 unsigned getNumAttrs() const { 477 return Attributes.size(); 478 } 479 480 const Attribute &getAttr(unsigned Idx) const { 481 return Attributes[Idx]; 482 } 483 484 void setAttrs(ArrayRef<Attribute> Attrs) { 485 Attributes = Attrs; 486 if (!Attrs.empty()) { 487 const Attribute &Attr = Attrs.back(); 488 SourceLocation L = Attr.ValueRange.getEnd(); 489 if (L.isValid()) 490 Range.setEnd(L); 491 else { 492 Range.setEnd(Attr.getNameLocEnd()); 493 } 494 } 495 } 496 497 void setGreaterLoc(SourceLocation GreaterLoc) { 498 Range.setEnd(GreaterLoc); 499 } 500 501 bool isSelfClosing() const { 502 return HTMLStartTagCommentBits.IsSelfClosing; 503 } 504 505 void setSelfClosing() { 506 HTMLStartTagCommentBits.IsSelfClosing = true; 507 } 508}; 509 510/// A closing HTML tag. 511class HTMLEndTagComment : public HTMLTagComment { 512public: 513 HTMLEndTagComment(SourceLocation LocBegin, 514 SourceLocation LocEnd, 515 StringRef TagName) : 516 HTMLTagComment(HTMLEndTagCommentKind, 517 LocBegin, LocEnd, 518 TagName, 519 LocBegin.getLocWithOffset(2), 520 LocBegin.getLocWithOffset(2 + TagName.size())) 521 { } 522 523 static bool classof(const Comment *C) { 524 return C->getCommentKind() == HTMLEndTagCommentKind; 525 } 526 527 child_iterator child_begin() const { return nullptr; } 528 529 child_iterator child_end() const { return nullptr; } 530}; 531 532/// Block content (contains inline content). 533/// Abstract class. 534class BlockContentComment : public Comment { 535protected: 536 BlockContentComment(CommentKind K, 537 SourceLocation LocBegin, 538 SourceLocation LocEnd) : 539 Comment(K, LocBegin, LocEnd) 540 { } 541 542public: 543 static bool classof(const Comment *C) { 544 return C->getCommentKind() >= FirstBlockContentCommentConstant && 545 C->getCommentKind() <= LastBlockContentCommentConstant; 546 } 547}; 548 549/// A single paragraph that contains inline content. 550class ParagraphComment : public BlockContentComment { 551 ArrayRef<InlineContentComment *> Content; 552 553public: 554 ParagraphComment(ArrayRef<InlineContentComment *> Content) : 555 BlockContentComment(ParagraphCommentKind, 556 SourceLocation(), 557 SourceLocation()), 558 Content(Content) { 559 if (Content.empty()) { 560 ParagraphCommentBits.IsWhitespace = true; 561 ParagraphCommentBits.IsWhitespaceValid = true; 562 return; 563 } 564 565 ParagraphCommentBits.IsWhitespaceValid = false; 566 567 setSourceRange(SourceRange(Content.front()->getLocStart(), 568 Content.back()->getLocEnd())); 569 setLocation(Content.front()->getLocStart()); 570 } 571 572 static bool classof(const Comment *C) { 573 return C->getCommentKind() == ParagraphCommentKind; 574 } 575 576 child_iterator child_begin() const { 577 return reinterpret_cast<child_iterator>(Content.begin()); 578 } 579 580 child_iterator child_end() const { 581 return reinterpret_cast<child_iterator>(Content.end()); 582 } 583 584 bool isWhitespace() const { 585 if (ParagraphCommentBits.IsWhitespaceValid) 586 return ParagraphCommentBits.IsWhitespace; 587 588 ParagraphCommentBits.IsWhitespace = isWhitespaceNoCache(); 589 ParagraphCommentBits.IsWhitespaceValid = true; 590 return ParagraphCommentBits.IsWhitespace; 591 } 592 593private: 594 bool isWhitespaceNoCache() const; 595}; 596 597/// A command that has zero or more word-like arguments (number of word-like 598/// arguments depends on command name) and a paragraph as an argument 599/// (e. g., \\brief). 600class BlockCommandComment : public BlockContentComment { 601public: 602 struct Argument { 603 SourceRange Range; 604 StringRef Text; 605 606 Argument() { } 607 Argument(SourceRange Range, StringRef Text) : Range(Range), Text(Text) { } 608 }; 609 610protected: 611 /// Word-like arguments. 612 ArrayRef<Argument> Args; 613 614 /// Paragraph argument. 615 ParagraphComment *Paragraph; 616 617 BlockCommandComment(CommentKind K, 618 SourceLocation LocBegin, 619 SourceLocation LocEnd, 620 unsigned CommandID, 621 CommandMarkerKind CommandMarker) : 622 BlockContentComment(K, LocBegin, LocEnd), 623 Paragraph(nullptr) { 624 setLocation(getCommandNameBeginLoc()); 625 BlockCommandCommentBits.CommandID = CommandID; 626 BlockCommandCommentBits.CommandMarker = CommandMarker; 627 } 628 629public: 630 BlockCommandComment(SourceLocation LocBegin, 631 SourceLocation LocEnd, 632 unsigned CommandID, 633 CommandMarkerKind CommandMarker) : 634 BlockContentComment(BlockCommandCommentKind, LocBegin, LocEnd), 635 Paragraph(nullptr) { 636 setLocation(getCommandNameBeginLoc()); 637 BlockCommandCommentBits.CommandID = CommandID; 638 BlockCommandCommentBits.CommandMarker = CommandMarker; 639 } 640 641 static bool classof(const Comment *C) { 642 return C->getCommentKind() >= FirstBlockCommandCommentConstant && 643 C->getCommentKind() <= LastBlockCommandCommentConstant; 644 } 645 646 child_iterator child_begin() const { 647 return reinterpret_cast<child_iterator>(&Paragraph); 648 } 649 650 child_iterator child_end() const { 651 return reinterpret_cast<child_iterator>(&Paragraph + 1); 652 } 653 654 unsigned getCommandID() const { 655 return BlockCommandCommentBits.CommandID; 656 } 657 658 StringRef getCommandName(const CommandTraits &Traits) const { 659 return Traits.getCommandInfo(getCommandID())->Name; 660 } 661 662 SourceLocation getCommandNameBeginLoc() const { 663 return getLocStart().getLocWithOffset(1); 664 } 665 666 SourceRange getCommandNameRange(const CommandTraits &Traits) const { 667 StringRef Name = getCommandName(Traits); 668 return SourceRange(getCommandNameBeginLoc(), 669 getLocStart().getLocWithOffset(1 + Name.size())); 670 } 671 672 unsigned getNumArgs() const { 673 return Args.size(); 674 } 675 676 StringRef getArgText(unsigned Idx) const { 677 return Args[Idx].Text; 678 } 679 680 SourceRange getArgRange(unsigned Idx) const { 681 return Args[Idx].Range; 682 } 683 684 void setArgs(ArrayRef<Argument> A) { 685 Args = A; 686 if (Args.size() > 0) { 687 SourceLocation NewLocEnd = Args.back().Range.getEnd(); 688 if (NewLocEnd.isValid()) 689 setSourceRange(SourceRange(getLocStart(), NewLocEnd)); 690 } 691 } 692 693 ParagraphComment *getParagraph() const LLVM_READONLY { 694 return Paragraph; 695 } 696 697 bool hasNonWhitespaceParagraph() const { 698 return Paragraph && !Paragraph->isWhitespace(); 699 } 700 701 void setParagraph(ParagraphComment *PC) { 702 Paragraph = PC; 703 SourceLocation NewLocEnd = PC->getLocEnd(); 704 if (NewLocEnd.isValid()) 705 setSourceRange(SourceRange(getLocStart(), NewLocEnd)); 706 } 707 708 CommandMarkerKind getCommandMarker() const LLVM_READONLY { 709 return static_cast<CommandMarkerKind>( 710 BlockCommandCommentBits.CommandMarker); 711 } 712}; 713 714/// Doxygen \\param command. 715class ParamCommandComment : public BlockCommandComment { 716private: 717 /// Parameter index in the function declaration. 718 unsigned ParamIndex; 719 720public: 721 enum : unsigned { 722 InvalidParamIndex = ~0U, 723 VarArgParamIndex = ~0U/*InvalidParamIndex*/ - 1U 724 }; 725 726 ParamCommandComment(SourceLocation LocBegin, 727 SourceLocation LocEnd, 728 unsigned CommandID, 729 CommandMarkerKind CommandMarker) : 730 BlockCommandComment(ParamCommandCommentKind, LocBegin, LocEnd, 731 CommandID, CommandMarker), 732 ParamIndex(InvalidParamIndex) { 733 ParamCommandCommentBits.Direction = In; 734 ParamCommandCommentBits.IsDirectionExplicit = false; 735 } 736 737 static bool classof(const Comment *C) { 738 return C->getCommentKind() == ParamCommandCommentKind; 739 } 740 741 enum PassDirection { 742 In, 743 Out, 744 InOut 745 }; 746 747 static const char *getDirectionAsString(PassDirection D); 748 749 PassDirection getDirection() const LLVM_READONLY { 750 return static_cast<PassDirection>(ParamCommandCommentBits.Direction); 751 } 752 753 bool isDirectionExplicit() const LLVM_READONLY { 754 return ParamCommandCommentBits.IsDirectionExplicit; 755 } 756 757 void setDirection(PassDirection Direction, bool Explicit) { 758 ParamCommandCommentBits.Direction = Direction; 759 ParamCommandCommentBits.IsDirectionExplicit = Explicit; 760 } 761 762 bool hasParamName() const { 763 return getNumArgs() > 0; 764 } 765 766 StringRef getParamName(const FullComment *FC) const; 767 768 StringRef getParamNameAsWritten() const { 769 return Args[0].Text; 770 } 771 772 SourceRange getParamNameRange() const { 773 return Args[0].Range; 774 } 775 776 bool isParamIndexValid() const LLVM_READONLY { 777 return ParamIndex != InvalidParamIndex; 778 } 779 780 bool isVarArgParam() const LLVM_READONLY { 781 return ParamIndex == VarArgParamIndex; 782 } 783 784 void setIsVarArgParam() { 785 ParamIndex = VarArgParamIndex; 786 assert(isParamIndexValid()); 787 } 788 789 unsigned getParamIndex() const LLVM_READONLY { 790 assert(isParamIndexValid()); 791 assert(!isVarArgParam()); 792 return ParamIndex; 793 } 794 795 void setParamIndex(unsigned Index) { 796 ParamIndex = Index; 797 assert(isParamIndexValid()); 798 assert(!isVarArgParam()); 799 } 800}; 801 802/// Doxygen \\tparam command, describes a template parameter. 803class TParamCommandComment : public BlockCommandComment { 804private: 805 /// If this template parameter name was resolved (found in template parameter 806 /// list), then this stores a list of position indexes in all template 807 /// parameter lists. 808 /// 809 /// For example: 810 /// \verbatim 811 /// template<typename C, template<typename T> class TT> 812 /// void test(TT<int> aaa); 813 /// \endverbatim 814 /// For C: Position = { 0 } 815 /// For TT: Position = { 1 } 816 /// For T: Position = { 1, 0 } 817 ArrayRef<unsigned> Position; 818 819public: 820 TParamCommandComment(SourceLocation LocBegin, 821 SourceLocation LocEnd, 822 unsigned CommandID, 823 CommandMarkerKind CommandMarker) : 824 BlockCommandComment(TParamCommandCommentKind, LocBegin, LocEnd, CommandID, 825 CommandMarker) 826 { } 827 828 static bool classof(const Comment *C) { 829 return C->getCommentKind() == TParamCommandCommentKind; 830 } 831 832 bool hasParamName() const { 833 return getNumArgs() > 0; 834 } 835 836 StringRef getParamName(const FullComment *FC) const; 837 838 StringRef getParamNameAsWritten() const { 839 return Args[0].Text; 840 } 841 842 SourceRange getParamNameRange() const { 843 return Args[0].Range; 844 } 845 846 bool isPositionValid() const LLVM_READONLY { 847 return !Position.empty(); 848 } 849 850 unsigned getDepth() const { 851 assert(isPositionValid()); 852 return Position.size(); 853 } 854 855 unsigned getIndex(unsigned Depth) const { 856 assert(isPositionValid()); 857 return Position[Depth]; 858 } 859 860 void setPosition(ArrayRef<unsigned> NewPosition) { 861 Position = NewPosition; 862 assert(isPositionValid()); 863 } 864}; 865 866/// A line of text contained in a verbatim block. 867class VerbatimBlockLineComment : public Comment { 868 StringRef Text; 869 870public: 871 VerbatimBlockLineComment(SourceLocation LocBegin, 872 StringRef Text) : 873 Comment(VerbatimBlockLineCommentKind, 874 LocBegin, 875 LocBegin.getLocWithOffset(Text.size())), 876 Text(Text) 877 { } 878 879 static bool classof(const Comment *C) { 880 return C->getCommentKind() == VerbatimBlockLineCommentKind; 881 } 882 883 child_iterator child_begin() const { return nullptr; } 884 885 child_iterator child_end() const { return nullptr; } 886 887 StringRef getText() const LLVM_READONLY { 888 return Text; 889 } 890}; 891 892/// A verbatim block command (e. g., preformatted code). Verbatim block has an 893/// opening and a closing command and contains multiple lines of text 894/// (VerbatimBlockLineComment nodes). 895class VerbatimBlockComment : public BlockCommandComment { 896protected: 897 StringRef CloseName; 898 SourceLocation CloseNameLocBegin; 899 ArrayRef<VerbatimBlockLineComment *> Lines; 900 901public: 902 VerbatimBlockComment(SourceLocation LocBegin, 903 SourceLocation LocEnd, 904 unsigned CommandID) : 905 BlockCommandComment(VerbatimBlockCommentKind, 906 LocBegin, LocEnd, CommandID, 907 CMK_At) // FIXME: improve source fidelity. 908 { } 909 910 static bool classof(const Comment *C) { 911 return C->getCommentKind() == VerbatimBlockCommentKind; 912 } 913 914 child_iterator child_begin() const { 915 return reinterpret_cast<child_iterator>(Lines.begin()); 916 } 917 918 child_iterator child_end() const { 919 return reinterpret_cast<child_iterator>(Lines.end()); 920 } 921 922 void setCloseName(StringRef Name, SourceLocation LocBegin) { 923 CloseName = Name; 924 CloseNameLocBegin = LocBegin; 925 } 926 927 void setLines(ArrayRef<VerbatimBlockLineComment *> L) { 928 Lines = L; 929 } 930 931 StringRef getCloseName() const { 932 return CloseName; 933 } 934 935 unsigned getNumLines() const { 936 return Lines.size(); 937 } 938 939 StringRef getText(unsigned LineIdx) const { 940 return Lines[LineIdx]->getText(); 941 } 942}; 943 944/// A verbatim line command. Verbatim line has an opening command, a single 945/// line of text (up to the newline after the opening command) and has no 946/// closing command. 947class VerbatimLineComment : public BlockCommandComment { 948protected: 949 StringRef Text; 950 SourceLocation TextBegin; 951 952public: 953 VerbatimLineComment(SourceLocation LocBegin, 954 SourceLocation LocEnd, 955 unsigned CommandID, 956 SourceLocation TextBegin, 957 StringRef Text) : 958 BlockCommandComment(VerbatimLineCommentKind, 959 LocBegin, LocEnd, 960 CommandID, 961 CMK_At), // FIXME: improve source fidelity. 962 Text(Text), 963 TextBegin(TextBegin) 964 { } 965 966 static bool classof(const Comment *C) { 967 return C->getCommentKind() == VerbatimLineCommentKind; 968 } 969 970 child_iterator child_begin() const { return nullptr; } 971 972 child_iterator child_end() const { return nullptr; } 973 974 StringRef getText() const { 975 return Text; 976 } 977 978 SourceRange getTextRange() const { 979 return SourceRange(TextBegin, getLocEnd()); 980 } 981}; 982 983/// Information about the declaration, useful to clients of FullComment. 984struct DeclInfo { 985 /// Declaration the comment is actually attached to (in the source). 986 /// Should not be NULL. 987 const Decl *CommentDecl; 988 989 /// CurrentDecl is the declaration with which the FullComment is associated. 990 /// 991 /// It can be different from \c CommentDecl. It happens when we we decide 992 /// that the comment originally attached to \c CommentDecl is fine for 993 /// \c CurrentDecl too (for example, for a redeclaration or an overrider of 994 /// \c CommentDecl). 995 /// 996 /// The information in the DeclInfo corresponds to CurrentDecl. 997 const Decl *CurrentDecl; 998 999 /// Parameters that can be referenced by \\param if \c CommentDecl is something 1000 /// that we consider a "function". 1001 ArrayRef<const ParmVarDecl *> ParamVars; 1002 1003 /// Function return type if \c CommentDecl is something that we consider 1004 /// a "function". 1005 QualType ReturnType; 1006 1007 /// Template parameters that can be referenced by \\tparam if \c CommentDecl is 1008 /// a template (\c IsTemplateDecl or \c IsTemplatePartialSpecialization is 1009 /// true). 1010 const TemplateParameterList *TemplateParameters; 1011 1012 /// A simplified description of \c CommentDecl kind that should be good enough 1013 /// for documentation rendering purposes. 1014 enum DeclKind { 1015 /// Everything else not explicitly mentioned below. 1016 OtherKind, 1017 1018 /// Something that we consider a "function": 1019 /// \li function, 1020 /// \li function template, 1021 /// \li function template specialization, 1022 /// \li member function, 1023 /// \li member function template, 1024 /// \li member function template specialization, 1025 /// \li ObjC method, 1026 /// \li a typedef for a function pointer, member function pointer, 1027 /// ObjC block. 1028 FunctionKind, 1029 1030 /// Something that we consider a "class": 1031 /// \li class/struct, 1032 /// \li class template, 1033 /// \li class template (partial) specialization. 1034 ClassKind, 1035 1036 /// Something that we consider a "variable": 1037 /// \li namespace scope variables; 1038 /// \li static and non-static class data members; 1039 /// \li enumerators. 1040 VariableKind, 1041 1042 /// A C++ namespace. 1043 NamespaceKind, 1044 1045 /// A C++ typedef-name (a 'typedef' decl specifier or alias-declaration), 1046 /// see \c TypedefNameDecl. 1047 TypedefKind, 1048 1049 /// An enumeration or scoped enumeration. 1050 EnumKind 1051 }; 1052 1053 /// What kind of template specialization \c CommentDecl is. 1054 enum TemplateDeclKind { 1055 NotTemplate, 1056 Template, 1057 TemplateSpecialization, 1058 TemplatePartialSpecialization 1059 }; 1060 1061 /// If false, only \c CommentDecl is valid. 1062 unsigned IsFilled : 1; 1063 1064 /// Simplified kind of \c CommentDecl, see \c DeclKind enum. 1065 unsigned Kind : 3; 1066 1067 /// Is \c CommentDecl a template declaration. 1068 unsigned TemplateKind : 2; 1069 1070 /// Is \c CommentDecl an ObjCMethodDecl. 1071 unsigned IsObjCMethod : 1; 1072 1073 /// Is \c CommentDecl a non-static member function of C++ class or 1074 /// instance method of ObjC class. 1075 /// Can be true only if \c IsFunctionDecl is true. 1076 unsigned IsInstanceMethod : 1; 1077 1078 /// Is \c CommentDecl a static member function of C++ class or 1079 /// class method of ObjC class. 1080 /// Can be true only if \c IsFunctionDecl is true. 1081 unsigned IsClassMethod : 1; 1082 1083 void fill(); 1084 1085 DeclKind getKind() const LLVM_READONLY { 1086 return static_cast<DeclKind>(Kind); 1087 } 1088 1089 TemplateDeclKind getTemplateKind() const LLVM_READONLY { 1090 return static_cast<TemplateDeclKind>(TemplateKind); 1091 } 1092}; 1093 1094/// A full comment attached to a declaration, contains block content. 1095class FullComment : public Comment { 1096 ArrayRef<BlockContentComment *> Blocks; 1097 DeclInfo *ThisDeclInfo; 1098 1099public: 1100 FullComment(ArrayRef<BlockContentComment *> Blocks, DeclInfo *D) : 1101 Comment(FullCommentKind, SourceLocation(), SourceLocation()), 1102 Blocks(Blocks), ThisDeclInfo(D) { 1103 if (Blocks.empty()) 1104 return; 1105 1106 setSourceRange(SourceRange(Blocks.front()->getLocStart(), 1107 Blocks.back()->getLocEnd())); 1108 setLocation(Blocks.front()->getLocStart()); 1109 } 1110 1111 static bool classof(const Comment *C) { 1112 return C->getCommentKind() == FullCommentKind; 1113 } 1114 1115 child_iterator child_begin() const { 1116 return reinterpret_cast<child_iterator>(Blocks.begin()); 1117 } 1118 1119 child_iterator child_end() const { 1120 return reinterpret_cast<child_iterator>(Blocks.end()); 1121 } 1122 1123 const Decl *getDecl() const LLVM_READONLY { 1124 return ThisDeclInfo->CommentDecl; 1125 } 1126 1127 const DeclInfo *getDeclInfo() const LLVM_READONLY { 1128 if (!ThisDeclInfo->IsFilled) 1129 ThisDeclInfo->fill(); 1130 return ThisDeclInfo; 1131 } 1132 1133 ArrayRef<BlockContentComment *> getBlocks() const { return Blocks; } 1134 1135}; 1136} // end namespace comments 1137} // end namespace clang 1138 1139#endif 1140 1141