@@ -598,6 +598,122 @@ static FuncDecl *makeFieldSetterDecl(ClangImporter::Implementation &Impl,
598598 return setterDecl;
599599}
600600
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+
601717// / Build the union field getter and setter.
602718// /
603719// / \code
@@ -971,6 +1087,11 @@ createValueConstructor(ClangImporter::Implementation &Impl,
9711087 // Construct the set of parameters from the list of members.
9721088 SmallVector<ParamDecl *, 8 > valueParameters;
9731089 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+
9741095 Identifier argName = wantCtorParamNames ? var->getName () : Identifier ();
9751096 auto param = new (context)
9761097 ParamDecl (/* IsLet*/ true , SourceLoc (), SourceLoc (), argName,
@@ -1014,6 +1135,10 @@ createValueConstructor(ClangImporter::Implementation &Impl,
10141135 for (unsigned pass = 0 ; pass < 2 ; pass++) {
10151136 for (unsigned i = 0 , e = members.size (); i < e; i++) {
10161137 auto var = members[i];
1138+
1139+ if (var->hasClangNode () && isa<clang::IndirectFieldDecl>(var->getClangDecl ()))
1140+ continue ;
1141+
10171142 if (var->hasStorage () == (pass != 0 ))
10181143 continue ;
10191144
@@ -1751,10 +1876,6 @@ namespace {
17511876 decl->getLexicalDeclContext ())) {
17521877 for (auto field : recordDecl->fields ()) {
17531878 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-
17581879 // Create a name for the declaration from the field name.
17591880 std::string Id;
17601881 llvm::raw_string_ostream IdStream (Id);
@@ -1767,8 +1888,12 @@ namespace {
17671888 else
17681889 llvm_unreachable (" unknown decl kind" );
17691890
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+ }
17721897 ImportedName Result;
17731898 Result.setDeclName (Impl.SwiftContext .getIdentifier (IdStream.str ()));
17741899 Result.setEffectiveContext (decl->getDeclContext ());
@@ -2433,11 +2558,6 @@ namespace {
24332558 if (decl->isInterface ())
24342559 return nullptr ;
24352560
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-
24412561 // FIXME: Figure out how to deal with incomplete types, since that
24422562 // notion doesn't exist in Swift.
24432563 decl = decl->getDefinition ();
@@ -2494,11 +2614,6 @@ namespace {
24942614 }
24952615
24962616 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-
25022617 // Non-nullable pointers can't be zero-initialized.
25032618 if (auto nullability = field->getType ()
25042619 ->getNullability (Impl.getClangASTContext ())) {
@@ -2547,6 +2662,15 @@ namespace {
25472662
25482663 auto VD = cast<VarDecl>(member);
25492664
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+
25502674 // Bitfields are imported as computed properties with Clang-generated
25512675 // accessors.
25522676 if (auto field = dyn_cast<clang::FieldDecl>(nd)) {
@@ -2563,19 +2687,16 @@ namespace {
25632687 }
25642688 }
25652689
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 ()) {
25672695 // Union fields should only be available indirectly via a computed
25682696 // property. Since the union is made of all of the fields at once,
25692697 // this is a trivial accessor that casts self to the correct
25702698 // 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);
25792700
25802701 // Create labeled initializers for unions that take one of the
25812702 // fields, which only initializes the data for that field.
@@ -2584,8 +2705,6 @@ namespace {
25842705 /* want param names*/ true ,
25852706 /* wantBody=*/ !Impl.hasFinishedTypeChecking ());
25862707 ctors.push_back (valueCtor);
2587- } else {
2588- members.push_back (VD);
25892708 }
25902709 }
25912710
@@ -2761,16 +2880,6 @@ namespace {
27612880 }
27622881
27632882 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-
27742883 Optional<ImportedName> correctSwiftName;
27752884 auto importedName = importFullName (decl, correctSwiftName);
27762885 if (!importedName) return nullptr ;
@@ -2977,8 +3086,24 @@ namespace {
29773086 Decl *VisitFieldDecl (const clang::FieldDecl *decl) {
29783087 // Fields are imported as variables.
29793088 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+ }
29823107
29833108 auto name = importedName.getDeclName ().getBaseName ();
29843109
0 commit comments