Skip to content

Commit 5769b2a

Browse files
[clang][ExtractAPI] Flatten children of nested anonymous records into the parent scope
When an anonymous record is nested within another record and is not attached to a variable's type, we migrate the children to the parent record. rdar://128092236
1 parent 6b373a5 commit 5769b2a

File tree

2 files changed

+42
-0
lines changed

2 files changed

+42
-0
lines changed

clang/include/clang/ExtractAPI/ExtractAPIVisitor.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ namespace impl {
3838

3939
template <typename Derived>
4040
class ExtractAPIVisitorBase : public RecursiveASTVisitor<Derived> {
41+
using Base = RecursiveASTVisitor<Derived>;
42+
4143
protected:
4244
ExtractAPIVisitorBase(ASTContext &Context, APISet &API)
4345
: Context(Context), API(API) {}
@@ -79,8 +81,10 @@ class ExtractAPIVisitorBase : public RecursiveASTVisitor<Derived> {
7981

8082
bool VisitNamespaceDecl(const NamespaceDecl *Decl);
8183

84+
bool TraverseRecordDecl(RecordDecl *Decl);
8285
bool VisitRecordDecl(const RecordDecl *Decl);
8386

87+
bool TraverseCXXRecordDecl(CXXRecordDecl *Decl);
8488
bool VisitCXXRecordDecl(const CXXRecordDecl *Decl);
8589

8690
bool VisitCXXMethodDecl(const CXXMethodDecl *Decl);
@@ -548,6 +552,19 @@ bool ExtractAPIVisitorBase<Derived>::VisitNamespaceDecl(
548552
return true;
549553
}
550554

555+
template <typename Derived>
556+
bool ExtractAPIVisitorBase<Derived>::TraverseRecordDecl(RecordDecl *Decl) {
557+
bool Ret = Base::TraverseRecordDecl(Decl);
558+
559+
if (!isEmbeddedInVarDeclarator(*Decl) && Decl->isAnonymousStructOrUnion()) {
560+
SmallString<128> USR;
561+
index::generateUSRForDecl(Decl, USR);
562+
API.removeRecord(USR);
563+
}
564+
565+
return Ret;
566+
}
567+
551568
template <typename Derived>
552569
bool ExtractAPIVisitorBase<Derived>::VisitRecordDecl(const RecordDecl *Decl) {
553570
if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
@@ -588,6 +605,19 @@ bool ExtractAPIVisitorBase<Derived>::VisitRecordDecl(const RecordDecl *Decl) {
588605
return true;
589606
}
590607

608+
template <typename Derived>
609+
bool ExtractAPIVisitorBase<Derived>::TraverseCXXRecordDecl(CXXRecordDecl *Decl) {
610+
bool Ret = Base::TraverseCXXRecordDecl(Decl);
611+
612+
if (!isEmbeddedInVarDeclarator(*Decl) && Decl->isAnonymousStructOrUnion()) {
613+
SmallString<128> USR;
614+
index::generateUSRForDecl(Decl, USR);
615+
API.removeRecord(USR);
616+
}
617+
618+
return Ret;
619+
}
620+
591621
template <typename Derived>
592622
bool ExtractAPIVisitorBase<Derived>::VisitCXXRecordDecl(
593623
const CXXRecordDecl *Decl) {

clang/test/ExtractAPI/anonymous_record_no_typedef.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,4 +163,16 @@ enum {
163163
// GLOBALOTHERCASE-NEXT: "GlobalOtherCase"
164164
// GLOBALOTHERCASE-NEXT: ]
165165

166+
// RUN: FileCheck %s --input-file %t/output.symbols.json --check-prefix VEC
167+
union Vector {
168+
struct {
169+
float X;
170+
float Y;
171+
};
172+
float Data[2];
173+
};
174+
// VEC-DAG: "!testRelLabel": "memberOf $ c:@U@Vector@FI@Data $ c:@U@Vector"
175+
// VEC-DAG: "!testRelLabel": "memberOf $ c:@U@Vector@Sa@FI@X $ c:@U@Vector"
176+
// VEC-DAG: "!testRelLabel": "memberOf $ c:@U@Vector@Sa@FI@Y $ c:@U@Vector"
177+
166178
// expected-no-diagnostics

0 commit comments

Comments
 (0)