Coverage Report

Created: 2020-09-19 12:23

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/utils/TableGen/ClangCommentCommandInfoEmitter.cpp
Line
Count
Source (jump to first uncovered line)
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-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
// This tablegen backend emits command lists and efficient matchers for command
10
// 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
21
using namespace llvm;
22
23
0
void clang::EmitClangCommentCommandInfo(RecordKeeper &Records, raw_ostream &OS) {
24
0
  emitSourceFileHeader("A list of commands useable in documentation "
25
0
                       "comments", OS);
26
0
27
0
  OS << "namespace {\n"
28
0
        "const CommandInfo Commands[] = {\n";
29
0
  std::vector<Record *> Tags = Records.getAllDerivedDefinitions("Command");
30
0
  for (size_t i = 0, e = Tags.size(); i != e; ++i) {
31
0
    Record &Tag = *Tags[i];
32
0
    OS << "  { "
33
0
       << "\"" << Tag.getValueAsString("Name") << "\", "
34
0
       << "\"" << Tag.getValueAsString("EndCommandName") << "\", "
35
0
       << i << ", "
36
0
       << Tag.getValueAsInt("NumArgs") << ", "
37
0
       << Tag.getValueAsBit("IsInlineCommand") << ", "
38
0
       << Tag.getValueAsBit("IsBlockCommand") << ", "
39
0
       << Tag.getValueAsBit("IsBriefCommand") << ", "
40
0
       << Tag.getValueAsBit("IsReturnsCommand") << ", "
41
0
       << Tag.getValueAsBit("IsParamCommand") << ", "
42
0
       << Tag.getValueAsBit("IsTParamCommand") << ", "
43
0
       << Tag.getValueAsBit("IsThrowsCommand") << ", "
44
0
       << Tag.getValueAsBit("IsDeprecatedCommand") << ", "
45
0
       << Tag.getValueAsBit("IsHeaderfileCommand") << ", "
46
0
       << Tag.getValueAsBit("IsEmptyParagraphAllowed") << ", "
47
0
       << Tag.getValueAsBit("IsVerbatimBlockCommand") << ", "
48
0
       << Tag.getValueAsBit("IsVerbatimBlockEndCommand") << ", "
49
0
       << Tag.getValueAsBit("IsVerbatimLineCommand") << ", "
50
0
       << Tag.getValueAsBit("IsDeclarationCommand") << ", "
51
0
       << Tag.getValueAsBit("IsFunctionDeclarationCommand") << ", "
52
0
       << Tag.getValueAsBit("IsRecordLikeDetailCommand") << ", "
53
0
       << Tag.getValueAsBit("IsRecordLikeDeclarationCommand") << ", "
54
0
       << /* IsUnknownCommand = */ "0"
55
0
       << " }";
56
0
    if (i + 1 != e)
57
0
      OS << ",";
58
0
    OS << "\n";
59
0
  }
60
0
  OS << "};\n"
61
0
        "} // unnamed namespace\n\n";
62
0
63
0
  std::vector<StringMatcher::StringPair> Matches;
64
0
  for (size_t i = 0, e = Tags.size(); i != e; ++i) {
65
0
    Record &Tag = *Tags[i];
66
0
    std::string Name = std::string(Tag.getValueAsString("Name"));
67
0
    std::string Return;
68
0
    raw_string_ostream(Return) << "return &Commands[" << i << "];";
69
0
    Matches.emplace_back(std::move(Name), std::move(Return));
70
0
  }
71
0
72
0
  OS << "const CommandInfo *CommandTraits::getBuiltinCommandInfo(\n"
73
0
     << "                                         StringRef Name) {\n";
74
0
  StringMatcher("Name", Matches, OS).Emit();
75
0
  OS << "  return nullptr;\n"
76
0
     << "}\n\n";
77
0
}
78
79
0
static std::string MangleName(StringRef Str) {
80
0
  std::string Mangled;
81
0
  for (unsigned i = 0, e = Str.size(); i != e; ++i) {
82
0
    switch (Str[i]) {
83
0
    default:
84
0
      Mangled += Str[i];
85
0
      break;
86
0
    case '[':
87
0
      Mangled += "lsquare";
88
0
      break;
89
0
    case ']':
90
0
      Mangled += "rsquare";
91
0
      break;
92
0
    case '{':
93
0
      Mangled += "lbrace";
94
0
      break;
95
0
    case '}':
96
0
      Mangled += "rbrace";
97
0
      break;
98
0
    case '$':
99
0
      Mangled += "dollar";
100
0
      break;
101
0
    case '/':
102
0
      Mangled += "slash";
103
0
      break;
104
0
    }
105
0
  }
106
0
  return Mangled;
107
0
}
108
109
0
void clang::EmitClangCommentCommandList(RecordKeeper &Records, raw_ostream &OS) {
110
0
  emitSourceFileHeader("A list of commands useable in documentation "
111
0
                       "comments", OS);
112
0
113
0
  OS << "#ifndef COMMENT_COMMAND\n"
114
0
     << "#  define COMMENT_COMMAND(NAME)\n"
115
0
     << "#endif\n";
116
0
117
0
  std::vector<Record *> Tags = Records.getAllDerivedDefinitions("Command");
118
0
  for (size_t i = 0, e = Tags.size(); i != e; ++i) {
119
0
    Record &Tag = *Tags[i];
120
0
    std::string MangledName = MangleName(Tag.getValueAsString("Name"));
121
0
122
0
    OS << "COMMENT_COMMAND(" << MangledName << ")\n";
123
0
  }
124
0
}