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