Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Always generate line numbers debug information #3831

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions spec/compiler/codegen/debug_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ describe "Code gen: debug" do
end

x = Foo.new || Bar.new
), debug: true)
), debug: Crystal::Debug::All)
end

it "inlines instance var access through getter in debug mode" do
Expand Down Expand Up @@ -45,6 +45,6 @@ describe "Code gen: debug" do
foo = Foo.new
foo.set
foo.bar.x
), debug: true, filename: "foo.cr").to_i.should eq(2)
), debug: Crystal::Debug::All, filename: "foo.cr").to_i.should eq(2)
end
end
4 changes: 2 additions & 2 deletions spec/spec_helper.cr
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ def parse(string, wants_doc = false)
parser.parse
end

def codegen(code, inject_primitives = true, debug = false)
def codegen(code, inject_primitives = true, debug = Crystal::Debug::None)
code = inject_primitives(code) if inject_primitives
node = parse code
result = semantic node
Expand All @@ -299,7 +299,7 @@ class Crystal::SpecRunOutput
end
end

def run(code, filename = nil, inject_primitives = true, debug = false)
def run(code, filename = nil, inject_primitives = true, debug = Crystal::Debug::None)
code = inject_primitives(code) if inject_primitives

# Code that requires the prelude doesn't run in LLVM's MCJIT
Expand Down
2 changes: 1 addition & 1 deletion src/compiler/crystal/codegen/call.cr
Original file line number Diff line number Diff line change
Expand Up @@ -452,7 +452,7 @@ class Crystal::CodeGenVisitor
end

def codegen_call_or_invoke(node, target_def, self_type, func, call_args, raises, type, is_closure = false, fun_type = nil)
set_current_debug_location node if @debug
set_current_debug_location node if @debug.line_numbers?

if raises && (rescue_block = @rescue_block)
invoke_out_block = new_block "invoke_out"
Expand Down
33 changes: 16 additions & 17 deletions src/compiler/crystal/codegen/codegen.cr
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ module Crystal
GET_EXCEPTION_NAME = "__crystal_get_exception"

class Program
def run(code, filename = nil, debug = false)
def run(code, filename = nil, debug = Debug::Default)
parser = Parser.new(code)
parser.filename = filename
node = parser.parse
Expand All @@ -23,7 +23,7 @@ module Crystal
evaluate node, debug: debug
end

def evaluate(node, debug = false)
def evaluate(node, debug = Debug::Default)
llvm_mod = codegen(node, single_module: true, debug: debug)[""]
main = llvm_mod.functions[MAIN_NAME]

Expand Down Expand Up @@ -58,7 +58,7 @@ module Crystal
end
end

def codegen(node, single_module = false, debug = false, llvm_mod = LLVM::Module.new("main_module"), expose_crystal_main = true)
def codegen(node, single_module = false, debug = Debug::Default, llvm_mod = LLVM::Module.new("main_module"), expose_crystal_main = true)
visitor = CodeGenVisitor.new self, node, single_module: single_module, debug: debug, llvm_mod: llvm_mod, expose_crystal_main: expose_crystal_main
node.accept visitor
visitor.process_finished_hooks
Expand Down Expand Up @@ -131,10 +131,9 @@ module Crystal
@cant_pass_closure_to_c_exception_call : Call?
@realloc_fun : LLVM::Function?

def initialize(@program : Program, @node : ASTNode, single_module = false, debug = false, @llvm_mod = LLVM::Module.new("main_module"), expose_crystal_main = true)
def initialize(@program : Program, @node : ASTNode, single_module = false, @debug = Debug::Default, @llvm_mod = LLVM::Module.new("main_module"), expose_crystal_main = true)
@main_mod = @llvm_mod
@single_module = !!single_module
@debug = !!debug
@abi = @program.target_machine.abi
@llvm_typer = @program.llvm_typer
@llvm_id = LLVMId.new(@program)
Expand All @@ -143,7 +142,7 @@ module Crystal
@main = @llvm_mod.functions.add(MAIN_NAME, [LLVM::Int32, LLVM::VoidPointer.pointer], ret_type)
@main.linkage = LLVM::Linkage::Internal unless expose_crystal_main

