clang 17.0.0git
API.cpp
Go to the documentation of this file.
1//===- ExtractAPI/API.cpp ---------------------------------------*- C++ -*-===//
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/// \file
10/// This file implements the APIRecord and derived record structs,
11/// and the APISet class.
12///
13//===----------------------------------------------------------------------===//
14
20#include "llvm/ADT/STLFunctionalExtras.h"
21#include "llvm/ADT/StringRef.h"
22#include <memory>
23
24using namespace clang::extractapi;
25using namespace llvm;
26
27namespace {
28
29template <typename RecordTy, typename... CtorArgsTy>
30RecordTy *addTopLevelRecord(DenseMap<StringRef, APIRecord *> &USRLookupTable,
32 StringRef USR, CtorArgsTy &&...CtorArgs) {
33 auto Result = RecordMap.insert({USR, nullptr});
34
35 // Create the record if it does not already exist
36 if (Result.second)
37 Result.first->second =
38 std::make_unique<RecordTy>(USR, std::forward<CtorArgsTy>(CtorArgs)...);
39
40 auto *Record = Result.first->second.get();
41 USRLookupTable.insert({USR, Record});
42 return Record;
43}
44
45} // namespace
46
48APISet::addGlobalVar(StringRef Name, StringRef USR, PresumedLoc Loc,
49 AvailabilitySet Availabilities, LinkageInfo Linkage,
50 const DocComment &Comment, DeclarationFragments Fragments,
51 DeclarationFragments SubHeading, bool IsFromSystemHeader) {
52 return addTopLevelRecord(USRBasedLookupTable, GlobalVariables, USR, Name, Loc,
53 std::move(Availabilities), Linkage, Comment,
54 Fragments, SubHeading, IsFromSystemHeader);
55}
56
58 StringRef Name, StringRef USR, PresumedLoc Loc,
59 AvailabilitySet Availabilities, LinkageInfo Linkage,
60 const DocComment &Comment, DeclarationFragments Fragments,
61 DeclarationFragments SubHeading, FunctionSignature Signature,
62 bool IsFromSystemHeader) {
63 return addTopLevelRecord(USRBasedLookupTable, GlobalFunctions, USR, Name, Loc,
64 std::move(Availabilities), Linkage, Comment,
65 Fragments, SubHeading, Signature,
66 IsFromSystemHeader);
67}
68
70 StringRef USR, PresumedLoc Loc,
71 AvailabilitySet Availabilities,
72 const DocComment &Comment,
74 DeclarationFragments SubHeading,
75 bool IsFromSystemHeader) {
76 auto Record = std::make_unique<EnumConstantRecord>(
77 USR, Name, Loc, std::move(Availabilities), Comment, Declaration,
78 SubHeading, IsFromSystemHeader);
79 Record->ParentInformation = APIRecord::HierarchyInformation(
80 Enum->USR, Enum->Name, Enum->getKind(), Enum);
81 USRBasedLookupTable.insert({USR, Record.get()});
82 return Enum->Constants.emplace_back(std::move(Record)).get();
83}
84
85EnumRecord *APISet::addEnum(StringRef Name, StringRef USR, PresumedLoc Loc,
86 AvailabilitySet Availabilities,
87 const DocComment &Comment,
89 DeclarationFragments SubHeading,
90 bool IsFromSystemHeader) {
91 return addTopLevelRecord(USRBasedLookupTable, Enums, USR, Name, Loc,
92 std::move(Availabilities), Comment, Declaration,
93 SubHeading, IsFromSystemHeader);
94}
95
97 StringRef USR, PresumedLoc Loc,
98 AvailabilitySet Availabilities,
99 const DocComment &Comment,
101 DeclarationFragments SubHeading,
102 bool IsFromSystemHeader) {
103 auto Record = std::make_unique<StructFieldRecord>(
104 USR, Name, Loc, std::move(Availabilities), Comment, Declaration,
105 SubHeading, IsFromSystemHeader);
106 Record->ParentInformation = APIRecord::HierarchyInformation(
107 Struct->USR, Struct->Name, Struct->getKind(), Struct);
108 USRBasedLookupTable.insert({USR, Record.get()});
109 return Struct->Fields.emplace_back(std::move(Record)).get();
110}
111
112StructRecord *APISet::addStruct(StringRef Name, StringRef USR, PresumedLoc Loc,
113 AvailabilitySet Availabilities,
114 const DocComment &Comment,
116 DeclarationFragments SubHeading,
117 bool IsFromSystemHeader) {
118 return addTopLevelRecord(USRBasedLookupTable, Structs, USR, Name, Loc,
119 std::move(Availabilities), Comment, Declaration,
120 SubHeading, IsFromSystemHeader);
121}
122
124 StringRef Name, StringRef USR, PresumedLoc Loc,
125 AvailabilitySet Availabilities, const DocComment &Comment,
127 SymbolReference Interface, bool IsFromSystemHeader) {
128 // Create the category record.
129 auto *Record =
130 addTopLevelRecord(USRBasedLookupTable, ObjCCategories, USR, Name, Loc,
131 std::move(Availabilities), Comment, Declaration,
132 SubHeading, Interface, IsFromSystemHeader);
133
134 // If this category is extending a known interface, associate it with the
135 // ObjCInterfaceRecord.
136 auto It = ObjCInterfaces.find(Interface.USR);
137 if (It != ObjCInterfaces.end())
138 It->second->Categories.push_back(Record);
139
140 return Record;
141}
142
144APISet::addObjCInterface(StringRef Name, StringRef USR, PresumedLoc Loc,
145 AvailabilitySet Availabilities, LinkageInfo Linkage,
146 const DocComment &Comment,
148 DeclarationFragments SubHeading,
149 SymbolReference SuperClass, bool IsFromSystemHeader) {
150 return addTopLevelRecord(USRBasedLookupTable, ObjCInterfaces, USR, Name, Loc,
151 std::move(Availabilities), Linkage, Comment,
152 Declaration, SubHeading, SuperClass,
153 IsFromSystemHeader);
154}
155
157 ObjCContainerRecord *Container, StringRef Name, StringRef USR,
158 PresumedLoc Loc, AvailabilitySet Availabilities, const DocComment &Comment,
160 FunctionSignature Signature, bool IsInstanceMethod,
161 bool IsFromSystemHeader) {
162 std::unique_ptr<ObjCMethodRecord> Record;
163 if (IsInstanceMethod)
164 Record = std::make_unique<ObjCInstanceMethodRecord>(
165 USR, Name, Loc, std::move(Availabilities), Comment, Declaration,
166 SubHeading, Signature, IsFromSystemHeader);
167 else
168 Record = std::make_unique<ObjCClassMethodRecord>(
169 USR, Name, Loc, std::move(Availabilities), Comment, Declaration,
170 SubHeading, Signature, IsFromSystemHeader);
171
172 Record->ParentInformation = APIRecord::HierarchyInformation(
173 Container->USR, Container->Name, Container->getKind(), Container);
174 USRBasedLookupTable.insert({USR, Record.get()});
175 return Container->Methods.emplace_back(std::move(Record)).get();
176}
177
179 ObjCContainerRecord *Container, StringRef Name, StringRef USR,
180 PresumedLoc Loc, AvailabilitySet Availabilities, const DocComment &Comment,
182 ObjCPropertyRecord::AttributeKind Attributes, StringRef GetterName,
183 StringRef SetterName, bool IsOptional, bool IsInstanceProperty,
184 bool IsFromSystemHeader) {
185 std::unique_ptr<ObjCPropertyRecord> Record;
186 if (IsInstanceProperty)
187 Record = std::make_unique<ObjCInstancePropertyRecord>(
188 USR, Name, Loc, std::move(Availabilities), Comment, Declaration,
189 SubHeading, Attributes, GetterName, SetterName, IsOptional,
190 IsFromSystemHeader);
191 else
192 Record = std::make_unique<ObjCClassPropertyRecord>(
193 USR, Name, Loc, std::move(Availabilities), Comment, Declaration,
194 SubHeading, Attributes, GetterName, SetterName, IsOptional,
195 IsFromSystemHeader);
196 Record->ParentInformation = APIRecord::HierarchyInformation(
197 Container->USR, Container->Name, Container->getKind(), Container);
198 USRBasedLookupTable.insert({USR, Record.get()});
199 return Container->Properties.emplace_back(std::move(Record)).get();
200}
201
203 ObjCContainerRecord *Container, StringRef Name, StringRef USR,
204 PresumedLoc Loc, AvailabilitySet Availabilities, const DocComment &Comment,
206 ObjCInstanceVariableRecord::AccessControl Access, bool IsFromSystemHeader) {
207 auto Record = std::make_unique<ObjCInstanceVariableRecord>(
208 USR, Name, Loc, std::move(Availabilities), Comment, Declaration,
209 SubHeading, Access, IsFromSystemHeader);
210 Record->ParentInformation = APIRecord::HierarchyInformation(
211 Container->USR, Container->Name, Container->getKind(), Container);
212 USRBasedLookupTable.insert({USR, Record.get()});
213 return Container->Ivars.emplace_back(std::move(Record)).get();
214}
215
216ObjCProtocolRecord *APISet::addObjCProtocol(StringRef Name, StringRef USR,
217 PresumedLoc Loc,
218 AvailabilitySet Availabilities,
219 const DocComment &Comment,
221 DeclarationFragments SubHeading,
222 bool IsFromSystemHeader) {
223 return addTopLevelRecord(USRBasedLookupTable, ObjCProtocols, USR, Name, Loc,
224 std::move(Availabilities), Comment, Declaration,
225 SubHeading, IsFromSystemHeader);
226}
227
229APISet::addMacroDefinition(StringRef Name, StringRef USR, PresumedLoc Loc,
231 DeclarationFragments SubHeading,
232 bool IsFromSystemHeader) {
233 return addTopLevelRecord(USRBasedLookupTable, Macros, USR, Name, Loc,
234 Declaration, SubHeading, IsFromSystemHeader);
235}
236
238APISet::addTypedef(StringRef Name, StringRef USR, PresumedLoc Loc,
239 AvailabilitySet Availabilities, const DocComment &Comment,
241 DeclarationFragments SubHeading,
242 SymbolReference UnderlyingType, bool IsFromSystemHeader) {
243 return addTopLevelRecord(USRBasedLookupTable, Typedefs, USR, Name, Loc,
244 std::move(Availabilities), Comment, Declaration,
245 SubHeading, UnderlyingType, IsFromSystemHeader);
246}
247
248APIRecord *APISet::findRecordForUSR(StringRef USR) const {
249 if (USR.empty())
250 return nullptr;
251
252 auto It = USRBasedLookupTable.find(USR);
253 if (It != USRBasedLookupTable.end())
254 return It->second;
255 return nullptr;
256}
257
258StringRef APISet::recordUSR(const Decl *D) {
261 return copyString(USR);
262}
263
264StringRef APISet::recordUSRForMacro(StringRef Name, SourceLocation SL,
265 const SourceManager &SM) {
267 index::generateUSRForMacro(Name, SL, SM, USR);
268 return copyString(USR);
269}
270
271StringRef APISet::copyString(StringRef String) {
272 if (String.empty())
273 return {};
274
275 // No need to allocate memory and copy if the string has already been stored.
276 if (StringAllocator.identifyObject(String.data()))
277 return String;
278
279 void *Ptr = StringAllocator.Allocate(String.size(), 1);
280 memcpy(Ptr, String.data(), String.size());
281 return StringRef(reinterpret_cast<const char *>(Ptr), String.size());
282}
283
288
289void GlobalFunctionRecord::anchor() {}
290void GlobalVariableRecord::anchor() {}
291void EnumConstantRecord::anchor() {}
292void EnumRecord::anchor() {}
293void StructFieldRecord::anchor() {}
294void StructRecord::anchor() {}
295void ObjCInstancePropertyRecord::anchor() {}
296void ObjCClassPropertyRecord::anchor() {}
297void ObjCInstanceVariableRecord::anchor() {}
298void ObjCInstanceMethodRecord::anchor() {}
299void ObjCClassMethodRecord::anchor() {}
300void ObjCCategoryRecord::anchor() {}
301void ObjCInterfaceRecord::anchor() {}
302void ObjCProtocolRecord::anchor() {}
303void MacroDefinitionRecord::anchor() {}
304void TypedefRecord::anchor() {}
This file defines the APIRecord-based structs and the APISet class.
#define SM(sm)
Definition: Cuda.cpp:80
__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:83
Represents an unpacked "presumed" location which can be presented to the user.
Encodes a location in the source.
This class handles loading and caching of source files into memory.
ObjCMethodRecord * addObjCMethod(ObjCContainerRecord *Container, StringRef Name, StringRef USR, PresumedLoc Loc, AvailabilitySet Availability, const DocComment &Comment, DeclarationFragments Declaration, DeclarationFragments SubHeading, FunctionSignature Signature, bool IsInstanceMethod, bool IsFromSystemHeader)
Create and add an Objective-C method record into the API set.
Definition: API.cpp:156
ObjCPropertyRecord * addObjCProperty(ObjCContainerRecord *Container, StringRef Name, StringRef USR, PresumedLoc Loc, AvailabilitySet Availability, const DocComment &Comment, DeclarationFragments Declaration, DeclarationFragments SubHeading, ObjCPropertyRecord::AttributeKind Attributes, StringRef GetterName, StringRef SetterName, bool IsOptional, bool IsInstanceProperty, bool IsFromSystemHeader)
Create and add an Objective-C property record into the API set.
Definition: API.cpp:178
StringRef copyString(StringRef String)
Copy String into the Allocator in this APISet.
Definition: API.cpp:271
TypedefRecord * addTypedef(StringRef Name, StringRef USR, PresumedLoc Loc, AvailabilitySet Availability, const DocComment &Comment, DeclarationFragments Declaration, DeclarationFragments SubHeading, SymbolReference UnderlyingType, bool IsFromSystemHeader)
Create a typedef record into the API set.
Definition: API.cpp:238
GlobalVariableRecord * addGlobalVar(StringRef Name, StringRef USR, PresumedLoc Loc, AvailabilitySet Availability, LinkageInfo Linkage, const DocComment &Comment, DeclarationFragments Declaration, DeclarationFragments SubHeadin, bool IsFromSystemHeaderg)
Create and add a global variable record into the API set.
Definition: API.cpp:48
StructFieldRecord * addStructField(StructRecord *Struct, StringRef Name, StringRef USR, PresumedLoc Loc, AvailabilitySet Availability, const DocComment &Comment, DeclarationFragments Declaration, DeclarationFragments SubHeading, bool IsFromSystemHeader)
Create and add a struct field record into the API set.
Definition: API.cpp:96
ObjCProtocolRecord * addObjCProtocol(StringRef Name, StringRef USR, PresumedLoc Loc, AvailabilitySet Availability, const DocComment &Comment, DeclarationFragments Declaration, DeclarationFragments SubHeading, bool IsFromSystemHeader)
Create and add an Objective-C protocol record into the API set.
Definition: API.cpp:216
ObjCInstanceVariableRecord * addObjCInstanceVariable(ObjCContainerRecord *Container, StringRef Name, StringRef USR, PresumedLoc Loc, AvailabilitySet Availability, const DocComment &Comment, DeclarationFragments Declaration, DeclarationFragments SubHeading, ObjCInstanceVariableRecord::AccessControl Access, bool IsFromSystemHeader)
Create and add an Objective-C instance variable record into the API set.
Definition: API.cpp:202
ObjCCategoryRecord * addObjCCategory(StringRef Name, StringRef USR, PresumedLoc Loc, AvailabilitySet Availability, const DocComment &Comment, DeclarationFragments Declaration, DeclarationFragments SubHeading, SymbolReference Interface, bool IsFromSystemHeader)
Create and add an Objective-C category record into the API set.
Definition: API.cpp:123
ObjCInterfaceRecord * addObjCInterface(StringRef Name, StringRef USR, PresumedLoc Loc, AvailabilitySet Availability, LinkageInfo Linkage, const DocComment &Comment, DeclarationFragments Declaration, DeclarationFragments SubHeading, SymbolReference SuperClass, bool IsFromSystemHeader)
Create and add an Objective-C interface record into the API set.
Definition: API.cpp:144
GlobalFunctionRecord * addGlobalFunction(StringRef Name, StringRef USR, PresumedLoc Loc, AvailabilitySet Availability, LinkageInfo Linkage, const DocComment &Comment, DeclarationFragments Declaration, DeclarationFragments SubHeading, FunctionSignature Signature, bool IsFromSystemHeader)
Create and add a function record into the API set.
Definition: API.cpp:57
MacroDefinitionRecord * addMacroDefinition(StringRef Name, StringRef USR, PresumedLoc Loc, DeclarationFragments Declaration, DeclarationFragments SubHeading, bool IsFromSystemHeader)
Create a macro definition record into the API set.
Definition: API.cpp:229
EnumConstantRecord * addEnumConstant(EnumRecord *Enum, StringRef Name, StringRef USR, PresumedLoc Loc, AvailabilitySet Availability, const DocComment &Comment, DeclarationFragments Declaration, DeclarationFragments SubHeading, bool IsFromSystemHeader)
Create and add an enum constant record into the API set.
Definition: API.cpp:69
StringRef recordUSR(const Decl *D)
Generate and store the USR of declaration D.
Definition: API.cpp:258
StringRef recordUSRForMacro(StringRef Name, SourceLocation SL, const SourceManager &SM)
Generate and store the USR for a macro Name.
Definition: API.cpp:264
StructRecord * addStruct(StringRef Name, StringRef USR, PresumedLoc Loc, AvailabilitySet Availability, const DocComment &Comment, DeclarationFragments Declaration, DeclarationFragments SubHeading, bool IsFromSystemHeader)
Create and add a struct record into the API set.
Definition: API.cpp:112
APIRecord * findRecordForUSR(StringRef USR) const
Finds the APIRecord for a given USR.
Definition: API.cpp:248
llvm::MapVector< StringRef, std::unique_ptr< RecordTy > > RecordMap
A mapping type to store a set of APIRecords with the USR as the key.
Definition: API.h:779
EnumRecord * addEnum(StringRef Name, StringRef USR, PresumedLoc Loc, AvailabilitySet Availability, const DocComment &Comment, DeclarationFragments Declaration, DeclarationFragments SubHeading, bool IsFromSystemHeader)
Create and add an enum record into the API set.
Definition: API.cpp:85
DeclarationFragments is a vector of tagged important parts of a symbol's declaration.
Store function signature information with DeclarationFragments of the return type and parameters.
std::vector< RawComment::CommentLine > DocComment
DocComment is a vector of RawComment::CommentLine.
Definition: API.h:51
bool generateUSRForMacro(const MacroDefinitionRecord *MD, const SourceManager &SM, SmallVectorImpl< char > &Buf)
Generate a USR for a macro, including the USR prefix.
bool generateUSRForDecl(const Decl *D, SmallVectorImpl< char > &Buf)
Generate a USR for a Decl, including the USR prefix.
Linkage
Describes the different kinds of linkage (C++ [basic.link], C99 6.2.2) that an entity may have.
Definition: Linkage.h:23
YAML serialization mapping.
Definition: Dominators.h:30
Stores information about the context of the declaration of this API.
Definition: API.h:81
The base representation of an API record. Holds common symbol information.
Definition: API.h:57
virtual ~APIRecord()=0
Definition: API.cpp:284
This holds information associated with enum constants.
Definition: API.h:194
This holds information associated with enums.
Definition: API.h:212
This holds information associated with global functions.
Definition: API.h:152
This holds information associated with global functions.
Definition: API.h:175
This holds information associated with macro definitions.
Definition: API.h:536
This holds information associated with Objective-C categories.
Definition: API.h:469
The base representation of an Objective-C container record.
Definition: API.h:449
This holds information associated with Objective-C instance variables.
Definition: API.h:347
This holds information associated with Objective-C interfaces/classes.
Definition: API.h:492
This holds information associated with Objective-C methods.
Definition: API.h:371
This holds information associated with Objective-C properties.
Definition: API.h:270
AttributeKind
The attributes associated with an Objective-C property.
Definition: API.h:272
This holds information associated with Objective-C protocols.
Definition: API.h:517
This holds information associated with struct fields.
Definition: API.h:232
This holds information associated with structs.
Definition: API.h:250
This represents a reference to another symbol that might come from external sources.
Definition: API.h:428
This holds information associated with typedefs.
Definition: API.h:558