Skip to content

Commit 0f98cb4

Browse files
debuginfo: Properly support by-value self arguments
1 parent 1a26bd1 commit 0f98cb4

File tree

1 file changed

+23
-4
lines changed

1 file changed

+23
-4
lines changed

src/librustc/middle/trans/debuginfo.rs

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -129,11 +129,13 @@ use driver::session;
129129
use lib::llvm::llvm;
130130
use lib::llvm::{ModuleRef, ContextRef, ValueRef};
131131
use lib::llvm::debuginfo::*;
132+
use middle::trans::adt;
133+
use middle::trans::base;
134+
use middle::trans::build;
132135
use middle::trans::common::*;
133136
use middle::trans::machine;
134137
use middle::trans::type_of;
135138
use middle::trans::type_::Type;
136-
use middle::trans::adt;
137139
use middle::trans;
138140
use middle::ty;
139141
use middle::pat_util;
@@ -453,12 +455,29 @@ pub fn create_self_argument_metadata(bcx: @mut Block,
453455

454456
let address_operations = &[unsafe { llvm::LLVMDIBuilderCreateOpDeref(Type::i64().to_ref()) }];
455457

458+
// The self argument comes in one of two forms:
459+
// (1) For `&self`, `~self`, and `@self` it is an alloca containing a pointer to the data. That
460+
// is the `{&~@}self` pointer is contained by value in the alloca, and `type_of_self` will
461+
// be `{&~@}Self`
462+
// (2) For by-value `self`, `llptr` will not be an alloca, but a pointer to the self-value. That
463+
// is by-value `self` is always implicitly passed by reference (sic!). So we have a couple
464+
// of problems here:
465+
// (a) There is no alloca to give to `llvm.dbg.declare` and
466+
// (b) `type_of_self` is `Self`, but `llptr` is of type `*Self`
467+
// In order to solve this problem, the else branch below creates a helper alloca which
468+
// contains a copy of `llptr`. We then describe the `self` parameter by pointing
469+
// `llvm.dbg.declare` to this helper alloca and tell it that the pointer there needs to be
470+
// dereferenced once to get to the actual data (similar to non-immediate by-value args).
456471
let variable_access = if unsafe { llvm::LLVMIsAAllocaInst(llptr) } != ptr::null() {
457472
DirectVariable { alloca: llptr }
458473
} else {
459-
// This is not stable and may break with future LLVM versions. llptr should really always
460-
// be an alloca. Anything else is not supported and just works by chance.
461-
IndirectVariable { alloca: llptr, address_operations: address_operations }
474+
// Create a helper alloca that allows us to track the self-argument properly. The alloca
475+
// contains a pointer to the self-value.
476+
let ptr_type = ty::mk_mut_ptr(bcx.tcx(), type_of_self);
477+
let helper_alloca = base::alloc_ty(bcx, ptr_type, "__self");
478+
build::Store(bcx, llptr, helper_alloca);
479+
480+
IndirectVariable { alloca: helper_alloca, address_operations: address_operations }
462481
};
463482

464483
declare_local(bcx,

0 commit comments

Comments
 (0)