@@ -3300,12 +3300,19 @@ namespace {
33003300
33013301 // Create the struct declaration and record it.
33023302 auto name = importedName.getDeclName ().getBaseIdentifier ();
3303- auto result = Impl.createDeclWithClangNode <StructDecl>(decl,
3304- AccessLevel::Public,
3305- Impl.importSourceLoc (decl->getBeginLoc ()),
3306- name,
3307- Impl.importSourceLoc (decl->getLocation ()),
3308- None, nullptr , dc);
3303+ StructDecl *result = nullptr ;
3304+ // Try to find an already-imported struct. This case happens any time
3305+ // there are nested structs. The "Parent" struct will import the "Child"
3306+ // struct at which point it attempts to import its decl context which is
3307+ // the "Parent" struct. Without trying to look up already-imported structs
3308+ // this will cause an infinite loop.
3309+ auto alreadyImportedResult =
3310+ Impl.ImportedDecls .find ({decl->getCanonicalDecl (), getVersion ()});
3311+ if (alreadyImportedResult != Impl.ImportedDecls .end ())
3312+ return alreadyImportedResult->second ;
3313+ result = Impl.createDeclWithClangNode <StructDecl>(
3314+ decl, AccessLevel::Public, Impl.importSourceLoc (decl->getBeginLoc ()),
3315+ name, Impl.importSourceLoc (decl->getLocation ()), None, nullptr , dc);
33093316 Impl.ImportedDecls [{decl->getCanonicalDecl (), getVersion ()}] = result;
33103317
33113318 // FIXME: Figure out what to do with superclasses in C++. One possible
@@ -3316,6 +3323,7 @@ namespace {
33163323 SmallVector<VarDecl *, 4 > members;
33173324 SmallVector<FuncDecl *, 4 > methods;
33183325 SmallVector<ConstructorDecl *, 4 > ctors;
3326+ SmallVector<TypeDecl *, 4 > nestedTypes;
33193327
33203328 // FIXME: Import anonymous union fields and support field access when
33213329 // it is nested in a struct.
@@ -3374,27 +3382,13 @@ namespace {
33743382 continue ;
33753383 }
33763384
3377- if (isa <TypeDecl>(member)) {
3385+ if (auto nestedType = dyn_cast <TypeDecl>(member)) {
33783386 // Only import definitions. Otherwise, we might add the same member
33793387 // twice.
33803388 if (auto tagDecl = dyn_cast<clang::TagDecl>(nd))
33813389 if (tagDecl->getDefinition () != tagDecl)
33823390 continue ;
3383- // A struct nested inside another struct will either be logically
3384- // a sibling of the outer struct, or contained inside of it, depending
3385- // on if it has a declaration name or not.
3386- //
3387- // struct foo { struct bar { ... } baz; } // sibling
3388- // struct foo { struct { ... } baz; } // child
3389- //
3390- // In the latter case, we add the imported type as a nested type
3391- // of the parent.
3392- //
3393- // TODO: C++ types have different rules.
3394- if (auto nominalDecl = dyn_cast<NominalTypeDecl>(member->getDeclContext ())) {
3395- assert (nominalDecl == result && " interesting nesting of C types?" );
3396- nominalDecl->addMember (member);
3397- }
3391+ nestedTypes.push_back (nestedType);
33983392 continue ;
33993393 }
34003394
@@ -3417,7 +3411,30 @@ namespace {
34173411 }
34183412
34193413 members.push_back (VD);
3414+ }
34203415
3416+ for (auto nestedType : nestedTypes) {
3417+ // A struct nested inside another struct will either be logically
3418+ // a sibling of the outer struct, or contained inside of it, depending
3419+ // on if it has a declaration name or not.
3420+ //
3421+ // struct foo { struct bar { ... } baz; } // sibling
3422+ // struct foo { struct { ... } baz; } // child
3423+ //
3424+ // In the latter case, we add the imported type as a nested type
3425+ // of the parent.
3426+ //
3427+ // TODO: C++ types have different rules.
3428+ if (auto nominalDecl =
3429+ dyn_cast<NominalTypeDecl>(nestedType->getDeclContext ())) {
3430+ assert (nominalDecl == result && " interesting nesting of C types?" );
3431+ nominalDecl->addMember (nestedType);
3432+ }
3433+ }
3434+
3435+ bool hasReferenceableFields = !members.empty ();
3436+ for (auto member : members) {
3437+ auto nd = cast<clang::NamedDecl>(member->getClangDecl ());
34213438 // Bitfields are imported as computed properties with Clang-generated
34223439 // accessors.
34233440 bool isBitField = false ;
@@ -3428,37 +3445,33 @@ namespace {
34283445 hasUnreferenceableStorage = true ;
34293446 isBitField = true ;
34303447
3431- makeBitFieldAccessors (Impl,
3432- const_cast <clang::RecordDecl *>(decl),
3433- result,
3434- const_cast <clang::FieldDecl *>(field),
3435- VD);
3448+ makeBitFieldAccessors (Impl, const_cast <clang::RecordDecl *>(decl),
3449+ result, const_cast <clang::FieldDecl *>(field),
3450+ member);
34363451 }
34373452 }
34383453
34393454 if (auto ind = dyn_cast<clang::IndirectFieldDecl>(nd)) {
34403455 // Indirect fields are created as computed property accessible the
34413456 // fields on the anonymous field from which they are injected.
3442- makeIndirectFieldAccessors (Impl, ind, members, result, VD );
3457+ makeIndirectFieldAccessors (Impl, ind, members, result, member );
34433458 } else if (decl->isUnion () && !isBitField) {
34443459 // Union fields should only be available indirectly via a computed
34453460 // property. Since the union is made of all of the fields at once,
34463461 // this is a trivial accessor that casts self to the correct
34473462 // field type.
3448- makeUnionFieldAccessors (Impl, result, VD );
3463+ makeUnionFieldAccessors (Impl, result, member );
34493464
34503465 // Create labeled initializers for unions that take one of the
34513466 // fields, which only initializes the data for that field.
3452- auto valueCtor =
3453- createValueConstructor (Impl, result, VD,
3454- /* want param names*/ true ,
3455- /* wantBody=*/ true );
3467+ auto valueCtor = createValueConstructor (Impl, result, member,
3468+ /* want param names*/ true ,
3469+ /* wantBody=*/ true );
34563470 ctors.push_back (valueCtor);
34573471 }
3472+ result->addMember (member);
34583473 }
34593474
3460- bool hasReferenceableFields = !members.empty ();
3461-
34623475 const clang::CXXRecordDecl *cxxRecordDecl =
34633476 dyn_cast<clang::CXXRecordDecl>(decl);
34643477 if (hasZeroInitializableStorage && !cxxRecordDecl) {
@@ -3486,10 +3499,6 @@ namespace {
34863499 ctors.push_back (valueCtor);
34873500 }
34883501
3489- for (auto member : members) {
3490- result->addMember (member);
3491- }
3492-
34933502 for (auto ctor : ctors) {
34943503 result->addMember (ctor);
34953504 }
@@ -9033,7 +9042,9 @@ ClangImporter::Implementation::loadAllMembers(Decl *D, uint64_t extra) {
90339042 if (!member)
90349043 continue ;
90359044
9036- enumDecl->addMember (member);
9045+ // TODO: remove this change when #34706 lands.
9046+ if (!member->NextDecl )
9047+ enumDecl->addMember (member);
90379048 }
90389049 }
90399050 return ;
0 commit comments