 // CHECK-LABEL: sil hidden @_TF13objc_bridging7setZangFTCSo3FooSb_T_
 // CHECK: bb0([[ARG0:%.*]] : $Foo, [[ARG1:%.*]] : $Bool):
 // CHECK:   [[BORROWED_ARG0:%.*]] = begin_borrow [[ARG0]]
-// CHECK:   apply {{%.*}}([[ARG1]], [[BORROWED_ARG0]]) : $@convention(objc_method) (Bool, Foo) -> ()
+// CHECK:   [[METHOD:%.*]] = class_method [volatile] [[BORROWED_ARG0]] : $Foo, #Foo.setZang!1.foreign
+// CHECK:   apply [[METHOD]]([[ARG1]], [[BORROWED_ARG0]]) : $@convention(objc_method) (Bool, Foo) -> ()
+// CHECK:   end_borrow [[BORROWED_ARG0]] from [[ARG0]]
+// CHECK:   destroy_value [[ARG0]]
+// CHECK: } // end sil function '_TF13objc_bridging7setZangFTCSo3FooSb_T_' 
 
 // NSString *bar(void);
 func callBar() -> String {

}

// CHECK-ios-i386-LABEL: sil hidden @_TF13objc_bridging6getZim
// CHECK-ios-i386:   [[OBJC_BOOL:%.*]] = apply {{.*}} : $@convention(objc_method) (Foo) -> ObjCBool
// CHECK-ios-i386:   [[CONVERT:%.*]] = function_ref @swift_ObjCBoolToBool : $@convention(thin) (ObjCBool) -> Bool
// CHECK-ios-i386:   [[SWIFT_BOOL:%.*]] = apply [[CONVERT]]([[OBJC_BOOL]]) : $@convention(thin) (ObjCBool) -> Bool
// CHECK-ios-i386:   return [[SWIFT_BOOL]] : $Bool
// CHECK-ios-i386: }

// CHECK-watchos-i386-LABEL: sil hidden @_TF13objc_bridging6getZim
// CHECK-watchos-i386:   [[BOOL:%.*]] = apply {{.*}} : $@convention(objc_method) (Foo) -> Bool
// CHECK-watchos-i386:   return [[BOOL]] : $Bool
// CHECK-watchos-i386: }

// CHECK-macosx-x86_64-LABEL: sil hidden @_TF13objc_bridging6getZim
// CHECK-macosx-x86_64:   [[OBJC_BOOL:%.*]] = apply {{.*}} : $@convention(objc_method) (Foo) -> ObjCBool
// CHECK-macosx-x86_64:   [[CONVERT:%.*]] = function_ref @swift_ObjCBoolToBool : $@convention(thin) (ObjCBool) -> Bool
// CHECK-macosx-x86_64:   [[SWIFT_BOOL:%.*]] = apply [[CONVERT]]([[OBJC_BOOL]]) : $@convention(thin) (ObjCBool) -> Bool
// CHECK-macosx-x86_64:   return [[SWIFT_BOOL]] : $Bool
// CHECK-macosx-x86_64: }

// CHECK-ios-x86_64-LABEL: sil hidden @_TF13objc_bridging6getZim
// CHECK-ios-x86_64:   [[SWIFT_BOOL:%.*]] = apply {{.*}} : $@convention(objc_method) (Foo) -> Bool
// CHECK-ios-x86_64:   return [[SWIFT_BOOL]] : $Bool
// CHECK-ios-x86_64: }

// CHECK-arm64-LABEL: sil hidden @_TF13objc_bridging6getZim
// CHECK-arm64:   [[SWIFT_BOOL:%.*]] = apply {{.*}} : $@convention(objc_method) (Foo) -> Bool
// CHECK-arm64:   return [[SWIFT_BOOL]] : $Bool
// CHECK-arm64: }

// @interface Foo -(void) setZim: (BOOL)b; @end


// REQUIRES: objc_interop

import Foundation
import Appliances


