aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/AST/Comment.h66
-rw-r--r--lib/AST/Comment.cpp4
2 files changed, 62 insertions, 8 deletions
diff --git a/include/clang/AST/Comment.h b/include/clang/AST/Comment.h
index 39753cfbd9..f59b5e504a 100644
--- a/include/clang/AST/Comment.h
+++ b/include/clang/AST/Comment.h
@@ -48,7 +48,20 @@ protected:
/// (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;
@@ -60,6 +73,19 @@ protected:
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;
@@ -76,7 +102,9 @@ protected:
union {
CommentBitfields CommentBits;
InlineContentCommentBitfields InlineContentCommentBits;
+ TextCommentBitfields TextCommentBits;
HTMLStartTagCommentBitfields HTMLStartTagCommentBits;
+ ParagraphCommentBitfields ParagraphCommentBits;
ParamCommandCommentBitfields ParamCommandCommentBits;
};
@@ -180,8 +208,9 @@ public:
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;
@@ -195,7 +224,17 @@ public:
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.
@@ -442,8 +481,13 @@ public:
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()));
@@ -464,7 +508,17 @@ public:
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
diff --git a/lib/AST/Comment.cpp b/lib/AST/Comment.cpp
index e215e63dec..f3f4d9bf16 100644
--- a/lib/AST/Comment.cpp
+++ b/lib/AST/Comment.cpp
@@ -100,7 +100,7 @@ Comment::child_iterator Comment::child_end() const {
llvm_unreachable("Unknown comment kind!");
}
-bool TextComment::isWhitespace() const {
+bool TextComment::isWhitespaceNoCache() const {
for (StringRef::const_iterator I = Text.begin(), E = Text.end();
I != E; ++I) {
const char C = *I;
@@ -111,7 +111,7 @@ bool TextComment::isWhitespace() const {
return true;
}
-bool ParagraphComment::isWhitespace() const {
+bool ParagraphComment::isWhitespaceNoCache() const {
for (child_iterator I = child_begin(), E = child_end(); I != E; ++I) {
if (const TextComment *TC = dyn_cast<TextComment>(*I)) {
if (!TC->isWhitespace())