Skip to content

Commit 4b110fc

Browse files
authored
---
yaml --- r: 343351 b: refs/heads/master-rebranch c: ed0d5dd h: refs/heads/master i: 343349: 00cee55 343347: bd966d8 343343: 987f468
1 parent 9aa5dde commit 4b110fc

File tree

8 files changed

+334
-151
lines changed

8 files changed

+334
-151
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1455,7 +1455,7 @@ refs/tags/swift-DEVELOPMENT-SNAPSHOT-2019-08-02-a: ddd2b2976aa9bfde5f20fe37f6bd2
14551455
refs/tags/swift-DEVELOPMENT-SNAPSHOT-2019-08-03-a: 171cc166f2abeb5ca2a4003700a8a78a108bd300
14561456
refs/heads/benlangmuir-patch-1: baaebaf39d52f3bf36710d4fe40cf212e996b212
14571457
refs/heads/i-do-redeclare: 8c4e6d5de5c1e3f0a2cedccf319df713ea22c48e
1458-
refs/heads/master-rebranch: feb48a61b99871829ebbbdb74139176845c1af9b
1458+
refs/heads/master-rebranch: ed0d5ddb2a9f0b10e45ffc5421bf44bd2c24c4c7
14591459
refs/heads/rdar-53901732: 9bd06af3284e18a109cdbf9aa59d833b24eeca7b
14601460
refs/heads/revert-26776-subst-always-returns-a-type: 1b8e18fdd391903a348970a4c848995d4cdd789c
14611461
refs/heads/tensorflow-merge: 8b854f62f80d4476cb383d43c4aac2001dde3cec

branches/master-rebranch/lib/Sema/DerivedConformanceEquatableHashable.cpp

Lines changed: 73 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,17 @@ enumElementPayloadSubpattern(EnumElementDecl *enumElementDecl,
257257
return pat;
258258
}
259259

260+
/// Build a type-checked integer literal.
261+
static IntegerLiteralExpr *buildIntegerLiteral(ASTContext &C, unsigned index) {
262+
Type intType = C.getIntDecl()->getDeclaredType();
263+
264+
auto literal = IntegerLiteralExpr::createFromUnsigned(C, index);
265+
literal->setType(intType);
266+
literal->setBuiltinInitializer(C.getIntBuiltinInitDecl(C.getIntDecl()));
267+
268+
return literal;
269+
}
270+
260271
/// Create AST statements which convert from an enum to an Int with a switch.
261272
/// \p stmts The generated statements are appended to this vector.
262273
/// \p parentDC Either an extension or the enum itself.
@@ -298,15 +309,20 @@ static DeclRefExpr *convertEnumToIndex(SmallVectorImpl<ASTNode> &stmts,
298309
SourceLoc(), SourceLoc(),
299310
Identifier(), elt, nullptr);
300311
pat->setImplicit();
312+
pat->setType(enumType);
301313

302314
auto labelItem = CaseLabelItem(pat);
303315

