diff --git a/include/swift/SIL/ApplySite.h b/include/swift/SIL/ApplySite.h index de97fef3e9bf0..e11ca87b047b6 100644 --- a/include/swift/SIL/ApplySite.h +++ b/include/swift/SIL/ApplySite.h @@ -21,6 +21,7 @@ #ifndef SWIFT_SIL_APPLYSITE_H #define SWIFT_SIL_APPLYSITE_H +#include "swift/Basic/STLExtras.h" #include "swift/SIL/SILArgument.h" #include "swift/SIL/SILBasicBlock.h" #include "swift/SIL/SILFunction.h" @@ -29,6 +30,8 @@ namespace swift { +class FullApplySite; + //===----------------------------------------------------------------------===// // ApplySite //===----------------------------------------------------------------------===// @@ -396,6 +399,10 @@ class ApplySite { llvm_unreachable("covered switch"); } + /// Returns true if \p op is an operand that passes an indirect + /// result argument to the apply site. + bool isIndirectResultOperand(const Operand &op) const; + /// Return whether the given apply is of a formally-throwing function /// which is statically known not to throw. bool isNonThrowing() const { @@ -425,6 +432,10 @@ class ApplySite { } void dump() const LLVM_ATTRIBUTE_USED { getInstruction()->dump(); } + + /// Attempt to cast this apply site to a full apply site, returning None on + /// failure. + Optional asFullApplySite() const; }; //===----------------------------------------------------------------------===// @@ -562,12 +573,6 @@ class FullApplySite : public ApplySite { return op.getOperandNumber() < getOperandIndexOfFirstArgument(); } - /// Returns true if \p op is an operand that passes an indirect - /// result argument to the apply site. - bool isIndirectResultOperand(const Operand &op) const { - return getCalleeArgIndex(op) < getNumIndirectSILResults(); - } - /// Is this an ApplySite that begins the evaluation of a coroutine. bool beginsCoroutineEvaluation() const { switch (getKind()) { @@ -637,6 +642,12 @@ class FullApplySite : public ApplySite { llvm_unreachable("covered switch isn't covered"); } + /// Returns true if \p op is an operand that passes an indirect + /// result argument to the apply site. + bool isIndirectResultOperand(const Operand &op) const { + return getCalleeArgIndex(op) < getNumIndirectSILResults(); + } + static FullApplySite getFromOpaqueValue(void *p) { return FullApplySite(p); } static bool classof(const SILInstruction *inst) { @@ -729,4 +740,23 @@ template <> struct DenseMapInfo<::swift::FullApplySite> { } // namespace llvm +//===----------------------------------------------------------------------===// +// Inline Definitions to work around Forward Declaration +//===----------------------------------------------------------------------===// + +namespace swift { + +inline Optional ApplySite::asFullApplySite() const { + return FullApplySite::isa(getInstruction()); +} + +inline bool ApplySite::isIndirectResultOperand(const Operand &op) const { + auto fas = asFullApplySite(); + if (!fas) + return false; + return fas->isIndirectResultOperand(op); +} + +} // namespace swift + #endif