@@ -466,6 +466,7 @@ class DeclAndTypePrinter::Implementation
466
466
467
467
clangFuncPrinter.printCustomCxxFunction (
468
468
{paramType},
469
+ /* NeedsReturnTypes=*/ true ,
469
470
[&](auto &types) {
470
471
// Printing function name and return type
471
472
os << " inline " << types[paramType] << " get" << name;
@@ -535,13 +536,13 @@ class DeclAndTypePrinter::Implementation
535
536
outOfLineOS << " });\n " ;
536
537
}
537
538
},
538
- ED->getModuleContext (), outOfLineOS);
539
+ ED, ED ->getModuleContext (), outOfLineOS);
539
540
};
540
541
541
542
auto printStruct = [&](StringRef caseName, EnumElementDecl *elementDecl,
542
543
Optional<IRABIDetailsProvider::EnumElementInfo>
543
544
elementInfo) {
544
- os << " inline const static struct { "
545
+ os << " inline const static struct _impl_ " << caseName << " { "
545
546
<< " // impl struct for case " << caseName << ' \n ' ;
546
547
os << " inline constexpr operator cases() const {\n " ;
547
548
os << " return cases::" ;
@@ -552,67 +553,112 @@ class DeclAndTypePrinter::Implementation
552
553
if (elementDecl != nullptr ) {
553
554
assert (elementInfo.hasValue ());
554
555
555
- Type paramType, objectType;
556
- NominalTypeDecl *objectTypeDecl = nullptr ;
557
- OptionalTypeKind optKind;
556
+ Type paramType;
558
557
559
558
// TODO: support tuple type
560
559
if (elementDecl->hasAssociatedValues () &&
561
560
elementDecl->getParameterList ()->size () == 1 ) {
562
- paramType = elementDecl->getParameterList ()->front ()->getType ();
563
- std::tie (objectType, optKind) = getObjectTypeAndOptionality (
564
- paramType->getNominalOrBoundGenericNominal (), paramType);
565
- objectTypeDecl = objectType->getNominalOrBoundGenericNominal ();
561
+ paramType =
562
+ elementDecl->getParameterList ()->front ()->getInterfaceType ();
566
563
}
567
564
568
565
SmallVector<Type> neededTypes;
569
566
if (paramType) {
570
567
neededTypes.push_back (paramType);
571
568
}
572
569
573
- // FIXME: support generic constructor.
574
- if (!ED->isGeneric ())
575
- clangFuncPrinter.printCustomCxxFunction (
576
- neededTypes,
577
- [&](auto &types) {
578
- // Printing function name and return type
579
- os << " inline " ;
580
- syntaxPrinter.printBaseName (elementDecl->getParentEnum ());
581
- os << " operator()" ;
582
-
583
- outOfLineOS << " inline " ;
584
- outOfLineSyntaxPrinter.printBaseName (
585
- elementDecl->getParentEnum ());
586
- outOfLineOS << ' ' ;
587
- outOfLineSyntaxPrinter.printBaseName (
588
- elementDecl->getParentEnum ());
589
- outOfLineOS << " ::_impl_" << elementDecl->getNameStr ()
590
- << " ::operator()" ;
591
- },
592
- [&](auto &types) {
593
- // Printing parameters
594
- if (!paramType) {
595
- return ;
596
- }
597
- assert (objectTypeDecl != nullptr );
598
- if (owningPrinter.typeMapping .getKnownCxxTypeInfo (
599
- objectTypeDecl)) {
600
- os << types[paramType] << " val" ;
601
- outOfLineOS << types[paramType] << " val" ;
570
+ clangFuncPrinter.printCustomCxxFunction (
571
+ neededTypes,
572
+ /* NeedsReturnTypes=*/ false ,
573
+ [&](auto &types) {
574
+ const auto *ED = elementDecl->getParentEnum ();
575
+ // Printing function name and return type
576
+ os << " inline " ;
577
+ syntaxPrinter.printNominalTypeReference (ED,
578
+ ED->getModuleContext ());
579
+ os << " operator()" ;
580
+
581
+ outOfLineSyntaxPrinter
582
+ .printNominalTypeOutsideMemberDeclTemplateSpecifiers (ED);
583
+ outOfLineOS << " inline " ;
584
+ outOfLineSyntaxPrinter.printNominalTypeReference (
585
+ ED, ED->getModuleContext ());
586
+ outOfLineOS << ' ' ;
587
+ outOfLineSyntaxPrinter.printNominalTypeQualifier (
588
+ ED, /* moduleContext=*/ ED->getModuleContext ());
589
+ outOfLineOS << " _impl_" << caseName << " ::operator()" ;
590
+ },
591
+ [&](auto &types) {
592
+ // Printing parameters
593
+ if (!paramType) {
594
+ return ;
595
+ }
596
+ os << types[paramType] << " val" ;
597
+ outOfLineOS << types[paramType] << " val" ;
598
+ },
599
+ true ,
600
+ [&](auto &types) {
601
+ auto *ED = elementDecl->getParentEnum ();
602
+ // Printing function body
603
+ outOfLineOS << " auto result = " ;
604
+ outOfLineSyntaxPrinter.printNominalTypeQualifier (
605
+ ED, ED->getModuleContext ());
606
+ outOfLineOS << " _make();\n " ;
607
+ if (paramType) {
608
+ if (paramType->getAs <GenericTypeParamType>()) {
609
+ auto type = types[paramType];
610
+ ClangSyntaxPrinter (outOfLineOS)
611
+ .printIgnoredCxx17ExtensionDiagnosticBlock ([&]() {
612
+ // FIXME: handle C++ types.
613
+ outOfLineOS << " if constexpr (std::is_base_of<::swift::"
614
+ << cxx_synthesis::getCxxImplNamespaceName ()
615
+ << " ::RefCountedClass, " << type
616
+ << " >::value) {\n " ;
617
+ outOfLineOS << " void *ptr = ::swift::"
618
+ << cxx_synthesis::getCxxImplNamespaceName ()
619
+ << " ::_impl_RefCountedClass::"
620
+ " copyOpaquePointer(val);\n " ;
621
+ outOfLineOS
622
+ << " memcpy(result._getOpaquePointer(), &ptr, "
623
+ " sizeof(ptr));\n " ;
624
+ outOfLineOS << " } else if constexpr (::swift::"
625
+ << cxx_synthesis::getCxxImplNamespaceName ()
626
+ << " ::isValueType<" << type << " >) {\n " ;
627
+
628
+ outOfLineOS << " alignas(" << type;
629
+ outOfLineOS << " ) unsigned char buffer[sizeof(" << type;
630
+ outOfLineOS << " )];\n " ;
631
+ outOfLineOS << " auto *valCopy = new(buffer) "
632
+ << type;
633
+ outOfLineOS << " (val);\n " ;
634
+ outOfLineOS << " " ;
635
+ outOfLineOS << cxx_synthesis::getCxxSwiftNamespaceName ()
636
+ << " ::" ;
637
+ outOfLineOS << cxx_synthesis::getCxxImplNamespaceName ();
638
+ outOfLineOS << " ::implClassFor<" << type;
639
+ outOfLineOS << " >::type::initializeWithTake(result._"
640
+ " getOpaquePointer(), " ;
641
+ outOfLineOS << cxx_synthesis::getCxxSwiftNamespaceName ()
642
+ << " ::" ;
643
+ outOfLineOS << cxx_synthesis::getCxxImplNamespaceName ();
644
+ outOfLineOS << " ::implClassFor<" << type;
645
+ outOfLineOS << " >::type::getOpaquePointer(*valCopy)" ;
646
+ outOfLineOS << " );\n " ;
647
+ outOfLineOS << " } else {\n " ;
648
+ outOfLineOS
649
+ << " memcpy(result._getOpaquePointer(), &val, "
650
+ " sizeof(val));\n " ;
651
+ outOfLineOS << " }\n " ;
652
+ });
602
653
} else {
603
- os << " const " << types[paramType] << " &val" ;
604
- outOfLineOS << " const " << types[paramType] << " &val" ;
605
- }
606
- },
607
- true ,
608
- [&](auto &types) {
609
- // Printing function body
610
- outOfLineOS << " auto result = " ;
611
- outOfLineSyntaxPrinter.printBaseName (
612
- elementDecl->getParentEnum ());
613
- outOfLineOS << " ::_make();\n " ;
614
-
615
- if (paramType) {
654
+
655
+ OptionalTypeKind optKind;
656
+ Type objectType;
657
+ std::tie (objectType, optKind) =
658
+ DeclAndTypePrinter::getObjectTypeAndOptionality (
659
+ ED, paramType);
660
+ auto objectTypeDecl =
661
+ objectType->getNominalOrBoundGenericNominal ();
616
662
assert (objectTypeDecl != nullptr );
617
663
618
664
if (owningPrinter.typeMapping .getKnownCxxTypeInfo (
@@ -621,6 +667,8 @@ class DeclAndTypePrinter::Implementation
621
667
<< " memcpy(result._getOpaquePointer(), &val, "
622
668
" sizeof(val));\n " ;
623
669
} else {
670
+ objectTypeDecl =
671
+ paramType->getNominalOrBoundGenericNominal ();
624
672
outOfLineOS << " alignas(" ;
625
673
outOfLineSyntaxPrinter
626
674
.printModuleNamespaceQualifiersIfNeeded (
@@ -666,19 +714,20 @@ class DeclAndTypePrinter::Implementation
666
714
outOfLineOS << " );\n " ;
667
715
}
668
716
}
669
-
670
- outOfLineOS << " result._destructiveInjectEnumTag(" ;
671
- if (ED->isResilient ()) {
672
- outOfLineOS << cxx_synthesis::getCxxImplNamespaceName ()
673
- << " ::" << elementInfo->globalVariableName ;
674
- } else {
675
- outOfLineOS << elementInfo->tag ;
676
- }
677
- outOfLineOS << " );\n " ;
678
- outOfLineOS << " return result;\n " ;
679
- outOfLineOS << " " ;
680
- },
681
- ED->getModuleContext (), outOfLineOS);
717
+ }
718
+
719
+ outOfLineOS << " result._destructiveInjectEnumTag(" ;
720
+ if (ED->isResilient ()) {
721
+ outOfLineOS << cxx_synthesis::getCxxImplNamespaceName ()
722
+ << " ::" << elementInfo->globalVariableName ;
723
+ } else {
724
+ outOfLineOS << elementInfo->tag ;
725
+ }
726
+ outOfLineOS << " );\n " ;
727
+ outOfLineOS << " return result;\n " ;
728
+ outOfLineOS << " " ;
729
+ },
730
+ ED, ED->getModuleContext (), outOfLineOS);
682
731
}
683
732
os << " } " ;
684
733
syntaxPrinter.printIdentifier (caseName);
0 commit comments