From 8999e5bfe67eae2ff71df504923ffe661b00fd5f Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Wed, 20 Jun 2018 17:51:29 +0300 Subject: [PATCH] psi2ir: support unsigned integer literals NB in FE unsigned integer constants are now represented using signed integer types (e.g., UInt constant actually holds an Int value). So, in IR so far we also represent unsigned constant literals as constant values of corresponding signed types, but with corresponding unsigned type: 0xFFFF_FFFFu becomes 'CONST Int type=kotlin.UInt value=-1' --- .../generators/ConstantValueGenerator.kt | 4 + .../expressions/unsignedIntegerLiterals.kt | 23 +++++ .../expressions/unsignedIntegerLiterals.txt | 95 +++++++++++++++++++ .../kotlin/ir/AbstractIrGeneratorTestCase.kt | 5 + .../kotlin/ir/IrTextTestCaseGenerated.java | 5 + 5 files changed, 132 insertions(+) create mode 100644 compiler/testData/ir/irText/expressions/unsignedIntegerLiterals.kt create mode 100644 compiler/testData/ir/irText/expressions/unsignedIntegerLiterals.txt diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ConstantValueGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ConstantValueGenerator.kt index 9c683bc5fbc..c504e5fe679 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ConstantValueGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ConstantValueGenerator.kt @@ -45,14 +45,18 @@ class ConstantValueGenerator( return when (constantValue) { is StringValue -> IrConstImpl.string(startOffset, endOffset, constantType, constantValue.value) is IntValue -> IrConstImpl.int(startOffset, endOffset, constantType, constantValue.value) + is UIntValue -> IrConstImpl.int(startOffset, endOffset, constantType, constantValue.value) is NullValue -> IrConstImpl.constNull(startOffset, endOffset, constantType) is BooleanValue -> IrConstImpl.boolean(startOffset, endOffset, constantType, constantValue.value) is LongValue -> IrConstImpl.long(startOffset, endOffset, constantType, constantValue.value) + is ULongValue -> IrConstImpl.long(startOffset, endOffset, constantType, constantValue.value) is DoubleValue -> IrConstImpl.double(startOffset, endOffset, constantType, constantValue.value) is FloatValue -> IrConstImpl.float(startOffset, endOffset, constantType, constantValue.value) is CharValue -> IrConstImpl.char(startOffset, endOffset, constantType, constantValue.value) is ByteValue -> IrConstImpl.byte(startOffset, endOffset, constantType, constantValue.value) + is UByteValue -> IrConstImpl.byte(startOffset, endOffset, constantType, constantValue.value) is ShortValue -> IrConstImpl.short(startOffset, endOffset, constantType, constantValue.value) + is UShortValue -> IrConstImpl.short(startOffset, endOffset, constantType, constantValue.value) is ArrayValue -> { val arrayElementType = varargElementType ?: constantType.getArrayElementType() diff --git a/compiler/testData/ir/irText/expressions/unsignedIntegerLiterals.kt b/compiler/testData/ir/irText/expressions/unsignedIntegerLiterals.kt new file mode 100644 index 00000000000..cce1c9bfd3a --- /dev/null +++ b/compiler/testData/ir/irText/expressions/unsignedIntegerLiterals.kt @@ -0,0 +1,23 @@ +// !LANGUAGE: +InlineClasses +// !SKIP_METADATA_VERSION_CHECK +// WITH_UNSIGNED + +val testSimpleUIntLiteral = 1u + +val testSimpleUIntLiteralWithOverflow = 0xFFFF_FFFFu + +val testUByteWithExpectedType: UByte = 1u + +val testUShortWithExpectedType: UShort = 1u + +val testUIntWithExpectedType: UInt = 1u + +val testULongWithExpectedType: ULong = 1u + +val testToUByte = 1.toUByte() + +val testToUShort = 1.toUShort() + +val testToUInt = 1.toUInt() + +val testToULong = 1.toULong() diff --git a/compiler/testData/ir/irText/expressions/unsignedIntegerLiterals.txt b/compiler/testData/ir/irText/expressions/unsignedIntegerLiterals.txt new file mode 100644 index 00000000000..b496038bdc0 --- /dev/null +++ b/compiler/testData/ir/irText/expressions/unsignedIntegerLiterals.txt @@ -0,0 +1,95 @@ +FILE fqName: fileName:/unsignedIntegerLiterals.kt + PROPERTY name:testSimpleUIntLiteral type:kotlin.UInt visibility:public modality:FINAL flags:val + FIELD PROPERTY_BACKING_FIELD name:testSimpleUIntLiteral type:kotlin.UInt visibility:public flags:final + EXPRESSION_BODY + CONST Int type=kotlin.UInt value=1 + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> () returnType:UInt flags: + correspondingProperty: PROPERTY name:testSimpleUIntLiteral type:kotlin.UInt visibility:public modality:FINAL flags:val + BLOCK_BODY + RETURN type=kotlin.Nothing from='(): UInt' + GET_FIELD 'testSimpleUIntLiteral: UInt' type=kotlin.UInt origin=null + PROPERTY name:testSimpleUIntLiteralWithOverflow type:kotlin.UInt visibility:public modality:FINAL flags:val + FIELD PROPERTY_BACKING_FIELD name:testSimpleUIntLiteralWithOverflow type:kotlin.UInt visibility:public flags:final + EXPRESSION_BODY + CONST Int type=kotlin.UInt value=-1 + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> () returnType:UInt flags: + correspondingProperty: PROPERTY name:testSimpleUIntLiteralWithOverflow type:kotlin.UInt visibility:public modality:FINAL flags:val + BLOCK_BODY + RETURN type=kotlin.Nothing from='(): UInt' + GET_FIELD 'testSimpleUIntLiteralWithOverflow: UInt' type=kotlin.UInt origin=null + PROPERTY name:testUByteWithExpectedType type:kotlin.UByte visibility:public modality:FINAL flags:val + FIELD PROPERTY_BACKING_FIELD name:testUByteWithExpectedType type:kotlin.UByte visibility:public flags:final + EXPRESSION_BODY + CONST Byte type=kotlin.UByte value=1 + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> () returnType:UByte flags: + correspondingProperty: PROPERTY name:testUByteWithExpectedType type:kotlin.UByte visibility:public modality:FINAL flags:val + BLOCK_BODY + RETURN type=kotlin.Nothing from='(): UByte' + GET_FIELD 'testUByteWithExpectedType: UByte' type=kotlin.UByte origin=null + PROPERTY name:testUShortWithExpectedType type:kotlin.UShort visibility:public modality:FINAL flags:val + FIELD PROPERTY_BACKING_FIELD name:testUShortWithExpectedType type:kotlin.UShort visibility:public flags:final + EXPRESSION_BODY + CONST Short type=kotlin.UShort value=1 + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> () returnType:UShort flags: + correspondingProperty: PROPERTY name:testUShortWithExpectedType type:kotlin.UShort visibility:public modality:FINAL flags:val + BLOCK_BODY + RETURN type=kotlin.Nothing from='(): UShort' + GET_FIELD 'testUShortWithExpectedType: UShort' type=kotlin.UShort origin=null + PROPERTY name:testUIntWithExpectedType type:kotlin.UInt visibility:public modality:FINAL flags:val + FIELD PROPERTY_BACKING_FIELD name:testUIntWithExpectedType type:kotlin.UInt visibility:public flags:final + EXPRESSION_BODY + CONST Int type=kotlin.UInt value=1 + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> () returnType:UInt flags: + correspondingProperty: PROPERTY name:testUIntWithExpectedType type:kotlin.UInt visibility:public modality:FINAL flags:val + BLOCK_BODY + RETURN type=kotlin.Nothing from='(): UInt' + GET_FIELD 'testUIntWithExpectedType: UInt' type=kotlin.UInt origin=null + PROPERTY name:testULongWithExpectedType type:kotlin.ULong visibility:public modality:FINAL flags:val + FIELD PROPERTY_BACKING_FIELD name:testULongWithExpectedType type:kotlin.ULong visibility:public flags:final + EXPRESSION_BODY + CONST Long type=kotlin.ULong value=1 + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> () returnType:ULong flags: + correspondingProperty: PROPERTY name:testULongWithExpectedType type:kotlin.ULong visibility:public modality:FINAL flags:val + BLOCK_BODY + RETURN type=kotlin.Nothing from='(): ULong' + GET_FIELD 'testULongWithExpectedType: ULong' type=kotlin.ULong origin=null + PROPERTY name:testToUByte type:kotlin.UByte visibility:public modality:FINAL flags:val + FIELD PROPERTY_BACKING_FIELD name:testToUByte type:kotlin.UByte visibility:public flags:final + EXPRESSION_BODY + CALL 'toUByte() on Int: UByte' type=kotlin.UByte origin=null + $receiver: CONST Int type=kotlin.Int value=1 + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> () returnType:UByte flags: + correspondingProperty: PROPERTY name:testToUByte type:kotlin.UByte visibility:public modality:FINAL flags:val + BLOCK_BODY + RETURN type=kotlin.Nothing from='(): UByte' + GET_FIELD 'testToUByte: UByte' type=kotlin.UByte origin=null + PROPERTY name:testToUShort type:kotlin.UShort visibility:public modality:FINAL flags:val + FIELD PROPERTY_BACKING_FIELD name:testToUShort type:kotlin.UShort visibility:public flags:final + EXPRESSION_BODY + CALL 'toUShort() on Int: UShort' type=kotlin.UShort origin=null + $receiver: CONST Int type=kotlin.Int value=1 + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> () returnType:UShort flags: + correspondingProperty: PROPERTY name:testToUShort type:kotlin.UShort visibility:public modality:FINAL flags:val + BLOCK_BODY + RETURN type=kotlin.Nothing from='(): UShort' + GET_FIELD 'testToUShort: UShort' type=kotlin.UShort origin=null + PROPERTY name:testToUInt type:kotlin.UInt visibility:public modality:FINAL flags:val + FIELD PROPERTY_BACKING_FIELD name:testToUInt type:kotlin.UInt visibility:public flags:final + EXPRESSION_BODY + CALL 'toUInt() on Int: UInt' type=kotlin.UInt origin=null + $receiver: CONST Int type=kotlin.Int value=1 + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> () returnType:UInt flags: + correspondingProperty: PROPERTY name:testToUInt type:kotlin.UInt visibility:public modality:FINAL flags:val + BLOCK_BODY + RETURN type=kotlin.Nothing from='(): UInt' + GET_FIELD 'testToUInt: UInt' type=kotlin.UInt origin=null + PROPERTY name:testToULong type:kotlin.ULong visibility:public modality:FINAL flags:val + FIELD PROPERTY_BACKING_FIELD name:testToULong type:kotlin.ULong visibility:public flags:final + EXPRESSION_BODY + CALL 'toULong() on Int: ULong' type=kotlin.ULong origin=null + $receiver: CONST Int type=kotlin.Int value=1 + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> () returnType:ULong flags: + correspondingProperty: PROPERTY name:testToULong type:kotlin.ULong visibility:public modality:FINAL flags:val + BLOCK_BODY + RETURN type=kotlin.Nothing from='(): ULong' + GET_FIELD 'testToULong: ULong' type=kotlin.ULong origin=null diff --git a/compiler/tests-common/tests/org/jetbrains/kotlin/ir/AbstractIrGeneratorTestCase.kt b/compiler/tests-common/tests/org/jetbrains/kotlin/ir/AbstractIrGeneratorTestCase.kt index 5f7493e030d..c5dd53a0705 100644 --- a/compiler/tests-common/tests/org/jetbrains/kotlin/ir/AbstractIrGeneratorTestCase.kt +++ b/compiler/tests-common/tests/org/jetbrains/kotlin/ir/AbstractIrGeneratorTestCase.kt @@ -51,6 +51,7 @@ abstract class AbstractIrGeneratorTestCase : CodegenTestCase() { val javacOptions = ArrayList(0) var addRuntime = false var addReflect = false + var addUnsigned = false for (file in files) { if (InTextDirectivesUtils.isDirectiveDefined(file.content, "WITH_RUNTIME")) { addRuntime = true @@ -58,6 +59,9 @@ abstract class AbstractIrGeneratorTestCase : CodegenTestCase() { if (InTextDirectivesUtils.isDirectiveDefined(file.content, "WITH_REFLECT")) { addReflect = true } + if (InTextDirectivesUtils.isDirectiveDefined(file.content, "WITH_UNSIGNED")) { + addUnsigned = true + } javacOptions.addAll(InTextDirectivesUtils.findListWithPrefixes(file.content, "// JAVAC_OPTIONS:")) } @@ -65,6 +69,7 @@ abstract class AbstractIrGeneratorTestCase : CodegenTestCase() { val configurationKind = when { addReflect -> ConfigurationKind.ALL addRuntime -> ConfigurationKind.NO_KOTLIN_REFLECT + addUnsigned -> ConfigurationKind.WITH_UNSIGNED_TYPES else -> ConfigurationKind.JDK_ONLY } diff --git a/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java b/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java index d84e1be0fcc..9f713e7330f 100644 --- a/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java @@ -1082,6 +1082,11 @@ public class IrTextTestCaseGenerated extends AbstractIrTextTestCase { runTest("compiler/testData/ir/irText/expressions/typeParameterClassLiteral.kt"); } + @TestMetadata("unsignedIntegerLiterals.kt") + public void testUnsignedIntegerLiterals() throws Exception { + runTest("compiler/testData/ir/irText/expressions/unsignedIntegerLiterals.kt"); + } + @TestMetadata("useImportedMember.kt") public void testUseImportedMember() throws Exception { runTest("compiler/testData/ir/irText/expressions/useImportedMember.kt");