304316
// generate: indexVar = <index>
305-
auto indexExpr = IntegerLiteralExpr::createFromUnsigned(C, index++);
317+
auto indexExpr = buildIntegerLiteral(C, index++);
318+
306319
auto indexRef = new (C) DeclRefExpr(indexVar, DeclNameLoc(),
307-
/*implicit*/true);
320+
/*implicit*/true,
321+
AccessSemantics::Ordinary,
322+
LValueType::get(intType));
308323
auto assignExpr = new (C) AssignExpr(indexRef, SourceLoc(),
309324
indexExpr, /*implicit*/ true);
325+
assignExpr->setType(TupleType::getEmpty(C));
310326
auto body = BraceStmt::create(C, SourceLoc(), ASTNode(assignExpr),
311327
SourceLoc());
312328
cases.push_back(CaseStmt::create(C, SourceLoc(), labelItem, SourceLoc(),
@@ -316,7 +332,9 @@ static DeclRefExpr *convertEnumToIndex(SmallVectorImpl<ASTNode> &stmts,
316332

317333
// generate: switch enumVar { }
318334
auto enumRef = new (C) DeclRefExpr(enumVarDecl, DeclNameLoc(),
319-
/*implicit*/true);
335+
/*implicit*/true,
336+
AccessSemantics::Ordinary,
337+
enumVarDecl->getType());
320338
auto switchStmt = SwitchStmt::create(LabeledStmtInfo(), SourceLoc(), enumRef,
321339
SourceLoc(), cases, SourceLoc(), C);
322340

@@ -381,17 +399,23 @@ deriveBodyEquatable_enum_uninhabited_eq(AbstractFunctionDecl *eqDecl, void *) {
381399
SmallVector<ASTNode, 0> cases;
382400

383401
// switch (a, b) { }
384-
auto aRef = new (C) DeclRefExpr(aParam, DeclNameLoc(), /*implicit*/ true);
385-
auto bRef = new (C) DeclRefExpr(bParam, DeclNameLoc(), /*implicit*/ true);
402+
auto aRef = new (C) DeclRefExpr(aParam, DeclNameLoc(), /*implicit*/ true,
403+
AccessSemantics::Ordinary,
404+
aParam->getType());
405+
auto bRef = new (C) DeclRefExpr(bParam, DeclNameLoc(), /*implicit*/ true,
406+
AccessSemantics::Ordinary,
407+
bParam->getType());
408+
TupleTypeElt abTupleElts[2] = { aParam->getType(), bParam->getType() };
386409
auto abExpr = TupleExpr::create(C, SourceLoc(), {aRef, bRef}, {}, {},
387410
SourceLoc(), /*HasTrailingClosure*/ false,
388-
/*implicit*/ true);
411+
/*implicit*/ true,
412+
TupleType::get(abTupleElts, C));
389413
auto switchStmt = SwitchStmt::create(LabeledStmtInfo(), SourceLoc(), abExpr,
390414
SourceLoc(), cases, SourceLoc(), C);
391415
statements.push_back(switchStmt);
392416

393417
auto body = BraceStmt::create(C, SourceLoc(), statements, SourceLoc());
394-
return { body, /*isTypeChecked=*/false };
418+
return { body, /*isTypeChecked=*/true };
395419
}
396420

397421
/// Derive the body for an '==' operator for an enum that has no associated
@@ -439,16 +463,20 @@ deriveBodyEquatable_enum_noAssociatedValues_eq(AbstractFunctionDecl *eqDecl,
439463
fnType);
440464
}
441465

466+
TupleTypeElt abTupleElts[2] = { aIndex->getType(), bIndex->getType() };
442467
TupleExpr *abTuple = TupleExpr::create(C, SourceLoc(), { aIndex, bIndex },
443468
{ }, { }, SourceLoc(),
444469
/*HasTrailingClosure*/ false,
445-
/*Implicit*/ true);
470+
/*Implicit*/ true,
471+
TupleType::get(abTupleElts, C));
446472

447-
auto *cmpExpr = new (C) BinaryExpr(cmpFuncExpr, abTuple, /*implicit*/ true);
473+
auto *cmpExpr = new (C) BinaryExpr(
474+
cmpFuncExpr, abTuple, /*implicit*/ true,
475+
fnType->castTo<FunctionType>()->getResult());
448476
statements.push_back(new (C) ReturnStmt(SourceLoc(), cmpExpr));
449477

450478
BraceStmt *body = BraceStmt::create(C, SourceLoc(), statements, SourceLoc());
451-
return { body, /*isTypeChecked=*/false };
479+
return { body, /*isTypeChecked=*/true };
452480
}
453481

