Beispiel #1
0
        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);
            }
        }