コード例 #1
0
ファイル: MethodBuilder.cs プロジェクト: tytouf/cilc
 public MethodBuilder(LLVM.Builder builder, MethodData method)
 {
     _builder   = builder;
     _method    = method;
     _stack     = new Stack<LLVM.Value>();
     _params    = new List<LLVM.Value>();
     _variables = new List<LLVM.Value>();
     _labels    = new Dictionary<int, LLVM.BasicBlock>();
 }
コード例 #2
0
ファイル: MethodBuilder.cs プロジェクト: tytouf/cilc
 private LLVM.Value ConvertInteger(LLVM.Value v, LLVM.Type toType)
 {
     Trace.Assert(v.Type.isInteger() && toType.isInteger());
     return _builder.CreateIntCast(v, toType); // signed cast
 }
コード例 #3
0
ファイル: CodeGenMethod.cs プロジェクト: tytouf/cilc
 public MethodData(MethodReference method, LLVM.Module module)
 {
     _method = method;
     _module = module;
 }
コード例 #4
0
 public static bool VerifyModule(this Module self, LLVMVerifierFailureAction Action, out string OutMessage)
 {
     return(LLVM.VerifyModule(self.GetModuleRef(), Action, out OutMessage));
 }
コード例 #5
0
        public static string GetIdentifier(this Module self)
        {
            var id = LLVM.GetModuleIdentifier(self.GetModuleRef(), out var len);

            return(id);
        }
コード例 #6
0
        public static void AddFunctionParamAttribute(this LLVMValueRef self, LLVMContextRef context, int param, LLVMAttributeKind kind, uint value = 0)
        {
            var att = LLVM.CreateEnumAttribute(context, kind.ToUInt(), value);

            LLVM.AddAttributeAtIndex(self, (LLVMAttributeIndex)(param + 1), att);
        }
コード例 #7
0
 public static LLVMTypeRef GetPointerTo(this LLVMTypeRef self)
 {
     return(LLVM.PointerType(self, 0));
 }
コード例 #8
0
 public static uint AlignmentOfType(this LLVMTargetDataRef self, LLVMTypeRef type)
 {
     return(LLVM.ABIAlignmentOfType(self, type));
 }
コード例 #9
0
 protected override LLVMValueRef ValueAsTypeInternal(LLVMTypeRef type, LLVMBuilderRef builder, bool signExtend)
 {
     return(LLVM.ConstReal(type, Value));
 }
コード例 #10
0
 public LLVMValueRef ValueAsInt64(LLVMBuilderRef builder, bool signExtend)
 {
     return(ValueAsTypeInternal(LLVM.Int32Type(), builder, signExtend));
 }
コード例 #11
0
        public bool Compile(CompilerOptions pOptions, out LLVMModuleRef?pModule)
        {
            double totalTime = 0;
            var    sw        = new System.Diagnostics.Stopwatch();

            sw.Start();

            //Read source files
            pModule = null;
            string source = string.IsNullOrEmpty(pOptions.SourceFile) ? pOptions.Source : ReadSourceFile(pOptions.SourceFile);

            if (source == null)
            {
                return(false);
            }

            var lexer  = new SmallerLexer();
            var stream = lexer.StartTokenStream(source, pOptions.SourceFile);
            var parser = new SmallerParser(stream);

            //Create AST
            var tree = parser.Parse();

            if (CompilerErrors.ErrorOccurred)
            {
                return(false);
            }

            totalTime += RecordPerfData(sw, "Parsed in: ");

            //Type inference, type checking, AST transformations
            var compilationModule = ModuleBuilder.Build(tree);

            if (compilationModule == null)
            {
                return(false);
            }

            totalTime += RecordPerfData(sw, "Type checked in: ");

            LLVMModuleRef      module      = LLVM.ModuleCreateWithName(tree.Name);
            LLVMPassManagerRef passManager = LLVM.CreateFunctionPassManagerForModule(module);

            if (pOptions.Optimizations)
            {
                LLVM.AddConstantPropagationPass(passManager);

                //Promote allocas to registers
                LLVM.AddPromoteMemoryToRegisterPass(passManager);

                //Do simple peephole optimizations
                LLVM.AddInstructionCombiningPass(passManager);

                //Re-associate expressions
                LLVM.AddReassociatePass(passManager);

                //Eliminate common subexpressions
                LLVM.AddGVNPass(passManager);

                //Simplify control flow graph
                LLVM.AddCFGSimplificationPass(passManager);
            }
            LLVM.InitializeFunctionPassManager(passManager);

            //Emitting LLVM bytecode
            using (var c = new EmittingContext(module, passManager, pOptions.Debug))
            {
                compilationModule.Emit(c);

                if (LLVM.VerifyModule(module, LLVMVerifierFailureAction.LLVMPrintMessageAction, out string message).Value != 0)
                {
                    LLVM.DumpModule(module);
                    LLVM.DisposePassManager(passManager);
                    pModule = null;
                    return(false);
                }
            }

            pModule = module;
            LLVM.DisposePassManager(passManager);

            totalTime += RecordPerfData(sw, "Emitted bytecode in: ");

            Console.WriteLine("Total time: " + totalTime + "s");

            return(true);
        }
