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