diff --git a/lib/AST/ConformanceLookup.cpp b/lib/AST/ConformanceLookup.cpp index 671b2e2e3caa6..87cb80a801812 100644 --- a/lib/AST/ConformanceLookup.cpp +++ b/lib/AST/ConformanceLookup.cpp @@ -533,6 +533,10 @@ static ProtocolConformanceRef getPackTypeConformance( PackConformance::get(type, protocol, patternConformances)); } +static bool shouldExpandExtensionMacro(Evaluator &evaluator, NominalTypeDecl *nominal) { + return !evaluator.hasActiveRequest(ExpandExtensionMacros{nominal}); +} + ProtocolConformanceRef LookupConformanceInModuleRequest::evaluate( Evaluator &evaluator, LookupConformanceDescriptor desc) const { @@ -670,10 +674,11 @@ LookupConformanceInModuleRequest::evaluate( // extension macro can generate a conformance to the // given protocol, but conformance macros do not specify // that information upfront. - (void)evaluateOrDefault( - ctx.evaluator, - ExpandExtensionMacros{nominal}, - { }); + if (shouldExpandExtensionMacro(ctx.evaluator, nominal)) + (void)evaluateOrDefault( + evaluator, + ExpandExtensionMacros{nominal}, + { }); // Find the root conformance in the nominal type declaration's // conformance lookup table. diff --git a/lib/ClangImporter/ImportDecl.cpp b/lib/ClangImporter/ImportDecl.cpp index 2b33b78852599..6c156bd97c672 100644 --- a/lib/ClangImporter/ImportDecl.cpp +++ b/lib/ClangImporter/ImportDecl.cpp @@ -15,10 +15,12 @@ //===----------------------------------------------------------------------===// #include "CFTypeInfo.h" +#include "ClangAdapter.h" #include "ClangDerivedConformances.h" #include "ImporterImpl.h" #include "SwiftDeclSynthesizer.h" #include "swift/AST/ASTContext.h" +#include "swift/AST/ASTPrinter.h" #include "swift/AST/Attr.h" #include "swift/AST/AvailabilityInference.h" #include "swift/AST/Builtins.h" @@ -5810,6 +5812,8 @@ namespace { result->setMemberLoader(&Impl, 0); + Impl.swiftifyProtocol(result); + return result; } @@ -6031,6 +6035,8 @@ namespace { } } } + + Impl.swiftifyProtocol(result); return result; } @@ -9039,16 +9045,25 @@ ClangImporter::Implementation::importSwiftAttrAttributes(Decl *MappedDecl) { } namespace { +class SwiftifyInfoPrinter; +static bool swiftifyImpl(SwiftifyInfoPrinter &printer, const FuncDecl *MappedDecl); + class SwiftifyInfoPrinter { public: static const ssize_t SELF_PARAM_INDEX = -2; static const ssize_t RETURN_VALUE_INDEX = -1; + +protected: clang::ASTContext &ctx; + ASTContext &SwiftContext; llvm::raw_ostream &out; bool firstParam = true; - SwiftifyInfoPrinter(clang::ASTContext &ctx, llvm::raw_ostream &out) - : ctx(ctx), out(out) { - out << "@_SwiftifyImport("; + llvm::StringMap typeMapping; + +public: + SwiftifyInfoPrinter(clang::ASTContext &ctx, ASTContext &SwiftContext, llvm::raw_ostream &out) + : ctx(ctx), SwiftContext(SwiftContext), out(out) { + out << "("; } ~SwiftifyInfoPrinter() { out << ")"; } @@ -9091,28 +9106,43 @@ class SwiftifyInfoPrinter { out << ")"; } - void printTypeMapping(const llvm::StringMap &mapping) { + bool registerStdSpanTypeMapping(Type swiftType, const clang::QualType clangType) { + const auto *decl = clangType->getAsTagDecl(); + if (decl && decl->isInStdNamespace() && decl->getName() == "span") { + typeMapping.insert(std::make_pair( + swiftType->getString(), swiftType->getDesugaredType()->getString())); + return true; + } + return false; + } + + void printTypeMapping() { printSeparator(); out << "typeMappings: ["; - if (mapping.empty()) { + if (typeMapping.empty()) { out << ":]"; return; } - llvm::interleaveComma(mapping, out, [&](const auto &entry) { + llvm::interleaveComma(typeMapping, out, [&](const auto &entry) { out << '"' << entry.getKey() << "\" : \"" << entry.getValue() << '"'; }); out << "]"; } -private: - void printSeparator() { - if (!firstParam) { - out << ", "; - } else { - firstParam = false; + void printAvailability() { + printSeparator(); + out << "availability: ["; + if (!SwiftContext.LangOpts.Target.isOSDarwin() && !SwiftContext.LangOpts.Target.isDriverKit()) { + out << ":]"; + return; } + printAvailabilityOfType("Span"); + printSeparator(); + printAvailabilityOfType("MutableSpan"); + out << "]"; } +private: void printParamOrReturn(ssize_t pointerIndex) { if (pointerIndex == SELF_PARAM_INDEX) out << ".self"; @@ -9121,87 +9151,228 @@ class SwiftifyInfoPrinter { else out << ".param(" << pointerIndex + 1 << ")"; } + + ValueDecl *getDecl(StringRef DeclName) { + SmallVector decls; + SwiftContext.lookupInSwiftModule(DeclName, decls); + assert(decls.size() == 1); + if (decls.size() != 1) return nullptr; + return decls[0]; + } + + StringRef getDarwinOSString() { + auto Target = SwiftContext.LangOpts.Target; + if (Target.isMacOSX()) { + return "macOS"; + } else if (Target.isTvOS()) { + return "tvOS"; + } else if (Target.isiOS()) { + return "iOS"; + } else if (Target.isWatchOS()) { + return "watchOS"; + } else if (Target.isXROS()) { + return "visionOS"; + } + llvm_unreachable("unknown darwin OS"); + } + + void printAvailabilityOfType(StringRef Name) { + ValueDecl *D = getDecl(Name); + auto Availability = AvailabilityInference::availableRange(D); + + out << "\"" << Name << "\":" << "\"" << getDarwinOSString() << " " << Availability.getVersionString() << "\""; + } + +protected: + void printSeparator() { + if (!firstParam) { + out << ", "; + } else { + firstParam = false; + } + } }; -} // namespace -void ClangImporter::Implementation::swiftify(FuncDecl *MappedDecl) { - if (!SwiftContext.LangOpts.hasFeature(Feature::SafeInteropWrappers)) - return; - auto ClangDecl = - dyn_cast_or_null(MappedDecl->getClangDecl()); - if (!ClangDecl) - return; +class SwiftifyProtocolInfoPrinter : public SwiftifyInfoPrinter { +public: + SwiftifyProtocolInfoPrinter(clang::ASTContext &ctx, ASTContext &SwiftContext, llvm::raw_ostream &out) + : SwiftifyInfoPrinter(ctx, SwiftContext, out) {} + + bool printMethod(const FuncDecl *Method) { + // don't emit .method() if we know it's going to be empty + if (!isa_and_nonnull(Method->getClangDecl())) + return false; + + printSeparator(); + out << ".method(signature: \""; + printMethodSignature(Method); + out << "\", paramInfo: ["; + // reset firstParam inside paramInfo array. At this point firstParam will + // always be false, so no need to save the current value. + assert(!firstParam); + firstParam = true; + bool hadAttributes = swiftifyImpl(*this, Method); + firstParam = false; + out << "])"; + return hadAttributes; + } + +private: + void printMethodSignature(const FuncDecl *Method) { + auto options = PrintOptions::printForDiagnostics(AccessLevel::Private, true); + StreamPrinter printer(out); + Method->print(printer, options); + } +}; + +static bool isLifetimeTarget(const FuncDecl *Func, const ParamDecl *Param, + size_t paramIndex) { + for (auto attr : Func->getAttrs().getAttributes()) { + auto entry = attr->getLifetimeEntry(); + auto descriptorOpt = entry->getTargetDescriptor(); + if (!descriptorOpt.has_value()) + continue; + auto descriptor = descriptorOpt.value(); + switch (descriptor.getDescriptorKind()) { + case LifetimeDescriptor::DescriptorKind::Named: + if (Param->getParameterName() == descriptor.getName()) + return true; + continue; + case LifetimeDescriptor::DescriptorKind::Ordered: + if (paramIndex == descriptor.getIndex()) + return true; + continue; + case LifetimeDescriptor::DescriptorKind::Self: + continue; + } + } + return false; +} + +static bool swiftifyImpl(SwiftifyInfoPrinter &printer, const FuncDecl *MappedDecl) { + const clang::Decl *ClangDecl = MappedDecl->getClangDecl(); + auto FuncD = dyn_cast(ClangDecl); + auto MethodD = dyn_cast(ClangDecl); + assert(FuncD || MethodD); - llvm::SmallString<128> MacroString; // We only attach the macro if it will produce an overload. Any __counted_by // will produce an overload, since UnsafeBufferPointer is still an improvement // over UnsafePointer, but std::span will only produce an overload if it also // has lifetime information, since std::span already contains bounds info. bool attachMacro = false; - { - llvm::raw_svector_ostream out(MacroString); - llvm::StringMap typeMapping; - - auto registerStdSpanTypeMapping = - [&typeMapping](Type swiftType, const clang::QualType clangType) { - const auto *decl = clangType->getAsTagDecl(); - if (decl && decl->isInStdNamespace() && decl->getName() == "span") { - typeMapping.insert( - std::make_pair(swiftType->getString(), - swiftType->getDesugaredType()->getString())); - return true; - } - return false; - }; - SwiftifyInfoPrinter printer(getClangASTContext(), out); - bool returnIsStdSpan = registerStdSpanTypeMapping( - MappedDecl->getResultInterfaceType(), ClangDecl->getReturnType()); - if (auto CAT = - ClangDecl->getReturnType()->getAs()) { - printer.printCountedBy(CAT, SwiftifyInfoPrinter::RETURN_VALUE_INDEX); - attachMacro = true; - } - bool returnHasLifetimeInfo = false; - if (SwiftDeclConverter::getImplicitObjectParamAnnotation< - clang::LifetimeBoundAttr>(ClangDecl)) { - printer.printLifetimeboundReturn(SwiftifyInfoPrinter::SELF_PARAM_INDEX, - true); - returnHasLifetimeInfo = true; - } - for (auto [index, clangParam] : llvm::enumerate(ClangDecl->parameters())) { - auto clangParamTy = clangParam->getType(); - auto swiftParam = MappedDecl->getParameters()->get(index); - bool paramHasBoundsInfo = false; - if (auto CAT = clangParamTy->getAs()) { - printer.printCountedBy(CAT, index); - attachMacro = paramHasBoundsInfo = true; - } - bool paramIsStdSpan = registerStdSpanTypeMapping( - swiftParam->getInterfaceType(), clangParamTy); - paramHasBoundsInfo |= paramIsStdSpan; - - bool paramHasLifetimeInfo = false; - if (clangParam->hasAttr()) { - printer.printNonEscaping(index); - paramHasLifetimeInfo = true; - } - if (clangParam->hasAttr()) { - printer.printLifetimeboundReturn( - index, !paramHasBoundsInfo && - swiftParam->getInterfaceType()->isEscapable()); + + clang::QualType returnType = FuncD ? FuncD->getReturnType() : MethodD->getReturnType(); + bool returnIsStdSpan = printer.registerStdSpanTypeMapping( + MappedDecl->getResultInterfaceType(), returnType); + if (auto CAT = returnType->getAs()) { + printer.printCountedBy(CAT, SwiftifyInfoPrinter::RETURN_VALUE_INDEX); + attachMacro = true; + } + bool returnHasLifetimeInfo = false; + if (FuncD && SwiftDeclConverter::getImplicitObjectParamAnnotation(FuncD)) { + printer.printLifetimeboundReturn(SwiftifyInfoPrinter::SELF_PARAM_INDEX, + true); + returnHasLifetimeInfo = true; + } + + auto parameters = FuncD ? FuncD->parameters() : MethodD->parameters(); + for (auto [index, clangParam] : llvm::enumerate(parameters)) { + auto clangParamTy = clangParam->getType(); + auto swiftParam = MappedDecl->getParameters()->get(index); + bool paramHasBoundsInfo = false; + if (auto CAT = clangParamTy->getAs()) { + printer.printCountedBy(CAT, index); + attachMacro = paramHasBoundsInfo = true; + } + bool paramIsStdSpan = printer.registerStdSpanTypeMapping( + swiftParam->getInterfaceType(), clangParamTy); + paramHasBoundsInfo |= paramIsStdSpan; + + bool paramHasLifetimeInfo = false; + if (clangParam->hasAttr()) { + printer.printNonEscaping(index); + paramHasLifetimeInfo = true; + } + if (clangParam->hasAttr()) { + // Escapable types should have their ownership borrowed, while + // nonescapable should have their lifetime copied. + // If this parameter has bounds info, the wrapper version of it will be + // nonescapable (Span) however, so then it should be copied despite being + // escapable in the original. + bool shouldBorrowLifetime = + !paramHasBoundsInfo && swiftParam->getInterfaceType()->isEscapable(); + // For inout parameters the callee could set the parameter to a new value + // with a lifetime that the caller is not aware of. So unless there is + // explicit lifetime info for the parameter, we can't borrow the lifetime + // of an inout. + if (!swiftParam->isInOut() || + isLifetimeTarget(MappedDecl, swiftParam, index)) { + printer.printLifetimeboundReturn(index, shouldBorrowLifetime); paramHasLifetimeInfo = true; returnHasLifetimeInfo = true; } - if (paramIsStdSpan && paramHasLifetimeInfo) - attachMacro = true; } - if (returnIsStdSpan && returnHasLifetimeInfo) + if (paramIsStdSpan && paramHasLifetimeInfo) attachMacro = true; - printer.printTypeMapping(typeMapping); + } + if (returnIsStdSpan && returnHasLifetimeInfo) + attachMacro = true; + + return attachMacro; +} +} // namespace + +void ClangImporter::Implementation::swiftifyProtocol( + NominalTypeDecl *MappedDecl) { + if (!SwiftContext.LangOpts.hasFeature(Feature::SafeInteropWrappers)) + return; + if (!isa(MappedDecl)) + return; + + llvm::SmallString<128> MacroString; + { + llvm::raw_svector_ostream out(MacroString); + out << "@_SwiftifyImportProtocol"; + + bool hasBoundsAttributes = false; + SwiftifyProtocolInfoPrinter printer(getClangASTContext(), SwiftContext, out); + for (Decl *SwiftMember : cast(MappedDecl)->getAllMembers()) { + FuncDecl *SwiftDecl = dyn_cast(SwiftMember); + if (!SwiftDecl) + continue; + hasBoundsAttributes |= + printer.printMethod(SwiftDecl); + } + + if (!hasBoundsAttributes) + return; + printer.printAvailability(); + printer.printTypeMapping(); + } + + importNontrivialAttribute(MappedDecl, MacroString); +} + +void ClangImporter::Implementation::swiftify( + FuncDecl *MappedDecl) { + if (!SwiftContext.LangOpts.hasFeature(Feature::SafeInteropWrappers)) + return; + if (!isa_and_nonnull(MappedDecl->getClangDecl())) + return; + + llvm::SmallString<128> MacroString; + { + llvm::raw_svector_ostream out(MacroString); + out << "@_SwiftifyImport"; + + SwiftifyInfoPrinter printer(getClangASTContext(), SwiftContext, out); + if (!swiftifyImpl(printer, MappedDecl)) + return; + printer.printAvailability(); + printer.printTypeMapping(); } - if (attachMacro) - importNontrivialAttribute(MappedDecl, MacroString); + importNontrivialAttribute(MappedDecl, MacroString); } static bool isUsingMacroName(clang::SourceManager &SM, diff --git a/lib/ClangImporter/ImporterImpl.h b/lib/ClangImporter/ImporterImpl.h index 870e68a2152ed..93ea7603482c7 100644 --- a/lib/ClangImporter/ImporterImpl.h +++ b/lib/ClangImporter/ImporterImpl.h @@ -1755,6 +1755,7 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation void importSwiftAttrAttributes(Decl *decl); void swiftify(FuncDecl *MappedDecl); + void swiftifyProtocol(NominalTypeDecl *MappedDecl); /// Find the lookup table that corresponds to the given Clang module. /// diff --git a/lib/DriverTool/swift_api_digester_main.cpp b/lib/DriverTool/swift_api_digester_main.cpp index e90269541f93b..340a6a29b72af 100644 --- a/lib/DriverTool/swift_api_digester_main.cpp +++ b/lib/DriverTool/swift_api_digester_main.cpp @@ -652,6 +652,7 @@ class PrunePass : public MatchedNodeListener, public SDKTreeDiffPass { ProtocolReqAllowlist(std::move(prAllowlist)), DebugMapping(DebugMapping) {} + void diagnoseMissingAvailable(SDKNodeDecl *D) { // For extensions of external types, we diagnose individual member's missing // available attribute instead of the extension itself. diff --git a/lib/Macros/Sources/SwiftMacros/SwiftifyImportMacro.swift b/lib/Macros/Sources/SwiftMacros/SwiftifyImportMacro.swift index 8ef08d222b968..9625cb19aedd1 100644 --- a/lib/Macros/Sources/SwiftMacros/SwiftifyImportMacro.swift +++ b/lib/Macros/Sources/SwiftMacros/SwiftifyImportMacro.swift @@ -545,7 +545,7 @@ struct CxxSpanReturnThunkBuilder: SpanBoundsThunkBuilder { } else { "MutableSpan" } - return "unsafe _cxxOverrideLifetime(\(raw: cast)(_unsafeCxxSpan: \(call)), copying: ())" + return "unsafe _swiftifyOverrideLifetime(\(raw: cast)(_unsafeCxxSpan: \(call)), copying: ())" } } @@ -691,20 +691,24 @@ struct CountedOrSizedReturnPointerThunkBuilder: PointerBoundsThunkBuilder { cast = optType.wrappedType } return """ - { () in - let _resultValue = \(call) - if unsafe _resultValue == nil { - return nil - } else { - return unsafe \(raw: cast)(\(raw: startLabel): _resultValue!, count: Int(\(countExpr))) - } - }() - """ + { () in + let _resultValue = \(call) + if unsafe _resultValue == nil { + return nil + } else { + return unsafe \(raw: cast)(\(raw: startLabel): _resultValue!, count: Int(\(countExpr))) + } + }() + """ } - return - """ - unsafe \(raw: cast)(\(raw: startLabel): \(call), count: Int(\(countExpr))) + var expr = ExprSyntax( """ + \(raw: cast)(\(raw: startLabel): \(call), count: Int(\(countExpr))) + """) + if generateSpan { + expr = "_swiftifyOverrideLifetime(\(expr), copying: ())" + } + return "unsafe \(expr)" } } @@ -778,6 +782,14 @@ struct CountedOrSizedPointerThunkBuilder: ParamBoundsThunkBuilder, PointerBounds let argExpr = ExprSyntax("\(unwrappedName).baseAddress") assert(args[index] == nil) args[index] = try castPointerToOpaquePointer(unwrapIfNonnullable(argExpr)) + + if skipTrivialCount { + if let countVar = countExpr.as(DeclReferenceExprSyntax.self) { + let i = try getParameterIndexForDeclRef(signature.parameterClause.parameters, countVar) + args[i] = castIntToTargetType( + expr: "\(unwrappedName).count", type: getParam(signature, i).type) + } + } let call = try base.buildFunctionCall(args) let ptrRef = unwrapIfNullable(ExprSyntax(DeclReferenceExprSyntax(baseName: name))) @@ -851,11 +863,13 @@ struct CountedOrSizedPointerThunkBuilder: ParamBoundsThunkBuilder, PointerBounds nullArgs[index] = ExprSyntax(NilLiteralExprSyntax(nilKeyword: .keyword(.nil))) return ExprSyntax( """ - { () in return if \(name) == nil { + { () in + return if \(name) == nil { \(try base.buildFunctionCall(nullArgs)) } else { \(unwrappedCall) - } }() + } + }() """) } return unwrappedCall @@ -1057,14 +1071,7 @@ func parseLifetimeDependence(_ enumConstructorExpr: FunctionCallExprSyntax) thro return (pointer, dependence) } -func parseTypeMappingParam(_ paramAST: LabeledExprSyntax?) throws -> [String: String]? { - guard let unwrappedParamAST = paramAST else { - return nil - } - let paramExpr = unwrappedParamAST.expression - guard let dictExpr = paramExpr.as(DictionaryExprSyntax.self) else { - return nil - } +func parseStringLiteralDict(_ dictExpr: DictionaryExprSyntax) throws -> [String: String] { var dict: [String: String] = [:] switch dictExpr.content { case .colon(_): @@ -1086,6 +1093,32 @@ func parseTypeMappingParam(_ paramAST: LabeledExprSyntax?) throws -> [String: St return dict } +func parseStringMappingParam(_ paramAST: LabeledExprSyntax?, paramName: String) throws -> [String: + String]? +{ + guard let unwrappedParamAST = paramAST else { + return nil + } + guard let label = unwrappedParamAST.label else { + return nil + } + if label.trimmed.text != paramName { + return nil + } + let paramExpr = unwrappedParamAST.expression + guard let dictExpr = paramExpr.as(DictionaryExprSyntax.self) else { + return nil + } + return try parseStringLiteralDict(dictExpr) +} + +func parseTypeMappingParam(_ paramAST: LabeledExprSyntax?) throws -> [String: String]? { + return try parseStringMappingParam(paramAST, paramName: "typeMappings") +} +func parseAvailabilityParam(_ paramAST: LabeledExprSyntax?) throws -> [String: String]? { + return try parseStringMappingParam(paramAST, paramName: "availability") +} + func parseCxxSpansInSignature( _ signature: FunctionSignatureSyntax, _ typeMappings: [String: String]? @@ -1117,11 +1150,10 @@ func parseCxxSpansInSignature( } func parseMacroParam( - _ paramAST: LabeledExprSyntax, _ signature: FunctionSignatureSyntax, + _ paramExpr: ExprSyntax, _ signature: FunctionSignatureSyntax, nonescapingPointers: inout Set, lifetimeDependencies: inout [SwiftifyExpr: [LifetimeDependence]] ) throws -> ParamInfo? { - let paramExpr = paramAST.expression guard let enumConstructorExpr = paramExpr.as(FunctionCallExprSyntax.self) else { throw DiagnosticError( "expected _SwiftifyInfo enum literal as argument, got '\(paramExpr)'", node: paramExpr) @@ -1304,6 +1336,23 @@ func isMutableSpan(_ type: TypeSyntax) -> Bool { return name == "MutableSpan" || name == "MutableRawSpan" } +func isImmutableSpan(_ type: TypeSyntax) -> Bool { + if let optType = type.as(OptionalTypeSyntax.self) { + return isImmutableSpan(optType.wrappedType) + } + if let impOptType = type.as(ImplicitlyUnwrappedOptionalTypeSyntax.self) { + return isImmutableSpan(impOptType.wrappedType) + } + if let attrType = type.as(AttributedTypeSyntax.self) { + return isImmutableSpan(attrType.baseType) + } + guard let identifierType = type.as(IdentifierTypeSyntax.self) else { + return false + } + let name = identifierType.name.text + return name == "Span" || name == "RawSpan" +} + func containsLifetimeAttr(_ attrs: AttributeListSyntax, for paramName: TokenSyntax) -> Bool { for elem in attrs { guard let attr = elem.as(AttributeSyntax.self) else { @@ -1351,6 +1400,171 @@ func paramLifetimeAttributes( return defaultLifetimes } +func getAvailability(_ newSignature: FunctionSignatureSyntax, _ typeAvailability: [String: String]?) + -> [AttributeListSyntax.Element] +{ + guard let typeAvailability = typeAvailability else { + return [] + } + var hasMutableSpan = false + var hasSpan = false + if let returnClause = newSignature.returnClause { + hasMutableSpan = isMutableSpan(returnClause.type) + hasSpan = isImmutableSpan(returnClause.type) + } + for param in newSignature.parameterClause.parameters { + if hasMutableSpan { + break + } + hasMutableSpan = isMutableSpan(param.type) + hasSpan = hasSpan || isImmutableSpan(param.type) + } + if !hasMutableSpan && !hasSpan { + return [] + } + let availability = + if hasMutableSpan { + typeAvailability["MutableSpan"] + } else { + typeAvailability["Span"] + } + return [.attribute(AttributeSyntax("@available(\(raw: availability!), *)"))] +} + +func setVisibility(_ modifiers: inout DeclModifierListSyntax, _ funcKeyword: inout TokenSyntax) { + var hasVisibilityModifier = false + for i in modifiers.indices { + let modName = modifiers[i].name.trimmed.text + if modName == "public" || modName == "internal" || modName == "private" || modName == "filePrivate" { + return + } + if modName == "open" { + modifiers[i] = modifiers[i].with(\.name, .identifier("public", + leadingTrivia: modifiers[i].leadingTrivia, trailingTrivia: modifiers[i].trailingTrivia)) + return + } + } + // We have no visibility modifier, so insert "public" + // If the next token has a line break, steal that to make it print consistently + if let firstMod = modifiers.first { + if !firstMod.leadingTrivia.isEmpty { + modifiers = [DeclModifierSyntax(name: .identifier("public", leadingTrivia: firstMod.leadingTrivia)), + firstMod.trimmed] + modifiers.dropFirst() + } + return + } + if !funcKeyword.leadingTrivia.isEmpty { + modifiers = [DeclModifierSyntax(name: .identifier("public", leadingTrivia: funcKeyword.leadingTrivia))] + modifiers + funcKeyword = .identifier("func", trailingTrivia: funcKeyword.trailingTrivia) + return + } + modifiers = [DeclModifierSyntax(name: .identifier("public"))] + modifiers +} + +func constructOverloadFunction( + forDecl funcDecl: FunctionDeclSyntax, + args arguments: [ExprSyntax], + typeAvailability: [String: String]?, + typeMappings: [String: String]? +) throws -> DeclSyntax { + var nonescapingPointers = Set() + var lifetimeDependencies: [SwiftifyExpr: [LifetimeDependence]] = [:] + var parsedArgs = try arguments.compactMap { + try parseMacroParam( + $0, funcDecl.signature, nonescapingPointers: &nonescapingPointers, + lifetimeDependencies: &lifetimeDependencies) + } + parsedArgs.append(contentsOf: try parseCxxSpansInSignature(funcDecl.signature, typeMappings)) + setNonescapingPointers(&parsedArgs, nonescapingPointers) + setLifetimeDependencies(&parsedArgs, lifetimeDependencies) + // We only transform non-escaping spans. + parsedArgs = parsedArgs.filter { + if let cxxSpanArg = $0 as? CxxSpan { + return cxxSpanArg.nonescaping || cxxSpanArg.pointerIndex == .return + } else { + return true + } + } + try checkArgs(parsedArgs, funcDecl) + parsedArgs.sort { a, b in + // make sure return value cast to Span happens last so that withUnsafeBufferPointer + // doesn't return a ~Escapable type + if a.pointerIndex != .return && b.pointerIndex == .return { + return true + } + if a.pointerIndex == .return && b.pointerIndex != .return { + return false + } + return paramOrReturnIndex(a.pointerIndex) < paramOrReturnIndex(b.pointerIndex) + } + let baseBuilder = FunctionCallBuilder(funcDecl) + + let skipTrivialCount = hasTrivialCountVariants(parsedArgs) + + let builder: BoundsCheckedThunkBuilder = parsedArgs.reduce( + baseBuilder, + { (prev, parsedArg) in + parsedArg.getBoundsCheckedThunkBuilder(prev, funcDecl, skipTrivialCount) + }) + let (newSignature, onlyReturnTypeChanged) = try builder.buildFunctionSignature([:], nil) + let checks = + skipTrivialCount + ? [] as [CodeBlockItemSyntax] + : try builder.buildBoundsChecks().map { e in + CodeBlockItemSyntax(leadingTrivia: "\n", item: e) + } + let call = CodeBlockItemSyntax( + item: CodeBlockItemSyntax.Item( + ReturnStmtSyntax( + returnKeyword: .keyword(.return, trailingTrivia: " "), + expression: try builder.buildFunctionCall([:])))) + let body = CodeBlockSyntax(statements: CodeBlockItemListSyntax(checks + [call])) + let returnLifetimeAttribute = getReturnLifetimeAttribute(funcDecl, lifetimeDependencies) + let lifetimeAttrs = + returnLifetimeAttribute + paramLifetimeAttributes(newSignature, funcDecl.attributes) + let availabilityAttr = getAvailability(newSignature, typeAvailability) + let disfavoredOverload: [AttributeListSyntax.Element] = + (onlyReturnTypeChanged + ? [ + .attribute( + AttributeSyntax( + atSign: .atSignToken(), + attributeName: IdentifierTypeSyntax(name: "_disfavoredOverload"))) + ] : []) + // non-@objc methods should not be open, fall back to public instead + var modifiers: DeclModifierListSyntax = funcDecl.modifiers + var funcKeyword: TokenSyntax = funcDecl.funcKeyword + setVisibility(&modifiers, &funcKeyword) + let newFunc = + funcDecl + .with(\.signature, newSignature) + .with(\.body, body) + .with( + \.attributes, + funcDecl.attributes.filter { e in + switch e { + case .attribute(let attr): + // don't apply this macro recursively, and avoid dupe _alwaysEmitIntoClient + let name = attr.attributeName.as(IdentifierTypeSyntax.self)?.name.text + return name == nil || (name != "_SwiftifyImport" && name != "_alwaysEmitIntoClient") + default: return true + } + } + [ + .attribute( + AttributeSyntax( + atSign: .atSignToken(), + attributeName: IdentifierTypeSyntax(name: "_alwaysEmitIntoClient"))) + ] + + availabilityAttr + + lifetimeAttrs + + disfavoredOverload + ) + // Break up the expression to let the compiler type check + return DeclSyntax(newFunc + .with(\.modifiers, modifiers) + .with(\.funcKeyword, funcKeyword)) +} + /// A macro that adds safe(r) wrappers for functions with unsafe pointer types. /// Depends on bounds, escapability and lifetime information for each pointer. /// Intended to map to C attributes like __counted_by, __ended_by and __no_escape, @@ -1374,92 +1588,127 @@ public struct SwiftifyImportMacro: PeerMacro { if typeMappings != nil { arguments = arguments.dropLast() } - var nonescapingPointers = Set() - var lifetimeDependencies: [SwiftifyExpr: [LifetimeDependence]] = [:] - var parsedArgs = try arguments.compactMap { - try parseMacroParam( - $0, funcDecl.signature, nonescapingPointers: &nonescapingPointers, - lifetimeDependencies: &lifetimeDependencies) + let typeAvailability = try parseAvailabilityParam(arguments.last) + if typeAvailability != nil { + arguments = arguments.dropLast() } - parsedArgs.append(contentsOf: try parseCxxSpansInSignature(funcDecl.signature, typeMappings)) - setNonescapingPointers(&parsedArgs, nonescapingPointers) - setLifetimeDependencies(&parsedArgs, lifetimeDependencies) - // We only transform non-escaping spans. - parsedArgs = parsedArgs.filter { - if let cxxSpanArg = $0 as? CxxSpan { - return cxxSpanArg.nonescaping || cxxSpanArg.pointerIndex == .return - } else { - return true + let args = arguments.map { $0.expression } + return [ + try constructOverloadFunction( + forDecl: funcDecl, args: args, typeAvailability: typeAvailability, + typeMappings: typeMappings) + ] + } catch let error as DiagnosticError { + context.diagnose( + Diagnostic( + node: error.node, message: MacroExpansionErrorMessage(error.description), + notes: error.notes)) + return [] + } + } +} + +func parseProtocolMacroParam( + _ paramAST: LabeledExprSyntax, + methods: [String: FunctionDeclSyntax] +) throws -> (FunctionDeclSyntax, [ExprSyntax]) { + let paramExpr = paramAST.expression + guard let enumConstructorExpr = paramExpr.as(FunctionCallExprSyntax.self) else { + throw DiagnosticError( + "expected _SwiftifyProtocolMethodInfo enum literal as argument, got '\(paramExpr)'", + node: paramExpr) + } + let enumName = try parseEnumName(paramExpr) + if enumName != "method" { + throw DiagnosticError( + "expected 'method', got '\(enumName)'", + node: enumConstructorExpr) + } + let argumentList = enumConstructorExpr.arguments + let methodSignatureArg = try getArgumentByName(argumentList, "signature") + guard let methodSignatureStringLit = methodSignatureArg.as(StringLiteralExprSyntax.self) else { + throw DiagnosticError( + "expected string literal for 'signature' parameter, got \(methodSignatureArg)", node: methodSignatureArg) + } + let methodSignature = methodSignatureStringLit.representedLiteralValue! + guard let methodSyntax = methods[methodSignature] else { + var notes: [Note] = [] + var name = methodSignature + if let methodSyntax = DeclSyntax("\(raw: methodSignature)").as(FunctionDeclSyntax.self) { + name = methodSyntax.name.trimmed.text + } + for (_, method) in methods where method.name.trimmed.text == name { + notes.append(Note(node: Syntax(method.name), message: MacroExpansionNoteMessage("did you mean '\(method.trimmed.description)'?"))) + } + throw DiagnosticError( + "method with signature '\(methodSignature)' not found in protocol", node: methodSignatureArg, notes: notes) + } + let paramInfoArg = try getArgumentByName(argumentList, "paramInfo") + guard let paramInfoArgList = paramInfoArg.as(ArrayExprSyntax.self) else { + throw DiagnosticError( + "expected array literal for 'paramInfo' parameter, got \(paramInfoArg)", node: paramInfoArg) + } + return (methodSyntax, paramInfoArgList.elements.map { ExprSyntax($0.expression) }) +} + +/// Similar to SwiftifyImportMacro, but for providing overloads to methods in +/// protocols using an extension, rather than in the same scope as the original. +public struct SwiftifyImportProtocolMacro: ExtensionMacro { + public static func expansion( + of node: AttributeSyntax, + attachedTo declaration: some DeclGroupSyntax, + providingExtensionsOf type: some TypeSyntaxProtocol, + conformingTo protocols: [TypeSyntax], + in context: some MacroExpansionContext + ) throws -> [ExtensionDeclSyntax] { + do { + let members: MemberBlockItemListSyntax = + switch declaration.kind { + case .protocolDecl: + declaration.as(ProtocolDeclSyntax.self)!.memberBlock.members + case .classDecl: + declaration.as(ClassDeclSyntax.self)!.memberBlock.members + default: + throw DiagnosticError( + "@_SwiftifyImportProtocol only works on protocols and classes", node: declaration) } + let argumentList = node.arguments!.as(LabeledExprListSyntax.self)! + var arguments = [LabeledExprSyntax](argumentList) + let typeMappings = try parseTypeMappingParam(arguments.last) + if typeMappings != nil { + arguments = arguments.dropLast() } - try checkArgs(parsedArgs, funcDecl) - parsedArgs.sort { a, b in - // make sure return value cast to Span happens last so that withUnsafeBufferPointer - // doesn't return a ~Escapable type - if a.pointerIndex != .return && b.pointerIndex == .return { - return true - } - if a.pointerIndex == .return && b.pointerIndex != .return { - return false - } - return paramOrReturnIndex(a.pointerIndex) < paramOrReturnIndex(b.pointerIndex) + let typeAvailability = try parseAvailabilityParam(arguments.last) + if typeAvailability != nil { + arguments = arguments.dropLast() } - let baseBuilder = FunctionCallBuilder(funcDecl) - - let skipTrivialCount = hasTrivialCountVariants(parsedArgs) - - let builder: BoundsCheckedThunkBuilder = parsedArgs.reduce( - baseBuilder, - { (prev, parsedArg) in - parsedArg.getBoundsCheckedThunkBuilder(prev, funcDecl, skipTrivialCount) - }) - let (newSignature, onlyReturnTypeChanged) = try builder.buildFunctionSignature([:], nil) - let checks = - skipTrivialCount - ? [] as [CodeBlockItemSyntax] - : try builder.buildBoundsChecks().map { e in - CodeBlockItemSyntax(leadingTrivia: "\n", item: e) + + var methods: [String: FunctionDeclSyntax] = [:] + for member in members { + guard let methodDecl = member.decl.as(FunctionDeclSyntax.self) else { + continue } - let call = CodeBlockItemSyntax( - item: CodeBlockItemSyntax.Item( - ReturnStmtSyntax( - returnKeyword: .keyword(.return, trailingTrivia: " "), - expression: try builder.buildFunctionCall([:])))) - let body = CodeBlockSyntax(statements: CodeBlockItemListSyntax(checks + [call])) - let returnLifetimeAttribute = getReturnLifetimeAttribute(funcDecl, lifetimeDependencies) - let lifetimeAttrs = - returnLifetimeAttribute + paramLifetimeAttributes(newSignature, funcDecl.attributes) - let disfavoredOverload: [AttributeListSyntax.Element] = - (onlyReturnTypeChanged - ? [ - .attribute( - AttributeSyntax( - atSign: .atSignToken(), - attributeName: IdentifierTypeSyntax(name: "_disfavoredOverload"))) - ] : []) - let newFunc = - funcDecl - .with(\.signature, newSignature) - .with(\.body, body) - .with( - \.attributes, - funcDecl.attributes.filter { e in - switch e { - case .attribute(let attr): - // don't apply this macro recursively, and avoid dupe _alwaysEmitIntoClient - let name = attr.attributeName.as(IdentifierTypeSyntax.self)?.name.text - return name == nil || (name != "_SwiftifyImport" && name != "_alwaysEmitIntoClient") - default: return true - } - } + [ - .attribute( - AttributeSyntax( - atSign: .atSignToken(), - attributeName: IdentifierTypeSyntax(name: "_alwaysEmitIntoClient"))) - ] - + lifetimeAttrs - + disfavoredOverload) - return [DeclSyntax(newFunc)] + let trimmedDecl = methodDecl.with(\.body, nil) + .with(\.attributes, []) + .trimmed + methods[trimmedDecl.description] = methodDecl + } + let overloads = try arguments.map { + let (method, args) = try parseProtocolMacroParam($0, methods: methods) + let function = try constructOverloadFunction( + forDecl: method, args: args, typeAvailability: typeAvailability, + typeMappings: typeMappings) + return MemberBlockItemSyntax(decl: function) + } + return [ + ExtensionDeclSyntax( + extensionKeyword: .identifier("extension"), extendedType: type, + memberBlock: MemberBlockSyntax( + leftBrace: .leftBraceToken(), + members: MemberBlockItemListSyntax(overloads), + rightBrace: .rightBraceToken()) + ) + ] } catch let error as DiagnosticError { context.diagnose( Diagnostic( diff --git a/lib/Sema/TypeCheckMacros.cpp b/lib/Sema/TypeCheckMacros.cpp index 2f3e1de638205..a04b12b5f91c6 100644 --- a/lib/Sema/TypeCheckMacros.cpp +++ b/lib/Sema/TypeCheckMacros.cpp @@ -1375,6 +1375,13 @@ static SourceFile *evaluateAttachedMacro(MacroDecl *macro, Decl *attachedTo, } else if (role == MacroRole::Conformance || role == MacroRole::Extension) { // Conformance macros always expand to extensions at file-scope. dc = attachedTo->getDeclContext()->getParentSourceFile(); + if (!dc) { + assert(isa( + attachedTo->getDeclContext()->getModuleScopeContext())); + dc = attachedTo->getDeclContext(); + // decls imported from clang do not have a SourceFile + assert(isa(dc) && !isa(dc)); + } } else { dc = attachedTo->getInnermostDeclContext(); } diff --git a/stdlib/public/Cxx/CxxSpan.swift b/stdlib/public/Cxx/CxxSpan.swift index 4064a650f8896..adc9425c85cf0 100644 --- a/stdlib/public/Cxx/CxxSpan.swift +++ b/stdlib/public/Cxx/CxxSpan.swift @@ -18,46 +18,6 @@ internal func unsafeBitCast( Builtin.reinterpretCast(x) } -/// Unsafely discard any lifetime dependency on the `dependent` argument. Return -/// a value identical to `dependent` with a lifetime dependency on the caller's -/// borrow scope of the `source` argument. -/// -/// This mimics the stdlib definition. It is public for use with import macros. -@unsafe -@_unsafeNonescapableResult -@_alwaysEmitIntoClient -@_transparent -@lifetime(borrow source) -public func _cxxOverrideLifetime< - T: ~Copyable & ~Escapable, U: ~Copyable & ~Escapable ->( - _ dependent: consuming T, borrowing source: borrowing U -) -> T { - // TODO: Remove @_unsafeNonescapableResult. Instead, the unsafe dependence - // should be expressed by a builtin that is hidden within the function body. - dependent -} - -/// Unsafely discard any lifetime dependency on the `dependent` argument. Return -/// a value identical to `dependent` that inherits all lifetime dependencies from -/// the `source` argument. -/// -/// This mimics the stdlib definition. It is public for use with import macros. -@unsafe -@_unsafeNonescapableResult -@_alwaysEmitIntoClient -@_transparent -@lifetime(copy source) -public func _cxxOverrideLifetime< - T: ~Copyable & ~Escapable, U: ~Copyable & ~Escapable ->( - _ dependent: consuming T, copying source: borrowing U -) -> T { - // TODO: Remove @_unsafeNonescapableResult. Instead, the unsafe dependence - // should be expressed by a builtin that is hidden within the function body. - dependent -} - /// A C++ type that is an object that can refer to a contiguous sequence of objects. /// /// C++ standard library type `std::span` conforms to this protocol. @@ -111,7 +71,7 @@ extension Span { let buffer = unsafe UnsafeBufferPointer(start: span.__dataUnsafe(), count: Int(span.size())) let newSpan = unsafe Span(_unsafeElements: buffer) // 'self' is limited to the caller's scope of the variable passed to the 'span' argument. - self = unsafe _cxxOverrideLifetime(newSpan, borrowing: span) + self = unsafe _swiftifyOverrideLifetime(newSpan, borrowing: span) } } @@ -127,7 +87,7 @@ extension MutableSpan { let buffer = unsafe UnsafeMutableBufferPointer(start: span.__dataUnsafe(), count: Int(span.size())) let newSpan = unsafe MutableSpan(_unsafeElements: buffer) // 'self' is limited to the caller's scope of the variable passed to the 'span' argument. - self = unsafe _cxxOverrideLifetime(newSpan, borrowing: span) + self = unsafe _swiftifyOverrideLifetime(newSpan, borrowing: span) } } diff --git a/stdlib/public/Cxx/CxxVector.swift b/stdlib/public/Cxx/CxxVector.swift index b226b3a6755a1..e3adf3266eb94 100644 --- a/stdlib/public/Cxx/CxxVector.swift +++ b/stdlib/public/Cxx/CxxVector.swift @@ -58,7 +58,7 @@ extension CxxVector { borrowing get { let buffer = unsafe UnsafeBufferPointer(start: self.__dataUnsafe(), count: Int(self.size())) let span = unsafe Span(_unsafeElements: buffer) - return unsafe _cxxOverrideLifetime(span, borrowing: self) + return unsafe _swiftifyOverrideLifetime(span, borrowing: self) } } } diff --git a/stdlib/public/core/SwiftifyImport.swift b/stdlib/public/core/SwiftifyImport.swift index 3efd0a645098a..784dcfe8c634f 100644 --- a/stdlib/public/core/SwiftifyImport.swift +++ b/stdlib/public/core/SwiftifyImport.swift @@ -54,12 +54,74 @@ public enum _SwiftifyInfo { /// It will replace some std::span arguments with Swift's Span type when sufficient information is /// available. /// -/// Currently not supported: return pointers, nested pointers, pointee "count" parameters, endedBy. +/// Currently not supported: nested pointers, pointee "count" parameters, endedBy. /// /// Parameter paramInfo: information about how the function uses the pointer passed to it. The /// safety of the generated wrapper function depends on this info being extensive and accurate. #if hasFeature(Macros) @attached(peer, names: overloaded) -public macro _SwiftifyImport(_ paramInfo: _SwiftifyInfo..., typeMappings: [String: String] = [:]) = +public macro _SwiftifyImport(_ paramInfo: _SwiftifyInfo..., availability: [String: String] = [:], typeMappings: [String: String] = [:]) = #externalMacro(module: "SwiftMacros", type: "SwiftifyImportMacro") #endif + +/// Allows annotating pointer parameters in a protocol method using the `@_SwiftifyImportProtocol` macro. +/// +/// This is not marked @available, because _SwiftifyImportProtocolMethod is available for any target. +/// Instances of _SwiftifyProtocolMethodInfo should ONLY be passed as arguments directly to +/// _SwiftifyImportProtocolMethod, so they should not affect linkage since there are never any instances +/// at runtime. +public enum _SwiftifyProtocolMethodInfo { + case method(signature: String, paramInfo: [_SwiftifyInfo]) +} + +/// Like _SwiftifyImport, but since protocols cannot contain function implementations they need to +/// be placed in a separate extension instead. Unlike _SwiftifyImport, which applies to a single +/// function, this macro supports feeding info about multiple methods and generating safe overloads +/// for all of them at once. +#if hasFeature(Macros) +@attached(extension, names: arbitrary) +public macro _SwiftifyImportProtocol(_ methodInfo: _SwiftifyProtocolMethodInfo..., + availability: [String: String] = [:], + typeMappings: [String: String] = [:]) = + #externalMacro(module: "SwiftMacros", type: "SwiftifyImportProtocolMacro") +#endif + +/// Unsafely discard any lifetime dependency on the `dependent` argument. Return +/// a value identical to `dependent` with a lifetime dependency on the caller's +/// borrow scope of the `source` argument. +/// +/// This mimics the stdlib definition. It is public for use with import macros. +@unsafe +@_unsafeNonescapableResult +@_alwaysEmitIntoClient +@_transparent +@lifetime(borrow source) +public func _swiftifyOverrideLifetime< + T: ~Copyable & ~Escapable, U: ~Copyable & ~Escapable +>( + _ dependent: consuming T, borrowing source: borrowing U +) -> T { + // TODO: Remove @_unsafeNonescapableResult. Instead, the unsafe dependence + // should be expressed by a builtin that is hidden within the function body. + dependent +} + +/// Unsafely discard any lifetime dependency on the `dependent` argument. Return +/// a value identical to `dependent` that inherits all lifetime dependencies from +/// the `source` argument. +/// +/// This mimics the stdlib definition. It is public for use with import macros. +@unsafe +@_unsafeNonescapableResult +@_alwaysEmitIntoClient +@_transparent +@lifetime(copy source) +public func _swiftifyOverrideLifetime< + T: ~Copyable & ~Escapable, U: ~Copyable & ~Escapable +>( + _ dependent: consuming T, copying source: borrowing U +) -> T { + // TODO: Remove @_unsafeNonescapableResult. Instead, the unsafe dependence + // should be expressed by a builtin that is hidden within the function body. + dependent +} \ No newline at end of file diff --git a/test/Interop/C/swiftify-import/Inputs/counted-by-noescape.h b/test/Interop/C/swiftify-import/Inputs/counted-by-noescape.h index 6ea131586ac7a..28b4be1c0c4b7 100644 --- a/test/Interop/C/swiftify-import/Inputs/counted-by-noescape.h +++ b/test/Interop/C/swiftify-import/Inputs/counted-by-noescape.h @@ -7,7 +7,7 @@ void simple(int len, int * __counted_by(len) __noescape p); void swiftAttr(int len, int *p) __attribute__(( - swift_attr("@_SwiftifyImport(.countedBy(pointer: .param(2), count: \"len\"), .nonescaping(pointer: .param(2)))"))); + swift_attr("@_SwiftifyImport(.countedBy(pointer: .param(2), count: \"len\"), .nonescaping(pointer: .param(2)), availability: [\"MutableSpan\": \"macOS 9999, *\"])"))); void shared(int len, int * __counted_by(len) __noescape p1, int * __counted_by(len) __noescape p2); diff --git a/test/Interop/C/swiftify-import/Inputs/sized-by-noescape.h b/test/Interop/C/swiftify-import/Inputs/sized-by-noescape.h index 7d18654569046..d39476fc8797c 100644 --- a/test/Interop/C/swiftify-import/Inputs/sized-by-noescape.h +++ b/test/Interop/C/swiftify-import/Inputs/sized-by-noescape.h @@ -6,7 +6,7 @@ void simple(int len, const void * __sized_by(len) __noescape p); void swiftAttr(int len, const void *p) __attribute__((swift_attr( - "@_SwiftifyImport(.sizedBy(pointer: .param(2), size: \"len\"), .nonescaping(pointer: .param(2)))"))); + "@_SwiftifyImport(.sizedBy(pointer: .param(2), size: \"len\"), .nonescaping(pointer: .param(2)), availability: [\"Span\": \"macOS 9999, *\"])"))); void shared(int len, const void * __sized_by(len) __noescape p1, const void * __sized_by(len) __noescape p2); diff --git a/test/Interop/C/swiftify-import/counted-by-noescape.swift b/test/Interop/C/swiftify-import/counted-by-noescape.swift index 339789074c959..3d06f583c915a 100644 --- a/test/Interop/C/swiftify-import/counted-by-noescape.swift +++ b/test/Interop/C/swiftify-import/counted-by-noescape.swift @@ -11,21 +11,28 @@ import CountedByNoEscapeClang -// CHECK: @lifetime(p: copy p) +// CHECK: @available(macOS {{.*}}, *) +// CHECK-NEXT: @lifetime(p: copy p) // CHECK-NEXT: @_alwaysEmitIntoClient public func complexExpr(_ len: Int32, _ offset: Int32, _ p: inout MutableSpan) +// CHECK-NEXT: @available(macOS {{.*}}, *) // CHECK-NEXT: @lifetime(p: copy p) // CHECK-NEXT: @_alwaysEmitIntoClient public func nonnull(_ p: inout MutableSpan) +// CHECK-NEXT: @available(macOS {{.*}}, *) // CHECK-NEXT: @lifetime(p: copy p) // CHECK-NEXT: @_alwaysEmitIntoClient public func nullUnspecified(_ p: inout MutableSpan) +// CHECK-NEXT: @available(macOS {{.*}}, *) // CHECK-NEXT: @lifetime(copy p) // CHECK-NEXT: @lifetime(p: copy p) // CHECK-NEXT: @_alwaysEmitIntoClient public func returnLifetimeBound(_ len1: Int32, _ p: inout MutableSpan) -> MutableSpan // CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func returnPointer(_ len: Int32) -> UnsafeMutableBufferPointer +// CHECK-NEXT: @available(macOS {{.*}}, *) // CHECK-NEXT: @lifetime(p1: copy p1) // CHECK-NEXT: @lifetime(p2: copy p2) // CHECK-NEXT: @_alwaysEmitIntoClient public func shared(_ len: Int32, _ p1: inout MutableSpan, _ p2: inout MutableSpan) +// CHECK-NEXT: @available(macOS {{.*}}, *) // CHECK-NEXT: @lifetime(p: copy p) // CHECK-NEXT: @_alwaysEmitIntoClient public func simple(_ p: inout MutableSpan) +// CHECK-NEXT: @available(macOS 9999, *) // CHECK-NEXT: @lifetime(p: copy p) // CHECK-NEXT: @_alwaysEmitIntoClient public func swiftAttr(_ p: inout MutableSpan) diff --git a/test/Interop/C/swiftify-import/sized-by-noescape.swift b/test/Interop/C/swiftify-import/sized-by-noescape.swift index 2510053201eaa..363eee704beaa 100644 --- a/test/Interop/C/swiftify-import/sized-by-noescape.swift +++ b/test/Interop/C/swiftify-import/sized-by-noescape.swift @@ -9,11 +9,18 @@ // Check that ClangImporter correctly infers and expands @_SwiftifyImport macros for functions with __sized_by __noescape parameters. import SizedByNoEscapeClang -// CHECK: @_alwaysEmitIntoClient public func complexExpr(_ len: Int{{.*}}, _ offset: Int{{.*}}, _ p: RawSpan) +// CHECK: @available(macOS {{.*}}, *) +// CHECK-NEXT: @_alwaysEmitIntoClient public func complexExpr(_ len: Int{{.*}}, _ offset: Int{{.*}}, _ p: RawSpan) +// CHECK-NEXT: @available(macOS {{.*}}, *) // CHECK-NEXT: @_alwaysEmitIntoClient public func nonnull(_ p: RawSpan) +// CHECK-NEXT: @available(macOS {{.*}}, *) // CHECK-NEXT: @_alwaysEmitIntoClient public func nullUnspecified(_ p: RawSpan) +// CHECK-NEXT: @available(macOS {{.*}}, *) // CHECK-NEXT: @_alwaysEmitIntoClient public func opaque(_ p: RawSpan) // CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func returnPointer(_ len: Int{{.*}}) -> UnsafeRawBufferPointer +// CHECK-NEXT: @available(macOS {{.*}}, *) // CHECK-NEXT: @_alwaysEmitIntoClient public func shared(_ len: Int{{.*}}, _ p1: RawSpan, _ p2: RawSpan) +// CHECK-NEXT: @available(macOS {{.*}}, *) // CHECK-NEXT: @_alwaysEmitIntoClient public func simple(_ p: RawSpan) +// CHECK-NEXT: @available(macOS 9999, *) // CHECK-NEXT: @_alwaysEmitIntoClient public func swiftAttr(_ p: RawSpan) diff --git a/test/Interop/Cxx/stdlib/std-span-interface.swift b/test/Interop/Cxx/stdlib/std-span-interface.swift index b910668fcdb11..fadf252abb0b9 100644 --- a/test/Interop/Cxx/stdlib/std-span-interface.swift +++ b/test/Interop/Cxx/stdlib/std-span-interface.swift @@ -13,7 +13,8 @@ import StdSpan import CxxStdlib // CHECK: struct DependsOnSelf { -// CHECK: @lifetime(borrow self) +// CHECK: @available(macOS {{.*}}, *) +// CHECK-NEXT: @lifetime(borrow self) // CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public borrowing func get() -> Span // CHECK-NEXT: borrowing func get() -> ConstSpanOfInt @@ -23,51 +24,66 @@ import CxxStdlib // CHECK-NEXT: func funcWithSafeWrapper3(_ v: borrowing VecOfInt) -> ConstSpanOfInt // CHECK: struct X { // CHECK-NEXT: init() +// CHECK-NEXT: @available(macOS {{.*}}, *) // CHECK-NEXT: @_alwaysEmitIntoClient public mutating func methodWithSafeWrapper(_ s: Span) // CHECK-NEXT: mutating func methodWithSafeWrapper(_ s: ConstSpanOfInt) // CHECK-NEXT: } // CHECK: struct SpanWithoutTypeAlias { // CHECK-NEXT: init() +// CHECK-NEXT: @available(macOS {{.*}}, *) // CHECK-NEXT: @lifetime(borrow self) // CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public mutating func bar() -> Span // CHECK-NEXT: mutating func bar() -> std.{{.*}}span<__cxxConst, _C{{.*}}_{{.*}}> +// CHECK-NEXT: @available(macOS {{.*}}, *) // CHECK-NEXT: @_alwaysEmitIntoClient public mutating func foo(_ s: Span) // CHECK-NEXT: mutating func foo(_ s: std.{{.*}}span<__cxxConst, _C{{.*}}_{{.*}}>) // CHECK-NEXT: } -// CHECK: @lifetime(s: copy s) +// CHECK: @available(macOS {{.*}}, *) +// CHECK-NEXT: @lifetime(s: copy s) // CHECK-NEXT: @_alwaysEmitIntoClient public func FuncWithMutableSafeWrapper(_ s: inout MutableSpan) +// CHECK-NEXT: @available(macOS {{.*}}, *) // CHECK-NEXT: @lifetime(copy s) // CHECK-NEXT: @lifetime(s: copy s) // CHECK-NEXT: @_alwaysEmitIntoClient public func FuncWithMutableSafeWrapper2(_ s: inout MutableSpan) -> MutableSpan -// CHECK-NEXT: @lifetime(borrow v) -// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func FuncWithMutableSafeWrapper3(_ v: inout VecOfInt) -> MutableSpan +// CHECK-NOT: FuncWithMutableSafeWrapper3 +// CHECK-NEXT: @available(macOS {{.*}}, *) // CHECK-NEXT: @lifetime(copy p) // CHECK-NEXT: @lifetime(p: copy p) // CHECK-NEXT: @_alwaysEmitIntoClient public func MixedFuncWithMutableSafeWrapper1(_ p: inout MutableSpan) -> MutableSpan -// CHECK-NEXT: @lifetime(borrow v) -// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func MixedFuncWithMutableSafeWrapper2(_ v: inout VecOfInt, _ len: Int32) -> MutableSpan +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func MixedFuncWithMutableSafeWrapper2(_ v: inout VecOfInt, _ len: Int32) -> UnsafeMutableBufferPointer +// CHECK-NEXT: @available(macOS {{.*}}, *) // CHECK-NEXT: @lifetime(s: copy s) // CHECK-NEXT: @_alwaysEmitIntoClient public func MixedFuncWithMutableSafeWrapper3(_ s: inout MutableSpan, _ p: UnsafeMutableBufferPointer) +// CHECK-NEXT: @available(macOS {{.*}}, *) // CHECK-NEXT: @lifetime(s: copy s) // CHECK-NEXT: @lifetime(p: copy p) // CHECK-NEXT: @_alwaysEmitIntoClient public func MixedFuncWithMutableSafeWrapper4(_ s: inout MutableSpan, _ p: inout MutableSpan) +// CHECK-NEXT: @available(macOS {{.*}}, *) // CHECK-NEXT: @lifetime(p: copy p) // CHECK-NEXT: @_alwaysEmitIntoClient public func MixedFuncWithMutableSafeWrapper5(_ s: SpanOfInt, _ p: inout MutableSpan) // CHECK-NEXT: @_alwaysEmitIntoClient public func MixedFuncWithMutableSafeWrapper6(_ s: SpanOfInt, _ p: UnsafeMutableBufferPointer) // CHECK-NEXT: @_alwaysEmitIntoClient public func MixedFuncWithMutableSafeWrapper7(_ p: UnsafeMutableBufferPointer) -> SpanOfInt -// CHECK: @_alwaysEmitIntoClient public func funcWithSafeWrapper(_ s: Span) +// CHECK: @available(macOS {{.*}}, *) +// CHECK-NEXT: @_alwaysEmitIntoClient public func funcWithSafeWrapper(_ s: Span) +// CHECK-NEXT: @available(macOS {{.*}}, *) // CHECK-NEXT: @lifetime(copy s) // CHECK-NEXT: @_alwaysEmitIntoClient public func funcWithSafeWrapper2(_ s: Span) -> Span +// CHECK-NEXT: @available(macOS {{.*}}, *) // CHECK-NEXT: @lifetime(borrow v) // CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func funcWithSafeWrapper3(_ v: borrowing VecOfInt) -> Span +// CHECK-NEXT: @available(macOS {{.*}}, *) // CHECK-NEXT: @lifetime(copy p) // CHECK-NEXT: @_alwaysEmitIntoClient public func mixedFuncWithSafeWrapper1(_ p: Span) -> Span +// CHECK-NEXT: @available(macOS {{.*}}, *) // CHECK-NEXT: @lifetime(borrow v) // CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload public func mixedFuncWithSafeWrapper2(_ v: borrowing VecOfInt, _ len: Int32) -> Span +// CHECK-NEXT: @available(macOS {{.*}}, *) // CHECK-NEXT: @_alwaysEmitIntoClient public func mixedFuncWithSafeWrapper3(_ s: Span, _ p: UnsafeMutableBufferPointer) +// CHECK-NEXT: @available(macOS {{.*}}, *) // CHECK-NEXT: @_alwaysEmitIntoClient public func mixedFuncWithSafeWrapper4(_ s: Span, _ p: Span) +// CHECK-NEXT: @available(macOS {{.*}}, *) // CHECK-NEXT: @_alwaysEmitIntoClient public func mixedFuncWithSafeWrapper5(_ s: ConstSpanOfInt, _ p: Span) // CHECK-NEXT: @_alwaysEmitIntoClient public func mixedFuncWithSafeWrapper6(_ s: ConstSpanOfInt, _ p: UnsafeMutableBufferPointer) // CHECK-NEXT: @_alwaysEmitIntoClient public func mixedFuncWithSafeWrapper7(_ p: UnsafeBufferPointer) -> ConstSpanOfInt diff --git a/test/Interop/Cxx/swiftify-import/counted-by-in-namespace.swift b/test/Interop/Cxx/swiftify-import/counted-by-in-namespace.swift index 38b3425136b1a..6b10a18baedc6 100644 --- a/test/Interop/Cxx/swiftify-import/counted-by-in-namespace.swift +++ b/test/Interop/Cxx/swiftify-import/counted-by-in-namespace.swift @@ -22,7 +22,7 @@ namespace foo { //--- namespace.swift import Namespace - + func test(s: UnsafeMutableBufferPointer) { foo.bar(s) -} +} diff --git a/test/Interop/Cxx/swiftify-import/counted-by-method.swift b/test/Interop/Cxx/swiftify-import/counted-by-method.swift index c15cd8564bc88..b05f5c0ed1732 100644 --- a/test/Interop/Cxx/swiftify-import/counted-by-method.swift +++ b/test/Interop/Cxx/swiftify-import/counted-by-method.swift @@ -5,7 +5,7 @@ // RUN: %target-swift-ide-test -plugin-path %swift-plugin-dir -I %t/Inputs -cxx-interoperability-mode=upcoming-swift -enable-experimental-feature SafeInteropWrappers -print-module -module-to-print=Method -source-filename=x | %FileCheck %s // RUN: %target-swift-frontend -plugin-path %swift-plugin-dir -I %t/Inputs -cxx-interoperability-mode=default -enable-experimental-feature SafeInteropWrappers %t/method.swift -dump-macro-expansions -typecheck -verify -// CHECK: @_alwaysEmitIntoClient +// CHECK: @_alwaysEmitIntoClient // CHECK-SAME: public mutating func bar(_ p: UnsafeMutableBufferPointer) //--- Inputs/module.modulemap @@ -23,8 +23,8 @@ public: //--- method.swift import Method - + func test(s: UnsafeMutableBufferPointer) { var foo = Foo() foo.bar(s) -} +} diff --git a/test/Interop/ObjC/swiftify-import/counted-by-in-class-noescape.swift b/test/Interop/ObjC/swiftify-import/counted-by-in-class-noescape.swift new file mode 100644 index 0000000000000..ab403d900db03 --- /dev/null +++ b/test/Interop/ObjC/swiftify-import/counted-by-in-class-noescape.swift @@ -0,0 +1,200 @@ +// REQUIRES: swift_feature_SafeInteropWrappers +// REQUIRES: swift_feature_LifetimeDependence + +// swift-ide-test doesn't currently trigger extension macro expansion, nor does it typecheck macro expansions, so dump macros with swift-frontend + +// RUN: %empty-directory(%t) +// RUN: split-file %s %t + +// RUN: %target-swift-frontend -emit-module -plugin-path %swift-plugin-dir -o %t/CountedByClassSpan.swiftmodule -I %t/Inputs -enable-experimental-feature SafeInteropWrappers -enable-experimental-feature LifetimeDependence %t/counted-by-class-noescape.swift -dump-macro-expansions -swift-version 6 2>&1 | %FileCheck %s + +//--- Inputs/module.modulemap +module CountedByClassNoescapeClang { + header "counted-by-class-noescape.h" + export * +} + +//--- Inputs/counted-by-class-noescape.h +#pragma once + +#define __counted_by(x) __attribute__((__counted_by__(x))) +#define __noescape __attribute__((__noescape__)) +#define __lifetimebound __attribute__((__lifetimebound__)) + +__attribute__((swift_attr("@available(SwiftStdlib 6.2, *)"))) +@interface CountedByClassSpan + - (void) simple:(int)len :(int * __counted_by(len) __noescape)p; + - (void) shared:(int)len :(int * __counted_by(len) __noescape)p1 :(int * __counted_by(len) __noescape)p2; + - (void) complexExpr:(int)len :(int) offset :(int * __counted_by(len - offset) __noescape)p; + - (void) nullUnspecified:(int)len :(int * __counted_by(len) _Null_unspecified __noescape)p; + - (void) nonnull:(int)len :(int * __counted_by(len) _Nonnull __noescape)p; + - (void) nullable:(int)len :(int * __counted_by(len) _Nullable __noescape)p; + + - (int * __counted_by(len)) returnPointer:(int)len :(int)len2 :(int * __counted_by(len2) __lifetimebound) p; + + + (void) staticMethod:(int)len :(int * __counted_by(len) __noescape)p; +@end + +// CHECK-LABEL: extension CountedByClassSpan { +// CHECK-NEXT: @_alwaysEmitIntoClient @available(macOS 9999, *) @lifetime(p: copy p) +// CHECK-NEXT: public class func simple(_ p: inout MutableSpan) { +// CHECK-NEXT: return unsafe p.withUnsafeMutableBufferPointer { _pPtr in +// CHECK-NEXT: return unsafe simple(Int32(exactly: _pPtr.count)!, _pPtr.baseAddress!) +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: @_alwaysEmitIntoClient @available(macOS 9999, *) @lifetime(p: copy p) +// CHECK-NEXT: public func simple(_ p: inout MutableSpan) { +// CHECK-NEXT: return unsafe p.withUnsafeMutableBufferPointer { _pPtr in +// CHECK-NEXT: return unsafe simple(Int32(exactly: _pPtr.count)!, _pPtr.baseAddress!) +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: @_alwaysEmitIntoClient @available(macOS 9999, *) @lifetime(p1: copy p1) @lifetime(p2: copy p2) +// CHECK-NEXT: public class func shared(_ len: Int32, _ p1: inout MutableSpan, _ p2: inout MutableSpan) { +// CHECK-NEXT: let _p1Count: some BinaryInteger = len +// CHECK-NEXT: if p1.count < _p1Count || _p1Count < 0 { +// CHECK-NEXT: fatalError("bounds check failure when calling unsafe function") +// CHECK-NEXT: } +// CHECK-NEXT: let _p2Count: some BinaryInteger = len +// CHECK-NEXT: if p2.count < _p2Count || _p2Count < 0 { +// CHECK-NEXT: fatalError("bounds check failure when calling unsafe function") +// CHECK-NEXT: } +// CHECK-NEXT: return unsafe p2.withUnsafeMutableBufferPointer { _p2Ptr in +// CHECK-NEXT: return unsafe p1.withUnsafeMutableBufferPointer { _p1Ptr in +// CHECK-NEXT: return unsafe shared(len, _p1Ptr.baseAddress!, _p2Ptr.baseAddress!) +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: @_alwaysEmitIntoClient @available(macOS 9999, *) @lifetime(p1: copy p1) @lifetime(p2: copy p2) +// CHECK-NEXT: public func shared(_ len: Int32, _ p1: inout MutableSpan, _ p2: inout MutableSpan) { +// CHECK-NEXT: let _p1Count: some BinaryInteger = len +// CHECK-NEXT: if p1.count < _p1Count || _p1Count < 0 { +// CHECK-NEXT: fatalError("bounds check failure when calling unsafe function") +// CHECK-NEXT: } +// CHECK-NEXT: let _p2Count: some BinaryInteger = len +// CHECK-NEXT: if p2.count < _p2Count || _p2Count < 0 { +// CHECK-NEXT: fatalError("bounds check failure when calling unsafe function") +// CHECK-NEXT: } +// CHECK-NEXT: return unsafe p2.withUnsafeMutableBufferPointer { _p2Ptr in +// CHECK-NEXT: return unsafe p1.withUnsafeMutableBufferPointer { _p1Ptr in +// CHECK-NEXT: return unsafe shared(len, _p1Ptr.baseAddress!, _p2Ptr.baseAddress!) +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: @_alwaysEmitIntoClient @available(macOS 9999, *) @lifetime(p: copy p) +// CHECK-NEXT: public class func complexExpr(_ len: Int32, _ offset: Int32, _ p: inout MutableSpan) { +// CHECK-NEXT: let _pCount: some BinaryInteger = len - offset +// CHECK-NEXT: if p.count < _pCount || _pCount < 0 { +// CHECK-NEXT: fatalError("bounds check failure when calling unsafe function") +// CHECK-NEXT: } +// CHECK-NEXT: return unsafe p.withUnsafeMutableBufferPointer { _pPtr in +// CHECK-NEXT: return unsafe complexExpr(len, offset, _pPtr.baseAddress!) +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: @_alwaysEmitIntoClient @available(macOS 9999, *) @lifetime(p: copy p) +// CHECK-NEXT: public func complexExpr(_ len: Int32, _ offset: Int32, _ p: inout MutableSpan) { +// CHECK-NEXT: let _pCount: some BinaryInteger = len - offset +// CHECK-NEXT: if p.count < _pCount || _pCount < 0 { +// CHECK-NEXT: fatalError("bounds check failure when calling unsafe function") +// CHECK-NEXT: } +// CHECK-NEXT: return unsafe p.withUnsafeMutableBufferPointer { _pPtr in +// CHECK-NEXT: return unsafe complexExpr(len, offset, _pPtr.baseAddress!) +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: @_alwaysEmitIntoClient @available(macOS 9999, *) @lifetime(p: copy p) +// CHECK-NEXT: public class func nullUnspecified(_ p: inout MutableSpan) { +// CHECK-NEXT: return unsafe p.withUnsafeMutableBufferPointer { _pPtr in +// CHECK-NEXT: return unsafe nullUnspecified(Int32(exactly: _pPtr.count)!, _pPtr.baseAddress!) +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: @_alwaysEmitIntoClient @available(macOS 9999, *) @lifetime(p: copy p) +// CHECK-NEXT: public func nullUnspecified(_ p: inout MutableSpan) { +// CHECK-NEXT: return unsafe p.withUnsafeMutableBufferPointer { _pPtr in +// CHECK-NEXT: return unsafe nullUnspecified(Int32(exactly: _pPtr.count)!, _pPtr.baseAddress!) +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: @_alwaysEmitIntoClient @available(macOS 9999, *) @lifetime(p: copy p) +// CHECK-NEXT: public class func nonnull(_ p: inout MutableSpan) { +// CHECK-NEXT: return unsafe p.withUnsafeMutableBufferPointer { _pPtr in +// CHECK-NEXT: return unsafe nonnull(Int32(exactly: _pPtr.count)!, _pPtr.baseAddress!) +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: @_alwaysEmitIntoClient @available(macOS 9999, *) @lifetime(p: copy p) +// CHECK-NEXT: public func nonnull(_ p: inout MutableSpan) { +// CHECK-NEXT: return unsafe p.withUnsafeMutableBufferPointer { _pPtr in +// CHECK-NEXT: return unsafe nonnull(Int32(exactly: _pPtr.count)!, _pPtr.baseAddress!) +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: @_alwaysEmitIntoClient @available(macOS 9999, *) @lifetime(p: copy p) +// CHECK-NEXT: public class func nullable(_ p: inout MutableSpan?) { +// CHECK-NEXT: return { () in +// CHECK-NEXT: return if p == nil { +// CHECK-NEXT: unsafe nullable(Int32(exactly: p?.count ?? 0)!, nil) +// CHECK-NEXT: } else { +// CHECK-NEXT: unsafe p!.withUnsafeMutableBufferPointer { _pPtr in +// CHECK-NEXT: return unsafe nullable(Int32(exactly: _pPtr.count)!, _pPtr.baseAddress) +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: }() +// CHECK-NEXT: } +// CHECK-NEXT: @_alwaysEmitIntoClient @available(macOS 9999, *) @lifetime(p: copy p) +// CHECK-NEXT: public func nullable(_ p: inout MutableSpan?) { +// CHECK-NEXT: return { () in +// CHECK-NEXT: return if p == nil { +// CHECK-NEXT: unsafe nullable(Int32(exactly: p?.count ?? 0)!, nil) +// CHECK-NEXT: } else { +// CHECK-NEXT: unsafe p!.withUnsafeMutableBufferPointer { _pPtr in +// CHECK-NEXT: return unsafe nullable(Int32(exactly: _pPtr.count)!, _pPtr.baseAddress) +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: }() +// CHECK-NEXT: } +// CHECK-NEXT: @_alwaysEmitIntoClient @available(macOS 9999, *) @lifetime(copy p) @lifetime(p: copy p) +// CHECK-NEXT: public class func returnPointer(_ len: Int32, _ p: inout MutableSpan) -> MutableSpan { +// CHECK-NEXT: return unsafe _swiftifyOverrideLifetime(MutableSpan(_unsafeStart: unsafe p.withUnsafeMutableBufferPointer { _pPtr in +// CHECK-NEXT: return unsafe returnPointer(len, Int32(exactly: _pPtr.count)!, _pPtr.baseAddress!) +// CHECK-NEXT: }, count: Int(len)), copying: ()) +// CHECK-NEXT: } +// CHECK-NEXT: @_alwaysEmitIntoClient @available(macOS 9999, *) @lifetime(copy p) @lifetime(p: copy p) +// CHECK-NEXT: public func returnPointer(_ len: Int32, _ p: inout MutableSpan) -> MutableSpan { +// CHECK-NEXT: return unsafe _swiftifyOverrideLifetime(MutableSpan(_unsafeStart: unsafe p.withUnsafeMutableBufferPointer { _pPtr in +// CHECK-NEXT: return unsafe returnPointer(len, Int32(exactly: _pPtr.count)!, _pPtr.baseAddress!) +// CHECK-NEXT: }, count: Int(len)), copying: ()) +// CHECK-NEXT: } +// CHECK-NEXT: @_alwaysEmitIntoClient @available(macOS 9999, *) @lifetime(p: copy p) +// CHECK-NEXT: public class func staticMethod(_ p: inout MutableSpan) { +// CHECK-NEXT: return unsafe p.withUnsafeMutableBufferPointer { _pPtr in +// CHECK-NEXT: return unsafe staticMethod(Int32(exactly: _pPtr.count)!, _pPtr.baseAddress!) +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: } + +__attribute__((swift_attr("@_SwiftifyImportProtocol(.method(name: \"open func swiftAttr(_ len: Int32, _ p: UnsafeMutablePointer!)\", paramInfo: [.countedBy(pointer: .param(2), count: \"len\"), .nonescaping(pointer: .param(2))]), availability: [\"Span\": \"macOS 9999\", \"MutableSpan\": \"macOS 9999\"])"))) +@interface SwiftAttrClass + - (void)swiftAttr:(int)len :(int *)p; +@end + +// CHECK: extension SwiftAttrClass { +// CHECK-NEXT: @_alwaysEmitIntoClient @available(macOS 9999, *) @lifetime(p: copy p) +// CHECK-NEXT: public func swiftAttr(_ p: inout MutableSpan) { +// CHECK-NEXT: return unsafe p.withUnsafeMutableBufferPointer { _pPtr in +// CHECK-NEXT: return unsafe swiftAttr(Int32(exactly: _pPtr.count)!, _pPtr.baseAddress!) +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: } + +//--- counted-by-class-noescape.swift +import CountedByClassNoescapeClang +import Cxx + +@available(macOS 9999, *) +@lifetime(p1: copy p1) @lifetime(p2: copy p2) +public func call(p1: inout MutableSpan, p2: inout MutableSpan, p3: inout MutableSpan?, x: CInt, y: CInt, a: CountedByClassSpan, b: SwiftAttrClass) { + a.simple(&p1) + a.shared(x, &p1, &p2) + a.complexExpr(x, y, &p1) + a.nullUnspecified(&p1) + a.nonnull(&p1) + a.nullable(&p3) + let r1: MutableSpan = a.returnPointer(x, &p1) + b.swiftAttr(&p1) +} \ No newline at end of file diff --git a/test/Interop/ObjC/swiftify-import/counted-by-in-class.swift b/test/Interop/ObjC/swiftify-import/counted-by-in-class.swift index 5cfa11553be9e..05754faa63b60 100644 --- a/test/Interop/ObjC/swiftify-import/counted-by-in-class.swift +++ b/test/Interop/ObjC/swiftify-import/counted-by-in-class.swift @@ -7,8 +7,11 @@ // REQUIRES: objc_interop -// CHECK: class Foo { -// CHECK: func bar(_ p: UnsafeMutableBufferPointer) +// CHECK: class Foo { +// CHECK-NEXT: class func swiftAttr(_ p: UnsafeMutablePointer!, count len: Int32) +// CHECK-NEXT: @_alwaysEmitIntoClient public func swiftAttr(_ p: UnsafeMutableBufferPointer) +// CHECK-NEXT: func swiftAttr(_ p: UnsafeMutablePointer!, count len: Int32) +// CHECK-NEXT: } //--- Inputs/module.modulemap module Method { @@ -18,12 +21,40 @@ module Method { //--- Inputs/method.h @interface Foo --(void)bar:(float *)p count:(int)len __attribute__((swift_attr("@_SwiftifyImport(.countedBy(pointer: .param(1), count: \"len\"))"))); +-(void)swiftAttr:(float *)p count:(int)len __attribute__((swift_attr("@_SwiftifyImport(.countedBy(pointer: .param(1), count: \"len\"))"))); +@end + +#define __counted_by(x) __attribute__((__counted_by__(x))) +#define __noescape __attribute__((__noescape__)) +#define __lifetimebound __attribute__((__lifetimebound__)) + +@interface Bar + - (void) simple:(int)len :(int * __counted_by(len))p; + - (void) shared:(int)len :(int * __counted_by(len))p1 :(int * __counted_by(len))p2; + - (void) complexExpr:(int)len :(int) offset :(int * __counted_by(len - offset))p; + - (void) nullUnspecified:(int)len :(int * __counted_by(len) _Null_unspecified)p; + - (void) nonnull:(int)len :(int * __counted_by(len) _Nonnull)p; + - (void) nullable:(int)len :(int * __counted_by(len) _Nullable)p; + - (int * __counted_by(len)) returnPointer:(int)len; + + + (void) staticMethod:(int)len :(int * __counted_by(len))p; @end //--- method.swift import Method - -func test(foo: Foo, s: UnsafeMutableBufferPointer) { - foo.bar(s) -} + +func testFoo(foo: Foo, s: UnsafeMutableBufferPointer) { + foo.swiftAttr(s) +} + +public func testBar(p: UnsafeMutableBufferPointer, x: CInt, y: CInt, a: Bar) { + a.simple(p) + a.shared(x, p, p) + a.complexExpr(x, y, p) + a.nullUnspecified(p) + a.nonnull(p) + a.nullable(p) + let _: UnsafeMutableBufferPointer = a.returnPointer(x) + let r = a.returnPointer(x) + let _: UnsafeMutablePointer? = r // make sure the original is the favored overload +} diff --git a/test/Interop/ObjC/swiftify-import/counted-by-protocol-noescape.swift b/test/Interop/ObjC/swiftify-import/counted-by-protocol-noescape.swift new file mode 100644 index 0000000000000..971f018c7a2cd --- /dev/null +++ b/test/Interop/ObjC/swiftify-import/counted-by-protocol-noescape.swift @@ -0,0 +1,138 @@ +// REQUIRES: swift_feature_SafeInteropWrappers +// REQUIRES: swift_feature_LifetimeDependence + +// swift-ide-test doesn't currently trigger extension macro expansion, nor does it typecheck macro expansions, so dump macros with swift-frontend + +// RUN: %empty-directory(%t) +// RUN: split-file %s %t + +// RUN: %target-swift-frontend -emit-module -plugin-path %swift-plugin-dir -o %t/CountedByProtocolSpan.swiftmodule -I %t/Inputs -enable-experimental-feature SafeInteropWrappers -enable-experimental-feature LifetimeDependence %t/counted-by-protocol-noescape.swift -dump-macro-expansions -swift-version 6 2>&1 | %FileCheck %s + +//--- Inputs/module.modulemap +module CountedByProtocolNoescapeClang { + header "counted-by-protocol-noescape.h" + export * +} + +//--- Inputs/counted-by-protocol-noescape.h +#pragma once + +#define __counted_by(x) __attribute__((__counted_by__(x))) +#define __noescape __attribute__((__noescape__)) +#define __lifetimebound __attribute__((__lifetimebound__)) + +__attribute__((swift_attr("@available(SwiftStdlib 6.2, *)"))) +@protocol CountedByProtocolSpan + - (void) simple:(int)len :(int * __counted_by(len) __noescape)p; + - (void) shared:(int)len :(int * __counted_by(len) __noescape)p1 :(int * __counted_by(len) __noescape)p2; + - (void) complexExpr:(int)len :(int) offset :(int * __counted_by(len - offset) __noescape)p; + - (void) nullUnspecified:(int)len :(int * __counted_by(len) _Null_unspecified __noescape)p; + - (void) nonnull:(int)len :(int * __counted_by(len) _Nonnull __noescape)p; + - (void) nullable:(int)len :(int * __counted_by(len) _Nullable __noescape)p; + + - (int * __counted_by(len)) returnPointer:(int)len :(int)len2 :(int * __counted_by(len2) __lifetimebound) p; + + + (void) staticMethod:(int)len :(int * __counted_by(len) __noescape)p; +@end + +// CHECK-LABEL: extension CountedByProtocolSpan { +// CHECK-NEXT: @_alwaysEmitIntoClient @available(macOS 9999, *) @lifetime(p: copy p) +// CHECK-NEXT: public func simple(_ p: inout MutableSpan) { +// CHECK-NEXT: return unsafe p.withUnsafeMutableBufferPointer { _pPtr in +// CHECK-NEXT: return unsafe simple(Int32(exactly: _pPtr.count)!, _pPtr.baseAddress!) +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: @_alwaysEmitIntoClient @available(macOS 9999, *) @lifetime(p1: copy p1) @lifetime(p2: copy p2) +// CHECK-NEXT: public func shared(_ len: Int32, _ p1: inout MutableSpan, _ p2: inout MutableSpan) { +// CHECK-NEXT: let _p1Count: some BinaryInteger = len +// CHECK-NEXT: if p1.count < _p1Count || _p1Count < 0 { +// CHECK-NEXT: fatalError("bounds check failure when calling unsafe function") +// CHECK-NEXT: } +// CHECK-NEXT: let _p2Count: some BinaryInteger = len +// CHECK-NEXT: if p2.count < _p2Count || _p2Count < 0 { +// CHECK-NEXT: fatalError("bounds check failure when calling unsafe function") +// CHECK-NEXT: } +// CHECK-NEXT: return unsafe p2.withUnsafeMutableBufferPointer { _p2Ptr in +// CHECK-NEXT: return unsafe p1.withUnsafeMutableBufferPointer { _p1Ptr in +// CHECK-NEXT: return unsafe shared(len, _p1Ptr.baseAddress!, _p2Ptr.baseAddress!) +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: @_alwaysEmitIntoClient @available(macOS 9999, *) @lifetime(p: copy p) +// CHECK-NEXT: public func complexExpr(_ len: Int32, _ offset: Int32, _ p: inout MutableSpan) { +// CHECK-NEXT: let _pCount: some BinaryInteger = len - offset +// CHECK-NEXT: if p.count < _pCount || _pCount < 0 { +// CHECK-NEXT: fatalError("bounds check failure when calling unsafe function") +// CHECK-NEXT: } +// CHECK-NEXT: return unsafe p.withUnsafeMutableBufferPointer { _pPtr in +// CHECK-NEXT: return unsafe complexExpr(len, offset, _pPtr.baseAddress!) +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: @_alwaysEmitIntoClient @available(macOS 9999, *) @lifetime(p: copy p) +// CHECK-NEXT: public func nullUnspecified(_ p: inout MutableSpan) { +// CHECK-NEXT: return unsafe p.withUnsafeMutableBufferPointer { _pPtr in +// CHECK-NEXT: return unsafe nullUnspecified(Int32(exactly: _pPtr.count)!, _pPtr.baseAddress!) +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: @_alwaysEmitIntoClient @available(macOS 9999, *) @lifetime(p: copy p) +// CHECK-NEXT: public func nonnull(_ p: inout MutableSpan) { +// CHECK-NEXT: return unsafe p.withUnsafeMutableBufferPointer { _pPtr in +// CHECK-NEXT: return unsafe nonnull(Int32(exactly: _pPtr.count)!, _pPtr.baseAddress!) +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: @_alwaysEmitIntoClient @available(macOS 9999, *) @lifetime(p: copy p) +// CHECK-NEXT: public func nullable(_ p: inout MutableSpan?) { +// CHECK-NEXT: return { () in +// CHECK-NEXT: if p == nil { +// CHECK-NEXT: unsafe nullable(Int32(exactly: p?.count ?? 0)!, nil) +// CHECK-NEXT: } else { +// CHECK-NEXT: unsafe p!.withUnsafeMutableBufferPointer { _pPtr in +// CHECK-NEXT: return unsafe nullable(Int32(exactly: _pPtr.count)!, _pPtr.baseAddress) +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: }() +// CHECK-NEXT: } +// CHECK-NEXT: @_alwaysEmitIntoClient @available(macOS 9999, *) @lifetime(copy p) @lifetime(p: copy p) +// CHECK-NEXT: public func returnPointer(_ len: Int32, _ p: inout MutableSpan) -> MutableSpan { +// CHECK-NEXT: return unsafe _swiftifyOverrideLifetime(MutableSpan(_unsafeStart: unsafe p.withUnsafeMutableBufferPointer { _pPtr in +// CHECK-NEXT: return unsafe returnPointer(len, Int32(exactly: _pPtr.count)!, _pPtr.baseAddress!) +// CHECK-NEXT: }, count: Int(len)), copying: ()) +// CHECK-NEXT: } +// CHECK-NEXT: @_alwaysEmitIntoClient @available(macOS 9999, *) @lifetime(p: copy p) +// CHECK-NEXT: public static func staticMethod(_ p: inout MutableSpan) { +// CHECK-NEXT: return unsafe p.withUnsafeMutableBufferPointer { _pPtr in +// CHECK-NEXT: return unsafe staticMethod(Int32(exactly: _pPtr.count)!, _pPtr.baseAddress!) +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: } + +__attribute__((swift_attr("@_SwiftifyImportProtocol(.method(name: \"func swiftAttr(_ len: Int32, _ p: UnsafeMutablePointer!)\", paramInfo: [.countedBy(pointer: .param(2), count: \"len\"), .nonescaping(pointer: .param(2))]), availability: [\"Span\": \"macOS 9999\", \"MutableSpan\": \"macOS 9999\"])"))) +@protocol SwiftAttrProtocol + - (void)swiftAttr:(int)len :(int *)p; +@end + +// CHECK-LABEL: extension SwiftAttrProtocol { +// CHECK-NEXT: @_alwaysEmitIntoClient @available(macOS 9999, *) @lifetime(p: copy p) +// CHECK-NEXT: public func swiftAttr(_ p: inout MutableSpan) { +// CHECK-NEXT: return unsafe p.withUnsafeMutableBufferPointer { _pPtr in +// CHECK-NEXT: return unsafe swiftAttr(Int32(exactly: _pPtr.count)!, _pPtr.baseAddress!) +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: } + +//--- counted-by-protocol-noescape.swift +import CountedByProtocolNoescapeClang +import Cxx + +@available(macOS 9999, *) +@lifetime(p1: copy p1) @lifetime(p2: copy p2) +public func call(p1: inout MutableSpan, p2: inout MutableSpan, p3: inout MutableSpan?, x: CInt, y: CInt, a: CountedByProtocolSpan, b: SwiftAttrProtocol) { + a.simple(&p1) + a.shared(x, &p1, &p2) + a.complexExpr(x, y, &p1) + a.nullUnspecified(&p1) + a.nonnull(&p1) + a.nullable(&p3) + let r1: MutableSpan = a.returnPointer(x, &p1) + b.swiftAttr(&p1) +} diff --git a/test/Interop/ObjC/swiftify-import/counted-by-protocol.swift b/test/Interop/ObjC/swiftify-import/counted-by-protocol.swift new file mode 100644 index 0000000000000..723db7decb605 --- /dev/null +++ b/test/Interop/ObjC/swiftify-import/counted-by-protocol.swift @@ -0,0 +1,107 @@ +// REQUIRES: swift_feature_SafeInteropWrappers + +// swift-ide-test doesn't currently trigger extension macro expansion, nor does it typecheck macro expansions, so dump macros with swift-frontend + +// RUN: %empty-directory(%t) +// RUN: split-file %s %t + +// RUN: %target-swift-frontend -emit-module -plugin-path %swift-plugin-dir -o %t/CountedByProtocol.swiftmodule -I %t/Inputs -enable-experimental-feature SafeInteropWrappers %t/counted-by-protocol.swift -dump-macro-expansions 2>&1 | %FileCheck %s + +//--- Inputs/module.modulemap +module CountedByProtocolClang { + header "counted-by-protocol.h" + export * +} + +//--- Inputs/counted-by-protocol.h +#pragma once + +#define __counted_by(x) __attribute__((__counted_by__(x))) + +@protocol CountedByProtocol + - (void) simple:(int)len :(int * __counted_by(len))p; + - (void) shared:(int)len :(int * __counted_by(len))p1 :(int * __counted_by(len))p2; + - (void) complexExpr:(int)len :(int) offset :(int * __counted_by(len - offset))p; + - (void) nullUnspecified:(int)len :(int * __counted_by(len) _Null_unspecified)p; + - (void) nonnull:(int)len :(int * __counted_by(len) _Nonnull)p; + - (void) nullable:(int)len :(int * __counted_by(len) _Nullable)p; + - (int * __counted_by(len)) returnPointer:(int)len; + + + (void) staticMethod:(int)len :(int * __counted_by(len))p; +@end + +// CHECK-LABEL: extension CountedByProtocol { +// CHECK-NEXT: @_alwaysEmitIntoClient +// CHECK-NEXT: public func simple(_ p: UnsafeMutableBufferPointer) { +// CHECK-NEXT: return unsafe simple(Int{{.*}}(exactly: p.count)!, p.baseAddress!) +// CHECK-NEXT: } +// CHECK-NEXT: @_alwaysEmitIntoClient +// CHECK-NEXT: public func shared(_ len: Int{{.*}}, _ p1: UnsafeMutableBufferPointer, _ p2: UnsafeMutableBufferPointer) { +// CHECK-NEXT: let _p1Count: some BinaryInteger = len +// CHECK-NEXT: if p1.count < _p1Count || _p1Count < 0 { +// CHECK-NEXT: fatalError("bounds check failure when calling unsafe function") +// CHECK-NEXT: } +// CHECK-NEXT: let _p2Count: some BinaryInteger = len +// CHECK-NEXT: if p2.count < _p2Count || _p2Count < 0 { +// CHECK-NEXT: fatalError("bounds check failure when calling unsafe function") +// CHECK-NEXT: } +// CHECK-NEXT: return unsafe shared(len, p1.baseAddress!, p2.baseAddress!) +// CHECK-NEXT: } +// CHECK-NEXT: @_alwaysEmitIntoClient +// CHECK-NEXT: public func complexExpr(_ len: Int{{.*}}, _ offset: Int{{.*}}, _ p: UnsafeMutableBufferPointer) { +// CHECK-NEXT: let _pCount: some BinaryInteger = len - offset +// CHECK-NEXT: if p.count < _pCount || _pCount < 0 { +// CHECK-NEXT: fatalError("bounds check failure when calling unsafe function") +// CHECK-NEXT: } +// CHECK-NEXT: return unsafe complexExpr(len, offset, p.baseAddress!) +// CHECK-NEXT: } +// CHECK-NEXT: @_alwaysEmitIntoClient +// CHECK-NEXT: public func nullUnspecified(_ p: UnsafeMutableBufferPointer) { +// CHECK-NEXT: return unsafe nullUnspecified(Int{{.*}}(exactly: p.count)!, p.baseAddress!) +// CHECK-NEXT: } +// CHECK-NEXT: @_alwaysEmitIntoClient +// CHECK-NEXT: public func nonnull(_ p: UnsafeMutableBufferPointer) { +// CHECK-NEXT: return unsafe nonnull(Int{{.*}}(exactly: p.count)!, p.baseAddress!) +// CHECK-NEXT: } +// CHECK-NEXT: @_alwaysEmitIntoClient +// CHECK-NEXT: public func nullable(_ p: UnsafeMutableBufferPointer?) { +// CHECK-NEXT: return unsafe nullable(Int{{.*}}(exactly: p?.count ?? 0)!, p?.baseAddress) +// CHECK-NEXT: } +// CHECK-NEXT: @_alwaysEmitIntoClient @_disfavoredOverload +// CHECK-NEXT: public func returnPointer(_ len: Int{{.*}}) -> UnsafeMutableBufferPointer { +// CHECK-NEXT: return unsafe UnsafeMutableBufferPointer(start: unsafe returnPointer(len), count: Int(len)) +// CHECK-NEXT: } +// CHECK-NEXT: @_alwaysEmitIntoClient +// CHECK-NEXT: public static func staticMethod(_ p: UnsafeMutableBufferPointer) { +// CHECK-NEXT: return unsafe staticMethod(Int{{.*}}(exactly: p.count)!, p.baseAddress!) +// CHECK-NEXT: } +// CHECK-NEXT: } + +__attribute__((swift_attr("@_SwiftifyImportProtocol(.method(name: \"func swiftAttr(_ len: Int32, _ p: UnsafeMutablePointer!)\", paramInfo: [.countedBy(pointer: .param(2), count: \"len\")]))"))) +@protocol SwiftAttrProtocol + - (void)swiftAttr:(int)len :(int *)p; +@end + +// CHECK-LABEL: extension SwiftAttrProtocol { +// CHECK-NEXT: @_alwaysEmitIntoClient +// CHECK-NEXT: public func swiftAttr(_ p: UnsafeMutableBufferPointer) { +// CHECK-NEXT: return unsafe swiftAttr(Int32(exactly: p.count)!, p.baseAddress!) +// CHECK-NEXT: } +// CHECK-NEXT: } + +//--- counted-by-protocol.swift +import CountedByProtocolClang + +@inlinable +public func call(p: UnsafeMutableBufferPointer, x: CInt, y: CInt, a: CountedByProtocol, b: SwiftAttrProtocol) { + a.simple(p) + a.shared(x, p, p) + a.complexExpr(x, y, p) + a.nullUnspecified(p) + a.nonnull(p) + a.nullable(p) + let r1: UnsafeMutableBufferPointer = a.returnPointer(x) + let r2 = a.returnPointer(x) + let r3: UnsafeMutablePointer? = r2 // make sure the original is the favored overload + b.swiftAttr(p) +} diff --git a/test/Macros/SwiftifyImport/CountedBy/CountExpr.swift b/test/Macros/SwiftifyImport/CountedBy/CountExpr.swift index 92fe4889bdad1..8e6983645d0a1 100644 --- a/test/Macros/SwiftifyImport/CountedBy/CountExpr.swift +++ b/test/Macros/SwiftifyImport/CountedBy/CountExpr.swift @@ -7,7 +7,7 @@ func myFunc(_ ptr: UnsafePointer, _ size: CInt, _ count: CInt) { } // CHECK: @_alwaysEmitIntoClient -// CHECK-NEXT: func myFunc(_ ptr: UnsafeBufferPointer, _ size: CInt, _ count: CInt) { +// CHECK-NEXT: public func myFunc(_ ptr: UnsafeBufferPointer, _ size: CInt, _ count: CInt) { // CHECK-NEXT: let _ptrCount: some BinaryInteger = size * count // CHECK-NEXT: if ptr.count < _ptrCount || _ptrCount < 0 { // CHECK-NEXT: fatalError("bounds check failure when calling unsafe function") diff --git a/test/Macros/SwiftifyImport/CountedBy/MultipleParams.swift b/test/Macros/SwiftifyImport/CountedBy/MultipleParams.swift index 6ad7bf0cc7824..1c8a609fb41ca 100644 --- a/test/Macros/SwiftifyImport/CountedBy/MultipleParams.swift +++ b/test/Macros/SwiftifyImport/CountedBy/MultipleParams.swift @@ -7,6 +7,6 @@ func myFunc(_ ptr: UnsafePointer, _ len: CInt, _ ptr2: UnsafePointer } // CHECK: @_alwaysEmitIntoClient -// CHECK-NEXT: func myFunc(_ ptr: UnsafeBufferPointer, _ ptr2: UnsafeBufferPointer) { +// CHECK-NEXT: public func myFunc(_ ptr: UnsafeBufferPointer, _ ptr2: UnsafeBufferPointer) { // CHECK-NEXT: return unsafe myFunc(ptr.baseAddress!, CInt(exactly: ptr.count)!, ptr2.baseAddress!, CInt(exactly: ptr2.count)!) // CHECK-NEXT: } diff --git a/test/Macros/SwiftifyImport/CountedBy/Mutable.swift b/test/Macros/SwiftifyImport/CountedBy/Mutable.swift index 1df1df1329115..487c08101fb8d 100644 --- a/test/Macros/SwiftifyImport/CountedBy/Mutable.swift +++ b/test/Macros/SwiftifyImport/CountedBy/Mutable.swift @@ -7,7 +7,7 @@ func myFunc(_ ptr: UnsafeMutablePointer, _ len: CInt) { } // CHECK: @_alwaysEmitIntoClient -// CHECK-NEXT: func myFunc(_ ptr: UnsafeMutableBufferPointer) { +// CHECK-NEXT: public func myFunc(_ ptr: UnsafeMutableBufferPointer) { // CHECK-NEXT: return unsafe myFunc(ptr.baseAddress!, CInt(exactly: ptr.count)!) // CHECK-NEXT: } diff --git a/test/Macros/SwiftifyImport/CountedBy/MutableSpan.swift b/test/Macros/SwiftifyImport/CountedBy/MutableSpan.swift index e03ccbcb7653b..97c305ea3c3e4 100644 --- a/test/Macros/SwiftifyImport/CountedBy/MutableSpan.swift +++ b/test/Macros/SwiftifyImport/CountedBy/MutableSpan.swift @@ -8,8 +8,8 @@ func myFunc(_ ptr: UnsafeMutablePointer, _ len: CInt) { } // CHECK: @_alwaysEmitIntoClient @lifetime(ptr: copy ptr) -// CHECK-NEXT: func myFunc(_ ptr: inout MutableSpan) { +// CHECK-NEXT: public func myFunc(_ ptr: inout MutableSpan) { // CHECK-NEXT: return unsafe ptr.withUnsafeMutableBufferPointer { _ptrPtr in -// CHECK-NEXT: return unsafe myFunc(_ptrPtr.baseAddress!, CInt(exactly: ptr.count)!) +// CHECK-NEXT: return unsafe myFunc(_ptrPtr.baseAddress!, CInt(exactly: _ptrPtr.count)!) // CHECK-NEXT: } // CHECK-NEXT: } diff --git a/test/Macros/SwiftifyImport/CountedBy/NamedParams.swift b/test/Macros/SwiftifyImport/CountedBy/NamedParams.swift index 6e450b8afa124..645e4a04a56d9 100644 --- a/test/Macros/SwiftifyImport/CountedBy/NamedParams.swift +++ b/test/Macros/SwiftifyImport/CountedBy/NamedParams.swift @@ -27,32 +27,32 @@ func allNamedOther(buf ptr: UnsafePointer, count len: CInt) { } // CHECK: @_alwaysEmitIntoClient -// CHECK-NEXT: func ptrNamed(ptr: UnsafeBufferPointer) { +// CHECK-NEXT: public func ptrNamed(ptr: UnsafeBufferPointer) { // CHECK-NEXT: return unsafe ptrNamed(ptr: ptr.baseAddress!, CInt(exactly: ptr.count)!) // CHECK-NEXT: } // CHECK: @_alwaysEmitIntoClient -// CHECK-NEXT: func ptrNamedOther(buf ptr: UnsafeBufferPointer) { +// CHECK-NEXT: public func ptrNamedOther(buf ptr: UnsafeBufferPointer) { // CHECK-NEXT: return unsafe ptrNamedOther(buf: ptr.baseAddress!, CInt(exactly: ptr.count)!) // CHECK-NEXT: } // CHECK: @_alwaysEmitIntoClient -// CHECK-NEXT: func lenNamed(_ ptr: UnsafeBufferPointer) { +// CHECK-NEXT: public func lenNamed(_ ptr: UnsafeBufferPointer) { // CHECK-NEXT: return unsafe lenNamed(ptr.baseAddress!, len: CInt(exactly: ptr.count)!) // CHECK-NEXT: } // CHECK: @_alwaysEmitIntoClient -// CHECK-NEXT: func lenNamedOther(_ ptr: UnsafeBufferPointer) { +// CHECK-NEXT: public func lenNamedOther(_ ptr: UnsafeBufferPointer) { // CHECK-NEXT: return unsafe lenNamedOther(ptr.baseAddress!, count: CInt(exactly: ptr.count)!) // CHECK-NEXT: } // CHECK: @_alwaysEmitIntoClient -// CHECK-NEXT: func allNamed(ptr: UnsafeBufferPointer) { +// CHECK-NEXT: public func allNamed(ptr: UnsafeBufferPointer) { // CHECK-NEXT: return unsafe allNamed(ptr: ptr.baseAddress!, len: CInt(exactly: ptr.count)!) // CHECK-NEXT: } // CHECK: @_alwaysEmitIntoClient -// CHECK-NEXT: func allNamedOther(buf ptr: UnsafeBufferPointer) { +// CHECK-NEXT: public func allNamedOther(buf ptr: UnsafeBufferPointer) { // CHECK-NEXT: return unsafe allNamedOther(buf: ptr.baseAddress!, count: CInt(exactly: ptr.count)!) // CHECK-NEXT: } diff --git a/test/Macros/SwiftifyImport/CountedBy/Nullable.swift b/test/Macros/SwiftifyImport/CountedBy/Nullable.swift index b0f3f2c926abe..9f79f3f859bd5 100644 --- a/test/Macros/SwiftifyImport/CountedBy/Nullable.swift +++ b/test/Macros/SwiftifyImport/CountedBy/Nullable.swift @@ -19,25 +19,25 @@ func myFunc4(_ ptr: UnsafeMutablePointer?, _ len: CInt) -> UnsafeMutablePo } // CHECK: @_alwaysEmitIntoClient -// CHECK-NEXT: func myFunc(_ ptr: UnsafeBufferPointer?) { +// CHECK-NEXT: public func myFunc(_ ptr: UnsafeBufferPointer?) { // CHECK-NEXT: return unsafe myFunc(ptr?.baseAddress, CInt(exactly: ptr?.count ?? 0)!) // CHECK-NEXT: } // CHECK: @_alwaysEmitIntoClient @lifetime(ptr: copy ptr) -// CHECK-NEXT: func myFunc2(_ ptr: inout MutableSpan?) { +// CHECK-NEXT: public func myFunc2(_ ptr: inout MutableSpan?) { // CHECK-NEXT: return { () in // CHECK-NEXT: return if ptr == nil { // CHECK-NEXT: unsafe myFunc2(nil, CInt(exactly: ptr?.count ?? 0)!) // CHECK-NEXT: } else { // CHECK-NEXT: unsafe ptr!.withUnsafeMutableBufferPointer { _ptrPtr in -// CHECK-NEXT: return unsafe myFunc2(_ptrPtr.baseAddress, CInt(exactly: ptr?.count ?? 0)!) +// CHECK-NEXT: return unsafe myFunc2(_ptrPtr.baseAddress, CInt(exactly: _ptrPtr.count)!) // CHECK-NEXT: } // CHECK-NEXT: } // CHECK-NEXT: }() // CHECK-NEXT: } // CHECK: @_alwaysEmitIntoClient @lifetime(ptr: copy ptr) @lifetime(ptr2: copy ptr2) -// CHECK-NEXT: func myFunc3(_ ptr: inout MutableSpan?, _ ptr2: inout MutableSpan?) { +// CHECK-NEXT: public func myFunc3(_ ptr: inout MutableSpan?, _ ptr2: inout MutableSpan?) { // CHECK-NEXT: return { () in // CHECK-NEXT: return if ptr2 == nil { // CHECK-NEXT: { () in @@ -45,7 +45,7 @@ func myFunc4(_ ptr: UnsafeMutablePointer?, _ len: CInt) -> UnsafeMutablePo // CHECK-NEXT: unsafe myFunc3(nil, CInt(exactly: ptr?.count ?? 0)!, nil, CInt(exactly: ptr2?.count ?? 0)!) // CHECK-NEXT: } else { // CHECK-NEXT: unsafe ptr!.withUnsafeMutableBufferPointer { _ptrPtr in -// CHECK-NEXT: return unsafe myFunc3(_ptrPtr.baseAddress, CInt(exactly: ptr?.count ?? 0)!, nil, CInt(exactly: ptr2?.count ?? 0)!) +// CHECK-NEXT: return unsafe myFunc3(_ptrPtr.baseAddress, CInt(exactly: _ptrPtr.count)!, nil, CInt(exactly: ptr2?.count ?? 0)!) // CHECK-NEXT: } // CHECK-NEXT: } // CHECK-NEXT: }() @@ -53,10 +53,10 @@ func myFunc4(_ ptr: UnsafeMutablePointer?, _ len: CInt) -> UnsafeMutablePo // CHECK-NEXT: unsafe ptr2!.withUnsafeMutableBufferPointer { _ptr2Ptr in // CHECK-NEXT: return { () in // CHECK-NEXT: return if ptr == nil { -// CHECK-NEXT: unsafe myFunc3(nil, CInt(exactly: ptr?.count ?? 0)!, _ptr2Ptr.baseAddress, CInt(exactly: ptr2?.count ?? 0)!) +// CHECK-NEXT: unsafe myFunc3(nil, CInt(exactly: ptr?.count ?? 0)!, _ptr2Ptr.baseAddress, CInt(exactly: _ptr2Ptr.count)!) // CHECK-NEXT: } else { // CHECK-NEXT: unsafe ptr!.withUnsafeMutableBufferPointer { _ptrPtr in -// CHECK-NEXT: return unsafe myFunc3(_ptrPtr.baseAddress, CInt(exactly: ptr?.count ?? 0)!, _ptr2Ptr.baseAddress, CInt(exactly: ptr2?.count ?? 0)!) +// CHECK-NEXT: return unsafe myFunc3(_ptrPtr.baseAddress, CInt(exactly: _ptrPtr.count)!, _ptr2Ptr.baseAddress, CInt(exactly: _ptr2Ptr.count)!) // CHECK-NEXT: } // CHECK-NEXT: } // CHECK-NEXT: }() @@ -66,7 +66,7 @@ func myFunc4(_ ptr: UnsafeMutablePointer?, _ len: CInt) -> UnsafeMutablePo // CHECK-NEXT: } // CHECK: @_alwaysEmitIntoClient @lifetime(copy ptr) @lifetime(ptr: copy ptr) -// CHECK-NEXT: func myFunc4(_ ptr: inout MutableSpan?, _ len: CInt) -> MutableSpan? { +// CHECK-NEXT: public func myFunc4(_ ptr: inout MutableSpan?, _ len: CInt) -> MutableSpan? { // CHECK-NEXT: let _ptrCount: some BinaryInteger = len // CHECK-NEXT: if ptr?.count ?? 0 < _ptrCount || _ptrCount < 0 { // CHECK-NEXT: fatalError("bounds check failure when calling unsafe function") diff --git a/test/Macros/SwiftifyImport/CountedBy/PointerReturn.swift b/test/Macros/SwiftifyImport/CountedBy/PointerReturn.swift index d1de7eeadd18c..fcd63d46e306a 100644 --- a/test/Macros/SwiftifyImport/CountedBy/PointerReturn.swift +++ b/test/Macros/SwiftifyImport/CountedBy/PointerReturn.swift @@ -20,23 +20,23 @@ func lifetimeDependentBorrow(_ p: borrowing UnsafePointer, _ len1: CInt, _ } // CHECK: @_alwaysEmitIntoClient @_disfavoredOverload -// CHECK-NEXT: func myFunc(_ len: CInt) -> UnsafeMutableBufferPointer { +// CHECK-NEXT: public func myFunc(_ len: CInt) -> UnsafeMutableBufferPointer { // CHECK-NEXT: return unsafe UnsafeMutableBufferPointer (start: unsafe myFunc(len), count: Int(len)) // CHECK-NEXT: } // CHECK: @_alwaysEmitIntoClient @_disfavoredOverload -// CHECK-NEXT: func nonEscaping(_ len: CInt) -> UnsafeBufferPointer { +// CHECK-NEXT: public func nonEscaping(_ len: CInt) -> UnsafeBufferPointer { // CHECK-NEXT: return unsafe UnsafeBufferPointer (start: unsafe nonEscaping(len), count: Int(len)) // CHECK: @_alwaysEmitIntoClient @lifetime(copy p) -// CHECK-NEXT: func lifetimeDependentCopy(_ p: Span, _ len2: CInt) -> Span { -// CHECK-NEXT: return unsafe Span (_unsafeStart: unsafe p.withUnsafeBufferPointer { _pPtr in -// CHECK-NEXT: return unsafe lifetimeDependentCopy(_pPtr.baseAddress!, CInt(exactly: p.count)!, len2) -// CHECK-NEXT: }, count: Int(len2)) +// CHECK-NEXT: public func lifetimeDependentCopy(_ p: Span, _ len2: CInt) -> Span { +// CHECK-NEXT: return unsafe _swiftifyOverrideLifetime(Span (_unsafeStart: unsafe p.withUnsafeBufferPointer { _pPtr in +// CHECK-NEXT: return unsafe lifetimeDependentCopy(_pPtr.baseAddress!, CInt(exactly: _pPtr.count)!, len2) +// CHECK-NEXT: }, count: Int(len2)), copying: ()) // CHECK-NEXT: } // CHECK: @_alwaysEmitIntoClient @lifetime(borrow p) -// CHECK-NEXT: func lifetimeDependentBorrow(_ p: borrowing UnsafeBufferPointer, _ len2: CInt) -> Span { -// CHECK-NEXT: return unsafe Span (_unsafeStart: unsafe lifetimeDependentBorrow(p.baseAddress!, CInt(exactly: p.count)!, len2), count: Int(len2)) +// CHECK-NEXT: public func lifetimeDependentBorrow(_ p: borrowing UnsafeBufferPointer, _ len2: CInt) -> Span { +// CHECK-NEXT: return unsafe _swiftifyOverrideLifetime(Span (_unsafeStart: unsafe lifetimeDependentBorrow(p.baseAddress!, CInt(exactly: p.count)!, len2), count: Int(len2)), copying: ()) // CHECK-NEXT: } diff --git a/test/Macros/SwiftifyImport/CountedBy/Protocol.swift b/test/Macros/SwiftifyImport/CountedBy/Protocol.swift new file mode 100644 index 0000000000000..4c712ee77ea5a --- /dev/null +++ b/test/Macros/SwiftifyImport/CountedBy/Protocol.swift @@ -0,0 +1,87 @@ +// REQUIRES: swift_swift_parser + +// RUN: %target-swift-frontend %s -swift-version 5 -module-name main -disable-availability-checking -typecheck -plugin-path %swift-plugin-dir -dump-macro-expansions -enable-experimental-feature Span -enable-experimental-feature LifetimeDependence 2>&1 | %FileCheck --match-full-lines %s + +@_SwiftifyImportProtocol(.method(signature: "func myFunc(_ ptr: UnsafePointer, _ len: CInt)", paramInfo: [.countedBy(pointer: .param(1), count: "len")])) +protocol SimpleProtocol { + func myFunc(_ ptr: UnsafePointer, _ len: CInt) +} + +// CHECK: extension SimpleProtocol { +// CHECK-NEXT: @_alwaysEmitIntoClient +// CHECK-NEXT: public func myFunc(_ ptr: UnsafeBufferPointer) { +// CHECK-NEXT: return unsafe myFunc(ptr.baseAddress!, CInt(exactly: ptr.count)!) +// CHECK-NEXT: } +// CHECK-NEXT: } + +@_SwiftifyImportProtocol(.method(signature: "func foo(_ ptr: UnsafePointer, _ len: CInt)", paramInfo: [.countedBy(pointer: .param(1), count: "len"), .nonescaping(pointer: .param(1))]), + .method(signature: "func bar(_ len: CInt) -> UnsafePointer", paramInfo: [.countedBy(pointer: .return, count: "len"), .nonescaping(pointer: .return), .lifetimeDependence(dependsOn: .self, pointer: .return, type: .borrow)])) +protocol SpanProtocol { + func foo(_ ptr: UnsafePointer, _ len: CInt) + func bar(_ len: CInt) -> UnsafePointer +} + +// CHECK: extension SpanProtocol { +// CHECK-NEXT: @_alwaysEmitIntoClient +// CHECK-NEXT: public func foo(_ ptr: Span) { +// CHECK-NEXT: return unsafe ptr.withUnsafeBufferPointer { _ptrPtr in +// CHECK-NEXT: return unsafe foo(_ptrPtr.baseAddress!, CInt(exactly: _ptrPtr.count)!) +// CHECK-NEXT: } +// CHECK-NEXT: } + +// CHECK-NEXT: @_alwaysEmitIntoClient @lifetime(borrow self) @_disfavoredOverload +// CHECK-NEXT: public func bar(_ len: CInt) -> Span { +// CHECK-NEXT: return unsafe _swiftifyOverrideLifetime(Span(_unsafeStart: unsafe bar(len), count: Int(len)), copying: ()) +// CHECK-NEXT: } +// CHECK-NEXT: } + +@_SwiftifyImportProtocol(.method(signature: "func foo(_ ptr: UnsafePointer, _ len: CInt)", paramInfo: [.countedBy(pointer: .param(1), count: "len"), .nonescaping(pointer: .param(1))]), + .method(signature: "func bar(_ ptr: UnsafePointer, _ len: CInt)", paramInfo: [.countedBy(pointer: .param(1), count: "len")])) +protocol MixedProtocol { + func foo(_ ptr: UnsafePointer, _ len: CInt) + func bar(_ ptr: UnsafePointer, _ len: CInt) +} + +// CHECK: extension MixedProtocol { +// CHECK-NEXT: @_alwaysEmitIntoClient +// CHECK-NEXT: public func foo(_ ptr: Span) { +// CHECK-NEXT: return unsafe ptr.withUnsafeBufferPointer { _ptrPtr in +// CHECK-NEXT: return unsafe foo(_ptrPtr.baseAddress!, CInt(exactly: _ptrPtr.count)!) +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: @_alwaysEmitIntoClient +// CHECK-NEXT: public func bar(_ ptr: UnsafeBufferPointer) { +// CHECK-NEXT: return unsafe bar(ptr.baseAddress!, CInt(exactly: ptr.count)!) +// CHECK-NEXT: } +// CHECK-NEXT: } + +@_SwiftifyImportProtocol(.method(signature: "func foo(_ ptr: UnsafePointer, _ len1: CInt)", paramInfo: [.countedBy(pointer: .param(1), count: "len1")]), + .method(signature: "func foo(bar: UnsafePointer, _ len2: CInt)", paramInfo: [.countedBy(pointer: .param(1), count: "len2")])) +protocol OverloadedProtocol { + func foo(_ ptr: UnsafePointer, _ len1: CInt) + func foo(bar: UnsafePointer, _ len2: CInt) + func foo() +} + +// CHECK: extension OverloadedProtocol { +// CHECK-NEXT: @_alwaysEmitIntoClient +// CHECK-NEXT: public func foo(_ ptr: UnsafeBufferPointer) { +// CHECK-NEXT: return unsafe foo(ptr.baseAddress!, CInt(exactly: ptr.count)!) +// CHECK-NEXT: } +// CHECK-NEXT: @_alwaysEmitIntoClient +// CHECK-NEXT: public func foo(bar: UnsafeBufferPointer) { +// CHECK-NEXT: return unsafe foo(bar: bar.baseAddress!, CInt(exactly: bar.count)!) +// CHECK-NEXT: } +// CHECK-NEXT: } + +@_SwiftifyImportProtocol(.method(signature: "open func myFunc(_ ptr: UnsafePointer, _ len: CInt)", paramInfo: [.countedBy(pointer: .param(1), count: "len")])) +class SimpleClass { + open func myFunc(_ ptr: UnsafePointer, _ len: CInt) {} +} + +// CHECK: extension SimpleClass { +// CHECK-NEXT: @_alwaysEmitIntoClient +// CHECK-NEXT: public func myFunc(_ ptr: UnsafeBufferPointer) { +// CHECK-NEXT: return unsafe myFunc(ptr.baseAddress!, CInt(exactly: ptr.count)!) +// CHECK-NEXT: } +// CHECK-NEXT: } diff --git a/test/Macros/SwiftifyImport/CountedBy/QualifiedTypes.swift b/test/Macros/SwiftifyImport/CountedBy/QualifiedTypes.swift index 3a7139e92f133..7577b2cd56f85 100644 --- a/test/Macros/SwiftifyImport/CountedBy/QualifiedTypes.swift +++ b/test/Macros/SwiftifyImport/CountedBy/QualifiedTypes.swift @@ -11,12 +11,12 @@ func bar(_ ptr: Swift.UnsafePointer, _ len: Swift.Int) -> () { } // CHECK: @_alwaysEmitIntoClient -// CHECK-NEXT: func foo(_ ptr: Swift.UnsafeBufferPointer) -> Swift.Void { +// CHECK-NEXT: public func foo(_ ptr: Swift.UnsafeBufferPointer) -> Swift.Void { // CHECK-NEXT: return unsafe foo(ptr.baseAddress!, ptr.count) // CHECK-NEXT: } // CHECK: @_alwaysEmitIntoClient -// CHECK-NEXT: func bar(_ ptr: Swift.UnsafeBufferPointer) -> () { +// CHECK-NEXT: public func bar(_ ptr: Swift.UnsafeBufferPointer) -> () { // CHECK-NEXT: return unsafe bar(ptr.baseAddress!, ptr.count) // CHECK-NEXT: } diff --git a/test/Macros/SwiftifyImport/CountedBy/Return.swift b/test/Macros/SwiftifyImport/CountedBy/Return.swift index ceebe3e43ac81..9c36b472942c4 100644 --- a/test/Macros/SwiftifyImport/CountedBy/Return.swift +++ b/test/Macros/SwiftifyImport/CountedBy/Return.swift @@ -7,6 +7,6 @@ func myFunc(_ ptr: UnsafePointer, _ len: CInt) -> CInt { } // CHECK: @_alwaysEmitIntoClient -// CHECK-NEXT: func myFunc(_ ptr: UnsafeBufferPointer) -> CInt { +// CHECK-NEXT: public func myFunc(_ ptr: UnsafeBufferPointer) -> CInt { // CHECK-NEXT: return unsafe myFunc(ptr.baseAddress!, CInt(exactly: ptr.count)!) // CHECK-NEXT: } diff --git a/test/Macros/SwiftifyImport/CountedBy/SharedCount.swift b/test/Macros/SwiftifyImport/CountedBy/SharedCount.swift index 71a084acb6f71..fdd70c5777a0b 100644 --- a/test/Macros/SwiftifyImport/CountedBy/SharedCount.swift +++ b/test/Macros/SwiftifyImport/CountedBy/SharedCount.swift @@ -7,7 +7,7 @@ func myFunc(_ ptr: UnsafePointer, _ ptr2: UnsafePointer, _ len: CInt } // CHECK: @_alwaysEmitIntoClient -// CHECK-NEXT: func myFunc(_ ptr: UnsafeBufferPointer, _ ptr2: UnsafeBufferPointer, _ len: CInt) { +// CHECK-NEXT: public func myFunc(_ ptr: UnsafeBufferPointer, _ ptr2: UnsafeBufferPointer, _ len: CInt) { // CHECK-NEXT: let _ptrCount: some BinaryInteger = len // CHECK-NEXT: if ptr.count < _ptrCount || _ptrCount < 0 { // CHECK-NEXT: fatalError("bounds check failure when calling unsafe function") diff --git a/test/Macros/SwiftifyImport/CountedBy/SimpleCount.swift b/test/Macros/SwiftifyImport/CountedBy/SimpleCount.swift index 3f252815fc557..b90dc336c1290 100644 --- a/test/Macros/SwiftifyImport/CountedBy/SimpleCount.swift +++ b/test/Macros/SwiftifyImport/CountedBy/SimpleCount.swift @@ -7,6 +7,6 @@ func myFunc(_ ptr: UnsafePointer, _ len: CInt) { } // CHECK: @_alwaysEmitIntoClient -// CHECK-NEXT: func myFunc(_ ptr: UnsafeBufferPointer) { +// CHECK-NEXT: public func myFunc(_ ptr: UnsafeBufferPointer) { // CHECK-NEXT: return unsafe myFunc(ptr.baseAddress!, CInt(exactly: ptr.count)!) // CHECK-NEXT: } diff --git a/test/Macros/SwiftifyImport/CountedBy/SimpleSpan.swift b/test/Macros/SwiftifyImport/CountedBy/SimpleSpan.swift index 69de53f1d9cf6..28a74b4a377f4 100644 --- a/test/Macros/SwiftifyImport/CountedBy/SimpleSpan.swift +++ b/test/Macros/SwiftifyImport/CountedBy/SimpleSpan.swift @@ -8,8 +8,8 @@ func myFunc(_ ptr: UnsafePointer, _ len: CInt) { } // CHECK: @_alwaysEmitIntoClient -// CHECK-NEXT: func myFunc(_ ptr: Span) { +// CHECK-NEXT: public func myFunc(_ ptr: Span) { // CHECK-NEXT: return unsafe ptr.withUnsafeBufferPointer { _ptrPtr in -// CHECK-NEXT: return unsafe myFunc(_ptrPtr.baseAddress!, CInt(exactly: ptr.count)!) +// CHECK-NEXT: return unsafe myFunc(_ptrPtr.baseAddress!, CInt(exactly: _ptrPtr.count)!) // CHECK-NEXT: } // CHECK-NEXT: } diff --git a/test/Macros/SwiftifyImport/CountedBy/SimpleSpanWithReturn.swift b/test/Macros/SwiftifyImport/CountedBy/SimpleSpanWithReturn.swift index 28f60f4971371..9de243ac471bf 100644 --- a/test/Macros/SwiftifyImport/CountedBy/SimpleSpanWithReturn.swift +++ b/test/Macros/SwiftifyImport/CountedBy/SimpleSpanWithReturn.swift @@ -8,8 +8,8 @@ func myFunc(_ ptr: UnsafePointer, _ len: CInt) -> CInt { } // CHECK: @_alwaysEmitIntoClient -// CHECK-NEXT: func myFunc(_ ptr: Span) -> CInt { +// CHECK-NEXT: public func myFunc(_ ptr: Span) -> CInt { // CHECK-NEXT: return unsafe ptr.withUnsafeBufferPointer { _ptrPtr in -// CHECK-NEXT: return unsafe myFunc(_ptrPtr.baseAddress!, CInt(exactly: ptr.count)!) +// CHECK-NEXT: return unsafe myFunc(_ptrPtr.baseAddress!, CInt(exactly: _ptrPtr.count)!) // CHECK-NEXT: } // CHECK-NEXT: } diff --git a/test/Macros/SwiftifyImport/CountedBy/SpanAndUnsafeBuffer.swift b/test/Macros/SwiftifyImport/CountedBy/SpanAndUnsafeBuffer.swift index b7774a244aa72..c3e47b56a093a 100644 --- a/test/Macros/SwiftifyImport/CountedBy/SpanAndUnsafeBuffer.swift +++ b/test/Macros/SwiftifyImport/CountedBy/SpanAndUnsafeBuffer.swift @@ -9,9 +9,9 @@ func myFunc(_ ptr1: UnsafePointer, _ len1: CInt, _ ptr2: UnsafePointer, _ ptr2: UnsafeBufferPointer) { +// CHECK-NEXT: public func myFunc(_ ptr1: Span, _ ptr2: UnsafeBufferPointer) { // CHECK-NEXT: return unsafe ptr1.withUnsafeBufferPointer { _ptr1Ptr in -// CHECK-NEXT: return unsafe myFunc(_ptr1Ptr.baseAddress!, CInt(exactly: ptr1.count)!, ptr2.baseAddress!, CInt(exactly: ptr2.count)!) +// CHECK-NEXT: return unsafe myFunc(_ptr1Ptr.baseAddress!, CInt(exactly: _ptr1Ptr.count)!, ptr2.baseAddress!, CInt(exactly: ptr2.count)!) // CHECK-NEXT: } // CHECK-NEXT: } diff --git a/test/Macros/SwiftifyImport/CountedBy/Unwrapped.swift b/test/Macros/SwiftifyImport/CountedBy/Unwrapped.swift index 8677adf97a741..36f73095388c0 100644 --- a/test/Macros/SwiftifyImport/CountedBy/Unwrapped.swift +++ b/test/Macros/SwiftifyImport/CountedBy/Unwrapped.swift @@ -7,7 +7,7 @@ func myFunc(_ ptr: UnsafePointer!, _ len: CInt) { } // CHECK: @_alwaysEmitIntoClient -// CHECK-NEXT: func myFunc(_ ptr: UnsafeBufferPointer) { +// CHECK-NEXT: public func myFunc(_ ptr: UnsafeBufferPointer) { // CHECK-NEXT: return unsafe myFunc(ptr.baseAddress!, CInt(exactly: ptr.count)!) // CHECK-NEXT: } diff --git a/test/Macros/SwiftifyImport/CxxSpan/LifetimeboundSpan.swift b/test/Macros/SwiftifyImport/CxxSpan/LifetimeboundSpan.swift index 17ed319fa0fe8..4bbd39f6cefda 100644 --- a/test/Macros/SwiftifyImport/CxxSpan/LifetimeboundSpan.swift +++ b/test/Macros/SwiftifyImport/CxxSpan/LifetimeboundSpan.swift @@ -58,66 +58,66 @@ func myFunc9(_ span: MutableSpanOfInt) -> MutableSpanOfInt { } // CHECK: @_alwaysEmitIntoClient @lifetime(copy span) -// CHECK-NEXT: func myFunc(_ span: Span) -> Span { -// CHECK-NEXT: return unsafe _cxxOverrideLifetime(Span(_unsafeCxxSpan: unsafe myFunc(SpanOfInt(span))), copying: ()) +// CHECK-NEXT: public func myFunc(_ span: Span) -> Span { +// CHECK-NEXT: return unsafe _swiftifyOverrideLifetime(Span(_unsafeCxxSpan: unsafe myFunc(SpanOfInt(span))), copying: ()) // CHECK-NEXT: } // CHECK: @_alwaysEmitIntoClient @lifetime(borrow vec) @_disfavoredOverload -// CHECK-NEXT: func myFunc2(_ vec: borrowing VecOfInt) -> Span { -// CHECK-NEXT: return unsafe _cxxOverrideLifetime(Span(_unsafeCxxSpan: unsafe myFunc2(vec)), copying: ()) +// CHECK-NEXT: public func myFunc2(_ vec: borrowing VecOfInt) -> Span { +// CHECK-NEXT: return unsafe _swiftifyOverrideLifetime(Span(_unsafeCxxSpan: unsafe myFunc2(vec)), copying: ()) // CHECK-NEXT: } // CHECK: @_alwaysEmitIntoClient @lifetime(copy span1, copy span2) -// CHECK-NEXT: func myFunc3(_ span1: Span, _ span2: Span) -> Span { -// CHECK-NEXT: return unsafe _cxxOverrideLifetime(Span(_unsafeCxxSpan: unsafe myFunc3(SpanOfInt(span1), SpanOfInt(span2))), copying: ()) +// CHECK-NEXT: public func myFunc3(_ span1: Span, _ span2: Span) -> Span { +// CHECK-NEXT: return unsafe _swiftifyOverrideLifetime(Span(_unsafeCxxSpan: unsafe myFunc3(SpanOfInt(span1), SpanOfInt(span2))), copying: ()) // CHECK-NEXT: } // CHECK: @_alwaysEmitIntoClient @lifetime(borrow vec, copy span) -// CHECK-NEXT: func myFunc4(_ vec: borrowing VecOfInt, _ span: Span) -> Span { -// CHECK-NEXT: return unsafe _cxxOverrideLifetime(Span(_unsafeCxxSpan: unsafe myFunc4(vec, SpanOfInt(span))), copying: ()) +// CHECK-NEXT: public func myFunc4(_ vec: borrowing VecOfInt, _ span: Span) -> Span { +// CHECK-NEXT: return unsafe _swiftifyOverrideLifetime(Span(_unsafeCxxSpan: unsafe myFunc4(vec, SpanOfInt(span))), copying: ()) // CHECK-NEXT: } // CHECK: @_alwaysEmitIntoClient @lifetime(borrow self) @_disfavoredOverload -// CHECK-NEXT: func myFunc5() -> Span { -// CHECK-NEXT: return unsafe _cxxOverrideLifetime(Span(_unsafeCxxSpan: unsafe myFunc5()), copying: ()) +// CHECK-NEXT: public func myFunc5() -> Span { +// CHECK-NEXT: return unsafe _swiftifyOverrideLifetime(Span(_unsafeCxxSpan: unsafe myFunc5()), copying: ()) // CHECK-NEXT: } // CHECK: @_alwaysEmitIntoClient @lifetime(copy span) -// CHECK-NEXT: func myFunc6(_ span: Span, _ ptr: RawSpan, _ count: CInt, _ size: CInt) -> Span { +// CHECK-NEXT: public func myFunc6(_ span: Span, _ ptr: RawSpan, _ count: CInt, _ size: CInt) -> Span { // CHECK-NEXT: let _ptrCount: some BinaryInteger = count * size // CHECK-NEXT: if ptr.byteCount < _ptrCount || _ptrCount < 0 { // CHECK-NEXT: fatalError("bounds check failure when calling unsafe function") // CHECK-NEXT: } -// CHECK-NEXT: return unsafe _cxxOverrideLifetime(Span(_unsafeCxxSpan: unsafe ptr.withUnsafeBytes { _ptrPtr in +// CHECK-NEXT: return unsafe _swiftifyOverrideLifetime(Span(_unsafeCxxSpan: unsafe ptr.withUnsafeBytes { _ptrPtr in // CHECK-NEXT: return unsafe myFunc6(SpanOfInt(span), _ptrPtr.baseAddress!, count, size) // CHECK-NEXT: }), copying: ()) // CHECK-NEXT: } // CHECK: @_alwaysEmitIntoClient @lifetime(copy span) -// CHECK-NEXT: func myFunc7(_ span: Span, _ ptr: RawSpan, _ count: CInt, _ size: CInt) -> Span { +// CHECK-NEXT: public func myFunc7(_ span: Span, _ ptr: RawSpan, _ count: CInt, _ size: CInt) -> Span { // CHECK-NEXT: let _ptrCount: some BinaryInteger = count * size // CHECK-NEXT: if ptr.byteCount < _ptrCount || _ptrCount < 0 { // CHECK-NEXT: fatalError("bounds check failure when calling unsafe function") // CHECK-NEXT: } -// CHECK-NEXT: return unsafe _cxxOverrideLifetime(Span(_unsafeCxxSpan: unsafe ptr.withUnsafeBytes { _ptrPtr in +// CHECK-NEXT: return unsafe _swiftifyOverrideLifetime(Span(_unsafeCxxSpan: unsafe ptr.withUnsafeBytes { _ptrPtr in // CHECK-NEXT: return unsafe myFunc7(SpanOfInt(span), _ptrPtr.baseAddress!, count, size) // CHECK-NEXT: }), copying: ()) // CHECK-NEXT: } // CHECK: @_alwaysEmitIntoClient @lifetime(copy span) -// CHECK-NEXT: func myFunc8(_ ptr: RawSpan, _ span: Span, _ count: CInt, _ size: CInt) -> Span { +// CHECK-NEXT: public func myFunc8(_ ptr: RawSpan, _ span: Span, _ count: CInt, _ size: CInt) -> Span { // CHECK-NEXT: let _ptrCount: some BinaryInteger = count * size // CHECK-NEXT: if ptr.byteCount < _ptrCount || _ptrCount < 0 { // CHECK-NEXT: fatalError("bounds check failure when calling unsafe function") // CHECK-NEXT: } -// CHECK-NEXT: return unsafe _cxxOverrideLifetime(Span(_unsafeCxxSpan: unsafe ptr.withUnsafeBytes { _ptrPtr in +// CHECK-NEXT: return unsafe _swiftifyOverrideLifetime(Span(_unsafeCxxSpan: unsafe ptr.withUnsafeBytes { _ptrPtr in // CHECK-NEXT: return unsafe myFunc8(_ptrPtr.baseAddress!, SpanOfInt(span), count, size) // CHECK-NEXT: }), copying: ()) // CHECK-NEXT: } // CHECK: @_alwaysEmitIntoClient @lifetime(copy span) @lifetime(span: copy span) -// CHECK-NEXT: func myFunc9(_ span: inout MutableSpan) -> MutableSpan { -// CHECK-NEXT: return unsafe _cxxOverrideLifetime(MutableSpan(_unsafeCxxSpan: unsafe span.withUnsafeMutableBufferPointer { _spanPtr in +// CHECK-NEXT: public func myFunc9(_ span: inout MutableSpan) -> MutableSpan { +// CHECK-NEXT: return unsafe _swiftifyOverrideLifetime(MutableSpan(_unsafeCxxSpan: unsafe span.withUnsafeMutableBufferPointer { _spanPtr in // CHECK-NEXT: return unsafe myFunc9(MutableSpanOfInt(_spanPtr)) // CHECK-NEXT: }), copying: ()) // CHECK-NEXT: } diff --git a/test/Macros/SwiftifyImport/CxxSpan/NoEscapeSpan.swift b/test/Macros/SwiftifyImport/CxxSpan/NoEscapeSpan.swift index 84474ac42795c..1a604c46e430d 100644 --- a/test/Macros/SwiftifyImport/CxxSpan/NoEscapeSpan.swift +++ b/test/Macros/SwiftifyImport/CxxSpan/NoEscapeSpan.swift @@ -26,26 +26,26 @@ func myFunc4(_ span: MutableSpanOfInt, _ secondSpan: MutableSpanOfInt) { } // CHECK: @_alwaysEmitIntoClient -// CHECK-NEXT: func myFunc(_ span: Span, _ secondSpan: SpanOfInt) { +// CHECK-NEXT: public func myFunc(_ span: Span, _ secondSpan: SpanOfInt) { // CHECK-NEXT: return unsafe myFunc(SpanOfInt(span), secondSpan) // CHECK-NEXT: } // CHECK: @_alwaysEmitIntoClient @lifetime(span: copy span) -// CHECK-NEXT: func myFunc2(_ span: inout MutableSpan, _ secondSpan: MutableSpanOfInt) { +// CHECK-NEXT: public func myFunc2(_ span: inout MutableSpan, _ secondSpan: MutableSpanOfInt) { // CHECK-NEXT: return unsafe span.withUnsafeMutableBufferPointer { _spanPtr in // CHECK-NEXT: return unsafe myFunc2(MutableSpanOfInt(_spanPtr), secondSpan) // CHECK-NEXT: } // CHECK-NEXT: } // CHECK: @_alwaysEmitIntoClient @lifetime(span: copy span) -// CHECK-NEXT: func myFunc3(_ span: inout MutableSpan, _ secondSpan: Span) { +// CHECK-NEXT: public func myFunc3(_ span: inout MutableSpan, _ secondSpan: Span) { // CHECK-NEXT: return unsafe span.withUnsafeMutableBufferPointer { _spanPtr in // CHECK-NEXT: return unsafe myFunc3(MutableSpanOfInt(_spanPtr), SpanOfInt(secondSpan)) // CHECK-NEXT: } // CHECK-NEXT: } // CHECK: @_alwaysEmitIntoClient @lifetime(span: copy span) @lifetime(secondSpan: copy secondSpan) -// CHECK-NEXT: func myFunc4(_ span: inout MutableSpan, _ secondSpan: inout MutableSpan) { +// CHECK-NEXT: public func myFunc4(_ span: inout MutableSpan, _ secondSpan: inout MutableSpan) { // CHECK-NEXT: return unsafe secondSpan.withUnsafeMutableBufferPointer { _secondSpanPtr in // CHECK-NEXT: return unsafe span.withUnsafeMutableBufferPointer { _spanPtr in // CHECK-NEXT: return unsafe myFunc4(MutableSpanOfInt(_spanPtr), MutableSpanOfInt(_secondSpanPtr)) diff --git a/test/Macros/SwiftifyImport/MacroErrors/UnexpectedCountType.swift b/test/Macros/SwiftifyImport/MacroErrors/UnexpectedCountType.swift index 6a230425c477c..686649b266eb6 100644 --- a/test/Macros/SwiftifyImport/MacroErrors/UnexpectedCountType.swift +++ b/test/Macros/SwiftifyImport/MacroErrors/UnexpectedCountType.swift @@ -10,7 +10,7 @@ func myFunc(_ ptr: UnsafePointer, _ len: String) { } // CHECK: @_alwaysEmitIntoClient -// CHECK-NEXT: func myFunc(_ ptr: UnsafeBufferPointer) { +// CHECK-NEXT: public func myFunc(_ ptr: UnsafeBufferPointer) { // CHECK-NEXT: myFunc(ptr.baseAddress!, String(exactly: ptr.count)!) // CHECK-NEXT: } diff --git a/test/Macros/SwiftifyImport/SizedBy/MultipleParams.swift b/test/Macros/SwiftifyImport/SizedBy/MultipleParams.swift index 912c9dbcd8822..ff57e275664bc 100644 --- a/test/Macros/SwiftifyImport/SizedBy/MultipleParams.swift +++ b/test/Macros/SwiftifyImport/SizedBy/MultipleParams.swift @@ -7,6 +7,6 @@ func myFunc(_ ptr: UnsafeRawPointer, _ size: CInt, _ ptr2: UnsafeRawPointer, _ s } // CHECK: @_alwaysEmitIntoClient -// CHECK-NEXT: func myFunc(_ ptr: UnsafeRawBufferPointer, _ ptr2: UnsafeRawBufferPointer) { +// CHECK-NEXT: public func myFunc(_ ptr: UnsafeRawBufferPointer, _ ptr2: UnsafeRawBufferPointer) { // CHECK-NEXT: return unsafe myFunc(ptr.baseAddress!, CInt(exactly: ptr.count)!, ptr2.baseAddress!, CInt(exactly: ptr2.count)!) // CHECK-NEXT: } diff --git a/test/Macros/SwiftifyImport/SizedBy/Mutable.swift b/test/Macros/SwiftifyImport/SizedBy/Mutable.swift index 1e8e9d9023d84..d389782a0245d 100644 --- a/test/Macros/SwiftifyImport/SizedBy/Mutable.swift +++ b/test/Macros/SwiftifyImport/SizedBy/Mutable.swift @@ -7,6 +7,6 @@ func myFunc(_ ptr: UnsafeMutableRawPointer, _ size: CInt) { } // CHECK: @_alwaysEmitIntoClient -// CHECK-NEXT: func myFunc(_ ptr: UnsafeMutableRawBufferPointer) { +// CHECK-NEXT: public func myFunc(_ ptr: UnsafeMutableRawBufferPointer) { // CHECK-NEXT: return unsafe myFunc(ptr.baseAddress!, CInt(exactly: ptr.count)!) // CHECK-NEXT: } diff --git a/test/Macros/SwiftifyImport/SizedBy/MutableRawSpan.swift b/test/Macros/SwiftifyImport/SizedBy/MutableRawSpan.swift index 912329466aca3..ba1d14088bbc5 100644 --- a/test/Macros/SwiftifyImport/SizedBy/MutableRawSpan.swift +++ b/test/Macros/SwiftifyImport/SizedBy/MutableRawSpan.swift @@ -8,8 +8,8 @@ func myFunc(_ ptr: UnsafeMutableRawPointer, _ size: CInt) { } // CHECK: @_alwaysEmitIntoClient @lifetime(ptr: copy ptr) -// CHECK-NEXT: func myFunc(_ ptr: inout MutableRawSpan) { +// CHECK-NEXT: public func myFunc(_ ptr: inout MutableRawSpan) { // CHECK-NEXT: return unsafe ptr.withUnsafeMutableBytes { _ptrPtr in -// CHECK-NEXT: return unsafe myFunc(_ptrPtr.baseAddress!, CInt(exactly: ptr.byteCount)!) +// CHECK-NEXT: return unsafe myFunc(_ptrPtr.baseAddress!, CInt(exactly: _ptrPtr.count)!) // CHECK-NEXT: } // CHECK-NEXT: } diff --git a/test/Macros/SwiftifyImport/SizedBy/Nullable.swift b/test/Macros/SwiftifyImport/SizedBy/Nullable.swift index 6a8059725c4c6..3d60c3ba2afac 100644 --- a/test/Macros/SwiftifyImport/SizedBy/Nullable.swift +++ b/test/Macros/SwiftifyImport/SizedBy/Nullable.swift @@ -7,6 +7,6 @@ func myFunc(_ ptr: UnsafeRawPointer?, _ size: CInt) { } // CHECK: @_alwaysEmitIntoClient -// CHECK-NEXT: func myFunc(_ ptr: UnsafeRawBufferPointer?) { +// CHECK-NEXT: public func myFunc(_ ptr: UnsafeRawBufferPointer?) { // CHECK-NEXT: return unsafe myFunc(ptr?.baseAddress, CInt(exactly: ptr?.count ?? 0)!) // CHECK-NEXT: } diff --git a/test/Macros/SwiftifyImport/SizedBy/Opaque.swift b/test/Macros/SwiftifyImport/SizedBy/Opaque.swift index c396d7f9cc295..f276222d8325d 100644 --- a/test/Macros/SwiftifyImport/SizedBy/Opaque.swift +++ b/test/Macros/SwiftifyImport/SizedBy/Opaque.swift @@ -27,44 +27,44 @@ func impNullableSpan(_ ptr: OpaquePointer!, _ size: CInt) { } // CHECK: @_alwaysEmitIntoClient -// CHECK-NEXT: func nonnullUnsafeRawBufferPointer(_ ptr: UnsafeRawBufferPointer) { +// CHECK-NEXT: public func nonnullUnsafeRawBufferPointer(_ ptr: UnsafeRawBufferPointer) { // CHECK-NEXT: return unsafe nonnullUnsafeRawBufferPointer(OpaquePointer(ptr.baseAddress!), CInt(exactly: ptr.count)!) // CHECK-NEXT: } // CHECK: @_alwaysEmitIntoClient -// CHECK-NEXT: func nullableUnsafeRawBufferPointer(_ ptr: UnsafeRawBufferPointer?) { +// CHECK-NEXT: public func nullableUnsafeRawBufferPointer(_ ptr: UnsafeRawBufferPointer?) { // CHECK-NEXT: return unsafe nullableUnsafeRawBufferPointer(OpaquePointer(ptr?.baseAddress), CInt(exactly: ptr?.count ?? 0)!) // CHECK-NEXT: } // CHECK: @_alwaysEmitIntoClient -// CHECK-NEXT: func impNullableUnsafeRawBufferPointer(_ ptr: UnsafeRawBufferPointer) { +// CHECK-NEXT: public func impNullableUnsafeRawBufferPointer(_ ptr: UnsafeRawBufferPointer) { // CHECK-NEXT: return unsafe impNullableUnsafeRawBufferPointer(OpaquePointer(ptr.baseAddress!), CInt(exactly: ptr.count)!) // CHECK-NEXT: } // CHECK: @_alwaysEmitIntoClient -// CHECK-NEXT: func nonnullSpan(_ ptr: RawSpan) { +// CHECK-NEXT: public func nonnullSpan(_ ptr: RawSpan) { // CHECK-NEXT: return unsafe ptr.withUnsafeBytes { _ptrPtr in -// CHECK-NEXT: return unsafe nonnullSpan(OpaquePointer(_ptrPtr.baseAddress!), CInt(exactly: ptr.byteCount)!) +// CHECK-NEXT: return unsafe nonnullSpan(OpaquePointer(_ptrPtr.baseAddress!), CInt(exactly: _ptrPtr.count)!) // CHECK-NEXT: } // CHECK-NEXT: } // CHECK: @_alwaysEmitIntoClient -// CHECK-NEXT: func nullableSpan(_ ptr: RawSpan?) { +// CHECK-NEXT: public func nullableSpan(_ ptr: RawSpan?) { // CHECK-NEXT: return { () in // CHECK-NEXT: return if ptr == nil { // CHECK-NEXT: unsafe nullableSpan(nil, CInt(exactly: ptr?.byteCount ?? 0)!) // CHECK-NEXT: } else { // CHECK-NEXT: unsafe ptr!.withUnsafeBytes { _ptrPtr in -// CHECK-NEXT: return unsafe nullableSpan(OpaquePointer(_ptrPtr.baseAddress), CInt(exactly: ptr?.byteCount ?? 0)!) +// CHECK-NEXT: return unsafe nullableSpan(OpaquePointer(_ptrPtr.baseAddress), CInt(exactly: _ptrPtr.count)!) // CHECK-NEXT: } // CHECK-NEXT: } // CHECK-NEXT: }() // CHECK-NEXT: } // CHECK: @_alwaysEmitIntoClient -// CHECK-NEXT: func impNullableSpan(_ ptr: RawSpan) { +// CHECK-NEXT: public func impNullableSpan(_ ptr: RawSpan) { // CHECK-NEXT: return unsafe ptr.withUnsafeBytes { _ptrPtr in -// CHECK-NEXT: return unsafe impNullableSpan(OpaquePointer(_ptrPtr.baseAddress!), CInt(exactly: ptr.byteCount)!) +// CHECK-NEXT: return unsafe impNullableSpan(OpaquePointer(_ptrPtr.baseAddress!), CInt(exactly: _ptrPtr.count)!) // CHECK-NEXT: } // CHECK-NEXT: } diff --git a/test/Macros/SwiftifyImport/SizedBy/Return.swift b/test/Macros/SwiftifyImport/SizedBy/Return.swift index 61dcbc9764861..3481b037660ae 100644 --- a/test/Macros/SwiftifyImport/SizedBy/Return.swift +++ b/test/Macros/SwiftifyImport/SizedBy/Return.swift @@ -7,6 +7,6 @@ func myFunc(_ ptr: UnsafeRawPointer, _ size: CInt) -> CInt { } // CHECK: @_alwaysEmitIntoClient -// CHECK-NEXT: func myFunc(_ ptr: UnsafeRawBufferPointer) -> CInt { +// CHECK-NEXT: public func myFunc(_ ptr: UnsafeRawBufferPointer) -> CInt { // CHECK-NEXT: return unsafe myFunc(ptr.baseAddress!, CInt(exactly: ptr.count)!) // CHECK-NEXT: } diff --git a/test/Macros/SwiftifyImport/SizedBy/SharedCount.swift b/test/Macros/SwiftifyImport/SizedBy/SharedCount.swift index 2d331b9c19805..7629e680718f6 100644 --- a/test/Macros/SwiftifyImport/SizedBy/SharedCount.swift +++ b/test/Macros/SwiftifyImport/SizedBy/SharedCount.swift @@ -7,7 +7,7 @@ func myFunc(_ ptr: UnsafeRawPointer, _ ptr2: UnsafeRawPointer, _ size: CInt) { } // CHECK: @_alwaysEmitIntoClient -// CHECK-NEXT: func myFunc(_ ptr: UnsafeRawBufferPointer, _ ptr2: UnsafeRawBufferPointer, _ size: CInt) { +// CHECK-NEXT: public func myFunc(_ ptr: UnsafeRawBufferPointer, _ ptr2: UnsafeRawBufferPointer, _ size: CInt) { // CHECK-NEXT: let _ptrCount: some BinaryInteger = size // CHECK-NEXT: if ptr.count < _ptrCount || _ptrCount < 0 { // CHECK-NEXT: fatalError("bounds check failure when calling unsafe function") diff --git a/test/Macros/SwiftifyImport/SizedBy/SimpleRawSpan.swift b/test/Macros/SwiftifyImport/SizedBy/SimpleRawSpan.swift index c7ed798638e34..ff1352c184034 100644 --- a/test/Macros/SwiftifyImport/SizedBy/SimpleRawSpan.swift +++ b/test/Macros/SwiftifyImport/SizedBy/SimpleRawSpan.swift @@ -8,8 +8,8 @@ func myFunc(_ ptr: UnsafeRawPointer, _ size: CInt) { } // CHECK: @_alwaysEmitIntoClient -// CHECK-NEXT: func myFunc(_ ptr: RawSpan) { +// CHECK-NEXT: public func myFunc(_ ptr: RawSpan) { // CHECK-NEXT: return unsafe ptr.withUnsafeBytes { _ptrPtr in -// CHECK-NEXT: return unsafe myFunc(_ptrPtr.baseAddress!, CInt(exactly: ptr.byteCount)!) +// CHECK-NEXT: return unsafe myFunc(_ptrPtr.baseAddress!, CInt(exactly: _ptrPtr.count)!) // CHECK-NEXT: } // CHECK-NEXT: } diff --git a/test/Macros/SwiftifyImport/SizedBy/SimpleRawSpanWithReturn.swift b/test/Macros/SwiftifyImport/SizedBy/SimpleRawSpanWithReturn.swift index 92586787da5b1..1d2e7fdf27b83 100644 --- a/test/Macros/SwiftifyImport/SizedBy/SimpleRawSpanWithReturn.swift +++ b/test/Macros/SwiftifyImport/SizedBy/SimpleRawSpanWithReturn.swift @@ -8,8 +8,8 @@ func myFunc(_ ptr: UnsafeRawPointer, _ size: CInt) -> CInt { } // CHECK: @_alwaysEmitIntoClient -// CHECK-NEXT: func myFunc(_ ptr: RawSpan) -> CInt { +// CHECK-NEXT: public func myFunc(_ ptr: RawSpan) -> CInt { // CHECK-NEXT: return unsafe ptr.withUnsafeBytes { _ptrPtr in -// CHECK-NEXT: return unsafe myFunc(_ptrPtr.baseAddress!, CInt(exactly: ptr.byteCount)!) +// CHECK-NEXT: return unsafe myFunc(_ptrPtr.baseAddress!, CInt(exactly: _ptrPtr.count)!) // CHECK-NEXT: } // CHECK-NEXT: } diff --git a/test/Macros/SwiftifyImport/SizedBy/SimpleSize.swift b/test/Macros/SwiftifyImport/SizedBy/SimpleSize.swift index 803d81e788d1f..9c17189c19d52 100644 --- a/test/Macros/SwiftifyImport/SizedBy/SimpleSize.swift +++ b/test/Macros/SwiftifyImport/SizedBy/SimpleSize.swift @@ -7,6 +7,6 @@ func myFunc(_ ptr: UnsafeRawPointer, _ size: CInt) { } // CHECK: @_alwaysEmitIntoClient -// CHECK-NEXT: func myFunc(_ ptr: UnsafeRawBufferPointer) { +// CHECK-NEXT: public func myFunc(_ ptr: UnsafeRawBufferPointer) { // CHECK-NEXT: return unsafe myFunc(ptr.baseAddress!, CInt(exactly: ptr.count)!) // CHECK-NEXT: } diff --git a/test/Macros/SwiftifyImport/SizedBy/SizeExpr.swift b/test/Macros/SwiftifyImport/SizedBy/SizeExpr.swift index 506ae8da2b687..b4055cf14a36c 100644 --- a/test/Macros/SwiftifyImport/SizedBy/SizeExpr.swift +++ b/test/Macros/SwiftifyImport/SizedBy/SizeExpr.swift @@ -7,7 +7,7 @@ func myFunc(_ ptr: UnsafeRawPointer, _ size: CInt, _ count: CInt) { } // CHECK: @_alwaysEmitIntoClient -// CHECK-NEXT: func myFunc(_ ptr: UnsafeRawBufferPointer, _ size: CInt, _ count: CInt) { +// CHECK-NEXT: public func myFunc(_ ptr: UnsafeRawBufferPointer, _ size: CInt, _ count: CInt) { // CHECK-NEXT: let _ptrCount: some BinaryInteger = size * count // CHECK-NEXT: if ptr.count < _ptrCount || _ptrCount < 0 { // CHECK-NEXT: fatalError("bounds check failure when calling unsafe function") diff --git a/test/Macros/SwiftifyImport/SizedBy/Unwrapped.swift b/test/Macros/SwiftifyImport/SizedBy/Unwrapped.swift index c18be3ae42f62..6569081783307 100644 --- a/test/Macros/SwiftifyImport/SizedBy/Unwrapped.swift +++ b/test/Macros/SwiftifyImport/SizedBy/Unwrapped.swift @@ -7,7 +7,7 @@ func myFunc(_ ptr: UnsafeRawPointer!, _ len: CInt) { } // CHECK: @_alwaysEmitIntoClient -// CHECK-NEXT: func myFunc(_ ptr: UnsafeRawBufferPointer) { +// CHECK-NEXT: public func myFunc(_ ptr: UnsafeRawBufferPointer) { // CHECK-NEXT: return unsafe myFunc(ptr.baseAddress!, CInt(exactly: ptr.count)!) // CHECK-NEXT: } diff --git a/test/abi/Inputs/macOS/arm64/stdlib/baseline b/test/abi/Inputs/macOS/arm64/stdlib/baseline index 7fa9a942d9065..4dfa8d6a7c560 100644 --- a/test/abi/Inputs/macOS/arm64/stdlib/baseline +++ b/test/abi/Inputs/macOS/arm64/stdlib/baseline @@ -8937,6 +8937,10 @@ _$ss27_BidirectionalCollectionBoxCMu _$ss27_BidirectionalCollectionBoxCfD _$ss27_BidirectionalCollectionBoxCfd _$ss27_BidirectionalCollectionBoxCy7ElementQzs09_AnyIndexC0_pcig +_$ss27_SwiftifyProtocolMethodInfoO6methodyABSS_Says01_aD0OGtcABmFWC +_$ss27_SwiftifyProtocolMethodInfoOMa +_$ss27_SwiftifyProtocolMethodInfoOMn +_$ss27_SwiftifyProtocolMethodInfoON _$ss27_allocateUninitializedArrayySayxG_BptBwlF _$ss27_bridgeAnythingToObjectiveCyyXlxlF _$ss27_debuggerTestingCheckExpectyySS_SStF diff --git a/test/abi/Inputs/macOS/arm64/stdlib/baseline-asserts b/test/abi/Inputs/macOS/arm64/stdlib/baseline-asserts index 4807b19909ef1..1589099082f83 100644 --- a/test/abi/Inputs/macOS/arm64/stdlib/baseline-asserts +++ b/test/abi/Inputs/macOS/arm64/stdlib/baseline-asserts @@ -8949,6 +8949,10 @@ _$ss27_BidirectionalCollectionBoxCMu _$ss27_BidirectionalCollectionBoxCfD _$ss27_BidirectionalCollectionBoxCfd _$ss27_BidirectionalCollectionBoxCy7ElementQzs09_AnyIndexC0_pcig +_$ss27_SwiftifyProtocolMethodInfoO6methodyABSS_Says01_aD0OGtcABmFWC +_$ss27_SwiftifyProtocolMethodInfoOMa +_$ss27_SwiftifyProtocolMethodInfoOMn +_$ss27_SwiftifyProtocolMethodInfoON _$ss27_allocateUninitializedArrayySayxG_BptBwlF _$ss27_bridgeAnythingToObjectiveCyyXlxlF _$ss27_debuggerTestingCheckExpectyySS_SStF diff --git a/test/abi/Inputs/macOS/x86_64/stdlib/baseline b/test/abi/Inputs/macOS/x86_64/stdlib/baseline index bc79fe5f89879..e05241dc5d31b 100644 --- a/test/abi/Inputs/macOS/x86_64/stdlib/baseline +++ b/test/abi/Inputs/macOS/x86_64/stdlib/baseline @@ -8962,6 +8962,10 @@ _$ss27_BidirectionalCollectionBoxCMu _$ss27_BidirectionalCollectionBoxCfD _$ss27_BidirectionalCollectionBoxCfd _$ss27_BidirectionalCollectionBoxCy7ElementQzs09_AnyIndexC0_pcig +_$ss27_SwiftifyProtocolMethodInfoO6methodyABSS_Says01_aD0OGtcABmFWC +_$ss27_SwiftifyProtocolMethodInfoOMa +_$ss27_SwiftifyProtocolMethodInfoOMn +_$ss27_SwiftifyProtocolMethodInfoON _$ss27_allocateUninitializedArrayySayxG_BptBwlF _$ss27_bridgeAnythingToObjectiveCyyXlxlF _$ss27_debuggerTestingCheckExpectyySS_SStF diff --git a/test/abi/Inputs/macOS/x86_64/stdlib/baseline-asserts b/test/abi/Inputs/macOS/x86_64/stdlib/baseline-asserts index ba9fb06fe7c5a..cc4c136826ca8 100644 --- a/test/abi/Inputs/macOS/x86_64/stdlib/baseline-asserts +++ b/test/abi/Inputs/macOS/x86_64/stdlib/baseline-asserts @@ -8974,6 +8974,10 @@ _$ss27_BidirectionalCollectionBoxCMu _$ss27_BidirectionalCollectionBoxCfD _$ss27_BidirectionalCollectionBoxCfd _$ss27_BidirectionalCollectionBoxCy7ElementQzs09_AnyIndexC0_pcig +_$ss27_SwiftifyProtocolMethodInfoO6methodyABSS_Says01_aD0OGtcABmFWC +_$ss27_SwiftifyProtocolMethodInfoOMa +_$ss27_SwiftifyProtocolMethodInfoOMn +_$ss27_SwiftifyProtocolMethodInfoON _$ss27_allocateUninitializedArrayySayxG_BptBwlF _$ss27_bridgeAnythingToObjectiveCyyXlxlF _$ss27_debuggerTestingCheckExpectyySS_SStF