backend/StaticData: weaken existing global assertion
to handle the case when global is used before defined (e.g. kotlin.Unit in stdlib).
This commit is contained in:
committed by
SvyatoslavScherbina
parent
361bb7a101
commit
462d2b5123
+17
-4
@@ -14,22 +14,35 @@ internal class StaticData(override val context: Context): ContextUtils {
|
|||||||
*/
|
*/
|
||||||
class Global private constructor(val staticData: StaticData, val llvmGlobal: LLVMValueRef) {
|
class Global private constructor(val staticData: StaticData, val llvmGlobal: LLVMValueRef) {
|
||||||
companion object {
|
companion object {
|
||||||
fun create(staticData: StaticData, type: LLVMTypeRef, name: String): Global {
|
|
||||||
val module = staticData.context.llvmModule
|
|
||||||
|
|
||||||
|
private fun createLlvmGlobal(module: LLVMModuleRef, type: LLVMTypeRef, name: String): LLVMValueRef {
|
||||||
val isUnnamed = (name == "") // LLVM will select the unique index and represent the global as `@idx`.
|
val isUnnamed = (name == "") // LLVM will select the unique index and represent the global as `@idx`.
|
||||||
|
|
||||||
if (!isUnnamed && LLVMGetNamedGlobal(module, name) != null) {
|
if (!isUnnamed) {
|
||||||
throw IllegalArgumentException("Global '$name' already exists")
|
LLVMGetNamedGlobal(module, name)?.let { existingGlobal ->
|
||||||
|
if (getGlobalType(existingGlobal) != type || LLVMGetInitializer(existingGlobal) != null) {
|
||||||
|
throw IllegalArgumentException("Global '$name' already exists")
|
||||||
|
} else {
|
||||||
|
return existingGlobal
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val llvmGlobal = LLVMAddGlobal(module, type, name)!!
|
val llvmGlobal = LLVMAddGlobal(module, type, name)!!
|
||||||
|
|
||||||
if (isUnnamed) {
|
if (isUnnamed) {
|
||||||
// Currently using unnamed globals may result in link errors due to symbol redefinition;
|
// Currently using unnamed globals may result in link errors due to symbol redefinition;
|
||||||
// apply the workaround:
|
// apply the workaround:
|
||||||
LLVMSetLinkage(llvmGlobal, LLVMLinkage.LLVMPrivateLinkage)
|
LLVMSetLinkage(llvmGlobal, LLVMLinkage.LLVMPrivateLinkage)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return llvmGlobal
|
||||||
|
}
|
||||||
|
|
||||||
|
fun create(staticData: StaticData, type: LLVMTypeRef, name: String): Global {
|
||||||
|
val module = staticData.context.llvmModule
|
||||||
|
|
||||||
|
val llvmGlobal = createLlvmGlobal(module!!, type, name)
|
||||||
return Global(staticData, llvmGlobal)
|
return Global(staticData, llvmGlobal)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user