Esempio n. 1
0
        public override LLVMValueRef Emit(EmittingContext pContext)
        {
            //Iterator should have been rewritten to normal for loop
            System.Diagnostics.Debug.Assert(Iterator == null);

            pContext.EmitDebugLocation(this);

            pContext.Locals.AddScope();
            pContext.AddDebugScope(Span);

            foreach (var d in Initializer)
            {
                d.Emit(pContext);
            }

            //for condition
            var          cond = Condition.Emit(pContext);
            LLVMValueRef cmp  = SmallTypeCache.GetLLVMDefault(Condition.Type, pContext);

            LLVMValueRef condv;

            if (Utils.TypeHelper.IsFloat(Condition.Type))
            {
                condv = LLVM.BuildFCmp(pContext.Builder, LLVMRealPredicate.LLVMRealONE, cond, cmp, "for_cond");
            }
            else
            {
                condv = LLVM.BuildICmp(pContext.Builder, LLVMIntPredicate.LLVMIntNE, cond, cmp, "for_cond");
            }

            var loop = LLVM.AppendBasicBlock(pContext.CurrentMethod, "for_body");
            var end  = LLVM.AppendBasicBlock(pContext.CurrentMethod, "for_end");

            pContext.BreakLocations.Push(end);

            //Jump to end or loop
            LLVM.BuildCondBr(pContext.Builder, condv, loop, end);

            //Loop
            LLVM.PositionBuilderAtEnd(pContext.Builder, loop);
            Body.Emit(pContext);
            foreach (var f in Finalizer)
            {
                f.Emit(pContext);
            }

            pContext.BreakLocations.Pop();

            //Jump back to start
            cond  = Condition.Emit(pContext);
            condv = LLVM.BuildICmp(pContext.Builder, LLVMIntPredicate.LLVMIntNE, cond, cmp, "for_cond");
            LLVM.BuildCondBr(pContext.Builder, condv, loop, end);

            //End
            LLVM.PositionBuilderAtEnd(pContext.Builder, end);

            pContext.RemoveDebugScope();
            pContext.Locals.RemoveScope();

            return(default);
Esempio n. 2
0
        public override LLVMValueRef Emit(EmittingContext pContext)
        {
            pContext.EmitDebugLocation(this);

            if (!External)
            {
                System.Diagnostics.Debug.Assert(!string.IsNullOrEmpty(_name), "Method name cannot be blank");
                var func = pContext.StartMethod(_name, this);
                pContext.AddDeferredStatementExecution();
                pContext.Locals.AddScope();
                pContext.AddDebugScope(Span);

                //Method bodies are slightly special because we want all variables to be declared in their scope
                //Don't call Body.Emit because that starts a new scope and all our variables will be not declared for deferred statements
                foreach (var s in Body.Statements)
                {
                    if (!s.Deferred)
                    {
                        s.Emit(pContext);
                    }
                    else
                    {
                        pContext.AddDeferredStatement(s);
                    }
                }

                //Emit all deferred statements unless the return handled it for us
                var lastIsReturn = Utils.SyntaxHelper.LastStatementIsReturn(Body);
                if (!lastIsReturn)
                {
                    foreach (var s in pContext.GetDeferredStatements())
                    {
                        s.Emit(pContext);
                    }

                    //We want to dispose variables after deferred statements because
                    //then variables referenced in deferred statements will still be valid
                    BlockSyntax.BuildCallToDispose(pContext);

                    if (ReturnValues.Count == 0)
                    {
                        LLVM.BuildRetVoid(pContext.Builder);
                    }
                    else
                    {
                        //Return statements have been validated. It probably returned in some other block earlier.
                        //LLVM requires return statement so just return default
                        LLVM.BuildRet(pContext.Builder, SmallTypeCache.GetLLVMDefault(Type, pContext));
                    }
                }

                //End method
                pContext.RemoveDeferredStatementExecution();
                pContext.RemoveDebugScope();
                pContext.Locals.RemoveScope();
                pContext.FinishMethod(func);
                return(func);
            }

            return(default);
Esempio n. 3
0
        public override LLVMSharp.LLVMValueRef Emit(EmittingContext pContext)
        {
            pContext.Locals.AddScope();
            pContext.AddDebugScope(Span);

            foreach (var s in Statements)
            {
                if (!s.Deferred)
                {
                    s.Emit(pContext);
                }
                else
                {
                    pContext.AddDeferredStatement(s);
                }
            }

            BuildCallToDispose(pContext);

            pContext.RemoveDebugScope();
            pContext.Locals.RemoveScope();
            return(default);