@@ -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,
@@ -8181,20 +8210,49 @@ ClangImporter::Implementation::createConstant(Identifier name, DeclContext *dc,
8181
8210
if (isNegative)
8182
8211
printedValue = printedValue.drop_front ();
8183
8212
8213
+ auto literalType = getConstantLiteralType (*this , type, convertKind);
8214
+
8184
8215
// Create the expression node.
8185
8216
StringRef printedValueCopy (context.AllocateCopy (printedValue));
8186
8217
if (value.getKind () == clang::APValue::Int) {
8187
8218
if (type->getCanonicalType ()->isBool ()) {
8188
- expr = new (context) BooleanLiteralExpr (value.getInt ().getBoolValue (),
8189
- SourceLoc (),
8190
- /* *Implicit=*/ true );
8219
+ auto *boolExpr =
8220
+ new (context) BooleanLiteralExpr (value.getInt ().getBoolValue (),
8221
+ SourceLoc (),
8222
+ /* *Implicit=*/ true );
8223
+
8224
+ boolExpr->setBuiltinInitializer (
8225
+ context.getBoolBuiltinInitDecl ());
8226
+ boolExpr->setType (literalType);
8227
+
8228
+ expr = boolExpr;
8191
8229
} else {
8192
- expr = new (context) IntegerLiteralExpr (printedValueCopy, SourceLoc (),
8193
- /* Implicit=*/ true );
8230
+ auto *intExpr =
8231
+ new (context) IntegerLiteralExpr (printedValueCopy, SourceLoc (),
8232
+ /* Implicit=*/ true );
8233
+
8234
+ auto *intDecl = literalType->getAnyNominal ();
8235
+ intExpr->setBuiltinInitializer (
8236
+ context.getIntBuiltinInitDecl (intDecl));
8237
+ intExpr->setType (literalType);
8238
+
8239
+ expr = intExpr;
8194
8240
}
8195
8241
} else {
8196
- expr = new (context) FloatLiteralExpr (printedValueCopy, SourceLoc (),
8197
- /* Implicit=*/ true );
8242
+ auto *floatExpr =
8243
+ new (context) FloatLiteralExpr (printedValueCopy, SourceLoc (),
8244
+ /* Implicit=*/ true );
8245
+
8246
+ auto maxFloatTypeDecl = context.get_MaxBuiltinFloatTypeDecl ();
8247
+ floatExpr->setBuiltinType (
8248
+ maxFloatTypeDecl->getUnderlyingTypeLoc ().getType ());
8249
+
8250
+ auto *floatDecl = literalType->getAnyNominal ();
8251
+ floatExpr->setBuiltinInitializer (
8252
+ context.getFloatBuiltinInitDecl (floatDecl));
8253
+ floatExpr->setType (literalType);
8254
+
8255
+ expr = floatExpr;
8198
8256
}
8199
8257
8200
8258
if (isNegative)
@@ -8216,6 +8274,13 @@ ClangImporter::Implementation::createConstant(Identifier name, DeclContext *dc,
8216
8274
bool isStatic,
8217
8275
ClangNode ClangN) {
8218
8276
auto expr = new (SwiftContext) StringLiteralExpr (value, SourceRange ());
8277
+
8278
+ auto literalType = getConstantLiteralType (*this , type, convertKind);
8279
+ auto *stringDecl = literalType->getAnyNominal ();
8280
+ expr->setBuiltinInitializer (
8281
+ SwiftContext.getStringBuiltinInitDecl (stringDecl));
8282
+ expr->setType (literalType);
8283
+
8219
8284
return createConstant (name, dc, type, expr, convertKind, isStatic, ClangN);
8220
8285
}
8221
8286
@@ -8280,20 +8345,42 @@ ClangImporter::Implementation::createConstant(Identifier name, DeclContext *dc,
8280
8345
case ConstantConvertKind::Construction:
8281
8346
case ConstantConvertKind::ConstructionWithUnwrap: {
8282
8347
auto typeRef = TypeExpr::createImplicit (type, C);
8283
-
8284
- expr = CallExpr::createImplicit (C, typeRef, { expr }, { C.Id_rawValue });
8285
- if (convertKind == ConstantConvertKind::ConstructionWithUnwrap)
8286
- expr = new (C) ForceValueExpr (expr, SourceLoc ());
8287
- break ;
8288
- }
8289
8348
8290
- case ConstantConvertKind::Coerce:
8291
- break ;
8349
+ // Reference init(rawValue: T)
8350
+ auto found = RawInits.find (type->getAnyNominal ());
8351
+ assert (found != RawInits.end ());
8352
+
8353
+ auto *init = found->second ;
8354
+ auto initTy = init->getInterfaceType ()->removeArgumentLabels (1 );
8355
+ auto declRef =
8356
+ new (C) DeclRefExpr (init, DeclNameLoc (), /* Implicit=*/ true ,
8357
+ AccessSemantics::Ordinary, initTy);
8358
+
8359
+ // (Self) -> ...
8360
+ initTy = initTy->castTo <FunctionType>()->getResult ();
8361
+ auto initRef = new (C) DotSyntaxCallExpr (declRef, SourceLoc (),
8362
+ typeRef, initTy);
8363
+ initRef->setThrows (false );
8364
+
8365
+ // (rawValue: T) -> ...
8366
+ initTy = initTy->castTo <FunctionType>()->getResult ();
8367
+
8368
+ auto initCall = CallExpr::createImplicit (C, initRef, { expr },
8369
+ { C.Id_rawValue });
8370
+ initCall->setType (initTy);
8371
+ initCall->setThrows (false );
8372
+
8373
+ expr = initCall;
8374
+
8375
+ // Force unwrap if our init(rawValue:) is failable, which is currently
8376
+ // the case with enums.
8377
+ if (convertKind == ConstantConvertKind::ConstructionWithUnwrap) {
8378
+ initTy = initTy->getOptionalObjectType ();
8379
+ expr = new (C) ForceValueExpr (expr, SourceLoc ());
8380
+ expr->setType (initTy);
8381
+ }
8292
8382
8293
- case ConstantConvertKind::Downcast: {
8294
- expr = new (C) ForcedCheckedCastExpr (expr, SourceLoc (), SourceLoc (),
8295
- TypeLoc::withoutLoc (type));
8296
- expr->setImplicit ();
8383
+ assert (initTy->isEqual (type));
8297
8384
break ;
8298
8385
}
8299
8386
}
@@ -8305,6 +8392,7 @@ ClangImporter::Implementation::createConstant(Identifier name, DeclContext *dc,
8305
8392
func->setBody (BraceStmt::create (C, SourceLoc (),
8306
8393
ASTNode (ret),
8307
8394
SourceLoc ()));
8395
+ func->setBodyTypeCheckedIfPresent ();
8308
8396
}
8309
8397
8310
8398
// Mark the function transparent so that we inline it away completely.
0 commit comments