private void ResolveVariableDecl(AstVariableDecl v) { Debug.Assert(v.Name != null); if (v.Directives != null) { foreach (var d in v.Directives) { foreach (var arg in d.Arguments) { arg.Scope = v.Scope; InferType(arg, null); } } } if (v.HasDirective("local")) { v.SetFlag(StmtFlags.IsLocal, true); } if (v.TypeExpr != null) { v.TypeExpr.AttachTo(v); v.TypeExpr.SetFlag(ExprFlags.ValueRequired, true); v.TypeExpr = ResolveTypeNow(v.TypeExpr, out var t); v.Type = t; } // initializer stuff if (v.Initializer == null) { if (v.GetFlag(StmtFlags.GlobalScope) && !v.HasDirective("extern")) { ReportError(v, $"Global variables must have an initializer"); } } else { v.Initializer.AttachTo(v); v.Initializer.SetFlag(ExprFlags.ValueRequired, true); v.Initializer = InferType(v.Initializer, v.Type); ConvertLiteralTypeToDefaultType(v.Initializer, v.Type); if (v.TypeExpr != null) { //v.Initializer = HandleReference(v.Initializer, v.Type, null); v.Initializer = CheckType(v.Initializer, v.Type); } } if (v.TypeExpr == null) { v.Type = v.Initializer.Type; } switch (v.Type) { case IntType _: case FloatType _: case BoolType _: case CharType _: case SliceType _: case StringType _: case ArrayType _: case StructType _: case EnumType _: case PointerType _: case ReferenceType _: case FunctionType _: case TupleType _: case RangeType _: break; case CheezType t when t.IsErrorType: break; default: ReportError(v, $"Variable can't have type {v.Type}"); break; } //if (vardecl.Type is SumType) //{ // ReportError(vardecl.Pattern, $"Invalid type for variable declaration: {vardecl.Type}"); //} }
private void InitGlobalVariable(AstVariableDecl decl, HashSet <AstVariableDecl> visited) { if (visited.Contains(decl)) { return; } if (decl.Dependencies != null) { foreach (var dep in decl.Dependencies) { if (dep is AstVariableDecl v) { InitGlobalVariable(v, visited); } } } visited.Add(decl); // Don't emit global variables that aren't even used if (dontEmitUnusedDeclarations && !decl.IsUsed) { return; } // create vars var type = CheezTypeToLLVMType(decl.Type); var name = decl.Name.Name; if (decl.TryGetDirective("linkname", out var linkname)) { name = linkname.Arguments[0].Value as string; } var varPtr = module.AddGlobal(type, name); varPtr.SetLinkage(LLVMLinkage.LLVMInternalLinkage); if (decl.HasDirective("thread_local")) { varPtr.SetThreadLocal(true); } //varPtr.SetLinkage(LLVMLinkage.LLVMExternalLinkage);// TODO? if (decl.HasDirective("extern")) { varPtr.SetLinkage(LLVMLinkage.LLVMExternalLinkage); } else { LLVMValueRef initializer = LLVM.ConstNull(CheezTypeToLLVMType(decl.Type)); varPtr.SetInitializer(initializer); } valueMap[decl] = varPtr; // do initialization TODO: other patterns if (decl.Initializer != null) { var x = GenerateExpression(decl.Initializer, true); builder.CreateStore(x, varPtr); } }