summaryrefslogtreecommitdiff
path: root/lib/IR
diff options
context:
space:
mode:
authorAdrian Prantl <aprantl@apple.com>2017-11-07 00:45:34 +0000
committerAdrian Prantl <aprantl@apple.com>2017-11-07 00:45:34 +0000
commit0227fe59a98b795b40e1e4b1b08cbe373d4c54c7 (patch)
tree9327c8b174a2151b7bdd925941b317ceb7b13069 /lib/IR
parented2657e43a72b4374b54ab9da9ffa0cc26630851 (diff)
Make DIExpression::createFragmentExpression() return an Optional.
We can't safely split arithmetic into multiple fragments because we can't express carry-over between fragments. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@317534 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/IR')
-rw-r--r--lib/IR/DebugInfoMetadata.cpp20
1 files changed, 15 insertions, 5 deletions
diff --git a/lib/IR/DebugInfoMetadata.cpp b/lib/IR/DebugInfoMetadata.cpp
index 0a9c5c19e5a..ae02392ea14 100644
--- a/lib/IR/DebugInfoMetadata.cpp
+++ b/lib/IR/DebugInfoMetadata.cpp
@@ -753,14 +753,23 @@ DIExpression *DIExpression::prepend(const DIExpression *Expr, bool Deref,
return DIExpression::get(Expr->getContext(), Ops);
}
-DIExpression *DIExpression::createFragmentExpression(const DIExpression *Expr,
- unsigned OffsetInBits,
- unsigned SizeInBits) {
+Optional<DIExpression *> DIExpression::createFragmentExpression(
+ const DIExpression *Expr, unsigned OffsetInBits, unsigned SizeInBits) {
SmallVector<uint64_t, 8> Ops;
// Copy over the expression, but leave off any trailing DW_OP_LLVM_fragment.
if (Expr) {
for (auto Op : Expr->expr_ops()) {
- if (Op.getOp() == dwarf::DW_OP_LLVM_fragment) {
+ switch (Op.getOp()) {
+ default: break;
+ case dwarf::DW_OP_plus:
+ case dwarf::DW_OP_minus:
+ // We can't safely split arithmetic into multiple fragments because we
+ // can't express carry-over between fragments.
+ //
+ // FIXME: We *could* preserve the lowest fragment of a constant offset
+ // operation if the offset fits into SizeInBits.
+ return None;
+ case dwarf::DW_OP_LLVM_fragment: {
// Make the new offset point into the existing fragment.
uint64_t FragmentOffsetInBits = Op.getArg(0);
// Op.getArg(0) is FragmentOffsetInBits.
@@ -768,7 +777,8 @@ DIExpression *DIExpression::createFragmentExpression(const DIExpression *Expr,
assert((OffsetInBits + SizeInBits <= Op.getArg(0) + Op.getArg(1)) &&
"new fragment outside of original fragment");
OffsetInBits += FragmentOffsetInBits;
- break;
+ continue;
+ }
}
Ops.push_back(Op.getOp());
for (unsigned I = 0; I < Op.getNumArgs(); ++I)