From: Dmitri Gribenko Date: Fri, 31 Aug 2012 02:21:44 +0000 (+0000) Subject: Comment HTML tag name machers: move from StringSwitch to an efficient X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c24a76e376a767edc14e60bed716396a84cb127a;p=clang Comment HTML tag name machers: move from StringSwitch to an efficient TableGen-generated string matcher. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@162969 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/CMakeLists.txt b/include/clang/AST/CMakeLists.txt index d7458aa790..339250b674 100644 --- a/include/clang/AST/CMakeLists.txt +++ b/include/clang/AST/CMakeLists.txt @@ -20,3 +20,11 @@ clang_tablegen(CommentNodes.inc -gen-clang-comment-nodes SOURCE ../Basic/CommentNodes.td TARGET ClangCommentNodes) +clang_tablegen(CommentHTMLTags.inc -gen-clang-comment-html-tags + SOURCE CommentHTMLTags.td + TARGET ClangCommentHTMLTags) + +clang_tablegen(CommentHTMLTagsProperties.inc -gen-clang-comment-html-tags-properties + SOURCE CommentHTMLTags.td + TARGET ClangCommentHTMLTagsProperties) + diff --git a/include/clang/AST/CommentHTMLTags.td b/include/clang/AST/CommentHTMLTags.td new file mode 100644 index 0000000000..f98e32ddca --- /dev/null +++ b/include/clang/AST/CommentHTMLTags.td @@ -0,0 +1,54 @@ +class Tag { + string Spelling = spelling; + bit EndTagOptional = 0; + bit EndTagForbidden = 0; +} + +def Em : Tag<"em">; +def Strong : Tag<"strong">; +def Tt : Tag<"tt">; +def I : Tag<"i">; +def B : Tag<"b">; +def Big : Tag<"big">; +def Small : Tag<"small">; +def Strike : Tag<"strike">; +def S : Tag<"s">; +def U : Tag<"u">; +def Font : Tag<"font">; +def A : Tag<"a">; +def Hr : Tag<"hr"> { let EndTagForbidden = 1; } +def Div : Tag<"div">; +def Span : Tag<"span">; +def H1 : Tag<"h1">; +def H2 : Tag<"h2">; +def H3 : Tag<"h3">; +def H4 : Tag<"h4">; +def H5 : Tag<"h5">; +def H6 : Tag<"h6">; +def Code : Tag<"code">; +def Blockquote : Tag<"blockquote">; +def Sub : Tag<"sub">; +def Sup : Tag<"sup">; +def Img : Tag<"img"> { let EndTagForbidden = 1; } +def P : Tag<"p"> { let EndTagOptional = 1; } +def Br : Tag<"br"> { let EndTagForbidden = 1; } +def Pre : Tag<"pre">; +def Ins : Tag<"ins">; +def Del : Tag<"del">; +def Ul : Tag<"ul">; +def Ol : Tag<"ol">; +def Li : Tag<"li"> { let EndTagOptional = 1; } +def Dl : Tag<"dl">; +def Dt : Tag<"dt"> { let EndTagOptional = 1; } +def Dd : Tag<"dd"> { let EndTagOptional = 1; } +def Table : Tag<"table">; +def Caption : Tag<"caption">; +def Thead : Tag<"thead"> { let EndTagOptional = 1; } +def Tfoot : Tag<"tfoot"> { let EndTagOptional = 1; } +def Tbody : Tag<"tbody"> { let EndTagOptional = 1; } +def Colgroup : Tag<"colgroup"> { let EndTagOptional = 1; } +def Col : Tag<"col"> { let EndTagForbidden = 1; } +def Tr : Tag<"tr"> { let EndTagOptional = 1; } +def Th : Tag<"th"> { let EndTagOptional = 1; } +def Td : Tag<"td"> { let EndTagOptional = 1; } + diff --git a/include/clang/AST/CommentSema.h b/include/clang/AST/CommentSema.h index d0ede9053c..a544aa947c 100644 --- a/include/clang/AST/CommentSema.h +++ b/include/clang/AST/CommentSema.h @@ -215,9 +215,6 @@ public: InlineCommandComment::RenderKind getInlineCommandRenderKind(StringRef Name) const; - - bool isHTMLEndTagOptional(StringRef Name); - bool isHTMLEndTagForbidden(StringRef Name); }; } // end namespace comments diff --git a/include/clang/AST/Makefile b/include/clang/AST/Makefile index f6dd4ce6e6..dd3a7656ba 100644 --- a/include/clang/AST/Makefile +++ b/include/clang/AST/Makefile @@ -1,6 +1,8 @@ CLANG_LEVEL := ../../.. TD_SRC_DIR = $(PROJ_SRC_DIR)/../Basic -BUILT_SOURCES = Attrs.inc AttrImpl.inc StmtNodes.inc DeclNodes.inc CommentNodes.inc +BUILT_SOURCES = Attrs.inc AttrImpl.inc StmtNodes.inc DeclNodes.inc \ + CommentNodes.inc CommentHTMLTags.inc \ + CommentHTMLTagsProperties.inc TABLEGEN_INC_FILES_COMMON = 1 @@ -33,3 +35,13 @@ $(ObjDir)/CommentNodes.inc.tmp : $(TD_SRC_DIR)/CommentNodes.td $(CLANG_TBLGEN) \ $(Echo) "Building Clang comment node tables with tblgen" $(Verb) $(ClangTableGen) -gen-clang-comment-nodes -o $(call SYSPATH, $@) $< +$(ObjDir)/CommentHTMLTags.inc.tmp : $(PROJ_SRC_DIR)/CommentHTMLTags.td $(CLANG_TBLGEN) \ + $(ObjDir)/.dir + $(Echo) "Building Clang comment HTML tag matchers with tblgen" + $(Verb) $(ClangTableGen) -gen-clang-comment-html-tags -o $(call SYSPATH, $@) $< + +$(ObjDir)/CommentHTMLTagsProperties.inc.tmp : $(PROJ_SRC_DIR)/CommentHTMLTags.td \ + $(CLANG_TBLGEN) $(ObjDir)/.dir + $(Echo) "Building Clang comment HTML tag properties with tblgen" + $(Verb) $(ClangTableGen) -gen-clang-comment-html-tags-properties -o $(call SYSPATH, $@) $< + diff --git a/lib/AST/CMakeLists.txt b/lib/AST/CMakeLists.txt index bcc96f912e..14c0aa5eed 100644 --- a/lib/AST/CMakeLists.txt +++ b/lib/AST/CMakeLists.txt @@ -65,6 +65,8 @@ add_dependencies(clangAST ClangAttrList ClangAttrImpl ClangCommentNodes + ClangCommentHTMLTags + ClangCommentHTMLTagsProperties ClangDeclNodes ClangDiagnosticAST ClangDiagnosticComment diff --git a/lib/AST/CommentLexer.cpp b/lib/AST/CommentLexer.cpp index 870db2be5f..eb0ac2472a 100644 --- a/lib/AST/CommentLexer.cpp +++ b/lib/AST/CommentLexer.cpp @@ -29,32 +29,8 @@ bool isHTMLHexCharacterReferenceCharacter(char C) { (C >= 'A' && C <= 'F'); } -bool isHTMLTagName(StringRef Name) { - return llvm::StringSwitch(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); -} +#include "clang/AST/CommentHTMLTags.inc" + } // unnamed namespace StringRef Lexer::resolveHTMLNamedCharacterReference(StringRef Name) const { diff --git a/lib/AST/CommentSema.cpp b/lib/AST/CommentSema.cpp index 923081dda6..ffb6e86788 100644 --- a/lib/AST/CommentSema.cpp +++ b/lib/AST/CommentSema.cpp @@ -18,6 +18,10 @@ namespace clang { namespace comments { +namespace { +#include "clang/AST/CommentHTMLTagsProperties.inc" +} // unnamed namespace + Sema::Sema(llvm::BumpPtrAllocator &Allocator, const SourceManager &SourceMgr, DiagnosticsEngine &Diags, const CommandTraits &Traits) : Allocator(Allocator), SourceMgr(SourceMgr), Diags(Diags), Traits(Traits), @@ -745,31 +749,6 @@ Sema::getInlineCommandRenderKind(StringRef Name) const { .Default(InlineCommandComment::RenderNormal); } -bool Sema::isHTMLEndTagOptional(StringRef Name) { - return llvm::StringSwitch(Name) - .Case("p", true) - .Case("li", true) - .Case("dt", true) - .Case("dd", true) - .Case("tr", true) - .Case("th", true) - .Case("td", true) - .Case("thead", true) - .Case("tfoot", true) - .Case("tbody", true) - .Case("colgroup", true) - .Default(false); -} - -bool Sema::isHTMLEndTagForbidden(StringRef Name) { - return llvm::StringSwitch(Name) - .Case("br", true) - .Case("hr", true) - .Case("img", true) - .Case("col", true) - .Default(false); -} - } // end namespace comments } // end namespace clang diff --git a/utils/TableGen/CMakeLists.txt b/utils/TableGen/CMakeLists.txt index 0d879214d4..ca2e4696a5 100644 --- a/utils/TableGen/CMakeLists.txt +++ b/utils/TableGen/CMakeLists.txt @@ -5,6 +5,7 @@ set(LLVM_LINK_COMPONENTS Support) add_tablegen(clang-tblgen CLANG ClangASTNodesEmitter.cpp ClangAttrEmitter.cpp + ClangCommentHTMLTagsEmitter.cpp ClangDiagnosticsEmitter.cpp ClangSACheckersEmitter.cpp NeonEmitter.cpp diff --git a/utils/TableGen/ClangCommentHTMLTagsEmitter.cpp b/utils/TableGen/ClangCommentHTMLTagsEmitter.cpp new file mode 100644 index 0000000000..0ae23b293e --- /dev/null +++ b/utils/TableGen/ClangCommentHTMLTagsEmitter.cpp @@ -0,0 +1,69 @@ +//===--- ClangCommentHTMLTagsEmitter.cpp - Generate HTML tag list for Clang -=// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This tablegen backend emits efficient matchers for HTML tags that are used +// in documentation comments. +// +//===----------------------------------------------------------------------===// + +#include "llvm/TableGen/Record.h" +#include "llvm/TableGen/StringMatcher.h" +#include + +using namespace llvm; + +namespace clang { +void EmitClangCommentHTMLTags(RecordKeeper &Records, raw_ostream &OS) { + std::vector Tags = Records.getAllDerivedDefinitions("Tag"); + std::vector Matches; + for (std::vector::iterator I = Tags.begin(), E = Tags.end(); + I != E; ++I) { + Record &Tag = **I; + std::string Spelling = Tag.getValueAsString("Spelling"); + Matches.push_back(StringMatcher::StringPair(Spelling, "return true;")); + } + + OS << "// This file is generated by TableGen. Do not edit.\n\n"; + + OS << "bool isHTMLTagName(StringRef Name) {\n"; + StringMatcher("Name", Matches, OS).Emit(); + OS << " return false;\n" + << "}\n\n"; +} + +void EmitClangCommentHTMLTagsProperties(RecordKeeper &Records, + raw_ostream &OS) { + std::vector Tags = Records.getAllDerivedDefinitions("Tag"); + std::vector MatchesEndTagOptional; + std::vector MatchesEndTagForbidden; + for (std::vector::iterator I = Tags.begin(), E = Tags.end(); + I != E; ++I) { + Record &Tag = **I; + std::string Spelling = Tag.getValueAsString("Spelling"); + StringMatcher::StringPair Match(Spelling, "return true;"); + if (Tag.getValueAsBit("EndTagOptional")) + MatchesEndTagOptional.push_back(Match); + if (Tag.getValueAsBit("EndTagForbidden")) + MatchesEndTagForbidden.push_back(Match); + } + + OS << "// This file is generated by TableGen. Do not edit.\n\n"; + + OS << "bool isHTMLEndTagOptional(StringRef Name) {\n"; + StringMatcher("Name", MatchesEndTagOptional, OS).Emit(); + OS << " return false;\n" + << "}\n\n"; + + OS << "bool isHTMLEndTagForbidden(StringRef Name) {\n"; + StringMatcher("Name", MatchesEndTagForbidden, OS).Emit(); + OS << " return false;\n" + << "}\n\n"; +} +} // end namespace clang + diff --git a/utils/TableGen/TableGen.cpp b/utils/TableGen/TableGen.cpp index d3408ed20f..bb9b918505 100644 --- a/utils/TableGen/TableGen.cpp +++ b/utils/TableGen/TableGen.cpp @@ -42,6 +42,8 @@ enum ActionType { GenClangDeclNodes, GenClangStmtNodes, GenClangSACheckers, + GenClangCommentHTMLTags, + GenClangCommentHTMLTagsProperties, GenOptParserDefs, GenOptParserImpl, GenArmNeon, GenArmNeonSema, @@ -95,6 +97,14 @@ namespace { "Generate Clang AST statement nodes"), clEnumValN(GenClangSACheckers, "gen-clang-sa-checkers", "Generate Clang Static Analyzer checkers"), + clEnumValN(GenClangCommentHTMLTags, + "gen-clang-comment-html-tags", + "Generate efficient matchers for HTML tag " + "names that are used in documentation comments"), + clEnumValN(GenClangCommentHTMLTagsProperties, + "gen-clang-comment-html-tags-properties", + "Generate efficient matchers for HTML tag " + "properties"), clEnumValN(GenArmNeon, "gen-arm-neon", "Generate arm_neon.h for clang"), clEnumValN(GenArmNeonSema, "gen-arm-neon-sema", @@ -164,6 +174,12 @@ public: case GenClangSACheckers: EmitClangSACheckers(Records, OS); break; + case GenClangCommentHTMLTags: + EmitClangCommentHTMLTags(Records, OS); + break; + case GenClangCommentHTMLTagsProperties: + EmitClangCommentHTMLTagsProperties(Records, OS); + break; case GenOptParserDefs: EmitOptParser(Records, OS, true); break; diff --git a/utils/TableGen/TableGenBackends.h b/utils/TableGen/TableGenBackends.h index 779de7c734..74fc60ec11 100644 --- a/utils/TableGen/TableGenBackends.h +++ b/utils/TableGen/TableGenBackends.h @@ -47,6 +47,9 @@ void EmitClangDiagsIndexName(RecordKeeper &Records, raw_ostream &OS); void EmitClangSACheckers(RecordKeeper &Records, raw_ostream &OS); +void EmitClangCommentHTMLTags(RecordKeeper &Records, raw_ostream &OS); +void EmitClangCommentHTMLTagsProperties(RecordKeeper &Records, raw_ostream &OS); + void EmitNeon(RecordKeeper &Records, raw_ostream &OS); void EmitNeonSema(RecordKeeper &Records, raw_ostream &OS); void EmitNeonTest(RecordKeeper &Records, raw_ostream &OS);