コード例 #1
0
        private void EmitLocation(IAstNode?node)
        {
            DILocalScope?scope = null;

            if (LexicalBlocks.Count > 0)
            {
                scope = LexicalBlocks.Peek( );
            }
            else if (InstructionBuilder.InsertFunction != null && InstructionBuilder.InsertFunction.DISubProgram != null)
            {
                scope = InstructionBuilder.InsertFunction.DISubProgram;
            }

            DILocation?loc = null;

            if (scope != null)
            {
                loc = new DILocation(InstructionBuilder.Context
                                     , ( uint )(node?.Location.StartLine ?? 0)
                                     , ( uint )(node?.Location.StartColumn ?? 0)
                                     , scope
                                     );
            }

            InstructionBuilder.SetDebugLocation(loc);
        }
コード例 #2
0
        private void EmitLocation(IAstNode node)
        {
            DIScope scope = Module.DICompileUnit;

            if (LexicalBlocks.Count > 0)
            {
                scope = LexicalBlocks.Peek( );
            }

            InstructionBuilder.SetDebugLocation(( uint )node.Location.StartLine, ( uint )node.Location.StartColumn, scope);
        }
コード例 #3
0
        private void EmitLocation(ParserRuleContext context)
        {
            if (context == null)
            {
                InstructionBuilder.SetDebugLocation(0, 0);
            }
            else
            {
                DIScope scope = Module.DICompileUnit;
                if (LexicalBlocks.Count > 0)
                {
                    scope = LexicalBlocks.Peek( );
                }

                InstructionBuilder.SetDebugLocation(( uint )context.Start.Line, ( uint )context.Start.Column, scope);
            }
        }
コード例 #4
0
        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;
            }
        }
コード例 #5
0
        private Function DefineFunction(Function function, ExpressionContext body)
        {
            if (!function.IsDeclaration)
            {
                throw new ArgumentException($"Function {function.Name} cannot be redefined", nameof(function));
            }

            var proto      = FunctionPrototypes[function.Name];
            var basicBlock = function.AppendBasicBlock("entry");

            InstructionBuilder.PositionAtEnd(basicBlock);

            var diFile = Module.DICompileUnit.File;
            var scope  = Module.DICompileUnit;

            LexicalBlocks.Push(function.DISubProgram);

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

            NamedValues.Clear( );
            foreach (var arg in function.Parameters)
            {
                uint line = ( uint )proto.Parameters[( int )(arg.Index)].Span.StartLine;
                uint col  = ( uint )proto.Parameters[( int )(arg.Index)].Span.StartColumn;

                var             argSlot  = CreateEntryBlockAlloca(function, arg.Name);
                DILocalVariable debugVar = Module.DIBuilder.CreateArgument(function.DISubProgram
                                                                           , arg.Name
                                                                           , diFile
                                                                           , line
                                                                           , DoubleType
                                                                           , true
                                                                           , DebugInfoFlags.None
                                                                           , checked (( ushort )(arg.Index + 1)) // Debug index starts at 1!
                                                                           );
                Module.DIBuilder.InsertDeclare(argSlot
                                               , debugVar
                                               , new DILocation(Context, line, col, function.DISubProgram)
                                               , InstructionBuilder.InsertBlock
                                               );

                InstructionBuilder.Store(arg, argSlot);
                NamedValues[arg.Name] = argSlot;
            }

            var funcReturn = body.Accept(this);

            if (funcReturn == null)
            {
                function.EraseFromParent( );
                LexicalBlocks.Pop( );
                return(null);
            }

            InstructionBuilder.Return(funcReturn);
            LexicalBlocks.Pop( );
            Module.DIBuilder.Finish(function.DISubProgram);
            function.Verify( );
            Trace.TraceInformation(function.ToString( ));

            return(function);
        }