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/lib/AST/Comment.cpp b/lib/AST/Comment.cpp
index 4681d5a..1520d13 100644
--- a/lib/AST/Comment.cpp
+++ b/lib/AST/Comment.cpp
@@ -86,6 +86,38 @@
   llvm_unreachable("Unknown comment kind!");
 }
 
+bool TextComment::isWhitespace() const {
+  for (StringRef::const_iterator I = Text.begin(), E = Text.end();
+       I != E; ++I) {
+    const char C = *I;
+    if (C != ' ' && C != '\n' && C != '\r' &&
+        C != '\t' && C != '\f' && C != '\v')
+      return false;
+  }
+  return true;
+}
+
+bool ParagraphComment::isWhitespace() const {
+  for (child_iterator I = child_begin(), E = child_end(); I != E; ++I) {
+    if (const TextComment *TC = dyn_cast<TextComment>(*I)) {
+      if (!TC->isWhitespace())
+        return false;
+    }
+  }
+  return true;
+}
+
+const char *ParamCommandComment::getDirectionAsString(PassDirection D) {
+  switch (D) {
+  case ParamCommandComment::In:
+    return "[in]";
+  case ParamCommandComment::Out:
+    return "[out]";
+  case ParamCommandComment::InOut:
+    return "[in,out]";
+  }
+  llvm_unreachable("unknown PassDirection");
+}
 
 } // end namespace comments
 } // end namespace clang