1e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko//===--- ClangCommentCommandInfoEmitter.cpp - Generate command lists -----====// 2e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko// 3e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko// The LLVM Compiler Infrastructure 4e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko// 5e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko// This file is distributed under the University of Illinois Open Source 6e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko// License. See LICENSE.TXT for details. 7e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko// 8e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko//===----------------------------------------------------------------------===// 9e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko// 108f1fa25a9e9f3fa4f2d7ecc0a08ebb08c0c4e642Dmitri Gribenko// This tablegen backend emits command lists and efficient matchers for command 11e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko// names that are used in documentation comments. 12e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko// 13e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko//===----------------------------------------------------------------------===// 14e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko 15e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko#include "llvm/TableGen/Record.h" 16e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko#include "llvm/TableGen/StringMatcher.h" 178f1fa25a9e9f3fa4f2d7ecc0a08ebb08c0c4e642Dmitri Gribenko#include "llvm/TableGen/TableGenBackend.h" 18e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko#include <vector> 19e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko 20e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenkousing namespace llvm; 21e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko 22e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenkonamespace clang { 23e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenkovoid EmitClangCommentCommandInfo(RecordKeeper &Records, raw_ostream &OS) { 248f1fa25a9e9f3fa4f2d7ecc0a08ebb08c0c4e642Dmitri Gribenko emitSourceFileHeader("A list of commands useable in documentation " 258f1fa25a9e9f3fa4f2d7ecc0a08ebb08c0c4e642Dmitri Gribenko "comments", OS); 26e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko 27e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko OS << "namespace {\n" 28e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko "const CommandInfo Commands[] = {\n"; 29e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko std::vector<Record *> Tags = Records.getAllDerivedDefinitions("Command"); 30e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko for (size_t i = 0, e = Tags.size(); i != e; ++i) { 31e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko Record &Tag = *Tags[i]; 32e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko OS << " { " 33e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko << "\"" << Tag.getValueAsString("Name") << "\", " 34e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko << "\"" << Tag.getValueAsString("EndCommandName") << "\", " 35e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko << i << ", " 36e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko << Tag.getValueAsInt("NumArgs") << ", " 37e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko << Tag.getValueAsBit("IsInlineCommand") << ", " 38e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko << Tag.getValueAsBit("IsBlockCommand") << ", " 39e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko << Tag.getValueAsBit("IsBriefCommand") << ", " 40e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko << Tag.getValueAsBit("IsReturnsCommand") << ", " 41e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko << Tag.getValueAsBit("IsParamCommand") << ", " 42e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko << Tag.getValueAsBit("IsTParamCommand") << ", " 43f6785e3117c0ce447e4d70065e069a9dc031f14cDmitri Gribenko << Tag.getValueAsBit("IsThrowsCommand") << ", " 440bd9838751384181ff387f2fb346896792b89617Dmitri Gribenko << Tag.getValueAsBit("IsDeprecatedCommand") << ", " 45f843a580c4a54ca147f22422ee8ccfd2347784fcFariborz Jahanian << Tag.getValueAsBit("IsHeaderfileCommand") << ", " 46abcf0dccc9cd4c802f4e7797bf452c6808d2226fDmitri Gribenko << Tag.getValueAsBit("IsEmptyParagraphAllowed") << ", " 47e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko << Tag.getValueAsBit("IsVerbatimBlockCommand") << ", " 48e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko << Tag.getValueAsBit("IsVerbatimBlockEndCommand") << ", " 49e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko << Tag.getValueAsBit("IsVerbatimLineCommand") << ", " 50e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko << Tag.getValueAsBit("IsDeclarationCommand") << ", " 512a268f2629b49958427e8eb02f2c3d565be71accFariborz Jahanian << Tag.getValueAsBit("IsFunctionDeclarationCommand") << ", " 52b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian << Tag.getValueAsBit("IsRecordLikeDetailCommand") << ", " 53b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian << Tag.getValueAsBit("IsRecordLikeDeclarationCommand") << ", " 54e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko << /* IsUnknownCommand = */ "0" 55e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko << " }"; 56e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko if (i + 1 != e) 57e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko OS << ","; 58e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko OS << "\n"; 59e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko } 60e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko OS << "};\n" 61e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko "} // unnamed namespace\n\n"; 62e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko 63e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko std::vector<StringMatcher::StringPair> Matches; 64e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko for (size_t i = 0, e = Tags.size(); i != e; ++i) { 65e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko Record &Tag = *Tags[i]; 66e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko std::string Name = Tag.getValueAsString("Name"); 67e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko std::string Return; 68e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko raw_string_ostream(Return) << "return &Commands[" << i << "];"; 69e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko Matches.push_back(StringMatcher::StringPair(Name, Return)); 70e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko } 71e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko 72e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko OS << "const CommandInfo *CommandTraits::getBuiltinCommandInfo(\n" 73e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko << " StringRef Name) {\n"; 74e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko StringMatcher("Name", Matches, OS).Emit(); 75e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko OS << " return NULL;\n" 76e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko << "}\n\n"; 77e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko} 78af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko 79af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenkostatic std::string MangleName(StringRef Str) { 80af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko std::string Mangled; 81af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko for (unsigned i = 0, e = Str.size(); i != e; ++i) { 82af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko switch (Str[i]) { 83af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko default: 84af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko Mangled += Str[i]; 85af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko break; 86af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko case '[': 87af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko Mangled += "lsquare"; 88af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko break; 89af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko case ']': 90af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko Mangled += "rsquare"; 91af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko break; 92af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko case '{': 93af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko Mangled += "lbrace"; 94af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko break; 95af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko case '}': 96af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko Mangled += "rbrace"; 97af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko break; 98af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko case '$': 99af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko Mangled += "dollar"; 100af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko break; 1015238e40f6ea6346b6bc1505e4975c2c4ab7fde09Fariborz Jahanian case '/': 1025238e40f6ea6346b6bc1505e4975c2c4ab7fde09Fariborz Jahanian Mangled += "slash"; 1035238e40f6ea6346b6bc1505e4975c2c4ab7fde09Fariborz Jahanian break; 104af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko } 105af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko } 106af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko return Mangled; 107af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko} 108af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko 109af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenkovoid EmitClangCommentCommandList(RecordKeeper &Records, raw_ostream &OS) { 110af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko emitSourceFileHeader("A list of commands useable in documentation " 111af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko "comments", OS); 112af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko 113af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko OS << "#ifndef COMMENT_COMMAND\n" 114af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko << "# define COMMENT_COMMAND(NAME)\n" 115af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko << "#endif\n"; 116af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko 117af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko std::vector<Record *> Tags = Records.getAllDerivedDefinitions("Command"); 118af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko for (size_t i = 0, e = Tags.size(); i != e; ++i) { 119af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko Record &Tag = *Tags[i]; 120af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko std::string MangledName = MangleName(Tag.getValueAsString("Name")); 121af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko 122af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko OS << "COMMENT_COMMAND(" << MangledName << ")\n"; 123af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko } 124af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko} 125e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko} // end namespace clang 126e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko 127