@@ -113,12 +113,26 @@ ldc::DIScope ldc::DIBuilder::GetCurrentScope() {
113113 return fn->diLexicalBlocks .top ();
114114}
115115
116- void ldc::DIBuilder::Declare (const Loc &loc, llvm::Value *var,
116+ // Sets the memory address for a debuginfo variable.
117+ void ldc::DIBuilder::Declare (const Loc &loc, llvm::Value *storage,
117118 ldc::DILocalVariable divar,
118119 ldc::DIExpression diexpr) {
119120 unsigned charnum = (loc.linnum ? loc.charnum : 0 );
120121 auto debugLoc = llvm::DebugLoc::get (loc.linnum , charnum, GetCurrentScope ());
121- DBuilder.insertDeclare (var, divar, diexpr, debugLoc, IR->scopebb ());
122+ DBuilder.insertDeclare (storage, divar, diexpr, debugLoc, IR->scopebb ());
123+ }
124+
125+ // Sets the (current) value for a debuginfo variable.
126+ void ldc::DIBuilder::SetValue (const Loc &loc, llvm::Value *value,
127+ ldc::DILocalVariable divar,
128+ ldc::DIExpression diexpr) {
129+ unsigned charnum = (loc.linnum ? loc.charnum : 0 );
130+ auto debugLoc = llvm::DebugLoc::get (loc.linnum , charnum, GetCurrentScope ());
131+ DBuilder.insertDbgValueIntrinsic (value,
132+ #if LDC_LLVM_VER < 600
133+ 0 ,
134+ #endif
135+ divar, diexpr, debugLoc, IR->scopebb ());
122136}
123137
124138ldc::DIFile ldc::DIBuilder::CreateFile (Loc &loc) {
@@ -1020,7 +1034,7 @@ void ldc::DIBuilder::EmitValue(llvm::Value *val, VarDeclaration *vd) {
10201034
10211035void ldc::DIBuilder::EmitLocalVariable (llvm::Value *ll, VarDeclaration *vd,
10221036 Type *type, bool isThisPtr,
1023- bool forceAsLocal,
1037+ bool forceAsLocal, bool isRefRVal,
10241038 llvm::ArrayRef<int64_t > addr) {
10251039 if (!mustEmitFullDebugInfo ())
10261040 return ;
@@ -1040,12 +1054,28 @@ void ldc::DIBuilder::EmitLocalVariable(llvm::Value *ll, VarDeclaration *vd,
10401054 if (static_cast <llvm::MDNode *>(TD) == nullptr )
10411055 return ; // unsupported
10421056
1043- if (vd->isRef () || vd->isOut ()) {
1057+ const bool isRefOrOut = vd->isRef () || vd->isOut (); // incl. special-ref vars
1058+
1059+ // For MSVC x64 targets, declare params rewritten by ExplicitByvalRewrite as
1060+ // DI references, as if they were ref parameters.
1061+ const bool isPassedExplicitlyByval =
1062+ isTargetMSVCx64 && !isRefOrOut && isaArgument (ll) && addr.empty ();
1063+
1064+ bool useDbgValueIntrinsic = false ;
1065+ if (isRefOrOut || isPassedExplicitlyByval) {
1066+ // With the exception of special-ref loop variables, the reference/pointer
1067+ // itself is constant. So we don't have to attach the debug information to a
1068+ // memory location and can use llvm.dbg.value to set the constant pointer
1069+ // for the DI reference.
1070+ useDbgValueIntrinsic =
1071+ isPassedExplicitlyByval || (!isSpecialRefVar (vd) && isRefRVal);
10441072#if LDC_LLVM_VER >= 308
1045- auto T = DtoType (type);
1046- TD = DBuilder.createReferenceType (llvm::dwarf::DW_TAG_reference_type, TD,
1047- getTypeAllocSize (T) * 8 , // size (bits)
1048- DtoAlignment (type) * 8 ); // align (bits)
1073+ // Note: createReferenceType expects the size to be the size of a pointer,
1074+ // not the size of the type the reference refers to.
1075+ TD = DBuilder.createReferenceType (
1076+ llvm::dwarf::DW_TAG_reference_type, TD,
1077+ gDataLayout ->getPointerSizeInBits (), // size (bits)
1078+ DtoAlignment (type) * 8 ); // align (bits)
10491079#else
10501080 TD = DBuilder.createReferenceType (llvm::dwarf::DW_TAG_reference_type, TD);
10511081#endif
@@ -1122,10 +1152,15 @@ void ldc::DIBuilder::EmitLocalVariable(llvm::Value *ll, VarDeclaration *vd,
11221152#endif
11231153 variableMap[vd] = debugVariable;
11241154
1125- // declare
1126- Declare (vd->loc , ll, debugVariable, addr.empty ()
1127- ? DBuilder.createExpression ()
1128- : DBuilder.createExpression (addr));
1155+ if (useDbgValueIntrinsic) {
1156+ SetValue (vd->loc , ll, debugVariable,
1157+ addr.empty () ? DBuilder.createExpression ()
1158+ : DBuilder.createExpression (addr));
1159+ } else {
1160+ Declare (vd->loc , ll, debugVariable,
1161+ addr.empty () ? DBuilder.createExpression ()
1162+ : DBuilder.createExpression (addr));
1163+ }
11291164}
11301165
11311166void ldc::DIBuilder::EmitGlobalVariable (llvm::GlobalVariable *llVar,
0 commit comments