@@ -250,27 +250,6 @@ class ExtractAPIVisitorBase : public RecursiveASTVisitor<Derived> {
250250 return D.getName ().empty () && getTypedefName (&D).empty () &&
251251 D.isEmbeddedInDeclarator () && !D.isFreeStanding ();
252252 }
253-
254- void maybeMergeWithAnonymousTag (const DeclaratorDecl &D,
255- RecordContext *NewRecordContext) {
256- if (!NewRecordContext)
257- return ;
258- auto *Tag = D.getType ()->getAsTagDecl ();
259- if (!Tag) {
260- if (const auto *AT = D.getASTContext ().getAsArrayType (D.getType ())) {
261- Tag = AT->getElementType ()->getAsTagDecl ();
262- }
263- }
264- SmallString<128 > TagUSR;
265- clang::index::generateUSRForDecl (Tag, TagUSR);
266- if (auto *Record = llvm::dyn_cast_if_present<TagRecord>(
267- API.findRecordForUSR (TagUSR))) {
268- if (Record->IsEmbeddedInVarDeclarator ) {
269- NewRecordContext->stealRecordChain (*Record);
270- API.removeRecord (Record);
271- }
272- }
273- }
274253};
275254
276255template <typename Derived>
@@ -322,14 +301,10 @@ bool ExtractAPIVisitorBase<Derived>::VisitVarDecl(const VarDecl *Decl) {
322301 SubHeading, Access, isInSystemHeader (Decl));
323302 } else {
324303 // Add the global variable record to the API set.
325- auto *NewRecord = API.createRecord <GlobalVariableRecord>(
304+ API.createRecord <GlobalVariableRecord>(
326305 USR, Name, createHierarchyInformationForDecl (*Decl), Loc,
327306 AvailabilityInfo::createFromDecl (Decl), Linkage, Comment, Declaration,
328307 SubHeading, isInSystemHeader (Decl));
329-
330- // If this global variable has a non typedef'd anonymous tag type let's
331- // pretend the type's child records are under us in the hierarchy.
332- maybeMergeWithAnonymousTag (*Decl, NewRecord);
333308 }
334309
335310 return true ;
@@ -565,15 +540,7 @@ bool ExtractAPIVisitorBase<Derived>::VisitNamespaceDecl(
565540
566541template <typename Derived>
567542bool ExtractAPIVisitorBase<Derived>::TraverseRecordDecl(RecordDecl *Decl) {
568- bool Ret = Base::TraverseRecordDecl (Decl);
569-
570- if (!isEmbeddedInVarDeclarator (*Decl) && Decl->isAnonymousStructOrUnion ()) {
571- SmallString<128 > USR;
572- index::generateUSRForDecl (Decl, USR);
573- API.removeRecord (USR);
574- }
575-
576- return Ret;
543+ return Base::TraverseRecordDecl (Decl);
577544}
578545
579546template <typename Derived>
@@ -620,13 +587,7 @@ template <typename Derived>
620587bool ExtractAPIVisitorBase<Derived>::TraverseCXXRecordDecl(
621588 CXXRecordDecl *Decl) {
622589 bool Ret = Base::TraverseCXXRecordDecl (Decl);
623-
624- if (!isEmbeddedInVarDeclarator (*Decl) && Decl->isAnonymousStructOrUnion ()) {
625- SmallString<128 > USR;
626- index::generateUSRForDecl (Decl, USR);
627- API.removeRecord (USR);
628- }
629-
590+ // Keep anonymous structs in the hierarchy to preserve path components
630591 return Ret;
631592}
632593
@@ -643,6 +604,11 @@ bool ExtractAPIVisitorBase<Derived>::VisitCXXRecordDecl(
643604
644605 SmallString<128 > USR;
645606 index::generateUSRForDecl (Decl, USR);
607+
608+ if (API.findRecordForUSR (USR)) {
609+ return true ;
610+ }
611+
646612 PresumedLoc Loc =
647613 Context.getSourceManager ().getPresumedLoc (Decl->getLocation ());
648614 DocComment Comment;
@@ -679,6 +645,13 @@ bool ExtractAPIVisitorBase<Derived>::VisitCXXRecordDecl(
679645 Record->KindForDisplay = getKindForDisplay (Decl);
680646 Record->Bases = getBases (Decl);
681647
648+ // Visit nested records
649+ for (const auto *NestedDecl : Decl->decls ()) {
650+ if (auto *NestedRecord = dyn_cast<CXXRecordDecl>(NestedDecl)) {
651+ VisitCXXRecordDecl (NestedRecord);
652+ }
653+ }
654+
682655 return true ;
683656}
684657
@@ -1320,31 +1293,26 @@ bool ExtractAPIVisitorBase<Derived>::VisitFieldDecl(const FieldDecl *Decl) {
13201293 DeclarationFragments SubHeading =
13211294 DeclarationFragmentsBuilder::getSubHeading (Decl);
13221295
1323- RecordContext *NewRecord = nullptr ;
13241296 if (isa<CXXRecordDecl>(Decl->getDeclContext ())) {
13251297 AccessControl Access = DeclarationFragmentsBuilder::getAccessControl (Decl);
13261298
1327- NewRecord = API.createRecord <CXXFieldRecord>(
1299+ API.createRecord <CXXFieldRecord>(
13281300 USR, Name, createHierarchyInformationForDecl (*Decl), Loc,
13291301 AvailabilityInfo::createFromDecl (Decl), Comment, Declaration,
13301302 SubHeading, Access, isInSystemHeader (Decl));
13311303 } else if (auto *RD = dyn_cast<RecordDecl>(Decl->getDeclContext ())) {
13321304 if (RD->isUnion ())
1333- NewRecord = API.createRecord <UnionFieldRecord>(
1305+ API.createRecord <UnionFieldRecord>(
13341306 USR, Name, createHierarchyInformationForDecl (*Decl), Loc,
13351307 AvailabilityInfo::createFromDecl (Decl), Comment, Declaration,
13361308 SubHeading, isInSystemHeader (Decl));
13371309 else
1338- NewRecord = API.createRecord <StructFieldRecord>(
1310+ API.createRecord <StructFieldRecord>(
13391311 USR, Name, createHierarchyInformationForDecl (*Decl), Loc,
13401312 AvailabilityInfo::createFromDecl (Decl), Comment, Declaration,
13411313 SubHeading, isInSystemHeader (Decl));
13421314 }
13431315
1344- // If this field has a non typedef'd anonymous tag type let's pretend the
1345- // type's child records are under us in the hierarchy.
1346- maybeMergeWithAnonymousTag (*Decl, NewRecord);
1347-
13481316 return true ;
13491317}
13501318
0 commit comments