[cfe-commits] r162407 - in /cfe/trunk: lib/AST/CommentLexer.cpp test/Sema/warn-documentation.cpp unittests/AST/CommentLexer.cpp

Dmitri Gribenko gribozavr at gmail.com
Wed Aug 22 15:56:08 PDT 2012


Author: gribozavr
Date: Wed Aug 22 17:56:08 2012
New Revision: 162407

URL: http://llvm.org/viewvc/llvm-project?rev=162407&view=rev
Log:
Comment parsing: parse "<blah" as an HTML tag only if "blah" is a known tag
name.  This should reduce the amount of warning false positives about bad HTML
in comments when the comment author intended to put a reference to a template.
This change will also enable us parse the comment as intended in these cases.

Fixes part 1 of PR13374.

Modified:
    cfe/trunk/lib/AST/CommentLexer.cpp
    cfe/trunk/test/Sema/warn-documentation.cpp
    cfe/trunk/unittests/AST/CommentLexer.cpp

Modified: cfe/trunk/lib/AST/CommentLexer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/CommentLexer.cpp?rev=162407&r1=162406&r2=162407&view=diff
==============================================================================
--- cfe/trunk/lib/AST/CommentLexer.cpp (original)
+++ cfe/trunk/lib/AST/CommentLexer.cpp Wed Aug 22 17:56:08 2012
@@ -28,6 +28,33 @@
          (C >= 'a' && C <= 'f') ||
          (C >= 'A' && C <= 'F');
 }