コード例 #12
0
        protected override Expression VisitBinary(BinaryExpression b)
        {
            sb.Append("(");
            this.Visit(b.Left);
            switch (b.NodeType)
            {
            case ExpressionType.Add:
                LLVMTypeRef[] sumParamTypes = new LLVMTypeRef[] { LLVM.Int32Type(), LLVM.Int32Type() };
                LLVMTypeRef   sumRetType    = LLVM.FunctionType(LLVM.Int32Type(), sumParamTypes, false);
                LLVMValueRef  sumFunc       = LLVM.AddFunction(module, "sum" + functionNumber, sumRetType);

                LLVMBasicBlockRef entry = LLVM.AppendBasicBlock(sumFunc, "entry");

                LLVMBuilderRef sumBuilder = LLVM.CreateBuilder();
                LLVM.PositionBuilderAtEnd(sumBuilder, entry);
                LLVMValueRef tmp = LLVM.BuildAdd(sumBuilder, LLVM.GetParam(sumFunc, 0), LLVM.GetParam(sumFunc, 1), "Sum" + functionNumber + "Entry");
                LLVM.BuildRet(sumBuilder, tmp);
                lastLLVMFunctionCalledFromMain = LLVM.BuildCall(mainBuilder, sumFunc, new LLVMValueRef[] { LLVM.ConstInt(LLVM.Int32Type(), 3, new LLVMBool(0)), LLVM.ConstInt(LLVM.Int32Type(), 2, new LLVMBool(0)) }, "functioncall");

                functionNumber++;
                break;

            default:
                throw new NotSupportedException(string.Format("The binary operator '{0}' is not supported", b.NodeType));
            }

            this.Visit(b.Right);
            sb.Append(")");
            return(b);
        }
コード例 #13
0
        protected override ExprAST VisitBinaryExprAST(BinaryExprAST node)
        {
            this.Visit(node.Lhs);
            this.Visit(node.Rhs);

            LLVMValueRef r = this.valueStack.Pop();
            LLVMValueRef l = this.valueStack.Pop();

            LLVMValueRef n;

            switch (node.NodeType)
            {
            case ExprType.AddExpr:
                n = LLVM.BuildFAdd(this.builder, l, r, "addtmp");
                break;

            case ExprType.SubtractExpr:
                n = LLVM.BuildFSub(this.builder, l, r, "subtmp");
                break;

            case ExprType.MultiplyExpr:
                n = LLVM.BuildFMul(this.builder, l, r, "multmp");
                break;

            case ExprType.LessThanExpr:
                // Convert bool 0/1 to double 0.0 or 1.0
                n = LLVM.BuildUIToFP(this.builder, LLVM.BuildFCmp(this.builder, LLVMRealPredicate.LLVMRealULT, l, r, "cmptmp"), LLVM.DoubleType(), "booltmp");
                break;

            default:
                throw new Exception("invalid binary operator");
            }

            this.valueStack.Push(n);
            return(node);
        }
コード例 #14
0
 protected override ExprAST VisitNumberExprAST(NumberExprAST node)
 {
     this.valueStack.Push(LLVM.ConstReal(LLVM.DoubleType(), node.Value));
     return(node);
 }
