diff options
| author | Duncan P. N. Exon Smith <dexonsmith@apple.com> | 2014-12-18 00:46:16 +0000 |
|---|---|---|
| committer | Duncan P. N. Exon Smith <dexonsmith@apple.com> | 2014-12-18 00:46:16 +0000 |
| commit | 97f07c2778d5a82bae0418e1f05f44baa388c046 (patch) | |
| tree | 7ba9903562e9aff04d23e6e9fb7673ec2b13d7f2 /llvm/lib/IR/DIBuilder.cpp | |
| parent | d927bd8d15183809789c875ba7371e92145a688e (diff) | |
| download | bcm5719-llvm-97f07c2778d5a82bae0418e1f05f44baa388c046.tar.gz bcm5719-llvm-97f07c2778d5a82bae0418e1f05f44baa388c046.zip | |
IR: Handle self-referencing DICompositeTypes in DIBuilder
Add API to DIBuilder to handle self-referencing `DICompositeType`s.
Self-references aren't expected in the debug info graph, and we take
advantage of that by only calling `resolveCycles()` on nodes that were
once forward declarations (otherwise, DIBuilder needs an expensive
tracking reference to every unresolved node it creates, which in cyclic
graphs is *all of them*).
However, clang seems to create self-referencing `DICompositeType`s. Add
API to manage this safely. The paired commit to clang will include the
regression test.
I'll make the `DICompositeType` API `private` in a follow-up to prevent
misuse (I've separated that to prevent build failures from missing the
clang commit).
llvm-svn: 224482
Diffstat (limited to 'llvm/lib/IR/DIBuilder.cpp')
| -rw-r--r-- | llvm/lib/IR/DIBuilder.cpp | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/llvm/lib/IR/DIBuilder.cpp b/llvm/lib/IR/DIBuilder.cpp index ee7e6a2b21b..1874d31e0a5 100644 --- a/llvm/lib/IR/DIBuilder.cpp +++ b/llvm/lib/IR/DIBuilder.cpp @@ -1205,3 +1205,35 @@ Instruction *DIBuilder::insertDbgValueIntrinsic(Value *V, uint64_t Offset, MetadataAsValue::get(VMContext, Expr)}; return CallInst::Create(ValueFn, Args, "", InsertAtEnd); } + +void DIBuilder::replaceVTableHolder(DICompositeType &T, DICompositeType VTableHolder) { + T.setContainingType(VTableHolder); + + // If this didn't create a self-reference, just return. + if (T != VTableHolder) + return; + + // Look for unresolved operands. T has dropped RAUW support and is already + // marked resolved, orphaning any cycles underneath it. + assert(T->isResolved() && "Expected self-reference to be resolved"); + for (const MDOperand &O : T->operands()) + if (auto *N = dyn_cast_or_null<MDNode>(O)) + trackIfUnresolved(N); +} + +void DIBuilder::replaceArrays(DICompositeType &T, DIArray Elements, + DIArray TParams) { + T.setArrays(Elements, TParams); + + // If T isn't resolved, there's no problem. + if (!T->isResolved()) + return; + + // If "T" is resolved, it may be due to a self-reference cycle. Track the + // arrays explicitly if they're unresolved, or else the cycles will be + // orphaned. + if (Elements) + trackIfUnresolved(Elements); + if (TParams) + trackIfUnresolved(TParams); +} |

