@@ -348,8 +348,17 @@ class DeclAndTypePrinter::Implementation
348348 // FIXME: Print struct's availability.
349349 ClangValueTypePrinter printer (os, owningPrinter.prologueOS ,
350350 owningPrinter.interopContext );
351- printer.printValueTypeDecl (
352- SD, /* bodyPrinter=*/ [&]() { printMembers (SD->getMembers ()); });
351+ printer.printValueTypeDecl (SD, /* bodyPrinter=*/ [&]() {
352+ printMembers (SD->getMembers ());
353+ for (const auto *ed :
354+ owningPrinter.interopContext .getExtensionsForNominalType (SD)) {
355+ auto sign = ed->getGenericSignature ();
356+ // FIXME: support requirements.
357+ if (!sign.getRequirements ().empty ())
358+ continue ;
359+ printMembers (ed->getMembers ());
360+ }
361+ });
353362 }
354363
355364 void visitExtensionDecl (ExtensionDecl *ED) {
@@ -866,7 +875,8 @@ class DeclAndTypePrinter::Implementation
866875
867876 void printAbstractFunctionAsMethod (AbstractFunctionDecl *AFD,
868877 bool isClassMethod,
869- bool isNSUIntegerSubscript = false ) {
878+ bool isNSUIntegerSubscript = false ,
879+ const SubscriptDecl *SD = nullptr ) {
870880 printDocumentationComment (AFD);
871881
872882 Optional<ForeignAsyncConvention> asyncConvention =
@@ -883,7 +893,11 @@ class DeclAndTypePrinter::Implementation
883893 if (isClassMethod)
884894 return ;
885895 assert (!AFD->isStatic ());
886- auto *typeDeclContext = cast<NominalTypeDecl>(AFD->getParent ());
896+ auto *typeDeclContext = dyn_cast<NominalTypeDecl>(AFD->getParent ());
897+ if (!typeDeclContext) {
898+ typeDeclContext =
899+ cast<ExtensionDecl>(AFD->getParent ())->getExtendedNominal ();
900+ }
887901
888902 std::string cFuncDecl;
889903 llvm::raw_string_ostream cFuncPrologueOS (cFuncDecl);
@@ -899,10 +913,15 @@ class DeclAndTypePrinter::Implementation
899913 os, owningPrinter.prologueOS , owningPrinter.typeMapping ,
900914 owningPrinter.interopContext , owningPrinter);
901915 if (auto *accessor = dyn_cast<AccessorDecl>(AFD)) {
902- declPrinter.printCxxPropertyAccessorMethod (
903- typeDeclContext, accessor, funcABI->getSignature (),
904- funcABI->getSymbolName (), resultTy,
905- /* isDefinition=*/ false );
916+ if (SD)
917+ declPrinter.printCxxSubscriptAccessorMethod (
918+ typeDeclContext, accessor, funcABI->getSignature (),
919+ funcABI->getSymbolName (), resultTy, /* isDefinition=*/ false );
920+ else
921+ declPrinter.printCxxPropertyAccessorMethod (
922+ typeDeclContext, accessor, funcABI->getSignature (),
923+ funcABI->getSymbolName (), resultTy,
924+ /* isDefinition=*/ false );
906925 } else {
907926 declPrinter.printCxxMethod (typeDeclContext, AFD,
908927 funcABI->getSignature (),
@@ -916,11 +935,15 @@ class DeclAndTypePrinter::Implementation
916935 owningPrinter);
917936
918937 if (auto *accessor = dyn_cast<AccessorDecl>(AFD)) {
919-
920- defPrinter.printCxxPropertyAccessorMethod (
921- typeDeclContext, accessor, funcABI->getSignature (),
922- funcABI->getSymbolName (), resultTy,
923- /* isDefinition=*/ true );
938+ if (SD)
939+ defPrinter.printCxxSubscriptAccessorMethod (
940+ typeDeclContext, accessor, funcABI->getSignature (),
941+ funcABI->getSymbolName (), resultTy, /* isDefinition=*/ true );
942+ else
943+ defPrinter.printCxxPropertyAccessorMethod (
944+ typeDeclContext, accessor, funcABI->getSignature (),
945+ funcABI->getSymbolName (), resultTy,
946+ /* isDefinition=*/ true );
924947 } else {
925948 defPrinter.printCxxMethod (typeDeclContext, AFD, funcABI->getSignature (),
926949 funcABI->getSymbolName (), resultTy,
@@ -1807,6 +1830,14 @@ class DeclAndTypePrinter::Implementation
18071830 }
18081831
18091832 void visitSubscriptDecl (SubscriptDecl *SD) {
1833+ if (outputLang == OutputLanguageMode::Cxx) {
1834+ if (!SD->isInstanceMember ())
1835+ return ;
1836+ auto *getter = SD->getOpaqueAccessor (AccessorKind::Get);
1837+ printAbstractFunctionAsMethod (getter, false ,
1838+ /* isNSUIntegerSubscript=*/ false , SD);
1839+ return ;
1840+ }
18101841 assert (SD->isInstanceMember () && " static subscripts not supported" );
18111842
18121843 bool isNSUIntegerSubscript = false ;
@@ -2511,9 +2542,9 @@ static bool isAsyncAlternativeOfOtherDecl(const ValueDecl *VD) {
25112542 return false ;
25122543}
25132544
2514- static bool hasExposeAttr (const ValueDecl *VD) {
2545+ static bool hasExposeAttr (const ValueDecl *VD, bool isExtension = false ) {
25152546 if (isa<NominalTypeDecl>(VD) && VD->getModuleContext ()->isStdlibModule ()) {
2516- if (VD == VD->getASTContext ().getStringDecl ())
2547+ if (VD == VD->getASTContext ().getStringDecl () && !isExtension )
25172548 return true ;
25182549 if (VD == VD->getASTContext ().getArrayDecl ())
25192550 return true ;
@@ -2523,6 +2554,26 @@ static bool hasExposeAttr(const ValueDecl *VD) {
25232554 return true ;
25242555 if (const auto *NMT = dyn_cast<NominalTypeDecl>(VD->getDeclContext ()))
25252556 return hasExposeAttr (NMT);
2557+ if (const auto *ED = dyn_cast<ExtensionDecl>(VD->getDeclContext ())) {
2558+ // FIXME: Do not expose 'index' methods as the overloads are conflicting.
2559+ // this should either be prohibited in the stdlib module, or the overloads
2560+ // should be renamed automatically or using the expose attribute.
2561+ if (ED->getExtendedNominal () == VD->getASTContext ().getArrayDecl ()) {
2562+ if (isa<AbstractFunctionDecl>(VD) &&
2563+ !cast<AbstractFunctionDecl>(VD)
2564+ ->getName ()
2565+ .getBaseName ()
2566+ .isSpecial () &&
2567+ cast<AbstractFunctionDecl>(VD)
2568+ ->getName ()
2569+ .getBaseName ()
2570+ .getIdentifier ()
2571+ .str ()
2572+ .contains_insensitive (" index" ))
2573+ return false ;
2574+ }
2575+ return hasExposeAttr (ED->getExtendedNominal (), /* isExtension=*/ true );
2576+ }
25262577 return false ;
25272578}
25282579
0 commit comments