(index<- )        ./librustc/middle/trans/debuginfo.rs

    git branch:    * master           5200215 auto merge of #14035 : alexcrichton/rust/experimental, r=huonw
    modified:    Fri May  9 13:02:28 2014
    1  // Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
    2  // file at the top-level directory of this distribution and at
    3  // http://rust-lang.org/COPYRIGHT.
    4  //
    5  // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
    6  // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
    7  // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
    8  // option. This file may not be copied, modified, or distributed
    9  // except according to those terms.
   10  
   11  /*!
   12  # Debug Info Module
   13  
   14  This module serves the purpose of generating debug symbols. We use LLVM's
   15  [source level debugging](http://llvm.org/docs/SourceLevelDebugging.html) features for generating
   16  the debug information. The general principle is this:
   17  
   18  Given the right metadata in the LLVM IR, the LLVM code generator is able to create DWARF debug
   19  symbols for the given code. The [metadata](http://llvm.org/docs/LangRef.html#metadata-type) is
   20  structured much like DWARF *debugging information entries* (DIE), representing type information
   21  such as datatype layout, function signatures, block layout, variable location and scope information,
   22  etc. It is the purpose of this module to generate correct metadata and insert it into the LLVM IR.
   23  
   24  As the exact format of metadata trees may change between different LLVM versions, we now use LLVM
   25  [DIBuilder](http://llvm.org/docs/doxygen/html/classllvm_1_1DIBuilder.html) to create metadata
   26  where possible. This will hopefully ease the adaption of this module to future LLVM versions.
   27  
   28  The public API of the module is a set of functions that will insert the correct metadata into the
   29  LLVM IR when called with the right parameters. The module is thus driven from an outside client with
   30  functions like `debuginfo::create_local_var_metadata(bcx: block, local: &ast::local)`.
   31  
   32  Internally the module will try to reuse already created metadata by utilizing a cache. The way to
   33  get a shared metadata node when needed is thus to just call the corresponding function in this
   34  module:
   35  
   36      let file_metadata = file_metadata(crate_context, path);
   37  
   38  The function will take care of probing the cache for an existing node for that exact file path.
   39  
   40  All private state used by the module is stored within either the CrateDebugContext struct (owned by
   41  the CrateContext) or the FunctionDebugContext (owned by the FunctionContext).
   42  
   43  This file consists of three conceptual sections:
   44  1. The public interface of the module
   45  2. Module-internal metadata creation functions
   46  3. Minor utility functions
   47  
   48  
   49  ## Recursive Types
   50  Some kinds of types, such as structs and enums can be recursive. That means that the type definition
   51  of some type X refers to some other type which in turn (transitively) refers to X. This introduces
   52  cycles into the type referral graph. A naive algorithm doing an on-demand, depth-first traversal of
   53  this graph when describing types, can get trapped in an endless loop when it reaches such a cycle.
   54  
   55  For example, the following simple type for a singly-linked list...
   56  
   57  ```
   58  struct List {
   59      value: int,
   60      tail: Option<Box<List>>,
   61  }
   62  ```
   63  
   64  will generate the following callstack with a naive DFS algorithm:
   65  
   66  ```
   67  describe(t = List)
   68    describe(t = int)
   69    describe(t = Option<Box<List>>)
   70      describe(t = Box<List>)
   71        describe(t = List) // at the beginning again...
   72        ...
   73  ```
   74  
   75  To break cycles like these, we use "forward declarations". That is, when the algorithm encounters a
   76  possibly recursive type (any struct or enum), it immediately creates a type description node and
   77  inserts it into the cache *before* describing the members of the type. This type description is just
   78  a stub (as type members are not described and added to it yet) but it allows the algorithm to
   79  already refer to the type. After the stub is inserted into the cache, the algorithm continues as
   80  before. If it now encounters a recursive reference, it will hit the cache and does not try to
   81  describe the type anew.
   82  
   83  This behaviour is encapsulated in the 'RecursiveTypeDescription' enum, which represents a kind of
   84  continuation, storing all state needed to continue traversal at the type members after the type has
   85  been registered with the cache. (This implementation approach might be a tad over-engineered and
   86  may change in the future)
   87  
   88  
   89  ## Source Locations and Line Information
   90  In addition to data type descriptions the debugging information must also allow to map machine code
   91  locations back to source code locations in order to be useful. This functionality is also handled in
   92  this module. The following functions allow to control source mappings:
   93  
   94  + set_source_location()
   95  + clear_source_location()
   96  + start_emitting_source_locations()
   97  
   98  `set_source_location()` allows to set the current source location. All IR instructions created after
   99  a call to this function will be linked to the given source location, until another location is
  100  specified with `set_source_location()` or the source location is cleared with
  101  `clear_source_location()`. In the later case, subsequent IR instruction will not be linked to any
  102  source location. As you can see, this is a stateful API (mimicking the one in LLVM), so be careful
  103  with source locations set by previous calls. It's probably best to not rely on any specific state
  104  being present at a given point in code.
  105  
  106  One topic that deserves some extra attention is *function prologues*. At the beginning of a
  107  function's machine code there are typically a few instructions for loading argument values into
  108  allocas and checking if there's enough stack space for the function to execute. This *prologue* is
  109  not visible in the source code and LLVM puts a special PROLOGUE END marker into the line table at
  110  the first non-prologue instruction of the function. In order to find out where the prologue ends,
  111  LLVM looks for the first instruction in the function body that is linked to a source location. So,
  112  when generating prologue instructions we have to make sure that we don't emit source location
  113  information until the 'real' function body begins. For this reason, source location emission is
  114  disabled by default for any new function being translated and is only activated after a call to the
  115  third function from the list above, `start_emitting_source_locations()`. This function should be
  116  called right before regularly starting to translate the top-level block of the given function.
  117  
  118  There is one exception to the above rule: `llvm.dbg.declare` instruction must be linked to the
  119  source location of the variable being declared. For function parameters these `llvm.dbg.declare`
  120  instructions typically occur in the middle of the prologue, however, they are ignored by LLVM's
  121  prologue detection. The `create_argument_metadata()` and related functions take care of linking the
  122  `llvm.dbg.declare` instructions to the correct source locations even while source location emission
  123  is still disabled, so there is no need to do anything special with source location handling here.
  124  
  125  */
  126  
  127  
  128  use driver::session;
  129  use driver::session::{FullDebugInfo, LimitedDebugInfo, NoDebugInfo};
  130  use lib::llvm::llvm;
  131  use lib::llvm::{ModuleRef, ContextRef, ValueRef};
  132  use lib::llvm::debuginfo::*;
  133  use metadata::csearch;
  134  use middle::trans::adt;
  135  use middle::trans::common::*;
  136  use middle::trans::datum::{Datum, Lvalue};
  137  use middle::trans::machine;
  138  use middle::trans::type_of;
  139  use middle::trans::type_::Type;
  140  use middle::trans;
  141  use middle::ty;
  142  use middle::pat_util;
  143  use util::ppaux;
  144  
  145  use std::c_str::{CString, ToCStr};
  146  use std::cell::{Cell, RefCell};
  147  use std::rc::{Rc, Weak};
  148  use collections::HashMap;
  149  use collections::HashSet;
  150  use libc::{c_uint, c_ulonglong, c_longlong};
  151  use std::ptr;
  152  use std::strbuf::StrBuf;
  153  use std::sync::atomics;
  154  use syntax::codemap::{Span, Pos};
  155  use syntax::{abi, ast, codemap, ast_util, ast_map};
  156  use syntax::owned_slice::OwnedSlice;
  157  use syntax::parse::token;
  158  use syntax::parse::token::special_idents;
  159  
  160  static DW_LANG_RUST: c_uint = 0x9000;
  161  
  162  static DW_TAG_auto_variable: c_uint = 0x100;
  163  static DW_TAG_arg_variable: c_uint = 0x101;
  164  
  165  static DW_ATE_boolean: c_uint = 0x02;
  166  static DW_ATE_float: c_uint = 0x04;
  167  static DW_ATE_signed: c_uint = 0x05;
  168  // static DW_ATE_signed_char: c_uint = 0x06;
  169  static DW_ATE_unsigned: c_uint = 0x07;
  170  static DW_ATE_unsigned_char: c_uint = 0x08;
  171  
  172  //=-------------------------------------------------------------------------------------------------
  173  //  Public Interface of debuginfo module
  174  //=-------------------------------------------------------------------------------------------------
  175  
  176  /// A context object for maintaining all state needed by the debuginfo module.
  177  pub struct CrateDebugContext {
  178      llcontext: ContextRef,
  179      builder: DIBuilderRef,
  180      current_debug_location: Cell<DebugLocation>,
  181      created_files: RefCell<HashMap<~str, DIFile>>,
  182      created_types: RefCell<HashMap<uint, DIType>>,
  183      created_enum_disr_types: RefCell<HashMap<ast::DefId, DIType>>,
  184      namespace_map: RefCell<HashMap<Vec<ast::Name>, Rc<NamespaceTreeNode>>>,
  185      // This collection is used to assert that composite types (structs, enums, ...) have their
  186      // members only set once:
  187      composite_types_completed: RefCell<HashSet<DIType>>,
  188  }
  189  
  190  impl CrateDebugContext {
  191      pub fn new(llmodModuleRef) -> CrateDebugContext {
  192          debug!("CrateDebugContext::new");
  193          let builder = unsafe { llvm::LLVMDIBuilderCreate(llmod) };
  194          // DIBuilder inherits context from the module, so we'd better use the same one
  195          let llcontext = unsafe { llvm::LLVMGetModuleContext(llmod) };
  196          return CrateDebugContext {
  197              llcontext: llcontext,
  198              builder: builder,
  199              current_debug_location: Cell::new(UnknownLocation),
  200              created_files: RefCell::new(HashMap::new()),
  201              created_types: RefCell::new(HashMap::new()),
  202              created_enum_disr_types: RefCell::new(HashMap::new()),
  203              namespace_map: RefCell::new(HashMap::new()),
  204              composite_types_completed: RefCell::new(HashSet::new()),
  205          };
  206      }
  207  }
  208  
  209  pub struct FunctionDebugContext {
  210      repr: FunctionDebugContextRepr,
  211  }
  212  
  213  enum FunctionDebugContextRepr {
  214      FunctionDebugContext(Box<FunctionDebugContextData>),
  215      DebugInfoDisabled,
  216      FunctionWithoutDebugInfo,
  217  }
  218  
  219  impl FunctionDebugContext {
  220      fn get_ref<'a>(&'a self, cx&CrateContext, spanSpan) -> &'a FunctionDebugContextData {
  221          match self.repr {
  222              FunctionDebugContext(box ref data) => data,
  223              DebugInfoDisabled => {
  224                  cx.sess().span_bug(span, FunctionDebugContext::debuginfo_disabled_message());
  225              }
  226              FunctionWithoutDebugInfo => {
  227                  cx.sess().span_bug(span, FunctionDebugContext::should_be_ignored_message());
  228              }
  229          }
  230      }
  231  
  232      fn debuginfo_disabled_message() -> &'static str {
  233          "debuginfo: Error trying to access FunctionDebugContext although debug info is disabled!"
  234      }
  235  
  236      fn should_be_ignored_message() -> &'static str {
  237          "debuginfo: Error trying to access FunctionDebugContext for function that should be \
  238           ignored by debug info!"
  239      }
  240  }
  241  
  242  struct FunctionDebugContextData {
  243      scope_map: RefCell<HashMap<ast::NodeId, DIScope>>,
  244      fn_metadata: DISubprogram,
  245      argument_counter: Cell<uint>,
  246      source_locations_enabled: Cell<bool>,
  247  }
  248  
  249  enum VariableAccess<'a> {
  250      // The llptr given is an alloca containing the variable's value
  251      DirectVariable { alloca: ValueRef },
  252      // The llptr given is an alloca containing the start of some pointer chain leading to the
  253      // variable's content.
  254      IndirectVariable { alloca: ValueRef, address_operations: &'a [ValueRef] }
  255  }
  256  
  257  enum VariableKind {
  258      ArgumentVariable(uint /*index*/),
  259      LocalVariable,
  260      CapturedVariable,
  261  }
  262  
  263  /// Create any deferred debug metadata nodes
  264  pub fn finalize(cx: &CrateContext) {
  265      if cx.dbg_cx.is_none() {
  266          return;
  267      }
  268  
  269      debug!("finalize");
  270      compile_unit_metadata(cx);
  271      unsafe {
  272          llvm::LLVMDIBuilderFinalize(DIB(cx));
  273          llvm::LLVMDIBuilderDispose(DIB(cx));
  274          // Debuginfo generation in LLVM by default uses a higher
  275          // version of dwarf than OS X currently understands. We can
  276          // instruct LLVM to emit an older version of dwarf, however,
  277          // for OS X to understand. For more info see #11352
  278          // This can be overridden using --llvm-opts -dwarf-version,N.
  279          if cx.sess().targ_cfg.os == abi::OsMacos {
  280              "Dwarf Version".with_c_str(
  281                  |s| llvm::LLVMRustAddModuleFlag(cx.llmod, s, 2));
  282          } else {
  283              // FIXME(#13611) this is a kludge fix because the linux bots have
  284              //               gdb 7.4 which doesn't understand dwarf4, we should
  285              //               do something more graceful here.
  286              "Dwarf Version".with_c_str(
  287                  |s| llvm::LLVMRustAddModuleFlag(cx.llmod, s, 3));
  288          }
  289  
  290          // Prevent bitcode readers from deleting the debug info.
  291          "Debug Info Version".with_c_str(
  292              |s| llvm::LLVMRustAddModuleFlag(cx.llmod, s,
  293                                              llvm::LLVMRustDebugMetadataVersion));
  294      };
  295  }
  296  
  297  /// Creates debug information for the given global variable.
  298  ///
  299  /// Adds the created metadata nodes directly to the crate's IR.
  300  pub fn create_global_var_metadata(cx: &CrateContext,
  301                                    node_idast::NodeId,
  302                                    globalValueRef) {
  303      if cx.dbg_cx.is_none() {
  304          return;
  305      }
  306  
  307      // Don't create debuginfo for globals inlined from other crates. The other crate should already
  308      // contain debuginfo for it. More importantly, the global might not even exist in un-inlined
  309      // form anywhere which would lead to a linker errors.
  310      if cx.external_srcs.borrow().contains_key(&node_id) {
  311          return;
  312      }
  313  
  314      let var_item = cx.tcx.map.get(node_id);
  315  
  316      let (ident, span) = match var_item {
  317          ast_map::NodeItem(item) => {
  318              match item.node {
  319                  ast::ItemStatic(..) => (item.ident, item.span),
  320                  _ => cx.sess().span_bug(item.span,
  321                                          format!("debuginfo::create_global_var_metadata() -
  322                                                  Captured var-id refers to unexpected ast_item
  323                                                  variant: {:?}",
  324                                                  var_item))
  325              }
  326          },
  327          _ => cx.sess().bug(format!("debuginfo::create_global_var_metadata() - Captured var-id \
  328                                     refers to unexpected ast_map variant: {:?}",
  329                                     var_item))
  330      };
  331  
  332      let filename = span_start(cx, span).file.name.clone();
  333      let file_metadata = file_metadata(cx, filename.as_slice());
  334  
  335      let is_local_to_unit = is_node_local_to_unit(cx, node_id);
  336      let loc = span_start(cx, span);
  337  
  338      let variable_type = ty::node_id_to_type(cx.tcx(), node_id);
  339      let type_metadata = type_metadata(cx, variable_type, span);
  340  
  341      let namespace_node = namespace_for_item(cx, ast_util::local_def(node_id));
  342      let var_name = token::get_ident(ident).get().to_str();
  343      let linkage_name = namespace_node.mangled_name_of_contained_item(var_name);
  344      let var_scope = namespace_node.scope;
  345  
  346      var_name.with_c_str(|var_name| {
  347          linkage_name.with_c_str(|linkage_name| {
  348              unsafe {
  349                  llvm::LLVMDIBuilderCreateStaticVariable(DIB(cx),
  350                                                          var_scope,
  351                                                          var_name,
  352                                                          linkage_name,
  353                                                          file_metadata,
  354                                                          loc.line as c_uint,
  355                                                          type_metadata,
  356                                                          is_local_to_unit,
  357                                                          global,
  358                                                          ptr::null());
  359              }
  360          })
  361      });
  362  }
  363  
  364  /// Creates debug information for the given local variable.
  365  ///
  366  /// Adds the created metadata nodes directly to the crate's IR.
  367  pub fn create_local_var_metadata(bcx: &Block, local: &ast::Local) {
  368      if fn_should_be_ignored(bcx.fcx) {
  369          return;
  370      }
  371  
  372      let cx = bcx.ccx();
  373      let def_map = &cx.tcx.def_map;
  374  
  375      pat_util::pat_bindings(def_map, local.pat, |_, node_id, span, path_ref| {
  376          let var_ident = ast_util::path_to_ident(path_ref);
  377  
  378          let datum = match bcx.fcx.lllocals.borrow().find_copy(&node_id) {
  379              Some(datum) => datum,
  380              None => {
  381                  bcx.sess().span_bug(span,
  382                      format!("no entry in lllocals table for {:?}",
  383                              node_id));
  384              }
  385          };
  386  
  387          let scope_metadata = scope_metadata(bcx.fcx, node_id, span);
  388  
  389          declare_local(bcx,
  390                        var_ident,
  391                        datum.ty,
  392                        scope_metadata,
  393                        DirectVariable { alloca: datum.val },
  394                        LocalVariable,
  395                        span);
  396      })
  397  }
  398  
  399  /// Creates debug information for a variable captured in a closure.
  400  ///
  401  /// Adds the created metadata nodes directly to the crate's IR.
  402  pub fn create_captured_var_metadata(bcx: &Block,
  403                                      node_idast::NodeId,
  404                                      env_data_typety::t,
  405                                      env_pointerValueRef,
  406                                      env_index: uint,
  407                                      closure_storety::TraitStore,
  408                                      spanSpan) {
  409      if fn_should_be_ignored(bcx.fcx) {
  410          return;
  411      }
  412  
  413      let cx = bcx.ccx();
  414  
  415      let ast_item = cx.tcx.map.find(node_id);
  416  
  417      let variable_ident = match ast_item {
  418          None => {
  419              cx.sess().span_bug(span, "debuginfo::create_captured_var_metadata: node not found");
  420          }
  421          Some(ast_map::NodeLocal(pat)) | Some(ast_map::NodeArg(pat)) => {
  422              match pat.node {
  423                  ast::PatIdent(_, ref path, _) => {
  424                      ast_util::path_to_ident(path)
  425                  }
  426                  _ => {
  427                      cx.sess()
  428                        .span_bug(span,
  429                                  format!(
  430                                  "debuginfo::create_captured_var_metadata() - \
  431                                   Captured var-id refers to unexpected \
  432                                   ast_map variant: {:?}",
  433                                   ast_item));
  434                  }
  435              }
  436          }
  437          _ => {
  438              cx.sess().span_bug(span, format!("debuginfo::create_captured_var_metadata() - \
  439                  Captured var-id refers to unexpected ast_map variant: {:?}", ast_item));
  440          }
  441      };
  442  
  443      let variable_type = node_id_type(bcx, node_id);
  444      let scope_metadata = bcx.fcx.debug_context.get_ref(cx, span).fn_metadata;
  445  
  446      let llvm_env_data_type = type_of::type_of(cx, env_data_type);
  447      let byte_offset_of_var_in_env = machine::llelement_offset(cx, llvm_env_data_type, env_index);
  448  
  449      let address_operations = unsafe {
  450          [llvm::LLVMDIBuilderCreateOpDeref(Type::i64(cx).to_ref()),
  451           llvm::LLVMDIBuilderCreateOpPlus(Type::i64(cx).to_ref()),
  452           C_i64(cx, byte_offset_of_var_in_env as i64),
  453           llvm::LLVMDIBuilderCreateOpDeref(Type::i64(cx).to_ref())]
  454      };
  455  
  456      let address_op_count = match closure_store {
  457          ty::RegionTraitStore(..) => {
  458              address_operations.len()
  459          }
  460          ty::UniqTraitStore => {
  461              address_operations.len() - 1
  462          }
  463      };
  464  
  465      let variable_access = IndirectVariable {
  466          alloca: env_pointer,
  467          address_operations: address_operations.slice_to(address_op_count)
  468      };
  469  
  470      declare_local(bcx,
  471                    variable_ident,
  472                    variable_type,
  473                    scope_metadata,
  474                    variable_access,
  475                    CapturedVariable,
  476                    span);
  477  }
  478  
  479  /// Creates debug information for a local variable introduced in the head of a match-statement arm.
  480  ///
  481  /// Adds the created metadata nodes directly to the crate's IR.
  482  pub fn create_match_binding_metadata(bcx: &Block,
  483                                       variable_identast::Ident,
  484                                       node_idast::NodeId,
  485                                       spanSpan,
  486                                       datumDatum<Lvalue>) {
  487      if fn_should_be_ignored(bcx.fcx) {
  488          return;
  489      }
  490  
  491      let scope_metadata = scope_metadata(bcx.fcx, node_id, span);
  492  
  493      declare_local(bcx,
  494                    variable_ident,
  495                    datum.ty,
  496                    scope_metadata,
  497                    DirectVariable { alloca: datum.val },
  498                    LocalVariable,
  499                    span);
  500  }
  501  
  502  /// Creates debug information for the given function argument.
  503  ///
  504  /// Adds the created metadata nodes directly to the crate's IR.
  505  pub fn create_argument_metadata(bcx: &Block, arg: &ast::Arg) {
  506      if fn_should_be_ignored(bcx.fcx) {
  507          return;
  508      }
  509  
  510      let fcx = bcx.fcx;
  511      let cx = fcx.ccx;
  512  
  513      let def_map = &cx.tcx.def_map;
  514      let scope_metadata = bcx.fcx.debug_context.get_ref(cx, arg.pat.span).fn_metadata;
  515  
  516      pat_util::pat_bindings(def_map, arg.pat, |_, node_id, span, path_ref| {
  517          let llarg = match bcx.fcx.llargs.borrow().find_copy(&node_id) {
  518              Some(v) => v,
  519              None => {
  520                  bcx.sess().span_bug(span,
  521                      format!("no entry in llargs table for {:?}",
  522                              node_id));
  523              }
  524          };
  525  
  526          if unsafe { llvm::LLVMIsAAllocaInst(llarg.val) } == ptr::null() {
  527              cx.sess().span_bug(span, "debuginfo::create_argument_metadata() - \
  528                                      Referenced variable location is not an alloca!");
  529          }
  530  
  531          let argument_ident = ast_util::path_to_ident(path_ref);
  532  
  533          let argument_index = {
  534              let counter = &fcx.debug_context.get_ref(cx, span).argument_counter;
  535              let argument_index = counter.get();
  536              counter.set(argument_index + 1);
  537              argument_index
  538          };
  539  
  540          declare_local(bcx,
  541                        argument_ident,
  542                        llarg.ty,
  543                        scope_metadata,
  544                        DirectVariable { alloca: llarg.val },
  545                        ArgumentVariable(argument_index),
  546                        span);
  547      })
  548  }
  549  
  550  /// Sets the current debug location at the beginning of the span.
  551  ///
  552  /// Maps to a call to llvm::LLVMSetCurrentDebugLocation(...). The node_id parameter is used to
  553  /// reliably find the correct visibility scope for the code position.
  554  pub fn set_source_location(fcx: &FunctionContext,
  555                             node_idast::NodeId,
  556                             spanSpan) {
  557      match fcx.debug_context.repr {
  558          DebugInfoDisabled => return,
  559          FunctionWithoutDebugInfo => {
  560              set_debug_location(fcx.ccx, UnknownLocation);
  561              return;
  562          }
  563          FunctionDebugContext(box ref function_debug_context) => {
  564              let cx = fcx.ccx;
  565  
  566              debug!("set_source_location: {}", cx.sess().codemap().span_to_str(span));
  567  
  568              if function_debug_context.source_locations_enabled.get() {
  569                  let loc = span_start(cx, span);
  570                  let scope = scope_metadata(fcx, node_id, span);
  571  
  572                  set_debug_location(cx, DebugLocation::new(scope, loc.line, loc.col.to_uint()));
  573              } else {
  574                  set_debug_location(cx, UnknownLocation);
  575              }
  576          }
  577      }
  578  }
  579  
  580  /// Clears the current debug location.
  581  ///
  582  /// Instructions generated hereafter won't be assigned a source location.
  583  pub fn clear_source_location(fcx: &FunctionContext) {
  584      if fn_should_be_ignored(fcx) {
  585          return;
  586      }
  587  
  588      set_debug_location(fcx.ccx, UnknownLocation);
  589  }
  590  
  591  /// Enables emitting source locations for the given functions.
  592  ///
  593  /// Since we don't want source locations to be emitted for the function prelude, they are disabled
  594  /// when beginning to translate a new function. This functions switches source location emitting on
  595  /// and must therefore be called before the first real statement/expression of the function is
  596  /// translated.
  597  pub fn start_emitting_source_locations(fcx: &FunctionContext) {
  598      match fcx.debug_context.repr {
  599          FunctionDebugContext(box ref data) => {
  600              data.source_locations_enabled.set(true)
  601          },
  602          _ => { /* safe to ignore */ }
  603      }
  604  }
  605  
  606  /// Creates the function-specific debug context.
  607  ///
  608  /// Returns the FunctionDebugContext for the function which holds state needed for debug info
  609  /// creation. The function may also return another variant of the FunctionDebugContext enum which
  610  /// indicates why no debuginfo should be created for the function.
  611  pub fn create_function_debug_context(cx: &CrateContext,
  612                                       fn_ast_idast::NodeId,
  613                                       param_substsOption<&param_substs>,
  614                                       llfnValueRef) -> FunctionDebugContext {
  615      if cx.sess().opts.debuginfo == NoDebugInfo {
  616          return FunctionDebugContext { repr: DebugInfoDisabled };
  617      }
  618  
  619      // Clear the debug location so we don't assign them in the function prelude. Do this here
  620      // already, in case we do an early exit from this function.
  621      set_debug_location(cx, UnknownLocation);
  622  
  623      if fn_ast_id == -1 {
  624          return FunctionDebugContext { repr: FunctionWithoutDebugInfo };
  625      }
  626  
  627      let empty_generics = ast::Generics { lifetimes: Vec::new(), ty_params: OwnedSlice::empty() };
  628  
  629      let fnitem = cx.tcx.map.get(fn_ast_id);
  630  
  631      let (ident, fn_decl, generics, top_level_block, span, has_path) = match fnitem {
  632          ast_map::NodeItem(ref item) => {
  633              match item.node {
  634                  ast::ItemFn(fn_decl, _, _, ref generics, top_level_block) => {
  635                      (item.ident, fn_decl, generics, top_level_block, item.span, true)
  636                  }
  637                  _ => {
  638                      cx.sess().span_bug(item.span,
  639                          "create_function_debug_context: item bound to non-function");
  640                  }
  641              }
  642          }
  643          ast_map::NodeMethod(ref method) => {
  644              (method.ident,
  645               method.decl,
  646               &method.generics,
  647               method.body,
  648               method.span,
  649               true)
  650          }
  651          ast_map::NodeExpr(ref expr) => {
  652              match expr.node {
  653                  ast::ExprFnBlock(fn_decl, top_level_block) |
  654                  ast::ExprProc(fn_decl, top_level_block) => {
  655                      let name = format!("fn{}", token::gensym("fn"));
  656                      let name = token::str_to_ident(name);
  657                      (name, fn_decl,
  658                          // This is not quite right. It should actually inherit the generics of the
  659                          // enclosing function.
  660                          &empty_generics,
  661                          top_level_block,
  662                          expr.span,
  663                          // Don't try to lookup the item path:
  664                          false)
  665                  }
  666                  _ => cx.sess().span_bug(expr.span,
  667                          "create_function_debug_context: expected an expr_fn_block here")
  668              }
  669          }
  670          ast_map::NodeTraitMethod(ref trait_method) => {
  671              match **trait_method {
  672                  ast::Provided(ref method) => {
  673                      (method.ident,
  674                       method.decl,
  675                       &method.generics,
  676                       method.body,
  677                       method.span,
  678                       true)
  679                  }
  680                  _ => {
  681                      cx.sess()
  682                        .bug(format!("create_function_debug_context: \
  683                                      unexpected sort of node: {:?}",
  684                                      fnitem))
  685                  }
  686              }
  687          }
  688          ast_map::NodeForeignItem(..) |
  689          ast_map::NodeVariant(..) |
  690          ast_map::NodeStructCtor(..) => {
  691              return FunctionDebugContext { repr: FunctionWithoutDebugInfo };
  692          }
  693          _ => cx.sess().bug(format!("create_function_debug_context: \
  694                                      unexpected sort of node: {:?}", fnitem))
  695      };
  696  
  697      // This can be the case for functions inlined from another crate
  698      if span == codemap::DUMMY_SP {
  699          return FunctionDebugContext { repr: FunctionWithoutDebugInfo };
  700      }
  701  
  702      let loc = span_start(cx, span);
  703      let file_metadata = file_metadata(cx, loc.file.name.as_slice());
  704  
  705      let function_type_metadata = unsafe {
  706          let fn_signature = get_function_signature(cx, fn_ast_id, fn_decl, param_substs, span);
  707          llvm::LLVMDIBuilderCreateSubroutineType(DIB(cx), file_metadata, fn_signature)
  708      };
  709  
  710      // get_template_parameters() will append a `<...>` clause to the function name if necessary.
  711      let mut function_name = StrBuf::from_str(token::get_ident(ident).get());
  712      let template_parameters = get_template_parameters(cx,
  713                                                        generics,
  714                                                        param_substs,
  715                                                        file_metadata,
  716                                                        &mut function_name);
  717  
  718      // There is no ast_map::Path for ast::ExprFnBlock-type functions. For now, just don't put them
  719      // into a namespace. In the future this could be improved somehow (storing a path in the
  720      // ast_map, or construct a path using the enclosing function).
  721      let (linkage_name, containing_scope) = if has_path {
  722          let namespace_node = namespace_for_item(cx, ast_util::local_def(fn_ast_id));
  723          let linkage_name = namespace_node.mangled_name_of_contained_item(
  724              function_name.as_slice());
  725          let containing_scope = namespace_node.scope;
  726          (linkage_name, containing_scope)
  727      } else {
  728          (function_name.as_slice().to_owned(), file_metadata)
  729      };
  730  
  731      // Clang sets this parameter to the opening brace of the function's block, so let's do this too.
  732      let scope_line = span_start(cx, top_level_block.span).line;
  733  
  734      let is_local_to_unit = is_node_local_to_unit(cx, fn_ast_id);
  735  
  736      let fn_metadata = function_name.as_slice().with_c_str(|function_name| {
  737                            linkage_name.with_c_str(|linkage_name| {
  738              unsafe {
  739                  llvm::LLVMDIBuilderCreateFunction(
  740                      DIB(cx),
  741                      containing_scope,
  742                      function_name,
  743                      linkage_name,
  744                      file_metadata,
  745                      loc.line as c_uint,
  746                      function_type_metadata,
  747                      is_local_to_unit,
  748                      true,
  749                      scope_line as c_uint,
  750                      FlagPrototyped as c_uint,
  751                      cx.sess().opts.optimize != session::No,
  752                      llfn,
  753                      template_parameters,
  754                      ptr::null())
  755              }
  756          })
  757      });
  758  
  759      // Initialize fn debug context (including scope map and namespace map)
  760      let fn_debug_context = box FunctionDebugContextData {
  761          scope_map: RefCell::new(HashMap::new()),
  762          fn_metadata: fn_metadata,
  763          argument_counter: Cell::new(1),
  764          source_locations_enabled: Cell::new(false),
  765      };
  766  
  767      let arg_pats = fn_decl.inputs.iter().map(|arg_ref| arg_ref.pat).collect::<Vec<_>>();
  768      populate_scope_map(cx,
  769                         arg_pats.as_slice(),
  770                         top_level_block,
  771                         fn_metadata,
  772                         &mut *fn_debug_context.scope_map.borrow_mut());
  773  
  774      return FunctionDebugContext { repr: FunctionDebugContext(fn_debug_context) };
  775  
  776      fn get_function_signature(cx: &CrateContext,
  777                                fn_ast_idast::NodeId,
  778                                fn_decl&ast::FnDecl,
  779                                param_substsOption<&param_substs>,
  780                                error_spanSpan) -> DIArray {
  781          if cx.sess().opts.debuginfo == LimitedDebugInfo {
  782              return create_DIArray(DIB(cx), []);
  783          }
  784  
  785          let mut signature = Vec::with_capacity(fn_decl.inputs.len() + 1);
  786  
  787          // Return type -- llvm::DIBuilder wants this at index 0
  788          match fn_decl.output.node {
  789              ast::TyNil => {
  790                  signature.push(ptr::null());
  791              }
  792              _ => {
  793                  assert_type_for_node_id(cx, fn_ast_id, error_span);
  794  
  795                  let return_type = ty::node_id_to_type(cx.tcx(), fn_ast_id);
  796                  let return_type = match param_substs {
  797                      None => return_type,
  798                      Some(substs) => {
  799                          ty::subst_tps(cx.tcx(),
  800                                        substs.tys.as_slice(),
  801                                        substs.self_ty,
  802                                        return_type)
  803                      }
  804                  };
  805  
  806                  signature.push(type_metadata(cx, return_type, codemap::DUMMY_SP));
  807              }
  808          }
  809  
  810          // Arguments types
  811          for arg in fn_decl.inputs.iter() {
  812              assert_type_for_node_id(cx, arg.pat.id, arg.pat.span);
  813              let arg_type = ty::node_id_to_type(cx.tcx(), arg.pat.id);
  814              let arg_type = match param_substs {
  815                  None => arg_type,
  816                  Some(substs) => {
  817                      ty::subst_tps(cx.tcx(),
  818                                    substs.tys.as_slice(),
  819                                    substs.self_ty,
  820                                    arg_type)
  821                  }
  822              };
  823  
  824              signature.push(type_metadata(cx, arg_type, codemap::DUMMY_SP));
  825          }
  826  
  827          return create_DIArray(DIB(cx), signature.as_slice());
  828      }
  829  
  830      fn get_template_parameters(cx&CrateContext,
  831                                 generics&ast::Generics,
  832                                 param_substsOption<&param_substs>,
  833                                 file_metadataDIFile,
  834                                 name_to_append_suffix_to&mut StrBuf)
  835                                 -> DIArray {
  836          let self_type = match param_substs {
  837              Some(param_substs) => param_substs.self_ty,
  838              _ => None
  839          };
  840  
  841          // Only true for static default methods:
  842          let has_self_type = self_type.is_some();
  843  
  844          if !generics.is_type_parameterized() && !has_self_type {
  845              return create_DIArray(DIB(cx), []);
  846          }
  847  
  848          name_to_append_suffix_to.push_char('<');
  849  
  850          // The list to be filled with template parameters:
  851          let mut template_paramsVec<DIDescriptor> =
  852              Vec::with_capacity(generics.ty_params.len() + 1);
  853  
  854          // Handle self type
  855          if has_self_type {
  856              let actual_self_type = self_type.unwrap();
  857              // Add self type name to <...> clause of function name
  858              let actual_self_type_name = ppaux::ty_to_str(cx.tcx(), actual_self_type);
  859              name_to_append_suffix_to.push_str(actual_self_type_name);
  860  
  861              if generics.is_type_parameterized() {
  862                  name_to_append_suffix_to.push_str(",");
  863              }
  864  
  865              // Only create type information if full debuginfo is enabled
  866              if cx.sess().opts.debuginfo == FullDebugInfo {
  867                  let actual_self_type_metadata = type_metadata(cx,
  868                                                                actual_self_type,
  869                                                                codemap::DUMMY_SP);
  870  
  871                  let ident = special_idents::type_self;
  872  
  873                  let param_metadata = token::get_ident(ident).get()
  874                                                              .with_c_str(|name| {
  875                      unsafe {
  876                          llvm::LLVMDIBuilderCreateTemplateTypeParameter(
  877                              DIB(cx),
  878                              file_metadata,
  879                              name,
  880                              actual_self_type_metadata,
  881                              ptr::null(),
  882                              0,
  883                              0)
  884                      }
  885                  });
  886  
  887                  template_params.push(param_metadata);
  888              }
  889          }
  890  
  891          // Handle other generic parameters
  892          let actual_types = match param_substs {
  893              Some(param_substs) => &param_substs.tys,
  894              None => {
  895                  return create_DIArray(DIB(cx), template_params.as_slice());
  896              }
  897          };
  898  
  899          for (index, &ast::TyParam{ ident: ident, .. }) in generics.ty_params.iter().enumerate() {
  900              let actual_type = *actual_types.get(index);
  901              // Add actual type name to <...> clause of function name
  902              let actual_type_name = ppaux::ty_to_str(cx.tcx(), actual_type);
  903              name_to_append_suffix_to.push_str(actual_type_name);
  904  
  905              if index != generics.ty_params.len() - 1 {
  906                  name_to_append_suffix_to.push_str(",");
  907              }
  908  
  909              // Again, only create type information if full debuginfo is enabled
  910              if cx.sess().opts.debuginfo == FullDebugInfo {
  911                  let actual_type_metadata = type_metadata(cx, actual_type, codemap::DUMMY_SP);
  912                  let param_metadata = token::get_ident(ident).get()
  913                                                              .with_c_str(|name| {
  914                      unsafe {
  915                          llvm::LLVMDIBuilderCreateTemplateTypeParameter(
  916                              DIB(cx),
  917                              file_metadata,
  918                              name,
  919                              actual_type_metadata,
  920                              ptr::null(),
  921                              0,
  922                              0)
  923                      }
  924                  });
  925                  template_params.push(param_metadata);
  926              }
  927          }
  928  
  929          name_to_append_suffix_to.push_char('>');
  930  
  931          return create_DIArray(DIB(cx), template_params.as_slice());
  932      }
  933  }
  934  
  935  //=-------------------------------------------------------------------------------------------------
  936  // Module-Internal debug info creation functions
  937  //=-------------------------------------------------------------------------------------------------
  938  
  939  fn is_node_local_to_unit(cx: &CrateContext, node_idast::NodeId) -> bool
  940  {
  941      // The is_local_to_unit flag indicates whether a function is local to the current compilation
  942      // unit (i.e. if it is *static* in the C-sense). The *reachable* set should provide a good
  943      // approximation of this, as it contains everything that might leak out of the current crate
  944      // (by being externally visible or by being inlined into something externally visible). It might
  945      // better to use the `exported_items` set from `driver::CrateAnalysis` in the future, but (atm)
  946      // this set is not available in the translation pass.
  947      !cx.reachable.contains(&node_id)
  948  }
  949  
  950  fn create_DIArray(builderDIBuilderRef, arr: &[DIDescriptor]) -> DIArray {
  951      return unsafe {
  952          llvm::LLVMDIBuilderGetOrCreateArray(builder, arr.as_ptr(), arr.len() as u32)
  953      };
  954  }
  955  
  956  fn compile_unit_metadata(cx: &CrateContext) {
  957      let work_dir = &cx.sess().working_dir;
  958      let compile_unit_name = match cx.sess().local_crate_source_file {
  959          None => fallback_path(cx),
  960          Some(ref abs_path) => {
  961              if abs_path.is_relative() {
  962                  cx.sess().warn("debuginfo: Invalid path to crate's local root source file!");
  963                  fallback_path(cx)
  964              } else {
  965                  match abs_path.path_relative_from(work_dir) {
  966                      Some(ref p) if p.is_relative() => {
  967                              // prepend "./" if necessary
  968                              let dotdot = bytes!("..");
  969                              let prefix = &[dotdot[0], ::std::path::SEP_BYTE];
  970                              let mut path_bytes = Vec::from_slice(p.as_vec());
  971  
  972                              if path_bytes.slice_to(2) != prefix &&
  973                                 path_bytes.slice_to(2) != dotdot {
  974                                  path_bytes.insert(0, prefix[0]);
  975                                  path_bytes.insert(1, prefix[1]);
  976                              }
  977  
  978                              path_bytes.as_slice().to_c_str()
  979                          }
  980                      _ => fallback_path(cx)
  981                  }
  982              }
  983          }
  984      };
  985  
  986      debug!("compile_unit_metadata: {:?}", compile_unit_name);
  987      let producer = format!("rustc version {}",
  988                             (option_env!("CFG_VERSION")).expect("CFG_VERSION"));
  989  
  990      compile_unit_name.with_ref(|compile_unit_name| {
  991          work_dir.as_vec().with_c_str(|work_dir| {
  992              producer.with_c_str(|producer| {
  993                  "".with_c_str(|flags| {
  994                      "".with_c_str(|split_name| {
  995                          unsafe {
  996                              llvm::LLVMDIBuilderCreateCompileUnit(
  997                                  debug_context(cx).builder,
  998                                  DW_LANG_RUST,
  999                                  compile_unit_name,
 1000                                  work_dir,
 1001                                  producer,
 1002                                  cx.sess().opts.optimize != session::No,
 1003                                  flags,
 1004                                  0,
 1005                                  split_name);
 1006                          }
 1007                      })
 1008                  })
 1009              })
 1010          })
 1011      });
 1012  
 1013      fn fallback_path(cx&CrateContext) -> CString {
 1014          cx.link_meta.crateid.name.as_slice().to_c_str()
 1015      }
 1016  }
 1017  
 1018  fn declare_local(bcx: &Block,
 1019                   variable_identast::Ident,
 1020                   variable_typety::t,
 1021                   scope_metadataDIScope,
 1022                   variable_accessVariableAccess,
 1023                   variable_kindVariableKind,
 1024                   spanSpan) {
 1025      let cx&CrateContext = bcx.ccx();
 1026  
 1027      let filename = span_start(cx, span).file.name.clone();
 1028      let file_metadata = file_metadata(cx, filename.as_slice());
 1029  
 1030      let name = token::get_ident(variable_ident);
 1031      let loc = span_start(cx, span);
 1032      let type_metadata = type_metadata(cx, variable_type, span);
 1033  
 1034      let (argument_index, dwarf_tag) = match variable_kind {
 1035          ArgumentVariable(index) => (index as c_uint, DW_TAG_arg_variable),
 1036          LocalVariable    |
 1037          CapturedVariable => (0, DW_TAG_auto_variable)
 1038      };
 1039  
 1040      let (var_alloca, var_metadata) = name.get().with_c_str(|name| {
 1041          match variable_access {
 1042              DirectVariable { alloca } => (
 1043                  alloca,
 1044                  unsafe {
 1045                      llvm::LLVMDIBuilderCreateLocalVariable(
 1046                          DIB(cx),
 1047                          dwarf_tag,
 1048                          scope_metadata,
 1049                          name,
 1050                          file_metadata,
 1051                          loc.line as c_uint,
 1052                          type_metadata,
 1053                          cx.sess().opts.optimize != session::No,
 1054                          0,
 1055                          argument_index)
 1056                  }
 1057              ),
 1058              IndirectVariable { alloca, address_operations } => (
 1059                  alloca,
 1060                  unsafe {
 1061                      llvm::LLVMDIBuilderCreateComplexVariable(
 1062                          DIB(cx),
 1063                          dwarf_tag,
 1064                          scope_metadata,
 1065                          name,
 1066                          file_metadata,
 1067                          loc.line as c_uint,
 1068                          type_metadata,
 1069                          address_operations.as_ptr(),
 1070                          address_operations.len() as c_uint,
 1071                          argument_index)
 1072                  }
 1073              )
 1074          }
 1075      });
 1076  
 1077      set_debug_location(cx, DebugLocation::new(scope_metadata, loc.line, loc.col.to_uint()));
 1078      unsafe {
 1079          let instr = llvm::LLVMDIBuilderInsertDeclareAtEnd(
 1080              DIB(cx),
 1081              var_alloca,
 1082              var_metadata,
 1083              bcx.llbb);
 1084  
 1085          llvm::LLVMSetInstDebugLocation(trans::build::B(bcx).llbuilder, instr);
 1086      }
 1087  
 1088      match variable_kind {
 1089          ArgumentVariable(_) | CapturedVariable => {
 1090              assert!(!bcx.fcx
 1091                          .debug_context
 1092                          .get_ref(cx, span)
 1093                          .source_locations_enabled
 1094                          .get());
 1095              set_debug_location(cx, UnknownLocation);
 1096          }
 1097          _ => { /* nothing to do */ }
 1098      }
 1099  }
 1100  
 1101  fn file_metadata(cx: &CrateContext, full_path: &str) -> DIFile {
 1102      match debug_context(cx).created_files.borrow().find_equiv(&full_path) {
 1103          Some(file_metadata) => return *file_metadata,
 1104          None => ()
 1105      }
 1106  
 1107      debug!("file_metadata: {}", full_path);
 1108  
 1109      // FIXME (#9639): This needs to handle non-utf8 paths
 1110      let work_dir = cx.sess().working_dir.as_str().unwrap();
 1111      let file_name =
 1112          if full_path.starts_with(work_dir) {
 1113              full_path.slice(work_dir.len() + 1u, full_path.len())
 1114          } else {
 1115              full_path
 1116          };
 1117  
 1118      let file_metadata =
 1119          file_name.with_c_str(|file_name| {
 1120              work_dir.with_c_str(|work_dir| {
 1121                  unsafe {
 1122                      llvm::LLVMDIBuilderCreateFile(DIB(cx), file_name, work_dir)
 1123                  }
 1124              })
 1125          });
 1126  
 1127      let mut created_files = debug_context(cx).created_files.borrow_mut();
 1128      created_files.insert(full_path.to_owned(), file_metadata);
 1129      return file_metadata;
 1130  }
 1131  
 1132  /// Finds the scope metadata node for the given AST node.
 1133  fn scope_metadata(fcx: &FunctionContext,
 1134                    node_idast::NodeId,
 1135                    spanSpan)
 1136                 -> DIScope {
 1137      let scope_map = &fcx.debug_context.get_ref(fcx.ccx, span).scope_map;
 1138      match scope_map.borrow().find_copy(&node_id) {
 1139          Some(scope_metadata) => scope_metadata,
 1140          None => {
 1141              let node = fcx.ccx.tcx.map.get(node_id);
 1142  
 1143              fcx.ccx.sess().span_bug(span,
 1144                  format!("debuginfo: Could not find scope info for node {:?}", node));
 1145          }
 1146      }
 1147  }
 1148  
 1149  fn basic_type_metadata(cx: &CrateContext, tty::t) -> DIType {
 1150  
 1151      debug!("basic_type_metadata: {:?}", ty::get(t));
 1152  
 1153      let (name, encoding) = match ty::get(t).sty {
 1154          ty::ty_nil => ("()".to_owned(), DW_ATE_unsigned),
 1155          ty::ty_bot => ("!".to_owned(), DW_ATE_unsigned),
 1156          ty::ty_bool => ("bool".to_owned(), DW_ATE_boolean),
 1157          ty::ty_char => ("char".to_owned(), DW_ATE_unsigned_char),
 1158          ty::ty_int(int_ty) => match int_ty {
 1159              ast::TyI => ("int".to_owned(), DW_ATE_signed),
 1160              ast::TyI8 => ("i8".to_owned(), DW_ATE_signed),
 1161              ast::TyI16 => ("i16".to_owned(), DW_ATE_signed),
 1162              ast::TyI32 => ("i32".to_owned(), DW_ATE_signed),
 1163              ast::TyI64 => ("i64".to_owned(), DW_ATE_signed)
 1164          },
 1165          ty::ty_uint(uint_ty) => match uint_ty {
 1166              ast::TyU => ("uint".to_owned(), DW_ATE_unsigned),
 1167              ast::TyU8 => ("u8".to_owned(), DW_ATE_unsigned),
 1168              ast::TyU16 => ("u16".to_owned(), DW_ATE_unsigned),
 1169              ast::TyU32 => ("u32".to_owned(), DW_ATE_unsigned),
 1170              ast::TyU64 => ("u64".to_owned(), DW_ATE_unsigned)
 1171          },
 1172          ty::ty_float(float_ty) => match float_ty {
 1173              ast::TyF32 => ("f32".to_owned(), DW_ATE_float),
 1174              ast::TyF64 => ("f64".to_owned(), DW_ATE_float),
 1175              ast::TyF128 => ("f128".to_owned(), DW_ATE_float)
 1176          },
 1177          _ => cx.sess().bug("debuginfo::basic_type_metadata - t is invalid type")
 1178      };
 1179  
 1180      let llvm_type = type_of::type_of(cx, t);
 1181      let (size, align) = size_and_align_of(cx, llvm_type);
 1182      let ty_metadata = name.with_c_str(|name| {
 1183          unsafe {
 1184              llvm::LLVMDIBuilderCreateBasicType(
 1185                  DIB(cx),
 1186                  name,
 1187                  bytes_to_bits(size),
 1188                  bytes_to_bits(align),
 1189                  encoding)
 1190          }
 1191      });
 1192  
 1193      return ty_metadata;
 1194  }
 1195  
 1196  fn pointer_type_metadata(cx: &CrateContext,
 1197                           pointer_typety::t,
 1198                           pointee_type_metadataDIType)
 1199                        -> DIType {
 1200      let pointer_llvm_type = type_of::type_of(cx, pointer_type);
 1201      let (pointer_size, pointer_align) = size_and_align_of(cx, pointer_llvm_type);
 1202      let name = ppaux::ty_to_str(cx.tcx(), pointer_type);
 1203      let ptr_metadata = name.with_c_str(|name| {
 1204          unsafe {
 1205              llvm::LLVMDIBuilderCreatePointerType(
 1206                  DIB(cx),
 1207                  pointee_type_metadata,
 1208                  bytes_to_bits(pointer_size),
 1209                  bytes_to_bits(pointer_align),
 1210                  name)
 1211          }
 1212      });
 1213      return ptr_metadata;
 1214  }
 1215  
 1216  enum MemberDescriptionFactory {
 1217      StructMD(StructMemberDescriptionFactory),
 1218      TupleMD(TupleMemberDescriptionFactory),
 1219      GeneralMD(GeneralMemberDescriptionFactory),
 1220      EnumVariantMD(EnumVariantMemberDescriptionFactory)
 1221  }
 1222  
 1223  impl MemberDescriptionFactory {
 1224      fn create_member_descriptions(&self, cx&CrateContext)
 1225                                    -> Vec<MemberDescription> {
 1226          match *self {
 1227              StructMD(ref this) => {
 1228                  this.create_member_descriptions(cx)
 1229              }
 1230              TupleMD(ref this) => {
 1231                  this.create_member_descriptions(cx)
 1232              }
 1233              GeneralMD(ref this) => {
 1234                  this.create_member_descriptions(cx)
 1235              }
 1236              EnumVariantMD(ref this) => {
 1237                  this.create_member_descriptions(cx)
 1238              }
 1239          }
 1240      }
 1241  }
 1242  
 1243  struct StructMemberDescriptionFactory {
 1244      fields: Vec<ty::field> ,
 1245      span: Span,
 1246  }
 1247  
 1248  impl StructMemberDescriptionFactory {
 1249      fn create_member_descriptions(&self, cx&CrateContext)
 1250                                    -> Vec<MemberDescription> {
 1251          self.fields.iter().map(|field| {
 1252              let name = if field.ident.name == special_idents::unnamed_field.name {
 1253                  "".to_owned()
 1254              } else {
 1255                  token::get_ident(field.ident).get().to_str()
 1256              };
 1257  
 1258              MemberDescription {
 1259                  name: name,
 1260                  llvm_type: type_of::type_of(cx, field.mt.ty),
 1261                  type_metadata: type_metadata(cx, field.mt.ty, self.span),
 1262                  offset: ComputedMemberOffset,
 1263              }
 1264          }).collect()
 1265      }
 1266  }
 1267  
 1268  fn prepare_struct_metadata(cx: &CrateContext,
 1269                             struct_typety::t,
 1270                             def_idast::DefId,
 1271                             substs: &ty::substs,
 1272                             spanSpan)
 1273                          -> RecursiveTypeDescription {
 1274      let struct_name = ppaux::ty_to_str(cx.tcx(), struct_type);
 1275      let struct_llvm_type = type_of::type_of(cx, struct_type);
 1276  
 1277      let (containing_scope, definition_span) = get_namespace_and_span_for_item(cx, def_id);
 1278  
 1279      let file_name = span_start(cx, definition_span).file.name.clone();
 1280      let file_metadata = file_metadata(cx, file_name.as_slice());
 1281  
 1282      let struct_metadata_stub = create_struct_stub(cx,
 1283                                                    struct_llvm_type,
 1284                                                    struct_name,
 1285                                                    containing_scope,
 1286                                                    file_metadata,
 1287                                                    definition_span);
 1288  
 1289      let fields = ty::struct_fields(cx.tcx(), def_id, substs);
 1290  
 1291      UnfinishedMetadata {
 1292          cache_id: cache_id_for_type(struct_type),
 1293          metadata_stub: struct_metadata_stub,
 1294          llvm_type: struct_llvm_type,
 1295          file_metadata: file_metadata,
 1296          member_description_factory: StructMD(StructMemberDescriptionFactory {
 1297              fields: fields,
 1298              span: span,
 1299          }),
 1300      }
 1301  }
 1302  
 1303  enum RecursiveTypeDescription {
 1304      UnfinishedMetadata {
 1305          cache_id: uint,
 1306          metadata_stub: DICompositeType,
 1307          llvm_type: Type,
 1308          file_metadata: DIFile,
 1309          member_description_factory: MemberDescriptionFactory,
 1310      },
 1311      FinalMetadata(DICompositeType)
 1312  }
 1313  
 1314  impl RecursiveTypeDescription {
 1315  
 1316      fn finalize(&self, cx&CrateContext) -> DICompositeType {
 1317          match *self {
 1318              FinalMetadata(metadata) => metadata,
 1319              UnfinishedMetadata {
 1320                  cache_id,
 1321                  metadata_stub,
 1322                  llvm_type,
 1323                  file_metadata,
 1324                  ref member_description_factory
 1325              } => {
 1326                  // Insert the stub into the cache in order to allow recursive references ...
 1327                  debug_context(cx).created_types.borrow_mut()
 1328                                   .insert(cache_id, metadata_stub);
 1329  
 1330                  // ... then create the member descriptions ...
 1331                  let member_descriptions = member_description_factory.create_member_descriptions(cx);
 1332  
 1333                  // ... and attach them to the stub to complete it.
 1334                  set_members_of_composite_type(cx,
 1335                                                metadata_stub,
 1336                                                llvm_type,
 1337                                                member_descriptions.as_slice(),
 1338                                                file_metadata,
 1339                                                codemap::DUMMY_SP);
 1340                  return metadata_stub;
 1341              }
 1342          }
 1343      }
 1344  }
 1345  
 1346  struct TupleMemberDescriptionFactory {
 1347      component_types: Vec<ty::t> ,
 1348      span: Span,
 1349  }
 1350  
 1351  impl TupleMemberDescriptionFactory {
 1352      fn create_member_descriptions(&self, cx&CrateContext)
 1353                                    -> Vec<MemberDescription> {
 1354          self.component_types.iter().map(|&component_type| {
 1355              MemberDescription {
 1356                  name: "".to_owned(),
 1357                  llvm_type: type_of::type_of(cx, component_type),
 1358                  type_metadata: type_metadata(cx, component_type, self.span),
 1359                  offset: ComputedMemberOffset,
 1360              }
 1361          }).collect()
 1362      }
 1363  }
 1364  
 1365  fn prepare_tuple_metadata(cx: &CrateContext,
 1366                            tuple_typety::t,
 1367                            component_types: &[ty::t],
 1368                            spanSpan)
 1369                         -> RecursiveTypeDescription {
 1370      let tuple_name = ppaux::ty_to_str(cx.tcx(), tuple_type);
 1371      let tuple_llvm_type = type_of::type_of(cx, tuple_type);
 1372  
 1373      let loc = span_start(cx, span);
 1374      let file_metadata = file_metadata(cx, loc.file.name.as_slice());
 1375  
 1376      UnfinishedMetadata {
 1377          cache_id: cache_id_for_type(tuple_type),
 1378          metadata_stub: create_struct_stub(cx,
 1379                                            tuple_llvm_type,
 1380                                            tuple_name,
 1381                                            file_metadata,
 1382                                            file_metadata,
 1383                                            span),
 1384          llvm_type: tuple_llvm_type,
 1385          file_metadata: file_metadata,
 1386          member_description_factory: TupleMD(TupleMemberDescriptionFactory {
 1387              component_types: Vec::from_slice(component_types),
 1388              span: span,
 1389          })
 1390      }
 1391  }
 1392  
 1393  struct GeneralMemberDescriptionFactory {
 1394      type_rep: Rc<adt::Repr>,
 1395      variants: Rc<Vec<Rc<ty::VariantInfo>>>,
 1396      discriminant_type_metadata: ValueRef,
 1397      containing_scope: DIScope,
 1398      file_metadata: DIFile,
 1399      span: Span,
 1400  }
 1401  
 1402  impl GeneralMemberDescriptionFactory {
 1403      fn create_member_descriptions(&self, cx&CrateContext)
 1404                                    -> Vec<MemberDescription> {
 1405          // Capture type_rep, so we don't have to copy the struct_defs array
 1406          let struct_defs = match *self.type_rep {
 1407              adt::General(_, ref struct_defs) => struct_defs,
 1408              _ => cx.sess().bug("unreachable")
 1409          };
 1410  
 1411          struct_defs
 1412              .iter()
 1413              .enumerate()
 1414              .map(|(i, struct_def)| {
 1415                  let (variant_type_metadata, variant_llvm_type, member_desc_factory) =
 1416                      describe_enum_variant(cx,
 1417                                            struct_def,
 1418                                            &**self.variants.get(i),
 1419                                            Some(self.discriminant_type_metadata),
 1420                                            self.containing_scope,
 1421                                            self.file_metadata,
 1422                                            self.span);
 1423  
 1424                  let member_descriptions =
 1425                      member_desc_factory.create_member_descriptions(cx);
 1426  
 1427                  set_members_of_composite_type(cx,
 1428                                                variant_type_metadata,
 1429                                                variant_llvm_type,
 1430                                                member_descriptions.as_slice(),
 1431                                                self.file_metadata,
 1432                                                codemap::DUMMY_SP);
 1433                  MemberDescription {
 1434                      name: "".to_owned(),
 1435                      llvm_type: variant_llvm_type,
 1436                      type_metadata: variant_type_metadata,
 1437                      offset: FixedMemberOffset { bytes: 0 },
 1438                  }
 1439          }).collect()
 1440      }
 1441  }
 1442  
 1443  struct EnumVariantMemberDescriptionFactory {
 1444      args: Vec<(~str, ty::t)> ,
 1445      discriminant_type_metadata: Option<DIType>,
 1446      span: Span,
 1447  }
 1448  
 1449  impl EnumVariantMemberDescriptionFactory {
 1450      fn create_member_descriptions(&self, cx&CrateContext)
 1451                                    -> Vec<MemberDescription> {
 1452          self.args.iter().enumerate().map(|(i, &(ref name, ty))| {
 1453              MemberDescription {
 1454                  name: name.to_str(),
 1455                  llvm_type: type_of::type_of(cx, ty),
 1456                  type_metadata: match self.discriminant_type_metadata {
 1457                      Some(metadata) if i == 0 => metadata,
 1458                      _ => type_metadata(cx, ty, self.span)
 1459                  },
 1460                  offset: ComputedMemberOffset,
 1461              }
 1462          }).collect()
 1463      }
 1464  }
 1465  
 1466  fn describe_enum_variant(cx: &CrateContext,
 1467                           struct_def: &adt::Struct,
 1468                           variant_info: &ty::VariantInfo,
 1469                           discriminant_type_metadataOption<DIType>,
 1470                           containing_scopeDIScope,
 1471                           file_metadataDIFile,
 1472                           spanSpan)
 1473                        -> (DICompositeType, Type, MemberDescriptionFactory) {
 1474      let variant_llvm_type =
 1475          Type::struct_(cx, struct_def.fields
 1476                                      .iter()
 1477                                      .map(|&t| type_of::type_of(cx, t))
 1478                                      .collect::<Vec<_>>()
 1479                                      .as_slice(),
 1480                        struct_def.packed);
 1481      // Could some consistency checks here: size, align, field count, discr type
 1482  
 1483      // Find the source code location of the variant's definition
 1484      let variant_definition_span = if variant_info.id.krate == ast::LOCAL_CRATE {
 1485          cx.tcx.map.span(variant_info.id.node)
 1486      } else {
 1487          // For definitions from other crates we have no location information available.
 1488          codemap::DUMMY_SP
 1489      };
 1490  
 1491      let metadata_stub = create_struct_stub(cx,
 1492                                             variant_llvm_type,
 1493                                             token::get_ident(variant_info.name).get(),
 1494                                             containing_scope,
 1495                                             file_metadata,
 1496                                             variant_definition_span);
 1497  
 1498      // Get the argument names from the enum variant info
 1499      let mut arg_namesVec<_> = match variant_info.arg_names {
 1500          Some(ref names) => {
 1501              names.iter().map(|ident| token::get_ident(*ident).get().to_str()).collect()
 1502          }
 1503          None => variant_info.args.iter().map(|_| "".to_owned()).collect()
 1504      };
 1505  
 1506      // If this is not a univariant enum, there is also the (unnamed) discriminant field
 1507      if discriminant_type_metadata.is_some() {
 1508          arg_names.insert(0, "".to_owned());
 1509      }
 1510  
 1511      // Build an array of (field name, field type) pairs to be captured in the factory closure.
 1512      let argsVec<(~str, ty::t)> = arg_names.iter()
 1513          .zip(struct_def.fields.iter())
 1514          .map(|(s, &t)| (s.to_str(), t))
 1515          .collect();
 1516  
 1517      let member_description_factory =
 1518          EnumVariantMD(EnumVariantMemberDescriptionFactory {
 1519              args: args,
 1520              discriminant_type_metadata: discriminant_type_metadata,
 1521              span: span,
 1522          });
 1523  
 1524      (metadata_stub, variant_llvm_type, member_description_factory)
 1525  }
 1526  
 1527  fn prepare_enum_metadata(cx: &CrateContext,
 1528                           enum_typety::t,
 1529                           enum_def_idast::DefId,
 1530                           spanSpan)
 1531                        -> RecursiveTypeDescription {
 1532      let enum_name = ppaux::ty_to_str(cx.tcx(), enum_type);
 1533  
 1534      let (containing_scope, definition_span) = get_namespace_and_span_for_item(cx, enum_def_id);
 1535      let loc = span_start(cx, definition_span);
 1536      let file_metadata = file_metadata(cx, loc.file.name.as_slice());
 1537  
 1538      // For empty enums there is an early exit. Just describe it as an empty struct with the
 1539      // appropriate type name
 1540      if ty::type_is_empty(cx.tcx(), enum_type) {
 1541          let empty_type_metadata = composite_type_metadata(cx,
 1542                                                            Type::nil(cx),
 1543                                                            enum_name,
 1544                                                            [],
 1545                                                            containing_scope,
 1546                                                            file_metadata,
 1547                                                            definition_span);
 1548  
 1549          return FinalMetadata(empty_type_metadata);
 1550      }
 1551  
 1552      let variants = ty::enum_variants(cx.tcx(), enum_def_id);
 1553  
 1554      let enumerators_metadataVec<DIDescriptor> = variants
 1555          .iter()
 1556          .map(|v| {
 1557              token::get_ident(v.name).get().with_c_str(|name| {
 1558                  unsafe {
 1559                      llvm::LLVMDIBuilderCreateEnumerator(
 1560                          DIB(cx),
 1561                          name,
 1562                          v.disr_val as c_ulonglong)
 1563                  }
 1564              })
 1565          })
 1566          .collect();
 1567  
 1568      let discriminant_type_metadata = |inttype| {
 1569          // We can reuse the type of the discriminant for all monomorphized instances of an enum
 1570          // because it doesn't depend on any type parameters. The def_id, uniquely identifying the
 1571          // enum's polytype acts as key in this cache.
 1572          let cached_discriminant_type_metadata = debug_context(cx).created_enum_disr_types
 1573                                                                   .borrow()
 1574                                                                   .find_copy(&enum_def_id);
 1575          match cached_discriminant_type_metadata {
 1576              Some(discriminant_type_metadata) => discriminant_type_metadata,
 1577              None => {
 1578                  let discriminant_llvm_type = adt::ll_inttype(cx, inttype);
 1579                  let (discriminant_size, discriminant_align) =
 1580                      size_and_align_of(cx, discriminant_llvm_type);
 1581                  let discriminant_base_type_metadata = type_metadata(cx,
 1582                                                                      adt::ty_of_inttype(inttype),
 1583                                                                      codemap::DUMMY_SP);
 1584                  let discriminant_name = get_enum_discriminant_name(cx, enum_def_id);
 1585  
 1586                  let discriminant_type_metadata = discriminant_name.get().with_c_str(|name| {
 1587                      unsafe {
 1588                          llvm::LLVMDIBuilderCreateEnumerationType(
 1589                              DIB(cx),
 1590                              containing_scope,
 1591                              name,
 1592                              file_metadata,
 1593                              loc.line as c_uint,
 1594                              bytes_to_bits(discriminant_size),
 1595                              bytes_to_bits(discriminant_align),
 1596                              create_DIArray(DIB(cx), enumerators_metadata.as_slice()),
 1597                              discriminant_base_type_metadata)
 1598                      }
 1599                  });
 1600  
 1601                  debug_context(cx).created_enum_disr_types
 1602                                   .borrow_mut()
 1603                                   .insert(enum_def_id, discriminant_type_metadata);
 1604  
 1605                  discriminant_type_metadata
 1606              }
 1607          }
 1608      };
 1609  
 1610      let type_rep = adt::represent_type(cx, enum_type);
 1611  
 1612      return match *type_rep {
 1613          adt::CEnum(inttype, _, _) => {
 1614              FinalMetadata(discriminant_type_metadata(inttype))
 1615          }
 1616          adt::Univariant(ref struct_def, _) => {
 1617              assert!(variants.len() == 1);
 1618              let (metadata_stub,
 1619                   variant_llvm_type,
 1620                   member_description_factory) =
 1621                      describe_enum_variant(cx,
 1622                                            struct_def,
 1623                                            &**variants.get(0),
 1624                                            None,
 1625                                            containing_scope,
 1626                                            file_metadata,
 1627                                            span);
 1628              UnfinishedMetadata {
 1629                  cache_id: cache_id_for_type(enum_type),
 1630                  metadata_stub: metadata_stub,
 1631                  llvm_type: variant_llvm_type,
 1632                  file_metadata: file_metadata,
 1633                  member_description_factory: member_description_factory
 1634              }
 1635          }
 1636          adt::General(inttype, _) => {
 1637              let discriminant_type_metadata = discriminant_type_metadata(inttype);
 1638              let enum_llvm_type = type_of::type_of(cx, enum_type);
 1639              let (enum_type_size, enum_type_align) = size_and_align_of(cx, enum_llvm_type);
 1640              let unique_id = generate_unique_type_id("DI_ENUM_");
 1641  
 1642              let enum_metadata = enum_name.with_c_str(|enum_name| {
 1643                  unique_id.with_c_str(|unique_id| {
 1644                      unsafe {
 1645                          llvm::LLVMDIBuilderCreateUnionType(
 1646                          DIB(cx),
 1647                          containing_scope,
 1648                          enum_name,
 1649                          file_metadata,
 1650                          loc.line as c_uint,
 1651                          bytes_to_bits(enum_type_size),
 1652                          bytes_to_bits(enum_type_align),
 1653                          0, // Flags
 1654                          ptr::null(),
 1655                          0, // RuntimeLang
 1656                          unique_id)
 1657                      }
 1658                  })
 1659              });
 1660  
 1661              UnfinishedMetadata {
 1662                  cache_id: cache_id_for_type(enum_type),
 1663                  metadata_stub: enum_metadata,
 1664                  llvm_type: enum_llvm_type,
 1665                  file_metadata: file_metadata,
 1666                  member_description_factory: GeneralMD(GeneralMemberDescriptionFactory {
 1667                      type_rep: type_rep.clone(),
 1668                      variants: variants,
 1669                      discriminant_type_metadata: discriminant_type_metadata,
 1670                      containing_scope: containing_scope,
 1671                      file_metadata: file_metadata,
 1672                      span: span,
 1673                  }),
 1674              }
 1675          }
 1676          adt::NullablePointer { nonnull: ref struct_def, nndiscr, .. } => {
 1677              let (metadata_stub,
 1678                   variant_llvm_type,
 1679                   member_description_factory) =
 1680                      describe_enum_variant(cx,
 1681                                            struct_def,
 1682                                            &**variants.get(nndiscr as uint),
 1683                                            None,
 1684                                            containing_scope,
 1685                                            file_metadata,
 1686                                            span);
 1687              UnfinishedMetadata {
 1688                  cache_id: cache_id_for_type(enum_type),
 1689                  metadata_stub: metadata_stub,
 1690                  llvm_type: variant_llvm_type,
 1691                  file_metadata: file_metadata,
 1692                  member_description_factory: member_description_factory
 1693              }
 1694          }
 1695      };
 1696  
 1697      fn get_enum_discriminant_name(cx: &CrateContext, def_idast::DefId) -> token::InternedString {
 1698          let name = if def_id.krate == ast::LOCAL_CRATE {
 1699              cx.tcx.map.get_path_elem(def_id.node).name()
 1700          } else {
 1701              csearch::get_item_path(&cx.tcx, def_id).last().unwrap().name()
 1702          };
 1703  
 1704          token::get_name(name)
 1705      }
 1706  }
 1707  
 1708  enum MemberOffset {
 1709      FixedMemberOffset { bytes: uint },
 1710      // For ComputedMemberOffset, the offset is read from the llvm type definition
 1711      ComputedMemberOffset
 1712  }
 1713  
 1714  struct MemberDescription {
 1715      name: ~str,
 1716      llvm_type: Type,
 1717      type_metadata: DIType,
 1718      offset: MemberOffset,
 1719  }
 1720  
 1721  /// Creates debug information for a composite type, that is, anything that results in a LLVM struct.
 1722  ///
 1723  /// Examples of Rust types to use this are: structs, tuples, boxes, vecs, and enums.
 1724  fn composite_type_metadata(cx: &CrateContext,
 1725                             composite_llvm_typeType,
 1726                             composite_type_name: &str,
 1727                             member_descriptions: &[MemberDescription],
 1728                             containing_scopeDIScope,
 1729                             file_metadataDIFile,
 1730                             definition_spanSpan)
 1731                          -> DICompositeType {
 1732      // Create the (empty) struct metadata node ...
 1733      let composite_type_metadata = create_struct_stub(cx,
 1734                                                       composite_llvm_type,
 1735                                                       composite_type_name,
 1736                                                       containing_scope,
 1737                                                       file_metadata,
 1738                                                       definition_span);
 1739  
 1740      // ... and immediately create and add the member descriptions.
 1741      set_members_of_composite_type(cx,
 1742                                    composite_type_metadata,
 1743                                    composite_llvm_type,
 1744                                    member_descriptions,
 1745                                    file_metadata,
 1746                                    definition_span);
 1747  
 1748      return composite_type_metadata;
 1749  }
 1750  
 1751  fn set_members_of_composite_type(cx: &CrateContext,
 1752                                   composite_type_metadataDICompositeType,
 1753                                   composite_llvm_typeType,
 1754                                   member_descriptions: &[MemberDescription],
 1755                                   file_metadataDIFile,
 1756                                   definition_spanSpan) {
 1757      // In some rare cases LLVM metadata uniquing would lead to an existing type description being
 1758      // used instead of a new one created in create_struct_stub. This would cause a hard to trace
 1759      // assertion in DICompositeType::SetTypeArray(). The following check makes sure that we get a
 1760      // better error message if this should happen again due to some regression.
 1761      {
 1762          let mut composite_types_completed =
 1763              debug_context(cx).composite_types_completed.borrow_mut();
 1764          if composite_types_completed.contains(&composite_type_metadata) {
 1765              cx.sess().span_bug(definition_span, "debuginfo::set_members_of_composite_type() - \
 1766                                                   Already completed forward declaration \
 1767                                                   re-encountered.");
 1768          } else {
 1769              composite_types_completed.insert(composite_type_metadata);
 1770          }
 1771      }
 1772  
 1773      let loc = span_start(cx, definition_span);
 1774  
 1775      let member_metadataVec<DIDescriptor> = member_descriptions
 1776          .iter()
 1777          .enumerate()
 1778          .map(|(i, member_description)| {
 1779              let (member_size, member_align) = size_and_align_of(cx, member_description.llvm_type);
 1780              let member_offset = match member_description.offset {
 1781                  FixedMemberOffset { bytes } => bytes as u64,
 1782                  ComputedMemberOffset => machine::llelement_offset(cx, composite_llvm_type, i)
 1783              };
 1784  
 1785              member_description.name.with_c_str(|member_name| {
 1786                  unsafe {
 1787                      llvm::LLVMDIBuilderCreateMemberType(
 1788                          DIB(cx),
 1789                          composite_type_metadata,
 1790                          member_name,
 1791                          file_metadata,
 1792                          loc.line as c_uint,
 1793                          bytes_to_bits(member_size),
 1794                          bytes_to_bits(member_align),
 1795                          bytes_to_bits(member_offset),
 1796                          0,
 1797                          member_description.type_metadata)
 1798                  }
 1799              })
 1800          })
 1801          .collect();
 1802  
 1803      unsafe {
 1804          let type_array = create_DIArray(DIB(cx), member_metadata.as_slice());
 1805          llvm::LLVMDICompositeTypeSetTypeArray(composite_type_metadata, type_array);
 1806      }
 1807  }
 1808  
 1809  // A convenience wrapper around LLVMDIBuilderCreateStructType(). Does not do any caching, does not
 1810  // add any fields to the struct. This can be done later with set_members_of_composite_type().
 1811  fn create_struct_stub(cx: &CrateContext,
 1812                        struct_llvm_typeType,
 1813                        struct_type_name: &str,
 1814                        containing_scopeDIScope,
 1815                        file_metadataDIFile,
 1816                        definition_spanSpan)
 1817                     -> DICompositeType {
 1818      let loc = span_start(cx, definition_span);
 1819      let (struct_size, struct_align) = size_and_align_of(cx, struct_llvm_type);
 1820  
 1821      // We assign unique IDs to the type stubs so LLVM metadata uniquing does not reuse instances
 1822      // where we don't want it.
 1823      let unique_id = generate_unique_type_id("DI_STRUCT_");
 1824  
 1825      return unsafe {
 1826          struct_type_name.with_c_str(|name| {
 1827              unique_id.with_c_str(|unique_id| {
 1828                  // LLVMDIBuilderCreateStructType() wants an empty array. A null pointer will lead to
 1829                  // hard to trace and debug LLVM assertions later on in llvm/lib/IR/Value.cpp
 1830                  let empty_array = create_DIArray(DIB(cx), []);
 1831  
 1832                  llvm::LLVMDIBuilderCreateStructType(
 1833                      DIB(cx),
 1834                      containing_scope,
 1835                      name,
 1836                      file_metadata,
 1837                      loc.line as c_uint,
 1838                      bytes_to_bits(struct_size),
 1839                      bytes_to_bits(struct_align),
 1840                      0,
 1841                      ptr::null(),
 1842                      empty_array,
 1843                      0,
 1844                      ptr::null(),
 1845                      unique_id)
 1846              })
 1847          })
 1848      };
 1849  }
 1850  
 1851  fn boxed_type_metadata(cx: &CrateContext,
 1852                         content_type_nameOption<&str>,
 1853                         content_llvm_typeType,
 1854                         content_type_metadataDIType,
 1855                         spanSpan)
 1856                      -> DICompositeType {
 1857      let box_type_name = match content_type_name {
 1858          Some(content_type_name) => format!("Boxed<{}>", content_type_name),
 1859          None                    => "BoxedType".to_owned()
 1860      };
 1861  
 1862      let box_llvm_type = Type::at_box(cx, content_llvm_type);
 1863      let member_llvm_types = box_llvm_type.field_types();
 1864      assert!(box_layout_is_correct(cx,
 1865                                    member_llvm_types.as_slice(),
 1866                                    content_llvm_type));
 1867  
 1868      let int_type = ty::mk_int();
 1869      let nil_pointer_type = ty::mk_nil_ptr(cx.tcx());
 1870      let nil_pointer_type_metadata = type_metadata(cx, nil_pointer_type, codemap::DUMMY_SP);
 1871  
 1872      let member_descriptions = [
 1873          MemberDescription {
 1874              name: "refcnt".to_owned(),
 1875              llvm_type: *member_llvm_types.get(0),
 1876              type_metadata: type_metadata(cx, int_type, codemap::DUMMY_SP),
 1877              offset: ComputedMemberOffset,
 1878          },
 1879          MemberDescription {
 1880              name: "drop_glue".to_owned(),
 1881              llvm_type: *member_llvm_types.get(1),
 1882              type_metadata: nil_pointer_type_metadata,
 1883              offset: ComputedMemberOffset,
 1884          },
 1885          MemberDescription {
 1886              name: "prev".to_owned(),
 1887              llvm_type: *member_llvm_types.get(2),
 1888              type_metadata: nil_pointer_type_metadata,
 1889              offset: ComputedMemberOffset,
 1890          },
 1891          MemberDescription {
 1892              name: "next".to_owned(),
 1893              llvm_type: *member_llvm_types.get(3),
 1894              type_metadata: nil_pointer_type_metadata,
 1895              offset: ComputedMemberOffset,
 1896          },
 1897          MemberDescription {
 1898              name: "val".to_owned(),
 1899              llvm_type: *member_llvm_types.get(4),
 1900              type_metadata: content_type_metadata,
 1901              offset: ComputedMemberOffset,
 1902          }
 1903      ];
 1904  
 1905      let loc = span_start(cx, span);
 1906      let file_metadata = file_metadata(cx, loc.file.name.as_slice());
 1907  
 1908      return composite_type_metadata(
 1909          cx,
 1910          box_llvm_type,
 1911          box_type_name,
 1912          member_descriptions,
 1913          file_metadata,
 1914          file_metadata,
 1915          span);
 1916  
 1917      // Unfortunately, we cannot assert anything but the correct types here---and not whether the
 1918      // 'next' and 'prev' pointers are in the correct order.
 1919      fn box_layout_is_correct(cx&CrateContext,
 1920                               member_llvm_types&[Type],
 1921                               content_llvm_typeType)
 1922                            -> bool {
 1923          member_llvm_types.len() == 5 &&
 1924          member_llvm_types[0] == cx.int_type &&
 1925          member_llvm_types[1] == Type::generic_glue_fn(cx).ptr_to() &&
 1926          member_llvm_types[2] == Type::i8(cx).ptr_to() &&
 1927          member_llvm_types[3] == Type::i8(cx).ptr_to() &&
 1928          member_llvm_types[4] == content_llvm_type
 1929      }
 1930  }
 1931  
 1932  fn fixed_vec_metadata(cx: &CrateContext,
 1933                        element_typety::t,
 1934                        len: uint,
 1935                        spanSpan)
 1936                     -> DIType {
 1937      let element_type_metadata = type_metadata(cx, element_type, span);
 1938      let element_llvm_type = type_of::type_of(cx, element_type);
 1939      let (element_type_size, element_type_align) = size_and_align_of(cx, element_llvm_type);
 1940  
 1941      let subrange = unsafe {
 1942          llvm::LLVMDIBuilderGetOrCreateSubrange(
 1943          DIB(cx),
 1944          0,
 1945          len as c_longlong)
 1946      };
 1947  
 1948      let subscripts = create_DIArray(DIB(cx), [subrange]);
 1949      return unsafe {
 1950          llvm::LLVMDIBuilderCreateArrayType(
 1951              DIB(cx),
 1952              bytes_to_bits(element_type_size * (len as u64)),
 1953              bytes_to_bits(element_type_align),
 1954              element_type_metadata,
 1955              subscripts)
 1956      };
 1957  }
 1958  
 1959  fn vec_metadata(cx: &CrateContext,
 1960                  element_typety::t,
 1961                  spanSpan)
 1962               -> DICompositeType {
 1963  
 1964      let element_type_metadata = type_metadata(cx, element_type, span);
 1965      let element_llvm_type = type_of::type_of(cx, element_type);
 1966      let (element_size, element_align) = size_and_align_of(cx, element_llvm_type);
 1967  
 1968      let vec_llvm_type = Type::vec(cx, &element_llvm_type);
 1969      let vec_type_name&str = format!("[{}]", ppaux::ty_to_str(cx.tcx(), element_type));
 1970  
 1971      let member_llvm_types = vec_llvm_type.field_types();
 1972  
 1973      let int_type_metadata = type_metadata(cx, ty::mk_int(), span);
 1974      let array_type_metadata = unsafe {
 1975          llvm::LLVMDIBuilderCreateArrayType(
 1976              DIB(cx),
 1977              bytes_to_bits(element_size),
 1978              bytes_to_bits(element_align),
 1979              element_type_metadata,
 1980              create_DIArray(DIB(cx), [llvm::LLVMDIBuilderGetOrCreateSubrange(DIB(cx), 0, 0)]))
 1981      };
 1982  
 1983      let member_descriptions = [
 1984          MemberDescription {
 1985              name: "fill".to_owned(),
 1986              llvm_type: *member_llvm_types.get(0),
 1987              type_metadata: int_type_metadata,
 1988              offset: ComputedMemberOffset,
 1989          },
 1990          MemberDescription {
 1991              name: "alloc".to_owned(),
 1992              llvm_type: *member_llvm_types.get(1),
 1993              type_metadata: int_type_metadata,
 1994              offset: ComputedMemberOffset,
 1995          },
 1996          MemberDescription {
 1997              name: "elements".to_owned(),
 1998              llvm_type: *member_llvm_types.get(2),
 1999              type_metadata: array_type_metadata,
 2000              offset: ComputedMemberOffset,
 2001          }
 2002      ];
 2003  
 2004      assert!(member_descriptions.len() == member_llvm_types.len());
 2005  
 2006      let loc = span_start(cx, span);
 2007      let file_metadata = file_metadata(cx, loc.file.name.as_slice());
 2008  
 2009      composite_type_metadata(
 2010          cx,
 2011          vec_llvm_type,
 2012          vec_type_name,
 2013          member_descriptions,
 2014          file_metadata,
 2015          file_metadata,
 2016          span)
 2017  }
 2018  
 2019  fn vec_slice_metadata(cx: &CrateContext,
 2020                        vec_typety::t,
 2021                        element_typety::t,
 2022                        spanSpan)
 2023                     -> DICompositeType {
 2024  
 2025      debug!("vec_slice_metadata: {:?}", ty::get(vec_type));
 2026  
 2027      let slice_llvm_type = type_of::type_of(cx, vec_type);
 2028      let slice_type_name = ppaux::ty_to_str(cx.tcx(), vec_type);
 2029  
 2030      let member_llvm_types = slice_llvm_type.field_types();
 2031      assert!(slice_layout_is_correct(cx,
 2032                                      member_llvm_types.as_slice(),
 2033                                      element_type));
 2034  
 2035      let data_ptr_type = ty::mk_ptr(cx.tcx(), ty::mt {
 2036          ty: element_type,
 2037          mutbl: ast::MutImmutable
 2038      });
 2039  
 2040      let member_descriptions = [
 2041          MemberDescription {
 2042              name: "data_ptr".to_owned(),
 2043              llvm_type: *member_llvm_types.get(0),
 2044              type_metadata: type_metadata(cx, data_ptr_type, span),
 2045              offset: ComputedMemberOffset,
 2046          },
 2047          MemberDescription {
 2048              name: "length".to_owned(),
 2049              llvm_type: *member_llvm_types.get(1),
 2050              type_metadata: type_metadata(cx, ty::mk_uint(), span),
 2051              offset: ComputedMemberOffset,
 2052          },
 2053      ];
 2054  
 2055      assert!(member_descriptions.len() == member_llvm_types.len());
 2056  
 2057      let loc = span_start(cx, span);
 2058      let file_metadata = file_metadata(cx, loc.file.name.as_slice());
 2059  
 2060      return composite_type_metadata(
 2061          cx,
 2062          slice_llvm_type,
 2063          slice_type_name,
 2064          member_descriptions,
 2065          file_metadata,
 2066          file_metadata,
 2067          span);
 2068  
 2069      fn slice_layout_is_correct(cx: &CrateContext,
 2070                                 member_llvm_types: &[Type],
 2071                                 element_typety::t)
 2072                              -> bool {
 2073          member_llvm_types.len() == 2 &&
 2074          member_llvm_types[0] == type_of::type_of(cx, element_type).ptr_to() &&
 2075          member_llvm_types[1] == cx.int_type
 2076      }
 2077  }
 2078  
 2079  fn subroutine_type_metadata(cx: &CrateContext,
 2080                              signature: &ty::FnSig,
 2081                              spanSpan)
 2082                           -> DICompositeType {
 2083      let loc = span_start(cx, span);
 2084      let file_metadata = file_metadata(cx, loc.file.name.as_slice());
 2085  
 2086      let mut signature_metadataVec<DIType> =
 2087          Vec::with_capacity(signature.inputs.len() + 1);
 2088  
 2089      // return type
 2090      signature_metadata.push(match ty::get(signature.output).sty {
 2091          ty::ty_nil => ptr::null(),
 2092          _ => type_metadata(cx, signature.output, span)
 2093      });
 2094  
 2095      // regular arguments
 2096      for &argument_type in signature.inputs.iter() {
 2097          signature_metadata.push(type_metadata(cx, argument_type, span));
 2098      }
 2099  
 2100      return unsafe {
 2101          llvm::LLVMDIBuilderCreateSubroutineType(
 2102              DIB(cx),
 2103              file_metadata,
 2104              create_DIArray(DIB(cx), signature_metadata.as_slice()))
 2105      };
 2106  }
 2107  
 2108  fn trait_metadata(cx: &CrateContext,
 2109                    def_idast::DefId,
 2110                    trait_typety::t,
 2111                    substs: &ty::substs,
 2112                    trait_storety::TraitStore,
 2113                    _: &ty::BuiltinBounds)
 2114                 -> DIType {
 2115      // The implementation provided here is a stub. It makes sure that the trait type is
 2116      // assigned the correct name, size, namespace, and source location. But it does not describe
 2117      // the trait's methods.
 2118      let last = ty::with_path(cx.tcx(), def_id, |mut path| path.last().unwrap());
 2119      let ident_string = token::get_name(last.name());
 2120      let name = ppaux::trait_store_to_str(cx.tcx(), trait_store) +
 2121                 ident_string.get();
 2122      // Add type and region parameters
 2123      let name = ppaux::parameterized(cx.tcx(), name, &substs.regions,
 2124                                      substs.tps.as_slice(), def_id, true);
 2125  
 2126      let (containing_scope, definition_span) = get_namespace_and_span_for_item(cx, def_id);
 2127  
 2128      let file_name = span_start(cx, definition_span).file.name.clone();
 2129      let file_metadata = file_metadata(cx, file_name.as_slice());
 2130  
 2131      let trait_llvm_type = type_of::type_of(cx, trait_type);
 2132  
 2133      composite_type_metadata(cx,
 2134                              trait_llvm_type,
 2135                              name,
 2136                              [],
 2137                              containing_scope,
 2138                              file_metadata,
 2139                              definition_span)
 2140  }
 2141  
 2142  fn type_metadata(cx: &CrateContext,
 2143                   tty::t,
 2144                   usage_site_spanSpan)
 2145                -> DIType {
 2146      let cache_id = cache_id_for_type(t);
 2147  
 2148      match debug_context(cx).created_types.borrow().find(&cache_id) {
 2149          Some(type_metadata) => return *type_metadata,
 2150          None => ()
 2151      }
 2152  
 2153      fn create_pointer_to_box_metadata(cx&CrateContext,
 2154                                        pointer_typety::t,
 2155                                        type_in_boxty::t)
 2156                                     -> DIType {
 2157          let content_type_name&str = ppaux::ty_to_str(cx.tcx(), type_in_box);
 2158          let content_llvm_type = type_of::type_of(cx, type_in_box);
 2159          let content_type_metadata = type_metadata(
 2160              cx,
 2161              type_in_box,
 2162              codemap::DUMMY_SP);
 2163  
 2164          let box_metadata = boxed_type_metadata(
 2165              cx,
 2166              Some(content_type_name),
 2167              content_llvm_type,
 2168              content_type_metadata,
 2169              codemap::DUMMY_SP);
 2170  
 2171          pointer_type_metadata(cx, pointer_type, box_metadata)
 2172      }
 2173  
 2174      debug!("type_metadata: {:?}", ty::get(t));
 2175  
 2176      let sty = &ty::get(t).sty;
 2177      let type_metadata = match *sty {
 2178          ty::ty_nil      |
 2179          ty::ty_bot      |
 2180          ty::ty_bool     |
 2181          ty::ty_char     |
 2182          ty::ty_int(_)   |
 2183          ty::ty_uint(_)  |
 2184          ty::ty_float(_) => {
 2185              basic_type_metadata(cx, t)
 2186          }
 2187          ty::ty_enum(def_id, _) => {
 2188              prepare_enum_metadata(cx, t, def_id, usage_site_span).finalize(cx)
 2189          }
 2190          ty::ty_box(typ) => {
 2191              create_pointer_to_box_metadata(cx, t, typ)
 2192          }
 2193          ty::ty_vec(ref mt, Some(len)) => fixed_vec_metadata(cx, mt.ty, len, usage_site_span),
 2194          ty::ty_uniq(typ) => {
 2195              match ty::get(typ).sty {
 2196                  ty::ty_vec(ref mt, None) => {
 2197                      let vec_metadata = vec_metadata(cx, mt.ty, usage_site_span);
 2198                      pointer_type_metadata(cx, t, vec_metadata)
 2199                  }
 2200                  ty::ty_str => {
 2201                      let i8_t = ty::mk_i8();
 2202                      let vec_metadata = vec_metadata(cx, i8_t, usage_site_span);
 2203                      pointer_type_metadata(cx, t, vec_metadata)
 2204                  }
 2205                  _ => {
 2206                      let pointee = type_metadata(cx, typ, usage_site_span);
 2207                      pointer_type_metadata(cx, t, pointee)
 2208                  }
 2209              }
 2210          }
 2211          ty::ty_ptr(ref mt) | ty::ty_rptr(_, ref mt) => {
 2212              match ty::get(mt.ty).sty {
 2213                  ty::ty_vec(ref mt, None) => vec_slice_metadata(cx, t, mt.ty, usage_site_span),
 2214                  ty::ty_str => {
 2215                      let i8_t = ty::mk_i8();
 2216                      vec_slice_metadata(cx, t, i8_t, usage_site_span)
 2217                  }
 2218                  _ => {
 2219                      let pointee = type_metadata(cx, mt.ty, usage_site_span);
 2220                      pointer_type_metadata(cx, t, pointee)
 2221                  }
 2222              }
 2223          }
 2224          ty::ty_bare_fn(ref barefnty) => {
 2225              subroutine_type_metadata(cx, &barefnty.sig, usage_site_span)
 2226          }
 2227          ty::ty_closure(ref closurety) => {
 2228              subroutine_type_metadata(cx, &closurety.sig, usage_site_span)
 2229          }
 2230          ty::ty_trait(box ty::TyTrait {
 2231                  def_id,
 2232                  ref substs,
 2233                  store,
 2234                  ref bounds
 2235              }) => {
 2236              trait_metadata(cx, def_id, t, substs, store, bounds)
 2237          }
 2238          ty::ty_struct(def_id, ref substs) => {
 2239              if ty::type_is_simd(cx.tcx(), t) {
 2240                  let element_type = ty::simd_type(cx.tcx(), t);
 2241                  let len = ty::simd_size(cx.tcx(), t);
 2242                  fixed_vec_metadata(cx, element_type, len, usage_site_span)
 2243              } else {
 2244                  prepare_struct_metadata(cx, t, def_id, substs, usage_site_span).finalize(cx)
 2245              }
 2246          }
 2247          ty::ty_tup(ref elements) => {
 2248              prepare_tuple_metadata(cx,
 2249                                     t,
 2250                                     elements.as_slice(),
 2251                                     usage_site_span).finalize(cx)
 2252          }
 2253          _ => cx.sess().bug(format!("debuginfo: unexpected type in type_metadata: {:?}", sty))
 2254      };
 2255  
 2256      debug_context(cx).created_types.borrow_mut().insert(cache_id, type_metadata);
 2257      type_metadata
 2258  }
 2259  
 2260  #[deriving(Eq)]
 2261  enum DebugLocation {
 2262      KnownLocation { scope: DIScope, line: uint, col: uint },
 2263      UnknownLocation
 2264  }
 2265  
 2266  impl DebugLocation {
 2267      fn new(scopeDIScope, lineuint, coluint) -> DebugLocation {
 2268          KnownLocation {
 2269              scope: scope,
 2270              line: line,
 2271              col: col,
 2272          }
 2273      }
 2274  }
 2275  
 2276  fn set_debug_location(cx: &CrateContext, debug_locationDebugLocation) {
 2277      if debug_location == debug_context(cx).current_debug_location.get() {
 2278          return;
 2279      }
 2280  
 2281      let metadata_node;
 2282  
 2283      match debug_location {
 2284          KnownLocation { scope, line, .. } => {
 2285              let col = 0; // Always set the column to zero like Clang and GCC
 2286              debug!("setting debug location to {} {}", line, col);
 2287              let elements = [C_i32(cx, line as i32), C_i32(cx, col as i32), scope, ptr::null()];
 2288              unsafe {
 2289                  metadata_node = llvm::LLVMMDNodeInContext(debug_context(cx).llcontext,
 2290                                                            elements.as_ptr(),
 2291                                                            elements.len() as c_uint);
 2292              }
 2293          }
 2294          UnknownLocation => {
 2295              debug!("clearing debug location ");
 2296              metadata_node = ptr::null();
 2297          }
 2298      };
 2299  
 2300      unsafe {
 2301          llvm::LLVMSetCurrentDebugLocation(cx.builder.b, metadata_node);
 2302      }
 2303  
 2304      debug_context(cx).current_debug_location.set(debug_location);
 2305  }
 2306  
 2307  //=-------------------------------------------------------------------------------------------------
 2308  //  Utility Functions
 2309  //=-------------------------------------------------------------------------------------------------
 2310  
 2311  fn cache_id_for_type(tty::t) -> uint {
 2312      ty::type_id(t)
 2313  }
 2314  
 2315  // Used to avoid LLVM metadata uniquing problems. See `create_struct_stub()` and
 2316  // `prepare_enum_metadata()`.
 2317  fn generate_unique_type_id(prefix: &'static str) -> ~str {
 2318      unsafe {
 2319          static mut unique_id_counter: atomics::AtomicUint = atomics::INIT_ATOMIC_UINT;
 2320          format!("{}{}", prefix, unique_id_counter.fetch_add(1, atomics::SeqCst))
 2321      }
 2322  }
 2323  
 2324  /// Return codemap::Loc corresponding to the beginning of the span
 2325  fn span_start(cx: &CrateContext, spanSpan) -> codemap::Loc {
 2326      cx.sess().codemap().lookup_char_pos(span.lo)
 2327  }
 2328  
 2329  fn size_and_align_of(cx: &CrateContext, llvm_typeType) -> (u64, u64) {
 2330      (machine::llsize_of_alloc(cx, llvm_type), machine::llalign_of_min(cx, llvm_type))
 2331  }
 2332  
 2333  fn bytes_to_bits(bytes: u64) -> c_ulonglong {
 2334      (bytes * 8) as c_ulonglong
 2335  }
 2336  
 2337  #[inline]
 2338  fn debug_context<'a>(cx: &'a CrateContext) -> &'a CrateDebugContext {
 2339      let debug_context&'a CrateDebugContext = cx.dbg_cx.get_ref();
 2340      debug_context
 2341  }
 2342  
 2343  #[inline]
 2344  fn DIB(cx: &CrateContext) -> DIBuilderRef {
 2345      cx.dbg_cx.get_ref().builder
 2346  }
 2347  
 2348  fn fn_should_be_ignored(fcx: &FunctionContext) -> bool {
 2349      match fcx.debug_context.repr {
 2350          FunctionDebugContext(_) => false,
 2351          _ => true
 2352      }
 2353  }
 2354  
 2355  fn assert_type_for_node_id(cx: &CrateContext, node_idast::NodeId, error_spanSpan) {
 2356      if !cx.tcx.node_types.borrow().contains_key(&(node_id as uint)) {
 2357          cx.sess().span_bug(error_span, "debuginfo: Could not find type for node id!");
 2358      }
 2359  }
 2360  
 2361  fn get_namespace_and_span_for_item(cx: &CrateContext, def_idast::DefId)
 2362                                     -> (DIScope, Span) {
 2363      let containing_scope = namespace_for_item(cx, def_id).scope;
 2364      let definition_span = if def_id.krate == ast::LOCAL_CRATE {
 2365          cx.tcx.map.span(def_id.node)
 2366      } else {
 2367          // For external items there is no span information
 2368          codemap::DUMMY_SP
 2369      };
 2370  
 2371      (containing_scope, definition_span)
 2372  }
 2373  
 2374  // This procedure builds the *scope map* for a given function, which maps any given ast::NodeId in
 2375  // the function's AST to the correct DIScope metadata instance.
 2376  //
 2377  // This builder procedure walks the AST in execution order and keeps track of what belongs to which
 2378  // scope, creating DIScope DIEs along the way, and introducing *artificial* lexical scope
 2379  // descriptors where necessary. These artificial scopes allow GDB to correctly handle name
 2380  // shadowing.
 2381  fn populate_scope_map(cx: &CrateContext,
 2382                        arg_pats: &[@ast::Pat],
 2383                        fn_entry_block: &ast::Block,
 2384                        fn_metadataDISubprogram,
 2385                        scope_map: &mut HashMap<ast::NodeId, DIScope>) {
 2386      let def_map = &cx.tcx.def_map;
 2387  
 2388      struct ScopeStackEntry {
 2389          scope_metadata: DIScope,
 2390          ident: Option<ast::Ident>
 2391      }
 2392  
 2393      let mut scope_stack = vec!(ScopeStackEntry { scope_metadata: fn_metadata, ident: None });
 2394  
 2395      // Push argument identifiers onto the stack so arguments integrate nicely with variable
 2396      // shadowing.
 2397      for &arg_pat in arg_pats.iter() {
 2398          pat_util::pat_bindings(def_map, arg_pat, |_, _, _, path_ref| {
 2399              let ident = ast_util::path_to_ident(path_ref);
 2400              scope_stack.push(ScopeStackEntry { scope_metadata: fn_metadata, ident: Some(ident) });
 2401          })
 2402      }
 2403  
 2404      // Clang creates a separate scope for function bodies, so let's do this too
 2405      with_new_scope(cx,
 2406                     fn_entry_block.span,
 2407                     &mut scope_stack,
 2408                     scope_map,
 2409                     |cx, scope_stack, scope_map| {
 2410          walk_block(cx, fn_entry_block, scope_stack, scope_map);
 2411      });
 2412  
 2413      // local helper functions for walking the AST.
 2414      fn with_new_scope(cx&CrateContext,
 2415                        scope_spanSpan,
 2416                        scope_stack&mut Vec<ScopeStackEntry> ,
 2417                        scope_map: &mut HashMap<ast::NodeId, DIScope>,
 2418                        inner_walk|&CrateContext,
 2419                                     &mut Vec<ScopeStackEntry> ,
 2420                                     &mut HashMap<ast::NodeId, DIScope>|) {
 2421          // Create a new lexical scope and push it onto the stack
 2422          let loc = cx.sess().codemap().lookup_char_pos(scope_span.lo);
 2423          let file_metadata = file_metadata(cx, loc.file.name.as_slice());
 2424          let parent_scope = scope_stack.last().unwrap().scope_metadata;
 2425  
 2426          let scope_metadata = unsafe {
 2427              llvm::LLVMDIBuilderCreateLexicalBlock(
 2428                  DIB(cx),
 2429                  parent_scope,
 2430                  file_metadata,
 2431                  loc.line as c_uint,
 2432                  loc.col.to_uint() as c_uint,
 2433                  0)
 2434          };
 2435  
 2436          scope_stack.push(ScopeStackEntry { scope_metadata: scope_metadata, ident: None });
 2437  
 2438          inner_walk(cx, scope_stack, scope_map);
 2439  
 2440          // pop artificial scopes
 2441          while scope_stack.last().unwrap().ident.is_some() {
 2442              scope_stack.pop();
 2443          }
 2444  
 2445          if scope_stack.last().unwrap().scope_metadata != scope_metadata {
 2446              cx.sess().span_bug(scope_span, "debuginfo: Inconsistency in scope management.");
 2447          }
 2448  
 2449          scope_stack.pop();
 2450      }
 2451  
 2452      fn walk_block(cx&CrateContext,
 2453                    block&ast::Block,
 2454                    scope_stack&mut Vec<ScopeStackEntry> ,
 2455                    scope_map&mut HashMap<ast::NodeId, DIScope>) {
 2456          scope_map.insert(block.id, scope_stack.last().unwrap().scope_metadata);
 2457  
 2458          // The interesting things here are statements and the concluding expression.
 2459          for statement in block.stmts.iter() {
 2460              scope_map.insert(ast_util::stmt_id(*statement),
 2461                               scope_stack.last().unwrap().scope_metadata);
 2462  
 2463              match statement.node {
 2464                  ast::StmtDecl(decl, _) => walk_decl(cx, decl, scope_stack, scope_map),
 2465                  ast::StmtExpr(exp, _) |
 2466                  ast::StmtSemi(exp, _) => walk_expr(cx, exp, scope_stack, scope_map),
 2467                  ast::StmtMac(..) => () // ignore macros (which should be expanded anyway)
 2468              }
 2469          }
 2470  
 2471          for exp in block.expr.iter() {
 2472              walk_expr(cx, *exp, scope_stack, scope_map);
 2473          }
 2474      }
 2475  
 2476      fn walk_decl(cx&CrateContext,
 2477                   decl&ast::Decl,
 2478                   scope_stack&mut Vec<ScopeStackEntry> ,
 2479                   scope_map&mut HashMap<ast::NodeId, DIScope>) {
 2480          match *decl {
 2481              codemap::Spanned { node: ast::DeclLocal(local), .. } => {
 2482                  scope_map.insert(local.id, scope_stack.last().unwrap().scope_metadata);
 2483  
 2484                  walk_pattern(cx, local.pat, scope_stack, scope_map);
 2485  
 2486                  for exp in local.init.iter() {
 2487                      walk_expr(cx, *exp, scope_stack, scope_map);
 2488                  }
 2489              }
 2490              _ => ()
 2491          }
 2492      }
 2493  
 2494      fn walk_pattern(cx&CrateContext,
 2495                      pat: @ast::Pat,
 2496                      scope_stack: &mut Vec<ScopeStackEntry> ,
 2497                      scope_map: &mut HashMap<ast::NodeId, DIScope>) {
 2498  
 2499          let def_map = &cx.tcx.def_map;
 2500  
 2501          // Unfortunately, we cannot just use pat_util::pat_bindings() or ast_util::walk_pat() here
 2502          // because we have to visit *all* nodes in order to put them into the scope map. The above
 2503          // functions don't do that.
 2504          match pat.node {
 2505              ast::PatIdent(_, ref path_ref, ref sub_pat_opt) => {
 2506  
 2507                  // Check if this is a binding. If so we need to put it on the scope stack and maybe
 2508                  // introduce an artificial scope
 2509                  if pat_util::pat_is_binding(def_map, pat) {
 2510  
 2511                      let ident = ast_util::path_to_ident(path_ref);
 2512  
 2513                      // LLVM does not properly generate 'DW_AT_start_scope' fields for variable DIEs.
 2514                      // For this reason we have to introduce an artificial scope at bindings whenever
 2515                      // a variable with the same name is declared in *any* parent scope.
 2516                      //
 2517                      // Otherwise the following error occurs:
 2518                      //
 2519                      // let x = 10;
 2520                      //
 2521                      // do_something(); // 'gdb print x' correctly prints 10
 2522                      //
 2523                      // {
 2524                      //     do_something(); // 'gdb print x' prints 0, because it already reads the
 2525                      //                     // uninitialized 'x' from the next line...
 2526                      //     let x = 100;
 2527                      //     do_something(); // 'gdb print x' correctly prints 100
 2528                      // }
 2529  
 2530                      // Is there already a binding with that name?
 2531                      // N.B.: this comparison must be UNhygienic... because
 2532                      // gdb knows nothing about the context, so any two
 2533                      // variables with the same name will cause the problem.
 2534                      let need_new_scope = scope_stack
 2535                          .iter()
 2536                          .any(|entry| entry.ident.iter().any(|i| i.name == ident.name));
 2537  
 2538                      if need_new_scope {
 2539                          // Create a new lexical scope and push it onto the stack
 2540                          let loc = cx.sess().codemap().lookup_char_pos(pat.span.lo);
 2541                          let file_metadata = file_metadata(cx,
 2542                                                            loc.file
 2543                                                               .name
 2544                                                               .as_slice());
 2545                          let parent_scope = scope_stack.last().unwrap().scope_metadata;
 2546  
 2547                          let scope_metadata = unsafe {
 2548                              llvm::LLVMDIBuilderCreateLexicalBlock(
 2549                                  DIB(cx),
 2550                                  parent_scope,
 2551                                  file_metadata,
 2552                                  loc.line as c_uint,
 2553                                  loc.col.to_uint() as c_uint,
 2554                                  0)
 2555                          };
 2556  
 2557                          scope_stack.push(ScopeStackEntry {
 2558                              scope_metadata: scope_metadata,
 2559                              ident: Some(ident)
 2560                          });
 2561  
 2562                      } else {
 2563                          // Push a new entry anyway so the name can be found
 2564                          let prev_metadata = scope_stack.last().unwrap().scope_metadata;
 2565                          scope_stack.push(ScopeStackEntry {
 2566                              scope_metadata: prev_metadata,
 2567                              ident: Some(ident)
 2568                          });
 2569                      }
 2570                  }
 2571  
 2572                  scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
 2573  
 2574                  for &sub_pat in sub_pat_opt.iter() {
 2575                      walk_pattern(cx, sub_pat, scope_stack, scope_map);
 2576                  }
 2577              }
 2578  
 2579              ast::PatWild | ast::PatWildMulti => {
 2580                  scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
 2581              }
 2582  
 2583              ast::PatEnum(_, ref sub_pats_opt) => {
 2584                  scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
 2585  
 2586                  for ref sub_pats in sub_pats_opt.iter() {
 2587                      for &p in sub_pats.iter() {
 2588                          walk_pattern(cx, p, scope_stack, scope_map);
 2589                      }
 2590                  }
 2591              }
 2592  
 2593              ast::PatStruct(_, ref field_pats, _) => {
 2594                  scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
 2595  
 2596                  for &ast::FieldPat { pat: sub_pat, .. } in field_pats.iter() {
 2597                      walk_pattern(cx, sub_pat, scope_stack, scope_map);
 2598                  }
 2599              }
 2600  
 2601              ast::PatTup(ref sub_pats) => {
 2602                  scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
 2603  
 2604                  for &sub_pat in sub_pats.iter() {
 2605                      walk_pattern(cx, sub_pat, scope_stack, scope_map);
 2606                  }
 2607              }
 2608  
 2609              ast::PatUniq(sub_pat) | ast::PatRegion(sub_pat) => {
 2610                  scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
 2611                  walk_pattern(cx, sub_pat, scope_stack, scope_map);
 2612              }
 2613  
 2614              ast::PatLit(exp) => {
 2615                  scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
 2616                  walk_expr(cx, exp, scope_stack, scope_map);
 2617              }
 2618  
 2619              ast::PatRange(exp1, exp2) => {
 2620                  scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
 2621                  walk_expr(cx, exp1, scope_stack, scope_map);
 2622                  walk_expr(cx, exp2, scope_stack, scope_map);
 2623              }
 2624  
 2625              ast::PatVec(ref front_sub_pats, ref middle_sub_pats, ref back_sub_pats) => {
 2626                  scope_map.insert(pat.id, scope_stack.last().unwrap().scope_metadata);
 2627  
 2628                  for &sub_pat in front_sub_pats.iter() {
 2629                      walk_pattern(cx, sub_pat, scope_stack, scope_map);
 2630                  }
 2631  
 2632                  for &sub_pat in middle_sub_pats.iter() {
 2633                      walk_pattern(cx, sub_pat, scope_stack, scope_map);
 2634                  }
 2635  
 2636                  for &sub_pat in back_sub_pats.iter() {
 2637                      walk_pattern(cx, sub_pat, scope_stack, scope_map);
 2638                  }
 2639              }
 2640          }
 2641      }
 2642  
 2643      fn walk_expr(cx&CrateContext,
 2644                   exp: &ast::Expr,
 2645                   scope_stack&mut Vec<ScopeStackEntry> ,
 2646                   scope_map&mut HashMap<ast::NodeId, DIScope>) {
 2647  
 2648          scope_map.insert(exp.id, scope_stack.last().unwrap().scope_metadata);
 2649  
 2650          match exp.node {
 2651              ast::ExprLit(_)   |
 2652              ast::ExprBreak(_) |
 2653              ast::ExprAgain(_) |
 2654              ast::ExprPath(_)  => {}
 2655  
 2656              ast::ExprVstore(sub_exp, _)   |
 2657              ast::ExprCast(sub_exp, _)     |
 2658              ast::ExprAddrOf(_, sub_exp)  |
 2659              ast::ExprField(sub_exp, _, _) |
 2660              ast::ExprParen(sub_exp)       => walk_expr(cx, sub_exp, scope_stack, scope_map),
 2661  
 2662              ast::ExprBox(place, sub_expr) => {
 2663                  walk_expr(cx, place, scope_stack, scope_map);
 2664                  walk_expr(cx, sub_expr, scope_stack, scope_map);
 2665              }
 2666  
 2667              ast::ExprRet(exp_opt) => match exp_opt {
 2668                  Some(sub_exp) => walk_expr(cx, sub_exp, scope_stack, scope_map),
 2669                  None => ()
 2670              },
 2671  
 2672              ast::ExprUnary(_, sub_exp) => {
 2673                  walk_expr(cx, sub_exp, scope_stack, scope_map);
 2674              }
 2675  
 2676              ast::ExprAssignOp(_, lhs, rhs) |
 2677              ast::ExprIndex(lhs, rhs)        |
 2678              ast::ExprBinary(_, lhs, rhs)    => {
 2679                  walk_expr(cx, lhs, scope_stack, scope_map);
 2680                  walk_expr(cx, rhs, scope_stack, scope_map);
 2681              }
 2682  
 2683              ast::ExprVec(ref init_expressions) |
 2684              ast::ExprTup(ref init_expressions) => {
 2685                  for ie in init_expressions.iter() {
 2686                      walk_expr(cx, *ie, scope_stack, scope_map);
 2687                  }
 2688              }
 2689  
 2690              ast::ExprAssign(sub_exp1, sub_exp2) |
 2691              ast::ExprRepeat(sub_exp1, sub_exp2) => {
 2692                  walk_expr(cx, sub_exp1, scope_stack, scope_map);
 2693                  walk_expr(cx, sub_exp2, scope_stack, scope_map);
 2694              }
 2695  
 2696              ast::ExprIf(cond_exp, then_block, ref opt_else_exp) => {
 2697                  walk_expr(cx, cond_exp, scope_stack, scope_map);
 2698  
 2699                  with_new_scope(cx,
 2700                                 then_block.span,
 2701                                 scope_stack,
 2702                                 scope_map,
 2703                                 |cx, scope_stack, scope_map| {
 2704                      walk_block(cx, then_block, scope_stack, scope_map);
 2705                  });
 2706  
 2707                  match *opt_else_exp {
 2708                      Some(else_exp) => walk_expr(cx, else_exp, scope_stack, scope_map),
 2709                      _ => ()
 2710                  }
 2711              }
 2712  
 2713              ast::ExprWhile(cond_exp, loop_body) => {
 2714                  walk_expr(cx, cond_exp, scope_stack, scope_map);
 2715  
 2716                  with_new_scope(cx,
 2717                                 loop_body.span,
 2718                                 scope_stack,
 2719                                 scope_map,
 2720                                 |cx, scope_stack, scope_map| {
 2721                      walk_block(cx, loop_body, scope_stack, scope_map);
 2722                  })
 2723              }
 2724  
 2725              ast::ExprForLoop(_, _, _, _) => {
 2726                  cx.sess().span_bug(exp.span, "debuginfo::populate_scope_map() - \
 2727                                                Found unexpanded for-loop.");
 2728              }
 2729  
 2730              ast::ExprMac(_) => {
 2731                  cx.sess().span_bug(exp.span, "debuginfo::populate_scope_map() - \
 2732                                                Found unexpanded macro.");
 2733              }
 2734  
 2735              ast::ExprLoop(block, _) |
 2736              ast::ExprBlock(block)   => {
 2737                  with_new_scope(cx,
 2738                                 block.span,
 2739                                 scope_stack,
 2740                                 scope_map,
 2741                                 |cx, scope_stack, scope_map| {
 2742                      walk_block(cx, block, scope_stack, scope_map);
 2743                  })
 2744              }
 2745  
 2746              ast::ExprFnBlock(decl, block) |
 2747              ast::ExprProc(decl, block) => {
 2748                  with_new_scope(cx,
 2749                                 block.span,
 2750                                 scope_stack,
 2751                                 scope_map,
 2752                                 |cx, scope_stack, scope_map| {
 2753                      for &ast::Arg { pat: pattern, .. } in decl.inputs.iter() {
 2754                          walk_pattern(cx, pattern, scope_stack, scope_map);
 2755                      }
 2756  
 2757                      walk_block(cx, block, scope_stack, scope_map);
 2758                  })
 2759              }
 2760  
 2761              ast::ExprCall(fn_exp, ref args) => {
 2762                  walk_expr(cx, fn_exp, scope_stack, scope_map);
 2763  
 2764                  for arg_exp in args.iter() {
 2765                      walk_expr(cx, *arg_exp, scope_stack, scope_map);
 2766                  }
 2767              }
 2768  
 2769              ast::ExprMethodCall(_, _, ref args) => {
 2770                  for arg_exp in args.iter() {
 2771                      walk_expr(cx, *arg_exp, scope_stack, scope_map);
 2772                  }
 2773              }
 2774  
 2775              ast::ExprMatch(discriminant_exp, ref arms) => {
 2776                  walk_expr(cx, discriminant_exp, scope_stack, scope_map);
 2777  
 2778                  // for each arm we have to first walk the pattern as these might introduce new
 2779                  // artificial scopes. It should be sufficient to walk only one pattern per arm, as
 2780                  // they all must contain the same binding names
 2781  
 2782                  for arm_ref in arms.iter() {
 2783                      let arm_span = arm_ref.pats.get(0).span;
 2784  
 2785                      with_new_scope(cx,
 2786                                     arm_span,
 2787                                     scope_stack,
 2788                                     scope_map,
 2789                                     |cx, scope_stack, scope_map| {
 2790                          for &pat in arm_ref.pats.iter() {
 2791                              walk_pattern(cx, pat, scope_stack, scope_map);
 2792                          }
 2793  
 2794                          for guard_exp in arm_ref.guard.iter() {
 2795                              walk_expr(cx, *guard_exp, scope_stack, scope_map)
 2796                          }
 2797  
 2798                          walk_expr(cx, arm_ref.body, scope_stack, scope_map);
 2799                      })
 2800                  }
 2801              }
 2802  
 2803              ast::ExprStruct(_, ref fields, ref base_exp) => {
 2804                  for &ast::Field { expr: exp, .. } in fields.iter() {
 2805                      walk_expr(cx, exp, scope_stack, scope_map);
 2806                  }
 2807  
 2808                  match *base_exp {
 2809                      Some(exp) => walk_expr(cx, exp, scope_stack, scope_map),
 2810                      None => ()
 2811                  }
 2812              }
 2813  
 2814              ast::ExprInlineAsm(ast::InlineAsm { inputs: ref inputs,
 2815                                                  outputs: ref outputs,
 2816                                                  .. }) => {
 2817                  // inputs, outputs: ~[(~str, @expr)]
 2818                  for &(_, exp) in inputs.iter() {
 2819                      walk_expr(cx, exp, scope_stack, scope_map);
 2820                  }
 2821  
 2822                  for &(_, exp) in outputs.iter() {
 2823                      walk_expr(cx, exp, scope_stack, scope_map);
 2824                  }
 2825              }
 2826          }
 2827      }
 2828  }
 2829  
 2830  
 2831  //=-------------------------------------------------------------------------------------------------
 2832  // Namespace Handling
 2833  //=-------------------------------------------------------------------------------------------------
 2834  
 2835  struct NamespaceTreeNode {
 2836      name: ast::Name,
 2837      scope: DIScope,
 2838      parent: Option<Weak<NamespaceTreeNode>>,
 2839  }
 2840  
 2841  impl NamespaceTreeNode {
 2842      fn mangled_name_of_contained_item(&self, item_name&str) -> ~str {
 2843          fn fill_nested(node: &NamespaceTreeNode, output: &mut StrBuf) {
 2844              match node.parent {
 2845                  Some(ref parent) => fill_nested(&*parent.upgrade().unwrap(), output),
 2846                  None => {}
 2847              }
 2848              let string = token::get_name(node.name);
 2849              output.push_str(format!("{}", string.get().len()));
 2850              output.push_str(string.get());
 2851          }
 2852  
 2853          let mut name = StrBuf::from_str("_ZN");
 2854          fill_nested(self, &mut name);
 2855          name.push_str(format!("{}", item_name.len()));
 2856          name.push_str(item_name);
 2857          name.push_char('E');
 2858          name.into_owned()
 2859      }
 2860  }
 2861  
 2862  fn namespace_for_item(cx: &CrateContext, def_idast::DefId) -> Rc<NamespaceTreeNode> {
 2863      ty::with_path(cx.tcx(), def_id, |path| {
 2864          // prepend crate name if not already present
 2865          let krate = if def_id.krate == ast::LOCAL_CRATE {
 2866              let crate_namespace_ident = token::str_to_ident(cx.link_meta
 2867                                                                .crateid
 2868                                                                .name
 2869                                                                .as_slice());
 2870              Some(ast_map::PathMod(crate_namespace_ident.name))
 2871          } else {
 2872              None
 2873          };
 2874          let mut path = krate.move_iter().chain(path).peekable();
 2875  
 2876          let mut current_key = Vec::new();
 2877          let mut parent_nodeOption<Rc<NamespaceTreeNode>> = None;
 2878  
 2879          // Create/Lookup namespace for each element of the path.
 2880          loop {
 2881              // Emulate a for loop so we can use peek below.
 2882              let path_element = match path.next() {
 2883                  Some(e) => e,
 2884                  None => break
 2885              };
 2886              // Ignore the name of the item (the last path element).
 2887              if path.peek().is_none() {
 2888                  break;
 2889              }
 2890  
 2891              let name = path_element.name();
 2892              current_key.push(name);
 2893  
 2894              let existing_node = debug_context(cx).namespace_map.borrow()
 2895                                                   .find_copy(&current_key);
 2896              let current_node = match existing_node {
 2897                  Some(existing_node) => existing_node,
 2898                  None => {
 2899                      // create and insert
 2900                      let parent_scope = match parent_node {
 2901                          Some(ref node) => node.scope,
 2902                          None => ptr::null()
 2903                      };
 2904                      let namespace_name = token::get_name(name);
 2905                      let scope = namespace_name.get().with_c_str(|namespace_name| {
 2906                          unsafe {
 2907                              llvm::LLVMDIBuilderCreateNameSpace(
 2908                                  DIB(cx),
 2909                                  parent_scope,
 2910                                  namespace_name,
 2911                                  // cannot reconstruct file ...
 2912                                  ptr::null(),
 2913                                  // ... or line information, but that's not so important.
 2914                                  0)
 2915                          }
 2916                      });
 2917  
 2918                      let node = Rc::new(NamespaceTreeNode {
 2919                          name: name,
 2920                          scope: scope,
 2921                          parent: parent_node.map(|parent| parent.downgrade()),
 2922                      });
 2923  
 2924                      debug_context(cx).namespace_map.borrow_mut()
 2925                                       .insert(current_key.clone(), node.clone());
 2926  
 2927                      node
 2928                  }
 2929              };
 2930  
 2931              parent_node = Some(current_node);
 2932          }
 2933  
 2934          match parent_node {
 2935              Some(node) => node,
 2936              None => {
 2937                  cx.sess().bug(format!("debuginfo::namespace_for_item(): \
 2938                      path too short for {:?}", def_id));
 2939              }
 2940          }
 2941      })
 2942  }


