Skip to content

Commit

Permalink
Always generate line numbers debug information
Browse files Browse the repository at this point in the history
  • Loading branch information
ysbaddaden committed Jan 3, 2017
1 parent 8aff8af commit df3fbb3
Show file tree
Hide file tree
Showing 8 changed files with 49 additions and 35 deletions.
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

0 comments on commit df3fbb3

Please sign in to comment.