Skip to content

Commit 2813912

Browse files
authored
Merge pull request #23010 from pschuh/s-5
FloatLiteralExpr now is lowered directly into SIL.
2 parents e8219a5 + 5160da6 commit 2813912

File tree

12 files changed

+75
-256
lines changed

12 files changed

+75
-256
lines changed

include/swift/AST/Expr.h

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -823,11 +823,11 @@ class NumberLiteralExpr : public LiteralExpr {
823823
}
824824
};
825825

826-
827826
/// Integer literal with a '+' or '-' sign, like '+4' or '- 2'.
828827
///
829-
/// After semantic analysis assigns types, this is guaranteed to only have
830-
/// a BuiltinIntegerType.
828+
/// After semantic analysis assigns types, this is guaranteed to have
829+
/// a BuiltinIntegerType or be a normal type and implicitly be
830+
/// AnyBuiltinIntegerType.
831831
class IntegerLiteralExpr : public NumberLiteralExpr {
832832
public:
833833
IntegerLiteralExpr(StringRef Val, SourceLoc DigitsLoc, bool Implicit = false)
@@ -855,9 +855,12 @@ class IntegerLiteralExpr : public NumberLiteralExpr {
855855
};
856856

857857
/// FloatLiteralExpr - Floating point literal, like '4.0'. After semantic
858-
/// analysis assigns types, this is guaranteed to only have a
858+
/// analysis assigns types, BuiltinTy is guaranteed to only have a
859859
/// BuiltinFloatingPointType.
860860
class FloatLiteralExpr : public NumberLiteralExpr {
861+
/// This is the type of the builtin literal.
862+
Type BuiltinTy;
863+
861864
public:
862865
FloatLiteralExpr(StringRef Val, SourceLoc Loc, bool Implicit = false)
863866
: NumberLiteralExpr(ExprKind::FloatLiteral, Val, Loc, Implicit)
@@ -870,6 +873,9 @@ class FloatLiteralExpr : public NumberLiteralExpr {
870873
static bool classof(const Expr *E) {
871874
return E->getKind() == ExprKind::FloatLiteral;
872875
}
876+
877+
Type getBuiltinType() const { return BuiltinTy; }
878+
void setBuiltinType(Type ty) { BuiltinTy = ty; }
873879
};
874880

875881
/// A Boolean literal ('true' or 'false')

lib/AST/ASTDumper.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1831,6 +1831,16 @@ class PrintExpr : public ExprVisitor<PrintExpr> {
18311831
printCommon(E, "float_literal_expr");
18321832
PrintWithColorRAII(OS, LiteralValueColor)
18331833
<< " value=" << E->getDigitsText();
1834+
PrintWithColorRAII(OS, LiteralValueColor) << " builtin_initializer=";
1835+
E->getBuiltinInitializer().dump(
1836+
PrintWithColorRAII(OS, LiteralValueColor).getOS());
1837+
PrintWithColorRAII(OS, LiteralValueColor) << " initializer=";
1838+
E->getInitializer().dump(PrintWithColorRAII(OS, LiteralValueColor).getOS());
1839+
if (!E->getBuiltinType().isNull()) {
1840+
PrintWithColorRAII(OS, TypeColor) << " builtin_type='";
1841+
E->getBuiltinType().print(PrintWithColorRAII(OS, TypeColor).getOS());
1842+
PrintWithColorRAII(OS, TypeColor) << "'";
1843+
}
18341844
PrintWithColorRAII(OS, ParenthesisColor) << ')';
18351845
}
18361846

lib/AST/Expr.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -974,8 +974,16 @@ llvm::APFloat FloatLiteralExpr::getValue() const {
974974
assert(!getType().isNull() && "Semantic analysis has not completed");
975975
assert(!getType()->hasError() && "Should have a valid type");
976976

977-
return getFloatLiteralValue(isNegative(), getDigitsText(),
978-
getType()->castTo<BuiltinFloatType>()->getAPFloatSemantics());
977+
Type ty = getType();
978+
if (!ty->is<BuiltinFloatType>()) {
979+
assert(!getBuiltinType().isNull() && "Semantic analysis has not completed");
980+
assert(!getBuiltinType()->hasError() && "Should have a valid type");
981+
ty = getBuiltinType();
982+
}
983+
984+
return getFloatLiteralValue(
985+
isNegative(), getDigitsText(),
986+
ty->castTo<BuiltinFloatType>()->getAPFloatSemantics());
979987
}
980988

981989
StringLiteralExpr::StringLiteralExpr(StringRef Val, SourceRange Range,

lib/SILGen/SILGenApply.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5543,10 +5543,21 @@ RValue SILGenFunction::emitLiteral(LiteralExpr *literal, SGFContext C) {
55435543
integerLiteral,
55445544
SILType::getBuiltinIntegerLiteralType(getASTContext()),
55455545
integerLiteral->getRawValue()));
5546-
CanType ty = integerManaged.getType().getASTType()->getCanonicalType();
5546+
CanType ty = integerManaged.getType().getASTType();
55475547
builtinLiteralArgs = RValue(*this, {integerManaged}, ty);
55485548
builtinInit = integerLiteral->getBuiltinInitializer();
55495549
init = integerLiteral->getInitializer();
5550+
} else if (auto floatLiteral = dyn_cast<FloatLiteralExpr>(literal)) {
5551+
auto *litTy = floatLiteral->getBuiltinType()->castTo<BuiltinFloatType>();
5552+
ManagedValue floatManaged = ManagedValue::forUnmanaged(B.createFloatLiteral(
5553+
floatLiteral,
5554+
SILType::getBuiltinFloatType(litTy->getFPKind(), getASTContext()),
5555+
floatLiteral->getValue()));
5556+
5557+
CanType ty = floatManaged.getType().getASTType();
5558+
builtinLiteralArgs = RValue(*this, {floatManaged}, ty);
5559+
builtinInit = floatLiteral->getBuiltinInitializer();
5560+
init = floatLiteral->getInitializer();
55505561
} else {
55515562
ASTContext &ctx = getASTContext();
55525563
SourceLoc loc = literal->getStartLoc();

lib/SILGen/SILGenExpr.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -959,8 +959,11 @@ RValue RValueEmitter::visitIntegerLiteralExpr(IntegerLiteralExpr *E,
959959
}
960960
RValue RValueEmitter::visitFloatLiteralExpr(FloatLiteralExpr *E,
961961
SGFContext C) {
962-
return RValue(SGF, E,
963-
ManagedValue::forUnmanaged(SGF.B.createFloatLiteral(E)));
962+
if (E->getType()->is<BuiltinFloatType>())
963+
return RValue(SGF, E,
964+
ManagedValue::forUnmanaged(SGF.B.createFloatLiteral(E)));
965+
966+
return SGF.emitLiteral(E, C);
964967
}
965968

966969
RValue RValueEmitter::visitBooleanLiteralExpr(BooleanLiteralExpr *E,

lib/SILOptimizer/Utils/ConstantFolding.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1122,6 +1122,9 @@ static SILValue foldFPTrunc(BuiltinInst *BI, const BuiltinInfo &Builtin,
11221122
tryExtractLiteralText(flitInst, fplitStr);
11231123

11241124
auto userType = CE ? CE->getType() : destType;
1125+
if (auto *FLE = Loc.getAsASTNode<FloatLiteralExpr>()) {
1126+
userType = FLE->getType();
1127+
}
11251128
auto diagId = overflow
11261129
? diag::warning_float_trunc_overflow
11271130
: (hexnInexact ? diag::warning_float_trunc_hex_inexact

lib/Sema/CSApply.cpp

Lines changed: 5 additions & 223 deletions
Original file line numberDiff line numberDiff line change
@@ -1060,65 +1060,6 @@ namespace {
10601060
/// Describes either a type or the name of a type to be resolved.
10611061
using TypeOrName = llvm::PointerUnion<Identifier, Type>;
10621062

1063-
/// Convert the given literal expression via a protocol pair.
1064-
///
1065-
/// This routine handles the two-step literal conversion process used
1066-
/// by integer, float, character, extended grapheme cluster, and string
1067-
/// literals. The first step uses \c builtinProtocol while the second
1068-
/// step uses \c protocol.
1069-
///
1070-
/// \param literal The literal expression.
1071-
///
1072-
/// \param type The literal type. This type conforms to \c protocol,
1073-
/// and may also conform to \c builtinProtocol.
1074-
///
1075-
/// \param openedType The literal type as it was opened in the type system.
1076-
///
1077-
/// \param protocol The protocol that describes the literal requirement.
1078-
///
1079-
/// \param literalType Either the name of the associated type in
1080-
/// \c protocol that describes the argument type of the conversion function
1081-
/// (\c literalFuncName) or the argument type itself.
1082-
///
1083-
/// \param literalFuncName The name of the conversion function requirement
1084-
/// in \c protocol.
1085-
///
1086-
/// \param builtinProtocol The "builtin" form of the protocol, which
1087-
/// always takes builtin types and can only be properly implemented
1088-
/// by standard library types. If \c type does not conform to this
1089-
/// protocol, it's literal type will.
1090-
///
1091-
/// \param builtinLiteralType Either the name of the associated type in
1092-
/// \c builtinProtocol that describes the argument type of the builtin
1093-
/// conversion function (\c builtinLiteralFuncName) or the argument type
1094-
/// itself.
1095-
///
1096-
/// \param builtinLiteralFuncName The name of the conversion function
1097-
/// requirement in \c builtinProtocol.
1098-
///
1099-
/// \param isBuiltinArgType Function that determines whether the given
1100-
/// type is acceptable as the argument type for the builtin conversion.
1101-
///
1102-
/// \param brokenProtocolDiag The diagnostic to emit if the protocol
1103-
/// is broken.
1104-
///
1105-
/// \param brokenBuiltinProtocolDiag The diagnostic to emit if the builtin
1106-
/// protocol is broken.
1107-
///
1108-
/// \returns the converted literal expression.
1109-
Expr *convertLiteral(Expr *literal,
1110-
Type type,
1111-
Type openedType,
1112-
ProtocolDecl *protocol,
1113-
TypeOrName literalType,
1114-
DeclName literalFuncName,
1115-
ProtocolDecl *builtinProtocol,
1116-
TypeOrName builtinLiteralType,
1117-
DeclName builtinLiteralFuncName,
1118-
bool (*isBuiltinArgType)(Type),
1119-
Diag<> brokenProtocolDiag,
1120-
Diag<> brokenBuiltinProtocolDiag);
1121-
11221063
/// Convert the given literal expression via a protocol pair.
11231064
///
11241065
/// This routine handles the two-step literal conversion process used
@@ -1903,19 +1844,11 @@ namespace {
19031844
DeclName builtinInitName(tc.Context, DeclBaseName::createConstructor(),
19041845
{ tc.Context.Id_builtinFloatLiteral });
19051846

1906-
return convertLiteral(
1907-
expr,
1908-
type,
1909-
cs.getType(expr),
1910-
protocol,
1911-
tc.Context.Id_FloatLiteralType,
1912-
initName,
1913-
builtinProtocol,
1914-
maxType,
1915-
builtinInitName,
1916-
nullptr,
1917-
diag::float_literal_broken_proto,
1918-
diag::builtin_float_literal_broken_proto);
1847+
expr->setBuiltinType(maxType);
1848+
return convertLiteralInPlace(
1849+
expr, type, protocol, tc.Context.Id_FloatLiteralType, initName,
1850+
builtinProtocol, builtinInitName, diag::float_literal_broken_proto,
1851+
diag::builtin_float_literal_broken_proto);
19191852
}
19201853

19211854
Expr *visitBooleanLiteralExpr(BooleanLiteralExpr *expr) {
@@ -6865,157 +6798,6 @@ ExprRewriter::coerceObjectArgumentToType(Expr *expr,
68656798
/*isImplicit*/ true));
68666799
}
68676800

6868-
Expr *ExprRewriter::convertLiteral(Expr *literal,
6869-
Type type,
6870-
Type openedType,
6871-
ProtocolDecl *protocol,
6872-
TypeOrName literalType,
6873-
DeclName literalFuncName,
6874-
ProtocolDecl *builtinProtocol,
6875-
TypeOrName builtinLiteralType,
6876-
DeclName builtinLiteralFuncName,
6877-
bool (*isBuiltinArgType)(Type),
6878-
Diag<> brokenProtocolDiag,
6879-
Diag<> brokenBuiltinProtocolDiag) {
6880-
auto &tc = cs.getTypeChecker();
6881-
6882-
auto getType = [&](const Expr *E) -> Type {
6883-
return cs.getType(E);
6884-
};
6885-
6886-
auto setType = [&](Expr *E, Type Ty) {
6887-
cs.setType(E, Ty);
6888-
};
6889-
6890-
// If coercing a literal to an unresolved type, we don't try to look up the
6891-
// witness members, just do it.
6892-
if (type->is<UnresolvedType>()) {
6893-
// Instead of updating the literal expr in place, allocate a new node. This
6894-
// avoids issues where Builtin types end up on expr nodes and pollute
6895-
// diagnostics.
6896-
literal = cast<LiteralExpr>(literal)->shallowClone(tc.Context, setType,
6897-
getType);
6898-
6899-
// The literal expression has this type.
6900-
cs.setType(literal, type);
6901-
return literal;
6902-
}
6903-
6904-
// Check whether this literal type conforms to the builtin protocol.
6905-
Optional<ProtocolConformanceRef> builtinConformance;
6906-
if (builtinProtocol &&
6907-
(builtinConformance =
6908-
tc.conformsToProtocol(
6909-
type, builtinProtocol, cs.DC,
6910-
(ConformanceCheckFlags::InExpression)))) {
6911-
6912-
// Find the builtin argument type we'll use.
6913-
Type argType;
6914-
if (builtinLiteralType.is<Type>())
6915-
argType = builtinLiteralType.get<Type>();
6916-
else
6917-
argType = tc.getWitnessType(type, builtinProtocol,
6918-
*builtinConformance,
6919-
builtinLiteralType.get<Identifier>(),
6920-
brokenBuiltinProtocolDiag);
6921-
6922-
if (!argType)
6923-
return nullptr;
6924-
6925-
// Make sure it's of an appropriate builtin type.
6926-
if (isBuiltinArgType && !isBuiltinArgType(argType)) {
6927-
tc.diagnose(builtinProtocol->getLoc(), brokenBuiltinProtocolDiag);
6928-
return nullptr;
6929-
}
6930-
6931-
// Instead of updating the literal expr in place, allocate a new node. This
6932-
// avoids issues where Builtin types end up on expr nodes and pollute
6933-
// diagnostics.
6934-
literal = cast<LiteralExpr>(literal)->shallowClone(tc.Context, setType,
6935-
getType);
6936-
6937-
// The literal expression has this type.
6938-
cs.setType(literal, argType);
6939-
6940-
// Call the builtin conversion operation.
6941-
// FIXME: Bogus location info.
6942-
Expr *base =
6943-
TypeExpr::createImplicitHack(literal->getLoc(), type, tc.Context);
6944-
6945-
cs.cacheExprTypes(base);
6946-
cs.setExprTypes(base);
6947-
cs.setExprTypes(literal);
6948-
SmallVector<Expr *, 1> arguments = { literal };
6949-
6950-
Expr *result = tc.callWitness(base, dc,
6951-
builtinProtocol, *builtinConformance,
6952-
builtinLiteralFuncName,
6953-
arguments,
6954-
brokenBuiltinProtocolDiag);
6955-
if (result)
6956-
cs.cacheExprTypes(result);
6957-
6958-
return result;
6959-
}
6960-
6961-
// This literal type must conform to the (non-builtin) protocol.
6962-
assert(protocol && "requirements should have stopped recursion");
6963-
auto conformance = tc.conformsToProtocol(type, protocol, cs.DC,
6964-
ConformanceCheckFlags::InExpression);
6965-
assert(conformance && "must conform to literal protocol");
6966-
6967-
// Figure out the (non-builtin) argument type if there is one.
6968-
Type argType;
6969-
if (literalType.is<Identifier>() &&
6970-
literalType.get<Identifier>().empty()) {
6971-
// If there is no argument to the constructor function, then just pass in
6972-
// the empty tuple.
6973-
literal =
6974-
cs.cacheType(
6975-
TupleExpr::createEmpty(tc.Context, literal->getLoc(),
6976-
literal->getLoc(),
6977-
/*implicit*/!literal->getLoc().isValid()));
6978-
} else {
6979-
// Otherwise, figure out the type of the constructor function and coerce to
6980-
// it.
6981-
if (literalType.is<Type>())
6982-
argType = literalType.get<Type>();
6983-
else
6984-
argType = tc.getWitnessType(type, protocol, *conformance,
6985-
literalType.get<Identifier>(),
6986-
brokenProtocolDiag);
6987-
if (!argType)
6988-
return nullptr;
6989-
6990-
// Convert the literal to the non-builtin argument type via the
6991-
// builtin protocol, first.
6992-
// FIXME: Do we need an opened type here?
6993-
literal = convertLiteral(literal, argType, argType, nullptr, Identifier(),
6994-
Identifier(), builtinProtocol,
6995-
builtinLiteralType, builtinLiteralFuncName,
6996-
isBuiltinArgType, brokenProtocolDiag,
6997-
brokenBuiltinProtocolDiag);
6998-
if (!literal)
6999-
return nullptr;
7000-
}
7001-
7002-
// Convert the resulting expression to the final literal type.
7003-
// FIXME: Bogus location info.
7004-
Expr *base = TypeExpr::createImplicitHack(literal->getLoc(), type,
7005-
tc.Context);
7006-
cs.cacheExprTypes(base);
7007-
cs.setExprTypes(base);
7008-
cs.setExprTypes(literal);
7009-
7010-
literal = tc.callWitness(base, dc,
7011-
protocol, *conformance, literalFuncName,
7012-
literal, brokenProtocolDiag);
7013-
if (literal)
7014-
cs.cacheExprTypes(literal);
7015-
7016-
return literal;
7017-
}
7018-
70196801
Expr *ExprRewriter::convertLiteralInPlace(Expr *literal,
70206802
Type type,
70216803
ProtocolDecl *protocol,

test/SILGen/default_arguments.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ func defarg1(i: Int = 17, d: Double, s: String = "Hello") { }
2626

2727
// CHECK-LABEL: sil hidden [ossa] @$s17default_arguments15testDefaultArg1yyF
2828
func testDefaultArg1() {
29-
// CHECK: [[FLOAT64:%[0-9]+]] = metatype $@thin Double.Type
3029
// CHECK: [[FLOATLIT:%[0-9]+]] = float_literal $Builtin.FPIEEE{{64|80}}, {{0x4009000000000000|0x4000C800000000000000}}
30+
// CHECK: [[FLOAT64:%[0-9]+]] = metatype $@thin Double.Type
3131
// CHECK: [[LITFN:%[0-9]+]] = function_ref @$sSd20_builtinFloatLiteralSdBf{{[_0-9]*}}__tcfC
3232
// CHECK: [[FLOATVAL:%[0-9]+]] = apply [[LITFN]]([[FLOATLIT]], [[FLOAT64]])
3333
// CHECK: [[DEF0FN:%[0-9]+]] = function_ref @$s17default_arguments7defarg1{{.*}}A_

test/SILGen/default_constructor.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ struct D {
1919
// CHECK-NEXT: [[METATYPE:%.*]] = metatype $@thin Int.Type
2020
// CHECK: [[FN:%.*]] = function_ref @$sSi22_builtinIntegerLiteralSiBI_tcfC : $@convention(method) (Builtin.IntLiteral, @thin Int.Type) -> Int
2121
// CHECK-NEXT: [[LEFT:%.*]] = apply [[FN]]([[VALUE]], [[METATYPE]]) : $@convention(method) (Builtin.IntLiteral, @thin Int.Type) -> Int
22-
// CHECK-NEXT: [[METATYPE:%.*]] = metatype $@thin Double.Type
2322
// CHECK-NEXT: [[VALUE:%.*]] = float_literal $Builtin.FPIEEE{{64|80}}, {{0x400C000000000000|0x4000E000000000000000}}
23+
// CHECK-NEXT: [[METATYPE:%.*]] = metatype $@thin Double.Type
2424
// CHECK: [[FN:%.*]] = function_ref @$sSd20_builtinFloatLiteralSdBf{{64|80}}__tcfC : $@convention(method) (Builtin.FPIEEE{{64|80}}, @thin Double.Type) -> Double
2525
// CHECK-NEXT: [[RIGHT:%.*]] = apply [[FN]]([[VALUE]], [[METATYPE]]) : $@convention(method) (Builtin.FPIEEE{{64|80}}, @thin Double.Type) -> Double
2626
// CHECK-NEXT: [[RESULT:%.*]] = tuple ([[LEFT]] : $Int, [[RIGHT]] : $Double)

0 commit comments

Comments
 (0)