Rewrote all usages of annotations from descriptors to IR

This commit is contained in:
Igor Chevdar
2019-06-24 19:34:55 +03:00
parent 1e8eb1d4a8
commit 440c03035d
22 changed files with 176 additions and 324 deletions
@@ -7,10 +7,11 @@ package org.jetbrains.kotlin.backend.konan
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.util.hasAnnotation
import org.jetbrains.kotlin.name.FqName
internal fun IrClass.isNonGeneratedAnnotation(): Boolean =
this.kind == ClassKind.ANNOTATION_CLASS &&
!this.descriptor.annotations.hasAnnotation(serialInfoAnnotationFqName)
!this.annotations.hasAnnotation(serialInfoAnnotationFqName)
private val serialInfoAnnotationFqName = FqName("kotlinx.serialization.SerialInfo")
@@ -13,12 +13,16 @@ internal const val NATIVE_PTR_NAME = "NativePtr"
internal const val NON_NULL_NATIVE_PTR_NAME = "NonNullNativePtr"
object KonanFqNames {
val packageName = FqName("kotlin.native")
val internalPackageName = FqName("kotlin.native.internal")
val nativePtr = internalPackageName.child(Name.identifier(NATIVE_PTR_NAME)).toUnsafe()
val nonNullNativePtr = internalPackageName.child(Name.identifier(NON_NULL_NATIVE_PTR_NAME)).toUnsafe()
val throws = FqName("kotlin.native.Throws")
val threadLocal = FqName("kotlin.native.concurrent.ThreadLocal")
val sharedImmutable = FqName("kotlin.native.concurrent.SharedImmutable")
val frozen = FqName("kotlin.native.internal.Frozen")
val typedIntrinsic = FqName("kotlin.native.internal.TypedIntrinsic")
val objCMethod = FqName("kotlinx.cinterop.ObjCMethod")
}
/**
@@ -14,10 +14,7 @@ import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.types.classifierOrFail
import org.jetbrains.kotlin.ir.util.constructedClass
import org.jetbrains.kotlin.ir.util.fqNameForIrSerialization
import org.jetbrains.kotlin.ir.util.hasAnnotation
import org.jetbrains.kotlin.ir.util.isReal
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.ExternalOverridabilityCondition
@@ -61,8 +58,7 @@ fun ClassDescriptor.isExternalObjCClass(): Boolean = this.isObjCClass() &&
}
fun IrClass.isExternalObjCClass(): Boolean = this.isObjCClass() &&
(this as IrDeclaration).parentDeclarationsWithSelf.filterIsInstance<IrClass>().any {
it.annotations.hasAnnotation(externalObjCClassFqName) ||
it.descriptor.annotations.hasAnnotation(externalObjCClassFqName)
it.annotations.hasAnnotation(externalObjCClassFqName)
}
fun ClassDescriptor.isObjCForwardDeclaration(): Boolean =
@@ -140,9 +136,9 @@ fun FunctionDescriptor.getObjCMethodInfo(): ObjCMethodInfo? = this.getObjCMethod
fun IrFunction.isObjCBridgeBased(): Boolean {
assert(this.isReal)
return this.descriptor.annotations.hasAnnotation(objCMethodFqName) ||
this.descriptor.annotations.hasAnnotation(objCFactoryFqName) ||
this.descriptor.annotations.hasAnnotation(objCConstructorFqName)
return this.annotations.hasAnnotation(objCMethodFqName) ||
this.annotations.hasAnnotation(objCFactoryFqName) ||
this.annotations.hasAnnotation(objCConstructorFqName)
}
/**
@@ -222,11 +218,11 @@ fun ConstructorDescriptor.objCConstructorIsDesignated(): Boolean {
}
val IrConstructor.isObjCConstructor get() = this.descriptor.annotations.hasAnnotation(objCConstructorFqName)
val IrConstructor.isObjCConstructor get() = this.annotations.hasAnnotation(objCConstructorFqName)
// TODO-DCE-OBJC-INIT: Selector should be preserved by DCE.
fun IrConstructor.getObjCInitMethod(): IrSimpleFunction? {
return this.descriptor.annotations.findAnnotation(objCConstructorFqName)?.let {
return this.annotations.findAnnotation(objCConstructorFqName)?.let {
val initSelector = it.getStringValue("initSelector")
this.constructedClass.declarations.asSequence()
.filterIsInstance<IrSimpleFunction>()
@@ -234,9 +230,9 @@ fun IrConstructor.getObjCInitMethod(): IrSimpleFunction? {
}
}
val IrFunction.hasObjCFactoryAnnotation get() = this.descriptor.annotations.hasAnnotation(objCFactoryFqName)
val IrFunction.hasObjCFactoryAnnotation get() = this.annotations.hasAnnotation(objCFactoryFqName)
val IrFunction.hasObjCMethodAnnotation get() = this.descriptor.annotations.hasAnnotation(objCMethodFqName)
val IrFunction.hasObjCMethodAnnotation get() = this.annotations.hasAnnotation(objCMethodFqName)
fun FunctionDescriptor.getObjCFactoryInitMethodInfo(): ObjCMethodInfo? {
val factoryAnnotation = this.annotations.findAnnotation(objCFactoryFqName) ?: return null
@@ -581,11 +581,9 @@ private fun IrType.isCEnumType(): Boolean {
.any { (it.classifierOrNull?.owner as? IrClass)?.fqNameForIrSerialization == FqName("kotlinx.cinterop.CEnum") }
}
// TODO: get rid of consulting descriptors for annotations.
// Make sure external stubs always get proper annotaions.
private fun IrDeclaration.hasCCallAnnotation(name: String): Boolean =
this.annotations.hasAnnotation(cCall.child(Name.identifier(name))) ||
this.descriptor.annotations.hasAnnotation(cCall.child(Name.identifier(name)))
this.annotations.hasAnnotation(cCall.child(Name.identifier(name)))
private fun IrValueParameter.isWCStringParameter() = hasCCallAnnotation("WCString")
@@ -5,17 +5,19 @@
package org.jetbrains.kotlin.backend.konan.descriptors
import org.jetbrains.kotlin.backend.konan.*
import org.jetbrains.kotlin.backend.konan.descriptors.resolveFakeOverride
import org.jetbrains.kotlin.backend.konan.ir.*
import org.jetbrains.kotlin.backend.konan.isInlinedNative
import org.jetbrains.kotlin.backend.konan.isObjCClass
import org.jetbrains.kotlin.backend.konan.llvm.longName
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.IrConst
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.types.isUnit
import org.jetbrains.kotlin.ir.util.fqNameForIrSerialization
import org.jetbrains.kotlin.ir.util.isReal
import org.jetbrains.kotlin.ir.util.isSuspend
import org.jetbrains.kotlin.ir.util.overrides
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.types.SimpleType
/**
@@ -75,12 +77,8 @@ internal fun IrSimpleFunction.resolveFakeOverride(allowAbstract: Boolean = false
return realSupers.first { allowAbstract || it.modality != Modality.ABSTRACT }
}
// TODO: don't forget to remove descriptor access here.
internal val IrFunction.isTypedIntrinsic: Boolean
get() = this.descriptor.isTypedIntrinsic
internal val IrDeclaration.isFrozen: Boolean
get() = this.descriptor.isFrozen
get() = annotations.hasAnnotation(KonanFqNames.typedIntrinsic)
internal val arrayTypes = setOf(
"kotlin.Array",
@@ -242,4 +240,28 @@ fun IrDeclaration.findTopLevelDeclaration(): IrDeclaration = when {
(this as IrField).correspondingProperty!!.findTopLevelDeclaration()
else ->
(this.parent as IrDeclaration).findTopLevelDeclaration()
}
}
internal val IrClass.isFrozen: Boolean
get() = annotations.hasAnnotation(KonanFqNames.frozen) ||
// RTTI is used for non-reference type box or Objective-C object wrapper:
!this.defaultType.binaryTypeIsReference() || this.isObjCClass()
fun IrConstructorCall.getAnnotationValue() = (getValueArgument(0) as? IrConst<String>)?.value
fun IrConstructorCall.getStringValue(name: String): String {
val parameter = symbol.owner.valueParameters.single { it.name.asString() == name }
return (getValueArgument(parameter.index) as IrConst<String>).value
}
fun IrFunction.externalSymbolOrThrow(): String? {
annotations.findAnnotation(RuntimeNames.symbolNameAnnotation)?.let { return it.getAnnotationValue() }
if (annotations.hasAnnotation(KonanFqNames.objCMethod)) return null
if (annotations.hasAnnotation(KonanFqNames.typedIntrinsic)) return null
if (annotations.hasAnnotation(RuntimeNames.cCall)) return null
throw Error("external function ${this.longName} must have @TypedIntrinsic, @SymbolName or @ObjCMethod annotation")
}
@@ -7,22 +7,14 @@ package org.jetbrains.kotlin.backend.konan.descriptors
import org.jetbrains.kotlin.backend.common.atMostOne
import org.jetbrains.kotlin.backend.konan.RuntimeNames
import org.jetbrains.kotlin.backend.konan.binaryTypeIsReference
import org.jetbrains.kotlin.backend.konan.isObjCClass
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.builtins.konan.KonanBuiltIns
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptorImpl
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.impl.FunctionDescriptorImpl
import org.jetbrains.kotlin.descriptors.konan.DeserializedKonanModuleOrigin
import org.jetbrains.kotlin.descriptors.konan.konanModuleOrigin
import org.jetbrains.kotlin.metadata.konan.KonanProtoBuf
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.DescriptorFactory
import org.jetbrains.kotlin.resolve.OverridingUtil
import org.jetbrains.kotlin.resolve.constants.StringValue
import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.resolve.descriptorUtil.module
@@ -30,11 +22,8 @@ import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPropertyDescriptor
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedSimpleFunctionDescriptor
import org.jetbrains.kotlin.serialization.konan.KonanPackageFragment
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.typeUtil.isNothing
import org.jetbrains.kotlin.types.typeUtil.isUnit
import org.jetbrains.kotlin.utils.addToStdlib.ifNotEmpty
/**
* Implementation of given method.
@@ -172,31 +161,6 @@ internal val DeclarationDescriptor.isExpectMember: Boolean
internal val DeclarationDescriptor.isSerializableExpectClass: Boolean
get() = this is ClassDescriptor && ExpectedActualDeclarationChecker.shouldGenerateExpectClass(this)
internal fun KotlinType?.createExtensionReceiver(owner: CallableDescriptor): ReceiverParameterDescriptor? =
DescriptorFactory.createExtensionReceiverParameterForCallable(
owner,
this,
Annotations.EMPTY
)
internal fun FunctionDescriptorImpl.initialize(
extensionReceiverType: KotlinType?,
dispatchReceiverParameter: ReceiverParameterDescriptor?,
typeParameters: List<TypeParameterDescriptor>,
unsubstitutedValueParameters: List<ValueParameterDescriptor>,
unsubstitutedReturnType: KotlinType?,
modality: Modality?,
visibility: Visibility
): FunctionDescriptorImpl = this.initialize(
extensionReceiverType.createExtensionReceiver(this),
dispatchReceiverParameter,
typeParameters,
unsubstitutedValueParameters,
unsubstitutedReturnType,
modality,
visibility
)
private fun sourceByIndex(descriptor: CallableMemberDescriptor, index: Int): SourceFile {
val fragment = descriptor.findPackage() as KonanPackageFragment
return fragment.sourceFileMap.sourceFile(index)
@@ -216,43 +180,4 @@ fun CallableMemberDescriptor.findSourceFile(): SourceFile {
}
}
internal val DeclarationDescriptor.isFrozen: Boolean
get() = this.annotations.hasAnnotation(RuntimeNames.frozenAnnotation) ||
(this is org.jetbrains.kotlin.descriptors.ClassDescriptor
// RTTI is used for non-reference type box or Objective-C object wrapper:
&& (!this.defaultType.binaryTypeIsReference() || this.isObjCClass()))
internal val FunctionDescriptor.isTypedIntrinsic: Boolean
get() = this.annotations.hasAnnotation(RuntimeNames.typedIntrinsicAnnotation)
// TODO: coalesce all our annotation value getters into fewer functions.
fun getAnnotationValue(annotation: AnnotationDescriptor): String? {
return annotation.allValueArguments.values.ifNotEmpty {
val stringValue = single() as? StringValue
stringValue?.value
}
}
fun CallableMemberDescriptor.externalSymbolOrThrow(): String? {
this.annotations.findAnnotation(RuntimeNames.symbolNameAnnotation)?.let {
return getAnnotationValue(it)!!
}
if (this.annotations.hasAnnotation(RuntimeNames.objCMethodAnnotation)) return null
if (this.annotations.hasAnnotation(RuntimeNames.typedIntrinsicAnnotation)) return null
if (this.annotations.hasAnnotation(RuntimeNames.cCall)) return null
throw Error("external function ${this} must have @TypedIntrinsic, @SymbolName or @ObjCMethod annotation")
}
fun createAnnotation(
descriptor: ClassDescriptor,
vararg values: Pair<String, String>
): AnnotationDescriptor = AnnotationDescriptorImpl(
descriptor.defaultType,
values.map { (name, value) -> Name.identifier(name) to StringValue(value) }.toMap(),
SourceElement.NO_SOURCE
)
val ModuleDescriptor.konanLibrary get() = (this.konanModuleOrigin as? DeserializedKonanModuleOrigin)?.library
@@ -451,13 +451,13 @@ internal class KonanSymbols(context: Context, private val symbolTable: SymbolTab
)
val listOfInternal = internalFunction("listOfInternal")
val threadLocal =
val threadLocal = symbolTable.referenceClass(
context.builtIns.builtInsModule.findClassAcrossModuleDependencies(
ClassId.topLevel(FqName("kotlin.native.concurrent.ThreadLocal")))!!
ClassId.topLevel(KonanFqNames.threadLocal))!!)
val sharedImmutable =
val sharedImmutable = symbolTable.referenceClass(
context.builtIns.builtInsModule.findClassAcrossModuleDependencies(
ClassId.topLevel(FqName("kotlin.native.concurrent.SharedImmutable")))!!
ClassId.topLevel(KonanFqNames.sharedImmutable))!!)
private fun topLevelClass(fqName: String): IrClassSymbol = topLevelClass(FqName(fqName))
private fun topLevelClass(fqName: FqName): IrClassSymbol = classById(ClassId.topLevel(fqName))
@@ -6,7 +6,6 @@
package org.jetbrains.kotlin.backend.konan.ir
import org.jetbrains.kotlin.backend.common.atMostOne
import org.jetbrains.kotlin.backend.konan.descriptors.getArgumentValueOrNull
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibilities
@@ -69,14 +68,7 @@ val IrClass.isFinalClass: Boolean
fun IrClass.isSpecialClassWithNoSupertypes() = this.isAny() || this.isNothing()
fun <T> IrDeclaration.getAnnotationArgumentValue(fqName: FqName, argumentName: String): T? {
val annotation = this.annotations.findAnnotation(fqName)
if (annotation == null) {
// As a last resort try searching the descriptor.
// This is needed for a period while we don't have IR for platform libraries.
return this.descriptor.annotations
.findAnnotation(fqName)
?.getArgumentValueOrNull<T>(argumentName)
}
val annotation = this.annotations.findAnnotation(fqName) ?: return null
for (index in 0 until annotation.valueArgumentsCount) {
val parameter = annotation.symbol.owner.valueParameters[index]
if (parameter.name == Name.identifier(argumentName)) {
@@ -18,11 +18,9 @@ import org.jetbrains.kotlin.backend.konan.ir.isUnit
import org.jetbrains.kotlin.backend.konan.llvm.KonanMangler.isExported
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.util.fqNameForIrSerialization
import org.jetbrains.kotlin.ir.types.getClass
import org.jetbrains.kotlin.ir.util.isSuspend
import org.jetbrains.kotlin.ir.util.isVararg
import org.jetbrains.kotlin.backend.konan.isInlinedNative
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.konan.library.KonanLibrary
import org.jetbrains.kotlin.library.uniqueName
@@ -45,20 +43,19 @@ object KonanMangler : KotlinManglerImpl() {
*/
override fun IrDeclaration.isPlatformSpecificExported(): Boolean {
// TODO: revise
val descriptorAnnotations = this.descriptor.annotations
if (descriptorAnnotations.hasAnnotation(RuntimeNames.symbolNameAnnotation)) {
if (annotations.hasAnnotation(RuntimeNames.symbolNameAnnotation)) {
// Treat any `@SymbolName` declaration as exported.
return true
}
if (descriptorAnnotations.hasAnnotation(RuntimeNames.exportForCppRuntime)) {
if (annotations.hasAnnotation(RuntimeNames.exportForCppRuntime)) {
// Treat any `@ExportForCppRuntime` declaration as exported.
return true
}
if (descriptorAnnotations.hasAnnotation(RuntimeNames.cnameAnnotation)) {
if (annotations.hasAnnotation(RuntimeNames.cnameAnnotation)) {
// Treat `@CName` declaration as exported.
return true
}
if (descriptorAnnotations.hasAnnotation(RuntimeNames.exportForCompilerAnnotation)) {
if (annotations.hasAnnotation(RuntimeNames.exportForCompilerAnnotation)) {
return true
}
@@ -107,13 +104,13 @@ object KonanMangler : KotlinManglerImpl() {
}
if (isExternal) {
this.descriptor.externalSymbolOrThrow()?.let {
this.externalSymbolOrThrow()?.let {
return it
}
}
this.descriptor.annotations.findAnnotation(RuntimeNames.exportForCppRuntime)?.let {
val name = getAnnotationValue(it) ?: this.name.asString()
this.annotations.findAnnotation(RuntimeNames.exportForCppRuntime)?.let {
val name = it.getAnnotationValue() ?: this.name.asString()
return name // no wrapping currently required
}
@@ -3,6 +3,7 @@ package org.jetbrains.kotlin.backend.konan.llvm
import kotlinx.cinterop.cValuesOf
import llvm.*
import org.jetbrains.kotlin.backend.konan.RuntimeNames
import org.jetbrains.kotlin.backend.konan.descriptors.getAnnotationValue
import org.jetbrains.kotlin.backend.konan.descriptors.isTypedIntrinsic
import org.jetbrains.kotlin.backend.konan.llvm.objc.genObjCSelector
import org.jetbrains.kotlin.backend.konan.reportCompilationError
@@ -12,8 +13,8 @@ import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.types.getClass
import org.jetbrains.kotlin.ir.util.dump
import org.jetbrains.kotlin.ir.util.findAnnotation
import org.jetbrains.kotlin.ir.util.isSuspend
import org.jetbrains.kotlin.name.Name
internal enum class IntrinsicType {
PLUS,
@@ -113,8 +114,8 @@ internal fun tryGetIntrinsicType(callSite: IrFunctionAccessExpression): Intrinsi
private fun getIntrinsicType(callSite: IrFunctionAccessExpression): IntrinsicType {
val function = callSite.symbol.owner
val annotation = function.descriptor.annotations.findAnnotation(RuntimeNames.typedIntrinsicAnnotation)!!
val value = annotation.allValueArguments.getValue(Name.identifier("kind")).value as String
val annotation = function.annotations.findAnnotation(RuntimeNames.typedIntrinsicAnnotation)!!
val value = annotation.getAnnotationValue()!!
return IntrinsicType.valueOf(value)
}
@@ -16,7 +16,6 @@ import org.jetbrains.kotlin.backend.konan.ir.*
import org.jetbrains.kotlin.backend.konan.ir.NaiveSourceBasedFileEntryImpl
import org.jetbrains.kotlin.backend.konan.ir.containsNull
import org.jetbrains.kotlin.backend.konan.llvm.coverage.*
import org.jetbrains.kotlin.backend.konan.llvm.objcexport.is64Bit
import org.jetbrains.kotlin.backend.konan.optimizations.*
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.builtins.UnsignedType
@@ -28,29 +27,14 @@ import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.descriptors.IrPropertyDelegateDescriptor
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.symbols.*
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
import org.jetbrains.kotlin.ir.visitors.acceptVoid
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.descriptorUtil.classId
private val threadLocalAnnotationFqName = FqName("kotlin.native.concurrent.ThreadLocal")
private val sharedAnnotationFqName = FqName("kotlin.native.concurrent.SharedImmutable")
private val frozenAnnotationFqName = FqName("kotlin.native.internal.Frozen")
val IrField.propertyDescriptor: PropertyDescriptor
get() {
val descriptor = this.descriptor
return if (descriptor is IrPropertyDelegateDescriptor)
descriptor.correspondingProperty
else
descriptor
}
internal enum class FieldStorage {
MAIN_THREAD,
SHARED,
@@ -59,17 +43,18 @@ internal enum class FieldStorage {
// TODO: maybe unannotated singleton objects shall be accessed from main thread only as well?
val IrClass.objectIsShared get() =
!descriptor.annotations.hasAnnotation(threadLocalAnnotationFqName)
!annotations.hasAnnotation(KonanFqNames.threadLocal)
internal val IrField.storageClass: FieldStorage get() {
val descriptor = propertyDescriptor
// TODO: Is this correct?
val annotations = correspondingPropertySymbol?.owner?.annotations ?: annotations
return when {
descriptor.annotations.hasAnnotation(threadLocalAnnotationFqName) -> FieldStorage.THREAD_LOCAL
annotations.hasAnnotation(KonanFqNames.threadLocal) -> FieldStorage.THREAD_LOCAL
!isFinal -> FieldStorage.MAIN_THREAD
descriptor.annotations.hasAnnotation(sharedAnnotationFqName) -> FieldStorage.SHARED
annotations.hasAnnotation(KonanFqNames.sharedImmutable) -> FieldStorage.SHARED
// TODO: simplify, once IR types are fully there.
type is IrSimpleType && (type as IrSimpleType).
classifier.descriptor.annotations.hasAnnotation(frozenAnnotationFqName) -> FieldStorage.SHARED
(type.classifierOrNull?.owner as? IrAnnotationContainer)
?.annotations?.hasAnnotation(KonanFqNames.frozen) == true -> FieldStorage.SHARED
else -> FieldStorage.MAIN_THREAD
}
}
@@ -682,7 +667,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
}
if (declaration.descriptor.retainAnnotation(context.config.target)) {
if (declaration.retainAnnotation(context.config.target)) {
context.llvm.usedFunctions.add(codegen.llvmFunction(declaration))
}
@@ -1452,11 +1437,10 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
}
//-------------------------------------------------------------------------//
// TODO: rewrite in IR!
private fun needMutationCheck(descriptor: org.jetbrains.kotlin.descriptors.DeclarationDescriptor): Boolean {
private fun needMutationCheck(irClass: IrClass): Boolean {
// For now we omit mutation checks on immutable types, as this allows initialization in constructor
// and it is assumed that API doesn't allow to change them.
return !descriptor.isFrozen
return !irClass.isFrozen
}
private fun evaluateSetField(value: IrSetField): LLVMValueRef {
@@ -1467,7 +1451,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
assert(thisPtr.type == codegen.kObjHeaderPtr) {
LLVMPrintTypeToString(thisPtr.type)?.toKString().toString()
}
if (needMutationCheck(value.descriptor.containingDeclaration)) {
if (needMutationCheck(value.symbol.owner.parentAsClass)) {
functionGenerationContext.call(context.llvm.mutationCheck,
listOf(functionGenerationContext.bitcast(codegen.kObjHeaderPtr, thisPtr)),
Lifetime.IRRELEVANT, ExceptionHandler.Caller)
@@ -2086,7 +2070,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
assert(irClass.isInterface)
assert(irClass.isExternalObjCClass())
val annotation = irClass.descriptor.annotations.findAnnotation(externalObjCClassFqName)!!
val annotation = irClass.annotations.findAnnotation(externalObjCClassFqName)!!
val protocolGetterName = annotation.getStringValue("protocolGetter")
val protocolGetter = context.llvm.externalFunction(
protocolGetterName,
@@ -8,13 +8,13 @@ package org.jetbrains.kotlin.backend.konan.llvm
import llvm.LLVMStoreSizeOfType
import llvm.LLVMValueRef
import org.jetbrains.kotlin.backend.common.atMostOne
import org.jetbrains.kotlin.backend.common.ir.simpleFunctions
import org.jetbrains.kotlin.backend.konan.*
import org.jetbrains.kotlin.backend.konan.descriptors.getStringValue
import org.jetbrains.kotlin.backend.konan.ir.*
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
import org.jetbrains.kotlin.ir.util.constructors
import org.jetbrains.kotlin.ir.util.findAnnotation
import org.jetbrains.kotlin.ir.util.fqNameForIrSerialization
import org.jetbrains.kotlin.ir.util.hasAnnotation
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
@@ -118,7 +118,7 @@ internal class KotlinObjCClassInfoGenerator(override val context: Context) : Con
.filterIsInstance<IrSimpleFunction>()
.mapNotNull {
val annotation =
it.descriptor.annotations.findAnnotation(context.interopBuiltIns.objCMethodImp.fqNameSafe) ?:
it.annotations.findAnnotation(context.interopBuiltIns.objCMethodImp.fqNameSafe) ?:
return@mapNotNull null
ObjCMethodDesc(
@@ -14,8 +14,6 @@ import org.jetbrains.kotlin.backend.konan.isExternalObjCClassMethod
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.konan.KonanAbiVersion
import org.jetbrains.kotlin.ir.util.fqNameSafe
import org.jetbrains.kotlin.ir.util.isAnnotationClass
import org.jetbrains.kotlin.ir.util.isInterface
import org.jetbrains.kotlin.library.KotlinAbiVersion
@@ -128,9 +126,9 @@ internal class RTTIGenerator(override val context: Context) : ContextUtils {
private val EXPORT_TYPE_INFO_FQ_NAME = FqName.fromSegments(listOf("kotlin", "native", "internal", "ExportTypeInfo"))
private fun exportTypeInfoIfRequired(irClass: IrClass, typeInfoGlobal: LLVMValueRef?) {
val annotation = irClass.descriptor.annotations.findAnnotation(EXPORT_TYPE_INFO_FQ_NAME)
val annotation = irClass.annotations.findAnnotation(EXPORT_TYPE_INFO_FQ_NAME)
if (annotation != null) {
val name = getAnnotationValue(annotation)!!
val name = annotation.getAnnotationValue()!!
// TODO: use LLVMAddAlias.
val global = addGlobal(name, pointerType(runtime.typeInfoType), isExported = true)
LLVMSetInitializer(global, typeInfoGlobal)
@@ -5,18 +5,18 @@
package org.jetbrains.kotlin.backend.konan.llvm
import org.jetbrains.kotlin.backend.konan.descriptors.getStringValueOrNull
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.backend.konan.descriptors.getAnnotationValue
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.util.findAnnotation
import org.jetbrains.kotlin.konan.target.KonanTarget
import org.jetbrains.kotlin.name.FqName
private val retainAnnotationName = FqName("kotlin.native.Retain")
private val retainForTargetAnnotationName = FqName("kotlin.native.RetainForTarget")
internal fun FunctionDescriptor.retainAnnotation(target: KonanTarget): Boolean {
internal fun IrFunction.retainAnnotation(target: KonanTarget): Boolean {
if (this.annotations.findAnnotation(retainAnnotationName) != null) return true
val forTarget = this.annotations.findAnnotation(retainForTargetAnnotationName)
if (forTarget != null && forTarget.getStringValueOrNull("target") == target.name) return true
if (forTarget != null && forTarget.getAnnotationValue() == target.name) return true
return false
}
@@ -14,7 +14,6 @@ import org.jetbrains.kotlin.backend.konan.Context
import org.jetbrains.kotlin.backend.konan.descriptors.synthesizedName
import org.jetbrains.kotlin.backend.common.pop
import org.jetbrains.kotlin.backend.common.push
import org.jetbrains.kotlin.backend.konan.ir.fqNameForIrSerialization
import org.jetbrains.kotlin.backend.konan.ir.isFunctionOrKFunctionType
import org.jetbrains.kotlin.backend.konan.llvm.functionName
import org.jetbrains.kotlin.descriptors.*
@@ -95,11 +94,10 @@ internal class CallableReferenceLowering(val context: Context): FileLoweringPass
if (cur !is IrCall)
break
val argument = if (i < stack.size - 1) stack[i + 1] else expression
val descriptor = cur.descriptor
val argumentDescriptor = descriptor.valueParameters.singleOrNull {
val parameter = cur.symbol.owner.valueParameters.singleOrNull {
cur.getValueArgument(it.index) == argument
}
if (argumentDescriptor?.annotations?.findAnnotation(VOLATILE_LAMBDA_FQ_NAME) != null) {
if (parameter?.annotations?.findAnnotation(VOLATILE_LAMBDA_FQ_NAME) != null) {
return expression
}
break
@@ -10,12 +10,13 @@ import org.jetbrains.kotlin.backend.konan.Context
import org.jetbrains.kotlin.contracts.parsing.ContractsDslNames
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrDeclarationContainer
import org.jetbrains.kotlin.ir.util.hasAnnotation
import org.jetbrains.kotlin.ir.util.transformFlat
internal class ContractsDslRemover(val context: Context) : DeclarationContainerLoweringPass {
override fun lower(irDeclarationContainer: IrDeclarationContainer) {
irDeclarationContainer.declarations.transformFlat {
if (it is IrClass && it.descriptor.annotations.hasAnnotation(ContractsDslNames.CONTRACTS_DSL_ANNOTATION_FQN))
if (it is IrClass && it.annotations.hasAnnotation(ContractsDslNames.CONTRACTS_DSL_ANNOTATION_FQN))
null
else
listOf(it)
@@ -12,6 +12,10 @@ import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
import org.jetbrains.kotlin.backend.common.lower.irBlock
import org.jetbrains.kotlin.backend.konan.Context
import org.jetbrains.kotlin.backend.konan.descriptors.synthesizedName
import org.jetbrains.kotlin.backend.konan.KonanBackendContext
import org.jetbrains.kotlin.backend.konan.ir.buildSimpleAnnotation
import org.jetbrains.kotlin.backend.konan.ir.typeWithStarProjections
import org.jetbrains.kotlin.backend.konan.isObjCClass
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptorImpl
import org.jetbrains.kotlin.descriptors.annotations.Annotations
@@ -87,10 +91,7 @@ internal class PropertyDelegationLowering(val context: Context) : FileLoweringPa
val kPropertiesFieldType: IrType = context.ir.symbols.array.typeWith(kPropertyImplType)
val kPropertiesField = WrappedFieldDescriptor(
Annotations.create(listOf(AnnotationDescriptorImpl(context.ir.symbols.sharedImmutable.defaultType,
emptyMap(), SourceElement.NO_SOURCE)))
).let {
val kPropertiesField = WrappedFieldDescriptor().let {
IrFieldImpl(
SYNTHETIC_OFFSET, SYNTHETIC_OFFSET,
DECLARATION_ORIGIN_KPROPERTIES_FOR_DELEGATION,
@@ -104,6 +105,7 @@ internal class PropertyDelegationLowering(val context: Context) : FileLoweringPa
).apply {
it.bind(this)
parent = irFile
annotations += buildSimpleAnnotation(context.irBuiltIns, startOffset, endOffset, context.ir.symbols.sharedImmutable.owner)
}
}
@@ -5,13 +5,13 @@
package org.jetbrains.kotlin.backend.konan.lower
import org.jetbrains.kotlin.backend.common.FileLoweringPass
import org.jetbrains.kotlin.backend.common.*
import org.jetbrains.kotlin.backend.common.descriptors.WrappedSimpleFunctionDescriptor
import org.jetbrains.kotlin.backend.common.descriptors.WrappedValueParameterDescriptor
import org.jetbrains.kotlin.backend.common.ir.copyTo
import org.jetbrains.kotlin.backend.common.ir.createDispatchReceiverParameter
import org.jetbrains.kotlin.backend.common.ir.simpleFunctions
import org.jetbrains.kotlin.backend.common.lower.*
import org.jetbrains.kotlin.backend.common.peek
import org.jetbrains.kotlin.backend.common.pop
import org.jetbrains.kotlin.backend.common.push
import org.jetbrains.kotlin.backend.konan.*
import org.jetbrains.kotlin.backend.konan.cgen.*
import org.jetbrains.kotlin.backend.konan.descriptors.allOverriddenFunctions
@@ -26,12 +26,7 @@ import org.jetbrains.kotlin.backend.konan.llvm.tryGetIntrinsicType
import org.jetbrains.kotlin.builtins.UnsignedTypes
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptorImpl
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.builders.*
@@ -43,15 +38,15 @@ import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.OverridingUtil
import org.jetbrains.kotlin.resolve.constants.StringValue
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassNotAny
internal abstract class BaseInteropIrTransformer(private val context: Context) : IrBuildingTransformer(context) {
@@ -159,20 +154,20 @@ internal class InteropLoweringPart1(val context: Context) : BaseInteropIrTransfo
irClass.declarations.toList().mapNotNull {
when {
it is IrSimpleFunction && it.descriptor.annotations.hasAnnotation(interop.objCAction) ->
it is IrSimpleFunction && it.annotations.hasAnnotation(interop.objCAction.fqNameSafe) ->
generateActionImp(it)
it is IrProperty && it.descriptor.annotations.hasAnnotation(interop.objCOutlet) ->
it is IrProperty && it.annotations.hasAnnotation(interop.objCOutlet.fqNameSafe) ->
generateOutletSetterImp(it)
it is IrConstructor && it.descriptor.annotations.hasAnnotation(interop.objCOverrideInit) ->
it is IrConstructor && it.annotations.hasAnnotation(interop.objCOverrideInit.fqNameSafe) ->
generateOverrideInit(irClass, it)
else -> null
}
}.let { irClass.addChildren(it) }
if (irClass.descriptor.annotations.hasAnnotation(interop.exportObjCClass.fqNameSafe)) {
if (irClass.annotations.hasAnnotation(interop.exportObjCClass.fqNameSafe)) {
val irBuilder = context.createIrBuilder(currentFile.symbol).at(irClass)
topLevelInitializers.add(irBuilder.getObjCClass(irClass.symbol))
}
@@ -224,51 +219,26 @@ internal class InteropLoweringPart1(val context: Context) : BaseInteropIrTransfo
// Generate `override fun init...(...) = this.initBy(...)`:
val resultDescriptor = SimpleFunctionDescriptorImpl.create(
irClass.descriptor,
Annotations.EMPTY,
initMethod.name,
CallableMemberDescriptor.Kind.DECLARATION,
SourceElement.NO_SOURCE
)
val valueParameters = constructor.valueParameters.map {
val descriptor = ValueParameterDescriptorImpl(
resultDescriptor,
null,
it.index,
Annotations.EMPTY,
it.name,
it.descriptor.type,
false,
false,
false,
it.varargElementType?.toKotlinType(),
SourceElement.NO_SOURCE
)
it.copy(descriptor)
}
resultDescriptor.initialize(
null,
irClass.descriptor.thisAsReceiverParameter,
emptyList<TypeParameterDescriptor>(),
valueParameters.map { it.descriptor as ValueParameterDescriptor },
irClass.descriptor.defaultType,
Modality.OPEN,
Visibilities.PUBLIC
)
val resultDescriptor = WrappedSimpleFunctionDescriptor()
return IrFunctionImpl(
constructor.startOffset, constructor.endOffset, OVERRIDING_INITIALIZER_BY_CONSTRUCTOR,
resultDescriptor,
irClass.defaultType
constructor.startOffset, constructor.endOffset,
OVERRIDING_INITIALIZER_BY_CONSTRUCTOR,
IrSimpleFunctionSymbolImpl(resultDescriptor),
initMethod.name,
Visibilities.PUBLIC,
Modality.OPEN,
irClass.defaultType,
isInline = false,
isExternal = false,
isTailrec = false,
isSuspend = false
).also { result ->
resultDescriptor.bind(result)
result.parent = irClass
result.createDispatchReceiverParameter()
result.valueParameters += valueParameters
constructor.valueParameters.mapTo(result.valueParameters) { it.copyTo(result) }
result.overriddenSymbols.add(initMethod.symbol)
result.descriptor.overriddenDescriptors = listOf(initMethod.descriptor)
result.body = context.createIrBuilder(result.symbol).irBlockBody(result) {
+irReturn(
@@ -390,54 +360,40 @@ internal class InteropLoweringPart1(val context: Context) : BaseInteropIrTransfo
}
}
val newDescriptor = SimpleFunctionDescriptorImpl.create(
function.descriptor.containingDeclaration,
Annotations.EMPTY,
("imp:" + selector).synthesizedName,
CallableMemberDescriptor.Kind.SYNTHESIZED,
SourceElement.NO_SOURCE
)
val valueParameters = parameterTypes.mapIndexed { index, it ->
ValueParameterDescriptorImpl(
newDescriptor,
null,
index,
Annotations.EMPTY,
Name.identifier("p$index"),
it.toKotlinType(),
false,
false,
false,
null,
SourceElement.NO_SOURCE
)
val newFunction = WrappedSimpleFunctionDescriptor().let {
IrFunctionImpl(
function.startOffset, function.endOffset,
IrDeclarationOrigin.DEFINED,
IrSimpleFunctionSymbolImpl(it),
("imp:$selector").synthesizedName,
Visibilities.PRIVATE,
Modality.FINAL,
returnType,
isInline = false,
isExternal = false,
isTailrec = false,
isSuspend = false
).apply {
it.bind(this)
}
}
newDescriptor.initialize(
null, null,
emptyList(),
valueParameters,
function.descriptor.returnType,
Modality.FINAL,
Visibilities.PRIVATE
)
val newFunction = IrFunctionImpl(
function.startOffset, function.endOffset,
IrDeclarationOrigin.DEFINED,
newDescriptor,
function.returnType
).apply {
parameterTypes.mapIndexedTo(this.valueParameters) { index, it ->
parameterTypes.mapIndexedTo(newFunction.valueParameters) { index, type ->
WrappedValueParameterDescriptor().let {
IrValueParameterImpl(
startOffset,
endOffset,
function.startOffset, function.endOffset,
IrDeclarationOrigin.DEFINED,
descriptor.valueParameters[index],
it,
null
)
IrValueParameterSymbolImpl(it),
Name.identifier("p$index"),
index,
type,
varargElementType = null,
isCrossinline = false,
isNoinline = false
).apply {
it.bind(this)
parent = newFunction
}
}
}
@@ -480,18 +436,6 @@ internal class InteropLoweringPart1(val context: Context) : BaseInteropIrTransfo
}
}
private fun createObjCMethodImpAnnotations(selector: String, encoding: String): Annotations {
val annotation = AnnotationDescriptorImpl(
context.interopBuiltIns.objCMethodImp.defaultType,
mapOf("selector" to selector, "encoding" to encoding)
.mapKeys { Name.identifier(it.key) }
.mapValues { StringValue(it.value) },
SourceElement.NO_SOURCE
)
return Annotations.create(listOf(annotation))
}
private fun checkKotlinObjCClass(irClass: IrClass) {
val kind = irClass.descriptor.kind
if (kind != ClassKind.CLASS && kind != ClassKind.OBJECT) {
@@ -561,7 +505,6 @@ internal class InteropLoweringPart1(val context: Context) : BaseInteropIrTransfo
builder.at(expression)
val constructedClass = outerClasses.peek()!!
val constructedClassDescriptor = constructedClass.descriptor
if (!constructedClass.isObjCClass()) {
return expression
@@ -578,12 +521,13 @@ internal class InteropLoweringPart1(val context: Context) : BaseInteropIrTransfo
}
}
val delegatingCallConstructingClass = expression.symbol.owner.constructedClass
if (!constructedClass.isExternalObjCClass() &&
(expression.symbol.owner.constructedClass).isExternalObjCClass()) {
delegatingCallConstructingClass.isExternalObjCClass()) {
// Calling super constructor from Kotlin Objective-C class.
assert(constructedClassDescriptor.getSuperClassNotAny() == expression.descriptor.constructedClass)
assert(constructedClass.getSuperClassNotAny() == delegatingCallConstructingClass)
val initMethod = expression.symbol.owner.getObjCInitMethod()!!
@@ -602,14 +546,14 @@ internal class InteropLoweringPart1(val context: Context) : BaseInteropIrTransfo
val initCall = builder.genLoweredObjCMethodCall(
initMethodInfo,
superQualifier = expression.symbol.owner.constructedClass.symbol,
superQualifier = delegatingCallConstructingClass.symbol,
receiver = builder.getRawPtr(builder.irGet(constructedClass.thisReceiver!!)),
arguments = initMethod.valueParameters.map { expression.getValueArgument(it.index) },
call = expression,
method = initMethod
)
val superConstructor = expression.symbol.owner.constructedClass
val superConstructor = delegatingCallConstructingClass
.constructors.single { it.valueParameters.size == 0 }.symbol
return builder.irBlock(expression) {
@@ -897,7 +841,7 @@ private class InteropTransformer(val context: Context, override val irFile: IrFi
}
}
if (function.descriptor.annotations.hasAnnotation(RuntimeNames.cCall)) {
if (function.annotations.hasAnnotation(RuntimeNames.cCall)) {
context.llvmImports.add(function.descriptor.llvmSymbolOrigin)
return generateWithStubs { generateCCall(expression, builder, isInvoke = false) }
}
@@ -1186,5 +1130,3 @@ private fun IrBuilder.irFloat(value: Float) =
private fun IrBuilder.irDouble(value: Double) =
IrConstImpl.double(startOffset, endOffset, context.irBuiltIns.doubleType, value)
private fun Annotations.hasAnnotation(descriptor: ClassDescriptor) = this.hasAnnotation(descriptor.fqNameSafe)
@@ -463,7 +463,7 @@ internal class TestProcessor (val context: Context) {
}
}
private val IrClass.ignored: Boolean get() = descriptor.annotations.hasAnnotation(IGNORE_FQ_NAME)
private val IrClass.ignored: Boolean get() = annotations.hasAnnotation(IGNORE_FQ_NAME)
/**
* Builds a test suite class representing a test class (any class in the original IrFile with method(s)
@@ -19,10 +19,7 @@ import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.IrCall
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
import org.jetbrains.kotlin.ir.expressions.IrGetField
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.getClass
import org.jetbrains.kotlin.ir.types.isNothing
@@ -602,15 +599,15 @@ internal object DataFlowIR {
}
val symbol = when {
it.isExternal || (it.symbol in context.irBuiltIns.irBuiltInsSymbols) -> {
val escapesAnnotation = it.descriptor.annotations.findAnnotation(FQ_NAME_ESCAPES)
val pointsToAnnotation = it.descriptor.annotations.findAnnotation(FQ_NAME_POINTS_TO)
val escapesAnnotation = it.annotations.findAnnotation(FQ_NAME_ESCAPES)
val pointsToAnnotation = it.annotations.findAnnotation(FQ_NAME_POINTS_TO)
@Suppress("UNCHECKED_CAST")
val escapesBitMask = (escapesAnnotation?.allValueArguments?.get(escapesWhoDescriptor.name) as? ConstantValue<Int>)?.value
val escapesBitMask = (escapesAnnotation?.getValueArgument(0) as? IrConst<Int>)?.value
@Suppress("UNCHECKED_CAST")
val pointsToBitMask = (pointsToAnnotation?.allValueArguments?.get(pointsToOnWhomDescriptor.name) as? ConstantValue<List<IntValue>>)?.value
val pointsToBitMask = (pointsToAnnotation?.getValueArgument(0) as? IrVararg)?.elements?.map { (it as IrConst<Int>).value }
FunctionSymbol.External(name.localHash.value, attributes, it, takeName { name }).apply {
escapes = escapesBitMask
pointsTo = pointsToBitMask?.let { it.map { it.value }.toIntArray() }
pointsTo = pointsToBitMask?.let { it.toIntArray() }
}
}
@@ -7,6 +7,7 @@ import org.jetbrains.kotlin.backend.konan.llvm.KonanMangler
import org.jetbrains.kotlin.backend.common.serialization.DeclarationTable
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.util.hasAnnotation
class KonanIrModuleSerializer(
logger: LoggingContext,
@@ -15,9 +16,9 @@ class KonanIrModuleSerializer(
) : IrModuleSerializer(logger, declarationTable, KonanMangler, bodiesOnlyForInlines) {
override fun backendSpecificExplicitRoot(declaration: IrFunction) =
declaration.descriptor.annotations.hasAnnotation(RuntimeNames.exportForCppRuntime)
declaration.annotations.hasAnnotation(RuntimeNames.exportForCppRuntime)
override fun backendSpecificExplicitRoot(declaration: IrClass) =
declaration.descriptor.annotations.hasAnnotation(RuntimeNames.exportTypeInfoAnnotation)
declaration.annotations.hasAnnotation(RuntimeNames.exportTypeInfoAnnotation)
}
@@ -7,22 +7,20 @@ package org.jetbrains.kotlin.ir.util
import org.jetbrains.kotlin.backend.common.CommonBackendContext
import org.jetbrains.kotlin.backend.common.descriptors.*
import org.jetbrains.kotlin.backend.common.descriptors.WrappedSimpleFunctionDescriptor
import org.jetbrains.kotlin.backend.common.descriptors.WrappedVariableDescriptor
import org.jetbrains.kotlin.backend.common.descriptors.substitute
import org.jetbrains.kotlin.backend.common.ir.copyParameterDeclarationsFrom
import org.jetbrains.kotlin.backend.konan.KonanBackendContext
import org.jetbrains.kotlin.backend.konan.KonanCompilationException
import org.jetbrains.kotlin.backend.konan.KonanFqNames
import org.jetbrains.kotlin.backend.konan.RuntimeNames
import org.jetbrains.kotlin.backend.konan.descriptors.synthesizedName
import org.jetbrains.kotlin.backend.konan.ir.allParameters
import org.jetbrains.kotlin.backend.konan.ir.buildSimpleAnnotation
import org.jetbrains.kotlin.backend.konan.ir.containsNull
import org.jetbrains.kotlin.builtins.KOTLIN_REFLECT_FQ_NAME
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.ParameterDescriptor
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptorImpl
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.builders.*
@@ -36,8 +34,6 @@ import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
import org.jetbrains.kotlin.ir.symbols.impl.IrFieldSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrVariableSymbolImpl
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
@@ -65,13 +61,7 @@ internal fun IrExpression.isNullConst() = this is IrConst<*> && this.kind == IrC
private var topLevelInitializersCounter = 0
internal fun IrFile.addTopLevelInitializer(expression: IrExpression, context: KonanBackendContext, threadLocal: Boolean) {
val descriptor = WrappedFieldDescriptor(
if (threadLocal)
Annotations.create(listOf(AnnotationDescriptorImpl(context.ir.symbols.threadLocal.defaultType,
emptyMap(), SourceElement.NO_SOURCE)))
else
Annotations.EMPTY
)
val descriptor = WrappedFieldDescriptor()
val irField = IrFieldImpl(
expression.startOffset, expression.endOffset,
IrDeclarationOrigin.DEFINED,
@@ -85,7 +75,10 @@ internal fun IrFile.addTopLevelInitializer(expression: IrExpression, context: Ko
).apply {
descriptor.bind(this)
initializer = IrExpressionBodyImpl(expression.startOffset, expression.endOffset, expression)
if (threadLocal)
annotations += buildSimpleAnnotation(context.irBuiltIns, startOffset, endOffset, context.ir.symbols.threadLocal.owner)
initializer = IrExpressionBodyImpl(startOffset, endOffset, expression)
}
addChild(irField)
}