mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
* add `UnownedRetainInst` and `UnownedReleaseInst` * add `var value` to `RetainValueInst` and `ReleaseValueInst` * make the protocol `UnaryInstruction` be an `Instruction` * add `var Type.isValueTypeWithDeinit` * add `var Type.isUnownedStorageType` * add `var OperandArray.values`
151 lines
4.9 KiB
Swift
151 lines
4.9 KiB
Swift
//===--- ApplySite.swift - Defines the ApplySite protocols ----------------===//
|
|
//
|
|
// This source file is part of the Swift.org open source project
|
|
//
|
|
// Copyright (c) 2014 - 2021 Apple Inc. and the Swift project authors
|
|
// Licensed under Apache License v2.0 with Runtime Library Exception
|
|
//
|
|
// See https://swift.org/LICENSE.txt for license information
|
|
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
import SILBridging
|
|
|
|
public struct ApplyOperands {
|
|
public static let calleeOperandIndex: Int = 0
|
|
public static let firstArgumentIndex = 1
|
|
}
|
|
|
|
public protocol ApplySite : Instruction {
|
|
var operands: OperandArray { get }
|
|
var numArguments: Int { get }
|
|
var substitutionMap: SubstitutionMap { get }
|
|
|
|
/// Converts an argument index of the apply to the corresponding argument index of the callee.
|
|
///
|
|
/// For a FullApplySite this is always a 1-to-1 mapping.
|
|
/// For a `partial_apply` the callee index can be higher than the caller's argument index
|
|
/// because the arguments to `partial_apply` are a suffix of the callee.
|
|
///
|
|
/// Example:
|
|
/// ```
|
|
/// func callee(a, b, c, d, e) { }
|
|
///
|
|
/// %pa = partial_apply @callee(c, d, e)
|
|
/// // caller indices: 0, 1, 2
|
|
/// // callee indices: 2, 3, 4
|
|
///
|
|
/// %a = apply %pa (a, b)
|
|
/// // caller indices: 0, 1
|
|
/// // callee indices: 0, 1
|
|
/// ```
|
|
func calleeArgIndex(callerArgIndex: Int) -> Int
|
|
|
|
/// Converts an argument index of a callee to the corresponding argument index of the apply.
|
|
///
|
|
/// If the apply does not actually apply that argument, it returns nil.
|
|
/// Otherwise, for a FullApplySite this is always a 1-to-1 mapping.
|
|
/// For a `partial_apply` the caller index can be lower than the callee's argument index
|
|
/// because the arguments to `partial_apply` are a suffix of the callee.
|
|
///
|
|
/// Example:
|
|
/// ```
|
|
/// func callee(a, b, c, d, e) { }
|
|
/// // callee indices: 0, 1, 2, 3, 4
|
|
/// // caller indices in %pa: -, -, 0, 1, 2 ("-" == nil)
|
|
/// // caller indices in %a: 0, 1, -, -, -
|
|
///
|
|
/// %pa = partial_apply @callee(c, d, e)
|
|
/// %a = apply %pa (a, b)
|
|
/// ```
|
|
func callerArgIndex(calleeArgIndex: Int) -> Int?
|
|
|
|
func getArgumentConvention(calleeArgIndex: Int) -> ArgumentConvention
|
|
}
|
|
|
|
extension ApplySite {
|
|
public var callee: Value { operands[ApplyOperands.calleeOperandIndex].value }
|
|
|
|
/// Returns the subset of operands which are argument operands.
|
|
///
|
|
/// This does not include the callee function operand.
|
|
public var argumentOperands: OperandArray {
|
|
let numArgs = bridged.ApplySite_getNumArguments()
|
|
let offset = ApplyOperands.firstArgumentIndex
|
|
return operands[offset..<(numArgs + offset)]
|
|
}
|
|
|
|
/// Returns the subset of operand values which are arguments.
|
|
///
|
|
/// This does not include the callee function operand.
|
|
public var arguments: LazyMapSequence<OperandArray, Value> {
|
|
argumentOperands.values
|
|
}
|
|
|
|
public var substitutionMap: SubstitutionMap {
|
|
SubstitutionMap(bridged.ApplySite_getSubstitutionMap())
|
|
}
|
|
|
|
/// Returns the argument index of an operand.
|
|
///
|
|
/// Returns nil if 'operand' is not an argument operand. This is the case if
|
|
/// it's the callee function operand.
|
|
public func argumentIndex(of operand: Operand) -> Int? {
|
|
let opIdx = operand.index
|
|
if opIdx >= ApplyOperands.firstArgumentIndex &&
|
|
opIdx <= ApplyOperands.firstArgumentIndex + numArguments {
|
|
return opIdx - ApplyOperands.firstArgumentIndex
|
|
}
|
|
return nil
|
|
}
|
|
|
|
/// Returns true if `operand` is the callee function operand and not am argument operand.
|
|
public func isCalleeOperand(_ operand: Operand) -> Bool {
|
|
return operand.index < ApplyOperands.firstArgumentIndex
|
|
}
|
|
|
|
public func getArgumentConvention(calleeArgIndex: Int) -> ArgumentConvention {
|
|
return bridged.ApplySite_getArgumentConvention(calleeArgIndex).convention
|
|
}
|
|
|
|
public var referencedFunction: Function? {
|
|
if let fri = callee as? FunctionRefInst {
|
|
return fri.referencedFunction
|
|
}
|
|
return nil
|
|
}
|
|
|
|
public func hasSemanticsAttribute(_ attr: StaticString) -> Bool {
|
|
if let callee = referencedFunction {
|
|
return callee.hasSemanticsAttribute(attr)
|
|
}
|
|
return false
|
|
}
|
|
}
|
|
|
|
public protocol FullApplySite : ApplySite {
|
|
var singleDirectResult: Value? { get }
|
|
}
|
|
|
|
extension FullApplySite {
|
|
public func calleeArgIndex(callerArgIndex: Int) -> Int {
|
|
assert(callerArgIndex >= 0 && callerArgIndex < numArguments)
|
|
return callerArgIndex
|
|
}
|
|
|
|
public func callerArgIndex(calleeArgIndex: Int) -> Int? {
|
|
if calleeArgIndex < numArguments {
|
|
return calleeArgIndex
|
|
}
|
|
return nil
|
|
}
|
|
|
|
/// The number of indirect out arguments.
|
|
///
|
|
/// 0 if the callee has a direct or no return value and 1, if it has an indirect return value.
|
|
public var numIndirectResultArguments: Int {
|
|
return bridged.FullApplySite_numIndirectResultArguments()
|
|
}
|
|
}
|