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