func getDescription(_ o: NSObject) -> String {
  return o.description
}
// CHECK-LABEL: sil hidden @_TF13objc_bridging14getDescription
// CHECK: bb0([[ARG:%.*]] : $NSObject):
// CHECK:   [[BORROWED_ARG:%.*]] = begin_borrow [[ARG]]
// CHECK:   [[DESCRIPTION:%.*]] = class_method [volatile] [[BORROWED_ARG]] : $NSObject, #NSObject.description!getter.1.foreign
// CHECK:   [[OPT_BRIDGED:%.*]] = apply [[DESCRIPTION]]([[BORROWED_ARG]])
// CHECK:   [[SELECT_RESULT:%.*]] = select_enum [[OPT_BRIDGED]]
// CHECK:   cond_br [[SELECT_RESULT]], [[SOME_BB:bb[0-9]+]], [[NONE_BB:bb[0-9]+]]
//
// CHECK: [[SOME_BB]]:
// CHECK:   [[BRIDGED:%.*]] = unchecked_enum_data [[OPT_BRIDGED]]
// CHECK:   [[NSSTRING_TO_STRING:%.*]] = function_ref @_TZFE10FoundationSS36_unconditionallyBridgeFromObjectiveCfGSqCSo8NSString_SS
// CHECK:   [[BRIDGED_BOX:%.*]] = enum $Optional<NSString>, #Optional.some!enumelt.1, [[BRIDGED]]
// CHECK:   [[NATIVE:%.*]] = apply [[NSSTRING_TO_STRING]]([[BRIDGED_BOX]],
// CHECK:   [[OPT_NATIVE:%.*]] = enum $Optional<String>, #Optional.some!enumelt.1, [[NATIVE]]
// CHECK:   br [[CONT_BB:bb[0-9]+]]([[OPT_NATIVE]] : $Optional<String>)
//
// CHECK: [[NONE_BB]]:
// CHECK:   [[OPT_NATIVE:%.*]] = enum $Optional<String>, #Optional.none!enumelt
// CHECK:   br [[CONT_BB]]([[OPT_NATIVE]] : $Optional<String>)
//
// CHECK: [[CONT_BB]]([[OPT_NATIVE:%.*]] : $Optional<String>):
// CHECK:   switch_enum [[OPT_NATIVE]] : $Optional<String>, case #Optional.none!enumelt: [[NONE_BB:bb[0-9]+]], default [[SOME_BB:bb[0-9]+]]
//
// CHECK: [[NONE_BB]]:
// CHECK:   unreachable
//
// CHECK: [[SOME_BB]]:
// CHECK:    [[NATIVE:%.*]] = unchecked_enum_data [[OPT_NATIVE]] : $Optional<String>
// CHECK:    end_borrow [[BORROWED_ARG]] from [[ARG]]
// CHECK:    destroy_value [[ARG]]
// CHECK:    return [[NATIVE]] 
// CHECK:}

func getUppercaseString(_ s: NSString) -> String {
  return s.uppercase()
}
// CHECK-LABEL: sil hidden @_TF13objc_bridging18getUppercaseString
// CHECK: bb0([[ARG:%.*]] : $NSString):
// -- The 'self' argument of NSString methods doesn't bridge.
// CHECK-NOT: function_ref @_TZFE10FoundationSS36_unconditionallyBridgeFromObjectiveCfGSqCSo8NSString_SS
// CHECK-NOT: function_ref @swift_StringToNSString
// CHECK:   [[BORROWED_ARG:%.*]] = begin_borrow [[ARG]]
// CHECK:   [[UPPERCASE_STRING:%.*]] = class_method [volatile] [[BORROWED_ARG]] : $NSString, #NSString.uppercase!1.foreign
// CHECK:   [[OPT_BRIDGED:%.*]] = apply [[UPPERCASE_STRING]]([[BORROWED_ARG]])
// CHECK:   [[HAS_VALUE:%.*]] = select_enum [[OPT_BRIDGED]]
// CHECK:   cond_br [[HAS_VALUE]], [[SOME_BB:bb[0-9]+]], [[NONE_BB:bb[0-9]+]]
//
// CHECK: [[SOME_BB]]:
// CHECK:   [[BRIDGED:%.*]] = unchecked_enum_data [[OPT_BRIDGED]]
// CHECK:   [[NSSTRING_TO_STRING:%.*]] = function_ref @_TZFE10FoundationSS36_unconditionallyBridgeFromObjectiveCfGSqCSo8NSString_SS
// CHECK:   [[BRIDGED_BOX:%.*]] = enum $Optional<NSString>, #Optional.some!enumelt.1, [[BRIDGED]]
// CHECK:   [[NATIVE:%.*]] = apply [[NSSTRING_TO_STRING]]([[BRIDGED_BOX]]
// CHECK:   [[OPT_NATIVE:%.*]] = enum $Optional<String>, #Optional.some!enumelt.1, [[NATIVE]]
// CHECK:   br [[CONT_BB:bb[0-9]+]]([[OPT_NATIVE]] : $Optional<String>)
//
// CHECK: [[NONE_BB]]:
// CHECK:   [[OPT_NATIVE:%.*]] = enum $Optional<String>, #Optional.none!enumelt
// CHECK:   br [[CONT_BB]]([[OPT_NATIVE]] : $Optional<String>)
//
// CHECK: [[CONT_BB]]([[OPT_NATIVE:%.*]] : $Optional<String>):
// CHECK:   switch_enum [[OPT_NATIVE]] : $Optional<String>, case #Optional.none!enumelt: [[NONE_BB:bb[0-9]+]], default [[SOME_BB:bb[0-9]+]]
//
// CHECK: [[NONE_BB]]:
// CHECK:   unreachable
//
// CHECK: [[SOME_BB]]:
// CHECK:   [[NATIVE:%.*]] = unchecked_enum_data [[OPT_NATIVE]] : $Optional<String>
// CHECK:   return [[NATIVE]]
// CHECK: }

