llvm-project

Форк
0
173 строки · 6.5 Кб
1
//===-- Implementation of APIIndexer class --------------------------------===//
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
#include "APIIndexer.h"
10

11
#include "llvm/ADT/StringExtras.h"
12
#include "llvm/ADT/StringRef.h"
13
#include "llvm/TableGen/Error.h"
14
#include "llvm/TableGen/Record.h"
15

16
namespace llvm_libc {
17

18
static const char NamedTypeClassName[] = "NamedType";
19
static const char PtrTypeClassName[] = "PtrType";
20
static const char RestrictedPtrTypeClassName[] = "RestrictedPtrType";
21
static const char ConstTypeClassName[] = "ConstType";
22
static const char StructTypeClassName[] = "Struct";
23

24
static const char StandardSpecClassName[] = "StandardSpec";
25
static const char PublicAPIClassName[] = "PublicAPI";
26

27
static bool isa(llvm::Record *Def, llvm::Record *TypeClass) {
28
  llvm::RecordRecTy *RecordType = Def->getType();
29
  llvm::ArrayRef<llvm::Record *> Classes = RecordType->getClasses();
30
  // We want exact types. That is, we don't want the classes listed in
31
  // spec.td to be subclassed. Hence, we do not want the record |Def|
32
  // to be of more than one class type..
33
  if (Classes.size() != 1)
34
    return false;
35
  return Classes[0] == TypeClass;
36
}
37

38
bool APIIndexer::isaNamedType(llvm::Record *Def) {
39
  return isa(Def, NamedTypeClass);
40
}
41

42
bool APIIndexer::isaStructType(llvm::Record *Def) {
43
  return isa(Def, StructClass);
44
}
45

46
bool APIIndexer::isaPtrType(llvm::Record *Def) {
47
  return isa(Def, PtrTypeClass);
48
}
49

50
bool APIIndexer::isaConstType(llvm::Record *Def) {
51
  return isa(Def, ConstTypeClass);
52
}
53

54
bool APIIndexer::isaRestrictedPtrType(llvm::Record *Def) {
55
  return isa(Def, RestrictedPtrTypeClass);
56
}
57

58
bool APIIndexer::isaStandardSpec(llvm::Record *Def) {
59
  return isa(Def, StandardSpecClass);
60
}
61

62
bool APIIndexer::isaPublicAPI(llvm::Record *Def) {
63
  return isa(Def, PublicAPIClass);
64
}
65

66
std::string APIIndexer::getTypeAsString(llvm::Record *TypeRecord) {
67
  if (isaNamedType(TypeRecord) || isaStructType(TypeRecord)) {
68
    return std::string(TypeRecord->getValueAsString("Name"));
69
  } else if (isaPtrType(TypeRecord)) {
70
    return getTypeAsString(TypeRecord->getValueAsDef("PointeeType")) + " *";
71
  } else if (isaConstType(TypeRecord)) {
72
    return std::string("const ") +
73
           getTypeAsString(TypeRecord->getValueAsDef("UnqualifiedType"));
74
  } else if (isaRestrictedPtrType(TypeRecord)) {
75
    return getTypeAsString(TypeRecord->getValueAsDef("PointeeType")) +
76
           " *__restrict";
77
  } else {
78
    llvm::PrintFatalError(TypeRecord->getLoc(), "Invalid type.\n");
79
  }
80
}
81

82
void APIIndexer::indexStandardSpecDef(llvm::Record *StandardSpec) {
83
  auto HeaderSpecList = StandardSpec->getValueAsListOfDefs("Headers");
84
  for (llvm::Record *HeaderSpec : HeaderSpecList) {
85
    llvm::StringRef Header = HeaderSpec->getValueAsString("Name");
86
    if (!StdHeader.has_value() || Header == StdHeader) {
87
      PublicHeaders.emplace(Header);
88
      auto MacroSpecList = HeaderSpec->getValueAsListOfDefs("Macros");
89
      // TODO: Trigger a fatal error on duplicate specs.
90
      for (llvm::Record *MacroSpec : MacroSpecList)
91
        MacroSpecMap[std::string(MacroSpec->getValueAsString("Name"))] =
92
            MacroSpec;
93

94
      auto TypeSpecList = HeaderSpec->getValueAsListOfDefs("Types");
95
      for (llvm::Record *TypeSpec : TypeSpecList)
96
        TypeSpecMap[std::string(TypeSpec->getValueAsString("Name"))] = TypeSpec;
97

98
      auto FunctionSpecList = HeaderSpec->getValueAsListOfDefs("Functions");
99
      for (llvm::Record *FunctionSpec : FunctionSpecList) {
100
        auto FunctionName = std::string(FunctionSpec->getValueAsString("Name"));
101
        FunctionSpecMap[FunctionName] = FunctionSpec;
102
        FunctionToHeaderMap[FunctionName] = std::string(Header);
103
      }
104

105
      auto EnumerationSpecList =
106
          HeaderSpec->getValueAsListOfDefs("Enumerations");
107
      for (llvm::Record *EnumerationSpec : EnumerationSpecList) {
108
        EnumerationSpecMap[std::string(
109
            EnumerationSpec->getValueAsString("Name"))] = EnumerationSpec;
110
      }
111

112
      auto ObjectSpecList = HeaderSpec->getValueAsListOfDefs("Objects");
113
      for (llvm::Record *ObjectSpec : ObjectSpecList) {
114
        auto ObjectName = std::string(ObjectSpec->getValueAsString("Name"));
115
        ObjectSpecMap[ObjectName] = ObjectSpec;
116
        ObjectToHeaderMap[ObjectName] = std::string(Header);
117
      }
118
    }
119
  }
120
}
121

122
void APIIndexer::indexPublicAPIDef(llvm::Record *PublicAPI) {
123
  // While indexing the public API, we do not check if any of the entities
124
  // requested is from an included standard. Such a check is done while
125
  // generating the API.
126
  auto MacroDefList = PublicAPI->getValueAsListOfDefs("Macros");
127
  for (llvm::Record *MacroDef : MacroDefList)
128
    MacroDefsMap[std::string(MacroDef->getValueAsString("Name"))] = MacroDef;
129

130
  auto TypeList = PublicAPI->getValueAsListOfStrings("Types");
131
  for (llvm::StringRef TypeName : TypeList)
132
    RequiredTypes.insert(std::string(TypeName));
133

134
  auto StructList = PublicAPI->getValueAsListOfStrings("Structs");
135
  for (llvm::StringRef StructName : StructList)
136
    Structs.insert(std::string(StructName));
137

138
  auto FunctionList = PublicAPI->getValueAsListOfStrings("Functions");
139
  for (llvm::StringRef FunctionName : FunctionList)
140
    Functions.insert(std::string(FunctionName));
141

142
  auto EnumerationList = PublicAPI->getValueAsListOfStrings("Enumerations");
143
  for (llvm::StringRef EnumerationName : EnumerationList)
144
    Enumerations.insert(std::string(EnumerationName));
145

146
  auto ObjectList = PublicAPI->getValueAsListOfStrings("Objects");
147
  for (llvm::StringRef ObjectName : ObjectList)
148
    Objects.insert(std::string(ObjectName));
149
}
150

151
void APIIndexer::index(llvm::RecordKeeper &Records) {
152
  NamedTypeClass = Records.getClass(NamedTypeClassName);
153
  PtrTypeClass = Records.getClass(PtrTypeClassName);
154
  RestrictedPtrTypeClass = Records.getClass(RestrictedPtrTypeClassName);
155
  StructClass = Records.getClass(StructTypeClassName);
156
  ConstTypeClass = Records.getClass(ConstTypeClassName);
157
  StandardSpecClass = Records.getClass(StandardSpecClassName);
158
  PublicAPIClass = Records.getClass(PublicAPIClassName);
159

160
  const auto &DefsMap = Records.getDefs();
161
  for (auto &Pair : DefsMap) {
162
    llvm::Record *Def = Pair.second.get();
163
    if (isaStandardSpec(Def))
164
      indexStandardSpecDef(Def);
165
    if (isaPublicAPI(Def)) {
166
      if (!StdHeader.has_value() ||
167
          Def->getValueAsString("HeaderName") == StdHeader)
168
        indexPublicAPIDef(Def);
169
    }
170
  }
171
}
172

173
} // namespace llvm_libc
174

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.