summaryrefslogtreecommitdiffstats
path: root/llvm/lib/IR/DebugInfo.cpp
diff options
context:
space:
mode:
authorDavid Blaikie <dblaikie@gmail.com>2014-05-06 03:41:57 +0000
committerDavid Blaikie <dblaikie@gmail.com>2014-05-06 03:41:57 +0000
commitd3f094a33be49952b8506fba5a34278781c9b113 (patch)
tree4b5aaf448e755c25adb3a185934637d0fd2c60bf /llvm/lib/IR/DebugInfo.cpp
parent9ef9ca470fbfbef88aadd2213e3d39574cdbba72 (diff)
downloadbcm5719-llvm-d3f094a33be49952b8506fba5a34278781c9b113.tar.gz
bcm5719-llvm-d3f094a33be49952b8506fba5a34278781c9b113.zip
PR19598: Provide the ability to RAUW a declaration with itself, creating a non-temporary copy and using that to RAUW.
Also, provide the ability to create temporary and non-temporary declarations, as not all declarations may be replaced by definitions later on. This provides the necessary infrastructure for Clang to fix PR19598, leaking temporary MDNodes in Clang's debug info generation. llvm-svn: 208054
Diffstat (limited to 'llvm/lib/IR/DebugInfo.cpp')
-rw-r--r--llvm/lib/IR/DebugInfo.cpp39
1 files changed, 19 insertions, 20 deletions
diff --git a/llvm/lib/IR/DebugInfo.cpp b/llvm/lib/IR/DebugInfo.cpp
index cf8afe251ad..db9e56defa1 100644
--- a/llvm/lib/IR/DebugInfo.cpp
+++ b/llvm/lib/IR/DebugInfo.cpp
@@ -335,7 +335,7 @@ unsigned DIArray::getNumElements() const {
/// replaceAllUsesWith - Replace all uses of the MDNode used by this
/// type with the one in the passed descriptor.
-void DIType::replaceAllUsesWith(DIDescriptor &D) {
+void DIType::replaceAllUsesWith(LLVMContext &VMContext, DIDescriptor D) {
assert(DbgNode && "Trying to replace an unverified type!");
@@ -344,13 +344,19 @@ void DIType::replaceAllUsesWith(DIDescriptor &D) {
// which, due to uniquing, has merged with the source. We shield clients from
// this detail by allowing a value to be replaced with replaceAllUsesWith()
// itself.
- if (DbgNode != D) {
- MDNode *Node = const_cast<MDNode *>(DbgNode);
- const MDNode *DN = D;
- const Value *V = cast_or_null<Value>(DN);
- Node->replaceAllUsesWith(const_cast<Value *>(V));
- MDNode::deleteTemporary(Node);
+ const MDNode *DN = D;
+ if (DbgNode == DN) {
+ SmallVector<Value*, 10> Ops(DbgNode->getNumOperands());
+ for (size_t i = 0; i != Ops.size(); ++i)
+ Ops[i] = DbgNode->getOperand(i);
+ DN = MDNode::get(VMContext, Ops);
}
+
+ MDNode *Node = const_cast<MDNode *>(DbgNode);
+ const Value *V = cast_or_null<Value>(DN);
+ Node->replaceAllUsesWith(const_cast<Value *>(V));
+ MDNode::deleteTemporary(Node);
+ DbgNode = D;
}
/// replaceAllUsesWith - Replace all uses of the MDNode used by this
@@ -358,19 +364,12 @@ void DIType::replaceAllUsesWith(DIDescriptor &D) {
void DIType::replaceAllUsesWith(MDNode *D) {
assert(DbgNode && "Trying to replace an unverified type!");
-
- // Since we use a TrackingVH for the node, its easy for clients to manufacture
- // legitimate situations where they want to replaceAllUsesWith() on something
- // which, due to uniquing, has merged with the source. We shield clients from
- // this detail by allowing a value to be replaced with replaceAllUsesWith()
- // itself.
- if (DbgNode != D) {
- MDNode *Node = const_cast<MDNode *>(DbgNode);
- const MDNode *DN = D;
- const Value *V = cast_or_null<Value>(DN);
- Node->replaceAllUsesWith(const_cast<Value *>(V));
- MDNode::deleteTemporary(Node);
- }
+ assert(DbgNode != D && "This replacement should always happen");
+ MDNode *Node = const_cast<MDNode *>(DbgNode);
+ const MDNode *DN = D;
+ const Value *V = cast_or_null<Value>(DN);
+ Node->replaceAllUsesWith(const_cast<Value *>(V));
+ MDNode::deleteTemporary(Node);
}
/// Verify - Verify that a compile unit is well formed.
OpenPOWER on IntegriCloud