/// (There is no separate AST node for a newline.)
unsigned HasTrailingNewline : 1;
};
- enum { NumInlineContentCommentBits = 9 };
+ 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 HTMLStartTagCommentBitfields {
friend class HTMLStartTagComment;
unsigned IsSelfClosing : 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 ParamCommandCommentBitfields {
friend class ParamCommandComment;
union {
CommentBitfields CommentBits;
InlineContentCommentBitfields InlineContentCommentBits;
+ TextCommentBitfields TextCommentBits;
HTMLStartTagCommentBitfields HTMLStartTagCommentBits;
+ ParagraphCommentBitfields ParagraphCommentBits;
ParamCommandCommentBitfields ParamCommandCommentBits;
};
SourceLocation LocEnd,
StringRef Text) :
InlineContentComment(TextCommentKind, LocBegin, LocEnd),
- Text(Text)
- { }
+ Text(Text) {
+ TextCommentBits.IsWhitespaceValid = false;
+ }
static bool classof(const Comment *C) {
return C->getCommentKind() == TextCommentKind;
StringRef getText() const LLVM_READONLY { return Text; }
- bool isWhitespace() const;
+ 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.
SourceLocation(),
SourceLocation()),
Content(Content) {
- if (Content.empty())
+ if (Content.empty()) {
+ ParagraphCommentBits.IsWhitespace = true;
+ ParagraphCommentBits.IsWhitespaceValid = true;
return;
+ }
+
+ ParagraphCommentBits.IsWhitespaceValid = false;
setSourceRange(SourceRange(Content.front()->getLocStart(),
Content.back()->getLocEnd()));
return reinterpret_cast<child_iterator>(Content.end());
}
- bool isWhitespace() const;
+ 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