// globalVarDecl lowers the given global variable declaration to LLVM IR, // emitting code to m. func (m *Module) globalVarDecl(n *ast.VarDecl) { // Input: // int x; // Output: // @x = global i32 0 ident := n.Name() dbg.Printf("create global variable: %v", n) typ := toIrType(n.Type()) var val value.Value switch { case n.Val != nil: panic("support for global variable initializer not yet implemented") case irtypes.IsInt(typ): var err error val, err = constant.NewInt(typ, "0") if err != nil { panic(fmt.Sprintf("unable to create integer constant; %v", err)) } default: val = constant.NewZeroInitializer(typ) } global, err := ir.NewGlobalDef(ident.Name, val, false) if err != nil { panic(fmt.Sprintf("unable to create global variable definition %q", ident)) } m.setIdentValue(ident, global) // Emit global variable definition. m.emitGlobal(global) }
// NewGlobalVar returns a new global variable declaration based on the given // name and global variable. func NewGlobalVarDecl(gname, globalVar interface{}) (*ir.GlobalDecl, error) { if globalVar, ok := globalVar.(*GlobalVar); ok { name, err := getGlobalName(gname) if err != nil { return nil, errutil.Err(err) } // Global variable declaration. if globalVar.val == nil { return ir.NewGlobalDecl(name, globalVar.typ, globalVar.immutable) } // Global variable definition. return ir.NewGlobalDef(name, globalVar.val, globalVar.immutable) } return nil, errutil.Newf("invalid global variable type; expected *GlobalVar, got %T", globalVar) }