@@ -596,6 +596,122 @@ static FuncDecl *makeFieldSetterDecl(ClangImporter::Implementation &Impl,
596
596
return setterDecl;
597
597
}
598
598
599
+ // / Build the indirect field getter and setter.
600
+ // /
601
+ // / \code
602
+ // / struct SomeImportedIndirectField {
603
+ // / struct __Unnamed_struct___Anonymous_field_1 {
604
+ // / var myField : Int
605
+ // / }
606
+ // / var __Anonymous_field_1 : __Unnamed_struct___Anonymous_field_1
607
+ // / var myField : Int {
608
+ // / get {
609
+ // / __Anonymous_field_1.myField
610
+ // / }
611
+ // / set(newValue) {
612
+ // / __Anonymous_field_1.myField = newValue
613
+ // / }
614
+ // / }
615
+ // / }
616
+ // / \endcode
617
+ // /
618
+ // / \returns a pair of getter and setter function decls.
619
+ static std::pair<FuncDecl *, FuncDecl *>
620
+ makeIndirectFieldAccessors (ClangImporter::Implementation &Impl,
621
+ const clang::IndirectFieldDecl *indirectField,
622
+ ArrayRef<VarDecl *> members,
623
+ StructDecl *importedStructDecl,
624
+ VarDecl *importedFieldDecl) {
625
+ auto &C = Impl.SwiftContext ;
626
+
627
+ auto getterDecl = makeFieldGetterDecl (Impl,
628
+ importedStructDecl,
629
+ importedFieldDecl);
630
+
631
+ auto setterDecl = makeFieldSetterDecl (Impl,
632
+ importedStructDecl,
633
+ importedFieldDecl);
634
+
635
+ importedFieldDecl->makeComputed (SourceLoc (), getterDecl, setterDecl, nullptr ,
636
+ SourceLoc ());
637
+
638
+ auto containingField = indirectField->chain ().front ();
639
+ VarDecl *anonymousFieldDecl = nullptr ;
640
+
641
+ // Reverse scan of the members because indirect field are generated just
642
+ // after the corresponding anonymous type, so a reverse scan allows
643
+ // swiftching from O(n) to O(1) here.
644
+ for (auto decl : reverse (members)) {
645
+ if (decl->getClangDecl () == containingField) {
646
+ anonymousFieldDecl = cast<VarDecl>(decl);
647
+ break ;
648
+ }
649
+ }
650
+ assert (anonymousFieldDecl && " anonymous field not generated" );
651
+
652
+ auto anonymousFieldType = anonymousFieldDecl->getInterfaceType ();
653
+ auto anonymousFieldTypeDecl = anonymousFieldType->getStructOrBoundGenericStruct ();
654
+
655
+ VarDecl *anonymousInnerFieldDecl = nullptr ;
656
+ for (auto decl : anonymousFieldTypeDecl->lookupDirect (importedFieldDecl->getName ())) {
657
+ if (isa<VarDecl>(decl)) {
658
+ anonymousInnerFieldDecl = cast<VarDecl>(decl);
659
+ break ;
660
+ }
661
+ }
662
+ assert (anonymousInnerFieldDecl && " cannot find field in anonymous generated structure" );
663
+
664
+ // Don't bother synthesizing the body if we've already finished type-checking.
665
+ if (Impl.hasFinishedTypeChecking ())
666
+ return { getterDecl, setterDecl };
667
+
668
+ // Synthesize the getter body
669
+ {
670
+ auto selfDecl = getterDecl->getImplicitSelfDecl ();
671
+ Expr *expr = new (C) DeclRefExpr (selfDecl, DeclNameLoc (),
672
+ /* implicit*/ true );
673
+ expr = new (C) MemberRefExpr (expr, SourceLoc (), anonymousFieldDecl,
674
+ DeclNameLoc (), /* implicit*/ true );
675
+
676
+ expr = new (C) MemberRefExpr (expr, SourceLoc (), anonymousInnerFieldDecl,
677
+ DeclNameLoc (), /* implicit*/ true );
678
+
679
+ auto ret = new (C) ReturnStmt (SourceLoc (), expr);
680
+ auto body = BraceStmt::create (C, SourceLoc (), ASTNode (ret), SourceLoc (),
681
+ /* implicit*/ true );
682
+ getterDecl->setBody (body);
683
+ getterDecl->getAttrs ().add (new (C) TransparentAttr (/* implicit*/ true ));
684
+ C.addExternalDecl (getterDecl);
685
+ }
686
+
687
+ // Synthesize the setter body
688
+ {
689
+ auto selfDecl = setterDecl->getImplicitSelfDecl ();
690
+ Expr *lhs = new (C) DeclRefExpr (selfDecl, DeclNameLoc (),
691
+ /* implicit*/ true );
692
+ lhs = new (C) MemberRefExpr (lhs, SourceLoc (), anonymousFieldDecl,
693
+ DeclNameLoc (), /* implicit*/ true );
694
+
695
+ lhs = new (C) MemberRefExpr (lhs, SourceLoc (), anonymousInnerFieldDecl,
696
+ DeclNameLoc (), /* implicit*/ true );
697
+
698
+ auto newValueDecl = setterDecl->getParameterList (1 )->get (0 );
699
+
700
+ auto rhs = new (C) DeclRefExpr (newValueDecl, DeclNameLoc (),
701
+ /* implicit*/ true );
702
+
703
+ auto assign = new (C) AssignExpr (lhs, SourceLoc (), rhs, /* implicit*/ true );
704
+
705
+ auto body = BraceStmt::create (C, SourceLoc (), { assign }, SourceLoc (),
706
+ /* implicit*/ true );
707
+ setterDecl->setBody (body);
708
+ setterDecl->getAttrs ().add (new (C) TransparentAttr (/* implicit*/ true ));
709
+ C.addExternalDecl (setterDecl);
710
+ }
711
+
712
+ return { getterDecl, setterDecl };
713
+ }
714
+
599
715
// / Build the union field getter and setter.
600
716
// /
601
717
// / \code
@@ -969,6 +1085,11 @@ createValueConstructor(ClangImporter::Implementation &Impl,
969
1085
// Construct the set of parameters from the list of members.
970
1086
SmallVector<ParamDecl *, 8 > valueParameters;
971
1087
for (auto var : members) {
1088
+ // TODO create value constructor with indirect fields instead of the
1089
+ // generated __Anonymous_field.
1090
+ if (var->hasClangNode () && isa<clang::IndirectFieldDecl>(var->getClangDecl ()))
1091
+ continue ;
1092
+
972
1093
Identifier argName = wantCtorParamNames ? var->getName () : Identifier ();
973
1094
auto param = new (context)
974
1095
ParamDecl (/* IsLet*/ true , SourceLoc (), SourceLoc (), argName,
@@ -1012,6 +1133,10 @@ createValueConstructor(ClangImporter::Implementation &Impl,
1012
1133
for (unsigned pass = 0 ; pass < 2 ; pass++) {
1013
1134
for (unsigned i = 0 , e = members.size (); i < e; i++) {
1014
1135
auto var = members[i];
1136
+
1137
+ if (var->hasClangNode () && isa<clang::IndirectFieldDecl>(var->getClangDecl ()))
1138
+ continue ;
1139
+
1015
1140
if (var->hasStorage () == (pass != 0 ))
1016
1141
continue ;
1017
1142
@@ -1749,10 +1874,6 @@ namespace {
1749
1874
decl->getLexicalDeclContext ())) {
1750
1875
for (auto field : recordDecl->fields ()) {
1751
1876
if (field->getType ()->getAsTagDecl () == decl) {
1752
- // We found the field. The field should not be anonymous, since we are
1753
- // using its name to derive the generated declaration name.
1754
- assert (!field->isAnonymousStructOrUnion ());
1755
-
1756
1877
// Create a name for the declaration from the field name.
1757
1878
std::string Id;
1758
1879
llvm::raw_string_ostream IdStream (Id);
@@ -1765,8 +1886,12 @@ namespace {
1765
1886
else
1766
1887
llvm_unreachable (" unknown decl kind" );
1767
1888
1768
- IdStream << " __Unnamed_" << kind
1769
- << " _" << field->getName ();
1889
+ IdStream << " __Unnamed_" << kind << " _" ;
1890
+ if (field->isAnonymousStructOrUnion ()) {
1891
+ IdStream << " __Anonymous_field" << field->getFieldIndex ();
1892
+ } else {
1893
+ IdStream << field->getName ();
1894
+ }
1770
1895
ImportedName Result;
1771
1896
Result.setDeclName (Impl.SwiftContext .getIdentifier (IdStream.str ()));
1772
1897
Result.setEffectiveContext (decl->getDeclContext ());
@@ -2430,11 +2555,6 @@ namespace {
2430
2555
if (decl->isInterface ())
2431
2556
return nullptr ;
2432
2557
2433
- // The types of anonymous structs or unions are never imported; their
2434
- // fields are dumped directly into the enclosing class.
2435
- if (decl->isAnonymousStructOrUnion ())
2436
- return nullptr ;
2437
-
2438
2558
// FIXME: Figure out how to deal with incomplete types, since that
2439
2559
// notion doesn't exist in Swift.
2440
2560
decl = decl->getDefinition ();
@@ -2491,11 +2611,6 @@ namespace {
2491
2611
}
2492
2612
2493
2613
if (auto field = dyn_cast<clang::FieldDecl>(nd)) {
2494
- // Skip anonymous structs or unions; they'll be dealt with via the
2495
- // IndirectFieldDecls.
2496
- if (field->isAnonymousStructOrUnion ())
2497
- continue ;
2498
-
2499
2614
// Non-nullable pointers can't be zero-initialized.
2500
2615
if (auto nullability = field->getType ()
2501
2616
->getNullability (Impl.getClangASTContext ())) {
@@ -2544,6 +2659,15 @@ namespace {
2544
2659
2545
2660
auto VD = cast<VarDecl>(member);
2546
2661
2662
+ if (isa<clang::IndirectFieldDecl>(nd) || decl->isUnion ()) {
2663
+ // Don't import unavailable fields that have no associated storage.
2664
+ if (VD->getAttrs ().isUnavailable (Impl.SwiftContext )) {
2665
+ continue ;
2666
+ }
2667
+ }
2668
+
2669
+ members.push_back (VD);
2670
+
2547
2671
// Bitfields are imported as computed properties with Clang-generated
2548
2672
// accessors.
2549
2673
if (auto field = dyn_cast<clang::FieldDecl>(nd)) {
@@ -2560,19 +2684,16 @@ namespace {
2560
2684
}
2561
2685
}
2562
2686
2563
- if (decl->isUnion ()) {
2687
+ if (auto ind = dyn_cast<clang::IndirectFieldDecl>(nd)) {
2688
+ // Indirect fields are created as computed property accessible the
2689
+ // fields on the anonymous field from which they are injected.
2690
+ makeIndirectFieldAccessors (Impl, ind, members, result, VD);
2691
+ } else if (decl->isUnion ()) {
2564
2692
// Union fields should only be available indirectly via a computed
2565
2693
// property. Since the union is made of all of the fields at once,
2566
2694
// this is a trivial accessor that casts self to the correct
2567
2695
// field type.
2568
-
2569
- // FIXME: Allow indirect field access of anonymous structs.
2570
- if (isa<clang::IndirectFieldDecl>(nd))
2571
- continue ;
2572
-
2573
- Decl *getter, *setter;
2574
- std::tie (getter, setter) = makeUnionFieldAccessors (Impl, result, VD);
2575
- members.push_back (VD);
2696
+ makeUnionFieldAccessors (Impl, result, VD);
2576
2697
2577
2698
// Create labeled initializers for unions that take one of the
2578
2699
// fields, which only initializes the data for that field.
@@ -2581,8 +2702,6 @@ namespace {
2581
2702
/* want param names*/ true ,
2582
2703
/* wantBody=*/ !Impl.hasFinishedTypeChecking ());
2583
2704
ctors.push_back (valueCtor);
2584
- } else {
2585
- members.push_back (VD);
2586
2705
}
2587
2706
}
2588
2707
@@ -2758,16 +2877,6 @@ namespace {
2758
2877
}
2759
2878
2760
2879
Decl *VisitIndirectFieldDecl (const clang::IndirectFieldDecl *decl) {
2761
- // Check whether the context of any of the fields in the chain is a
2762
- // union. If so, don't import this field.
2763
- for (auto f = decl->chain_begin (), fEnd = decl->chain_end (); f != fEnd ;
2764
- ++f) {
2765
- if (auto record = dyn_cast<clang::RecordDecl>((*f)->getDeclContext ())) {
2766
- if (record->isUnion ())
2767
- return nullptr ;
2768
- }
2769
- }
2770
-
2771
2880
Optional<ImportedName> correctSwiftName;
2772
2881
auto importedName = importFullName (decl, correctSwiftName);
2773
2882
if (!importedName) return nullptr ;
@@ -2963,8 +3072,24 @@ namespace {
2963
3072
Decl *VisitFieldDecl (const clang::FieldDecl *decl) {
2964
3073
// Fields are imported as variables.
2965
3074
Optional<ImportedName> correctSwiftName;
2966
- auto importedName = importFullName (decl, correctSwiftName);
2967
- if (!importedName) return nullptr ;
3075
+ ImportedName importedName;
3076
+
3077
+ if (!decl->isAnonymousStructOrUnion ()) {
3078
+ importedName = importFullName (decl, correctSwiftName);
3079
+ if (!importedName) {
3080
+ return nullptr ;
3081
+ }
3082
+ } else {
3083
+ // Generate a field name for anonymous fields, this will be used in
3084
+ // order to be able to expose the indirect fields injected from there
3085
+ // as computed properties forwarding the access to the subfield.
3086
+ std::string Id;
3087
+ llvm::raw_string_ostream IdStream (Id);
3088
+
3089
+ IdStream << " __Anonymous_field" << decl->getFieldIndex ();
3090
+ importedName.setDeclName (Impl.SwiftContext .getIdentifier (IdStream.str ()));
3091
+ importedName.setEffectiveContext (decl->getDeclContext ());
3092
+ }
2968
3093
2969
3094
auto name = importedName.getDeclName ().getBaseName ();
2970
3095
0 commit comments