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