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 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> 23 24 using namespace clang::extractapi; 25 using namespace llvm; 26 27 namespace { 28 29 template <typename RecordTy, typename... CtorArgsTy> 30 RecordTy *addTopLevelRecord(DenseMap<StringRef, APIRecord *> &USRLookupTable, 31 APISet::RecordMap<RecordTy> &RecordMap, 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 47 GlobalVariableRecord * 48 APISet::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 57 GlobalVariableTemplateRecord *APISet::addGlobalVariableTemplate( 58 StringRef Name, StringRef USR, PresumedLoc Loc, 59 AvailabilitySet Availability, LinkageInfo Linkage, 60 const DocComment &Comment, DeclarationFragments Declaration, 61 DeclarationFragments SubHeading, Template Template, 62 bool IsFromSystemHeader) { 63 return addTopLevelRecord(USRBasedLookupTable, GlobalVariableTemplates, USR, 64 Name, Loc, std::move(Availability), Linkage, Comment, 65 Declaration, SubHeading, Template, 66 IsFromSystemHeader); 67 } 68 69 GlobalFunctionRecord *APISet::addGlobalFunction( 70 StringRef Name, StringRef USR, PresumedLoc Loc, 71 AvailabilitySet Availabilities, LinkageInfo Linkage, 72 const DocComment &Comment, DeclarationFragments Fragments, 73 DeclarationFragments SubHeading, FunctionSignature Signature, 74 bool IsFromSystemHeader) { 75 return addTopLevelRecord(USRBasedLookupTable, GlobalFunctions, USR, Name, Loc, 76 std::move(Availabilities), Linkage, Comment, 77 Fragments, SubHeading, Signature, 78 IsFromSystemHeader); 79 } 80 81 GlobalFunctionTemplateRecord *APISet::addGlobalFunctionTemplate( 82 StringRef Name, StringRef USR, PresumedLoc Loc, 83 AvailabilitySet Availability, LinkageInfo Linkage, 84 const DocComment &Comment, DeclarationFragments Declaration, 85 DeclarationFragments SubHeading, FunctionSignature Signature, 86 Template Template, bool IsFromSystemHeader) { 87 return addTopLevelRecord(USRBasedLookupTable, GlobalFunctionTemplates, USR, 88 Name, Loc, std::move(Availability), Linkage, Comment, 89 Declaration, SubHeading, Signature, Template, 90 IsFromSystemHeader); 91 } 92 93 GlobalFunctionTemplateSpecializationRecord * 94 APISet::addGlobalFunctionTemplateSpecialization( 95 StringRef Name, StringRef USR, PresumedLoc Loc, 96 AvailabilitySet Availability, LinkageInfo Linkage, 97 const DocComment &Comment, DeclarationFragments Declaration, 98 DeclarationFragments SubHeading, FunctionSignature Signature, 99 bool IsFromSystemHeader) { 100 return addTopLevelRecord( 101 USRBasedLookupTable, GlobalFunctionTemplateSpecializations, USR, Name, 102 Loc, std::move(Availability), Linkage, Comment, Declaration, SubHeading, 103 Signature, IsFromSystemHeader); 104 } 105 106 EnumConstantRecord *APISet::addEnumConstant(EnumRecord *Enum, StringRef Name, 107 StringRef USR, PresumedLoc Loc, 108 AvailabilitySet Availabilities, 109 const DocComment &Comment, 110 DeclarationFragments Declaration, 111 DeclarationFragments SubHeading, 112 bool IsFromSystemHeader) { 113 auto Record = std::make_unique<EnumConstantRecord>( 114 USR, Name, Loc, std::move(Availabilities), Comment, Declaration, 115 SubHeading, IsFromSystemHeader); 116 Record->ParentInformation = APIRecord::HierarchyInformation( 117 Enum->USR, Enum->Name, Enum->getKind(), Enum); 118 USRBasedLookupTable.insert({USR, Record.get()}); 119 return Enum->Constants.emplace_back(std::move(Record)).get(); 120 } 121 122 EnumRecord *APISet::addEnum(StringRef Name, StringRef USR, PresumedLoc Loc, 123 AvailabilitySet Availabilities, 124 const DocComment &Comment, 125 DeclarationFragments Declaration, 126 DeclarationFragments SubHeading, 127 bool IsFromSystemHeader) { 128 return addTopLevelRecord(USRBasedLookupTable, Enums, USR, Name, Loc, 129 std::move(Availabilities), Comment, Declaration, 130 SubHeading, IsFromSystemHeader); 131 } 132 133 StructFieldRecord *APISet::addStructField(StructRecord *Struct, StringRef Name, 134 StringRef USR, PresumedLoc Loc, 135 AvailabilitySet Availabilities, 136 const DocComment &Comment, 137 DeclarationFragments Declaration, 138 DeclarationFragments SubHeading, 139 bool IsFromSystemHeader) { 140 auto Record = std::make_unique<StructFieldRecord>( 141 USR, Name, Loc, std::move(Availabilities), Comment, Declaration, 142 SubHeading, IsFromSystemHeader); 143 Record->ParentInformation = APIRecord::HierarchyInformation( 144 Struct->USR, Struct->Name, Struct->getKind(), Struct); 145 USRBasedLookupTable.insert({USR, Record.get()}); 146 return Struct->Fields.emplace_back(std::move(Record)).get(); 147 } 148 149 StructRecord *APISet::addStruct(StringRef Name, StringRef USR, PresumedLoc Loc, 150 AvailabilitySet Availabilities, 151 const DocComment &Comment, 152 DeclarationFragments Declaration, 153 DeclarationFragments SubHeading, 154 bool IsFromSystemHeader) { 155 return addTopLevelRecord(USRBasedLookupTable, Structs, USR, Name, Loc, 156 std::move(Availabilities), Comment, Declaration, 157 SubHeading, IsFromSystemHeader); 158 } 159 160 StaticFieldRecord * 161 APISet::addStaticField(StringRef Name, StringRef USR, PresumedLoc Loc, 162 AvailabilitySet Availabilities, LinkageInfo Linkage, 163 const DocComment &Comment, 164 DeclarationFragments Declaration, 165 DeclarationFragments SubHeading, SymbolReference Context, 166 AccessControl Access, bool IsFromSystemHeader) { 167 return addTopLevelRecord(USRBasedLookupTable, StaticFields, USR, Name, Loc, 168 std::move(Availabilities), Linkage, Comment, 169 Declaration, SubHeading, Context, Access, 170 IsFromSystemHeader); 171 } 172 173 CXXFieldRecord * 174 APISet::addCXXField(CXXClassRecord *CXXClass, StringRef Name, StringRef USR, 175 PresumedLoc Loc, AvailabilitySet Availabilities, 176 const DocComment &Comment, DeclarationFragments Declaration, 177 DeclarationFragments SubHeading, AccessControl Access, 178 bool IsFromSystemHeader) { 179 auto Record = std::make_unique<CXXFieldRecord>( 180 USR, Name, Loc, std::move(Availabilities), Comment, Declaration, 181 SubHeading, Access, IsFromSystemHeader); 182 Record->ParentInformation = APIRecord::HierarchyInformation( 183 CXXClass->USR, CXXClass->Name, CXXClass->getKind(), CXXClass); 184 USRBasedLookupTable.insert({USR, Record.get()}); 185 return CXXClass->Fields.emplace_back(std::move(Record)).get(); 186 } 187 188 CXXClassRecord * 189 APISet::addCXXClass(StringRef Name, StringRef USR, PresumedLoc Loc, 190 AvailabilitySet Availabilities, const DocComment &Comment, 191 DeclarationFragments Declaration, 192 DeclarationFragments SubHeading, APIRecord::RecordKind Kind, 193 bool IsFromSystemHeader) { 194 return addTopLevelRecord(USRBasedLookupTable, CXXClasses, USR, Name, Loc, 195 std::move(Availabilities), Comment, Declaration, 196 SubHeading, Kind, IsFromSystemHeader); 197 } 198 199 ClassTemplateRecord *APISet::addClassTemplate( 200 StringRef Name, StringRef USR, PresumedLoc Loc, 201 AvailabilitySet Availability, const DocComment &Comment, 202 DeclarationFragments Declaration, DeclarationFragments SubHeading, 203 Template Template, bool IsFromSystemHeader) { 204 205 return addTopLevelRecord(USRBasedLookupTable, ClassTemplates, USR, Name, Loc, 206 std::move(Availability), Comment, Declaration, 207 SubHeading, Template, IsFromSystemHeader); 208 } 209 210 ClassTemplateSpecializationRecord *APISet::addClassTemplateSpecialization( 211 StringRef Name, StringRef USR, PresumedLoc Loc, 212 AvailabilitySet Availability, const DocComment &Comment, 213 DeclarationFragments Declaration, DeclarationFragments SubHeading, 214 bool IsFromSystemHeader) { 215 return addTopLevelRecord(USRBasedLookupTable, ClassTemplateSpecializations, 216 USR, Name, Loc, std::move(Availability), Comment, 217 Declaration, SubHeading, IsFromSystemHeader); 218 } 219 220 ClassTemplatePartialSpecializationRecord * 221 APISet::addClassTemplatePartialSpecialization( 222 StringRef Name, StringRef USR, PresumedLoc Loc, 223 AvailabilitySet Availability, const DocComment &Comment, 224 DeclarationFragments Declaration, DeclarationFragments SubHeading, 225 Template Template, bool IsFromSystemHeader) { 226 return addTopLevelRecord(USRBasedLookupTable, 227 ClassTemplatePartialSpecializations, USR, Name, Loc, 228 std::move(Availability), Comment, Declaration, 229 SubHeading, Template, IsFromSystemHeader); 230 } 231 232 GlobalVariableTemplateSpecializationRecord * 233 APISet::addGlobalVariableTemplateSpecialization( 234 StringRef Name, StringRef USR, PresumedLoc Loc, 235 AvailabilitySet Availability, LinkageInfo Linkage, 236 const DocComment &Comment, DeclarationFragments Declaration, 237 DeclarationFragments SubHeading, bool IsFromSystemHeader) { 238 return addTopLevelRecord(USRBasedLookupTable, 239 GlobalVariableTemplateSpecializations, USR, Name, 240 Loc, std::move(Availability), Linkage, Comment, 241 Declaration, SubHeading, IsFromSystemHeader); 242 } 243 244 GlobalVariableTemplatePartialSpecializationRecord * 245 APISet::addGlobalVariableTemplatePartialSpecialization( 246 StringRef Name, StringRef USR, PresumedLoc Loc, 247 AvailabilitySet Availability, LinkageInfo Linkage, 248 const DocComment &Comment, DeclarationFragments Declaration, 249 DeclarationFragments SubHeading, Template Template, 250 bool IsFromSystemHeader) { 251 return addTopLevelRecord( 252 USRBasedLookupTable, GlobalVariableTemplatePartialSpecializations, USR, 253 Name, Loc, std::move(Availability), Linkage, Comment, Declaration, 254 SubHeading, Template, IsFromSystemHeader); 255 } 256 257 ConceptRecord *APISet::addConcept(StringRef Name, StringRef USR, 258 PresumedLoc Loc, AvailabilitySet Availability, 259 const DocComment &Comment, 260 DeclarationFragments Declaration, 261 DeclarationFragments SubHeading, 262 Template Template, bool IsFromSystemHeader) { 263 return addTopLevelRecord(USRBasedLookupTable, Concepts, USR, Name, Loc, 264 std::move(Availability), Comment, Declaration, 265 SubHeading, Template, IsFromSystemHeader); 266 } 267 268 CXXMethodRecord *APISet::addCXXMethod( 269 CXXClassRecord *CXXClassRecord, StringRef Name, StringRef USR, 270 PresumedLoc Loc, AvailabilitySet Availability, const DocComment &Comment, 271 DeclarationFragments Declaration, DeclarationFragments SubHeading, 272 FunctionSignature Signature, bool IsStatic, AccessControl Access, 273 bool IsFromSystemHeader) { 274 std::unique_ptr<CXXMethodRecord> Record; 275 if (IsStatic) 276 Record = std::make_unique<CXXStaticMethodRecord>( 277 USR, Name, Loc, std::move(Availability), Comment, Declaration, 278 SubHeading, Signature, Access, IsFromSystemHeader); 279 else 280 Record = std::make_unique<CXXInstanceMethodRecord>( 281 USR, Name, Loc, std::move(Availability), Comment, Declaration, 282 SubHeading, Signature, Access, IsFromSystemHeader); 283 284 Record->ParentInformation = APIRecord::HierarchyInformation( 285 CXXClassRecord->USR, CXXClassRecord->Name, CXXClassRecord->getKind(), 286 CXXClassRecord); 287 USRBasedLookupTable.insert({USR, Record.get()}); 288 return CXXClassRecord->Methods.emplace_back(std::move(Record)).get(); 289 } 290 291 CXXMethodRecord *APISet::addCXXSpecialMethod( 292 CXXClassRecord *CXXClassRecord, StringRef Name, StringRef USR, 293 PresumedLoc Loc, AvailabilitySet Availability, const DocComment &Comment, 294 DeclarationFragments Declaration, DeclarationFragments SubHeading, 295 FunctionSignature Signature, bool IsConstructor, AccessControl Access, 296 bool IsFromSystemHeader) { 297 std::unique_ptr<CXXMethodRecord> Record; 298 if (IsConstructor) 299 Record = std::make_unique<CXXConstructorRecord>( 300 USR, Name, Loc, std::move(Availability), Comment, Declaration, 301 SubHeading, Signature, Access, IsFromSystemHeader); 302 else 303 Record = std::make_unique<CXXDestructorRecord>( 304 USR, Name, Loc, std::move(Availability), Comment, Declaration, 305 SubHeading, Signature, Access, IsFromSystemHeader); 306 307 Record->ParentInformation = APIRecord::HierarchyInformation( 308 CXXClassRecord->USR, CXXClassRecord->Name, CXXClassRecord->getKind(), 309 CXXClassRecord); 310 USRBasedLookupTable.insert({USR, Record.get()}); 311 return CXXClassRecord->Methods.emplace_back(std::move(Record)).get(); 312 } 313 314 CXXMethodTemplateRecord *APISet::addCXXMethodTemplate( 315 APIRecord *Parent, StringRef Name, StringRef USR, PresumedLoc Loc, 316 AvailabilitySet Availability, const DocComment &Comment, 317 DeclarationFragments Declaration, DeclarationFragments SubHeading, 318 FunctionSignature Signature, AccessControl Access, Template Template, 319 bool IsFromSystemHeader) { 320 auto *Record = addTopLevelRecord(USRBasedLookupTable, CXXMethodTemplates, USR, 321 Name, Loc, std::move(Availability), Comment, 322 Declaration, SubHeading, Signature, Access, 323 Template, IsFromSystemHeader); 324 Record->ParentInformation = APIRecord::HierarchyInformation( 325 Parent->USR, Parent->Name, Parent->getKind(), Parent); 326 327 return Record; 328 } 329 330 CXXMethodTemplateSpecializationRecord *APISet::addCXXMethodTemplateSpec( 331 APIRecord *Parent, StringRef Name, StringRef USR, PresumedLoc Loc, 332 AvailabilitySet Availability, const DocComment &Comment, 333 DeclarationFragments Declaration, DeclarationFragments SubHeading, 334 FunctionSignature Signature, AccessControl Access, 335 bool IsFromSystemHeader) { 336 337 auto *Record = addTopLevelRecord( 338 USRBasedLookupTable, CXXMethodTemplateSpecializations, USR, Name, Loc, 339 std::move(Availability), Comment, Declaration, SubHeading, Signature, 340 Access, IsFromSystemHeader); 341 Record->ParentInformation = APIRecord::HierarchyInformation( 342 Parent->USR, Parent->Name, Parent->getKind(), Parent); 343 344 return Record; 345 } 346 347 ObjCCategoryRecord *APISet::addObjCCategory( 348 StringRef Name, StringRef USR, PresumedLoc Loc, 349 AvailabilitySet Availabilities, const DocComment &Comment, 350 DeclarationFragments Declaration, DeclarationFragments SubHeading, 351 SymbolReference Interface, bool IsFromSystemHeader, 352 bool IsFromExternalModule) { 353 // Create the category record. 354 auto *Record = 355 addTopLevelRecord(USRBasedLookupTable, ObjCCategories, USR, Name, Loc, 356 std::move(Availabilities), Comment, Declaration, 357 SubHeading, Interface, IsFromSystemHeader); 358 359 Record->IsFromExternalModule = IsFromExternalModule; 360 361 auto It = ObjCInterfaces.find(Interface.USR); 362 if (It != ObjCInterfaces.end()) 363 It->second->Categories.push_back(Record); 364 365 return Record; 366 } 367 368 ObjCInterfaceRecord * 369 APISet::addObjCInterface(StringRef Name, StringRef USR, PresumedLoc Loc, 370 AvailabilitySet Availabilities, LinkageInfo Linkage, 371 const DocComment &Comment, 372 DeclarationFragments Declaration, 373 DeclarationFragments SubHeading, 374 SymbolReference SuperClass, bool IsFromSystemHeader) { 375 return addTopLevelRecord(USRBasedLookupTable, ObjCInterfaces, USR, Name, Loc, 376 std::move(Availabilities), Linkage, Comment, 377 Declaration, SubHeading, SuperClass, 378 IsFromSystemHeader); 379 } 380 381 ObjCMethodRecord *APISet::addObjCMethod( 382 ObjCContainerRecord *Container, StringRef Name, StringRef USR, 383 PresumedLoc Loc, AvailabilitySet Availabilities, const DocComment &Comment, 384 DeclarationFragments Declaration, DeclarationFragments SubHeading, 385 FunctionSignature Signature, bool IsInstanceMethod, 386 bool IsFromSystemHeader) { 387 std::unique_ptr<ObjCMethodRecord> Record; 388 if (IsInstanceMethod) 389 Record = std::make_unique<ObjCInstanceMethodRecord>( 390 USR, Name, Loc, std::move(Availabilities), Comment, Declaration, 391 SubHeading, Signature, IsFromSystemHeader); 392 else 393 Record = std::make_unique<ObjCClassMethodRecord>( 394 USR, Name, Loc, std::move(Availabilities), Comment, Declaration, 395 SubHeading, Signature, IsFromSystemHeader); 396 397 Record->ParentInformation = APIRecord::HierarchyInformation( 398 Container->USR, Container->Name, Container->getKind(), Container); 399 USRBasedLookupTable.insert({USR, Record.get()}); 400 return Container->Methods.emplace_back(std::move(Record)).get(); 401 } 402 403 ObjCPropertyRecord *APISet::addObjCProperty( 404 ObjCContainerRecord *Container, StringRef Name, StringRef USR, 405 PresumedLoc Loc, AvailabilitySet Availabilities, const DocComment &Comment, 406 DeclarationFragments Declaration, DeclarationFragments SubHeading, 407 ObjCPropertyRecord::AttributeKind Attributes, StringRef GetterName, 408 StringRef SetterName, bool IsOptional, bool IsInstanceProperty, 409 bool IsFromSystemHeader) { 410 std::unique_ptr<ObjCPropertyRecord> Record; 411 if (IsInstanceProperty) 412 Record = std::make_unique<ObjCInstancePropertyRecord>( 413 USR, Name, Loc, std::move(Availabilities), Comment, Declaration, 414 SubHeading, Attributes, GetterName, SetterName, IsOptional, 415 IsFromSystemHeader); 416 else 417 Record = std::make_unique<ObjCClassPropertyRecord>( 418 USR, Name, Loc, std::move(Availabilities), Comment, Declaration, 419 SubHeading, Attributes, GetterName, SetterName, IsOptional, 420 IsFromSystemHeader); 421 Record->ParentInformation = APIRecord::HierarchyInformation( 422 Container->USR, Container->Name, Container->getKind(), Container); 423 USRBasedLookupTable.insert({USR, Record.get()}); 424 return Container->Properties.emplace_back(std::move(Record)).get(); 425 } 426 427 ObjCInstanceVariableRecord *APISet::addObjCInstanceVariable( 428 ObjCContainerRecord *Container, StringRef Name, StringRef USR, 429 PresumedLoc Loc, AvailabilitySet Availabilities, const DocComment &Comment, 430 DeclarationFragments Declaration, DeclarationFragments SubHeading, 431 ObjCInstanceVariableRecord::AccessControl Access, bool IsFromSystemHeader) { 432 auto Record = std::make_unique<ObjCInstanceVariableRecord>( 433 USR, Name, Loc, std::move(Availabilities), Comment, Declaration, 434 SubHeading, Access, IsFromSystemHeader); 435 Record->ParentInformation = APIRecord::HierarchyInformation( 436 Container->USR, Container->Name, Container->getKind(), Container); 437 USRBasedLookupTable.insert({USR, Record.get()}); 438 return Container->Ivars.emplace_back(std::move(Record)).get(); 439 } 440 441 ObjCProtocolRecord *APISet::addObjCProtocol(StringRef Name, StringRef USR, 442 PresumedLoc Loc, 443 AvailabilitySet Availabilities, 444 const DocComment &Comment, 445 DeclarationFragments Declaration, 446 DeclarationFragments SubHeading, 447 bool IsFromSystemHeader) { 448 return addTopLevelRecord(USRBasedLookupTable, ObjCProtocols, USR, Name, Loc, 449 std::move(Availabilities), Comment, Declaration, 450 SubHeading, IsFromSystemHeader); 451 } 452 453 MacroDefinitionRecord * 454 APISet::addMacroDefinition(StringRef Name, StringRef USR, PresumedLoc Loc, 455 DeclarationFragments Declaration, 456 DeclarationFragments SubHeading, 457 bool IsFromSystemHeader) { 458 return addTopLevelRecord(USRBasedLookupTable, Macros, USR, Name, Loc, 459 Declaration, SubHeading, IsFromSystemHeader); 460 } 461 462 TypedefRecord * 463 APISet::addTypedef(StringRef Name, StringRef USR, PresumedLoc Loc, 464 AvailabilitySet Availabilities, const DocComment &Comment, 465 DeclarationFragments Declaration, 466 DeclarationFragments SubHeading, 467 SymbolReference UnderlyingType, bool IsFromSystemHeader) { 468 return addTopLevelRecord(USRBasedLookupTable, Typedefs, USR, Name, Loc, 469 std::move(Availabilities), Comment, Declaration, 470 SubHeading, UnderlyingType, IsFromSystemHeader); 471 } 472 473 APIRecord *APISet::findRecordForUSR(StringRef USR) const { 474 if (USR.empty()) 475 return nullptr; 476 477 return USRBasedLookupTable.lookup(USR); 478 } 479 480 StringRef APISet::recordUSR(const Decl *D) { 481 SmallString<128> USR; 482 index::generateUSRForDecl(D, USR); 483 return copyString(USR); 484 } 485 486 StringRef APISet::recordUSRForMacro(StringRef Name, SourceLocation SL, 487 const SourceManager &SM) { 488 SmallString<128> USR; 489 index::generateUSRForMacro(Name, SL, SM, USR); 490 return copyString(USR); 491 } 492 493 StringRef APISet::copyString(StringRef String) { 494 if (String.empty()) 495 return {}; 496 497 // No need to allocate memory and copy if the string has already been stored. 498 if (StringAllocator.identifyObject(String.data())) 499 return String; 500 501 void *Ptr = StringAllocator.Allocate(String.size(), 1); 502 memcpy(Ptr, String.data(), String.size()); 503 return StringRef(reinterpret_cast<const char *>(Ptr), String.size()); 504 } 505 506 APIRecord::~APIRecord() {} 507 ObjCContainerRecord::~ObjCContainerRecord() {} 508 ObjCMethodRecord::~ObjCMethodRecord() {} 509 ObjCPropertyRecord::~ObjCPropertyRecord() {} 510 CXXMethodRecord::~CXXMethodRecord() {} 511 512 void GlobalFunctionRecord::anchor() {} 513 void GlobalVariableRecord::anchor() {} 514 void EnumConstantRecord::anchor() {} 515 void EnumRecord::anchor() {} 516 void StructFieldRecord::anchor() {} 517 void StructRecord::anchor() {} 518 void CXXFieldRecord::anchor() {} 519 void CXXClassRecord::anchor() {} 520 void CXXConstructorRecord::anchor() {} 521 void CXXDestructorRecord::anchor() {} 522 void CXXInstanceMethodRecord::anchor() {} 523 void CXXStaticMethodRecord::anchor() {} 524 void ObjCInstancePropertyRecord::anchor() {} 525 void ObjCClassPropertyRecord::anchor() {} 526 void ObjCInstanceVariableRecord::anchor() {} 527 void ObjCInstanceMethodRecord::anchor() {} 528 void ObjCClassMethodRecord::anchor() {} 529 void ObjCCategoryRecord::anchor() {} 530 void ObjCInterfaceRecord::anchor() {} 531 void ObjCProtocolRecord::anchor() {} 532 void MacroDefinitionRecord::anchor() {} 533 void TypedefRecord::anchor() {} 534