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"