@@ -5554,7 +5554,10 @@ Decl *SwiftDeclConverter::importEnumCaseAlias(
5554
5554
auto constantRef =
5555
5555
new (Impl.SwiftContext ) DeclRefExpr (original, DeclNameLoc (),
5556
5556
/* implicit*/ true );
5557
+ constantRef->setType (original->getInterfaceType ());
5558
+
5557
5559
Type importedEnumTy = importedEnum->getDeclaredInterfaceType ();
5560
+
5558
5561
auto typeRef = TypeExpr::createImplicit (importedEnumTy, Impl.SwiftContext );
5559
5562
auto instantiate = new (Impl.SwiftContext )
5560
5563
DotSyntaxCallExpr (constantRef, SourceLoc (), typeRef);
@@ -8147,6 +8150,21 @@ ClangImporter::Implementation::importDeclContextOf(
8147
8150
return ext;
8148
8151
}
8149
8152
8153
+ static Type getConstantLiteralType (ClangImporter::Implementation &Impl,
8154
+ Type type, ConstantConvertKind convertKind) {
8155
+ switch (convertKind) {
8156
+ case ConstantConvertKind::Construction:
8157
+ case ConstantConvertKind::ConstructionWithUnwrap: {
8158
+ auto found = Impl.RawTypes .find (type->getAnyNominal ());
8159
+ assert (found != Impl.RawTypes .end ());
8160
+ return found->second ;
8161
+ }
8162
+
8163
+ default :
8164
+ return type;
8165
+ }
8166
+ }
8167
+
8150
8168
ValueDecl *
8151
8169
ClangImporter::Implementation::createConstant (Identifier name, DeclContext *dc,
8152
8170
Type type,
@@ -8188,20 +8206,49 @@ ClangImporter::Implementation::createConstant(Identifier name, DeclContext *dc,
8188
8206
if (isNegative)
8189
8207
printedValue = printedValue.drop_front ();
8190
8208
8209
+ auto literalType = getConstantLiteralType (*this , type, convertKind);
8210
+
8191
8211
// Create the expression node.
8192
8212
StringRef printedValueCopy (context.AllocateCopy (printedValue));
8193
8213
if (value.getKind () == clang::APValue::Int) {
8194
8214
if (type->getCanonicalType ()->isBool ()) {
8195
- expr = new (context) BooleanLiteralExpr (value.getInt ().getBoolValue (),
8196
- SourceLoc (),
8197
- /* *Implicit=*/ true );
8215
+ auto *boolExpr =
8216
+ new (context) BooleanLiteralExpr (value.getInt ().getBoolValue (),
8217
+ SourceLoc (),
8218
+ /* *Implicit=*/ true );
8219
+
8220
+ boolExpr->setBuiltinInitializer (
8221
+ context.getBoolBuiltinInitDecl ());
8222
+ boolExpr->setType (literalType);
8223
+
8224
+ expr = boolExpr;
8198
8225
} else {
8199
- expr = new (context) IntegerLiteralExpr (printedValueCopy, SourceLoc (),
8200
- /* Implicit=*/ true );
8226
+ auto *intExpr =
8227
+ new (context) IntegerLiteralExpr (printedValueCopy, SourceLoc (),
8228
+ /* Implicit=*/ true );
8229
+
8230
+ auto *intDecl = literalType->getAnyNominal ();
8231
+ intExpr->setBuiltinInitializer (
8232
+ context.getIntBuiltinInitDecl (intDecl));
8233
+ intExpr->setType (literalType);
8234
+
8235
+ expr = intExpr;
8201
8236
}
8202
8237
} else {
8203
- expr = new (context) FloatLiteralExpr (printedValueCopy, SourceLoc (),
8204
- /* Implicit=*/ true );
8238
+ auto *floatExpr =
8239
+ new (context) FloatLiteralExpr (printedValueCopy, SourceLoc (),
8240
+ /* Implicit=*/ true );
8241
+
8242
+ auto maxFloatTypeDecl = context.get_MaxBuiltinFloatTypeDecl ();
8243
+ floatExpr->setBuiltinType (
8244
+ maxFloatTypeDecl->getUnderlyingTypeLoc ().getType ());
8245
+
8246
+ auto *floatDecl = literalType->getAnyNominal ();
8247
+ floatExpr->setBuiltinInitializer (
8248
+ context.getFloatBuiltinInitDecl (floatDecl));
8249
+ floatExpr->setType (literalType);
8250
+
8251
+ expr = floatExpr;
8205
8252
}
8206
8253
8207
8254
if (isNegative)
@@ -8223,6 +8270,13 @@ ClangImporter::Implementation::createConstant(Identifier name, DeclContext *dc,
8223
8270
bool isStatic,
8224
8271
ClangNode ClangN) {
8225
8272
auto expr = new (SwiftContext) StringLiteralExpr (value, SourceRange ());
8273
+
8274
+ auto literalType = getConstantLiteralType (*this , type, convertKind);
8275
+ auto *stringDecl = literalType->getAnyNominal ();
8276
+ expr->setBuiltinInitializer (
8277
+ SwiftContext.getStringBuiltinInitDecl (stringDecl));
8278
+ expr->setType (literalType);
8279
+
8226
8280
return createConstant (name, dc, type, expr, convertKind, isStatic, ClangN);
8227
8281
}
8228
8282
@@ -8287,10 +8341,42 @@ ClangImporter::Implementation::createConstant(Identifier name, DeclContext *dc,
8287
8341
case ConstantConvertKind::Construction:
8288
8342
case ConstantConvertKind::ConstructionWithUnwrap: {
8289
8343
auto typeRef = TypeExpr::createImplicit (type, C);
8290
-
8291
- expr = CallExpr::createImplicit (C, typeRef, { expr }, { C.Id_rawValue });
8292
- if (convertKind == ConstantConvertKind::ConstructionWithUnwrap)
8344
+
8345
+ // Reference init(rawValue: T)
8346
+ auto found = RawInits.find (type->getAnyNominal ());
8347
+ assert (found != RawInits.end ());
8348
+
8349
+ auto *init = found->second ;
8350
+ auto initTy = init->getInterfaceType ()->removeArgumentLabels (1 );
8351
+ auto declRef =
8352
+ new (C) DeclRefExpr (init, DeclNameLoc (), /* Implicit=*/ true ,
8353
+ AccessSemantics::Ordinary, initTy);
8354
+
8355
+ // (Self) -> ...
8356
+ initTy = initTy->castTo <FunctionType>()->getResult ();
8357
+ auto initRef = new (C) DotSyntaxCallExpr (declRef, SourceLoc (),
8358
+ typeRef, initTy);
8359
+ initRef->setThrows (false );
8360
+
8361
+ // (rawValue: T) -> ...
8362
+ initTy = initTy->castTo <FunctionType>()->getResult ();
8363
+
8364
+ auto initCall = CallExpr::createImplicit (C, initRef, { expr },
8365
+ { C.Id_rawValue });
8366
+ initCall->setType (initTy);
8367
+ initCall->setThrows (false );
8368
+
8369
+ expr = initCall;
8370
+
8371
+ // Force unwrap if our init(rawValue:) is failable, which is currently
8372
+ // the case with enums.
8373
+ if (convertKind == ConstantConvertKind::ConstructionWithUnwrap) {
8374
+ initTy = initTy->getOptionalObjectType ();
8293
8375
expr = new (C) ForceValueExpr (expr, SourceLoc ());
8376
+ expr->setType (initTy);
8377
+ }
8378
+
8379
+ assert (initTy->isEqual (type));
8294
8380
break ;
8295
8381
}
8296
8382
}
@@ -8302,6 +8388,7 @@ ClangImporter::Implementation::createConstant(Identifier name, DeclContext *dc,
8302
8388
func->setBody (BraceStmt::create (C, SourceLoc (),
8303
8389
ASTNode (ret),
8304
8390
SourceLoc ()));
8391
+ func->setBodyTypeCheckedIfPresent ();
8305
8392
}
8306
8393
8307
8394
// Mark the function transparent so that we inline it away completely.
0 commit comments