コード例 #15
0
        protected override ExprAST VisitForExprAST(ForExprAST node)
        {
            // Output this as:
            //   ...
            //   start = startexpr
            //   goto loop
            // loop:
            //   variable = phi [start, loopheader], [nextvariable, loopend]
            //   ...
            //   bodyexpr
            //   ...
            // loopend:
            //   step = stepexpr
            //   nextvariable = variable + step
            //   endcond = endexpr
            //   br endcond, loop, endloop
            // outloop:

            // Emit the start code first, without 'variable' in scope.
            this.Visit(node.Start);
            var startVal = this.valueStack.Pop();

            // Make the new basic block for the loop header, inserting after current
            // block.
            var preheaderBB = LLVM.GetInsertBlock(this.builder);
            var function    = LLVM.GetBasicBlockParent(preheaderBB);
            var loopBB      = LLVM.AppendBasicBlock(function, "loop");

            // Insert an explicit fall through from the current block to the LoopBB.
            LLVM.BuildBr(this.builder, loopBB);

            // Start insertion in LoopBB.
            LLVM.PositionBuilderAtEnd(this.builder, loopBB);

            // Start the PHI node with an entry for Start.
            var variable = LLVM.BuildPhi(this.builder, LLVM.DoubleType(), node.VarName);

            LLVM.AddIncoming(variable, out startVal, out preheaderBB, 1);

            // Within the loop, the variable is defined equal to the PHI node.  If it
            // shadows an existing variable, we have to restore it, so save it now.
            LLVMValueRef oldVal;

            if (this.namedValues.TryGetValue(node.VarName, out oldVal))
            {
                this.namedValues[node.VarName] = variable;
            }
            else
            {
                this.namedValues.Add(node.VarName, variable);
            }

            // Emit the body of the loop.  This, like any other expr, can change the
            // current BB.  Note that we ignore the value computed by the body, but don't
            // allow an error.
            this.Visit(node.Body);

            // Emit the step value.
            LLVMValueRef stepVal;

            if (node.Step != null)
            {
                this.Visit(node.Step);
                stepVal = this.valueStack.Pop();
            }
            else
            {
                // If not specified, use 1.0.
                stepVal = LLVM.ConstReal(LLVM.DoubleType(), 1.0);
            }

            LLVMValueRef nextVar = LLVM.BuildFAdd(this.builder, variable, stepVal, "nextvar");

            // Compute the end condition.
            this.Visit(node.End);
            LLVMValueRef endCond = LLVM.BuildFCmp(this.builder, LLVMRealPredicate.LLVMRealONE, this.valueStack.Pop(), LLVM.ConstReal(LLVM.DoubleType(), 0.0), "loopcond");

            // Create the "after loop" block and insert it.
            var loopEndBB = LLVM.GetInsertBlock(this.builder);
            var afterBB   = LLVM.AppendBasicBlock(function, "afterloop");

            // Insert the conditional branch into the end of LoopEndBB.
            LLVM.BuildCondBr(this.builder, endCond, loopBB, afterBB);

            // Any new code will be inserted in AfterBB.
            LLVM.PositionBuilderAtEnd(this.builder, afterBB);

            // Add a new entry to the PHI node for the backedge.
            LLVM.AddIncoming(variable, out nextVar, out loopEndBB, 1);

            // Restore the unshadowed variable.
            if (oldVal.Pointer != IntPtr.Zero)
            {
                this.namedValues[node.VarName] = oldVal;
            }
            else
            {
                this.namedValues.Remove(node.VarName);
            }

            this.valueStack.Push(LLVM.ConstReal(LLVM.DoubleType(), 0.0));

            return(node);
        }
コード例 #16
0
ファイル: MethodBuilder.cs プロジェクト: tytouf/cilc
 private LLVM.Value ConvertToType(LLVM.Value v, LLVM.Type toType)
 {
     LLVM.Type vType = v.Type;
     if (vType.isPointer() && toType.isPointer()) {
     return ConvertPointer(v, toType);
     }
     Console.WriteLine("v was not converted to toType");
     return v; // TODO, FIXME
 }
