diff --git a/lib/ClangImporter/SwiftifyDecl.cpp b/lib/ClangImporter/SwiftifyDecl.cpp index 9a7770117092f..6d5b40bb655ce 100644 --- a/lib/ClangImporter/SwiftifyDecl.cpp +++ b/lib/ClangImporter/SwiftifyDecl.cpp @@ -414,13 +414,24 @@ static bool swiftifyImpl(ClangImporter::Implementation &Self, } bool isClangInstanceMethod = - isa(ClangDecl) && - !isa(ClangDecl) && - cast(ClangDecl)->isInstance(); - size_t swiftNumParams = MappedDecl->getParameters()->size() - - (ClangDecl->isVariadic() ? 1 : 0); - ASSERT((MappedDecl->isImportAsInstanceMember() == isClangInstanceMethod) == - (getNumParams(ClangDecl) == swiftNumParams)); + (isa(ClangDecl) && + !isa(ClangDecl) && + cast(ClangDecl)->isInstance()) || + (isa(ClangDecl) && + cast(ClangDecl)->isInstanceMethod()); + + size_t swiftNumParams = MappedDecl->getParameters()->size(); + if (MappedDecl->isInstanceMember() && !isClangInstanceMethod) { + ASSERT(MappedDecl->isImportAsInstanceMember()); + swiftNumParams += 1; + } + if (getNumParams(ClangDecl) != swiftNumParams) { + DLOG("mismatching parameter lists"); + assert(ClangDecl->isVariadic() || + MappedDecl->getForeignErrorConvention().has_value() || + MappedDecl->getForeignAsyncConvention().has_value()); + return false; + } size_t selfParamIndex = MappedDecl->isImportAsInstanceMember() ? MappedDecl->getSelfIndex() @@ -531,6 +542,9 @@ class SwiftifyProtocolInfoPrinter : public SwiftifyInfoPrinter { void printMethodSignature(const FuncDecl *Method) { auto options = PrintOptions::printForDiagnostics(AccessLevel::Private, true); + for (const auto *attr : Method->getAttrs()) { + options.ExcludeAttrList.push_back(attr->getKind()); + } StreamPrinter printer(out); Method->print(printer, options); } diff --git a/test/Interop/C/swiftify-import/Inputs/counted-by.h b/test/Interop/C/swiftify-import/Inputs/counted-by.h index 2b855eeffc430..5fde5abf2d285 100644 --- a/test/Interop/C/swiftify-import/Inputs/counted-by.h +++ b/test/Interop/C/swiftify-import/Inputs/counted-by.h @@ -62,3 +62,5 @@ void hexLiteral(int * __counted_by(0xfa) p); void binaryLiteral(int * __counted_by(0b10) p); void octalLiteral(int * __counted_by(0777) p); + +void variadic(int len, int * __counted_by(len) p, ...); diff --git a/test/Interop/C/swiftify-import/counted-by-no-swiftify.swift b/test/Interop/C/swiftify-import/counted-by-no-swiftify.swift index ff565150f4126..7948eeb80f6a5 100644 --- a/test/Interop/C/swiftify-import/counted-by-no-swiftify.swift +++ b/test/Interop/C/swiftify-import/counted-by-no-swiftify.swift @@ -16,3 +16,4 @@ // CHECK-NOT: @_alwaysEmitIntoClient {{.*}} longLiteral // CHECK-NOT: @_alwaysEmitIntoClient {{.*}} sizeofType // CHECK-NOT: @_alwaysEmitIntoClient {{.*}} sizeofParam +// CHECK-NOT: @_alwaysEmitIntoClient {{.*}} variadic diff --git a/test/Interop/ObjC/swiftify-import/Inputs/objc-no-swiftify.h b/test/Interop/ObjC/swiftify-import/Inputs/objc-no-swiftify.h index 4b01f0e94f4f7..0ee95be5d6312 100644 --- a/test/Interop/ObjC/swiftify-import/Inputs/objc-no-swiftify.h +++ b/test/Interop/ObjC/swiftify-import/Inputs/objc-no-swiftify.h @@ -7,3 +7,14 @@ void autoreleaseParam(SomeClass * __autoreleasing * __counted_by(len) p, int len); // expected-note{{declared here}} SomeClass * __autoreleasing * __counted_by(len) autoreleaseReturn(int len); + +@interface NSError +@end + +@interface NSData +@end + +@protocol Foo +- (void)errorAsTry:(int) len : (int * __counted_by(len)) p error:(NSError * *) error; +- (void)completionHandlerAsAsync:(int) len : (int * __counted_by(len)) p completionHandler:(void (^)(NSData * data, NSError *)) completionHandler; +@end diff --git a/test/Interop/ObjC/swiftify-import/objc-no-swiftify.swift b/test/Interop/ObjC/swiftify-import/objc-no-swiftify.swift index 5c918bc4bec5c..4563154e203ed 100644 --- a/test/Interop/ObjC/swiftify-import/objc-no-swiftify.swift +++ b/test/Interop/ObjC/swiftify-import/objc-no-swiftify.swift @@ -7,8 +7,7 @@ import NoSwiftifyClang -// CHECK-NOT: @_alwaysEmitIntoClient @_disfavoredOverload public func callAutoreleaseParam -// CHECK-NOT: @_alwaysEmitIntoClient @_disfavoredOverload public func callAutoreleaseReturn +// CHECK-NOT: @_alwaysEmitIntoClient @_disfavoredOverload public func callAutoreleaseParam(_ p: UnsafeMutableBufferPointer) { // expected-error@+2{{missing argument for parameter #2 in call}} @@ -19,4 +18,14 @@ public func callAutoreleaseParam(_ p: UnsafeMutableBufferPointer) { public func callAutoreleaseReturn() { // expected-error@+1{{cannot convert value of type 'AutoreleasingUnsafeMutablePointer?' to specified type 'UnsafeMutableBufferPointer'}} let p: UnsafeMutableBufferPointer = autoreleaseReturn(10) -} \ No newline at end of file +} + +public func callErrorAsTry(_ x: Foo, _ p: UnsafeMutablePointer, _ error: AutoreleasingUnsafeMutablePointer) { + x.error(asTry: 10, p, error: error) +} + +public func callCompletionHandlerAsAsync(_ x: Foo, _ p: UnsafeMutablePointer) { + x.completionHandler(asAsync: 10, p, completionHandler: { (a: NSData?, b: NSError?) in + print("asdf") + }) +}