454482
/// Derive the body for an '==' operator for an enum where at least one of the
@@ -1132,19 +1160,49 @@ deriveBodyHashable_hashValue(AbstractFunctionDecl *hashValueDecl, void *) {
11321160
ASTContext &C = parentDC->getASTContext();
11331161

11341162
// return _hashValue(for: self)
1135-
auto *hashFunc = C.getHashValueForDecl();
1136-
auto hashExpr = new (C) DeclRefExpr(hashFunc, DeclNameLoc(),
1137-
/*implicit*/ true);
1163+
1164+
// 'self'
11381165
auto selfDecl = hashValueDecl->getImplicitSelfDecl();
1166+
Type selfType = selfDecl->getType();
11391167
auto selfRef = new (C) DeclRefExpr(selfDecl, DeclNameLoc(),
1140-
/*implicit*/ true);
1168+
/*implicit*/ true,
1169+
AccessSemantics::Ordinary,
1170+
selfType);
1171+
1172+
// _hashValue(for:)
1173+
auto *hashFunc = C.getHashValueForDecl();
1174+
if (!hashFunc->hasInterfaceType())
1175+
static_cast<TypeChecker *>(C.getLazyResolver())->validateDecl(hashFunc);
1176+
1177+
auto substitutions = SubstitutionMap::get(
1178+
hashFunc->getGenericSignature(),
1179+
[&](SubstitutableType *dependentType) {
1180+
if (auto gp = dyn_cast<GenericTypeParamType>(dependentType)) {
1181+
if (gp->getDepth() == 0 && gp->getIndex() == 0)
1182+
return selfType;
1183+
}
1184+
1185+
return Type(dependentType);
1186+
},
1187+
LookUpConformanceInModule(hashValueDecl->getModuleContext()));
1188+
ConcreteDeclRef hashFuncRef(hashFunc, substitutions);
1189+
1190+
Type hashFuncType = hashFunc->getInterfaceType().subst(substitutions);
1191+
auto hashExpr = new (C) DeclRefExpr(hashFuncRef, DeclNameLoc(),
1192+
/*implicit*/ true,
1193+
AccessSemantics::Ordinary,
1194+
hashFuncType);
1195+
Type hashFuncResultType =
1196+
hashFuncType->castTo<AnyFunctionType>()->getResult();
11411197
auto callExpr = CallExpr::createImplicit(C, hashExpr,
11421198
{ selfRef }, { C.Id_for });
1199+
callExpr->setType(hashFuncResultType);
1200+
11431201
auto returnStmt = new (C) ReturnStmt(SourceLoc(), callExpr);
11441202

11451203
auto body = BraceStmt::create(C, SourceLoc(), {returnStmt}, SourceLoc(),
11461204
/*implicit*/ true);
1147-
return { body, /*isTypeChecked=*/false };
1205+
return { body, /*isTypeChecked=*/true };
11481206
}
11491207

11501208
/// Derive a 'hashValue' implementation.

