summaryrefslogtreecommitdiff
path: root/clang-r353983/include/clang/AST/Comment.h
diff options
context:
space:
mode:
authorRalf Luther <luther.ralf@gmail.com>2019-03-27 20:23:17 +0000
committerGerrit Code Review <gerrit2@aicp-server-3>2019-03-27 20:23:17 +0000
commit1ce3a9d272e564b22a1333a1e36a3d3ab7cfab01 (patch)
tree391382eadd4fec5bb480f2e8934fa352770221d1 /clang-r353983/include/clang/AST/Comment.h
parentd1d48b140bafaa8a50107292f5fce95562575765 (diff)
parent4f56932d3416ac03f646bc1a611b3135fec2fe08 (diff)
Merge "Update prebuilt Clang to r353983." into p9.0HEADp9.0-backupp9.0
Diffstat (limited to 'clang-r353983/include/clang/AST/Comment.h')
-rw-r--r--clang-r353983/include/clang/AST/Comment.h1136
1 files changed, 1136 insertions, 0 deletions
diff --git a/clang-r353983/include/clang/AST/Comment.h b/clang-r353983/include/clang/AST/Comment.h
new file mode 100644
index 00000000..2c284a27
--- /dev/null
+++ b/clang-r353983/include/clang/AST/Comment.h
@@ -0,0 +1,1136 @@
+//===--- 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 : 2;
+ unsigned CommandID : CommandInfo::NumCommandIDBits;
+ };
+ enum { NumInlineCommandCommentBits = NumInlineContentCommentBits + 2 +
+ 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"
+ };
+
+ 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(const ASTContext &Context) const;
+ void dump(raw_ostream &OS, const CommandTraits *Traits,
+ const SourceManager *SM) 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:
+ struct Argument {
+ SourceRange Range;
+ StringRef Text;
+
+ Argument(SourceRange Range, StringRef Text) : Range(Range), Text(Text) { }
+ };
+
+ /// The most appropriate rendering mode for this command, chosen on command
+ /// semantics in Doxygen.
+ enum RenderKind {
+ RenderNormal,
+ RenderBold,
+ RenderMonospaced,
+ RenderEmphasized
+ };
+
+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()),
+ ValueRange(SourceRange()), Value(StringRef())
+ { }
+
+ 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 {
+public:
+ struct Argument {
+ SourceRange Range;
+ StringRef Text;
+
+ Argument() { }
+ Argument(SourceRange Range, StringRef Text) : Range(Range), Text(Text) { }
+ };
+
+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,
+ /// \li a typedef for a function pointer, member function pointer,
+ /// ObjC block.
+ 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;
+ /// \li static and non-static class data members;
+ /// \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;
+
+ void fill();
+
+ DeclKind getKind() const LLVM_READONLY {
+ return static_cast<DeclKind>(Kind);
+ }
+
+ TemplateDeclKind getTemplateKind() const LLVM_READONLY {
+ return static_cast<TemplateDeclKind>(TemplateKind);
+ }
+};
+
+/// 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
+