librustc/middle/trans/debuginfo.rs:1195:1-1195:1 -fn- definition:
fn pointer_type_metadata(cx: &CrateContext,
                         pointer_type: ty::t,
                         pointee_type_metadata: DIType)
references:- 5
2171:         pointer_type_metadata(cx, pointer_type, box_metadata)
2172:     }
--
2219:                     let pointee = type_metadata(cx, mt.ty, usage_site_span);
2220:                     pointer_type_metadata(cx, t, pointee)
2221:                 }


librustc/middle/trans/debuginfo.rs:2861:1-2861:1 -fn- definition:
fn namespace_for_item(cx: &CrateContext, def_id: ast::DefId) -> Rc<NamespaceTreeNode> {
    ty::with_path(cx.tcx(), def_id, |path| {
        // prepend crate name if not already present
references:- 3
2362:                                    -> (DIScope, Span) {
2363:     let containing_scope = namespace_for_item(cx, def_id).scope;
2364:     let definition_span = if def_id.krate == ast::LOCAL_CRATE {


librustc/middle/trans/debuginfo.rs:2324:67-2324:67 -fn- definition:
/// Return codemap::Loc corresponding to the beginning of the span
fn span_start(cx: &CrateContext, span: Span) -> codemap::Loc {
    cx.sess().codemap().lookup_char_pos(span.lo)
references:- 17
2057:     let loc = span_start(cx, span);
2058:     let file_metadata = file_metadata(cx, loc.file.name.as_slice());
--
2128:     let file_name = span_start(cx, definition_span).file.name.clone();
2129:     let file_metadata = file_metadata(cx, file_name.as_slice());


librustc/middle/trans/debuginfo.rs:1723:85-1723:85 -fn- definition:
/// Examples of Rust types to use this are: structs, tuples, boxes, vecs, and enums.
fn composite_type_metadata(cx: &CrateContext,
                           composite_llvm_type: Type,
references:- 5
1908:     return composite_type_metadata(
1909:         cx,
--
2133:     composite_type_metadata(cx,
2134:                             trait_llvm_type,


librustc/middle/trans/debuginfo.rs:1345:1-1345:1 -struct- definition:
struct TupleMemberDescriptionFactory {
    component_types: Vec<ty::t> ,
    span: Span,
references:- 3
1385:         file_metadata: file_metadata,
1386:         member_description_factory: TupleMD(TupleMemberDescriptionFactory {
1387:             component_types: Vec::from_slice(component_types),


librustc/middle/trans/debuginfo.rs:208:1-208:1 -struct- definition:
pub struct FunctionDebugContext {
    repr: FunctionDebugContextRepr,
}
references:- 8
774:     return FunctionDebugContext { repr: FunctionDebugContext(fn_debug_context) };
librustc/middle/trans/common.rs:
274:     // Used and maintained by the debuginfo module.
275:     pub debug_context: debuginfo::FunctionDebugContext,
librustc/middle/trans/debuginfo.rs:
698:     if span == codemap::DUMMY_SP {
699:         return FunctionDebugContext { repr: FunctionWithoutDebugInfo };
700:     }


librustc/middle/trans/debuginfo.rs:1713:1-1713:1 -struct- definition:
struct MemberDescription {
    name: ~str,
    llvm_type: Type,
references:- 21
1995:         },
1996:         MemberDescription {
1997:             name: "elements".to_owned(),
--
2046:         },
2047:         MemberDescription {
2048:             name: "length".to_owned(),


librustc/middle/trans/debuginfo.rs:1302:1-1302:1 -enum- definition:
enum RecursiveTypeDescription {
    UnfinishedMetadata {
        cache_id: uint,
references:- 4
1530:                          span: Span)
1531:                       -> RecursiveTypeDescription {
1532:     let enum_name = ppaux::ty_to_str(cx.tcx(), enum_type);


librustc/middle/trans/debuginfo.rs:2452:4-2452:4 -fn- definition:
    fn walk_block(cx: &CrateContext,
                  block: &ast::Block,
                  scope_stack: &mut Vec<ScopeStackEntry> ,
references:- 5
2741:                                |cx, scope_stack, scope_map| {
2742:                     walk_block(cx, block, scope_stack, scope_map);
2743:                 })
--
2757:                     walk_block(cx, block, scope_stack, scope_map);
2758:                 })


librustc/middle/trans/debuginfo.rs:1392:1-1392:1 -struct- definition:
struct GeneralMemberDescriptionFactory {
    type_rep: Rc<adt::Repr>,
    variants: Rc<Vec<Rc<ty::VariantInfo>>>,
references:- 3
1665:                 file_metadata: file_metadata,
1666:                 member_description_factory: GeneralMD(GeneralMemberDescriptionFactory {
1667:                     type_rep: type_rep.clone(),


librustc/middle/trans/debuginfo.rs:2018:1-2018:1 -fn- definition:
fn vec_slice_metadata(cx: &CrateContext,
                      vec_type: ty::t,
                      element_type: ty::t,
references:- 2
2212:             match ty::get(mt.ty).sty {
2213:                 ty::ty_vec(ref mt, None) => vec_slice_metadata(cx, t, mt.ty, usage_site_span),
2214:                 ty::ty_str => {
2215:                     let i8_t = ty::mk_i8();
2216:                     vec_slice_metadata(cx, t, i8_t, usage_site_span)
2217:                 }


librustc/middle/trans/debuginfo.rs:2843:8-2843:8 -fn- definition:
        fn fill_nested(node: &NamespaceTreeNode, output: &mut StrBuf) {
            match node.parent {
                Some(ref parent) => fill_nested(&*parent.upgrade().unwrap(), output),
references:- 2
2844:             match node.parent {
2845:                 Some(ref parent) => fill_nested(&*parent.upgrade().unwrap(), output),
2846:                 None => {}
--
2853:         let mut name = StrBuf::from_str("_ZN");
2854:         fill_nested(self, &mut name);
2855:         name.push_str(format!("{}", item_name.len()));


librustc/middle/trans/debuginfo.rs:2078:1-2078:1 -fn- definition:
fn subroutine_type_metadata(cx: &CrateContext,
                            signature: &ty::FnSig,
                            span: Span)
references:- 2
2227:         ty::ty_closure(ref closurety) => {
2228:             subroutine_type_metadata(cx, &closurety.sig, usage_site_span)
2229:         }


librustc/middle/trans/debuginfo.rs:2332:1-2332:1 -fn- definition:
fn bytes_to_bits(bytes: u64) -> c_ulonglong {
    (bytes * 8) as c_ulonglong
}
references:- 17
1593:                             loc.line as c_uint,
1594:                             bytes_to_bits(discriminant_size),
1595:                             bytes_to_bits(discriminant_align),
--
1952:             bytes_to_bits(element_type_size * (len as u64)),
1953:             bytes_to_bits(element_type_align),
1954:             element_type_metadata,
--
1977:             bytes_to_bits(element_size),
1978:             bytes_to_bits(element_align),
1979:             element_type_metadata,


librustc/middle/trans/debuginfo.rs:2141:1-2141:1 -fn- definition:
fn type_metadata(cx: &CrateContext,
                 t: ty::t,
                 usage_site_span: Span)
references:- 22
910:             if cx.sess().opts.debuginfo == FullDebugInfo {
911:                 let actual_type_metadata = type_metadata(cx, actual_type, codemap::DUMMY_SP);
912:                 let param_metadata = token::get_ident(ident).get()
--
2158:         let content_llvm_type = type_of::type_of(cx, type_in_box);
2159:         let content_type_metadata = type_metadata(
2160:             cx,
--
2205:                 _ => {
2206:                     let pointee = type_metadata(cx, typ, usage_site_span);
2207:                     pointer_type_metadata(cx, t, pointee)
--
2218:                 _ => {
2219:                     let pointee = type_metadata(cx, mt.ty, usage_site_span);
2220:                     pointer_type_metadata(cx, t, pointee)


librustc/middle/trans/debuginfo.rs:553:70-553:70 -fn- definition:
/// reliably find the correct visibility scope for the code position.
pub fn set_source_location(fcx: &FunctionContext,
                           node_id: ast::NodeId,
references:- 4
librustc/middle/trans/expr.rs:
322:     debuginfo::set_source_location(bcx.fcx, expr.id, expr.span);
librustc/middle/trans/base.rs:
911:         match call_info {
912:             Some(info) => debuginfo::set_source_location(bcx.fcx, info.id, info.span),
913:             None => debuginfo::clear_source_location(bcx.fcx)
--
929:         match call_info {
930:             Some(info) => debuginfo::set_source_location(bcx.fcx, info.id, info.span),
931:             None => debuginfo::clear_source_location(bcx.fcx)
librustc/middle/trans/expr.rs:
115:     debug!("trans_into() expr={}", expr.repr(bcx.tcx()));
116:     debuginfo::set_source_location(bcx.fcx, expr.id, expr.span);


librustc/middle/trans/debuginfo.rs:1017:1-1017:1 -fn- definition:
fn declare_local(bcx: &Block,
                 variable_ident: ast::Ident,
                 variable_type: ty::t,
references:- 4
389:         declare_local(bcx,
390:                       var_ident,
--
470:     declare_local(bcx,
471:                   variable_ident,
--
540:         declare_local(bcx,
541:                       argument_ident,


librustc/middle/trans/debuginfo.rs:2328:1-2328:1 -fn- definition:
fn size_and_align_of(cx: &CrateContext, llvm_type: Type) -> (u64, u64) {
    (machine::llsize_of_alloc(cx, llvm_type), machine::llalign_of_min(cx, llvm_type))
}
references:- 8
1200:     let pointer_llvm_type = type_of::type_of(cx, pointer_type);
1201:     let (pointer_size, pointer_align) = size_and_align_of(cx, pointer_llvm_type);
1202:     let name = ppaux::ty_to_str(cx.tcx(), pointer_type);
--
1965:     let element_llvm_type = type_of::type_of(cx, element_type);
1966:     let (element_size, element_align) = size_and_align_of(cx, element_llvm_type);


librustc/middle/trans/debuginfo.rs:2260:16-2260:16 -enum- definition:
enum DebugLocation {
    KnownLocation { scope: DIScope, line: uint, col: uint },
    UnknownLocation
references:- 7
2261: enum DebugLocation {
--
2266: impl DebugLocation {
2267:     fn new(scope: DIScope, line: uint, col: uint) -> DebugLocation {
--
2276: fn set_debug_location(cx: &CrateContext, debug_location: DebugLocation) {
2277:     if debug_location == debug_context(cx).current_debug_location.get() {


librustc/middle/trans/debuginfo.rs:2494:4-2494:4 -fn- definition:
    fn walk_pattern(cx: &CrateContext,
                    pat: @ast::Pat,
                    scope_stack: &mut Vec<ScopeStackEntry> ,
references:- 11
2596:                 for &ast::FieldPat { pat: sub_pat, .. } in field_pats.iter() {
2597:                     walk_pattern(cx, sub_pat, scope_stack, scope_map);
2598:                 }
--
2632:                 for &sub_pat in middle_sub_pats.iter() {
2633:                     walk_pattern(cx, sub_pat, scope_stack, scope_map);
2634:                 }
--
2753:                     for &ast::Arg { pat: pattern, .. } in decl.inputs.iter() {
2754:                         walk_pattern(cx, pattern, scope_stack, scope_map);
2755:                     }
--
2790:                         for &pat in arm_ref.pats.iter() {
2791:                             walk_pattern(cx, pat, scope_stack, scope_map);
2792:                         }


librustc/middle/trans/debuginfo.rs:582:74-582:74 -fn- definition:
/// Instructions generated hereafter won't be assigned a source location.
pub fn clear_source_location(fcx: &FunctionContext) {
    if fn_should_be_ignored(fcx) {
references:- 10
librustc/middle/trans/controlflow.rs:
169:     let then_bcx_out = trans_block(then_bcx_in, thn, dest);
170:     debuginfo::clear_source_location(bcx.fcx);
--
190:     // right before.
191:     debuginfo::clear_source_location(next_bcx.fcx);
librustc/middle/trans/base.rs:
930:             Some(info) => debuginfo::set_source_location(bcx.fcx, info.id, info.span),
931:             None => debuginfo::clear_source_location(bcx.fcx)
932:         };
--
1091:     }
1092:     debuginfo::clear_source_location(cx.fcx);
1093:     let p = Alloca(cx, ty, name);
--
1322:     build_return_block(fcx, ret_cx);
1323:     debuginfo::clear_source_location(fcx);
1324:     fcx.cleanup();
librustc/middle/trans/closure.rs:
459:     // HACK(eddyb) finish_fn cannot be used here, we returned directly.
460:     debuginfo::clear_source_location(&fcx);
461:     fcx.cleanup();
librustc/middle/trans/base.rs:
1108:     }
1109:     debuginfo::clear_source_location(cx.fcx);
1110:     return ArrayAlloca(cx, ty, v);


librustc/middle/trans/debuginfo.rs:1750:1-1750:1 -fn- definition:
fn set_members_of_composite_type(cx: &CrateContext,
                                 composite_type_metadata: DICompositeType,
                                 composite_llvm_type: Type,
references:- 3
1427:                 set_members_of_composite_type(cx,
1428:                                               variant_type_metadata,
--
1740:     // ... and immediately create and add the member descriptions.
1741:     set_members_of_composite_type(cx,
1742:                                   composite_type_metadata,


librustc/middle/trans/debuginfo.rs:2354:1-2354:1 -fn- definition:
fn assert_type_for_node_id(cx: &CrateContext, node_id: ast::NodeId, error_span: Span) {
    if !cx.tcx.node_types.borrow().contains_key(&(node_id as uint)) {
        cx.sess().span_bug(error_span, "debuginfo: Could not find type for node id!");
references:- 2
792:             _ => {
793:                 assert_type_for_node_id(cx, fn_ast_id, error_span);
--
811:         for arg in fn_decl.inputs.iter() {
812:             assert_type_for_node_id(cx, arg.pat.id, arg.pat.span);
813:             let arg_type = ty::node_id_to_type(cx.tcx(), arg.pat.id);


librustc/middle/trans/debuginfo.rs:2275:1-2275:1 -fn- definition:
fn set_debug_location(cx: &CrateContext, debug_location: DebugLocation) {
    if debug_location == debug_context(cx).current_debug_location.get() {
        return;
references:- 7
588:     set_debug_location(fcx.ccx, UnknownLocation);
589: }
--
1094:                         .get());
1095:             set_debug_location(cx, UnknownLocation);
1096:         }


librustc/middle/trans/debuginfo.rs:2414:4-2414:4 -fn- definition:
    fn with_new_scope(cx: &CrateContext,
                      scope_span: Span,
                      scope_stack: &mut Vec<ScopeStackEntry> ,
references:- 6
2716:                 with_new_scope(cx,
2717:                                loop_body.span,
--
2785:                     with_new_scope(cx,
2786:                                    arm_span,


librustc/middle/trans/debuginfo.rs:176:79-176:79 -struct- definition:
/// A context object for maintaining all state needed by the debuginfo module.
pub struct CrateDebugContext {
    llcontext: ContextRef,
references:- 6
195:         let llcontext = unsafe { llvm::LLVMGetModuleContext(llmod) };
196:         return CrateDebugContext {
197:             llcontext: llcontext,
--
2338: fn debug_context<'a>(cx: &'a CrateContext) -> &'a CrateDebugContext {
2339:     let debug_context: &'a CrateDebugContext = cx.dbg_cx.get_ref();
librustc/middle/trans/context.rs:
122:     pub uses_gc: bool,
123:     pub dbg_cx: Option<debuginfo::CrateDebugContext>,
librustc/middle/trans/debuginfo.rs:
2338: fn debug_context<'a>(cx: &'a CrateContext) -> &'a CrateDebugContext {
2339:     let debug_context: &'a CrateDebugContext = cx.dbg_cx.get_ref();
2340:     debug_context


librustc/middle/trans/debuginfo.rs:2347:1-2347:1 -fn- definition:
fn fn_should_be_ignored(fcx: &FunctionContext) -> bool {
    match fcx.debug_context.repr {
        FunctionDebugContext(_) => false,
references:- 5
583: pub fn clear_source_location(fcx: &FunctionContext) {
584:     if fn_should_be_ignored(fcx) {
585:         return;


librustc/middle/trans/debuginfo.rs:1958:1-1958:1 -fn- definition:
fn vec_metadata(cx: &CrateContext,
                element_type: ty::t,
                span: Span)
references:- 2
2201:                     let i8_t = ty::mk_i8();
2202:                     let vec_metadata = vec_metadata(cx, i8_t, usage_site_span);
2203:                     pointer_type_metadata(cx, t, vec_metadata)


librustc/middle/trans/debuginfo.rs:2337:10-2337:10 -fn- definition:
fn debug_context<'a>(cx: &'a CrateContext) -> &'a CrateDebugContext {
    let debug_context: &'a CrateDebugContext = cx.dbg_cx.get_ref();
    debug_context
references:- 14
2148:     match debug_context(cx).created_types.borrow().find(&cache_id) {
2149:         Some(type_metadata) => return *type_metadata,
--
2276: fn set_debug_location(cx: &CrateContext, debug_location: DebugLocation) {
2277:     if debug_location == debug_context(cx).current_debug_location.get() {
2278:         return;
--
2288:             unsafe {
2289:                 metadata_node = llvm::LLVMMDNodeInContext(debug_context(cx).llcontext,
2290:                                                           elements.as_ptr(),
--
2304:     debug_context(cx).current_debug_location.set(debug_location);
2305: }
--
2894:             let existing_node = debug_context(cx).namespace_map.borrow()
2895:                                                  .find_copy(&current_key);
--
2924:                     debug_context(cx).namespace_map.borrow_mut()
2925:                                      .insert(current_key.clone(), node.clone());


librustc/middle/trans/debuginfo.rs:2834:1-2834:1 -struct- definition:
struct NamespaceTreeNode {
    name: ast::Name,
    scope: DIScope,
references:- 7
2918:                     let node = Rc::new(NamespaceTreeNode {
2919:                         name: name,


librustc/middle/trans/debuginfo.rs:1931:1-1931:1 -fn- definition:
fn fixed_vec_metadata(cx: &CrateContext,
                      element_type: ty::t,
                      len: uint,
references:- 2
2192:         }
2193:         ty::ty_vec(ref mt, Some(len)) => fixed_vec_metadata(cx, mt.ty, len, usage_site_span),
2194:         ty::ty_uniq(typ) => {
--
2241:                 let len = ty::simd_size(cx.tcx(), t);
2242:                 fixed_vec_metadata(cx, element_type, len, usage_site_span)
2243:             } else {


librustc/middle/trans/debuginfo.rs:2310:1-2310:1 -fn- definition:
fn cache_id_for_type(t: ty::t) -> uint {
    ty::type_id(t)
}
references:- 6
1628:             UnfinishedMetadata {
1629:                 cache_id: cache_id_for_type(enum_type),
1630:                 metadata_stub: metadata_stub,
--
1687:             UnfinishedMetadata {
1688:                 cache_id: cache_id_for_type(enum_type),
1689:                 metadata_stub: metadata_stub,
--
2145:               -> DIType {
2146:     let cache_id = cache_id_for_type(t);


librustc/middle/trans/debuginfo.rs:1442:1-1442:1 -struct- definition:
struct EnumVariantMemberDescriptionFactory {
    args: Vec<(~str, ty::t)> ,
    discriminant_type_metadata: Option<DIType>,
references:- 3
1517:     let member_description_factory =
1518:         EnumVariantMD(EnumVariantMemberDescriptionFactory {
1519:             args: args,


librustc/middle/trans/debuginfo.rs:2316:30-2316:30 -fn- definition:
// `prepare_enum_metadata()`.
fn generate_unique_type_id(prefix: &'static str) -> ~str {
    unsafe {
references:- 2
1822:     // where we don't want it.
1823:     let unique_id = generate_unique_type_id("DI_STRUCT_");


librustc/middle/trans/debuginfo.rs:2360:1-2360:1 -fn- definition:
fn get_namespace_and_span_for_item(cx: &CrateContext, def_id: ast::DefId)
                                   -> (DIScope, Span) {
    let containing_scope = namespace_for_item(cx, def_id).scope;
references:- 3
1277:     let (containing_scope, definition_span) = get_namespace_and_span_for_item(cx, def_id);
--
2126:     let (containing_scope, definition_span) = get_namespace_and_span_for_item(cx, def_id);


librustc/middle/trans/debuginfo.rs:1215:1-1215:1 -enum- definition:
enum MemberDescriptionFactory {
    StructMD(StructMemberDescriptionFactory),
    TupleMD(TupleMemberDescriptionFactory),
references:- 3
1308:         file_metadata: DIFile,
1309:         member_description_factory: MemberDescriptionFactory,
1310:     },
--
1472:                          span: Span)
1473:                       -> (DICompositeType, Type, MemberDescriptionFactory) {
1474:     let variant_llvm_type =


librustc/middle/trans/debuginfo.rs:1242:1-1242:1 -struct- definition:
struct StructMemberDescriptionFactory {
    fields: Vec<ty::field> ,
    span: Span,
references:- 3
1295:         file_metadata: file_metadata,
1296:         member_description_factory: StructMD(StructMemberDescriptionFactory {
1297:             fields: fields,


librustc/middle/trans/debuginfo.rs:2388:4-2388:4 -struct- definition:
    struct ScopeStackEntry {
        scope_metadata: DIScope,
        ident: Option<ast::Ident>
references:- 11
2557:                         scope_stack.push(ScopeStackEntry {
2558:                             scope_metadata: scope_metadata,
--
2564:                         let prev_metadata = scope_stack.last().unwrap().scope_metadata;
2565:                         scope_stack.push(ScopeStackEntry {
2566:                             scope_metadata: prev_metadata,
--
2644:                  exp: &ast::Expr,
2645:                  scope_stack: &mut Vec<ScopeStackEntry> ,
2646:                  scope_map: &mut HashMap<ast::NodeId, DIScope>) {


librustc/middle/trans/debuginfo.rs:241:1-241:1 -struct- definition:
struct FunctionDebugContextData {
    scope_map: RefCell<HashMap<ast::NodeId, DIScope>>,
    fn_metadata: DISubprogram,
references:- 3
759:     // Initialize fn debug context (including scope map and namespace map)
760:     let fn_debug_context = box FunctionDebugContextData {
761:         scope_map: RefCell::new(HashMap::new()),


librustc/middle/trans/debuginfo.rs:1132:58-1132:58 -fn- definition:
/// Finds the scope metadata node for the given AST node.
fn scope_metadata(fcx: &FunctionContext,
                  node_id: ast::NodeId,
references:- 3
491:     let scope_metadata = scope_metadata(bcx.fcx, node_id, span);
--
569:                 let loc = span_start(cx, span);
570:                 let scope = scope_metadata(fcx, node_id, span);


librustc/middle/trans/debuginfo.rs:1465:1-1465:1 -fn- definition:
fn describe_enum_variant(cx: &CrateContext,
                         struct_def: &adt::Struct,
                         variant_info: &ty::VariantInfo,
references:- 3
1620:                  member_description_factory) =
1621:                     describe_enum_variant(cx,
1622:                                           struct_def,
--
1679:                  member_description_factory) =
1680:                     describe_enum_variant(cx,
1681:                                           struct_def,


librustc/middle/trans/debuginfo.rs:949:1-949:1 -fn- definition:
fn create_DIArray(builder: DIBuilderRef, arr: &[DIDescriptor]) -> DIArray {
    return unsafe {
        llvm::LLVMDIBuilderGetOrCreateArray(builder, arr.as_ptr(), arr.len() as u32)
references:- 11
2103:             file_metadata,
2104:             create_DIArray(DIB(cx), signature_metadata.as_slice()))
2105:     };


librustc/middle/trans/debuginfo.rs:938:1-938:1 -fn- definition:
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
references:- 2
335:     let is_local_to_unit = is_node_local_to_unit(cx, node_id);
336:     let loc = span_start(cx, span);
--
734:     let is_local_to_unit = is_node_local_to_unit(cx, fn_ast_id);


librustc/middle/trans/debuginfo.rs:1013:4-1013:4 -fn- definition:
    fn fallback_path(cx: &CrateContext) -> CString {
        cx.link_meta.crateid.name.as_slice().to_c_str()
    }
references:- 3
962:                 cx.sess().warn("debuginfo: Invalid path to crate's local root source file!");
963:                 fallback_path(cx)
964:             } else {
--
979:                         }
980:                     _ => fallback_path(cx)
981:                 }


librustc/middle/trans/debuginfo.rs:2643:4-2643:4 -fn- definition:
    fn walk_expr(cx: &CrateContext,
                 exp: &ast::Expr,
                 scope_stack: &mut Vec<ScopeStackEntry> ,
references:- 29
2672:             ast::ExprUnary(_, sub_exp) => {
2673:                 walk_expr(cx, sub_exp, scope_stack, scope_map);
2674:             }
--
2696:             ast::ExprIf(cond_exp, then_block, ref opt_else_exp) => {
2697:                 walk_expr(cx, cond_exp, scope_stack, scope_map);
--
2775:             ast::ExprMatch(discriminant_exp, ref arms) => {
2776:                 walk_expr(cx, discriminant_exp, scope_stack, scope_map);
--
2798:                         walk_expr(cx, arm_ref.body, scope_stack, scope_map);
2799:                     })
--
2822:                 for &(_, exp) in outputs.iter() {
2823:                     walk_expr(cx, exp, scope_stack, scope_map);
2824:                 }


librustc/middle/trans/debuginfo.rs:2343:10-2343:10 -fn- definition:
fn DIB(cx: &CrateContext) -> DIBuilderRef {
    cx.dbg_cx.get_ref().builder
}
references:- 37


librustc/middle/trans/debuginfo.rs:1100:1-1100:1 -fn- definition:
fn file_metadata(cx: &CrateContext, full_path: &str) -> DIFile {
    match debug_context(cx).created_files.borrow().find_equiv(&full_path) {
        Some(file_metadata) => return *file_metadata,
references:- 13
702:     let loc = span_start(cx, span);
703:     let file_metadata = file_metadata(cx, loc.file.name.as_slice());
--
2422:         let loc = cx.sess().codemap().lookup_char_pos(scope_span.lo);
2423:         let file_metadata = file_metadata(cx, loc.file.name.as_slice());
2424:         let parent_scope = scope_stack.last().unwrap().scope_metadata;
--
2540:                         let loc = cx.sess().codemap().lookup_char_pos(pat.span.lo);
2541:                         let file_metadata = file_metadata(cx,
2542:                                                           loc.file


librustc/middle/trans/debuginfo.rs:1810:94-1810:94 -fn- definition:
// add any fields to the struct. This can be done later with set_members_of_composite_type().
fn create_struct_stub(cx: &CrateContext,
                      struct_llvm_type: Type,
references:- 4
1282:     let struct_metadata_stub = create_struct_stub(cx,
1283:                                                   struct_llvm_type,
--
1377:         cache_id: cache_id_for_type(tuple_type),
1378:         metadata_stub: create_struct_stub(cx,
1379:                                           tuple_llvm_type,
--
1732:     // Create the (empty) struct metadata node ...
1733:     let composite_type_metadata = create_struct_stub(cx,
1734:                                                      composite_llvm_type,