SHA256
1
0
forked from pool/ldc
ldc/ldc-0.17.5-backport_pr_2315.patch
Marc Schütz 9878662e8a Accepting request 614484 from home:Guillaume_G:branches:devel:languages:D
- Add patch to fix ARM builds:
  * ldc-1.9.0-fix_arm_build.patch

- Update to 1.9.0 and use 0.17.5 to bootstrap

- Add patch to fix rpmlint error:
  * ldc-0.17.5-add_missing_include.patch
- Add patches to add LLVM6 support:
  * ldc-0.17.5-add_support_to_LLVM6.patch
  * ldc-0.17.5-backport_pr_2315.patch
- Add patch to be able to use ldc:
  * ldc-0.17.5-default-to-pic.patch

- update to version 0.17.5:
  * Added LLVM 5.0 support.
  * druntime: fixes for Android and addition of core.math.yl2x[p1]() for x86(_64) targets.
  * dmd-testsuite: backported runnable/cppa.d fix for GCC > 5.
  * CI updates.

OBS-URL: https://build.opensuse.org/request/show/614484
OBS-URL: https://build.opensuse.org/package/show/devel:languages:D/ldc?expand=0&rev=14
2018-06-06 10:24:25 +00:00

434 lines
17 KiB
Diff

From 6ed3ce435845e72ce8c88d39c0f7d3fb950ef54e Mon Sep 17 00:00:00 2001
From: Johan Engelen <jbc.engelen@gmail.com>
Date: Mon, 18 Sep 2017 23:11:32 +0200
Subject: [PATCH] Backport PR #2315.
The change is to fix debuginfo build errors with Phobos and LLVM5.0. This PR is mostly copy-pasting from master and fixing compile errors, so not much checking whether things make sense or not for LTS.
---
gen/dibuilder.cpp | 104 ++++++++++++++++++++++++++++++++++++++++++++----------
gen/dibuilder.h | 13 +++++--
gen/functions.cpp | 11 +++---
gen/nested.cpp | 103 ++++++++++++++++++++++++++++-------------------------
4 files changed, 159 insertions(+), 72 deletions(-)
diff --git a/gen/dibuilder.cpp b/gen/dibuilder.cpp
index f322811ea..1bc9c47c2 100644
--- a/gen/dibuilder.cpp
+++ b/gen/dibuilder.cpp
@@ -62,7 +62,9 @@ Module *ldc::DIBuilder::getDefinedModule(Dsymbol *s) {
////////////////////////////////////////////////////////////////////////////////
ldc::DIBuilder::DIBuilder(IRState *const IR)
- : IR(IR), DBuilder(IR->module), CUNode(nullptr) {}
+ : IR(IR), DBuilder(IR->module), CUNode(nullptr),
+ isTargetMSVCx64(global.params.targetTriple.isWindowsMSVCEnvironment() &&
+ global.params.targetTriple.isArch64Bit()) {}
llvm::LLVMContext &ldc::DIBuilder::getContext() { return IR->context(); }
@@ -75,7 +77,7 @@ ldc::DIScope ldc::DIBuilder::GetCurrentScope() {
return fn->diLexicalBlocks.top();
}
-void ldc::DIBuilder::Declare(const Loc &loc, llvm::Value *var,
+void ldc::DIBuilder::Declare(const Loc &loc, llvm::Value *storage,
ldc::DILocalVariable divar
#if LDC_LLVM_VER >= 306
,
@@ -83,19 +85,42 @@ void ldc::DIBuilder::Declare(const Loc &loc, llvm::Value *var,
#endif
) {
unsigned charnum = (loc.linnum ? loc.charnum : 0);
+ auto debugLoc = llvm::DebugLoc::get(loc.linnum, charnum, GetCurrentScope());
#if LDC_LLVM_VER < 307
- llvm::Instruction *instr = DBuilder.insertDeclare(var, divar,
+ llvm::Instruction *instr = DBuilder.insertDeclare(storage, divar,
#if LDC_LLVM_VER >= 306
diexpr,
#endif
IR->scopebb());
- instr->setDebugLoc(
- llvm::DebugLoc::get(loc.linnum, charnum, GetCurrentScope()));
+ instr->setDebugLoc(debugLoc);
+#else // if LLVM >= 3.7
+ DBuilder.insertDeclare(storage, divar, diexpr, debugLoc, IR->scopebb());
+#endif
+}
+
+// Sets the (current) value for a debuginfo variable.
+void ldc::DIBuilder::SetValue(const Loc &loc, llvm::Value *value,
+ ldc::DILocalVariable divar
+#if LDC_LLVM_VER >= 306
+ ,
+ ldc::DIExpression diexpr
+#endif
+ ) {
+ unsigned charnum = (loc.linnum ? loc.charnum : 0);
+ auto debugLoc = llvm::DebugLoc::get(loc.linnum, charnum, GetCurrentScope());
+#if LDC_LLVM_VER < 307
+ llvm::Instruction *instr = DBuilder.insertDbgValueIntrinsic(value, divar,
+#if LDC_LLVM_VER >= 306
+ diexpr,
+#endif
+ IR->scopebb());
+ instr->setDebugLoc(debugLoc);
#else // if LLVM >= 3.7
- DBuilder.insertDeclare(
- var, divar, diexpr,
- llvm::DebugLoc::get(loc.linnum, charnum, GetCurrentScope()),
- IR->scopebb());
+ DBuilder.insertDbgValueIntrinsic(value,
+#if LDC_LLVM_VER < 600
+ 0,
+#endif
+ divar, diexpr, debugLoc, IR->scopebb());
#endif
}
@@ -852,6 +877,7 @@ void ldc::DIBuilder::EmitValue(llvm::Value *val, VarDeclaration *vd) {
void ldc::DIBuilder::EmitLocalVariable(llvm::Value *ll, VarDeclaration *vd,
Type *type, bool isThisPtr,
+ bool forceAsLocal, bool isRefRVal,
#if LDC_LLVM_VER >= 306
llvm::ArrayRef<int64_t> addr
#else
@@ -872,13 +898,46 @@ void ldc::DIBuilder::EmitLocalVariable(llvm::Value *ll, VarDeclaration *vd,
}
// get type description
- ldc::DIType TD = CreateTypeDescription(type ? type : vd->type, true);
+ if (!type)
+ type = vd->type;
+ ldc::DIType TD = CreateTypeDescription(type, true);
if (static_cast<llvm::MDNode *>(TD) == nullptr) {
return; // unsupported
}
- if (vd->storage_class & (STCref | STCout)) {
+ const bool isRefOrOut = vd->isRef() || vd->isOut(); // incl. special-ref vars
+
+ // For MSVC x64 targets, declare params rewritten by ExplicitByvalRewrite as
+ // DI references, as if they were ref parameters.
+ const bool isPassedExplicitlyByval =
+ isTargetMSVCx64 && !isRefOrOut && isaArgument(ll) && addr.empty();
+
+ bool useDbgValueIntrinsic = false;
+ if (isRefOrOut || isPassedExplicitlyByval) {
+ // With the exception of special-ref loop variables, the reference/pointer
+ // itself is constant. So we don't have to attach the debug information to a
+ // memory location and can use llvm.dbg.value to set the constant pointer
+ // for the DI reference.
+ useDbgValueIntrinsic =
+ isPassedExplicitlyByval || (!isSpecialRefVar(vd) && isRefRVal);
+#if LDC_LLVM_VER >= 308
+ // Note: createReferenceType expects the size to be the size of a pointer,
+ // not the size of the type the reference refers to.
+ TD = DBuilder.createReferenceType(
+ llvm::dwarf::DW_TAG_reference_type, TD,
+ gDataLayout->getPointerSizeInBits(), // size (bits)
+ DtoAlignment(type) * 8); // align (bits)
+#else
TD = DBuilder.createReferenceType(llvm::dwarf::DW_TAG_reference_type, TD);
+#endif
+ } else {
+ // FIXME: For MSVC x64 targets, declare dynamic array and vector parameters
+ // as DI locals to work around garbage for both cdb and VS debuggers.
+ if (isTargetMSVCx64) {
+ TY ty = type->toBasetype()->ty;
+ if (ty == Tarray || ty == Tvector)
+ forceAsLocal = true;
+ }
}
// get variable description
@@ -886,7 +945,7 @@ void ldc::DIBuilder::EmitLocalVariable(llvm::Value *ll, VarDeclaration *vd,
#if LDC_LLVM_VER < 308
unsigned tag;
- if (vd->isParameter()) {
+ if (!forceAsLocal && vd->isParameter()) {
tag = llvm::dwarf::DW_TAG_arg_variable;
} else {
tag = llvm::dwarf::DW_TAG_auto_variable;
@@ -930,7 +989,7 @@ void ldc::DIBuilder::EmitLocalVariable(llvm::Value *ll, VarDeclaration *vd,
Flags // flags
);
#else
- if (vd->isParameter()) {
+ if (!forceAsLocal && vd->isParameter()) {
FuncDeclaration *fd = vd->parent->isFuncDeclaration();
assert(fd);
size_t argNo = 0;
@@ -970,14 +1029,23 @@ void ldc::DIBuilder::EmitLocalVariable(llvm::Value *ll, VarDeclaration *vd,
#endif
variableMap[vd] = debugVariable;
-// declare
+ if (useDbgValueIntrinsic) {
#if LDC_LLVM_VER >= 306
- Declare(vd->loc, ll, debugVariable, addr.empty()
- ? DBuilder.createExpression()
- : DBuilder.createExpression(addr));
+ SetValue(vd->loc, ll, debugVariable,
+ addr.empty() ? DBuilder.createExpression()
+ : DBuilder.createExpression(addr));
#else
- Declare(vd->loc, ll, debugVariable);
+ SetValue(vd->loc, ll, debugVariable);
#endif
+ } else {
+#if LDC_LLVM_VER >= 306
+ Declare(vd->loc, ll, debugVariable,
+ addr.empty() ? DBuilder.createExpression()
+ : DBuilder.createExpression(addr));
+#else
+ Declare(vd->loc, ll, debugVariable);
+#endif
+ }
}
void
diff --git a/gen/dibuilder.h b/gen/dibuilder.h
index fbfa830da..8fc5dea6c 100644
--- a/gen/dibuilder.h
+++ b/gen/dibuilder.h
@@ -79,6 +79,8 @@ class DIBuilder {
const llvm::MDNode *CUNode;
#endif
+ const bool isTargetMSVCx64;
+
DICompileUnit GetCU() {
#if LDC_LLVM_VER >= 307
return CUNode;
@@ -133,7 +135,8 @@ class DIBuilder {
/// \param addr An array of complex address operations.
void
EmitLocalVariable(llvm::Value *ll, VarDeclaration *vd, Type *type = nullptr,
- bool isThisPtr = false,
+ bool isThisPtr = false, bool forceAsLocal = false,
+ bool isRefRVal = false,
#if LDC_LLVM_VER >= 306
llvm::ArrayRef<int64_t> addr = llvm::ArrayRef<int64_t>()
#else
@@ -155,12 +158,18 @@ class DIBuilder {
llvm::LLVMContext &getContext();
Module *getDefinedModule(Dsymbol *s);
DIScope GetCurrentScope();
- void Declare(const Loc &loc, llvm::Value *var, ldc::DILocalVariable divar
+ void Declare(const Loc &loc, llvm::Value *storage, ldc::DILocalVariable divar
#if LDC_LLVM_VER >= 306
,
ldc::DIExpression diexpr
#endif
);
+ void SetValue(const Loc &loc, llvm::Value *value, ldc::DILocalVariable divar
+#if LDC_LLVM_VER >= 306
+ ,
+ ldc::DIExpression diexpr
+#endif
+ );
void AddBaseFields(ClassDeclaration *sd, ldc::DIFile file,
#if LDC_LLVM_VER >= 306
std::vector<llvm::Metadata *> &elems
diff --git a/gen/functions.cpp b/gen/functions.cpp
index 796124db4..107779ecd 100644
--- a/gen/functions.cpp
+++ b/gen/functions.cpp
@@ -861,10 +861,13 @@ void DtoDefineFunction(FuncDeclaration *fd) {
++llArgIdx;
}
- if (global.params.symdebug &&
- !(isaArgument(irparam->value) &&
- isaArgument(irparam->value)->hasByValAttr())) {
- gIR->DBuilder.EmitLocalVariable(irparam->value, vd, debugInfoType);
+ // The debuginfos for captured params are handled later by
+ // DtoCreateNestedContext().
+ if (global.params.symdebug && vd->nestedrefs.dim == 0) {
+ // Reference (ref/out) parameters have no storage themselves as they are
+ // constant pointers, so pass the reference rvalue to EmitLocalVariable().
+ gIR->DBuilder.EmitLocalVariable(irparam->value, vd, debugInfoType,
+ false, false, /*isRefRVal=*/true);
}
}
}
diff --git a/gen/nested.cpp b/gen/nested.cpp
index 2a13a1aa6..2b72f9873 100644
--- a/gen/nested.cpp
+++ b/gen/nested.cpp
@@ -58,14 +58,13 @@ DValue *DtoNestedVariable(Loc &loc, Type *astype, VarDeclaration *vd,
// Check whether we can access the needed frame
FuncDeclaration *fd = irfunc->decl;
- while (fd != vdparent) {
- if (fd->isStatic()) {
- error(loc, "function %s cannot access frame of function %s",
- irfunc->decl->toPrettyChars(), vdparent->toPrettyChars());
- return new DVarValue(astype, llvm::UndefValue::get(DtoPtrToType(astype)));
- }
+ while (fd && fd != vdparent) {
fd = getParentFunc(fd, false);
- assert(fd);
+ }
+ if (!fd) {
+ error(loc, "function %s cannot access frame of function %s",
+ irfunc->decl->toPrettyChars(), vdparent->toPrettyChars());
+ return new DVarValue(astype, llvm::UndefValue::get(DtoPtrToType(astype)));
}
// is the nested variable in this scope?
@@ -73,38 +72,32 @@ DValue *DtoNestedVariable(Loc &loc, Type *astype, VarDeclaration *vd,
return makeVarDValue(astype, vd);
}
- LLValue *dwarfValue = nullptr;
-#if LDC_LLVM_VER >= 306
- std::vector<int64_t> dwarfAddr;
-#else
- std::vector<LLValue *> dwarfAddr;
-#endif
-
// get the nested context
LLValue *ctx = nullptr;
- if (irfunc->nestedVar) {
- // If this function has its own nested context struct, always load it.
- ctx = irfunc->nestedVar;
- dwarfValue = ctx;
+ bool skipDIDeclaration = false;
+ auto currentCtx = irfunc->nestedVar;
+ if (currentCtx) {
+ Logger::println("Using own nested context of current function");
+ ctx = currentCtx;
} else if (irfunc->decl->isMember2()) {
- // If this is a member function of a nested class without its own
- // context, load the vthis member.
+ Logger::println(
+ "Current function is member of nested class, loading vthis");
+
AggregateDeclaration *cd = irfunc->decl->isMember2();
LLValue *val = irfunc->thisArg;
if (cd->isClassDeclaration()) {
val = DtoLoad(val);
}
ctx = DtoLoad(DtoGEPi(val, 0, getVthisIdx(cd), ".vthis"));
+ skipDIDeclaration = true;
} else {
- // Otherwise, this is a simple nested function, load from the context
- // argument.
+ Logger::println("Regular nested function, loading context arg");
+
ctx = DtoLoad(irfunc->nestArg);
- dwarfValue = irfunc->nestArg;
- if (global.params.symdebug) {
- gIR->DBuilder.OpDeref(dwarfAddr);
- }
}
+
assert(ctx);
+ IF_LOG { Logger::cout() << "Context: " << *ctx << '\n'; }
DtoCreateNestedContextType(vdparent->isFuncDeclaration());
assert(isIrLocalCreated(vd));
@@ -112,11 +105,9 @@ DValue *DtoNestedVariable(Loc &loc, Type *astype, VarDeclaration *vd,
////////////////////////////////////
// Extract variable from nested context
- LLValue *val = DtoBitCast(ctx, LLPointerType::getUnqual(irfunc->frameType));
- IF_LOG {
- Logger::cout() << "Context: " << *val << '\n';
- Logger::cout() << "of type: " << *irfunc->frameType << '\n';
- }
+ const auto frameType = LLPointerType::getUnqual(irfunc->frameType);
+ IF_LOG { Logger::cout() << "casting to: " << *irfunc->frameType << '\n'; }
+ LLValue *val = DtoBitCast(ctx, frameType);
IrLocal *const irLocal = getIrLocal(vd);
const auto vardepth = irLocal->nestedDepth;
@@ -135,10 +126,6 @@ DValue *DtoNestedVariable(Loc &loc, Type *astype, VarDeclaration *vd,
IF_LOG Logger::println("Same depth");
} else {
// Load frame pointer and index that...
- if (dwarfValue && global.params.symdebug) {
- gIR->DBuilder.OpOffset(dwarfAddr, val, vardepth);
- gIR->DBuilder.OpDeref(dwarfAddr);
- }
IF_LOG Logger::println("Lower depth");
val = DtoGEPi(val, 0, vardepth);
IF_LOG Logger::cout() << "Frame index: " << *val << '\n';
@@ -150,27 +137,42 @@ DValue *DtoNestedVariable(Loc &loc, Type *astype, VarDeclaration *vd,
const auto idx = irLocal->nestedIndex;
assert(idx != -1 && "Nested context not yet resolved for variable.");
- if (dwarfValue && global.params.symdebug) {
- gIR->DBuilder.OpOffset(dwarfAddr, val, idx);
- }
+#if LDC_LLVM_VER >= 306
+ std::vector<int64_t> dwarfAddrOps;
+#else
+ std::vector<LLValue *> dwarfAddrOps;
+#endif
- val = DtoGEPi(val, 0, idx, vd->toChars());
+ LLValue *gep = DtoGEPi(val, 0, idx, vd->toChars());
+ val = gep;
IF_LOG {
Logger::cout() << "Addr: " << *val << '\n';
Logger::cout() << "of type: " << *val->getType() << '\n';
}
- if (byref || (vd->isParameter() && getIrParameter(vd)->arg &&
- getIrParameter(vd)->arg->byref)) {
+ const bool isRefOrOut = vd->isRef() || vd->isOut();
+ if (isSpecialRefVar(vd)) {
+ // Handled appropriately by makeVarDValue() and EmitLocalVariable(), pass
+ // storage of pointer (reference lvalue).
+ } else if (byref || isRefOrOut) {
val = DtoAlignedLoad(val);
- // dwarfOpDeref(dwarfAddr);
+ // ref/out variables get a reference-debuginfo-type in EmitLocalVariable();
+ // pass the GEP as reference lvalue in that case.
+ if (!isRefOrOut)
+ gIR->DBuilder.OpDeref(dwarfAddrOps);
IF_LOG {
Logger::cout() << "Was byref, now: " << *irLocal->value << '\n';
Logger::cout() << "of type: " << *irLocal->value->getType() << '\n';
}
}
- if (dwarfValue && global.params.symdebug) {
- gIR->DBuilder.EmitLocalVariable(dwarfValue, vd, nullptr, false, dwarfAddr);
+ if (!skipDIDeclaration && global.params.symdebug) {
+#if LDC_LLVM_VER < 500
+ // Because we are passing a GEP instead of an alloca to
+ // llvm.dbg.declare, we have to make the address dereference explicit.
+ gIR->DBuilder.OpDeref(dwarfAddrOps);
+#endif
+ gIR->DBuilder.EmitLocalVariable(gep, vd, nullptr, false,
+ /*forceAsLocal=*/true, false, dwarfAddrOps);
}
return makeVarDValue(astype, vd, val);
@@ -532,12 +534,17 @@ void DtoCreateNestedContext(FuncDeclaration *fd) {
if (global.params.symdebug) {
#if LDC_LLVM_VER >= 306
- LLSmallVector<int64_t, 2> addr;
+ LLSmallVector<int64_t, 2> dwarfAddrOps;
#else
- LLSmallVector<LLValue *, 2> addr;
+ LLSmallVector<LLValue *, 2> dwarfAddrOps;
+#endif
+#if LDC_LLVM_VER < 500
+ // Because we are passing a GEP instead of an alloca to
+ // llvm.dbg.declare, we have to make the address dereference explicit.
+ gIR->DBuilder.OpDeref(dwarfAddrOps);
#endif
- gIR->DBuilder.OpOffset(addr, frameType, irLocal->nestedIndex);
- gIR->DBuilder.EmitLocalVariable(gep, vd, nullptr, false, addr);
+ gIR->DBuilder.EmitLocalVariable(gep, vd, nullptr, false, false, false,
+ dwarfAddrOps);
}
}
}