[docs] Fix build-docs.sh
[llvm-project.git] / clang / lib / ExtractAPI / API.cpp
blob8ab03a833e3c2c8ab547300ade5f3f5089aa8d6d
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 //===----------------------------------------------------------------------===//
15 #include "clang/ExtractAPI/API.h"
16 #include "clang/AST/CommentCommandTraits.h"
17 #include "clang/AST/CommentLexer.h"
18 #include "clang/AST/RawCommentList.h"
19 #include "clang/Index/USRGeneration.h"
20 #include "llvm/ADT/STLFunctionalExtras.h"
21 #include "llvm/ADT/StringRef.h"
22 #include <memory>
24 using namespace clang::extractapi;
25 using namespace llvm;
27 namespace {
29 template <typename RecordTy, typename... CtorArgsTy>
30 RecordTy *addTopLevelRecord(APISet::RecordMap<RecordTy> &RecordMap,
31 StringRef USR, CtorArgsTy &&...CtorArgs) {
32 auto Result = RecordMap.insert({USR, nullptr});
34 // Create the record if it does not already exist
35 if (Result.second)
36 Result.first->second =
37 std::make_unique<RecordTy>(USR, std::forward<CtorArgsTy>(CtorArgs)...);
39 return Result.first->second.get();
42 } // namespace
44 GlobalVariableRecord *
45 APISet::addGlobalVar(StringRef Name, StringRef USR, PresumedLoc Loc,
46 AvailabilitySet Availabilities, LinkageInfo Linkage,
47 const DocComment &Comment, DeclarationFragments Fragments,
48 DeclarationFragments SubHeading) {
49 return addTopLevelRecord(GlobalVariables, USR, Name, Loc,
50 std::move(Availabilities), Linkage, Comment,
51 Fragments, SubHeading);
54 GlobalFunctionRecord *APISet::addGlobalFunction(
55 StringRef Name, StringRef USR, PresumedLoc Loc,
56 AvailabilitySet Availabilities, LinkageInfo Linkage,
57 const DocComment &Comment, DeclarationFragments Fragments,
58 DeclarationFragments SubHeading, FunctionSignature Signature) {
59 return addTopLevelRecord(GlobalFunctions, USR, Name, Loc,
60 std::move(Availabilities), Linkage, Comment,
61 Fragments, SubHeading, Signature);
64 EnumConstantRecord *APISet::addEnumConstant(EnumRecord *Enum, StringRef Name,
65 StringRef USR, PresumedLoc Loc,
66 AvailabilitySet Availabilities,
67 const DocComment &Comment,
68 DeclarationFragments Declaration,
69 DeclarationFragments SubHeading) {
70 auto Record = std::make_unique<EnumConstantRecord>(
71 USR, Name, Loc, std::move(Availabilities), Comment, Declaration,
72 SubHeading);
73 return Enum->Constants.emplace_back(std::move(Record)).get();
76 EnumRecord *APISet::addEnum(StringRef Name, StringRef USR, PresumedLoc Loc,
77 AvailabilitySet Availabilities,
78 const DocComment &Comment,
79 DeclarationFragments Declaration,
80 DeclarationFragments SubHeading) {
81 return addTopLevelRecord(Enums, USR, Name, Loc, std::move(Availabilities),
82 Comment, Declaration, SubHeading);
85 StructFieldRecord *APISet::addStructField(StructRecord *Struct, StringRef Name,
86 StringRef USR, PresumedLoc Loc,
87 AvailabilitySet Availabilities,
88 const DocComment &Comment,
89 DeclarationFragments Declaration,
90 DeclarationFragments SubHeading) {
91 auto Record = std::make_unique<StructFieldRecord>(
92 USR, Name, Loc, std::move(Availabilities), Comment, Declaration,
93 SubHeading);
94 return Struct->Fields.emplace_back(std::move(Record)).get();
97 StructRecord *APISet::addStruct(StringRef Name, StringRef USR, PresumedLoc Loc,
98 AvailabilitySet Availabilities,
99 const DocComment &Comment,
100 DeclarationFragments Declaration,
101 DeclarationFragments SubHeading) {
102 return addTopLevelRecord(Structs, USR, Name, Loc, std::move(Availabilities),
103 Comment, Declaration, SubHeading);
106 ObjCCategoryRecord *APISet::addObjCCategory(StringRef Name, StringRef USR,
107 PresumedLoc Loc,
108 AvailabilitySet Availabilities,
109 const DocComment &Comment,
110 DeclarationFragments Declaration,
111 DeclarationFragments SubHeading,
112 SymbolReference Interface) {
113 // Create the category record.
114 auto *Record = addTopLevelRecord(ObjCCategories, USR, Name, Loc,
115 std::move(Availabilities), Comment,
116 Declaration, SubHeading, Interface);
118 // If this category is extending a known interface, associate it with the
119 // ObjCInterfaceRecord.
120 auto It = ObjCInterfaces.find(Interface.USR);
121 if (It != ObjCInterfaces.end())
122 It->second->Categories.push_back(Record);
124 return Record;
127 ObjCInterfaceRecord *APISet::addObjCInterface(
128 StringRef Name, StringRef USR, PresumedLoc Loc,
129 AvailabilitySet Availabilities, LinkageInfo Linkage,
130 const DocComment &Comment, DeclarationFragments Declaration,
131 DeclarationFragments SubHeading, SymbolReference SuperClass) {
132 return addTopLevelRecord(ObjCInterfaces, USR, Name, Loc,
133 std::move(Availabilities), Linkage, Comment,
134 Declaration, SubHeading, SuperClass);
137 ObjCMethodRecord *APISet::addObjCMethod(
138 ObjCContainerRecord *Container, StringRef Name, StringRef USR,
139 PresumedLoc Loc, AvailabilitySet Availabilities, const DocComment &Comment,
140 DeclarationFragments Declaration, DeclarationFragments SubHeading,
141 FunctionSignature Signature, bool IsInstanceMethod) {
142 auto Record = std::make_unique<ObjCMethodRecord>(
143 USR, Name, Loc, std::move(Availabilities), Comment, Declaration,
144 SubHeading, Signature, IsInstanceMethod);
145 return Container->Methods.emplace_back(std::move(Record)).get();
148 ObjCPropertyRecord *APISet::addObjCProperty(
149 ObjCContainerRecord *Container, StringRef Name, StringRef USR,
150 PresumedLoc Loc, AvailabilitySet Availabilities, const DocComment &Comment,
151 DeclarationFragments Declaration, DeclarationFragments SubHeading,
152 ObjCPropertyRecord::AttributeKind Attributes, StringRef GetterName,
153 StringRef SetterName, bool IsOptional) {
154 auto Record = std::make_unique<ObjCPropertyRecord>(
155 USR, Name, Loc, std::move(Availabilities), Comment, Declaration,
156 SubHeading, Attributes, GetterName, SetterName, IsOptional);
157 return Container->Properties.emplace_back(std::move(Record)).get();
160 ObjCInstanceVariableRecord *APISet::addObjCInstanceVariable(
161 ObjCContainerRecord *Container, StringRef Name, StringRef USR,
162 PresumedLoc Loc, AvailabilitySet Availabilities, const DocComment &Comment,
163 DeclarationFragments Declaration, DeclarationFragments SubHeading,
164 ObjCInstanceVariableRecord::AccessControl Access) {
165 auto Record = std::make_unique<ObjCInstanceVariableRecord>(
166 USR, Name, Loc, std::move(Availabilities), Comment, Declaration,
167 SubHeading, Access);
168 return Container->Ivars.emplace_back(std::move(Record)).get();
171 ObjCProtocolRecord *APISet::addObjCProtocol(StringRef Name, StringRef USR,
172 PresumedLoc Loc,
173 AvailabilitySet Availabilities,
174 const DocComment &Comment,
175 DeclarationFragments Declaration,
176 DeclarationFragments SubHeading) {
177 return addTopLevelRecord(ObjCProtocols, USR, Name, Loc,
178 std::move(Availabilities), Comment, Declaration,
179 SubHeading);
182 MacroDefinitionRecord *
183 APISet::addMacroDefinition(StringRef Name, StringRef USR, PresumedLoc Loc,
184 DeclarationFragments Declaration,
185 DeclarationFragments SubHeading) {
186 return addTopLevelRecord(Macros, USR, Name, Loc, Declaration, SubHeading);
189 TypedefRecord *APISet::addTypedef(StringRef Name, StringRef USR,
190 PresumedLoc Loc,
191 AvailabilitySet Availabilities,
192 const DocComment &Comment,
193 DeclarationFragments Declaration,
194 DeclarationFragments SubHeading,
195 SymbolReference UnderlyingType) {
196 return addTopLevelRecord(Typedefs, USR, Name, Loc, std::move(Availabilities),
197 Comment, Declaration, SubHeading, UnderlyingType);
200 StringRef APISet::recordUSR(const Decl *D) {
201 SmallString<128> USR;
202 index::generateUSRForDecl(D, USR);
203 return copyString(USR);
206 StringRef APISet::recordUSRForMacro(StringRef Name, SourceLocation SL,
207 const SourceManager &SM) {
208 SmallString<128> USR;
209 index::generateUSRForMacro(Name, SL, SM, USR);
210 return copyString(USR);
213 StringRef APISet::copyString(StringRef String) {
214 if (String.empty())
215 return {};
217 // No need to allocate memory and copy if the string has already been stored.
218 if (StringAllocator.identifyObject(String.data()))
219 return String;
221 void *Ptr = StringAllocator.Allocate(String.size(), 1);
222 memcpy(Ptr, String.data(), String.size());
223 return StringRef(reinterpret_cast<const char *>(Ptr), String.size());
226 APIRecord::~APIRecord() {}
228 ObjCContainerRecord::~ObjCContainerRecord() {}
230 void GlobalFunctionRecord::anchor() {}
231 void GlobalVariableRecord::anchor() {}
232 void EnumConstantRecord::anchor() {}
233 void EnumRecord::anchor() {}
234 void StructFieldRecord::anchor() {}
235 void StructRecord::anchor() {}
236 void ObjCPropertyRecord::anchor() {}
237 void ObjCInstanceVariableRecord::anchor() {}
238 void ObjCMethodRecord::anchor() {}
239 void ObjCCategoryRecord::anchor() {}
240 void ObjCInterfaceRecord::anchor() {}
241 void ObjCProtocolRecord::anchor() {}
242 void MacroDefinitionRecord::anchor() {}
243 void TypedefRecord::anchor() {}