コード例 #17
0
        protected override ExprAST VisitIfExprAST(IfExpAST node)
        {
            this.Visit(node.Condition);
            var condv = LLVM.BuildFCmp(this.builder, LLVMRealPredicate.LLVMRealONE, this.valueStack.Pop(), LLVM.ConstReal(LLVM.DoubleType(), 0.0), "ifcond");

            LLVMValueRef func = LLVM.GetBasicBlockParent(LLVM.GetInsertBlock(builder));

            // Create blocks for the then and else cases.  Insert the 'then' block at the
            // end of the function.
            LLVMBasicBlockRef thenBB  = LLVM.AppendBasicBlock(func, "then");
            LLVMBasicBlockRef elseBB  = LLVM.AppendBasicBlock(func, "else");
            LLVMBasicBlockRef mergeBB = LLVM.AppendBasicBlock(func, "ifcont");

            LLVM.BuildCondBr(this.builder, condv, thenBB, elseBB);

            // Emit then value.
            LLVM.PositionBuilderAtEnd(this.builder, thenBB);

            this.Visit(node.Then);
            var thenV = this.valueStack.Pop();

            LLVM.BuildBr(this.builder, mergeBB);

            // Codegen of 'Then' can change the current block, update ThenBB for the PHI.
            thenBB = LLVM.GetInsertBlock(this.builder);

            // Emit else block.

            LLVM.PositionBuilderAtEnd(this.builder, elseBB);

            this.Visit(node.Else);
            var elseV = this.valueStack.Pop();

            LLVM.BuildBr(this.builder, mergeBB);

            // Codegen of 'Else' can change the current block, update ElseBB for the PHI.
            elseBB = LLVM.GetInsertBlock(this.builder);

            // Emit merge block.
            LLVM.PositionBuilderAtEnd(this.builder, mergeBB);
            var phi = LLVM.BuildPhi(this.builder, LLVM.DoubleType(), "iftmp");

            LLVM.AddIncoming(phi, out thenV, out thenBB, 1);
            LLVM.AddIncoming(phi, out elseV, out elseBB, 1);

            this.valueStack.Push(phi);

            return(node);
        }
コード例 #18
0
ファイル: LlvmExecutionEngine.cs プロジェクト: ionlang/engine
 public void Dispose()
 {
     LLVM.DisposeExecutionEngine(this.reference);
 }
コード例 #19
0
 public static void Dispose(this LLVMTargetMachineRef self)
 {
     LLVM.DisposeTargetMachine(self);
 }
コード例 #20
0
 public Number()
 {
     this.State = NumberState.Ok;
     this.Kind  = Semantics.DefaultKind;
     this.Value = LLVM.ConstInt(GetLLVMType(), 0, new LLVMBool(0));
 }
コード例 #21
0
        public static void AddFunctionReturnAttribute(this LLVMValueRef self, LLVMContextRef context, LLVMAttributeKind kind, uint value = 0)
        {
            var att = LLVM.CreateEnumAttribute(context, kind.ToUInt(), value);

            LLVM.AddAttributeAtIndex(self, LLVMAttributeIndex.LLVMAttributeReturnIndex, att);
        }
コード例 #22
0
        public Number Convert(NumberKind kind)
        {
            if (kind == this.Kind)
            {
                return(this);
            }
            if (this.HasErrors)
            {
                return(new Number(this.State, this.Kind));
            }

            if (this.Kind.IsInteger())
            {
                if (this.Kind.IsSigned())
                {
                    var n = new Number(this.Int64Value, kind);
                    n.State |= this.State;
                    return(n);
                }
                else
                {
                    var n = new Number(this.UInt64Value, kind);
                    n.State |= this.State;
                    return(n);
                }
            }
            else
            {
                if (kind.IsFloat())
                {
                    int status;
                    var apFloat = LLVMExt.APFloatFromAPFloat(this.APFloat, GetAPFloatSemantics(kind), out status);
                    return(new Number(dummy: string.Empty)
                    {
                        APFloat = apFloat,
                        State = this.State | (NumberState)status,
                        Kind = kind
                    });
                }
                else
                {
                    if (this.Kind == NumberKind.Double)
                    {
                        var n = new Number(this.DoubleValue, kind);
                        n.State |= this.State;
                        return(n);
                    }
                    else if (this.Kind == NumberKind.Float)
                    {
                        var n = new Number(this.FloatValue, kind);
                        n.State |= this.State;
                        return(n);
                    }
                    else
                    {
                        if (kind.IsSigned())
                        {
                            var overflows = CheckForLongOverflow();
                            if (overflows == 1)
                            {
                                return(new Number(NumberState.Overflow, kind));
                            }
                            else if (overflows == -1)
                            {
                                return(new Number(NumberState.Underflow, kind));
                            }
                            else
                            {
                                var longValue  = LLVM.ConstFPToSI(LLVMExt.APFloatToValue(APFloat), LLVM.Int64Type());
                                var longValue2 = LLVM.ConstIntGetSExtValue(longValue);

                                return(new Number(longValue2, kind));
                            }
                        }
                        else
                        {
                            var overflows = CheckForULongOverflow();
                            if (overflows == 1)
                            {
                                return(new Number(NumberState.Overflow, kind));
                            }
                            else if (overflows == -1)
                            {
                                return(new Number(NumberState.Underflow, kind));
                            }
                            else
                            {
                                var ulongValue  = LLVM.ConstFPToUI(LLVMExt.APFloatToValue(APFloat), LLVM.Int64Type());
                                var ulongValue2 = LLVM.ConstIntGetZExtValue(ulongValue);

                                return(new Number(ulongValue2, kind));
                            }
                        }
                    }
                }
            }
        }
