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