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);
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);
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);