From 5b53de17752a11c52679dca46e8a4b4ea3fe1354 Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Fri, 24 Apr 2015 15:49:20 +1200 Subject: [PATCH] debuginfo: extract create.rs --- src/librustc_trans/trans/debuginfo/create.rs | 124 +++++++++++++++++++ src/librustc_trans/trans/debuginfo/mod.rs | 101 +-------------- 2 files changed, 129 insertions(+), 96 deletions(-) create mode 100644 src/librustc_trans/trans/debuginfo/create.rs diff --git a/src/librustc_trans/trans/debuginfo/create.rs b/src/librustc_trans/trans/debuginfo/create.rs new file mode 100644 index 000000000000..246a22a6211d --- /dev/null +++ b/src/librustc_trans/trans/debuginfo/create.rs @@ -0,0 +1,124 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://!rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Module-Internal debug info creation functions. + +use super::utils::{span_start, DIB}; + +use super::{set_debug_location, type_metadata, file_metadata, DW_TAG_auto_variable, DW_TAG_arg_variable}; +use super::VariableKind::{self, ArgumentVariable, CapturedVariable, LocalVariable}; +use super::VariableAccess::{self, DirectVariable, IndirectVariable}; +use super::InternalDebugLocation::{self, UnknownLocation}; + +use llvm; +use llvm::debuginfo::{DIScope, DIBuilderRef, DIDescriptor, DIArray}; + +use trans; +use trans::common::{CrateContext, Block}; +use middle::ty::Ty; +use session::config; + +use libc::c_uint; +use std::ffi::CString; +use syntax::codemap::{Span, Pos}; +use syntax::ast; +use syntax::parse::token; + +pub fn is_node_local_to_unit(cx: &CrateContext, node_id: ast::NodeId) -> bool +{ + // The is_local_to_unit flag indicates whether a function is local to the + // current compilation unit (i.e. if it is *static* in the C-sense). The + // *reachable* set should provide a good approximation of this, as it + // contains everything that might leak out of the current crate (by being + // externally visible or by being inlined into something externally + // visible). It might better to use the `exported_items` set from + // `driver::CrateAnalysis` in the future, but (atm) this set is not + // available in the translation pass. + !cx.reachable().contains(&node_id) +} + +#[allow(non_snake_case)] +pub fn create_DIArray(builder: DIBuilderRef, arr: &[DIDescriptor]) -> DIArray { + return unsafe { + llvm::LLVMDIBuilderGetOrCreateArray(builder, arr.as_ptr(), arr.len() as u32) + }; +} + +pub fn declare_local<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, + variable_name: ast::Name, + variable_type: Ty<'tcx>, + scope_metadata: DIScope, + variable_access: VariableAccess, + variable_kind: VariableKind, + span: Span) { + let cx: &CrateContext = bcx.ccx(); + + let filename = span_start(cx, span).file.name.clone(); + let file_metadata = file_metadata(cx, &filename[..]); + + let name = token::get_name(variable_name); + let loc = span_start(cx, span); + let type_metadata = type_metadata(cx, variable_type, span); + + let (argument_index, dwarf_tag) = match variable_kind { + ArgumentVariable(index) => (index as c_uint, DW_TAG_arg_variable), + LocalVariable | + CapturedVariable => (0, DW_TAG_auto_variable) + }; + + let name = CString::new(name.as_bytes()).unwrap(); + match (variable_access, &[][..]) { + (DirectVariable { alloca }, address_operations) | + (IndirectVariable {alloca, address_operations}, _) => { + let metadata = unsafe { + llvm::LLVMDIBuilderCreateVariable( + DIB(cx), + dwarf_tag, + scope_metadata, + name.as_ptr(), + file_metadata, + loc.line as c_uint, + type_metadata, + cx.sess().opts.optimize != config::No, + 0, + address_operations.as_ptr(), + address_operations.len() as c_uint, + argument_index) + }; + set_debug_location(cx, InternalDebugLocation::new(scope_metadata, + loc.line, + loc.col.to_usize())); + unsafe { + let instr = llvm::LLVMDIBuilderInsertDeclareAtEnd( + DIB(cx), + alloca, + metadata, + address_operations.as_ptr(), + address_operations.len() as c_uint, + bcx.llbb); + + llvm::LLVMSetInstDebugLocation(trans::build::B(bcx).llbuilder, instr); + } + } + } + + match variable_kind { + ArgumentVariable(_) | CapturedVariable => { + assert!(!bcx.fcx + .debug_context + .get_ref(cx, span) + .source_locations_enabled + .get()); + set_debug_location(cx, UnknownLocation); + } + _ => { /* nothing to do */ } + } +} + diff --git a/src/librustc_trans/trans/debuginfo/mod.rs b/src/librustc_trans/trans/debuginfo/mod.rs index 306bed6785a2..c1cdfb587b3e 100644 --- a/src/librustc_trans/trans/debuginfo/mod.rs +++ b/src/librustc_trans/trans/debuginfo/mod.rs @@ -13,10 +13,12 @@ mod doc; pub mod gdb; mod utils; +mod create; use self::utils::{debug_context, DIB, span_start, bytes_to_bits, size_and_align_of, assert_type_for_node_id, get_namespace_and_span_for_item, fn_should_be_ignored, contains_nodebug_attribute, create_scope_map}; +use self::create::{declare_local, create_DIArray, is_node_local_to_unit}; use self::VariableAccess::*; use self::VariableKind::*; @@ -31,7 +33,7 @@ use llvm::{ModuleRef, ContextRef, ValueRef}; use llvm::debuginfo::*; use metadata::csearch; use middle::subst::{self, Substs}; -use trans::{self, adt, machine, type_of}; +use trans::{adt, machine, type_of}; use trans::common::{self, NodeIdAndSpan, CrateContext, FunctionContext, Block, NormalizingClosureTyper}; use trans::_match::{BindingInfo, TrByCopy, TrByMove, TrByRef}; @@ -535,7 +537,7 @@ struct FunctionDebugContextData { source_location_override: Cell, } -enum VariableAccess<'a> { +pub enum VariableAccess<'a> { // The llptr given is an alloca containing the variable's value DirectVariable { alloca: ValueRef }, // The llptr given is an alloca containing the start of some pointer chain @@ -543,7 +545,7 @@ enum VariableAccess<'a> { IndirectVariable { alloca: ValueRef, address_operations: &'a [i64] } } -enum VariableKind { +pub enum VariableKind { ArgumentVariable(usize /*index*/), LocalVariable, CapturedVariable, @@ -1430,29 +1432,6 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, } } -//=----------------------------------------------------------------------------- -// Module-Internal debug info creation functions -//=----------------------------------------------------------------------------- - -fn is_node_local_to_unit(cx: &CrateContext, node_id: ast::NodeId) -> bool -{ - // The is_local_to_unit flag indicates whether a function is local to the - // current compilation unit (i.e. if it is *static* in the C-sense). The - // *reachable* set should provide a good approximation of this, as it - // contains everything that might leak out of the current crate (by being - // externally visible or by being inlined into something externally - // visible). It might better to use the `exported_items` set from - // `driver::CrateAnalysis` in the future, but (atm) this set is not - // available in the translation pass. - !cx.reachable().contains(&node_id) -} - -#[allow(non_snake_case)] -fn create_DIArray(builder: DIBuilderRef, arr: &[DIDescriptor]) -> DIArray { - return unsafe { - llvm::LLVMDIBuilderGetOrCreateArray(builder, arr.as_ptr(), arr.len() as u32) - }; -} fn compile_unit_metadata(cx: &CrateContext) -> DIDescriptor { let work_dir = &cx.sess().working_dir; @@ -1504,76 +1483,6 @@ fn compile_unit_metadata(cx: &CrateContext) -> DIDescriptor { } } -fn declare_local<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, - variable_name: ast::Name, - variable_type: Ty<'tcx>, - scope_metadata: DIScope, - variable_access: VariableAccess, - variable_kind: VariableKind, - span: Span) { - let cx: &CrateContext = bcx.ccx(); - - let filename = span_start(cx, span).file.name.clone(); - let file_metadata = file_metadata(cx, &filename[..]); - - let name = token::get_name(variable_name); - let loc = span_start(cx, span); - let type_metadata = type_metadata(cx, variable_type, span); - - let (argument_index, dwarf_tag) = match variable_kind { - ArgumentVariable(index) => (index as c_uint, DW_TAG_arg_variable), - LocalVariable | - CapturedVariable => (0, DW_TAG_auto_variable) - }; - - let name = CString::new(name.as_bytes()).unwrap(); - match (variable_access, &[][..]) { - (DirectVariable { alloca }, address_operations) | - (IndirectVariable {alloca, address_operations}, _) => { - let metadata = unsafe { - llvm::LLVMDIBuilderCreateVariable( - DIB(cx), - dwarf_tag, - scope_metadata, - name.as_ptr(), - file_metadata, - loc.line as c_uint, - type_metadata, - cx.sess().opts.optimize != config::No, - 0, - address_operations.as_ptr(), - address_operations.len() as c_uint, - argument_index) - }; - set_debug_location(cx, InternalDebugLocation::new(scope_metadata, - loc.line, - loc.col.to_usize())); - unsafe { - let instr = llvm::LLVMDIBuilderInsertDeclareAtEnd( - DIB(cx), - alloca, - metadata, - address_operations.as_ptr(), - address_operations.len() as c_uint, - bcx.llbb); - - llvm::LLVMSetInstDebugLocation(trans::build::B(bcx).llbuilder, instr); - } - } - } - - match variable_kind { - ArgumentVariable(_) | CapturedVariable => { - assert!(!bcx.fcx - .debug_context - .get_ref(cx, span) - .source_locations_enabled - .get()); - set_debug_location(cx, UnknownLocation); - } - _ => { /* nothing to do */ } - } -} fn file_metadata(cx: &CrateContext, full_path: &str) -> DIFile { match debug_context(cx).created_files.borrow().get(full_path) {