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