@@ -867,8 +867,8 @@ makeUnionFieldAccessors(ClangImporter::Implementation &Impl,
867
867
868
868
static clang::DeclarationName
869
869
getAccessorDeclarationName (clang::ASTContext &Ctx,
870
- clang::RecordDecl *structDecl,
871
- clang::FieldDecl *fieldDecl,
870
+ StructDecl *structDecl,
871
+ VarDecl *fieldDecl,
872
872
const char *suffix) {
873
873
std::string id;
874
874
llvm::raw_string_ostream IdStream (id);
@@ -906,8 +906,8 @@ makeBitFieldAccessors(ClangImporter::Implementation &Impl,
906
906
auto fieldNameInfo = clang::DeclarationNameInfo (fieldDecl->getDeclName (),
907
907
clang::SourceLocation ());
908
908
909
- auto cGetterName = getAccessorDeclarationName (Ctx, structDecl, fieldDecl ,
910
- " getter" );
909
+ auto cGetterName = getAccessorDeclarationName (Ctx, importedStructDecl ,
910
+ importedFieldDecl, " getter" );
911
911
auto cGetterType = Ctx.getFunctionType (fieldDecl->getType (),
912
912
recordType,
913
913
clang::FunctionProtoType::ExtProtoInfo ());
@@ -933,8 +933,8 @@ makeBitFieldAccessors(ClangImporter::Implementation &Impl,
933
933
cSetterParamTypes.push_back (fieldType);
934
934
cSetterParamTypes.push_back (recordPointerType);
935
935
936
- auto cSetterName = getAccessorDeclarationName (Ctx, structDecl, fieldDecl ,
937
- " setter" );
936
+ auto cSetterName = getAccessorDeclarationName (Ctx, importedStructDecl ,
937
+ importedFieldDecl, " setter" );
938
938
auto cSetterType = Ctx.getFunctionType (Ctx.VoidTy ,
939
939
cSetterParamTypes,
940
940
clang::FunctionProtoType::ExtProtoInfo ());
@@ -1062,6 +1062,62 @@ makeBitFieldAccessors(ClangImporter::Implementation &Impl,
1062
1062
return { getterDecl, setterDecl };
1063
1063
}
1064
1064
1065
+ // Fake a declaration name for anonymous enums, unions and structs.
1066
+ static Identifier getClangDeclName (ClangImporter::Implementation &Impl,
1067
+ const clang::TagDecl *decl) {
1068
+ Identifier name;
1069
+ if (decl->getDeclName ())
1070
+ name = Impl.importName (decl);
1071
+ else if (auto *typedefForAnon = decl->getTypedefNameForAnonDecl ())
1072
+ name = Impl.importName (typedefForAnon);
1073
+
1074
+ // If the type has no name and no structure name, but is not anonymous,
1075
+ // generate a name for it. Specifically this is for cases like:
1076
+ // struct a {
1077
+ // struct {} z;
1078
+ // }
1079
+ // Where the member z is an unnamed struct, but does have a member-name
1080
+ // and is accessible as a member of struct a.
1081
+ if (name.empty () && decl->isRecord ()) {
1082
+ auto dc = decl->getParent ();
1083
+ if (!dc->isRecord ())
1084
+ return name;
1085
+
1086
+ auto recordDecl = cast<clang::RecordDecl>(dc);
1087
+
1088
+ for (auto m : recordDecl->decls ()) {
1089
+ auto field = dyn_cast<clang::FieldDecl>(m);
1090
+ if (!field)
1091
+ continue ;
1092
+
1093
+ if (auto recordType = dyn_cast<clang::RecordType>(field->getType ().getCanonicalType ())) {
1094
+ if (recordType->getDecl () == decl) {
1095
+ // We found the field. It better not be anonymous.
1096
+ assert (!field->isAnonymousStructOrUnion ());
1097
+
1098
+ // Create a name for the structure from the field name.
1099
+ std::string Id;
1100
+ llvm::raw_string_ostream IdStream (Id);
1101
+
1102
+ const char *kind;
1103
+ if (decl->isStruct ())
1104
+ kind = " struct" ;
1105
+ else if (decl->isUnion ())
1106
+ kind = " union" ;
1107
+ else
1108
+ assert (false && " unknown decl kind" );
1109
+
1110
+ IdStream << " __Unnamed_" << kind
1111
+ << " _" << field->getName ();
1112
+ return Impl.SwiftContext .getIdentifier (IdStream.str ());
1113
+ }
1114
+ }
1115
+ }
1116
+ }
1117
+
1118
+ return name;
1119
+ }
1120
+
1065
1121
namespace {
1066
1122
class CFPointeeInfo {
1067
1123
bool IsValid;
@@ -2078,12 +2134,7 @@ namespace {
2078
2134
return nullptr ;
2079
2135
}
2080
2136
2081
- Identifier name;
2082
- if (decl->getDeclName ())
2083
- name = Impl.importName (decl);
2084
- else if (auto *typedefForAnon = decl->getTypedefNameForAnonDecl ())
2085
- name = Impl.importName (typedefForAnon);
2086
-
2137
+ auto name = getClangDeclName (Impl, decl);
2087
2138
if (name.empty ())
2088
2139
return nullptr ;
2089
2140
@@ -2338,12 +2389,7 @@ namespace {
2338
2389
return nullptr ;
2339
2390
}
2340
2391
2341
- Identifier name;
2342
- if (decl->getDeclName ())
2343
- name = Impl.importName (decl);
2344
- else if (auto *typedefForAnon = decl->getTypedefNameForAnonDecl ())
2345
- name = Impl.importName (typedefForAnon);
2346
-
2392
+ auto name = getClangDeclName (Impl, decl);
2347
2393
if (name.empty ())
2348
2394
return nullptr ;
2349
2395
@@ -2370,105 +2416,108 @@ namespace {
2370
2416
2371
2417
// FIXME: Import anonymous union fields and support field access when
2372
2418
// it is nested in a struct.
2373
- if (!(decl->isUnion () && decl->isAnonymousStructOrUnion ())) {
2374
- for (auto m = decl->decls_begin (), mEnd = decl->decls_end ();
2375
- m != mEnd ; ++m) {
2376
- auto nd = dyn_cast<clang::NamedDecl>(*m);
2377
- if (!nd) {
2378
- // We couldn't import the member, so we can't reference it in Swift.
2379
- hasUnreferenceableStorage = true ;
2380
- hasMemberwiseInitializer = false ;
2381
- continue ;
2382
- }
2383
2419
2420
+ for (auto m = decl->decls_begin (), mEnd = decl->decls_end ();
2421
+ m != mEnd ; ++m) {
2422
+ auto nd = dyn_cast<clang::NamedDecl>(*m);
2423
+ if (!nd) {
2424
+ // We couldn't import the member, so we can't reference it in Swift.
2425
+ hasUnreferenceableStorage = true ;
2426
+ hasMemberwiseInitializer = false ;
2427
+ continue ;
2428
+ }
2429
+
2430
+ if (auto field = dyn_cast<clang::FieldDecl>(nd)) {
2384
2431
// Skip anonymous structs or unions; they'll be dealt with via the
2385
2432
// IndirectFieldDecls.
2386
- if (auto field = dyn_cast<clang::FieldDecl>(nd)) {
2387
- if (field->isAnonymousStructOrUnion ())
2388
- continue ;
2433
+ if (field->isAnonymousStructOrUnion ())
2434
+ continue ;
2389
2435
2390
- // Non-nullable pointers can't be zero-initialized.
2391
- if (auto nullability = field->getType ()
2392
- ->getNullability (Impl.getClangASTContext ())) {
2393
- if (*nullability == clang::NullabilityKind::NonNull)
2394
- hasZeroInitializableStorage = false ;
2395
- }
2396
- // TODO: If we had the notion of a closed enum with no private
2397
- // cases or resilience concerns, then complete NS_ENUMs with
2398
- // no case corresponding to zero would also not be zero-
2399
- // initializable.
2400
-
2401
- // Unnamed bitfields are just for padding and should not
2402
- // inhibit creation of a memberwise initializer.
2403
- if (field->isUnnamedBitfield ()) {
2404
- hasUnreferenceableStorage = true ;
2405
- continue ;
2406
- }
2436
+ // Non-nullable pointers can't be zero-initialized.
2437
+ if (auto nullability = field->getType ()
2438
+ ->getNullability (Impl.getClangASTContext ())) {
2439
+ if (*nullability == clang::NullabilityKind::NonNull)
2440
+ hasZeroInitializableStorage = false ;
2407
2441
}
2408
-
2409
- auto member = Impl.importDecl (nd);
2410
- if (!member || !isa<VarDecl>(member)) {
2411
- // We don't import nested struct decls from C as nested structs,
2412
- // which wouldn't match C or ObjC semantics. It's OK to skip these.
2413
- // TODO: For C++ types we *would* want to preserve the nesting.
2414
- if (dyn_cast_or_null<TypeDecl>(member))
2415
- continue ;
2416
-
2417
- // Otherwise, we don't know what this field is. Assume it may be
2418
- // important in C.
2442
+ // TODO: If we had the notion of a closed enum with no private
2443
+ // cases or resilience concerns, then complete NS_ENUMs with
2444
+ // no case corresponding to zero would also not be zero-
2445
+ // initializable.
2446
+
2447
+ // Unnamed bitfields are just for padding and should not
2448
+ // inhibit creation of a memberwise initializer.
2449
+ if (field->isUnnamedBitfield ()) {
2419
2450
hasUnreferenceableStorage = true ;
2420
- hasMemberwiseInitializer = false ;
2421
2451
continue ;
2422
2452
}
2423
-
2424
- auto VD = cast<VarDecl>(member);
2453
+ }
2425
2454
2426
- // Bitfields are imported as computed properties with Clang-generated
2427
- // accessors.
2428
- if (auto field = dyn_cast<clang::FieldDecl>(nd)) {
2429
- if (field->isUnnamedBitfield ())
2430
- continue ;
2455
+ auto member = Impl.importDecl (nd);
2456
+ if (!member) {
2457
+ // We don't know what this field is. Assume it may be important in C.
2458
+ hasUnreferenceableStorage = true ;
2459
+ hasMemberwiseInitializer = false ;
2460
+ continue ;
2461
+ }
2462
+
2463
+ if (isa<TypeDecl>(member)) {
2464
+ // A struct nested inside another struct will either be logically
2465
+ // a sibling of the outer struct, or contained inside of it, depending
2466
+ // on if it has a declaration name or not.
2467
+ //
2468
+ // struct foo { struct bar { ... } baz; } // sibling
2469
+ // struct foo { struct { ... } baz; } // child
2470
+ //
2471
+ // In the latter case, we add the imported type as a nested type
2472
+ // of the parent.
2473
+ //
2474
+ // TODO: C++ types have different rules.
2475
+ if (auto nominalDecl = dyn_cast<NominalTypeDecl>(member->getDeclContext ()))
2476
+ nominalDecl->addMember (member);
2477
+ continue ;
2478
+ }
2431
2479
2432
- if (field->isBitField ()) {
2433
- // We can't represent this struct completely in SIL anymore,
2434
- // but we're still able to define a memberwise initializer.
2435
- hasUnreferenceableStorage = true ;
2480
+ auto VD = cast<VarDecl>(member);
2436
2481
2437
- makeBitFieldAccessors (Impl,
2438
- const_cast <clang::RecordDecl *>(decl),
2439
- result,
2440
- const_cast <clang::FieldDecl *>(field),
2441
- VD);
2442
- }
2482
+ // Bitfields are imported as computed properties with Clang-generated
2483
+ // accessors.
2484
+ if (auto field = dyn_cast<clang::FieldDecl>(nd)) {
2485
+ if (field->isBitField ()) {
2486
+ // We can't represent this struct completely in SIL anymore,
2487
+ // but we're still able to define a memberwise initializer.
2488
+ hasUnreferenceableStorage = true ;
2489
+
2490
+ makeBitFieldAccessors (Impl,
2491
+ const_cast <clang::RecordDecl *>(decl),
2492
+ result,
2493
+ const_cast <clang::FieldDecl *>(field),
2494
+ VD);
2443
2495
}
2496
+ }
2444
2497
2445
- if (decl->isUnion ()) {
2446
- // Union fields should only be available indirectly via a computed
2447
- // property. Since the union is made of all of the fields at once,
2448
- // this is a trivial accessor that casts self to the correct
2449
- // field type.
2498
+ if (decl->isUnion ()) {
2499
+ // Union fields should only be available indirectly via a computed
2500
+ // property. Since the union is made of all of the fields at once,
2501
+ // this is a trivial accessor that casts self to the correct
2502
+ // field type.
2450
2503
2451
- // FIXME: Allow indirect field access of anonymous structs.
2452
- if (isa<clang::IndirectFieldDecl>(nd))
2453
- continue ;
2504
+ // FIXME: Allow indirect field access of anonymous structs.
2505
+ if (isa<clang::IndirectFieldDecl>(nd))
2506
+ continue ;
2454
2507
2455
- VD->setLet (false );
2456
- Decl *getter, *setter;
2457
- std::tie (getter, setter) = makeUnionFieldAccessors (Impl,
2458
- result,
2459
- VD);
2460
- members.push_back (VD);
2461
-
2462
- // Create labeled inititializers for unions that take one of the
2463
- // fields, which only initializes the data for that field.
2464
- auto valueCtor =
2465
- createValueConstructor (result, VD,
2466
- /* want param names*/ true ,
2467
- /* wantBody=*/ !Impl.hasFinishedTypeChecking ());
2468
- ctors.push_back (valueCtor);
2469
- } else {
2470
- members.push_back (VD);
2471
- }
2508
+ Decl *getter, *setter;
2509
+ std::tie (getter, setter) = makeUnionFieldAccessors (Impl, result, VD);
2510
+ members.push_back (VD);
2511
+
2512
+ // Create labeled inititializers for unions that take one of the
2513
+ // fields, which only initializes the data for that field.
2514
+ auto valueCtor =
2515
+ createValueConstructor (result, VD,
2516
+ /* want param names*/ true ,
2517
+ /* wantBody=*/ !Impl.hasFinishedTypeChecking ());
2518
+ ctors.push_back (valueCtor);
2519
+ } else {
2520
+ members.push_back (VD);
2472
2521
}
2473
2522
}
2474
2523
0 commit comments