Skip to content

[stdlib] Restore MemoryLayout.*(ofValue:) #4041

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Aug 12, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 6 additions & 9 deletions lib/Sema/MiscDiagnostics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2145,9 +2145,6 @@ bool AvailabilityWalker::diagnoseMemoryLayoutMigration(const ValueDecl *D,
.Case("sizeof", {"size", false})
.Case("alignof", {"alignment", false})
.Case("strideof", {"stride", false})
.Case("sizeofValue", {"size", true})
.Case("alignofValue", {"alignment", true})
.Case("strideofValue", {"stride", true})
.Default({});

if (KindValue.first.empty())
Expand All @@ -2162,7 +2159,7 @@ bool AvailabilityWalker::diagnoseMemoryLayoutMigration(const ValueDecl *D,

auto subject = args->getSubExpr();
if (!isValue) {
// sizeof(x.dynamicType) is equivalent to sizeofValue(x)
// sizeof(type(of: x)) is equivalent to sizeofValue(x)
if (auto DTE = dyn_cast<DynamicTypeExpr>(subject)) {
subject = DTE->getBase();
isValue = true;
Expand All @@ -2179,14 +2176,14 @@ bool AvailabilityWalker::diagnoseMemoryLayoutMigration(const ValueDecl *D,
if (isValue) {
auto valueType = subject->getType()->getRValueType();
if (!valueType || valueType->is<ErrorType>()) {
// If we dont have good argument, We cannot emit fix-it.
return true;
// If we don't have a suitable argument, we cannot emit a fix-it.
return true;
}

// NOTE: We are destructively replacing the source text here.
// For instance, `sizeof(x.doSomethig())` => `MemoryLayout<T>.size` where
// T is return type of `doSomething()`. If that function have any
// side effects, it will break the source.
// `sizeof(type(of: doSomething()))` => `MemoryLayout<T>.size`, where T is
// the return type of `doSomething()`. If that function has any side
// effects, this replacement will break the source.
diag.fixItReplace(call->getSourceRange(),
(Prefix + valueType->getString() + Suffix + Kind).str());
} else {
Expand Down
2 changes: 1 addition & 1 deletion stdlib/private/SwiftPrivateLibcExtras/Subprocess.swift
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ public func spawnChild(_ args: [String])

// If execve() encountered an error, we write the errno encountered to the
// parent write pipe.
let errnoSize = MemoryLayout._ofInstance(errno).size
let errnoSize = MemoryLayout.size(ofValue: errno)
var execveErrno = errno
let writtenBytes = withUnsafePointer(to: &execveErrno) {
write(childToParentPipe.writeFD, UnsafePointer($0), errnoSize)
Expand Down
2 changes: 1 addition & 1 deletion stdlib/public/SDK/Foundation/Data.swift
Original file line number Diff line number Diff line change
Expand Up @@ -669,7 +669,7 @@ public struct Data : ReferenceConvertible, Equatable, Hashable, RandomAccessColl
public mutating func next() -> UInt8? {
guard _idx < _endIdx else { return nil }
defer { _idx += 1 }
let bufferSize = MemoryLayout._ofInstance(_buffer).size
let bufferSize = MemoryLayout.size(ofValue: _buffer)
return withUnsafeMutablePointer(to: &_buffer) { ptr_ in
let ptr = UnsafeMutableRawPointer(ptr_).assumingMemoryBound(to: UInt8.self)
let bufferIdx = _idx % bufferSize
Expand Down
2 changes: 1 addition & 1 deletion stdlib/public/core/BridgeObjectiveC.swift
Original file line number Diff line number Diff line change
Expand Up @@ -546,7 +546,7 @@ internal struct _CocoaFastEnumerationStackBuf {
_item14 = _item0
_item15 = _item0

_sanityCheck(MemoryLayout._ofInstance(self).size >=
_sanityCheck(MemoryLayout.size(ofValue: self) >=
MemoryLayout<Optional<UnsafeRawPointer>>.size * count)
}
}
Expand Down
6 changes: 3 additions & 3 deletions stdlib/public/core/Builtin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public func sizeof<T>(_:T.Type) -> Int {
Builtin.unreachable()
}

@available(*, unavailable, message: "use MemoryLayout<T>.size instead.")
@available(*, unavailable, renamed: "MemoryLayout.size(ofValue:)")
public func sizeofValue<T>(_:T) -> Int {
Builtin.unreachable()
}
Expand All @@ -30,7 +30,7 @@ public func alignof<T>(_:T.Type) -> Int {
Builtin.unreachable()
}

@available(*, unavailable, message: "use MemoryLayout<T>.alignment instead.")
@available(*, unavailable, renamed: "MemoryLayout.alignment(ofValue:)")
public func alignofValue<T>(_:T) -> Int {
Builtin.unreachable()
}
Expand All @@ -40,7 +40,7 @@ public func strideof<T>(_:T.Type) -> Int {
Builtin.unreachable()
}

@available(*, unavailable, message: "use MemoryLayout<T>.stride instead.")
@available(*, unavailable, renamed: "MemoryLayout.stride(ofValue:)")
public func strideofValue<T>(_:T) -> Int {
Builtin.unreachable()
}
Expand Down
2 changes: 1 addition & 1 deletion stdlib/public/core/Character.swift
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ public struct Character :
let (count, initialUTF8) = s._core._encodeSomeUTF8(from: 0)
// Notice that the result of sizeof() is a small non-zero number and can't
// overflow when multiplied by 8.
let bits = MemoryLayout._ofInstance(initialUTF8).size &* 8 &- 1
let bits = MemoryLayout.size(ofValue: initialUTF8) &* 8 &- 1
if _fastPath(
count == s._core.count && (initialUTF8 & (1 << numericCast(bits))) != 0) {
_representation = .small(Builtin.trunc_Int64_Int63(initialUTF8._value))
Expand Down
47 changes: 33 additions & 14 deletions stdlib/public/core/MemoryLayout.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,40 +12,59 @@

/// The memory layout of a type, describing its size, stride, and alignment.
public enum MemoryLayout<T> {

/// The contiguous memory footprint of the type.
/// The contiguous memory footprint of `T`.
///
/// The `size` property for a type `T` does not include any
/// dynamically-allocated or "remote" storage. In particular,
/// `MemoryLayout<T>.size`, when `T` is a class type, is the same regardless
/// of how many stored properties `T` has.
/// Does not include any dynamically-allocated or "remote" storage. In
/// particular, `MemoryLayout<T>.size`, when `T` is a class type, is the same
/// regardless of how many stored properties `T` has.
@_transparent
public static var size: Int {
return Int(Builtin.sizeof(T.self))
}

/// The number of bytes from the start of one instance to the start of the
/// next, when stored in a contiguous array.
/// The number of bytes from the start of one instance of `T` to the start of
/// the next in an `Array<T>`.
///
/// This is the same as the number of bytes moved when an `UnsafePointer<T>`
/// is incremented. The type may have a lower minimal alignment that trades
/// runtime performance for space efficiency. The result is always positive.
/// is incremented. `T` may have a lower minimal alignment that trades runtime
/// performance for space efficiency. The result is always positive.
@_transparent
public static var stride: Int {
return Int(Builtin.strideof_nonzero(T.self))
}

/// The default memory alignment of the type.
/// The default memory alignment of `T`.
@_transparent
public static var alignment: Int {
return Int(Builtin.alignof(T.self))
}
}

extension MemoryLayout {
/// Returns the contiguous memory footprint of `T`.
///
/// Does not include any dynamically-allocated or "remote" storage. In
/// particular, `MemoryLayout.size(ofValue: x)`, when `x` is a class instance,
/// is the same regardless of how many stored properties `T` has.
@_transparent
public static func size(ofValue _: T) -> Int {
return MemoryLayout.size
}

/// Returns the number of bytes from the start of one instance of `T` to the
/// start of the next in an `Array<T>`.
///
/// This is the same as the number of bytes moved when an `UnsafePointer<T>`
/// is incremented. `T` may have a lower minimal alignment that trades runtime
/// performance for space efficiency. The result is always positive.
@_transparent
public static func stride(ofValue _: T) -> Int {
return MemoryLayout.stride
}

/// Returns the default memory alignment of `T`.
@_transparent
public // @testable
static func _ofInstance(_: @autoclosure () -> T) -> MemoryLayout<T>.Type {
return MemoryLayout<T>.self
public static func alignment(ofValue _: T) -> Int {
return MemoryLayout.alignment
}
}
2 changes: 1 addition & 1 deletion stdlib/public/core/Unicode.swift
Original file line number Diff line number Diff line change
Expand Up @@ -839,7 +839,7 @@ internal func _transcodeSomeUTF16AsUTF8<Input>(
nextIndex = input.index(nextIndex, offsetBy: utf16Length)
}
// FIXME: Annoying check, courtesy of <rdar://problem/16740169>
if utf8Count < MemoryLayout._ofInstance(result).size {
if utf8Count < MemoryLayout.size(ofValue: result) {
result |= ~0 << numericCast(utf8Count * 8)
}
return (nextIndex, result)
Expand Down
8 changes: 4 additions & 4 deletions stdlib/public/core/VarArgs.swift
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ extension Int64 : CVarArg, _CVarArgAligned {
/// the value returned by `_cVarArgEncoding`.
public var _cVarArgAlignment: Int {
// FIXME: alignof differs from the ABI alignment on some architectures
return MemoryLayout._ofInstance(self).alignment
return MemoryLayout.alignment(ofValue: self)
}
}

Expand Down Expand Up @@ -192,7 +192,7 @@ extension UInt64 : CVarArg, _CVarArgAligned {
/// the value returned by `_cVarArgEncoding`.
public var _cVarArgAlignment: Int {
// FIXME: alignof differs from the ABI alignment on some architectures
return MemoryLayout._ofInstance(self).alignment
return MemoryLayout.alignment(ofValue: self)
}
}

Expand Down Expand Up @@ -265,7 +265,7 @@ extension Float : _CVarArgPassedAsDouble, _CVarArgAligned {
/// the value returned by `_cVarArgEncoding`.
public var _cVarArgAlignment: Int {
// FIXME: alignof differs from the ABI alignment on some architectures
return MemoryLayout._ofInstance(Double(self)).alignment
return MemoryLayout.alignment(ofValue: Double(self))
}
}

Expand All @@ -280,7 +280,7 @@ extension Double : _CVarArgPassedAsDouble, _CVarArgAligned {
/// the value returned by `_cVarArgEncoding`.
public var _cVarArgAlignment: Int {
// FIXME: alignof differs from the ABI alignment on some architectures
return MemoryLayout._ofInstance(self).alignment
return MemoryLayout.alignment(ofValue: self)
}
}

Expand Down
2 changes: 1 addition & 1 deletion test/1_stdlib/Character.swift
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ CharacterTests.test("sizeof") {
expectTrue(size1 == 8 || size1 == 9)

var a: Character = "a"
let size2 = MemoryLayout._ofInstance(a).size
let size2 = MemoryLayout.size(ofValue: a)
expectTrue(size2 == 8 || size2 == 9)

expectEqual(size1, size2)
Expand Down
6 changes: 3 additions & 3 deletions test/1_stdlib/Renames.swift
Original file line number Diff line number Diff line change
Expand Up @@ -284,9 +284,9 @@ func _MemoryLayout<T>(t: T) {
_ = sizeof(T.self) // expected-error {{'sizeof' is unavailable: use MemoryLayout<T>.size instead.}} {{7-14=MemoryLayout<}} {{15-21=>.size}} {{none}}
_ = alignof(T.self) // expected-error {{'alignof' is unavailable: use MemoryLayout<T>.alignment instead.}} {{7-15=MemoryLayout<}} {{16-22=>.alignment}} {{none}}
_ = strideof(T.self) // expected-error {{'strideof' is unavailable: use MemoryLayout<T>.stride instead.}} {{7-16=MemoryLayout<}} {{17-23=>.stride}} {{none}}
_ = sizeofValue(t) // expected-error {{'sizeofValue' is unavailable: use MemoryLayout<T>.size instead.}} {{7-21=MemoryLayout<T>.size}} {{none}}
_ = alignofValue(t) // expected-error {{'alignofValue' is unavailable: use MemoryLayout<T>.alignment instead.}} {{7-22=MemoryLayout<T>.alignment}} {{none}}
_ = strideofValue(t) // expected-error {{'strideofValue' is unavailable: use MemoryLayout<T>.stride instead.}} {{7-23=MemoryLayout<T>.stride}} {{none}}
_ = sizeofValue(t) // expected-error {{'sizeofValue' has been replaced by 'MemoryLayout.size(ofValue:)'}} {{7-18=MemoryLayout.size}} {{19-19=ofValue: }} {{none}}
_ = alignofValue(t) // expected-error {{'alignofValue' has been replaced by 'MemoryLayout.alignment(ofValue:)'}} {{7-19=MemoryLayout.alignment}} {{20-20=ofValue: }} {{none}}
_ = strideofValue(t) // expected-error {{'strideofValue' has been replaced by 'MemoryLayout.stride(ofValue:)'}} {{7-20=MemoryLayout.stride}} {{21-21=ofValue: }} {{none}}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add tests for the new migration fixits that you added?

Copy link
Collaborator Author

@xwu xwu Aug 5, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will do, as soon as I'm in front of a computer this afternoon.

Edit: done.

}

func _Mirror() {
Expand Down
2 changes: 1 addition & 1 deletion test/Interpreter/SDK/c_pointers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ puts(s)
//

var unsorted = [3, 14, 15, 9, 2, 6, 5]
qsort(&unsorted, unsorted.count, MemoryLayout._ofInstance(unsorted[0]).size) { a, b in
qsort(&unsorted, unsorted.count, MemoryLayout.size(ofValue: unsorted[0])) { a, b in
return Int32(a!.load(as: Int.self) - b!.load(as: Int.self))
}
// CHECK-NEXT: [2, 3, 5, 6, 9, 14, 15]
Expand Down
2 changes: 1 addition & 1 deletion test/Interpreter/enum.swift
Original file line number Diff line number Diff line change
Expand Up @@ -440,7 +440,7 @@ struct OptionalTuple<T> {
}
}
func test_optional_generic_tuple<T>(_ a: OptionalTuple<T>) -> T {
print("optional pair is same size as pair: \(MemoryLayout._ofInstance(a).size == MemoryLayout<T>.size*2)")
print("optional pair is same size as pair: \(MemoryLayout.size(ofValue: a) == MemoryLayout<T>.size*2)")
return a.value!.0
}
print("Int result: \(test_optional_generic_tuple(OptionalTuple<Int>((5, 6))))")
Expand Down
6 changes: 1 addition & 5 deletions test/expr/expressions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -891,9 +891,5 @@ func se0101<P: Pse0101>(x: Cse0101<P>) {
_ = sizeof(Cse0101<P>.self) // expected-error {{'sizeof' is unavailable: use MemoryLayout<T>.size instead.}} {{7-14=MemoryLayout<}} {{24-30=>.size}} {{none}}
_ = alignof(Cse0101<P>.T.self) // expected-error {{'alignof' is unavailable: use MemoryLayout<T>.alignment instead.}} {{7-15=MemoryLayout<}} {{27-33=>.alignment}} {{none}}
_ = strideof(P.Type.self) // expected-error {{'strideof' is unavailable: use MemoryLayout<T>.stride instead.}} {{7-16=MemoryLayout<}} {{22-28=>.stride}} {{none}}
_ = sizeof(type(of: x)) // expected-error {{'sizeof' is unavailable: use MemoryLayout<T>.size instead.}} {{7-26=MemoryLayout<Cse0101<P>>.size}} {{none}}/

_ = sizeofValue(x) // expected-error {{'sizeofValue' is unavailable: use MemoryLayout<T>.size instead.}} {{7-21=MemoryLayout<Cse0101<P>>.size}} {{none}}
_ = alignofValue(x.val) // expected-error {{'alignofValue' is unavailable: use MemoryLayout<T>.alignment instead.}} {{7-26=MemoryLayout<P>.alignment}} {{none}}
_ = strideofValue(x.val.getIt()) // expected-error {{'strideofValue' is unavailable: use MemoryLayout<T>.stride instead.}} {{7-35=MemoryLayout<P.Value>.stride}} {{none}}
_ = sizeof(type(of: x)) // expected-error {{'sizeof' is unavailable: use MemoryLayout<T>.size instead.}} {{7-26=MemoryLayout<Cse0101<P>>.size}} {{none}}
}
4 changes: 2 additions & 2 deletions validation-test/stdlib/Arrays.swift.gyb
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,9 @@ var ArrayTestSuite = TestSuite("Array")
ArrayTestSuite.test("sizeof") {
var a = [ 10, 20, 30 ]
#if arch(i386) || arch(arm)
expectEqual(4, MemoryLayout._ofInstance(a).size)
expectEqual(4, MemoryLayout.size(ofValue: a))
#else
expectEqual(8, MemoryLayout._ofInstance(a).size)
expectEqual(8, MemoryLayout.size(ofValue: a))
#endif
}

Expand Down
4 changes: 2 additions & 2 deletions validation-test/stdlib/Dictionary.swift
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,9 @@ DictionaryTestSuite.test("AssociatedTypes") {
DictionaryTestSuite.test("sizeof") {
var dict = [1: "meow", 2: "meow"]
#if arch(i386) || arch(arm)
expectEqual(4, MemoryLayout._ofInstance(dict).size)
expectEqual(4, MemoryLayout.size(ofValue: dict))
#else
expectEqual(8, MemoryLayout._ofInstance(dict).size)
expectEqual(8, MemoryLayout.size(ofValue: dict))
#endif
}

Expand Down
2 changes: 1 addition & 1 deletion validation-test/stdlib/NSNumberBridging.swift.gyb
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ extension ${Self} {
func toNSNumberByteArray() -> [UInt8] {
var v = self.bitPattern
var result: [UInt8] = []
for _ in 0 ..< MemoryLayout._ofInstance(v).size {
for _ in 0 ..< MemoryLayout.size(ofValue: v) {
result.append(UInt8(v & 0xff))
v = v >> 8
}
Expand Down
4 changes: 2 additions & 2 deletions validation-test/stdlib/OpenCLSDKOverlay.swift
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ tests.test("clSetKernelArgsListAPPLE") {
kernel!, 3,
0, MemoryLayout<cl_mem>.size, inputPtr,
1, MemoryLayout<cl_mem>.size, outputPtr,
2, MemoryLayout._ofInstance(count).size, countPtr)
2, MemoryLayout.size(ofValue: count), countPtr)
}
}
}
Expand All @@ -208,7 +208,7 @@ tests.test("clSetKernelArgsListAPPLE") {

// Get the maximum work group size for executing the kernel on the device
//
err = clGetKernelWorkGroupInfo(kernel, device_id, cl_kernel_work_group_info(CL_KERNEL_WORK_GROUP_SIZE), MemoryLayout._ofInstance(local).size, &local, nil)
err = clGetKernelWorkGroupInfo(kernel, device_id, cl_kernel_work_group_info(CL_KERNEL_WORK_GROUP_SIZE), MemoryLayout.size(ofValue: local), &local, nil)
if (err != CL_SUCCESS)
{
print("Error: Failed to retrieve kernel work group info! \(err)")
Expand Down
4 changes: 2 additions & 2 deletions validation-test/stdlib/Set.swift
Original file line number Diff line number Diff line change
Expand Up @@ -325,9 +325,9 @@ SetTestSuite.test("AssociatedTypes") {
SetTestSuite.test("sizeof") {
var s = Set(["Hello", "world"])
#if arch(i386) || arch(arm)
expectEqual(4, MemoryLayout._ofInstance(s).size)
expectEqual(4, MemoryLayout.size(ofValue: s))
#else
expectEqual(8, MemoryLayout._ofInstance(s).size)
expectEqual(8, MemoryLayout.size(ofValue: s))
#endif
}

Expand Down