Path: blob/main/contrib/llvm-project/clang/utils/TableGen/ClangCommentCommandInfoEmitter.cpp
35231 views
//===--- ClangCommentCommandInfoEmitter.cpp - Generate command lists -----====//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This tablegen backend emits command lists and efficient matchers for command9// names that are used in documentation comments.10//11//===----------------------------------------------------------------------===//1213#include "TableGenBackends.h"1415#include "llvm/TableGen/Record.h"16#include "llvm/TableGen/StringMatcher.h"17#include "llvm/TableGen/TableGenBackend.h"18#include <vector>1920using namespace llvm;2122void clang::EmitClangCommentCommandInfo(RecordKeeper &Records,23raw_ostream &OS) {24emitSourceFileHeader("A list of commands useable in documentation comments",25OS, Records);2627OS << "namespace {\n"28"const CommandInfo Commands[] = {\n";29std::vector<Record *> Tags = Records.getAllDerivedDefinitions("Command");30for (size_t i = 0, e = Tags.size(); i != e; ++i) {31Record &Tag = *Tags[i];32OS << " { "33<< "\"" << Tag.getValueAsString("Name") << "\", "34<< "\"" << Tag.getValueAsString("EndCommandName") << "\", " << i << ", "35<< Tag.getValueAsInt("NumArgs") << ", "36<< Tag.getValueAsBit("IsInlineCommand") << ", "37<< Tag.getValueAsBit("IsBlockCommand") << ", "38<< Tag.getValueAsBit("IsBriefCommand") << ", "39<< Tag.getValueAsBit("IsReturnsCommand") << ", "40<< Tag.getValueAsBit("IsParamCommand") << ", "41<< Tag.getValueAsBit("IsTParamCommand") << ", "42<< Tag.getValueAsBit("IsThrowsCommand") << ", "43<< Tag.getValueAsBit("IsDeprecatedCommand") << ", "44<< Tag.getValueAsBit("IsHeaderfileCommand") << ", "45<< Tag.getValueAsBit("IsParCommand") << ", "46<< Tag.getValueAsBit("IsEmptyParagraphAllowed") << ", "47<< Tag.getValueAsBit("IsVerbatimBlockCommand") << ", "48<< Tag.getValueAsBit("IsVerbatimBlockEndCommand") << ", "49<< Tag.getValueAsBit("IsVerbatimLineCommand") << ", "50<< Tag.getValueAsBit("IsDeclarationCommand") << ", "51<< Tag.getValueAsBit("IsFunctionDeclarationCommand") << ", "52<< Tag.getValueAsBit("IsRecordLikeDetailCommand") << ", "53<< Tag.getValueAsBit("IsRecordLikeDeclarationCommand") << ", "54<< /* IsUnknownCommand = */ "0" << " }";55if (i + 1 != e)56OS << ",";57OS << "\n";58}59OS << "};\n"60"} // unnamed namespace\n\n";6162std::vector<StringMatcher::StringPair> Matches;63for (size_t i = 0, e = Tags.size(); i != e; ++i) {64Record &Tag = *Tags[i];65std::string Name = std::string(Tag.getValueAsString("Name"));66std::string Return;67raw_string_ostream(Return) << "return &Commands[" << i << "];";68Matches.emplace_back(std::move(Name), std::move(Return));69}7071OS << "const CommandInfo *CommandTraits::getBuiltinCommandInfo(\n"72<< " StringRef Name) {\n";73StringMatcher("Name", Matches, OS).Emit();74OS << " return nullptr;\n"75<< "}\n\n";76}7778static std::string MangleName(StringRef Str) {79std::string Mangled;80for (unsigned i = 0, e = Str.size(); i != e; ++i) {81switch (Str[i]) {82default:83Mangled += Str[i];84break;85case '(':86Mangled += "lparen";87break;88case ')':89Mangled += "rparen";90break;91case '[':92Mangled += "lsquare";93break;94case ']':95Mangled += "rsquare";96break;97case '{':98Mangled += "lbrace";99break;100case '}':101Mangled += "rbrace";102break;103case '$':104Mangled += "dollar";105break;106case '/':107Mangled += "slash";108break;109}110}111return Mangled;112}113114void clang::EmitClangCommentCommandList(RecordKeeper &Records,115raw_ostream &OS) {116emitSourceFileHeader("A list of commands useable in documentation comments",117OS, Records);118119OS << "#ifndef COMMENT_COMMAND\n"120<< "# define COMMENT_COMMAND(NAME)\n"121<< "#endif\n";122123std::vector<Record *> Tags = Records.getAllDerivedDefinitions("Command");124for (size_t i = 0, e = Tags.size(); i != e; ++i) {125Record &Tag = *Tags[i];126std::string MangledName = MangleName(Tag.getValueAsString("Name"));127128OS << "COMMENT_COMMAND(" << MangledName << ")\n";129}130}131132133