Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 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