emit_main_def_debug_metadata(@main, "??") if @debug
emit_main_def_debug_metadata(@main, "??") unless @debug.none?

@context = Context.new @main, @program
@context.return_type = @main_ret_type
Expand Down Expand Up @@ -200,13 +199,13 @@ module Crystal

initialize_simple_class_vars_and_constants

if @debug && (filename = @program.filename)
if @debug.line_numbers? && (filename = @program.filename)
set_current_debug_location Location.new(filename, 1, 1)
end

alloca_vars @program.vars, @program

emit_vars_debug_info(@program.vars) if @debug
emit_vars_debug_info(@program.vars) if @debug.variables?
end

# Here we only initialize simple constants and class variables, those
Expand Down Expand Up @@ -307,7 +306,7 @@ module Crystal
end

@modules.each do |name, mod|
push_debug_info_metadata(mod) if @debug
push_debug_info_metadata(mod) unless @debug.none?

mod.dump if dump_all_llvm || name =~ dump_llvm_regex

Expand Down Expand Up @@ -350,7 +349,7 @@ module Crystal
if vars = file_module.vars?
alloca_vars vars, file_module

emit_vars_debug_info(vars) if @debug
emit_vars_debug_info(vars) if @debug.variables?
end
node.node.accept self
@last = llvm_nil
Expand Down Expand Up @@ -526,7 +525,7 @@ module Crystal

last_fun = target_def_fun(node.call.target_def, owner)

set_current_debug_location(node) if @debug
set_current_debug_location(node) if @debug.line_numbers?
fun_ptr = bit_cast(last_fun, LLVM::VoidPointer)
if call_self && !owner.metaclass? && !owner.is_a?(LibType)
ctx_ptr = bit_cast(call_self, LLVM::VoidPointer)
Expand Down Expand Up @@ -697,7 +696,7 @@ module Crystal
then_block, else_block = new_blocks "then", "else"

request_value do
set_current_debug_location(node) if @debug
set_current_debug_location(node) if @debug.line_numbers?
codegen_cond_branch node.cond, then_block, else_block
end

Expand Down Expand Up @@ -731,7 +730,7 @@ module Crystal
position_at_end while_block

request_value do
set_current_debug_location node.cond if @debug
set_current_debug_location node.cond if @debug.line_numbers?
codegen_cond_branch node.cond, body_block, exit_block
end

Expand Down Expand Up @@ -772,7 +771,7 @@ module Crystal
end

def visit(node : Break)
set_current_debug_location(node) if @debug
set_current_debug_location(node) if @debug.line_numbers?
node_type = accept_control_expression(node)

if break_phi = context.break_phi
Expand All @@ -792,7 +791,7 @@ module Crystal
end

def visit(node : Next)
set_current_debug_location(node) if @debug
set_current_debug_location(node) if @debug.line_numbers?
node_type = accept_control_expression(node)

case target = node.target
Expand Down Expand Up @@ -880,7 +879,7 @@ module Crystal

last = @last

set_current_debug_location node if @debug
set_current_debug_location node if @debug.line_numbers?
ptr = case target
when InstanceVar
instance_var_ptr context.type, target.name, llvm_self_ptr
Expand Down Expand Up @@ -1534,7 +1533,7 @@ module Crystal

0.upto(blocks.size - 2) do |i|
position_at_end blocks[i]
clear_current_debug_location if @debug
clear_current_debug_location if @debug.line_numbers?
br blocks[i + 1]
end

Expand Down
2 changes: 1 addition & 1 deletion src/compiler/crystal/codegen/exception.cr
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ class Crystal::CodeGenVisitor
if a_rescue_name = a_rescue.name
context.vars = context.vars.dup
get_exception_fun = main_fun(GET_EXCEPTION_NAME)
set_current_debug_location node if @debug
set_current_debug_location node if @debug.line_numbers?
exception_ptr = call get_exception_fun, [bit_cast(unwind_ex_obj, get_exception_fun.params.first.type)]
exception = int2ptr exception_ptr, LLVMTyper::TYPE_ID_POINTER
unless a_rescue.type.virtual?
Expand Down
12 changes: 7 additions & 5 deletions src/compiler/crystal/codegen/fun.cr
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ class Crystal::CodeGenVisitor

