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") << ", " 430bd9838751384181ff387f2fb346896792b89617Dmitri Gribenko << Tag.getValueAsBit("IsDeprecatedCommand") << ", " 44f843a580c4a54ca147f22422ee8ccfd2347784fcFariborz Jahanian << Tag.getValueAsBit("IsHeaderfileCommand") << ", " 45abcf0dccc9cd4c802f4e7797bf452c6808d2226fDmitri Gribenko << Tag.getValueAsBit("IsEmptyParagraphAllowed") << ", " 46e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko << Tag.getValueAsBit("IsVerbatimBlockCommand") << ", " 47e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko << Tag.getValueAsBit("IsVerbatimBlockEndCommand") << ", " 48e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko << Tag.getValueAsBit("IsVerbatimLineCommand") << ", " 49e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko << Tag.getValueAsBit("IsDeclarationCommand") << ", " 502a268f2629b49958427e8eb02f2c3d565be71accFariborz Jahanian << Tag.getValueAsBit("IsFunctionDeclarationCommand") << ", " 51b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian << Tag.getValueAsBit("IsRecordLikeDetailCommand") << ", " 52b421b56d5a83c5bcae576b714ebd9df7b745368dFariborz Jahanian << Tag.getValueAsBit("IsRecordLikeDeclarationCommand") << ", " 53e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko << /* IsUnknownCommand = */ "0" 54e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko << " }"; 55e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko if (i + 1 != e) 56e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko OS << ","; 57e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko OS << "\n"; 58e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko } 59e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko OS << "};\n" 60e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko "} // unnamed namespace\n\n"; 61e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko 62e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko std::vector<StringMatcher::StringPair> Matches; 63e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko for (size_t i = 0, e = Tags.size(); i != e; ++i) { 64e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko Record &Tag = *Tags[i]; 65e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko std::string Name = Tag.getValueAsString("Name"); 66e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko std::string Return; 67e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko raw_string_ostream(Return) << "return &Commands[" << i << "];"; 68e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko Matches.push_back(StringMatcher::StringPair(Name, Return)); 69e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko } 70e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko 71e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko OS << "const CommandInfo *CommandTraits::getBuiltinCommandInfo(\n" 72e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko << " StringRef Name) {\n"; 73e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko StringMatcher("Name", Matches, OS).Emit(); 74e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko OS << " return NULL;\n" 75e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko << "}\n\n"; 76e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko} 77af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko 78af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenkostatic std::string MangleName(StringRef Str) { 79af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko std::string Mangled; 80af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko for (unsigned i = 0, e = Str.size(); i != e; ++i) { 81af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko switch (Str[i]) { 82af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko default: 83af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko Mangled += Str[i]; 84af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko break; 85af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko case '[': 86af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko Mangled += "lsquare"; 87af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko break; 88af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko case ']': 89af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko Mangled += "rsquare"; 90af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko break; 91af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko case '{': 92af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko Mangled += "lbrace"; 93af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko break; 94af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko case '}': 95af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko Mangled += "rbrace"; 96af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko break; 97af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko case '$': 98af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko Mangled += "dollar"; 99af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko break; 1005238e40f6ea6346b6bc1505e4975c2c4ab7fde09Fariborz Jahanian case '/': 1015238e40f6ea6346b6bc1505e4975c2c4ab7fde09Fariborz Jahanian Mangled += "slash"; 1025238e40f6ea6346b6bc1505e4975c2c4ab7fde09Fariborz Jahanian break; 103af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko } 104af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko } 105af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko return Mangled; 106af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko} 107af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko 108af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenkovoid EmitClangCommentCommandList(RecordKeeper &Records, raw_ostream &OS) { 109af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko emitSourceFileHeader("A list of commands useable in documentation " 110af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko "comments", OS); 111af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko 112af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko OS << "#ifndef COMMENT_COMMAND\n" 113af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko << "# define COMMENT_COMMAND(NAME)\n" 114af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko << "#endif\n"; 115af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko 116af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko std::vector<Record *> Tags = Records.getAllDerivedDefinitions("Command"); 117af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko for (size_t i = 0, e = Tags.size(); i != e; ++i) { 118af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko Record &Tag = *Tags[i]; 119af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko std::string MangledName = MangleName(Tag.getValueAsString("Name")); 120af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko 121af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko OS << "COMMENT_COMMAND(" << MangledName << ")\n"; 122af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko } 123af01bed59b2fe18fa483f5dbb86584b31eda6f98Dmitri Gribenko} 124e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko} // end namespace clang 125e4330a302ac20b41b9800267ebd4b5b01f8553f8Dmitri Gribenko 126