public override Value?Visit(FunctionDefinition definition) { definition.ValidateNotNull(nameof(definition)); var function = GetOrDeclareFunction(definition.Signature); if (!function.IsDeclaration) { throw new CodeGeneratorException($"Function {function.Name} cannot be redefined in the same module"); } try { var entryBlock = function.AppendBasicBlock("entry"); InstructionBuilder.PositionAtEnd(entryBlock); using (NamedValues.EnterScope( )) { foreach (var param in definition.Signature.Parameters) { var argSlot = InstructionBuilder.Alloca(function.Context.DoubleType) .RegisterName(param.Name); InstructionBuilder.Store(function.Parameters[param.Index], argSlot); NamedValues[param.Name] = argSlot; } foreach (LocalVariableDeclaration local in definition.LocalVariables) { var localSlot = InstructionBuilder.Alloca(function.Context.DoubleType) .RegisterName(local.Name); NamedValues[local.Name] = localSlot; } EmitBranchToNewBlock("body"); var funcReturn = definition.Body.Accept(this) ?? throw new CodeGeneratorException(ExpectValidFunc); InstructionBuilder.Return(funcReturn); function.Verify( ); FunctionPassManager.Run(function); if (definition.IsAnonymous) { function.AddAttribute(FunctionAttributeIndex.Function, AttributeKind.AlwaysInline) .Linkage(Linkage.Private); AnonymousFunctions.Add(function); } return(function); } } catch (CodeGeneratorException) { function.EraseFromParent( ); throw; } }
public override Value?Visit(FunctionDefinition definition) { definition.ValidateNotNull(nameof(definition)); var function = GetOrDeclareFunction(definition.Signature); if (!function.IsDeclaration) { throw new CodeGeneratorException($"Function {function.Name} cannot be redefined in the same module"); } Debug.Assert(function.DISubProgram != null, "Expected function with non-null DISubProgram"); LexicalBlocks.Push(function.DISubProgram); try { var entryBlock = function.AppendBasicBlock("entry"); InstructionBuilder.PositionAtEnd(entryBlock); // Unset the location for the prologue emission (leading instructions with no // location in a function are considered part of the prologue and the debugger // will run past them when breaking on a function) EmitLocation(null); using (NamedValues.EnterScope( )) { foreach (var param in definition.Signature.Parameters) { var argSlot = InstructionBuilder.Alloca(function.Context.DoubleType) .RegisterName(param.Name); AddDebugInfoForAlloca(argSlot, function, param); InstructionBuilder.Store(function.Parameters[param.Index], argSlot); NamedValues[param.Name] = argSlot; } foreach (LocalVariableDeclaration local in definition.LocalVariables) { var localSlot = InstructionBuilder.Alloca(function.Context.DoubleType) .RegisterName(local.Name); AddDebugInfoForAlloca(localSlot, function, local); NamedValues[local.Name] = localSlot; } EmitBranchToNewBlock("body"); var funcReturn = definition.Body.Accept(this) ?? throw new CodeGeneratorException(ExpectValidFunc); InstructionBuilder.Return(funcReturn); Module.DIBuilder.Finish(function.DISubProgram); function.Verify( ); FunctionPassManager.Run(function); if (definition.IsAnonymous) { function.AddAttribute(FunctionAttributeIndex.Function, AttributeKind.AlwaysInline) .Linkage(Linkage.Private); AnonymousFunctions.Add(function); } return(function); } } catch (CodeGeneratorException) { function.EraseFromParent( ); throw; } }