needs_body = !target_def.is_a?(External) || is_exported_fun
if needs_body
emit_def_debug_metadata target_def if @debug
emit_def_debug_metadata target_def unless @debug.none?

context.fun.add_attribute LLVM::Attribute::UWTable
if @program.has_flag?("darwin")
Expand All @@ -77,7 +77,7 @@ class Crystal::CodeGenVisitor
new_entry_block

if is_closure
clear_current_debug_location if @debug
clear_current_debug_location if @debug.line_numbers?
setup_closure_vars context.closure_vars.not_nil!
else
context.reset_closure
Expand All @@ -95,12 +95,12 @@ class Crystal::CodeGenVisitor
context.closure_parent_context = closure_parent_context
end

set_current_debug_location target_def if @debug
set_current_debug_location target_def if @debug.line_numbers?
alloca_vars target_def.vars, target_def, args, context.closure_parent_context

create_local_copy_of_fun_args(target_def, self_type, args, is_fun_literal, is_closure)

if @debug
if @debug.variables?
in_alloca_block do
args_offset = !is_fun_literal && self_type.passed_as_self? ? 2 : 1
location = target_def.location
Expand All @@ -121,7 +121,9 @@ class Crystal::CodeGenVisitor

accept target_def.body

set_current_debug_location target_def.end_location if @debug
if @debug.line_numbers?
set_current_debug_location target_def.end_location
end

codegen_return(target_def)

Expand Down
14 changes: 10 additions & 4 deletions src/compiler/crystal/command.cr
Original file line number Diff line number Diff line change
Expand Up @@ -281,8 +281,11 @@ class Crystal::Command
compiler.cross_compile = true
end
end
opts.on("-d", "--debug", "Add symbolic debug info") do
compiler.debug = true
opts.on("-d", "--debug", "Add full symbolic debug info") do
compiler.debug = Crystal::Debug::All
end
opts.on("", "--no-debug", "Skip any symbolic debug info") do
compiler.debug = Crystal::Debug::None
end
end

Expand Down Expand Up @@ -443,8 +446,11 @@ class Crystal::Command
end

private def setup_simple_compiler_options(compiler, opts)
opts.on("-d", "--debug", "Add symbolic debug info") do
compiler.debug = true
opts.on("-d", "--debug", "Add full symbolic debug info") do
compiler.debug = Crystal::Debug::All
end
opts.on("", "--no-debug", "Skip any symbolic debug info") do
compiler.debug = Crystal::Debug::None
end
opts.on("-D FLAG", "--define FLAG", "Define a compile-time flag") do |flag|
compiler.flags << flag
Expand Down
13 changes: 10 additions & 3 deletions src/compiler/crystal/compiler.cr
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ require "colorize"
require "crypto/md5"

module Crystal
@[Flags]
enum Debug
LineNumbers
Variables
Default = LineNumbers
end

# Main interface to the compiler.
#
# A Compiler parses source code, type checks it and
Expand Down Expand Up @@ -35,7 +42,7 @@ module Crystal

# If `true`, the executable will be generated with debug code
# that can be understood by `gdb` and `lldb`.
property? debug = false
property debug = Debug::Default

# If `true`, `.ll` files will be generated in the default cache
# directory for each generated LLVM module.
Expand Down Expand Up @@ -153,7 +160,7 @@ module Crystal
program.cache_dir = CacheDir.instance.directory_for(sources)
program.target_machine = target_machine
program.flags << "release" if release?
program.flags << "debug" if debug?
program.flags << "debug" unless debug.none?
program.flags.merge! @flags
program.wants_doc = wants_doc?
program.color = color?
Expand Down Expand Up @@ -209,7 +216,7 @@ module Crystal
@link_flags = "#{@link_flags} -rdynamic"

llvm_modules = Crystal.timing("Codegen (crystal)", @stats) do
program.codegen node, debug: @debug, single_module: @single_module || @release || @cross_compile || @emit, expose_crystal_main: false
program.codegen node, debug: debug, single_module: @single_module || @release || @cross_compile || @emit, expose_crystal_main: false
end

if @cross_compile
Expand Down