コード例 #23
0
        public static void AddCallAttribute(this LLVMValueRef self, LLVMContextRef context, int arg, LLVMAttributeKind kind, uint value = 0)
        {
            var att = LLVM.CreateEnumAttribute(context, kind.ToUInt(), value);

            LLVM.AddCallSiteAttribute(self, (LLVMAttributeIndex)(arg + 1), att);
        }
コード例 #24
0
 void LoadZeroExternalValue()
 {
     this.ExternalValue = LLVM.ConstInt(GetLLVMType(internalType: false), 0, new LLVMBool(0));
 }
コード例 #25
0
        public static LLVMTargetDataRef GetTargetData(this Module self)
        {
            var data = LLVM.GetModuleDataLayout(self.GetModuleRef());

            return(data);
        }
コード例 #26
0
        LLVMTypeRef GetLLVMType(bool internalType = true)
        {
            switch (this.Kind)
            {
            case NumberKind.Int8:
                return(internalType ? LLVM.Int128Type() : LLVM.Int8Type());

            case NumberKind.Int16:
                return(internalType ? LLVM.Int128Type() : LLVM.Int16Type());

            case NumberKind.Int32:
                return(internalType ? LLVM.Int128Type() : LLVM.Int32Type());

            case NumberKind.Int64:
                return(internalType ? LLVM.Int128Type() : LLVM.Int64Type());

            case NumberKind.UInt8:
                return(internalType ? LLVM.Int128Type() : LLVM.Int8Type());

            case NumberKind.UInt16:
                return(internalType ? LLVM.Int128Type() : LLVM.Int16Type());

            case NumberKind.UInt32:
                return(internalType ? LLVM.Int128Type() : LLVM.Int32Type());

            case NumberKind.UInt64:
                return(internalType ? LLVM.Int128Type() : LLVM.Int64Type());

            case NumberKind.Float:
                return(LLVM.FloatType());

            case NumberKind.Double:
                return(LLVM.DoubleType());

            case NumberKind.Real:
            case NumberKind.Quad:
                switch (this.Kind == NumberKind.Real ? Semantics.LongDoubleSemantics : Semantics.QuadSemantics)
                {
                case FloatSemantics.IEEEHalf:
                    return(LLVM.HalfType());

                case FloatSemantics.IEEESingle:
                    return(LLVM.FloatType());

                case FloatSemantics.IEEEDouble:
                    return(LLVM.DoubleType());

                case FloatSemantics.IEEEQuad:
                    return(LLVM.FP128Type());

                case FloatSemantics.PPCDoubleDouble:
                    return(LLVM.PPCFP128Type());

                case FloatSemantics.X87DoubleExtended:
                    return(LLVM.X86FP80Type());

                default:
                    throw new NotSupportedException();
                }

            default:
                throw new NotSupportedException();
            }
        }
コード例 #27
0
        public static IEnumerable <(string, LLVMValueRef)> BuildFunctions(LLVMModuleRef module)
        {
            yield return(BuildFunctionEntry(module, FunctionNames.Malloc64F, new[] { LLVM.Int32Type() }, LLVM.Int64Type()));

            yield return(BuildFunctionEntry(module, FunctionNames.Free, new[] { LLVM.Int64Type() }, LLVM.VoidType()));

            yield return(BuildFunctionEntry(module, FunctionNames.Set64F, new[] { LLVM.DoubleType(), LLVM.Int64Type(), LLVM.Int32Type() }));

            yield return(BuildFunctionEntry(module, FunctionNames.Zero64F, new[] { LLVM.Int64Type(), LLVM.Int32Type() }));

            yield return(BuildFunctionEntry(module, FunctionNames.Exp64FI, new[] { LLVM.Int64Type(), LLVM.Int32Type() }));

            yield return(BuildFunctionEntry(module, FunctionNames.Copy64F, new[] { LLVM.Int64Type(), LLVM.Int64Type(), LLVM.Int32Type() }));

            yield return(BuildFunctionEntry(module, FunctionNames.Add64FI, new[] { LLVM.Int64Type(), LLVM.Int64Type(), LLVM.Int32Type() }));

            yield return(BuildFunctionEntry(module, FunctionNames.Mul64FI, new[] { LLVM.Int64Type(), LLVM.Int64Type(), LLVM.Int32Type() }));

            yield break;
        }
