// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-ir %s | FileCheck %s
// REQUIRES: objc_interop

import Foundation

class C: NSObject {}
@objc protocol P {}
@objc protocol Q {}
protocol NonObjC: class {}

// CHECK: @_TMPV34type_layout_reference_storage_objc26ReferenceStorageTypeLayout = global {{.*}} @create_generic_metadata_ReferenceStorageTypeLayout
// CHECK: define private %swift.type* @create_generic_metadata_ReferenceStorageTypeLayout
struct ReferenceStorageTypeLayout<T> {
  var z: T

  // -- ObjC-refcounted class
  // CHECK: store i8** getelementptr inbounds (i8*, i8** @_TWVXoBO, i32 17)
  unowned(safe)   var cs:  C
  // CHECK: store i8** getelementptr inbounds (i8*, i8** @_TWVMBo, i32 17)
  unowned(unsafe) var cu:  C
  // CHECK: store i8** getelementptr inbounds (i8*, i8** @_TWVXwGSqBO_, i32 17)
  weak            var cwo: C?
  // CHECK: store i8** getelementptr inbounds (i8*, i8** @_TWVXwGSqBO_, i32 17)
  weak            var cwi: C!

  // -- Pure ObjC protocols are unknown-refcounted
  // CHECK: store i8** getelementptr inbounds (i8*, i8** @_TWVXoBO, i32 17)
  unowned(safe)   var ps:  P
  // CHECK: store i8** getelementptr inbounds (i8*, i8** @_TWVMBo, i32 17)
  unowned(unsafe) var pu:  P
  // CHECK: store i8** getelementptr inbounds (i8*, i8** @_TWVXwGSqBO_, i32 17)
  weak            var pwo: P?
  // CHECK: store i8** getelementptr inbounds (i8*, i8** @_TWVXwGSqBO_, i32 17)
  weak            var pwi: P!

  // CHECK: store i8** getelementptr inbounds (i8*, i8** @_TWVXoBO, i32 17)
  unowned(safe)   var pqs:  protocol<P, Q>
  // CHECK: store i8** getelementptr inbounds (i8*, i8** @_TWVMBo, i32 17)
  unowned(unsafe) var pqu:  protocol<P, Q>
  // CHECK: store i8** getelementptr inbounds (i8*, i8** @_TWVXwGSqBO_, i32 17)
  weak            var pqwo: protocol<P, Q>?
  // CHECK: store i8** getelementptr inbounds (i8*, i8** @_TWVXwGSqBO_, i32 17)
  weak            var pqwi: protocol<P, Q>!

  // -- Open-code layouts when there are witness tables.
  // CHECK-64: store i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @type_layout_16_8_7fffffff_bt, i32 0, i32 0)
  unowned(safe)   var pqrs:  protocol<P, Q, NonObjC>
  // CHECK-64: store i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @type_layout_16_8_7fffffff_pod, i32 0, i32 0)
  unowned(unsafe) var pqru:  protocol<P, Q, NonObjC>
  // CHECK-64: store i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @type_layout_16_8_1, i32 0, i32 0)
  weak            var pqrwo: protocol<P, Q, NonObjC>?
  // CHECK-64: store i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @type_layout_16_8_1, i32 0, i32 0)
  weak            var pqrwi: protocol<P, Q, NonObjC>!
}
