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