Skip to content

Commit f275507

Browse files
[clang][ExtractAPI] Fix handling of anonymous TagDecls
This changes the handling of anonymous TagDecls to the following rules: - If the TagDecl is embedded in the declaration for some VarDecl (this is the only possibility for RecordDecls), then pretend the child decls belong to the VarDecl - If it's an EnumDecl proceed as we did previously, i.e., embed it in the enclosing DeclContext. Additionally this fixes a few issues with declaration fragments not consistently including "{ ... }" for anonymous TagDecls. To make testing these additions easier this patch fixes some text declaration fragments merging issues and updates tests accordingly.
1 parent 417a068 commit f275507

File tree

14 files changed

+427
-569
lines changed

14 files changed

+427
-569
lines changed

clang/include/clang/ExtractAPI/API.h

Lines changed: 88 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -208,20 +208,20 @@ struct APIRecord {
208208
RK_ClassTemplate,
209209
RK_ClassTemplateSpecialization,
210210
RK_ClassTemplatePartialSpecialization,
211-
RK_LastRecordContext,
212-
RK_GlobalFunction,
213-
RK_GlobalFunctionTemplate,
214-
RK_GlobalFunctionTemplateSpecialization,
211+
RK_StructField,
212+
RK_UnionField,
213+
RK_CXXField,
214+
RK_StaticField,
215+
RK_CXXFieldTemplate,
215216
RK_GlobalVariable,
216217
RK_GlobalVariableTemplate,
217218
RK_GlobalVariableTemplateSpecialization,
218219
RK_GlobalVariableTemplatePartialSpecialization,
220+
RK_LastRecordContext,
221+
RK_GlobalFunction,
222+
RK_GlobalFunctionTemplate,
223+
RK_GlobalFunctionTemplateSpecialization,
219224
RK_EnumConstant,
220-
RK_StructField,
221-
RK_UnionField,
222-
RK_StaticField,
223-
RK_CXXField,
224-
RK_CXXFieldTemplate,
225225
RK_Concept,
226226
RK_CXXStaticMethod,
227227
RK_CXXInstanceMethod,
@@ -321,6 +321,8 @@ class RecordContext {
321321

322322
RecordContext(APIRecord::RecordKind Kind) : Kind(Kind) {}
323323

324+
void stealRecordChain(RecordContext &Other);
325+
324326
APIRecord::RecordKind getKind() const { return Kind; }
325327

326328
struct record_iterator {
@@ -475,31 +477,36 @@ struct GlobalFunctionTemplateSpecializationRecord : GlobalFunctionRecord {
475477
};
476478

477479
/// This holds information associated with global functions.
478-
struct GlobalVariableRecord : APIRecord {
480+
struct GlobalVariableRecord : APIRecord, RecordContext {
479481
GlobalVariableRecord(StringRef USR, StringRef Name, SymbolReference Parent,
480482
PresumedLoc Loc, AvailabilityInfo Availability,
481483
LinkageInfo Linkage, const DocComment &Comment,
482484
DeclarationFragments Declaration,
483485
DeclarationFragments SubHeading, bool IsFromSystemHeader)
484486
: APIRecord(RK_GlobalVariable, USR, Name, Parent, Loc,
485487
std::move(Availability), Linkage, Comment, Declaration,
486-
SubHeading, IsFromSystemHeader) {}
488+
SubHeading, IsFromSystemHeader),
489+
RecordContext(RK_GlobalVariable) {}
487490

488491
GlobalVariableRecord(RecordKind Kind, StringRef USR, StringRef Name,
489-
SymbolReference Parent,
490-
491-
PresumedLoc Loc, AvailabilityInfo Availability,
492-
LinkageInfo Linkage, const DocComment &Comment,
492+
SymbolReference Parent, PresumedLoc Loc,
493+
AvailabilityInfo Availability, LinkageInfo Linkage,
494+
const DocComment &Comment,
493495
DeclarationFragments Declaration,
494496
DeclarationFragments SubHeading, bool IsFromSystemHeader)
495497
: APIRecord(Kind, USR, Name, Parent, Loc, std::move(Availability),
496498
Linkage, Comment, Declaration, SubHeading,
497-
IsFromSystemHeader) {}
499+
IsFromSystemHeader),
500+
RecordContext(Kind) {}
498501

499502
static bool classof(const APIRecord *Record) {
500503
return classofKind(Record->getKind());
501504
}
502-
static bool classofKind(RecordKind K) { return K == RK_GlobalVariable; }
505+
static bool classofKind(RecordKind K) {
506+
return K == RK_GlobalVariable || K == RK_GlobalVariableTemplate ||
507+
K == RK_GlobalVariableTemplateSpecialization ||
508+
K == RK_GlobalVariableTemplatePartialSpecialization;
509+
}
503510

504511
private:
505512
virtual void anchor();
@@ -591,36 +598,64 @@ struct EnumConstantRecord : APIRecord {
591598
virtual void anchor();
592599
};
593600

601+
struct TagRecord : APIRecord, RecordContext {
602+
TagRecord(RecordKind Kind, StringRef USR, StringRef Name,
603+
SymbolReference Parent, PresumedLoc Loc,
604+
AvailabilityInfo Availability, const DocComment &Comment,
605+
DeclarationFragments Declaration, DeclarationFragments SubHeading,
606+
bool IsFromSystemHeader, bool IsEmbeddedInVarDeclarator,
607+
AccessControl Access = AccessControl())
608+
: APIRecord(Kind, USR, Name, Parent, Loc, std::move(Availability),
609+
LinkageInfo::none(), Comment, Declaration, SubHeading,
610+
IsFromSystemHeader, std::move(Access)),
611+
RecordContext(Kind),
612+
IsEmbeddedInVarDeclarator(IsEmbeddedInVarDeclarator){};
613+
614+
static bool classof(const APIRecord *Record) {
615+
return classofKind(Record->getKind());
616+
}
617+
static bool classofKind(RecordKind K) {
618+
return K == RK_Struct || K == RK_Union || K == RK_Enum;
619+
}
620+
621+
bool IsEmbeddedInVarDeclarator;
622+
623+
virtual ~TagRecord() = 0;
624+
};
625+
594626
/// This holds information associated with enums.
595-
struct EnumRecord : APIRecord, RecordContext {
627+
struct EnumRecord : TagRecord {
596628
EnumRecord(StringRef USR, StringRef Name, SymbolReference Parent,
597629
PresumedLoc Loc, AvailabilityInfo Availability,
598630
const DocComment &Comment, DeclarationFragments Declaration,
599-
DeclarationFragments SubHeading, bool IsFromSystemHeader)
600-
: APIRecord(RK_Enum, USR, Name, Parent, Loc, std::move(Availability),
601-
LinkageInfo::none(), Comment, Declaration, SubHeading,
602-
IsFromSystemHeader),
603-
RecordContext(RK_Enum) {}
631+
DeclarationFragments SubHeading, bool IsFromSystemHeader,
632+
bool IsEmbeddedInVarDeclarator,
633+
AccessControl Access = AccessControl())
634+
: TagRecord(RK_Enum, USR, Name, Parent, Loc, std::move(Availability),
635+
Comment, Declaration, SubHeading, IsFromSystemHeader,
636+
IsEmbeddedInVarDeclarator, std::move(Access)) {}
604637

605638
static bool classof(const APIRecord *Record) {
606639
return classofKind(Record->getKind());
607640
}
641+
608642
static bool classofKind(RecordKind K) { return K == RK_Enum; }
609643

610644
private:
611645
virtual void anchor();
612646
};
613647

614648
/// This holds information associated with struct or union fields fields.
615-
struct RecordFieldRecord : APIRecord {
649+
struct RecordFieldRecord : APIRecord, RecordContext {
616650
RecordFieldRecord(RecordKind Kind, StringRef USR, StringRef Name,
617651
SymbolReference Parent, PresumedLoc Loc,
618652
AvailabilityInfo Availability, const DocComment &Comment,
619653
DeclarationFragments Declaration,
620654
DeclarationFragments SubHeading, bool IsFromSystemHeader)
621655
: APIRecord(Kind, USR, Name, Parent, Loc, std::move(Availability),
622656
LinkageInfo::none(), Comment, Declaration, SubHeading,
623-
IsFromSystemHeader) {}
657+
IsFromSystemHeader),
658+
RecordContext(Kind) {}
624659

625660
static bool classof(const APIRecord *Record) {
626661
return classofKind(Record->getKind());
@@ -633,16 +668,17 @@ struct RecordFieldRecord : APIRecord {
633668
};
634669

635670
/// This holds information associated with structs and unions.
636-
struct RecordRecord : APIRecord, RecordContext {
671+
struct RecordRecord : TagRecord {
637672
RecordRecord(RecordKind Kind, StringRef USR, StringRef Name,
638673
SymbolReference Parent, PresumedLoc Loc,
639674
AvailabilityInfo Availability, const DocComment &Comment,
640675
DeclarationFragments Declaration,
641-
DeclarationFragments SubHeading, bool IsFromSystemHeader)
642-
: APIRecord(Kind, USR, Name, Parent, Loc, std::move(Availability),
643-
LinkageInfo::none(), Comment, Declaration, SubHeading,
644-
IsFromSystemHeader),
645-
RecordContext(Kind) {}
676+
DeclarationFragments SubHeading, bool IsFromSystemHeader,
677+
bool IsEmbeddedInVarDeclarator,
678+
AccessControl Access = AccessControl())
679+
: TagRecord(Kind, USR, Name, Parent, Loc, std::move(Availability),
680+
Comment, Declaration, SubHeading, IsFromSystemHeader,
681+
IsEmbeddedInVarDeclarator, std::move(Access)) {}
646682

647683
static bool classof(const APIRecord *Record) {
648684
return classofKind(Record->getKind());
@@ -651,6 +687,8 @@ struct RecordRecord : APIRecord, RecordContext {
651687
return K == RK_Struct || K == RK_Union;
652688
}
653689

690+
bool isAnonymousWithNoTypedef() { return Name.empty(); }
691+
654692
virtual ~RecordRecord() = 0;
655693
};
656694

@@ -676,9 +714,11 @@ struct StructRecord : RecordRecord {
676714
StructRecord(StringRef USR, StringRef Name, SymbolReference Parent,
677715
PresumedLoc Loc, AvailabilityInfo Availability,
678716
const DocComment &Comment, DeclarationFragments Declaration,
679-
DeclarationFragments SubHeading, bool IsFromSystemHeader)
717+
DeclarationFragments SubHeading, bool IsFromSystemHeader,
718+
bool IsEmbeddedInVarDeclarator)
680719
: RecordRecord(RK_Struct, USR, Name, Parent, Loc, std::move(Availability),
681-
Comment, Declaration, SubHeading, IsFromSystemHeader) {}
720+
Comment, Declaration, SubHeading, IsFromSystemHeader,
721+
IsEmbeddedInVarDeclarator) {}
682722

683723
static bool classof(const APIRecord *Record) {
684724
return classofKind(Record->getKind());
@@ -711,9 +751,11 @@ struct UnionRecord : RecordRecord {
711751
UnionRecord(StringRef USR, StringRef Name, SymbolReference Parent,
712752
PresumedLoc Loc, AvailabilityInfo Availability,
713753
const DocComment &Comment, DeclarationFragments Declaration,
714-
DeclarationFragments SubHeading, bool IsFromSystemHeader)
754+
DeclarationFragments SubHeading, bool IsFromSystemHeader,
755+
bool IsEmbeddedInVarDeclarator)
715756
: RecordRecord(RK_Union, USR, Name, Parent, Loc, std::move(Availability),
716-
Comment, Declaration, SubHeading, IsFromSystemHeader) {}
757+
Comment, Declaration, SubHeading, IsFromSystemHeader,
758+
IsEmbeddedInVarDeclarator) {}
717759

718760
static bool classof(const APIRecord *Record) {
719761
return classofKind(Record->getKind());
@@ -724,15 +766,16 @@ struct UnionRecord : RecordRecord {
724766
virtual void anchor();
725767
};
726768

727-
struct CXXFieldRecord : APIRecord {
769+
struct CXXFieldRecord : APIRecord, RecordContext {
728770
CXXFieldRecord(StringRef USR, StringRef Name, SymbolReference Parent,
729771
PresumedLoc Loc, AvailabilityInfo Availability,
730772
const DocComment &Comment, DeclarationFragments Declaration,
731773
DeclarationFragments SubHeading, AccessControl Access,
732774
bool IsFromSystemHeader)
733775
: APIRecord(RK_CXXField, USR, Name, Parent, Loc, std::move(Availability),
734776
LinkageInfo::none(), Comment, Declaration, SubHeading,
735-
IsFromSystemHeader, std::move(Access)) {}
777+
IsFromSystemHeader, std::move(Access)),
778+
RecordContext(RK_CXXField) {}
736779

737780
CXXFieldRecord(RecordKind Kind, StringRef USR, StringRef Name,
738781
SymbolReference Parent, PresumedLoc Loc,
@@ -742,7 +785,8 @@ struct CXXFieldRecord : APIRecord {
742785
bool IsFromSystemHeader)
743786
: APIRecord(Kind, USR, Name, Parent, Loc, std::move(Availability),
744787
LinkageInfo::none(), Comment, Declaration, SubHeading,
745-
IsFromSystemHeader, std::move(Access)) {}
788+
IsFromSystemHeader, std::move(Access)),
789+
RecordContext(Kind) {}
746790

747791
static bool classof(const APIRecord *Record) {
748792
return classofKind(Record->getKind());
@@ -1118,18 +1162,18 @@ struct ObjCContainerRecord : APIRecord, RecordContext {
11181162
virtual ~ObjCContainerRecord() = 0;
11191163
};
11201164

1121-
struct CXXClassRecord : APIRecord, RecordContext {
1165+
struct CXXClassRecord : RecordRecord {
11221166
SmallVector<SymbolReference> Bases;
11231167

11241168
CXXClassRecord(StringRef USR, StringRef Name, SymbolReference Parent,
11251169
PresumedLoc Loc, AvailabilityInfo Availability,
11261170
const DocComment &Comment, DeclarationFragments Declaration,
11271171
DeclarationFragments SubHeading, RecordKind Kind,
1128-
AccessControl Access, bool IsFromSystemHeader)
1129-
: APIRecord(Kind, USR, Name, Parent, Loc, std::move(Availability),
1130-
LinkageInfo::none(), Comment, Declaration, SubHeading,
1131-
IsFromSystemHeader, std::move(Access)),
1132-
RecordContext(Kind) {}
1172+
AccessControl Access, bool IsFromSystemHeader,
1173+
bool IsEmbeddedInVarDeclarator = false)
1174+
: RecordRecord(Kind, USR, Name, Parent, Loc, std::move(Availability),
1175+
Comment, Declaration, SubHeading, IsFromSystemHeader,
1176+
IsEmbeddedInVarDeclarator, std::move(Access)) {}
11331177

11341178
static bool classof(const APIRecord *Record) {
11351179
return classofKind(Record->getKind());

clang/include/clang/ExtractAPI/APIRecords.inc

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,11 @@ CONCRETE_RECORD(GlobalVariableTemplateSpecializationRecord,
3535
CONCRETE_RECORD(GlobalVariableTemplatePartialSpecializationRecord,
3636
GlobalVariableRecord,
3737
RK_GlobalVariableTemplatePartialSpecialization)
38+
ABSTRACT_RECORD(TagRecord, APIRecord)
3839
CONCRETE_RECORD(EnumConstantRecord, APIRecord, RK_EnumConstant)
39-
CONCRETE_RECORD(EnumRecord, APIRecord, RK_Enum)
40+
CONCRETE_RECORD(EnumRecord, TagRecord, RK_Enum)
4041
ABSTRACT_RECORD(RecordFieldRecord, APIRecord)
41-
ABSTRACT_RECORD(RecordRecord, APIRecord)
42+
ABSTRACT_RECORD(RecordRecord, TagRecord)
4243
CONCRETE_RECORD(StructFieldRecord, RecordFieldRecord, RK_StructField)
4344
CONCRETE_RECORD(StructRecord, APIRecord, RK_Struct)
4445
CONCRETE_RECORD(UnionFieldRecord, RecordFieldRecord, RK_UnionField)
@@ -99,5 +100,16 @@ RECORD_CONTEXT(ClassTemplateSpecializationRecord,
99100
RK_ClassTemplateSpecialization)
100101
RECORD_CONTEXT(ClassTemplatePartialSpecializationRecord,
101102
RK_ClassTemplatePartialSpecialization)
103+
RECORD_CONTEXT(StructFieldRecord, RK_StructField)
104+
RECORD_CONTEXT(UnionFieldRecord, RK_UnionField)
105+
RECORD_CONTEXT(CXXFieldRecord, RK_CXXField)
106+
RECORD_CONTEXT(StaticFieldRecord, RK_StaticField)
107+
RECORD_CONTEXT(CXXFieldTemplateRecord, RK_CXXFieldTemplate)
108+
RECORD_CONTEXT(GlobalVariableRecord, RK_GlobalVariable)
109+
RECORD_CONTEXT(GlobalVariableTemplateRecord, RK_GlobalVariableTemplate)
110+
RECORD_CONTEXT(GlobalVariableTemplateSpecializationRecord,
111+
RK_GlobalVariableTemplateSpecialization)
112+
RECORD_CONTEXT(GlobalVariableTemplatePartialSpecializationRecord,
113+
RK_GlobalVariableTemplatePartialSpecialization)
102114

103115
#undef RECORD_CONTEXT

0 commit comments

Comments
 (0)