@@ -3300,12 +3300,19 @@ namespace {
3300
3300
3301
3301
// Create the struct declaration and record it.
3302
3302
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);
3309
3316
Impl.ImportedDecls [{decl->getCanonicalDecl (), getVersion ()}] = result;
3310
3317
3311
3318
// FIXME: Figure out what to do with superclasses in C++. One possible
@@ -3316,6 +3323,7 @@ namespace {
3316
3323
SmallVector<VarDecl *, 4 > members;
3317
3324
SmallVector<FuncDecl *, 4 > methods;
3318
3325
SmallVector<ConstructorDecl *, 4 > ctors;
3326
+ SmallVector<TypeDecl *, 4 > nestedTypes;
3319
3327
3320
3328
// FIXME: Import anonymous union fields and support field access when
3321
3329
// it is nested in a struct.
@@ -3374,27 +3382,13 @@ namespace {
3374
3382
continue ;
3375
3383
}
3376
3384
3377
- if (isa <TypeDecl>(member)) {
3385
+ if (auto nestedType = dyn_cast <TypeDecl>(member)) {
3378
3386
// Only import definitions. Otherwise, we might add the same member
3379
3387
// twice.
3380
3388
if (auto tagDecl = dyn_cast<clang::TagDecl>(nd))
3381
3389
if (tagDecl->getDefinition () != tagDecl)
3382
3390
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);
3398
3392
continue ;
3399
3393
}
3400
3394
@@ -3417,7 +3411,30 @@ namespace {
3417
3411
}
3418
3412
3419
3413
members.push_back (VD);
3414
+ }
3420
3415
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 ());
3421
3438
// Bitfields are imported as computed properties with Clang-generated
3422
3439
// accessors.
3423
3440
bool isBitField = false ;
@@ -3428,37 +3445,33 @@ namespace {
3428
3445
hasUnreferenceableStorage = true ;
3429
3446
isBitField = true ;
3430
3447
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);
3436
3451
}
3437
3452
}
3438
3453
3439
3454
if (auto ind = dyn_cast<clang::IndirectFieldDecl>(nd)) {
3440
3455
// Indirect fields are created as computed property accessible the
3441
3456
// fields on the anonymous field from which they are injected.
3442
- makeIndirectFieldAccessors (Impl, ind, members, result, VD );
3457
+ makeIndirectFieldAccessors (Impl, ind, members, result, member );
3443
3458
} else if (decl->isUnion () && !isBitField) {
3444
3459
// Union fields should only be available indirectly via a computed
3445
3460
// property. Since the union is made of all of the fields at once,
3446
3461
// this is a trivial accessor that casts self to the correct
3447
3462
// field type.
3448
- makeUnionFieldAccessors (Impl, result, VD );
3463
+ makeUnionFieldAccessors (Impl, result, member );
3449
3464
3450
3465
// Create labeled initializers for unions that take one of the
3451
3466
// 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 );
3456
3470
ctors.push_back (valueCtor);
3457
3471
}
3472
+ result->addMember (member);
3458
3473
}
3459
3474
3460
- bool hasReferenceableFields = !members.empty ();
3461
-
3462
3475
const clang::CXXRecordDecl *cxxRecordDecl =
3463
3476
dyn_cast<clang::CXXRecordDecl>(decl);
3464
3477
if (hasZeroInitializableStorage && !cxxRecordDecl) {
@@ -3486,10 +3499,6 @@ namespace {
3486
3499
ctors.push_back (valueCtor);
3487
3500
}
3488
3501
3489
- for (auto member : members) {
3490
- result->addMember (member);
3491
- }
3492
-
3493
3502
for (auto ctor : ctors) {
3494
3503
result->addMember (ctor);
3495
3504
}
@@ -9033,7 +9042,9 @@ ClangImporter::Implementation::loadAllMembers(Decl *D, uint64_t extra) {
9033
9042
if (!member)
9034
9043
continue ;
9035
9044
9036
- enumDecl->addMember (member);
9045
+ // TODO: remove this change when #34706 lands.
9046
+ if (!member->NextDecl )
9047
+ enumDecl->addMember (member);
9037
9048
}
9038
9049
}
9039
9050
return ;
0 commit comments