brintos

brintos / llvm-project-archived public Read only

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