Skip to content

Commit afafb3c

Browse files
evelez7daniel-grumberg
authored andcommitted
[clang][ExtractAPI] Add support for C++ classes with fix
Reintroduce D153557 with fix for use-after-free from f4de606 and minor changes. Reviewed By: dang Differential Revision: https://reviews.llvm.org/D157007
1 parent 317e1c6 commit afafb3c

16 files changed

+3259
-47
lines changed

clang/include/clang/ExtractAPI/API.h

Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "clang/AST/DeclObjC.h"
2323
#include "clang/AST/RawCommentList.h"
2424
#include "clang/Basic/SourceLocation.h"
25+
#include "clang/Basic/Specifiers.h"
2526
#include "clang/ExtractAPI/AvailabilityInfo.h"
2627
#include "clang/ExtractAPI/DeclarationFragments.h"
2728
#include "llvm/ADT/MapVector.h"
@@ -64,6 +65,14 @@ struct APIRecord {
6465
RK_Enum,
6566
RK_StructField,
6667
RK_Struct,
68+
RK_Union,
69+
RK_StaticField,
70+
RK_CXXField,
71+
RK_CXXClass,
72+
RK_CXXStaticMethod,
73+
RK_CXXInstanceMethod,
74+
RK_CXXConstructorMethod,
75+
RK_CXXDestructorMethod,
6776
RK_ObjCInstanceProperty,
6877
RK_ObjCClassProperty,
6978
RK_ObjCIvar,
@@ -266,6 +275,132 @@ struct StructRecord : APIRecord {
266275
virtual void anchor();
267276
};
268277

278+
struct CXXFieldRecord : APIRecord {
279+
AccessControl Access;
280+
281+
CXXFieldRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
282+
AvailabilitySet Availabilities, const DocComment &Comment,
283+
DeclarationFragments Declaration,
284+
DeclarationFragments SubHeading, AccessControl Access,
285+
bool IsFromSystemHeader)
286+
: APIRecord(RK_CXXField, USR, Name, Loc, std::move(Availabilities),
287+
LinkageInfo::none(), Comment, Declaration, SubHeading,
288+
IsFromSystemHeader),
289+
Access(Access) {}
290+
291+
CXXFieldRecord(RecordKind Kind, StringRef USR, StringRef Name,
292+
PresumedLoc Loc, AvailabilitySet Availabilities,
293+
const DocComment &Comment, DeclarationFragments Declaration,
294+
DeclarationFragments SubHeading, AccessControl Access,
295+
bool IsFromSystemHeader)
296+
: APIRecord(Kind, USR, Name, Loc, std::move(Availabilities),
297+
LinkageInfo::none(), Comment, Declaration, SubHeading,
298+
IsFromSystemHeader),
299+
Access(Access) {}
300+
301+
static bool classof(const APIRecord *Record) {
302+
return Record->getKind() == RK_CXXField;
303+
}
304+
305+
private:
306+
virtual void anchor();
307+
};
308+
309+
struct CXXMethodRecord : APIRecord {
310+
FunctionSignature Signature;
311+
AccessControl Access;
312+
313+
CXXMethodRecord() = delete;
314+
315+
CXXMethodRecord(RecordKind Kind, StringRef USR, StringRef Name,
316+
PresumedLoc Loc, AvailabilitySet Availabilities,
317+
const DocComment &Comment, DeclarationFragments Declaration,
318+
DeclarationFragments SubHeading, FunctionSignature Signature,
319+
AccessControl Access, bool IsFromSystemHeader)
320+
: APIRecord(Kind, USR, Name, Loc, std::move(Availabilities),
321+
LinkageInfo::none(), Comment, Declaration, SubHeading,
322+
IsFromSystemHeader),
323+
Signature(Signature), Access(Access) {}
324+
325+
virtual ~CXXMethodRecord() = 0;
326+
};
327+
328+
struct CXXConstructorRecord : CXXMethodRecord {
329+
CXXConstructorRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
330+
AvailabilitySet Availabilities,
331+
const DocComment &Comment,
332+
DeclarationFragments Declaration,
333+
DeclarationFragments SubHeading,
334+
FunctionSignature Signature, AccessControl Access,
335+
bool IsFromSystemHeader)
336+
: CXXMethodRecord(RK_CXXConstructorMethod, USR, Name, Loc,
337+
std::move(Availabilities), Comment, Declaration,
338+
SubHeading, Signature, Access, IsFromSystemHeader) {}
339+
static bool classof(const APIRecord *Record) {
340+
return Record->getKind() == RK_CXXConstructorMethod;
341+
}
342+
343+
private:
344+
virtual void anchor();
345+
};
346+
347+
struct CXXDestructorRecord : CXXMethodRecord {
348+
CXXDestructorRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
349+
AvailabilitySet Availabilities, const DocComment &Comment,
350+
DeclarationFragments Declaration,
351+
DeclarationFragments SubHeading,
352+
FunctionSignature Signature, AccessControl Access,
353+
bool IsFromSystemHeader)
354+
: CXXMethodRecord(RK_CXXDestructorMethod, USR, Name, Loc,
355+
std::move(Availabilities), Comment, Declaration,
356+
SubHeading, Signature, Access, IsFromSystemHeader) {}
357+
static bool classof(const APIRecord *Record) {
358+
return Record->getKind() == RK_CXXDestructorMethod;
359+
}
360+
361+
private:
362+
virtual void anchor();
363+
};
364+
365+
struct CXXStaticMethodRecord : CXXMethodRecord {
366+
CXXStaticMethodRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
367+
AvailabilitySet Availabilities,
368+
const DocComment &Comment,
369+
DeclarationFragments Declaration,
370+
DeclarationFragments SubHeading,
371+
FunctionSignature Signature, AccessControl Access,
372+
bool IsFromSystemHeader)
373+
: CXXMethodRecord(RK_CXXStaticMethod, USR, Name, Loc,
374+
std::move(Availabilities), Comment, Declaration,
375+
SubHeading, Signature, Access, IsFromSystemHeader) {}
376+
static bool classof(const APIRecord *Record) {
377+
return Record->getKind() == RK_CXXStaticMethod;
378+
}
379+
380+
private:
381+
virtual void anchor();
382+
};
383+
384+
struct CXXInstanceMethodRecord : CXXMethodRecord {
385+
CXXInstanceMethodRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
386+
AvailabilitySet Availabilities,
387+
const DocComment &Comment,
388+
DeclarationFragments Declaration,
389+
DeclarationFragments SubHeading,
390+
FunctionSignature Signature, AccessControl Access,
391+
bool IsFromSystemHeader)
392+
: CXXMethodRecord(RK_CXXInstanceMethod, USR, Name, Loc,
393+
std::move(Availabilities), Comment, Declaration,
394+
SubHeading, Signature, Access, IsFromSystemHeader) {}
395+
396+
static bool classof(const APIRecord *Record) {
397+
return Record->getKind() == RK_CXXInstanceMethod;
398+
}
399+
400+
private:
401+
virtual void anchor();
402+
};
403+
269404
/// This holds information associated with Objective-C properties.
270405
struct ObjCPropertyRecord : APIRecord {
271406
/// The attributes associated with an Objective-C property.
@@ -444,6 +579,24 @@ struct SymbolReference {
444579
bool empty() const { return Name.empty() && USR.empty() && Source.empty(); }
445580
};
446581

582+
struct StaticFieldRecord : CXXFieldRecord {
583+
SymbolReference Context;
584+
585+
StaticFieldRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
586+
AvailabilitySet Availabilities, LinkageInfo Linkage,
587+
const DocComment &Comment, DeclarationFragments Declaration,
588+
DeclarationFragments SubHeading, SymbolReference Context,
589+
AccessControl Access, bool IsFromSystemHeader)
590+
: CXXFieldRecord(RK_StaticField, USR, Name, Loc,
591+
std::move(Availabilities), Comment, Declaration,
592+
SubHeading, Access, IsFromSystemHeader),
593+
Context(Context) {}
594+
595+
static bool classof(const APIRecord *Record) {
596+
return Record->getKind() == RK_StaticField;
597+
}
598+
};
599+
447600
/// The base representation of an Objective-C container record. Holds common
448601
/// information associated with Objective-C containers.
449602
struct ObjCContainerRecord : APIRecord {
@@ -465,6 +618,28 @@ struct ObjCContainerRecord : APIRecord {
465618
virtual ~ObjCContainerRecord() = 0;
466619
};
467620

621+
struct CXXClassRecord : APIRecord {
622+
SmallVector<std::unique_ptr<CXXFieldRecord>> Fields;
623+
SmallVector<std::unique_ptr<CXXMethodRecord>> Methods;
624+
SmallVector<SymbolReference> Bases;
625+
626+
CXXClassRecord(StringRef USR, StringRef Name, PresumedLoc Loc,
627+
AvailabilitySet Availabilities, const DocComment &Comment,
628+
DeclarationFragments Declaration,
629+
DeclarationFragments SubHeading, RecordKind Kind,
630+
bool IsFromSystemHeader)
631+
: APIRecord(Kind, USR, Name, Loc, std::move(Availabilities),
632+
LinkageInfo::none(), Comment, Declaration, SubHeading,
633+
IsFromSystemHeader) {}
634+
635+
static bool classof(const APIRecord *Record) {
636+
return (Record->getKind() == RK_CXXClass);
637+
}
638+
639+
private:
640+
virtual void anchor();
641+
};
642+
468643
/// This holds information associated with Objective-C categories.
469644
struct ObjCCategoryRecord : ObjCContainerRecord {
470645
SymbolReference Interface;
@@ -591,6 +766,12 @@ struct has_function_signature<ObjCInstanceMethodRecord>
591766
: public std::true_type {};
592767
template <>
593768
struct has_function_signature<ObjCClassMethodRecord> : public std::true_type {};
769+
template <>
770+
struct has_function_signature<CXXMethodRecord> : public std::true_type {};
771+
772+
template <typename RecordTy> struct has_access : public std::false_type {};
773+
template <> struct has_access<CXXMethodRecord> : public std::true_type {};
774+
template <> struct has_access<CXXFieldRecord> : public std::true_type {};
594775

595776
/// APISet holds the set of API records collected from given inputs.
596777
class APISet {
@@ -668,6 +849,41 @@ class APISet {
668849
DeclarationFragments SubHeading,
669850
bool IsFromSystemHeader);
670851

852+
StaticFieldRecord *
853+
addStaticField(StringRef Name, StringRef USR, PresumedLoc Loc,
854+
AvailabilitySet Availabilities, LinkageInfo Linkage,
855+
const DocComment &Comment, DeclarationFragments Declaration,
856+
DeclarationFragments SubHeading, SymbolReference Context,
857+
AccessControl Access, bool IsFromSystemHeaderg);
858+
859+
CXXFieldRecord *addCXXField(CXXClassRecord *CXXClass, StringRef Name,
860+
StringRef USR, PresumedLoc Loc,
861+
AvailabilitySet Availabilities,
862+
const DocComment &Comment,
863+
DeclarationFragments Declaration,
864+
DeclarationFragments SubHeading,
865+
AccessControl Access, bool IsFromSystemHeader);
866+
867+
CXXClassRecord *
868+
addCXXClass(StringRef Name, StringRef USR, PresumedLoc Loc,
869+
AvailabilitySet Availability, const DocComment &Comment,
870+
DeclarationFragments Declaration, DeclarationFragments SubHeading,
871+
APIRecord::RecordKind Kind, bool IsFromSystemHeader);
872+
873+
CXXMethodRecord *
874+
addCXXMethod(CXXClassRecord *CXXClassRecord, StringRef Name, StringRef USR,
875+
PresumedLoc Loc, AvailabilitySet Availability,
876+
const DocComment &Comment, DeclarationFragments Declaration,
877+
DeclarationFragments SubHeading, FunctionSignature Signature,
878+
bool IsStatic, AccessControl Access, bool IsFromSystemHeader);
879+
880+
CXXMethodRecord *addCXXSpecialMethod(
881+
CXXClassRecord *CXXClassRecord, StringRef Name, StringRef USR,
882+
PresumedLoc Loc, AvailabilitySet Availability, const DocComment &Comment,
883+
DeclarationFragments Declaration, DeclarationFragments SubHeading,
884+
FunctionSignature Signature, bool IsConstructor, AccessControl Access,
885+
bool IsFromSystemHeader);
886+
671887
/// Create and add an Objective-C category record into the API set.
672888
///
673889
/// Note: the caller is responsible for keeping the StringRef \p Name and
@@ -790,8 +1006,12 @@ class APISet {
7901006
const RecordMap<GlobalVariableRecord> &getGlobalVariables() const {
7911007
return GlobalVariables;
7921008
}
1009+
const RecordMap<StaticFieldRecord> &getStaticFields() const {
1010+
return StaticFields;
1011+
}
7931012
const RecordMap<EnumRecord> &getEnums() const { return Enums; }
7941013
const RecordMap<StructRecord> &getStructs() const { return Structs; }
1014+
const RecordMap<CXXClassRecord> &getCXXClasses() const { return CXXClasses; }
7951015
const RecordMap<ObjCCategoryRecord> &getObjCCategories() const {
7961016
return ObjCCategories;
7971017
}
@@ -845,8 +1065,10 @@ class APISet {
8451065
llvm::DenseMap<StringRef, APIRecord *> USRBasedLookupTable;
8461066
RecordMap<GlobalFunctionRecord> GlobalFunctions;
8471067
RecordMap<GlobalVariableRecord> GlobalVariables;
1068+
RecordMap<StaticFieldRecord> StaticFields;
8481069
RecordMap<EnumRecord> Enums;
8491070
RecordMap<StructRecord> Structs;
1071+
RecordMap<CXXClassRecord> CXXClasses;
8501072
RecordMap<ObjCCategoryRecord> ObjCCategories;
8511073
RecordMap<ObjCInterfaceRecord> ObjCInterfaces;
8521074
RecordMap<ObjCProtocolRecord> ObjCProtocols;

0 commit comments

Comments
 (0)