コード例 #28
0
ファイル: TerminatorInst.cs プロジェクト: bamfbamf/LLVMSharp
 public BasicBlock GetSuccessor(uint idx) => LLVM.GetSuccessor(this.Unwrap(), idx).Wrap();
コード例 #29
0
ファイル: Cil2Llvm.cs プロジェクト: tytouf/cilc
 public static void Init(LLVM.Module module, LLVM.Builder builder)
 {
     if (_module == null) {
     _module  = module;
     _builder = builder;
     _types   = new Dictionary<TypeReference, CodeGenType>();
     _methods = new Dictionary<MethodReference, MethodData>();
     }
 }
コード例 #30
0
ファイル: TerminatorInst.cs プロジェクト: bamfbamf/LLVMSharp
 public void SetSuccessor(uint idx, BasicBlock b) => LLVM.SetSuccessor(this.Unwrap(), idx, b.Unwrap <LLVMBasicBlockRef>());
コード例 #31
0
ファイル: MethodBuilder.cs プロジェクト: tytouf/cilc
 private LLVM.Value ConvertPointer(LLVM.Value v, LLVM.Type toType)
 {
     Trace.Assert(v.Type.isPointer() && toType.isPointer());
     return _builder.CreateBitCast(v, toType);
 }
コード例 #32
0
 public static LLVMValueRef BuildAtomicCmpXchg(this LLVMBuilderRef builder, LLVMValueRef ptr, LLVMValueRef cmp,
                                               LLVMValueRef @new, LLVMAtomicOrdering successOrdering, LLVMAtomicOrdering failureOrdering,
                                               bool singleThread) =>
 LLVM.BuildAtomicCmpXchg(builder, ptr, cmp, @new, successOrdering, failureOrdering, singleThread ? 1 : 0);
コード例 #33
0
 public static ulong SizeOfTypeInBits(this LLVMTargetDataRef self, LLVMTypeRef type)
 {
     return(LLVM.SizeOfTypeInBits(self, type));
 }
コード例 #34
0
        protected override ExprAST VisitPrototypeAST(PrototypeAST node)
        {
            // Make the function type:  double(double,double) etc.
            var argumentCount = (uint)node.Arguments.Count;
            var arguments     = new LLVMTypeRef[Math.Max(argumentCount, 1)];

            var function = LLVM.GetNamedFunction(this.module, node.Name);

            // If F conflicted, there was already something named 'Name'.  If it has a
            // body, don't allow redefinition or reextern.
            if (function.Pointer != IntPtr.Zero)
            {
                // If F already has a body, reject this.
                if (LLVM.CountBasicBlocks(function) != 0)
                {
                    throw new Exception("redefinition of function.");
                }

                // If F took a different number of args, reject.
                if (LLVM.CountParams(function) != argumentCount)
                {
                    throw new Exception("redefinition of function with different # args");
                }
            }
            else
            {
                for (int i = 0; i < argumentCount; ++i)
                {
                    arguments[i] = LLVM.DoubleType();
                }

                function = LLVM.AddFunction(this.module, node.Name, LLVM.FunctionType(LLVM.DoubleType(), out arguments[0], argumentCount, LLVMBoolFalse));
                LLVM.SetLinkage(function, LLVMLinkage.LLVMExternalLinkage);
            }

            for (int i = 0; i < argumentCount; ++i)
            {
                string argumentName = node.Arguments[i];

                LLVMValueRef param = LLVM.GetParam(function, (uint)i);
                LLVM.SetValueName(param, argumentName);

                this.namedValues[argumentName] = param;
            }

            this.valueStack.Push(function);
            return(node);
        }