Enable comment parsing and semantic analysis to emit diagnostics. A few
diagnostics implemented -- see testcases.
I created a new TableGen file for comment diagnostics,
DiagnosticCommentKinds.td, because comment diagnostics don't logically
fit into AST diagnostics file. But I don't feel strongly about it.
This also implements support for self-closing HTML tags in comment
lexer and parser (for example, <br />).
In order to issue precise diagnostics CommentSema needs to know the
declaration the comment is attached to. There is no easy way to find a decl by
comment, so we match comments and decls in lockstep: after parsing one
declgroup we check if we have any new, not yet attached comments. If we do --
then we do the usual comment-finding process.
It is interesting that this automatically handles trailing comments.
We pick up not only comments that precede the declaration, but also
comments that *follow* the declaration -- thanks to the lookahead in
the lexer: after parsing the declgroup we've consumed the semicolon
and looked ahead through comments.
Added -Wdocumentation-html flag for semantic HTML errors to allow the user to
disable only HTML warnings (but not HTML parse errors, which we emit as
warnings in -Wdocumentation).
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@160078 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/unittests/AST/CommentParser.cpp b/unittests/AST/CommentParser.cpp
index d5dd0a9..c779a88 100644
--- a/unittests/AST/CommentParser.cpp
+++ b/unittests/AST/CommentParser.cpp
@@ -57,8 +57,8 @@
comments::Lexer L(Begin, CommentOptions(),
Source, Source + strlen(Source));
- comments::Sema S(Allocator);
- comments::Parser P(L, S, Allocator);
+ comments::Sema S(Allocator, SourceMgr, Diags);
+ comments::Parser P(L, S, Allocator, SourceMgr, Diags);
comments::FullComment *FC = P.parseFullComment();
if (DEBUG) {
@@ -292,6 +292,25 @@
return ::testing::AssertionSuccess();
}
+struct SelfClosing {};
+
+::testing::AssertionResult HasHTMLOpenTagAt(const Comment *C,
+ size_t Idx,
+ HTMLOpenTagComment *&HOT,
+ StringRef TagName,
+ SelfClosing) {
+ ::testing::AssertionResult AR = HasHTMLOpenTagAt(C, Idx, HOT, TagName);
+ if (!AR)
+ return AR;
+
+ if (!HOT->isSelfClosing())
+ return ::testing::AssertionFailure()
+ << "HTMLOpenTagComment is not self-closing";
+
+ return ::testing::AssertionSuccess();
+}
+
+
struct NoAttrs {};
::testing::AssertionResult HasHTMLOpenTagAt(const Comment *C,
@@ -303,6 +322,10 @@
if (!AR)
return AR;
+ if (HOT->isSelfClosing())
+ return ::testing::AssertionFailure()
+ << "HTMLOpenTagComment is self-closing";
+
if (HOT->getAttrCount() != 0)
return ::testing::AssertionFailure()
<< "HTMLOpenTagComment has " << HOT->getAttrCount() << " attr(s), "
@@ -321,6 +344,10 @@
if (!AR)
return AR;
+ if (HOT->isSelfClosing())
+ return ::testing::AssertionFailure()
+ << "HTMLOpenTagComment is self-closing";
+
if (HOT->getAttrCount() != 1)
return ::testing::AssertionFailure()
<< "HTMLOpenTagComment has " << HOT->getAttrCount() << " attr(s), "
@@ -837,6 +864,28 @@
TEST_F(CommentParserTest, HTML2) {
const char *Sources[] = {
+ "// <br/>",
+ "// <br />"
+ };
+
+ for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
+ FullComment *FC = parseString(Sources[i]);
+ ASSERT_TRUE(HasChildCount(FC, 1));
+
+ {
+ ParagraphComment *PC;
+ HTMLOpenTagComment *HOT;
+ ASSERT_TRUE(GetChildAt(FC, 0, PC));
+
+ ASSERT_TRUE(HasChildCount(PC, 2));
+ ASSERT_TRUE(HasTextAt(PC, 0, " "));
+ ASSERT_TRUE(HasHTMLOpenTagAt(PC, 1, HOT, "br", SelfClosing()));
+ }
+ }
+}
+
+TEST_F(CommentParserTest, HTML3) {
+ const char *Sources[] = {
"// <a href",
"// <a href ",
"// <a href>",
@@ -859,7 +908,7 @@
}
}
-TEST_F(CommentParserTest, HTML3) {
+TEST_F(CommentParserTest, HTML4) {
const char *Sources[] = {
"// <a href=\"bbb\"",
"// <a href=\"bbb\">",
@@ -881,7 +930,7 @@
}
}
-TEST_F(CommentParserTest, HTML4) {
+TEST_F(CommentParserTest, HTML5) {
const char *Sources[] = {
"// </a",
"// </a>",
@@ -904,7 +953,7 @@
}
}
-TEST_F(CommentParserTest, HTML5) {
+TEST_F(CommentParserTest, HTML6) {
const char *Source =
"// <pre>\n"
"// Aaa\n"