1 //===- ExtractAPI/API.h -----------------------------------------*- 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 defines the APIRecord-based structs and the APISet class. 11 /// 12 /// Clang ExtractAPI is a tool to collect API information from a given set of 13 /// header files. The structures in this file describe data representations of 14 /// the API information collected for various kinds of symbols. 15 /// 16 //===----------------------------------------------------------------------===// 17 18 #ifndef LLVM_CLANG_EXTRACTAPI_API_H 19 #define LLVM_CLANG_EXTRACTAPI_API_H 20 21 #include "clang/AST/Decl.h" 22 #include "clang/AST/DeclObjC.h" 23 #include "clang/AST/RawCommentList.h" 24 #include "clang/Basic/SourceLocation.h" 25 #include "clang/ExtractAPI/AvailabilityInfo.h" 26 #include "clang/ExtractAPI/DeclarationFragments.h" 27 #include "llvm/ADT/MapVector.h" 28 #include "llvm/ADT/StringRef.h" 29 #include "llvm/ADT/Triple.h" 30 #include "llvm/Support/Allocator.h" 31 #include "llvm/Support/Casting.h" 32 #include <memory> 33 #include <type_traits> 34 35 namespace clang { 36 namespace extractapi { 37 38 /// DocComment is a vector of RawComment::CommentLine. 39 /// 40 /// Each line represents one line of striped documentation comment, 41 /// with source range information. This simplifies calculating the source 42 /// location of a character in the doc comment for pointing back to the source 43 /// file. 44 /// e.g. 45 /// \code 46 /// /// This is a documentation comment 47 /// ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~' First line. 48 /// /// with multiple lines. 49 /// ^~~~~~~~~~~~~~~~~~~~~~~' Second line. 50 /// \endcode 51 using DocComment = std::vector<RawComment::CommentLine>; 52 53 // Classes deriving from APIRecord need to have USR be the first constructor 54 // argument. This is so that they are compatible with `addTopLevelRecord` 55 // defined in API.cpp 56 /// The base representation of an API record. Holds common symbol information. 57 struct APIRecord { 58 /// Discriminator for LLVM-style RTTI (dyn_cast<> et al.) 59 enum RecordKind { 60 RK_Unknown, 61 RK_GlobalFunction, 62 RK_GlobalVariable, 63 RK_EnumConstant, 64 RK_Enum, 65 RK_StructField, 66 RK_Struct, 67 RK_ObjCInstanceProperty, 68 RK_ObjCClassProperty, 69 RK_ObjCIvar, 70 RK_ObjCClassMethod, 71 RK_ObjCInstanceMethod, 72 RK_ObjCInterface, 73 RK_ObjCCategory, 74 RK_ObjCProtocol, 75 RK_MacroDefinition, 76 RK_Typedef, 77 }; 78 79 /// Stores information about the context of the declaration of this API. 80 /// This is roughly analogous to the DeclContext hierarchy for an AST Node. 81 struct HierarchyInformation { 82 /// The USR of the parent API. 83 StringRef ParentUSR; 84 /// The name of the parent API. 85 StringRef ParentName; 86 /// The record kind of the parent API. 87 RecordKind ParentKind = RK_Unknown; 88 /// A pointer to the parent APIRecord if known. 89 APIRecord *ParentRecord = nullptr; 90 91 HierarchyInformation() = default; 92 HierarchyInformation(StringRef ParentUSR, StringRef ParentName, 93 RecordKind Kind, APIRecord *ParentRecord = nullptr) 94 : ParentUSR(ParentUSR), ParentName(ParentName), ParentKind(Kind), 95 ParentRecord(ParentRecord) {} 96 97 bool empty() const { 98 return ParentUSR.empty() && ParentName.empty() && 99 ParentKind == RK_Unknown && ParentRecord == nullptr; 100 } 101 }; 102 103 StringRef USR; 104 StringRef Name; 105 PresumedLoc Location; 106 AvailabilitySet Availabilities; 107 LinkageInfo Linkage; 108 109 /// Documentation comment lines attached to this symbol declaration. 110 DocComment Comment; 111 112 /// Declaration fragments of this symbol declaration. 113 DeclarationFragments Declaration; 114 115 /// SubHeading provides a more detailed representation than the plain 116 /// declaration name. 117 /// 118 /// SubHeading is an array of declaration fragments of tagged declaration 119 /// name, with potentially more tokens (for example the \c +/- symbol for 120 /// Objective-C class/instance methods). 121 DeclarationFragments SubHeading; 122 123 /// Information about the parent record of this record. 124 HierarchyInformation ParentInformation; 125 126 /// Whether the symbol was defined in a system header. 127 bool IsFromSystemHeader; 128 129 private: 130 const RecordKind Kind; 131 132 public: 133 RecordKind getKind() const { return Kind; } 134 135 APIRecord() = delete; 136 137 APIRecord(RecordKind Kind, StringRef USR, StringRef Name, 138 PresumedLoc Location, AvailabilitySet Availabilities, 139 LinkageInfo Linkage, const DocComment &Comment, 140 DeclarationFragments Declaration, DeclarationFragments SubHeading, 141 bool IsFromSystemHeader) 142 : USR(USR), Name(Name), Location(Location), 143 Availabilities(std::move(Availabilities)), Linkage(Linkage), 144 Comment(Comment), Declaration(Declaration), SubHeading(SubHeading), 145 IsFromSystemHeader(IsFromSystemHeader), Kind(Kind) {} 146 147 // Pure virtual destructor to make APIRecord abstract 148 virtual ~APIRecord() = 0; 149 }; 150 151 /// This holds information associated with global functions. 152 struct GlobalFunctionRecord : APIRecord { 153 FunctionSignature Signature; 154 155 GlobalFunctionRecord(StringRef USR, StringRef Name, PresumedLoc Loc, 156 AvailabilitySet Availabilities, LinkageInfo Linkage, 157 const DocComment &Comment, 158 DeclarationFragments Declaration, 159 DeclarationFragments SubHeading, 160 FunctionSignature Signature, bool IsFromSystemHeader) 161 : APIRecord(RK_GlobalFunction, USR, Name, Loc, std::move(Availabilities), 162 Linkage, Comment, Declaration, SubHeading, 163 IsFromSystemHeader), 164 Signature(Signature) {} 165 166 static bool classof(const APIRecord *Record) { 167 return Record->getKind() == RK_GlobalFunction; 168 } 169 170 private: 171 virtual void anchor(); 172 }; 173 174 /// This holds information associated with global functions. 175 struct GlobalVariableRecord : APIRecord { 176 GlobalVariableRecord(StringRef USR, StringRef Name, PresumedLoc Loc, 177 AvailabilitySet Availabilities, LinkageInfo Linkage, 178 const DocComment &Comment, 179 DeclarationFragments Declaration, 180 DeclarationFragments SubHeading, bool IsFromSystemHeader) 181 : APIRecord(RK_GlobalVariable, USR, Name, Loc, std::move(Availabilities), 182 Linkage, Comment, Declaration, SubHeading, 183 IsFromSystemHeader) {} 184 185 static bool classof(const APIRecord *Record) { 186 return Record->getKind() == RK_GlobalVariable; 187 } 188 189 private: 190 virtual void anchor(); 191 }; 192 193 /// This holds information associated with enum constants. 194 struct EnumConstantRecord : APIRecord { 195 EnumConstantRecord(StringRef USR, StringRef Name, PresumedLoc Loc, 196 AvailabilitySet Availabilities, const DocComment &Comment, 197 DeclarationFragments Declaration, 198 DeclarationFragments SubHeading, bool IsFromSystemHeader) 199 : APIRecord(RK_EnumConstant, USR, Name, Loc, std::move(Availabilities), 200 LinkageInfo::none(), Comment, Declaration, SubHeading, 201 IsFromSystemHeader) {} 202 203 static bool classof(const APIRecord *Record) { 204 return Record->getKind() == RK_EnumConstant; 205 } 206 207 private: 208 virtual void anchor(); 209 }; 210 211 /// This holds information associated with enums. 212 struct EnumRecord : APIRecord { 213 SmallVector<std::unique_ptr<EnumConstantRecord>> Constants; 214 215 EnumRecord(StringRef USR, StringRef Name, PresumedLoc Loc, 216 AvailabilitySet Availabilities, const DocComment &Comment, 217 DeclarationFragments Declaration, DeclarationFragments SubHeading, 218 bool IsFromSystemHeader) 219 : APIRecord(RK_Enum, USR, Name, Loc, std::move(Availabilities), 220 LinkageInfo::none(), Comment, Declaration, SubHeading, 221 IsFromSystemHeader) {} 222 223 static bool classof(const APIRecord *Record) { 224 return Record->getKind() == RK_Enum; 225 } 226 227 private: 228 virtual void anchor(); 229 }; 230 231 /// This holds information associated with struct fields. 232 struct StructFieldRecord : APIRecord { 233 StructFieldRecord(StringRef USR, StringRef Name, PresumedLoc Loc, 234 AvailabilitySet Availabilities, const DocComment &Comment, 235 DeclarationFragments Declaration, 236 DeclarationFragments SubHeading, bool IsFromSystemHeader) 237 : APIRecord(RK_StructField, USR, Name, Loc, std::move(Availabilities), 238 LinkageInfo::none(), Comment, Declaration, SubHeading, 239 IsFromSystemHeader) {} 240 241 static bool classof(const APIRecord *Record) { 242 return Record->getKind() == RK_StructField; 243 } 244 245 private: 246 virtual void anchor(); 247 }; 248 249 /// This holds information associated with structs. 250 struct StructRecord : APIRecord { 251 SmallVector<std::unique_ptr<StructFieldRecord>> Fields; 252 253 StructRecord(StringRef USR, StringRef Name, PresumedLoc Loc, 254 AvailabilitySet Availabilities, const DocComment &Comment, 255 DeclarationFragments Declaration, 256 DeclarationFragments SubHeading, bool IsFromSystemHeader) 257 : APIRecord(RK_Struct, USR, Name, Loc, std::move(Availabilities), 258 LinkageInfo::none(), Comment, Declaration, SubHeading, 259 IsFromSystemHeader) {} 260 261 static bool classof(const APIRecord *Record) { 262 return Record->getKind() == RK_Struct; 263 } 264 265 private: 266 virtual void anchor(); 267 }; 268 269 /// This holds information associated with Objective-C properties. 270 struct ObjCPropertyRecord : APIRecord { 271 /// The attributes associated with an Objective-C property. 272 enum AttributeKind : unsigned { 273 NoAttr = 0, 274 ReadOnly = 1, 275 Dynamic = 1 << 2, 276 }; 277 278 AttributeKind Attributes; 279 StringRef GetterName; 280 StringRef SetterName; 281 bool IsOptional; 282 283 ObjCPropertyRecord(RecordKind Kind, StringRef USR, StringRef Name, 284 PresumedLoc Loc, AvailabilitySet Availabilities, 285 const DocComment &Comment, 286 DeclarationFragments Declaration, 287 DeclarationFragments SubHeading, AttributeKind Attributes, 288 StringRef GetterName, StringRef SetterName, 289 bool IsOptional, bool IsFromSystemHeader) 290 : APIRecord(Kind, USR, Name, Loc, std::move(Availabilities), 291 LinkageInfo::none(), Comment, Declaration, SubHeading, 292 IsFromSystemHeader), 293 Attributes(Attributes), GetterName(GetterName), SetterName(SetterName), 294 IsOptional(IsOptional) {} 295 296 bool isReadOnly() const { return Attributes & ReadOnly; } 297 bool isDynamic() const { return Attributes & Dynamic; } 298 299 virtual ~ObjCPropertyRecord() = 0; 300 }; 301 302 struct ObjCInstancePropertyRecord : ObjCPropertyRecord { 303 ObjCInstancePropertyRecord(StringRef USR, StringRef Name, PresumedLoc Loc, 304 AvailabilitySet Availabilities, 305 const DocComment &Comment, 306 DeclarationFragments Declaration, 307 DeclarationFragments SubHeading, 308 AttributeKind Attributes, StringRef GetterName, 309 StringRef SetterName, bool IsOptional, 310 bool IsFromSystemHeader) 311 : ObjCPropertyRecord(RK_ObjCInstanceProperty, USR, Name, Loc, 312 std::move(Availabilities), Comment, Declaration, 313 SubHeading, Attributes, GetterName, SetterName, 314 IsOptional, IsFromSystemHeader) {} 315 316 static bool classof(const APIRecord *Record) { 317 return Record->getKind() == RK_ObjCInstanceProperty; 318 } 319 320 private: 321 virtual void anchor(); 322 }; 323 324 struct ObjCClassPropertyRecord : ObjCPropertyRecord { 325 ObjCClassPropertyRecord(StringRef USR, StringRef Name, PresumedLoc Loc, 326 AvailabilitySet Availabilities, 327 const DocComment &Comment, 328 DeclarationFragments Declaration, 329 DeclarationFragments SubHeading, 330 AttributeKind Attributes, StringRef GetterName, 331 StringRef SetterName, bool IsOptional, 332 bool IsFromSystemHeader) 333 : ObjCPropertyRecord(RK_ObjCClassProperty, USR, Name, Loc, 334 std::move(Availabilities), Comment, Declaration, 335 SubHeading, Attributes, GetterName, SetterName, 336 IsOptional, IsFromSystemHeader) {} 337 338 static bool classof(const APIRecord *Record) { 339 return Record->getKind() == RK_ObjCClassProperty; 340 } 341 342 private: 343 virtual void anchor(); 344 }; 345 346 /// This holds information associated with Objective-C instance variables. 347 struct ObjCInstanceVariableRecord : APIRecord { 348 using AccessControl = ObjCIvarDecl::AccessControl; 349 AccessControl Access; 350 351 ObjCInstanceVariableRecord(StringRef USR, StringRef Name, PresumedLoc Loc, 352 AvailabilitySet Availabilities, 353 const DocComment &Comment, 354 DeclarationFragments Declaration, 355 DeclarationFragments SubHeading, 356 AccessControl Access, bool IsFromSystemHeader) 357 : APIRecord(RK_ObjCIvar, USR, Name, Loc, std::move(Availabilities), 358 LinkageInfo::none(), Comment, Declaration, SubHeading, 359 IsFromSystemHeader), 360 Access(Access) {} 361 362 static bool classof(const APIRecord *Record) { 363 return Record->getKind() == RK_ObjCIvar; 364 } 365 366 private: 367 virtual void anchor(); 368 }; 369 370 /// This holds information associated with Objective-C methods. 371 struct ObjCMethodRecord : APIRecord { 372 FunctionSignature Signature; 373 374 ObjCMethodRecord() = delete; 375 376 ObjCMethodRecord(RecordKind Kind, StringRef USR, StringRef Name, 377 PresumedLoc Loc, AvailabilitySet Availabilities, 378 const DocComment &Comment, DeclarationFragments Declaration, 379 DeclarationFragments SubHeading, FunctionSignature Signature, 380 bool IsFromSystemHeader) 381 : APIRecord(Kind, USR, Name, Loc, std::move(Availabilities), 382 LinkageInfo::none(), Comment, Declaration, SubHeading, 383 IsFromSystemHeader), 384 Signature(Signature) {} 385 386 virtual ~ObjCMethodRecord() = 0; 387 }; 388 389 struct ObjCInstanceMethodRecord : ObjCMethodRecord { 390 ObjCInstanceMethodRecord(StringRef USR, StringRef Name, PresumedLoc Loc, 391 AvailabilitySet Availabilities, 392 const DocComment &Comment, 393 DeclarationFragments Declaration, 394 DeclarationFragments SubHeading, 395 FunctionSignature Signature, bool IsFromSystemHeader) 396 : ObjCMethodRecord(RK_ObjCInstanceMethod, USR, Name, Loc, 397 std::move(Availabilities), Comment, Declaration, 398 SubHeading, Signature, IsFromSystemHeader) {} 399 static bool classof(const APIRecord *Record) { 400 return Record->getKind() == RK_ObjCInstanceMethod; 401 } 402 403 private: 404 virtual void anchor(); 405 }; 406 407 struct ObjCClassMethodRecord : ObjCMethodRecord { 408 ObjCClassMethodRecord(StringRef USR, StringRef Name, PresumedLoc Loc, 409 AvailabilitySet Availabilities, 410 const DocComment &Comment, 411 DeclarationFragments Declaration, 412 DeclarationFragments SubHeading, 413 FunctionSignature Signature, bool IsFromSystemHeader) 414 : ObjCMethodRecord(RK_ObjCClassMethod, USR, Name, Loc, 415 std::move(Availabilities), Comment, Declaration, 416 SubHeading, Signature, IsFromSystemHeader) {} 417 418 static bool classof(const APIRecord *Record) { 419 return Record->getKind() == RK_ObjCClassMethod; 420 } 421 422 private: 423 virtual void anchor(); 424 }; 425 426 /// This represents a reference to another symbol that might come from external 427 /// sources. 428 struct SymbolReference { 429 StringRef Name; 430 StringRef USR; 431 432 /// The source project/module/product of the referred symbol. 433 StringRef Source; 434 435 SymbolReference() = default; 436 SymbolReference(StringRef Name, StringRef USR = "", StringRef Source = "") 437 : Name(Name), USR(USR), Source(Source) {} 438 SymbolReference(const APIRecord &Record) 439 : Name(Record.Name), USR(Record.USR) {} 440 441 /// Determine if this SymbolReference is empty. 442 /// 443 /// \returns true if and only if all \c Name, \c USR, and \c Source is empty. 444 bool empty() const { return Name.empty() && USR.empty() && Source.empty(); } 445 }; 446 447 /// The base representation of an Objective-C container record. Holds common 448 /// information associated with Objective-C containers. 449 struct ObjCContainerRecord : APIRecord { 450 SmallVector<std::unique_ptr<ObjCMethodRecord>> Methods; 451 SmallVector<std::unique_ptr<ObjCPropertyRecord>> Properties; 452 SmallVector<std::unique_ptr<ObjCInstanceVariableRecord>> Ivars; 453 SmallVector<SymbolReference> Protocols; 454 455 ObjCContainerRecord() = delete; 456 457 ObjCContainerRecord(RecordKind Kind, StringRef USR, StringRef Name, 458 PresumedLoc Loc, AvailabilitySet Availabilities, 459 LinkageInfo Linkage, const DocComment &Comment, 460 DeclarationFragments Declaration, 461 DeclarationFragments SubHeading, bool IsFromSystemHeader) 462 : APIRecord(Kind, USR, Name, Loc, std::move(Availabilities), Linkage, 463 Comment, Declaration, SubHeading, IsFromSystemHeader) {} 464 465 virtual ~ObjCContainerRecord() = 0; 466 }; 467 468 /// This holds information associated with Objective-C categories. 469 struct ObjCCategoryRecord : ObjCContainerRecord { 470 SymbolReference Interface; 471 472 ObjCCategoryRecord(StringRef USR, StringRef Name, PresumedLoc Loc, 473 AvailabilitySet Availabilities, const DocComment &Comment, 474 DeclarationFragments Declaration, 475 DeclarationFragments SubHeading, SymbolReference Interface, 476 bool IsFromSystemHeader) 477 : ObjCContainerRecord(RK_ObjCCategory, USR, Name, Loc, 478 std::move(Availabilities), LinkageInfo::none(), 479 Comment, Declaration, SubHeading, 480 IsFromSystemHeader), 481 Interface(Interface) {} 482 483 static bool classof(const APIRecord *Record) { 484 return Record->getKind() == RK_ObjCCategory; 485 } 486 487 private: 488 virtual void anchor(); 489 }; 490 491 /// This holds information associated with Objective-C interfaces/classes. 492 struct ObjCInterfaceRecord : ObjCContainerRecord { 493 SymbolReference SuperClass; 494 // ObjCCategoryRecord%s are stored in and owned by APISet. 495 SmallVector<ObjCCategoryRecord *> Categories; 496 497 ObjCInterfaceRecord(StringRef USR, StringRef Name, PresumedLoc Loc, 498 AvailabilitySet Availabilities, LinkageInfo Linkage, 499 const DocComment &Comment, 500 DeclarationFragments Declaration, 501 DeclarationFragments SubHeading, 502 SymbolReference SuperClass, bool IsFromSystemHeader) 503 : ObjCContainerRecord(RK_ObjCInterface, USR, Name, Loc, 504 std::move(Availabilities), Linkage, Comment, 505 Declaration, SubHeading, IsFromSystemHeader), 506 SuperClass(SuperClass) {} 507 508 static bool classof(const APIRecord *Record) { 509 return Record->getKind() == RK_ObjCInterface; 510 } 511 512 private: 513 virtual void anchor(); 514 }; 515 516 /// This holds information associated with Objective-C protocols. 517 struct ObjCProtocolRecord : ObjCContainerRecord { 518 ObjCProtocolRecord(StringRef USR, StringRef Name, PresumedLoc Loc, 519 AvailabilitySet Availabilities, const DocComment &Comment, 520 DeclarationFragments Declaration, 521 DeclarationFragments SubHeading, bool IsFromSystemHeader) 522 : ObjCContainerRecord(RK_ObjCProtocol, USR, Name, Loc, 523 std::move(Availabilities), LinkageInfo::none(), 524 Comment, Declaration, SubHeading, 525 IsFromSystemHeader) {} 526 527 static bool classof(const APIRecord *Record) { 528 return Record->getKind() == RK_ObjCProtocol; 529 } 530 531 private: 532 virtual void anchor(); 533 }; 534 535 /// This holds information associated with macro definitions. 536 struct MacroDefinitionRecord : APIRecord { 537 MacroDefinitionRecord(StringRef USR, StringRef Name, PresumedLoc Loc, 538 DeclarationFragments Declaration, 539 DeclarationFragments SubHeading, 540 bool IsFromSystemHeader) 541 : APIRecord(RK_MacroDefinition, USR, Name, Loc, AvailabilitySet(), 542 LinkageInfo(), {}, Declaration, SubHeading, 543 IsFromSystemHeader) {} 544 545 static bool classof(const APIRecord *Record) { 546 return Record->getKind() == RK_MacroDefinition; 547 } 548 549 private: 550 virtual void anchor(); 551 }; 552 553 /// This holds information associated with typedefs. 554 /// 555 /// Note: Typedefs for anonymous enums and structs typically don't get emitted 556 /// by the serializers but still get a TypedefRecord. Instead we use the 557 /// typedef name as a name for the underlying anonymous struct or enum. 558 struct TypedefRecord : APIRecord { 559 SymbolReference UnderlyingType; 560 561 TypedefRecord(StringRef USR, StringRef Name, PresumedLoc Loc, 562 AvailabilitySet Availabilities, const DocComment &Comment, 563 DeclarationFragments Declaration, 564 DeclarationFragments SubHeading, SymbolReference UnderlyingType, 565 bool IsFromSystemHeader) 566 : APIRecord(RK_Typedef, USR, Name, Loc, std::move(Availabilities), 567 LinkageInfo(), Comment, Declaration, SubHeading, 568 IsFromSystemHeader), 569 UnderlyingType(UnderlyingType) {} 570 571 static bool classof(const APIRecord *Record) { 572 return Record->getKind() == RK_Typedef; 573 } 574 575 private: 576 virtual void anchor(); 577 }; 578 579 /// Check if a record type has a function signature mixin. 580 /// 581 /// This is denoted by the record type having a ``Signature`` field of type 582 /// FunctionSignature. 583 template <typename RecordTy> 584 struct has_function_signature : public std::false_type {}; 585 template <> 586 struct has_function_signature<GlobalFunctionRecord> : public std::true_type {}; 587 template <> 588 struct has_function_signature<ObjCMethodRecord> : public std::true_type {}; 589 template <> 590 struct has_function_signature<ObjCInstanceMethodRecord> 591 : public std::true_type {}; 592 template <> 593 struct has_function_signature<ObjCClassMethodRecord> : public std::true_type {}; 594 595 /// APISet holds the set of API records collected from given inputs. 596 class APISet { 597 public: 598 /// Create and add a global variable record into the API set. 599 /// 600 /// Note: the caller is responsible for keeping the StringRef \p Name and 601 /// \p USR alive. APISet::copyString provides a way to copy strings into 602 /// APISet itself, and APISet::recordUSR(const Decl *D) is a helper method 603 /// to generate the USR for \c D and keep it alive in APISet. 604 GlobalVariableRecord * 605 addGlobalVar(StringRef Name, StringRef USR, PresumedLoc Loc, 606 AvailabilitySet Availability, LinkageInfo Linkage, 607 const DocComment &Comment, DeclarationFragments Declaration, 608 DeclarationFragments SubHeadin, bool IsFromSystemHeaderg); 609 610 /// Create and add a function record into the API set. 611 /// 612 /// Note: the caller is responsible for keeping the StringRef \p Name and 613 /// \p USR alive. APISet::copyString provides a way to copy strings into 614 /// APISet itself, and APISet::recordUSR(const Decl *D) is a helper method 615 /// to generate the USR for \c D and keep it alive in APISet. 616 GlobalFunctionRecord * 617 addGlobalFunction(StringRef Name, StringRef USR, PresumedLoc Loc, 618 AvailabilitySet Availability, LinkageInfo Linkage, 619 const DocComment &Comment, DeclarationFragments Declaration, 620 DeclarationFragments SubHeading, 621 FunctionSignature Signature, bool IsFromSystemHeader); 622 623 /// Create and add an enum constant record into the API set. 624 /// 625 /// Note: the caller is responsible for keeping the StringRef \p Name and 626 /// \p USR alive. APISet::copyString provides a way to copy strings into 627 /// APISet itself, and APISet::recordUSR(const Decl *D) is a helper method 628 /// to generate the USR for \c D and keep it alive in APISet. 629 EnumConstantRecord * 630 addEnumConstant(EnumRecord *Enum, StringRef Name, StringRef USR, 631 PresumedLoc Loc, AvailabilitySet Availability, 632 const DocComment &Comment, DeclarationFragments Declaration, 633 DeclarationFragments SubHeading, bool IsFromSystemHeader); 634 635 /// Create and add an enum record into the API set. 636 /// 637 /// Note: the caller is responsible for keeping the StringRef \p Name and 638 /// \p USR alive. APISet::copyString provides a way to copy strings into 639 /// APISet itself, and APISet::recordUSR(const Decl *D) is a helper method 640 /// to generate the USR for \c D and keep it alive in APISet. 641 EnumRecord *addEnum(StringRef Name, StringRef USR, PresumedLoc Loc, 642 AvailabilitySet Availability, const DocComment &Comment, 643 DeclarationFragments Declaration, 644 DeclarationFragments SubHeading, bool IsFromSystemHeader); 645 646 /// Create and add a struct field record into the API set. 647 /// 648 /// Note: the caller is responsible for keeping the StringRef \p Name and 649 /// \p USR alive. APISet::copyString provides a way to copy strings into 650 /// APISet itself, and APISet::recordUSR(const Decl *D) is a helper method 651 /// to generate the USR for \c D and keep it alive in APISet. 652 StructFieldRecord * 653 addStructField(StructRecord *Struct, StringRef Name, StringRef USR, 654 PresumedLoc Loc, AvailabilitySet Availability, 655 const DocComment &Comment, DeclarationFragments Declaration, 656 DeclarationFragments SubHeading, bool IsFromSystemHeader); 657 658 /// Create and add a struct record into the API set. 659 /// 660 /// Note: the caller is responsible for keeping the StringRef \p Name and 661 /// \p USR alive. APISet::copyString provides a way to copy strings into 662 /// APISet itself, and APISet::recordUSR(const Decl *D) is a helper method 663 /// to generate the USR for \c D and keep it alive in APISet. 664 StructRecord *addStruct(StringRef Name, StringRef USR, PresumedLoc Loc, 665 AvailabilitySet Availability, 666 const DocComment &Comment, 667 DeclarationFragments Declaration, 668 DeclarationFragments SubHeading, 669 bool IsFromSystemHeader); 670 671 /// Create and add an Objective-C category record into the API set. 672 /// 673 /// Note: the caller is responsible for keeping the StringRef \p Name and 674 /// \p USR alive. APISet::copyString provides a way to copy strings into 675 /// APISet itself, and APISet::recordUSR(const Decl *D) is a helper method 676 /// to generate the USR for \c D and keep it alive in APISet. 677 ObjCCategoryRecord * 678 addObjCCategory(StringRef Name, StringRef USR, PresumedLoc Loc, 679 AvailabilitySet Availability, const DocComment &Comment, 680 DeclarationFragments Declaration, 681 DeclarationFragments SubHeading, SymbolReference Interface, 682 bool IsFromSystemHeader); 683 684 /// Create and add an Objective-C interface record into the API set. 685 /// 686 /// Note: the caller is responsible for keeping the StringRef \p Name and 687 /// \p USR alive. APISet::copyString provides a way to copy strings into 688 /// APISet itself, and APISet::recordUSR(const Decl *D) is a helper method 689 /// to generate the USR for \c D and keep it alive in APISet. 690 ObjCInterfaceRecord * 691 addObjCInterface(StringRef Name, StringRef USR, PresumedLoc Loc, 692 AvailabilitySet Availability, LinkageInfo Linkage, 693 const DocComment &Comment, DeclarationFragments Declaration, 694 DeclarationFragments SubHeading, SymbolReference SuperClass, 695 bool IsFromSystemHeader); 696 697 /// Create and add an Objective-C method record into the API set. 698 /// 699 /// Note: the caller is responsible for keeping the StringRef \p Name and 700 /// \p USR alive. APISet::copyString provides a way to copy strings into 701 /// APISet itself, and APISet::recordUSR(const Decl *D) is a helper method 702 /// to generate the USR for \c D and keep it alive in APISet. 703 ObjCMethodRecord * 704 addObjCMethod(ObjCContainerRecord *Container, StringRef Name, StringRef USR, 705 PresumedLoc Loc, AvailabilitySet Availability, 706 const DocComment &Comment, DeclarationFragments Declaration, 707 DeclarationFragments SubHeading, FunctionSignature Signature, 708 bool IsInstanceMethod, bool IsFromSystemHeader); 709 710 /// Create and add an Objective-C property record into the API set. 711 /// 712 /// Note: the caller is responsible for keeping the StringRef \p Name and 713 /// \p USR alive. APISet::copyString provides a way to copy strings into 714 /// APISet itself, and APISet::recordUSR(const Decl *D) is a helper method 715 /// to generate the USR for \c D and keep it alive in APISet. 716 ObjCPropertyRecord * 717 addObjCProperty(ObjCContainerRecord *Container, StringRef Name, StringRef USR, 718 PresumedLoc Loc, AvailabilitySet Availability, 719 const DocComment &Comment, DeclarationFragments Declaration, 720 DeclarationFragments SubHeading, 721 ObjCPropertyRecord::AttributeKind Attributes, 722 StringRef GetterName, StringRef SetterName, bool IsOptional, 723 bool IsInstanceProperty, bool IsFromSystemHeader); 724 725 /// Create and add an Objective-C instance variable record into the API set. 726 /// 727 /// Note: the caller is responsible for keeping the StringRef \p Name and 728 /// \p USR alive. APISet::copyString provides a way to copy strings into 729 /// APISet itself, and APISet::recordUSR(const Decl *D) is a helper method 730 /// to generate the USR for \c D and keep it alive in APISet. 731 ObjCInstanceVariableRecord *addObjCInstanceVariable( 732 ObjCContainerRecord *Container, StringRef Name, StringRef USR, 733 PresumedLoc Loc, AvailabilitySet Availability, const DocComment &Comment, 734 DeclarationFragments Declaration, DeclarationFragments SubHeading, 735 ObjCInstanceVariableRecord::AccessControl Access, 736 bool IsFromSystemHeader); 737 738 /// Create and add an Objective-C protocol record into the API set. 739 /// 740 /// Note: the caller is responsible for keeping the StringRef \p Name and 741 /// \p USR alive. APISet::copyString provides a way to copy strings into 742 /// APISet itself, and APISet::recordUSR(const Decl *D) is a helper method 743 /// to generate the USR for \c D and keep it alive in APISet. 744 ObjCProtocolRecord * 745 addObjCProtocol(StringRef Name, StringRef USR, PresumedLoc Loc, 746 AvailabilitySet Availability, const DocComment &Comment, 747 DeclarationFragments Declaration, 748 DeclarationFragments SubHeading, bool IsFromSystemHeader); 749 750 /// Create a macro definition record into the API set. 751 /// 752 /// Note: the caller is responsible for keeping the StringRef \p Name and 753 /// \p USR alive. APISet::copyString provides a way to copy strings into 754 /// APISet itself, and APISet::recordUSRForMacro(StringRef Name, 755 /// SourceLocation SL, const SourceManager &SM) is a helper method to generate 756 /// the USR for the macro and keep it alive in APISet. 757 MacroDefinitionRecord *addMacroDefinition(StringRef Name, StringRef USR, 758 PresumedLoc Loc, 759 DeclarationFragments Declaration, 760 DeclarationFragments SubHeading, 761 bool IsFromSystemHeader); 762 763 /// Create a typedef record into the API set. 764 /// 765 /// Note: the caller is responsible for keeping the StringRef \p Name and 766 /// \p USR alive. APISet::copyString provides a way to copy strings into 767 /// APISet itself, and APISet::recordUSR(const Decl *D) is a helper method 768 /// to generate the USR for \c D and keep it alive in APISet. 769 TypedefRecord * 770 addTypedef(StringRef Name, StringRef USR, PresumedLoc Loc, 771 AvailabilitySet Availability, const DocComment &Comment, 772 DeclarationFragments Declaration, DeclarationFragments SubHeading, 773 SymbolReference UnderlyingType, bool IsFromSystemHeader); 774 775 /// A mapping type to store a set of APIRecord%s with the USR as the key. 776 template <typename RecordTy, 777 typename = 778 std::enable_if_t<std::is_base_of<APIRecord, RecordTy>::value>> 779 using RecordMap = llvm::MapVector<StringRef, std::unique_ptr<RecordTy>>; 780 781 /// Get the target triple for the ExtractAPI invocation. 782 const llvm::Triple &getTarget() const { return Target; } 783 784 /// Get the language used by the APIs. 785 Language getLanguage() const { return Lang; } 786 787 const RecordMap<GlobalFunctionRecord> &getGlobalFunctions() const { 788 return GlobalFunctions; 789 } 790 const RecordMap<GlobalVariableRecord> &getGlobalVariables() const { 791 return GlobalVariables; 792 } 793 const RecordMap<EnumRecord> &getEnums() const { return Enums; } 794 const RecordMap<StructRecord> &getStructs() const { return Structs; } 795 const RecordMap<ObjCCategoryRecord> &getObjCCategories() const { 796 return ObjCCategories; 797 } 798 const RecordMap<ObjCInterfaceRecord> &getObjCInterfaces() const { 799 return ObjCInterfaces; 800 } 801 const RecordMap<ObjCProtocolRecord> &getObjCProtocols() const { 802 return ObjCProtocols; 803 } 804 const RecordMap<MacroDefinitionRecord> &getMacros() const { return Macros; } 805 const RecordMap<TypedefRecord> &getTypedefs() const { return Typedefs; } 806 807 /// Finds the APIRecord for a given USR. 808 /// 809 /// \returns a pointer to the APIRecord associated with that USR or nullptr. 810 APIRecord *findRecordForUSR(StringRef USR) const; 811 812 /// Generate and store the USR of declaration \p D. 813 /// 814 /// Note: The USR string is stored in and owned by Allocator. 815 /// 816 /// \returns a StringRef of the generated USR string. 817 StringRef recordUSR(const Decl *D); 818 819 /// Generate and store the USR for a macro \p Name. 820 /// 821 /// Note: The USR string is stored in and owned by Allocator. 822 /// 823 /// \returns a StringRef to the generate USR string. 824 StringRef recordUSRForMacro(StringRef Name, SourceLocation SL, 825 const SourceManager &SM); 826 827 /// Copy \p String into the Allocator in this APISet. 828 /// 829 /// \returns a StringRef of the copied string in APISet::Allocator. 830 StringRef copyString(StringRef String); 831 832 APISet(const llvm::Triple &Target, Language Lang, 833 const std::string &ProductName) 834 : Target(Target), Lang(Lang), ProductName(ProductName) {} 835 836 private: 837 /// BumpPtrAllocator to store generated/copied strings. 838 /// 839 /// Note: The main use for this is being able to deduplicate strings. 840 llvm::BumpPtrAllocator StringAllocator; 841 842 const llvm::Triple Target; 843 const Language Lang; 844 845 llvm::DenseMap<StringRef, APIRecord *> USRBasedLookupTable; 846 RecordMap<GlobalFunctionRecord> GlobalFunctions; 847 RecordMap<GlobalVariableRecord> GlobalVariables; 848 RecordMap<EnumRecord> Enums; 849 RecordMap<StructRecord> Structs; 850 RecordMap<ObjCCategoryRecord> ObjCCategories; 851 RecordMap<ObjCInterfaceRecord> ObjCInterfaces; 852 RecordMap<ObjCProtocolRecord> ObjCProtocols; 853 RecordMap<MacroDefinitionRecord> Macros; 854 RecordMap<TypedefRecord> Typedefs; 855 856 public: 857 const std::string ProductName; 858 }; 859 860 } // namespace extractapi 861 } // namespace clang 862 863 #endif // LLVM_CLANG_EXTRACTAPI_API_H 864