//============================================================
// Global Variable
//============================================================
///|
pub struct GlobalVariable {
uid : UInt64
vty : &Type
elementTy : &Type
users : Array[&User]
mod : Module
mut name : String
linkage : Ref[Linkage]
visibility : Ref[Visibility]
unnamed_addr : Ref[UnnamedAddr]
mut initializer : &Constant?
initializerTy : &Type
}
///|
fn GlobalVariable::new(
vty : &Type,
name : String,
initializer~ : &Constant?,
linkage~ : Linkage,
visibility? : Visibility = Visibility::Default,
unnamed_addr? : UnnamedAddr = UnnamedAddr::NoUnnamedAddr,
mod : Module,
) -> GlobalVariable {
let uid = valueUIDAssigner.assign()
let ctx = vty.getContext()
let elementTy = match vty.asTypeEnum() {
ArrayType(a) => a.getElementType()
_ => vty
}
let initializerTy = vty
let vty = ctx.getPtrTy()
let users = []
GlobalVariable::{
uid,
vty,
elementTy,
users,
mod,
name,
linkage: Ref::new(linkage),
visibility: Ref::new(visibility),
unnamed_addr: Ref::new(unnamed_addr),
initializer,
initializerTy,
}
}
///|
pub impl Value for GlobalVariable with getValueBase(self) {
ValueBase::{ uid: self.uid, vty: self.vty, users: self.users }
}
///|
pub impl Value for GlobalVariable with asValueEnum(self) {
GlobalVariable(self)
}
///|
pub impl Value for GlobalVariable with getValueRepr(self) {
"@\{self.name}"
}
///|
pub impl Value for GlobalVariable with getName(self) {
Some(self.name)
}
///|
pub impl Value for GlobalVariable with setName(self, name : String) {
if name is "" {
raise LLVMValueError(
"Misuse `GlobalVariable::setName`: name cannot be empty",
)
}
if isInValidName(name) {
let msg = "Misuse `GlobalVariable::setName`: " +
"name '\{name}' contains illegal characters, " +
"only alphanumeric characters and underscores are allowed."
raise LLVMValueError(msg)
}
self.name = name
}
///|
pub impl Value for GlobalVariable with removeName(_) {
let msg = "Calling always failed function `GlobalVariable::removeName`. " +
"remove function name is not allowed."
raise LLVMValueError(msg)
}
///|
pub impl Value for GlobalVariable with getNameOrSlot(self) {
Some(Left(self.name))
}
///|
pub impl GlobalValue for GlobalVariable with asGlobalValueEnum(self) {
GlobalVariable(self)
}
///|
pub impl GlobalValue for GlobalVariable with getGlobalValueBase(self) {
GlobalValueBase::{
linkage: self.linkage,
visibility: self.visibility,
unnamed_addr: self.unnamed_addr,
}
}
///|
pub impl Show for GlobalVariable with output(self, logger) {
let align = self.mod.getDataLayout().getAlignment(self.elementTy)
logger.write_string("@\{self.name} = ")
let linkage_str = self.linkage.val.to_string()
if !linkage_str.is_empty() {
logger.write_string("\{linkage_str} ")
}
let visibility_str = self.visibility.val.to_string()
if !visibility_str.is_empty() {
logger.write_string("\{visibility_str} ")
}
let unnamed_addr_str = self.unnamed_addr.val.to_string()
if !unnamed_addr_str.is_empty() {
logger.write_string("\{unnamed_addr_str} ")
}
logger.write_string("global ")
if self.initializer is Some(i) {
logger.write_string("\{i}")
} else {
logger.write_string("\{self.initializerTy} zeroinitializer")
}
logger.write_string(", \{align}\n")
}
///|
pub fn GlobalVariable::setInitializer(
self : GlobalVariable,
init : &Constant,
) -> Unit {
self.initializer = Some(init)
}
///|
pub fn GlobalVariable::removeInitializer(self : GlobalVariable) -> Unit {
self.initializer = None
}
//============================================================
// Global Variable
//============================================================
///|
pub struct GlobalConstant {
uid : UInt64
vty : &Type
// For Global Array, it's type is PointerType,
// and it has element type
elementTy : &Type
users : Array[&User]
mod : Module
mut name : String
linkage : Ref[Linkage]
visibility : Ref[Visibility]
unnamed_addr : Ref[UnnamedAddr]
mut value : &Constant
}
///|
fn GlobalConstant::new(
vty : &Type,
name : String,
value : &Constant,
mod : Module,
linkage~ : Linkage,
visibility~ : Visibility,
unnamed_addr~ : UnnamedAddr,
) -> GlobalConstant {
let uid = valueUIDAssigner.assign()
let ctx = vty.getContext()
let elementTy = match vty.asTypeEnum() {
ArrayType(a) => a.getElementType()
_ => vty
}
let vty = ctx.getPtrTy()
let users = []
GlobalConstant::{
uid,
vty,
elementTy,
users,
mod,
name,
linkage: Ref::new(linkage),
visibility: Ref::new(visibility),
unnamed_addr: Ref::new(unnamed_addr),
value,
}
}
///|
pub impl Value for GlobalConstant with getValueBase(self) {
ValueBase::{ uid: self.uid, vty: self.vty, users: self.users }
}
///|
pub impl Value for GlobalConstant with asValueEnum(self) {
GlobalConstant(self)
}
///|
pub impl Value for GlobalConstant with getValueRepr(self) {
"@\{self.name}"
}
///|
pub impl Value for GlobalConstant with getName(self) {
Some(self.name)
}
///|
pub impl Value for GlobalConstant with setName(self, name : String) {
if name is "" {
raise LLVMValueError(
"Misuse `GlobalConstant::setName`: name cannot be empty",
)
}
if isInValidName(name) {
let msg = "Misuse `GlobalConstant::setName`: " +
"name '\{name}' contains illegal characters, " +
"only alphanumeric characters and underscores are allowed."
raise LLVMValueError(msg)
}
self.name = name
}
///|
pub impl Value for GlobalConstant with removeName(_) {
let msg = "Calling always failed function `GlobalConstant::removeName`. " +
"remove function name is not allowed."
raise LLVMValueError(msg)
}
///|
pub impl Value for GlobalConstant with getNameOrSlot(self) {
Some(Left(self.name))
}
///|
pub impl GlobalValue for GlobalConstant with asGlobalValueEnum(self) {
GlobalConstant(self)
}
///|
pub impl GlobalValue for GlobalConstant with getGlobalValueBase(self) {
GlobalValueBase::{
linkage: self.linkage,
visibility: self.visibility,
unnamed_addr: self.unnamed_addr,
}
}
///|
pub impl Show for GlobalConstant with output(self, logger) {
let align = self.mod.getDataLayout().getAlignment(self.elementTy)
logger.write_string("@\{self.name} = ")
let linkage_str = self.linkage.val.to_string()
if !linkage_str.is_empty() {
logger.write_string("\{linkage_str} ")
}
let visibility_str = self.visibility.val.to_string()
if !visibility_str.is_empty() {
logger.write_string("\{visibility_str} ")
}
let unnamed_addr_str = self.unnamed_addr.val.to_string()
if !unnamed_addr_str.is_empty() {
logger.write_string("\{unnamed_addr_str} ")
}
logger.write_string("constant \{self.value}, \{align}\n")
}
///|
pub fn GlobalConstant::setValue(
self : GlobalConstant,
init : &Constant,
) -> Unit {
self.value = init
}