@@ -1001,6 +1001,7 @@ makeUnionFieldAccessors(ClangImporter::Implementation &Impl,
1001
1001
{ inoutSelf },
1002
1002
{ Identifier () });
1003
1003
selfPointer->setType (C.TheRawPointerType );
1004
+ selfPointer->setThrows (false );
1004
1005
1005
1006
auto initializeFn = cast<FuncDecl>(getBuiltinValueDecl (
1006
1007
C, C.getIdentifier (" initialize" )));
@@ -1018,6 +1019,7 @@ makeUnionFieldAccessors(ClangImporter::Implementation &Impl,
1018
1019
{ newValueRef, selfPointer },
1019
1020
{ Identifier (), Identifier () });
1020
1021
initialize->setType (TupleType::getEmpty (C));
1022
+ initialize->setThrows (false );
1021
1023
1022
1024
auto body = BraceStmt::create (C, SourceLoc (), { initialize }, SourceLoc (),
1023
1025
/* implicit*/ true );
@@ -1499,15 +1501,19 @@ static void makeStructRawValued(
1499
1501
createValueConstructor (Impl, structDecl, var,
1500
1502
/* wantCtorParamNames=*/ false ,
1501
1503
/* wantBody=*/ !Impl.hasFinishedTypeChecking ()));
1502
- structDecl->addMember (
1504
+
1505
+ auto *initRawValue =
1503
1506
createValueConstructor (Impl, structDecl, var,
1504
1507
/* wantCtorParamNames=*/ true ,
1505
- /* wantBody=*/ !Impl.hasFinishedTypeChecking ()));
1508
+ /* wantBody=*/ !Impl.hasFinishedTypeChecking ());
1509
+ structDecl->addMember (initRawValue);
1506
1510
structDecl->addMember (patternBinding);
1507
1511
structDecl->addMember (var);
1508
1512
structDecl->addMember (varGetter);
1509
1513
1510
1514
addSynthesizedTypealias (structDecl, ctx.Id_RawValue , underlyingType);
1515
+ Impl.RawTypes [structDecl] = underlyingType;
1516
+ Impl.RawInits [structDecl] = initRawValue;
1511
1517
}
1512
1518
1513
1519
// / Create a rawValue-ed constructor that bridges to its underlying storage.
@@ -1650,6 +1656,8 @@ static void makeStructRawValuedWithBridge(
1650
1656
structDecl->addMember (computedVarGetter);
1651
1657
1652
1658
addSynthesizedTypealias (structDecl, ctx.Id_RawValue , bridgedType);
1659
+ Impl.RawTypes [structDecl] = bridgedType;
1660
+ Impl.RawInits [structDecl] = init;
1653
1661
}
1654
1662
1655
1663
// / Build a declaration for an Objective-C subscript getter.
@@ -2852,6 +2860,8 @@ namespace {
2852
2860
enumDecl->addMember (rawValueBinding);
2853
2861
2854
2862
addSynthesizedTypealias (enumDecl, C.Id_RawValue , underlyingType);
2863
+ Impl.RawTypes [enumDecl] = underlyingType;
2864
+ Impl.RawInits [enumDecl] = rawValueConstructor;
2855
2865
2856
2866
// If we have an error wrapper, finish it up now that its
2857
2867
// nested enum has been constructed.
@@ -3381,7 +3391,7 @@ namespace {
3381
3391
// Create the global constant.
3382
3392
auto result = Impl.createConstant (name, dc, type,
3383
3393
clang::APValue (decl->getInitVal ()),
3384
- ConstantConvertKind::Coerce ,
3394
+ ConstantConvertKind::None ,
3385
3395
/* static*/ dc->isTypeContext (), decl);
3386
3396
Impl.ImportedDecls [{decl->getCanonicalDecl (), getVersion ()}] = result;
3387
3397
@@ -5546,11 +5556,15 @@ Decl *SwiftDeclConverter::importEnumCaseAlias(
5546
5556
auto constantRef =
5547
5557
new (Impl.SwiftContext ) DeclRefExpr (original, DeclNameLoc (),
5548
5558
/* implicit*/ true );
5559
+ constantRef->setType (original->getInterfaceType ());
5560
+
5549
5561
Type importedEnumTy = importedEnum->getDeclaredInterfaceType ();
5562
+
5550
5563
auto typeRef = TypeExpr::createImplicit (importedEnumTy, Impl.SwiftContext );
5551
5564
auto instantiate = new (Impl.SwiftContext )
5552
5565
DotSyntaxCallExpr (constantRef, SourceLoc (), typeRef);
5553
5566
instantiate->setType (importedEnumTy);
5567
+ instantiate->setThrows (false );
5554
5568
5555
5569
Decl *CD = Impl.createConstant (name, importIntoDC, importedEnumTy,
5556
5570
instantiate, ConstantConvertKind::None,
@@ -8139,6 +8153,21 @@ ClangImporter::Implementation::importDeclContextOf(
8139
8153
return ext;
8140
8154
}
8141
8155
8156
+ static Type getConstantLiteralType (ClangImporter::Implementation &Impl,
8157
+ Type type, ConstantConvertKind convertKind) {
8158
+ switch (convertKind) {
8159
+ case ConstantConvertKind::Construction:
8160
+ case ConstantConvertKind::ConstructionWithUnwrap: {
8161
+ auto found = Impl.RawTypes .find (type->getAnyNominal ());
8162
+ assert (found != Impl.RawTypes .end ());
8163
+ return found->second ;
8164
+ }
8165
+
8166
+ default :
8167
+ return type;
8168
+ }
8169
+ }
8170
+
8142
8171
ValueDecl *
8143
8172
ClangImporter::Implementation::createConstant (Identifier name, DeclContext *dc,
8144
8173
Type type,
@@ -8180,20 +8209,49 @@ ClangImporter::Implementation::createConstant(Identifier name, DeclContext *dc,
8180
8209
if (isNegative)
8181
8210
printedValue = printedValue.drop_front ();
8182
8211
8212
+ auto literalType = getConstantLiteralType (*this , type, convertKind);
8213
+
8183
8214
// Create the expression node.
8184
8215
StringRef printedValueCopy (context.AllocateCopy (printedValue));
8185
8216
if (value.getKind () == clang::APValue::Int) {
8186
8217
if (type->getCanonicalType ()->isBool ()) {
8187
- expr = new (context) BooleanLiteralExpr (value.getInt ().getBoolValue (),
8188
- SourceLoc (),
8189
- /* *Implicit=*/ true );
8218
+ auto *boolExpr =
8219
+ new (context) BooleanLiteralExpr (value.getInt ().getBoolValue (),
8220
+ SourceLoc (),
8221
+ /* *Implicit=*/ true );
8222
+
8223
+ boolExpr->setBuiltinInitializer (
8224
+ context.getBoolBuiltinInitDecl ());
8225
+ boolExpr->setType (literalType);
8226
+
8227
+ expr = boolExpr;
8190
8228
} else {
8191
- expr = new (context) IntegerLiteralExpr (printedValueCopy, SourceLoc (),
8192
- /* Implicit=*/ true );
8229
+ auto *intExpr =
8230
+ new (context) IntegerLiteralExpr (printedValueCopy, SourceLoc (),
8231
+ /* Implicit=*/ true );
8232
+
8233
+ auto *intDecl = literalType->getAnyNominal ();
8234
+ intExpr->setBuiltinInitializer (
8235
+ context.getIntBuiltinInitDecl (intDecl));
8236
+ intExpr->setType (literalType);
8237
+
8238
+ expr = intExpr;
8193
8239
}
8194
8240
} else {
8195
- expr = new (context) FloatLiteralExpr (printedValueCopy, SourceLoc (),
8196
- /* Implicit=*/ true );
8241
+ auto *floatExpr =
8242
+ new (context) FloatLiteralExpr (printedValueCopy, SourceLoc (),
8243
+ /* Implicit=*/ true );
8244
+
8245
+ auto maxFloatTypeDecl = context.get_MaxBuiltinFloatTypeDecl ();
8246
+ floatExpr->setBuiltinType (
8247
+ maxFloatTypeDecl->getUnderlyingTypeLoc ().getType ());
8248
+
8249
+ auto *floatDecl = literalType->getAnyNominal ();
8250
+ floatExpr->setBuiltinInitializer (
8251
+ context.getFloatBuiltinInitDecl (floatDecl));
8252
+ floatExpr->setType (literalType);
8253
+
8254
+ expr = floatExpr;
8197
8255
}
8198
8256
8199
8257
if (isNegative)
@@ -8215,6 +8273,13 @@ ClangImporter::Implementation::createConstant(Identifier name, DeclContext *dc,
8215
8273
bool isStatic,
8216
8274
ClangNode ClangN) {
8217
8275
auto expr = new (SwiftContext) StringLiteralExpr (value, SourceRange ());
8276
+
8277
+ auto literalType = getConstantLiteralType (*this , type, convertKind);
8278
+ auto *stringDecl = literalType->getAnyNominal ();
8279
+ expr->setBuiltinInitializer (
8280
+ SwiftContext.getStringBuiltinInitDecl (stringDecl));
8281
+ expr->setType (literalType);
8282
+
8218
8283
return createConstant (name, dc, type, expr, convertKind, isStatic, ClangN);
8219
8284
}
8220
8285
@@ -8279,20 +8344,42 @@ ClangImporter::Implementation::createConstant(Identifier name, DeclContext *dc,
8279
8344
case ConstantConvertKind::Construction:
8280
8345
case ConstantConvertKind::ConstructionWithUnwrap: {
8281
8346
auto typeRef = TypeExpr::createImplicit (type, C);
8282
-
8283
- expr = CallExpr::createImplicit (C, typeRef, { expr }, { C.Id_rawValue });
8284
- if (convertKind == ConstantConvertKind::ConstructionWithUnwrap)
8285
- expr = new (C) ForceValueExpr (expr, SourceLoc ());
8286
- break ;
8287
- }
8288
8347
8289
- case ConstantConvertKind::Coerce:
8290
- break ;
8348
+ // Reference init(rawValue: T)
8349
+ auto found = RawInits.find (type->getAnyNominal ());
8350
+ assert (found != RawInits.end ());
8351
+
8352
+ auto *init = found->second ;
8353
+ auto initTy = init->getInterfaceType ()->removeArgumentLabels (1 );
8354
+ auto declRef =
8355
+ new (C) DeclRefExpr (init, DeclNameLoc (), /* Implicit=*/ true ,
8356
+ AccessSemantics::Ordinary, initTy);
8357
+
8358
+ // (Self) -> ...
8359
+ initTy = initTy->castTo <FunctionType>()->getResult ();
8360
+ auto initRef = new (C) DotSyntaxCallExpr (declRef, SourceLoc (),
8361
+ typeRef, initTy);
8362
+ initRef->setThrows (false );
8363
+
8364
+ // (rawValue: T) -> ...
8365
+ initTy = initTy->castTo <FunctionType>()->getResult ();
8366
+
8367
+ auto initCall = CallExpr::createImplicit (C, initRef, { expr },
8368
+ { C.Id_rawValue });
8369
+ initCall->setType (initTy);
8370
+ initCall->setThrows (false );
8371
+
8372
+ expr = initCall;
8373
+
8374
+ // Force unwrap if our init(rawValue:) is failable, which is currently
8375
+ // the case with enums.
8376
+ if (convertKind == ConstantConvertKind::ConstructionWithUnwrap) {
8377
+ initTy = initTy->getOptionalObjectType ();
8378
+ expr = new (C) ForceValueExpr (expr, SourceLoc ());
8379
+ expr->setType (initTy);
8380
+ }
8291
8381
8292
- case ConstantConvertKind::Downcast: {
8293
- expr = new (C) ForcedCheckedCastExpr (expr, SourceLoc (), SourceLoc (),
8294
- TypeLoc::withoutLoc (type));
8295
- expr->setImplicit ();
8382
+ assert (initTy->isEqual (type));
8296
8383
break ;
8297
8384
}
8298
8385
}
@@ -8304,6 +8391,7 @@ ClangImporter::Implementation::createConstant(Identifier name, DeclContext *dc,
8304
8391
func->setBody (BraceStmt::create (C, SourceLoc (),
8305
8392
ASTNode (ret),
8306
8393
SourceLoc ()));
8394
+ func->setBodyTypeCheckedIfPresent ();
8307
8395
}
8308
8396
8309
8397
// Mark the function transparent so that we inline it away completely.
0 commit comments