mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
It used to be done with a library intrinsic which returns the array and an element address pointer. A `mark_dependence` was used to "connect" the two results. But this resulted in completely wrong OSSA after inlining. It just didn't get caught be the verifier because the SIL was obfuscated by address-pointer conversions. Now we don't use the second result (= the element address) of the intrinsic but generate a correct borrow scope from the first (= array) result. Within that borrow scope we project out the element address with a `ref_tail_addr` instruction. This relies on knowledge of the internal Array data structures. However those data structures are baked into the ABI since a long time and will not change.
82 lines
2.6 KiB
C++
82 lines
2.6 KiB
C++
//===--- Varargs.h - SIL generation for (native) Swift varargs --*- C++ -*-===//
|
|
//
|
|
// This source file is part of the Swift.org open source project
|
|
//
|
|
// Copyright (c) 2014 - 2017 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// A storage structure for holding a destructured rvalue with an optional
|
|
// cleanup(s).
|
|
// Ownership of the rvalue can be "forwarded" to disable the associated
|
|
// cleanup(s).
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef SWIFT_LOWERING_VARARGS_H
|
|
#define SWIFT_LOWERING_VARARGS_H
|
|
|
|
#include "ManagedValue.h"
|
|
#include "swift/SIL/AbstractionPattern.h"
|
|
|
|
namespace swift {
|
|
namespace Lowering {
|
|
class SILGenFunction;
|
|
class TypeLowering;
|
|
|
|
/// Information about a varargs emission.
|
|
class VarargsInfo {
|
|
ManagedValue Array;
|
|
CleanupHandle borrowCleanup;
|
|
CleanupHandle AbortCleanup;
|
|
SILValue BaseAddress;
|
|
AbstractionPattern BasePattern;
|
|
const TypeLowering &BaseTL;
|
|
public:
|
|
VarargsInfo(ManagedValue array, CleanupHandle borrowCleanup, CleanupHandle abortCleanup,
|
|
SILValue baseAddress, const TypeLowering &baseTL,
|
|
AbstractionPattern basePattern)
|
|
: Array(array), borrowCleanup(borrowCleanup), AbortCleanup(abortCleanup),
|
|
BaseAddress(baseAddress), BasePattern(basePattern), BaseTL(baseTL) {}
|
|
|
|
/// Return the array value. emitEndVarargs() is really the only
|
|
/// function that should be accessing this directly.
|
|
ManagedValue getArray() const {
|
|
return Array;
|
|
}
|
|
|
|
CleanupHandle getBorrowCleanup() const { return borrowCleanup; }
|
|
|
|
CleanupHandle getAbortCleanup() const { return AbortCleanup; }
|
|
|
|
/// An address of the lowered type.
|
|
SILValue getBaseAddress() const { return BaseAddress; }
|
|
|
|
AbstractionPattern getBaseAbstractionPattern() const {
|
|
return BasePattern;
|
|
}
|
|
|
|
const TypeLowering &getBaseTypeLowering() const {
|
|
return BaseTL;
|
|
}
|
|
};
|
|
|
|
/// Begin a varargs emission sequence.
|
|
VarargsInfo emitBeginVarargs(SILGenFunction &SGF, SILLocation loc,
|
|
CanType baseTy, CanType arrayTy,
|
|
unsigned numElements);
|
|
|
|
/// Successfully end a varargs emission sequence.
|
|
ManagedValue emitEndVarargs(SILGenFunction &SGF, SILLocation loc,
|
|
VarargsInfo &&varargs,
|
|
unsigned numElements);
|
|
|
|
} // end namespace Lowering
|
|
} // end namespace swift
|
|
|
|
#endif
|