+
+bool isHTMLTagName(StringRef Name) {
+  return llvm::StringSwitch<bool>(Name)
+      .Cases("em", "strong", true)
+      .Cases("tt", "i", "b", "big", "small", true)
+      .Cases("strike", "s", "u", "font", true)
+      .Case("a", true)
+      .Case("hr", true)
+      .Cases("div", "span", true)
+      .Cases("h1", "h2", "h3", true)
+      .Cases("h4", "h5", "h6", true)
+      .Case("code", true)
+      .Case("blockquote", true)
+      .Cases("sub", "sup", true)
+      .Case("img", true)
+      .Case("p", true)
+      .Case("br", true)
+      .Case("pre", true)
+      .Cases("ins", "del", true)
+      .Cases("ul", "ol", "li", true)
+      .Cases("dl", "dt", "dd", true)
+      .Cases("table", "caption", true)
+      .Cases("thead", "tfoot", "tbody", true)
+      .Cases("colgroup", "col", true)
+      .Cases("tr", "th", "td", true)
+      .Default(false);
+}
 } // unnamed namespace
 
 StringRef Lexer::resolveHTMLNamedCharacterReference(StringRef Name) const {
@@ -585,8 +612,12 @@
   assert(BufferPtr[0] == '<' &&
          isHTMLIdentifierStartingCharacter(BufferPtr[1]));
   const char *TagNameEnd = skipHTMLIdentifier(BufferPtr + 2, CommentEnd);
-
   StringRef Name(BufferPtr + 1, TagNameEnd - (BufferPtr + 1));
+  if (!isHTMLTagName(Name)) {
+    formTextToken(T, TagNameEnd);
+    return;
+  }
+
   formTokenWithChars(T, TagNameEnd, tok::html_start_tag);
   T.setHTMLTagStartName(Name);
 
@@ -665,11 +696,16 @@
 
   const char *TagNameBegin = skipWhitespace(BufferPtr + 2, CommentEnd);
   const char *TagNameEnd = skipHTMLIdentifier(TagNameBegin, CommentEnd);
+  StringRef Name(TagNameBegin, TagNameEnd - TagNameBegin);
+  if (!isHTMLTagName(Name)) {
+    formTextToken(T, TagNameEnd);
+    return;
+  }
 
   const char *End = skipWhitespace(TagNameEnd, CommentEnd);
 
   formTokenWithChars(T, End, tok::html_end_tag);
-  T.setHTMLTagEndName(StringRef(TagNameBegin, TagNameEnd - TagNameBegin));
+  T.setHTMLTagEndName(Name);
 
   if (BufferPtr != CommentEnd && *BufferPtr == '>')
     State = LS_HTMLEndTag;

Modified: cfe/trunk/test/Sema/warn-documentation.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/warn-documentation.cpp?rev=162407&r1=162406&r2=162407&view=diff
==============================================================================
--- cfe/trunk/test/Sema/warn-documentation.cpp (original)
+++ cfe/trunk/test/Sema/warn-documentation.cpp Wed Aug 22 17:56:08 2012
@@ -38,13 +38,13 @@
 int test_html8(int);
 
 // expected-warning at +2 {{HTML start tag prematurely ended, expected attribute name or '>'}} expected-note at +1 {{HTML tag started here}}
-/** Aaa bbb<ccc ddd eee
+/** Aaa bbb<img ddd eee
  * fff ggg.
  */
 int test_html9(int);
 
 // expected-warning at +1 {{HTML start tag prematurely ended, expected attribute name or '>'}}
-/** Aaa bbb<ccc ddd eee 42%
+/** Aaa bbb<img ddd eee 42%
  * fff ggg.
  */
 int test_html10(int);

Modified: cfe/trunk/unittests/AST/CommentLexer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/CommentLexer.cpp?rev=162407&r1=162406&r2=162407&view=diff
==============================================================================
--- cfe/trunk/unittests/AST/CommentLexer.cpp (original)
+++ cfe/trunk/unittests/AST/CommentLexer.cpp Wed Aug 22 17:56:08 2012
@@ -822,7 +822,7 @@
 
 TEST_F(CommentLexerTest, HTML3) {
   const char *Source =
-    "// < tag";
+    "// < img";
 
   std::vector<Token> Toks;
 
@@ -837,15 +837,15 @@
   ASSERT_EQ(StringRef("<"),    Toks[1].getText());
 
   ASSERT_EQ(tok::text,         Toks[2].getKind());
-  ASSERT_EQ(StringRef(" tag"), Toks[2].getText());
+  ASSERT_EQ(StringRef(" img"), Toks[2].getText());
 
   ASSERT_EQ(tok::newline,      Toks[3].getKind());
 }
 
 TEST_F(CommentLexerTest, HTML4) {
   const char *Sources[] = {
-    "// <tag",
-    "// <tag "
+    "// <img",
+    "// <img "
   };
 
   for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
@@ -859,7 +859,7 @@
     ASSERT_EQ(StringRef(" "),      Toks[0].getText());
 
     ASSERT_EQ(tok::html_start_tag, Toks[1].getKind());
-    ASSERT_EQ(StringRef("tag"),    Toks[1].getHTMLTagStartName());
+    ASSERT_EQ(StringRef("img"),    Toks[1].getHTMLTagStartName());
 
     ASSERT_EQ(tok::newline,        Toks[2].getKind());
   }
@@ -867,7 +867,7 @@
 
 TEST_F(CommentLexerTest, HTML5) {
   const char *Source =
-    "// <tag 42";
+    "// <img 42";
 
   std::vector<Token> Toks;
 
@@ -879,7 +879,7 @@
   ASSERT_EQ(StringRef(" "),      Toks[0].getText());
 
   ASSERT_EQ(tok::html_start_tag, Toks[1].getKind());
-  ASSERT_EQ(StringRef("tag"),    Toks[1].getHTMLTagStartName());
+  ASSERT_EQ(StringRef("img"),    Toks[1].getHTMLTagStartName());
 
   ASSERT_EQ(tok::text,           Toks[2].getKind());
   ASSERT_EQ(StringRef("42"),     Toks[2].getText());
@@ -888,7 +888,7 @@
 }
 
 TEST_F(CommentLexerTest, HTML6) {
-  const char *Source = "// <tag> Meow";
+  const char *Source = "// <img> Meow";
 
   std::vector<Token> Toks;
 
@@ -900,7 +900,7 @@
   ASSERT_EQ(StringRef(" "),      Toks[0].getText());
 
   ASSERT_EQ(tok::html_start_tag, Toks[1].getKind());
-  ASSERT_EQ(StringRef("tag"),    Toks[1].getHTMLTagStartName());
+  ASSERT_EQ(StringRef("img"),    Toks[1].getHTMLTagStartName());
 
   ASSERT_EQ(tok::html_greater,   Toks[2].getKind());
 
@@ -911,7 +911,7 @@
 }
 
 TEST_F(CommentLexerTest, HTML7) {
-  const char *Source = "// <tag=";
+  const char *Source = "// <img=";
 
   std::vector<Token> Toks;
 
@@ -923,7 +923,7 @@
   ASSERT_EQ(StringRef(" "),      Toks[0].getText());
 
   ASSERT_EQ(tok::html_start_tag, Toks[1].getKind());
-  ASSERT_EQ(StringRef("tag"),    Toks[1].getHTMLTagStartName());
+  ASSERT_EQ(StringRef("img"),    Toks[1].getHTMLTagStartName());
 
   ASSERT_EQ(tok::text,           Toks[2].getKind());
   ASSERT_EQ(StringRef("="),      Toks[2].getText());
@@ -932,7 +932,7 @@
 }
 
 TEST_F(CommentLexerTest, HTML8) {
-  const char *Source = "// <tag attr=> Meow";
+  const char *Source = "// <img src=> Meow";
 
   std::vector<Token> Toks;
 
@@ -944,10 +944,10 @@
   ASSERT_EQ(StringRef(" "),      Toks[0].getText());
 
   ASSERT_EQ(tok::html_start_tag, Toks[1].getKind());
-  ASSERT_EQ(StringRef("tag"),    Toks[1].getHTMLTagStartName());
+  ASSERT_EQ(StringRef("img"),    Toks[1].getHTMLTagStartName());
 
   ASSERT_EQ(tok::html_ident,     Toks[2].getKind());
-  ASSERT_EQ(StringRef("attr"),   Toks[2].getHTMLIdent());
+  ASSERT_EQ(StringRef("src"),   Toks[2].getHTMLIdent());
 
   ASSERT_EQ(tok::html_equals,    Toks[3].getKind());
 
@@ -961,8 +961,8 @@
 
 TEST_F(CommentLexerTest, HTML9) {
   const char *Sources[] = {
-    "// <tag attr",
-    "// <tag attr "
+    "// <img src",
+    "// <img src "
   };
 
   for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
@@ -976,10 +976,10 @@
     ASSERT_EQ(StringRef(" "),      Toks[0].getText());
 
     ASSERT_EQ(tok::html_start_tag, Toks[1].getKind());
-    ASSERT_EQ(StringRef("tag"),    Toks[1].getHTMLTagStartName());
+    ASSERT_EQ(StringRef("img"),    Toks[1].getHTMLTagStartName());
 
     ASSERT_EQ(tok::html_ident,     Toks[2].getKind());
-    ASSERT_EQ(StringRef("attr"),   Toks[2].getHTMLIdent());
+    ASSERT_EQ(StringRef("src"),    Toks[2].getHTMLIdent());
 
     ASSERT_EQ(tok::newline,        Toks[3].getKind());
   }
@@ -987,8 +987,8 @@
 
 TEST_F(CommentLexerTest, HTML10) {
   const char *Sources[] = {
-    "// <tag attr=",
-    "// <tag attr ="
+    "// <img src=",
+    "// <img src ="
   };
 
   for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
@@ -1002,10 +1002,10 @@
     ASSERT_EQ(StringRef(" "),      Toks[0].getText());
 
     ASSERT_EQ(tok::html_start_tag, Toks[1].getKind());
-    ASSERT_EQ(StringRef("tag"),    Toks[1].getHTMLTagStartName());
+    ASSERT_EQ(StringRef("img"),    Toks[1].getHTMLTagStartName());
 
     ASSERT_EQ(tok::html_ident,     Toks[2].getKind());
-    ASSERT_EQ(StringRef("attr"),   Toks[2].getHTMLIdent());
+    ASSERT_EQ(StringRef("src"),    Toks[2].getHTMLIdent());
 
     ASSERT_EQ(tok::html_equals,    Toks[3].getKind());
 
@@ -1015,10 +1015,10 @@
 
 TEST_F(CommentLexerTest, HTML11) {
   const char *Sources[] = {
-    "// <tag attr=\"",
-    "// <tag attr = \"",
-    "// <tag attr=\'",
-    "// <tag attr = \'"
+    "// <img src=\"",
+    "// <img src = \"",
+    "// <img src=\'",
+    "// <img src = \'"
   };
 
   for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
@@ -1032,10 +1032,10 @@
     ASSERT_EQ(StringRef(" "),          Toks[0].getText());
 
     ASSERT_EQ(tok::html_start_tag,     Toks[1].getKind());
-    ASSERT_EQ(StringRef("tag"),        Toks[1].getHTMLTagStartName());
+    ASSERT_EQ(StringRef("img"),        Toks[1].getHTMLTagStartName());
 
     ASSERT_EQ(tok::html_ident,         Toks[2].getKind());
-    ASSERT_EQ(StringRef("attr"),       Toks[2].getHTMLIdent());
+    ASSERT_EQ(StringRef("src"),        Toks[2].getHTMLIdent());
 
     ASSERT_EQ(tok::html_equals,        Toks[3].getKind());
 
@@ -1047,7 +1047,7 @@
 }
 
 TEST_F(CommentLexerTest, HTML12) {
-  const char *Source = "// <tag attr=@";
+  const char *Source = "// <img src=@";
 
   std::vector<Token> Toks;
 
@@ -1059,10 +1059,10 @@
   ASSERT_EQ(StringRef(" "),      Toks[0].getText());
 
   ASSERT_EQ(tok::html_start_tag, Toks[1].getKind());
-  ASSERT_EQ(StringRef("tag"),    Toks[1].getHTMLTagStartName());
+  ASSERT_EQ(StringRef("img"),    Toks[1].getHTMLTagStartName());
 
   ASSERT_EQ(tok::html_ident,     Toks[2].getKind());
-  ASSERT_EQ(StringRef("attr"),   Toks[2].getHTMLIdent());
+  ASSERT_EQ(StringRef("src"),    Toks[2].getHTMLIdent());
 
   ASSERT_EQ(tok::html_equals,    Toks[3].getKind());
 
@@ -1074,10 +1074,10 @@
 
 TEST_F(CommentLexerTest, HTML13) {
   const char *Sources[] = {
-    "// <tag attr=\"val\\\"\\'val",
-    "// <tag attr=\"val\\\"\\'val\"",
-    "// <tag attr=\'val\\\"\\'val",
-    "// <tag attr=\'val\\\"\\'val\'"
+    "// <img src=\"val\\\"\\'val",
+    "// <img src=\"val\\\"\\'val\"",
+    "// <img src=\'val\\\"\\'val",
+    "// <img src=\'val\\\"\\'val\'"
   };
 
   for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
@@ -1091,10 +1091,10 @@
     ASSERT_EQ(StringRef(" "),             Toks[0].getText());
 
     ASSERT_EQ(tok::html_start_tag,        Toks[1].getKind());
-    ASSERT_EQ(StringRef("tag"),           Toks[1].getHTMLTagStartName());
+    ASSERT_EQ(StringRef("img"),           Toks[1].getHTMLTagStartName());
 
     ASSERT_EQ(tok::html_ident,            Toks[2].getKind());
-    ASSERT_EQ(StringRef("attr"),          Toks[2].getHTMLIdent());
+    ASSERT_EQ(StringRef("src"),           Toks[2].getHTMLIdent());
 
     ASSERT_EQ(tok::html_equals,           Toks[3].getKind());
 
@@ -1107,8 +1107,8 @@
 
 TEST_F(CommentLexerTest, HTML14) {
   const char *Sources[] = {
-    "// <tag attr=\"val\\\"\\'val\">",
-    "// <tag attr=\'val\\\"\\'val\'>"
+    "// <img src=\"val\\\"\\'val\">",
+    "// <img src=\'val\\\"\\'val\'>"
   };
 
   for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
@@ -1122,10 +1122,10 @@
     ASSERT_EQ(StringRef(" "),             Toks[0].getText());
 
     ASSERT_EQ(tok::html_start_tag,        Toks[1].getKind());
-    ASSERT_EQ(StringRef("tag"),           Toks[1].getHTMLTagStartName());
+    ASSERT_EQ(StringRef("img"),           Toks[1].getHTMLTagStartName());
 
     ASSERT_EQ(tok::html_ident,            Toks[2].getKind());
-    ASSERT_EQ(StringRef("attr"),          Toks[2].getHTMLIdent());
+    ASSERT_EQ(StringRef("src"),           Toks[2].getHTMLIdent());
 
     ASSERT_EQ(tok::html_equals,           Toks[3].getKind());
 
@@ -1140,8 +1140,8 @@
 
 TEST_F(CommentLexerTest, HTML15) {
   const char *Sources[] = {
-    "// <tag/>",
-    "// <tag />"
+    "// <img/>",
+    "// <img />"
   };
 
   for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
@@ -1155,7 +1155,7 @@
     ASSERT_EQ(StringRef(" "),          Toks[0].getText());
 
     ASSERT_EQ(tok::html_start_tag,     Toks[1].getKind());
-    ASSERT_EQ(StringRef("tag"),        Toks[1].getHTMLTagStartName());
+    ASSERT_EQ(StringRef("img"),        Toks[1].getHTMLTagStartName());
 
     ASSERT_EQ(tok::html_slash_greater, Toks[2].getKind());
 
@@ -1165,8 +1165,8 @@
 
 TEST_F(CommentLexerTest, HTML16) {
   const char *Sources[] = {
-    "// <tag/ Aaa",
-    "// <tag / Aaa"
+    "// <img/ Aaa",
+    "// <img / Aaa"
   };
 
   for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
@@ -1180,7 +1180,7 @@
     ASSERT_EQ(StringRef(" "),          Toks[0].getText());
 
     ASSERT_EQ(tok::html_start_tag,     Toks[1].getKind());
-    ASSERT_EQ(StringRef("tag"),        Toks[1].getHTMLTagStartName());
+    ASSERT_EQ(StringRef("img"),        Toks[1].getHTMLTagStartName());
 
     ASSERT_EQ(tok::text,               Toks[2].getKind());
     ASSERT_EQ(StringRef("/"),          Toks[2].getText());
@@ -1201,13 +1201,13 @@
 
   ASSERT_EQ(3U, Toks.size());
 
-  ASSERT_EQ(tok::text,         Toks[0].getKind());
-  ASSERT_EQ(StringRef(" "),    Toks[0].getText());
+  ASSERT_EQ(tok::text,       Toks[0].getKind());
+  ASSERT_EQ(StringRef(" "),  Toks[0].getText());
 
-  ASSERT_EQ(tok::html_end_tag, Toks[1].getKind());
-  ASSERT_EQ(StringRef(""),     Toks[1].getHTMLTagEndName());
+  ASSERT_EQ(tok::text,       Toks[1].getKind());
+  ASSERT_EQ(StringRef("</"), Toks[1].getText());
 
-  ASSERT_EQ(tok::newline,      Toks[2].getKind());
+  ASSERT_EQ(tok::newline,    Toks[2].getKind());
 }
 
 TEST_F(CommentLexerTest, HTML18) {
@@ -1219,20 +1219,20 @@
 
   ASSERT_EQ(4U, Toks.size());
 
-  ASSERT_EQ(tok::text,         Toks[0].getKind());
-  ASSERT_EQ(StringRef(" "),    Toks[0].getText());
+  ASSERT_EQ(tok::text,       Toks[0].getKind());
+  ASSERT_EQ(StringRef(" "),  Toks[0].getText());
 
-  ASSERT_EQ(tok::html_end_tag, Toks[1].getKind());
-  ASSERT_EQ(StringRef(""),     Toks[1].getHTMLTagEndName());
+  ASSERT_EQ(tok::text,       Toks[1].getKind());
+  ASSERT_EQ(StringRef("</"), Toks[1].getText());
 
-  ASSERT_EQ(tok::text,         Toks[2].getKind());
-  ASSERT_EQ(StringRef("@"),    Toks[2].getText());
+  ASSERT_EQ(tok::text,       Toks[2].getKind());
+  ASSERT_EQ(StringRef("@"),  Toks[2].getText());
 
-  ASSERT_EQ(tok::newline,      Toks[3].getKind());
+  ASSERT_EQ(tok::newline,    Toks[3].getKind());
 }
 
 TEST_F(CommentLexerTest, HTML19) {
-  const char *Source = "// </tag";
+  const char *Source = "// </img";
 
   std::vector<Token> Toks;
 
@@ -1244,35 +1244,51 @@
   ASSERT_EQ(StringRef(" "),    Toks[0].getText());
 
   ASSERT_EQ(tok::html_end_tag, Toks[1].getKind());
-  ASSERT_EQ(StringRef("tag"),  Toks[1].getHTMLTagEndName());
+  ASSERT_EQ(StringRef("img"),  Toks[1].getHTMLTagEndName());
 
   ASSERT_EQ(tok::newline,      Toks[2].getKind());
 }
 
-TEST_F(CommentLexerTest, HTML20) {
-  const char *Sources[] = {
-    "// </tag>",
-    "// </ tag>",
-    "// </ tag >"
-  };
+TEST_F(CommentLexerTest, NotAKnownHTMLTag1) {
+  const char *Source = "// <tag>";
 
-  for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
-    std::vector<Token> Toks;
+  std::vector<Token> Toks;
 
-    lexString(Sources[i], Toks);
+  lexString(Source, Toks);
 
-    ASSERT_EQ(4U, Toks.size());
+  ASSERT_EQ(4U, Toks.size());
 
-    ASSERT_EQ(tok::text,         Toks[0].getKind());
-    ASSERT_EQ(StringRef(" "),    Toks[0].getText());
+  ASSERT_EQ(tok::text,         Toks[0].getKind());
+  ASSERT_EQ(StringRef(" "),    Toks[0].getText());
 
-    ASSERT_EQ(tok::html_end_tag, Toks[1].getKind());
-    ASSERT_EQ(StringRef("tag"),  Toks[1].getHTMLTagEndName());
+  ASSERT_EQ(tok::text,         Toks[1].getKind());
+  ASSERT_EQ(StringRef("<tag"), Toks[1].getText());
 
-    ASSERT_EQ(tok::html_greater, Toks[2].getKind());
+  ASSERT_EQ(tok::text,         Toks[2].getKind());
+  ASSERT_EQ(StringRef(">"),    Toks[2].getText());
 
-    ASSERT_EQ(tok::newline,      Toks[3].getKind());
-  }
+  ASSERT_EQ(tok::newline,      Toks[3].getKind());
+}
+
+TEST_F(CommentLexerTest, NotAKnownHTMLTag2) {
+  const char *Source = "// </tag>";
+
+  std::vector<Token> Toks;
+
+  lexString(Source, Toks);
+
+  ASSERT_EQ(4U, Toks.size());
+
+  ASSERT_EQ(tok::text,          Toks[0].getKind());
+  ASSERT_EQ(StringRef(" "),     Toks[0].getText());
+
+  ASSERT_EQ(tok::text,          Toks[1].getKind());
+  ASSERT_EQ(StringRef("</tag"), Toks[1].getText());
+
+  ASSERT_EQ(tok::text,          Toks[2].getKind());
+  ASSERT_EQ(StringRef(">"),     Toks[2].getText());
+
+  ASSERT_EQ(tok::newline,       Toks[3].getKind());
 }
 
 TEST_F(CommentLexerTest, HTMLCharacterReferences1) {





More information about the cfe-commits mailing list