branches/master-rebranch/stdlib/private/OSLog/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ add_swift_target_library(swiftOSLogPrototype
44

55
OSLog.swift
66
OSLogMessage.swift
7+
OSLogIntegerTypes.swift
78

89
SWIFT_MODULE_DEPENDS_IOS Darwin os
910
SWIFT_MODULE_DEPENDS_OSX Darwin os
Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
//===----------------- OSLogIntegerTypes.swift ----------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
// This file defines extensions for interpolating integer expressions into a
14+
// OSLogMesage. It defines `appendInterpolation` functions for standard integer
15+
// types. It also defines extensions for serializing integer types into the
16+
// argument buffer passed to os_log ABIs.
17+
//
18+
// The `appendInterpolation` functions defined in this file accept formatting
19+
// and privacy options along with the interpolated expression as shown below:
20+
//
21+
// "\(x, format: .hex, privacy: .private\)"
22+
23+
extension OSLogInterpolation {
24+
25+
/// Define interpolation for expressions of type Int.
26+
/// - Parameters:
27+
/// - number: the interpolated expression of type Int, which is autoclosured.
28+
/// - format: a formatting option available for integer types, defined by the
29+
/// enum `IntFormat`.
30+
/// - privacy: a privacy qualifier which is either private or public.
31+
/// The default is public.
32+
@_transparent
33+
@_optimize(none)
34+
public mutating func appendInterpolation(
35+
_ number: @autoclosure @escaping () -> Int,
36+
format: IntFormat = .decimal,
37+
privacy: Privacy = .public
38+
) {
39+
appendInteger(number, format: format, privacy: privacy)
40+
}
41+
42+
/// Define interpolation for expressions of type Int32.
43+
/// - Parameters:
44+
/// - number: the interpolated expression of type Int32, which is autoclosured.
45+
/// - format: a formatting option available for integer types, defined by the
46+
/// enum `IntFormat`.
47+
/// - privacy: a privacy qualifier which is either private or public.
48+
/// The default is public.
49+
@_transparent
50+
@_optimize(none)
51+
public mutating func appendInterpolation(
52+
_ number: @autoclosure @escaping () -> Int32,
53+
format: IntFormat = .decimal,
54+
privacy: Privacy = .public
55+
) {
56+
appendInteger(number, format: format, privacy: privacy)
57+
}
58+
59+
/// Given an integer, create and append a format specifier for the integer to the
60+
/// format string property. Also, append the integer along with necessary headers
61+
/// to the OSLogArguments property.
62+
@_transparent
63+
@_optimize(none)
64+
@usableFromInline
65+
internal mutating func appendInteger<T>(
66+
_ number: @escaping () -> T,
67+
format: IntFormat,
68+
privacy: Privacy
69+
) where T: FixedWidthInteger {
70+
guard argumentCount < maxOSLogArgumentCount else { return }
71+
72+
let isPrivateArgument = isPrivate(privacy)
73+
formatString +=
74+
getIntegerFormatSpecifier(
75+
T.self,
76+
format,
77+
isPrivateArgument)
78+
addIntHeaders(isPrivateArgument, sizeForEncoding(T.self))
79+
80+
arguments.append(number)
81+
argumentCount += 1
82+
}
83+
84+
/// Update preamble and append argument headers based on the parameters of
85+
/// the interpolation.
86+
@_transparent
87+
@_optimize(none)
88+
@usableFromInline
89+
internal mutating func addIntHeaders(_ isPrivate: Bool, _ byteCount: Int) {
90+
// Append argument header.
91+
let argumentHeader = getArgumentHeader(isPrivate: isPrivate, type: .scalar)
92+
arguments.append(argumentHeader)
93+
94+
// Append number of bytes needed to serialize the argument.
95+
arguments.append(UInt8(byteCount))
96+
97+
// Increment total byte size by the number of bytes needed for this
98+
// argument, which is the sum of the byte size of the argument and
99+
// two bytes needed for the headers.
100+
totalBytesForSerializingArguments += byteCount + 2
101+
102+
preamble = getUpdatedPreamble(isPrivate: isPrivate)
103+
}
104+
105+
/// Construct an os_log format specifier from the given parameters.
106+
/// This function must be constant evaluable and all its arguments
107+
/// must be known at compile time.
108+
@inlinable
109+
@_semantics("oslog.interpolation.getFormatSpecifier")
110+
@_effects(readonly)
111+
@_optimize(none)
112+
internal func getIntegerFormatSpecifier<T>(
113+
_ integerType: T.Type,
114+
_ format: IntFormat,
115+
_ isPrivate: Bool
116+
) -> String where T : FixedWidthInteger {
117+
var formatSpecifier: String = isPrivate ? "%{private}" : "%{public}"
118+
119+
// Add a length modifier to the specifier.
120+
// TODO: more length modifiers will be added.
121+
if (integerType.bitWidth == CLongLong.bitWidth) {
122+
formatSpecifier += "ll"
123+
}
124+
125+
// TODO: more format specifiers will be added.
126+
switch (format) {
127+
case .hex:
128+
formatSpecifier += "x"
129+
case .octal:
130+
formatSpecifier += "o"
131+
default:
132+
formatSpecifier += integerType.isSigned ? "d" : "u"
133+
}
134+
return formatSpecifier
135+
}
136+
}
137+
138+
extension OSLogArguments {
139+
/// Append an (autoclosured) interpolated expression of integer type, passed to
140+
/// `OSLogMessage.appendInterpolation`, to the array of closures tracked
141+
/// by this instance.
142+
@usableFromInline
143+
internal mutating func append<T>(
144+
_ value: @escaping () -> T
145+
) where T: FixedWidthInteger {
146+
argumentClosures!.append({ $0.serialize(value()) })
147+
}
148+
}
149+
150+
/// Return the number of bytes needed for serializing an integer argument as
151+
/// specified by os_log. This function must be constant evaluable.
152+
@inlinable
153+
@_semantics("oslog.integers.sizeForEncoding")
154+
@_effects(readonly)
155+
@_optimize(none)
156+
internal func sizeForEncoding<T>(
157+
_ type: T.Type
158+
) -> Int where T : FixedWidthInteger {
159+
return type.bitWidth &>> logBitsPerByte
160+
}
161+
162+
extension OSLogByteBufferBuilder {
163+
/// Serialize an integer at the buffer location pointed to by `position`.
164+
@usableFromInline
165+
internal mutating func serialize<T>(
166+
_ value: T
167+
) where T : FixedWidthInteger {
168+
let byteCount = sizeForEncoding(T.self)
169+
let dest = UnsafeMutableRawBufferPointer(start: position, count: byteCount)
170+
withUnsafeBytes(of: value) { dest.copyMemory(from: $0) }
171+
position += byteCount
172+
}
173+
}

0 commit comments

Comments
 (0)