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   StringRef USR;
59   StringRef Name;
60   PresumedLoc Location;
61   AvailabilityInfo Availability;
62   LinkageInfo Linkage;
63 
64   /// Documentation comment lines attached to this symbol declaration.
65   DocComment Comment;
66 
67   /// Declaration fragments of this symbol declaration.
68   DeclarationFragments Declaration;
69 
70   /// SubHeading provides a more detailed representation than the plain
71   /// declaration name.
72   ///
73   /// SubHeading is an array of declaration fragments of tagged declaration
74   /// name, with potentially more tokens (for example the \c +/- symbol for
75   /// Objective-C class/instance methods).
76   DeclarationFragments SubHeading;
77 
78   /// Discriminator for LLVM-style RTTI (dyn_cast<> et al.)
79   enum RecordKind {
80     RK_GlobalFunction,
81     RK_GlobalVariable,
82     RK_EnumConstant,
83     RK_Enum,
84     RK_StructField,
85     RK_Struct,
86     RK_ObjCProperty,
87     RK_ObjCIvar,
88     RK_ObjCMethod,
89     RK_ObjCInterface,
90     RK_ObjCCategory,
91     RK_ObjCProtocol,
92     RK_MacroDefinition,
93     RK_Typedef,
94   };
95 
96 private:
97   const RecordKind Kind;
98 
99 public:
100   RecordKind getKind() const { return Kind; }
101 
102   APIRecord() = delete;
103 
104   APIRecord(RecordKind Kind, StringRef USR, StringRef Name,
105             PresumedLoc Location, const AvailabilityInfo &Availability,
106             LinkageInfo Linkage, const DocComment &Comment,
107             DeclarationFragments Declaration, DeclarationFragments SubHeading)
108       : USR(USR), Name(Name), Location(Location), Availability(Availability),
109         Linkage(Linkage), Comment(Comment), Declaration(Declaration),
110         SubHeading(SubHeading), Kind(Kind) {}
111 
112   // Pure virtual destructor to make APIRecord abstract
113   virtual ~APIRecord() = 0;
114 };
115 
116 /// This holds information associated with global functions.
117 struct GlobalFunctionRecord : APIRecord {
118   FunctionSignature Signature;
119 
120   GlobalFunctionRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
121                        const AvailabilityInfo &Availability,
122                        LinkageInfo Linkage, const DocComment &Comment,
123                        DeclarationFragments Declaration,
124                        DeclarationFragments SubHeading,
125                        FunctionSignature Signature)
126       : APIRecord(RK_GlobalFunction, USR, Name, Loc, Availability, Linkage,
127                   Comment, Declaration, SubHeading),
128         Signature(Signature) {}
129 
130   static bool classof(const APIRecord *Record) {
131     return Record->getKind() == RK_GlobalFunction;
132   }
133 
134 private:
135   virtual void anchor();
136 };
137 
138 /// This holds information associated with global functions.
139 struct GlobalVariableRecord : APIRecord {
140   GlobalVariableRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
141                        const AvailabilityInfo &Availability,
142                        LinkageInfo Linkage, const DocComment &Comment,
143                        DeclarationFragments Declaration,
144                        DeclarationFragments SubHeading)
145       : APIRecord(RK_GlobalVariable, USR, Name, Loc, Availability, Linkage,
146                   Comment, Declaration, SubHeading) {}
147 
148   static bool classof(const APIRecord *Record) {
149     return Record->getKind() == RK_GlobalVariable;
150   }
151 
152 private:
153   virtual void anchor();
154 };
155 
156 /// This holds information associated with enum constants.
157 struct EnumConstantRecord : APIRecord {
158   EnumConstantRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
159                      const AvailabilityInfo &Availability,
160                      const DocComment &Comment,
161                      DeclarationFragments Declaration,
162                      DeclarationFragments SubHeading)
163       : APIRecord(RK_EnumConstant, USR, Name, Loc, Availability,
164                   LinkageInfo::none(), Comment, Declaration, SubHeading) {}
165 
166   static bool classof(const APIRecord *Record) {
167     return Record->getKind() == RK_EnumConstant;
168   }
169 
170 private:
171   virtual void anchor();
172 };
173 
174 /// This holds information associated with enums.
175 struct EnumRecord : APIRecord {
176   SmallVector<std::unique_ptr<EnumConstantRecord>> Constants;
177 
178   EnumRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
179              const AvailabilityInfo &Availability, const DocComment &Comment,
180              DeclarationFragments Declaration, DeclarationFragments SubHeading)
181       : APIRecord(RK_Enum, USR, Name, Loc, Availability, LinkageInfo::none(),
182                   Comment, Declaration, SubHeading) {}
183 
184   static bool classof(const APIRecord *Record) {
185     return Record->getKind() == RK_Enum;
186   }
187 
188 private:
189   virtual void anchor();
190 };
191 
192 /// This holds information associated with struct fields.
193 struct StructFieldRecord : APIRecord {
194   StructFieldRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
195                     const AvailabilityInfo &Availability,
196                     const DocComment &Comment, DeclarationFragments Declaration,
197                     DeclarationFragments SubHeading)
198       : APIRecord(RK_StructField, USR, Name, Loc, Availability,
199                   LinkageInfo::none(), Comment, Declaration, SubHeading) {}
200 
201   static bool classof(const APIRecord *Record) {
202     return Record->getKind() == RK_StructField;
203   }
204 
205 private:
206   virtual void anchor();
207 };
208 
209 /// This holds information associated with structs.
210 struct StructRecord : APIRecord {
211   SmallVector<std::unique_ptr<StructFieldRecord>> Fields;
212 
213   StructRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
214                const AvailabilityInfo &Availability, const DocComment &Comment,
215                DeclarationFragments Declaration,
216                DeclarationFragments SubHeading)
217       : APIRecord(RK_Struct, USR, Name, Loc, Availability, LinkageInfo::none(),
218                   Comment, Declaration, SubHeading) {}
219 
220   static bool classof(const APIRecord *Record) {
221     return Record->getKind() == RK_Struct;
222   }
223 
224 private:
225   virtual void anchor();
226 };
227 
228 /// This holds information associated with Objective-C properties.
229 struct ObjCPropertyRecord : APIRecord {
230   /// The attributes associated with an Objective-C property.
231   enum AttributeKind : unsigned {
232     NoAttr = 0,
233     ReadOnly = 1,
234     Class = 1 << 1,
235     Dynamic = 1 << 2,
236   };
237 
238   AttributeKind Attributes;
239   StringRef GetterName;
240   StringRef SetterName;
241   bool IsOptional;
242 
243   ObjCPropertyRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
244                      const AvailabilityInfo &Availability,
245                      const DocComment &Comment,
246                      DeclarationFragments Declaration,
247                      DeclarationFragments SubHeading, AttributeKind Attributes,
248                      StringRef GetterName, StringRef SetterName,
249                      bool IsOptional)
250       : APIRecord(RK_ObjCProperty, USR, Name, Loc, Availability,
251                   LinkageInfo::none(), Comment, Declaration, SubHeading),
252         Attributes(Attributes), GetterName(GetterName), SetterName(SetterName),
253         IsOptional(IsOptional) {}
254 
255   bool isReadOnly() const { return Attributes & ReadOnly; }
256   bool isDynamic() const { return Attributes & Dynamic; }
257   bool isClassProperty() const { return Attributes & Class; }
258 
259   static bool classof(const APIRecord *Record) {
260     return Record->getKind() == RK_ObjCProperty;
261   }
262 
263 private:
264   virtual void anchor();
265 };
266 
267 /// This holds information associated with Objective-C instance variables.
268 struct ObjCInstanceVariableRecord : APIRecord {
269   using AccessControl = ObjCIvarDecl::AccessControl;
270   AccessControl Access;
271 
272   ObjCInstanceVariableRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
273                              const AvailabilityInfo &Availability,
274                              const DocComment &Comment,
275                              DeclarationFragments Declaration,
276                              DeclarationFragments SubHeading,
277                              AccessControl Access)
278       : APIRecord(RK_ObjCIvar, USR, Name, Loc, Availability,
279                   LinkageInfo::none(), Comment, Declaration, SubHeading),
280         Access(Access) {}
281 
282   static bool classof(const APIRecord *Record) {
283     return Record->getKind() == RK_ObjCIvar;
284   }
285 
286 private:
287   virtual void anchor();
288 };
289 
290 /// This holds information associated with Objective-C methods.
291 struct ObjCMethodRecord : APIRecord {
292   FunctionSignature Signature;
293   bool IsInstanceMethod;
294 
295   ObjCMethodRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
296                    const AvailabilityInfo &Availability,
297                    const DocComment &Comment, DeclarationFragments Declaration,
298                    DeclarationFragments SubHeading, FunctionSignature Signature,
299                    bool IsInstanceMethod)
300       : APIRecord(RK_ObjCMethod, USR, Name, Loc, Availability,
301                   LinkageInfo::none(), Comment, Declaration, SubHeading),
302         Signature(Signature), IsInstanceMethod(IsInstanceMethod) {}
303 
304   static bool classof(const APIRecord *Record) {
305     return Record->getKind() == RK_ObjCMethod;
306   }
307 
308 private:
309   virtual void anchor();
310 };
311 
312 /// This represents a reference to another symbol that might come from external
313 /// sources.
314 struct SymbolReference {
315   StringRef Name;
316   StringRef USR;
317 
318   /// The source project/module/product of the referred symbol.
319   StringRef Source;
320 
321   SymbolReference() = default;
322   SymbolReference(StringRef Name, StringRef USR = "", StringRef Source = "")
323       : Name(Name), USR(USR), Source(Source) {}
324   SymbolReference(const APIRecord &Record)
325       : Name(Record.Name), USR(Record.USR) {}
326 
327   /// Determine if this SymbolReference is empty.
328   ///
329   /// \returns true if and only if all \c Name, \c USR, and \c Source is empty.
330   bool empty() const { return Name.empty() && USR.empty() && Source.empty(); }
331 };
332 
333 /// The base representation of an Objective-C container record. Holds common
334 /// information associated with Objective-C containers.
335 struct ObjCContainerRecord : APIRecord {
336   SmallVector<std::unique_ptr<ObjCMethodRecord>> Methods;
337   SmallVector<std::unique_ptr<ObjCPropertyRecord>> Properties;
338   SmallVector<std::unique_ptr<ObjCInstanceVariableRecord>> Ivars;
339   SmallVector<SymbolReference> Protocols;
340 
341   ObjCContainerRecord() = delete;
342 
343   ObjCContainerRecord(RecordKind Kind, StringRef USR, StringRef Name,
344                       PresumedLoc Loc, const AvailabilityInfo &Availability,
345                       LinkageInfo Linkage, const DocComment &Comment,
346                       DeclarationFragments Declaration,
347                       DeclarationFragments SubHeading)
348       : APIRecord(Kind, USR, Name, Loc, Availability, Linkage, Comment,
349                   Declaration, SubHeading) {}
350 
351   virtual ~ObjCContainerRecord() = 0;
352 };
353 
354 /// This holds information associated with Objective-C categories.
355 struct ObjCCategoryRecord : ObjCContainerRecord {
356   SymbolReference Interface;
357 
358   ObjCCategoryRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
359                      const AvailabilityInfo &Availability,
360                      const DocComment &Comment,
361                      DeclarationFragments Declaration,
362                      DeclarationFragments SubHeading, SymbolReference Interface)
363       : ObjCContainerRecord(RK_ObjCCategory, USR, Name, Loc, Availability,
364                             LinkageInfo::none(), Comment, Declaration,
365                             SubHeading),
366         Interface(Interface) {}
367 
368   static bool classof(const APIRecord *Record) {
369     return Record->getKind() == RK_ObjCCategory;
370   }
371 
372 private:
373   virtual void anchor();
374 };
375 
376 /// This holds information associated with Objective-C interfaces/classes.
377 struct ObjCInterfaceRecord : ObjCContainerRecord {
378   SymbolReference SuperClass;
379   // ObjCCategoryRecord%s are stored in and owned by APISet.
380   SmallVector<ObjCCategoryRecord *> Categories;
381 
382   ObjCInterfaceRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
383                       const AvailabilityInfo &Availability, LinkageInfo Linkage,
384                       const DocComment &Comment,
385                       DeclarationFragments Declaration,
386                       DeclarationFragments SubHeading,
387                       SymbolReference SuperClass)
388       : ObjCContainerRecord(RK_ObjCInterface, USR, Name, Loc, Availability,
389                             Linkage, Comment, Declaration, SubHeading),
390         SuperClass(SuperClass) {}
391 
392   static bool classof(const APIRecord *Record) {
393     return Record->getKind() == RK_ObjCInterface;
394   }
395 
396 private:
397   virtual void anchor();
398 };
399 
400 /// This holds information associated with Objective-C protocols.
401 struct ObjCProtocolRecord : ObjCContainerRecord {
402   ObjCProtocolRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
403                      const AvailabilityInfo &Availability,
404                      const DocComment &Comment,
405                      DeclarationFragments Declaration,
406                      DeclarationFragments SubHeading)
407       : ObjCContainerRecord(RK_ObjCProtocol, USR, Name, Loc, Availability,
408                             LinkageInfo::none(), Comment, Declaration,
409                             SubHeading) {}
410 
411   static bool classof(const APIRecord *Record) {
412     return Record->getKind() == RK_ObjCProtocol;
413   }
414 
415 private:
416   virtual void anchor();
417 };
418 
419 /// This holds information associated with macro definitions.
420 struct MacroDefinitionRecord : APIRecord {
421   MacroDefinitionRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
422                         DeclarationFragments Declaration,
423                         DeclarationFragments SubHeading)
424       : APIRecord(RK_MacroDefinition, USR, Name, Loc, AvailabilityInfo(),
425                   LinkageInfo(), {}, Declaration, SubHeading) {}
426 
427   static bool classof(const APIRecord *Record) {
428     return Record->getKind() == RK_MacroDefinition;
429   }
430 
431 private:
432   virtual void anchor();
433 };
434 
435 /// This holds information associated with typedefs.
436 ///
437 /// Note: Typedefs for anonymous enums and structs typically don't get emitted
438 /// by the serializers but still get a TypedefRecord. Instead we use the
439 /// typedef name as a name for the underlying anonymous struct or enum.
440 struct TypedefRecord : APIRecord {
441   SymbolReference UnderlyingType;
442 
443   TypedefRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
444                 const AvailabilityInfo &Availability, const DocComment &Comment,
445                 DeclarationFragments Declaration,
446                 DeclarationFragments SubHeading, SymbolReference UnderlyingType)
447       : APIRecord(RK_Typedef, USR, Name, Loc, Availability, LinkageInfo(),
448                   Comment, Declaration, SubHeading),
449         UnderlyingType(UnderlyingType) {}
450 
451   static bool classof(const APIRecord *Record) {
452     return Record->getKind() == RK_Typedef;
453   }
454 
455 private:
456   virtual void anchor();
457 };
458 
459 /// Check if a record type has a function signature mixin.
460 ///
461 /// This is denoted by the record type having a ``Signature`` field of type
462 /// FunctionSignature.
463 template <typename RecordTy>
464 struct has_function_signature : public std::false_type {};
465 template <>
466 struct has_function_signature<GlobalFunctionRecord> : public std::true_type {};
467 template <>
468 struct has_function_signature<ObjCMethodRecord> : public std::true_type {};
469 
470 /// APISet holds the set of API records collected from given inputs.
471 class APISet {
472 public:
473   /// Create and add a global variable record into the API set.
474   ///
475   /// Note: the caller is responsible for keeping the StringRef \p Name and
476   /// \p USR alive. APISet::copyString provides a way to copy strings into
477   /// APISet itself, and APISet::recordUSR(const Decl *D) is a helper method
478   /// to generate the USR for \c D and keep it alive in APISet.
479   GlobalVariableRecord *
480   addGlobalVar(StringRef Name, StringRef USR, PresumedLoc Loc,
481                const AvailabilityInfo &Availability, LinkageInfo Linkage,
482                const DocComment &Comment, DeclarationFragments Declaration,
483                DeclarationFragments SubHeading);
484 
485   /// Create and add a function record into the API set.
486   ///
487   /// Note: the caller is responsible for keeping the StringRef \p Name and
488   /// \p USR alive. APISet::copyString provides a way to copy strings into
489   /// APISet itself, and APISet::recordUSR(const Decl *D) is a helper method
490   /// to generate the USR for \c D and keep it alive in APISet.
491   GlobalFunctionRecord *
492   addGlobalFunction(StringRef Name, StringRef USR, PresumedLoc Loc,
493                     const AvailabilityInfo &Availability, LinkageInfo Linkage,
494                     const DocComment &Comment, DeclarationFragments Declaration,
495                     DeclarationFragments SubHeading,
496                     FunctionSignature Signature);
497 
498   /// Create and add an enum constant record into the API set.
499   ///
500   /// Note: the caller is responsible for keeping the StringRef \p Name and
501   /// \p USR alive. APISet::copyString provides a way to copy strings into
502   /// APISet itself, and APISet::recordUSR(const Decl *D) is a helper method
503   /// to generate the USR for \c D and keep it alive in APISet.
504   EnumConstantRecord *addEnumConstant(EnumRecord *Enum, StringRef Name,
505                                       StringRef USR, PresumedLoc Loc,
506                                       const AvailabilityInfo &Availability,
507                                       const DocComment &Comment,
508                                       DeclarationFragments Declaration,
509                                       DeclarationFragments SubHeading);
510 
511   /// Create and add an enum record into the API set.
512   ///
513   /// Note: the caller is responsible for keeping the StringRef \p Name and
514   /// \p USR alive. APISet::copyString provides a way to copy strings into
515   /// APISet itself, and APISet::recordUSR(const Decl *D) is a helper method
516   /// to generate the USR for \c D and keep it alive in APISet.
517   EnumRecord *addEnum(StringRef Name, StringRef USR, PresumedLoc Loc,
518                       const AvailabilityInfo &Availability,
519                       const DocComment &Comment,
520                       DeclarationFragments Declaration,
521                       DeclarationFragments SubHeading);
522 
523   /// Create and add a struct field record into the API set.
524   ///
525   /// Note: the caller is responsible for keeping the StringRef \p Name and
526   /// \p USR alive. APISet::copyString provides a way to copy strings into
527   /// APISet itself, and APISet::recordUSR(const Decl *D) is a helper method
528   /// to generate the USR for \c D and keep it alive in APISet.
529   StructFieldRecord *addStructField(StructRecord *Struct, StringRef Name,
530                                     StringRef USR, PresumedLoc Loc,
531                                     const AvailabilityInfo &Availability,
532                                     const DocComment &Comment,
533                                     DeclarationFragments Declaration,
534                                     DeclarationFragments SubHeading);
535 
536   /// Create and add a struct record into the API set.
537   ///
538   /// Note: the caller is responsible for keeping the StringRef \p Name and
539   /// \p USR alive. APISet::copyString provides a way to copy strings into
540   /// APISet itself, and APISet::recordUSR(const Decl *D) is a helper method
541   /// to generate the USR for \c D and keep it alive in APISet.
542   StructRecord *addStruct(StringRef Name, StringRef USR, PresumedLoc Loc,
543                           const AvailabilityInfo &Availability,
544                           const DocComment &Comment,
545                           DeclarationFragments Declaration,
546                           DeclarationFragments SubHeading);
547 
548   /// Create and add an Objective-C category record into the API set.
549   ///
550   /// Note: the caller is responsible for keeping the StringRef \p Name and
551   /// \p USR alive. APISet::copyString provides a way to copy strings into
552   /// APISet itself, and APISet::recordUSR(const Decl *D) is a helper method
553   /// to generate the USR for \c D and keep it alive in APISet.
554   ObjCCategoryRecord *
555   addObjCCategory(StringRef Name, StringRef USR, PresumedLoc Loc,
556                   const AvailabilityInfo &Availability,
557                   const DocComment &Comment, DeclarationFragments Declaration,
558                   DeclarationFragments SubHeading, SymbolReference Interface);
559 
560   /// Create and add an Objective-C interface record into the API set.
561   ///
562   /// Note: the caller is responsible for keeping the StringRef \p Name and
563   /// \p USR alive. APISet::copyString provides a way to copy strings into
564   /// APISet itself, and APISet::recordUSR(const Decl *D) is a helper method
565   /// to generate the USR for \c D and keep it alive in APISet.
566   ObjCInterfaceRecord *
567   addObjCInterface(StringRef Name, StringRef USR, PresumedLoc Loc,
568                    const AvailabilityInfo &Availability, LinkageInfo Linkage,
569                    const DocComment &Comment, DeclarationFragments Declaration,
570                    DeclarationFragments SubHeading, SymbolReference SuperClass);
571 
572   /// Create and add an Objective-C method record into the API set.
573   ///
574   /// Note: the caller is responsible for keeping the StringRef \p Name and
575   /// \p USR alive. APISet::copyString provides a way to copy strings into
576   /// APISet itself, and APISet::recordUSR(const Decl *D) is a helper method
577   /// to generate the USR for \c D and keep it alive in APISet.
578   ObjCMethodRecord *
579   addObjCMethod(ObjCContainerRecord *Container, StringRef Name, StringRef USR,
580                 PresumedLoc Loc, const AvailabilityInfo &Availability,
581                 const DocComment &Comment, DeclarationFragments Declaration,
582                 DeclarationFragments SubHeading, FunctionSignature Signature,
583                 bool IsInstanceMethod);
584 
585   /// Create and add an Objective-C property record into the API set.
586   ///
587   /// Note: the caller is responsible for keeping the StringRef \p Name and
588   /// \p USR alive. APISet::copyString provides a way to copy strings into
589   /// APISet itself, and APISet::recordUSR(const Decl *D) is a helper method
590   /// to generate the USR for \c D and keep it alive in APISet.
591   ObjCPropertyRecord *
592   addObjCProperty(ObjCContainerRecord *Container, StringRef Name, StringRef USR,
593                   PresumedLoc Loc, const AvailabilityInfo &Availability,
594                   const DocComment &Comment, DeclarationFragments Declaration,
595                   DeclarationFragments SubHeading,
596                   ObjCPropertyRecord::AttributeKind Attributes,
597                   StringRef GetterName, StringRef SetterName, bool IsOptional);
598 
599   /// Create and add an Objective-C instance variable record into the API set.
600   ///
601   /// Note: the caller is responsible for keeping the StringRef \p Name and
602   /// \p USR alive. APISet::copyString provides a way to copy strings into
603   /// APISet itself, and APISet::recordUSR(const Decl *D) is a helper method
604   /// to generate the USR for \c D and keep it alive in APISet.
605   ObjCInstanceVariableRecord *addObjCInstanceVariable(
606       ObjCContainerRecord *Container, StringRef Name, StringRef USR,
607       PresumedLoc Loc, const AvailabilityInfo &Availability,
608       const DocComment &Comment, DeclarationFragments Declaration,
609       DeclarationFragments SubHeading,
610       ObjCInstanceVariableRecord::AccessControl Access);
611 
612   /// Create and add an Objective-C protocol record into the API set.
613   ///
614   /// Note: the caller is responsible for keeping the StringRef \p Name and
615   /// \p USR alive. APISet::copyString provides a way to copy strings into
616   /// APISet itself, and APISet::recordUSR(const Decl *D) is a helper method
617   /// to generate the USR for \c D and keep it alive in APISet.
618   ObjCProtocolRecord *addObjCProtocol(StringRef Name, StringRef USR,
619                                       PresumedLoc Loc,
620                                       const AvailabilityInfo &Availability,
621                                       const DocComment &Comment,
622                                       DeclarationFragments Declaration,
623                                       DeclarationFragments SubHeading);
624 
625   /// Create a macro definition record into the API set.
626   ///
627   /// Note: the caller is responsible for keeping the StringRef \p Name and
628   /// \p USR alive. APISet::copyString provides a way to copy strings into
629   /// APISet itself, and APISet::recordUSRForMacro(StringRef Name,
630   /// SourceLocation SL, const SourceManager &SM) is a helper method to generate
631   /// the USR for the macro and keep it alive in APISet.
632   MacroDefinitionRecord *addMacroDefinition(StringRef Name, StringRef USR,
633                                             PresumedLoc Loc,
634                                             DeclarationFragments Declaration,
635                                             DeclarationFragments SubHeading);
636 
637   /// Create a typedef record into the API set.
638   ///
639   /// Note: the caller is responsible for keeping the StringRef \p Name and
640   /// \p USR alive. APISet::copyString provides a way to copy strings into
641   /// APISet itself, and APISet::recordUSR(const Decl *D) is a helper method
642   /// to generate the USR for \c D and keep it alive in APISet.
643   TypedefRecord *addTypedef(StringRef Name, StringRef USR, PresumedLoc Loc,
644                             const AvailabilityInfo &Availability,
645                             const DocComment &Comment,
646                             DeclarationFragments Declaration,
647                             DeclarationFragments SubHeading,
648                             SymbolReference UnderlyingType);
649 
650   /// A mapping type to store a set of APIRecord%s with the USR as the key.
651   template <typename RecordTy,
652             typename =
653                 std::enable_if_t<std::is_base_of<APIRecord, RecordTy>::value>>
654   using RecordMap = llvm::MapVector<StringRef, std::unique_ptr<RecordTy>>;
655 
656   /// Get the target triple for the ExtractAPI invocation.
657   const llvm::Triple &getTarget() const { return Target; }
658 
659   /// Get the language used by the APIs.
660   Language getLanguage() const { return Lang; }
661 
662   const RecordMap<GlobalFunctionRecord> &getGlobalFunctions() const {
663     return GlobalFunctions;
664   }
665   const RecordMap<GlobalVariableRecord> &getGlobalVariables() const {
666     return GlobalVariables;
667   }
668   const RecordMap<EnumRecord> &getEnums() const { return Enums; }
669   const RecordMap<StructRecord> &getStructs() const { return Structs; }
670   const RecordMap<ObjCCategoryRecord> &getObjCCategories() const {
671     return ObjCCategories;
672   }
673   const RecordMap<ObjCInterfaceRecord> &getObjCInterfaces() const {
674     return ObjCInterfaces;
675   }
676   const RecordMap<ObjCProtocolRecord> &getObjCProtocols() const {
677     return ObjCProtocols;
678   }
679   const RecordMap<MacroDefinitionRecord> &getMacros() const { return Macros; }
680   const RecordMap<TypedefRecord> &getTypedefs() const { return Typedefs; }
681 
682   /// Generate and store the USR of declaration \p D.
683   ///
684   /// Note: The USR string is stored in and owned by Allocator.
685   ///
686   /// \returns a StringRef of the generated USR string.
687   StringRef recordUSR(const Decl *D);
688 
689   /// Generate and store the USR for a macro \p Name.
690   ///
691   /// Note: The USR string is stored in and owned by Allocator.
692   ///
693   /// \returns a StringRef to the generate USR string.
694   StringRef recordUSRForMacro(StringRef Name, SourceLocation SL,
695                               const SourceManager &SM);
696 
697   /// Copy \p String into the Allocator in this APISet.
698   ///
699   /// \returns a StringRef of the copied string in APISet::Allocator.
700   StringRef copyString(StringRef String);
701 
702   APISet(const llvm::Triple &Target, Language Lang)
703       : Target(Target), Lang(Lang) {}
704 
705 private:
706   /// BumpPtrAllocator to store generated/copied strings.
707   ///
708   /// Note: The main use for this is being able to deduplicate strings.
709   llvm::BumpPtrAllocator StringAllocator;
710 
711   const llvm::Triple Target;
712   const Language Lang;
713 
714   RecordMap<GlobalFunctionRecord> GlobalFunctions;
715   RecordMap<GlobalVariableRecord> GlobalVariables;
716   RecordMap<EnumRecord> Enums;
717   RecordMap<StructRecord> Structs;
718   RecordMap<ObjCCategoryRecord> ObjCCategories;
719   RecordMap<ObjCInterfaceRecord> ObjCInterfaces;
720   RecordMap<ObjCProtocolRecord> ObjCProtocols;
721   RecordMap<MacroDefinitionRecord> Macros;
722   RecordMap<TypedefRecord> Typedefs;
723 };
724 
725 } // namespace extractapi
726 } // namespace clang
727 
728 #endif // LLVM_CLANG_EXTRACTAPI_API_H
729