namespace {
class HeaderBuilder {
+ /// \brief Whether there are any fields yet.
+ ///
+ /// Note that this is not equivalent to \c Chars.empty(), since \a concat()
+ /// may have been called already with an empty string.
+ bool IsEmpty;
SmallVector<char, 256> Chars;
public:
- explicit HeaderBuilder(Twine T) { T.toVector(Chars); }
- HeaderBuilder(const HeaderBuilder &X) : Chars(X.Chars) {}
- HeaderBuilder(HeaderBuilder &&X) : Chars(std::move(X.Chars)) {}
+ HeaderBuilder() : IsEmpty(true) {}
+ HeaderBuilder(const HeaderBuilder &X) : IsEmpty(X.IsEmpty), Chars(X.Chars) {}
+ HeaderBuilder(HeaderBuilder &&X)
+ : IsEmpty(X.IsEmpty), Chars(std::move(X.Chars)) {}
template <class Twineable> HeaderBuilder &concat(Twineable &&X) {
- Chars.push_back(0);
+ if (IsEmpty)
+ IsEmpty = false;
+ else
+ Chars.push_back(0);
Twine(X).toVector(Chars);
return *this;
}
}
static HeaderBuilder get(unsigned Tag) {
- return HeaderBuilder("0x" + Twine::utohexstr(Tag));
+ return HeaderBuilder().concat("0x" + Twine::utohexstr(Tag));
}
};
}
// Now that all temp nodes have been replaced or deleted, resolve remaining
// cycles.
for (const auto &N : UnresolvedNodes)
- if (N)
- cast<UniquableMDNode>(N)->resolveCycles();
+ if (N && !N->isResolved())
+ N->resolveCycles();
UnresolvedNodes.clear();
// Can't handle unresolved nodes anymore.
DebugEmissionKind Kind,
bool EmitDebugInfo) {
- assert(((Lang <= dwarf::DW_LANG_OCaml && Lang >= dwarf::DW_LANG_C89) ||
+ assert(((Lang <= dwarf::DW_LANG_Fortran08 && Lang >= dwarf::DW_LANG_C89) ||
(Lang <= dwarf::DW_LANG_hi_user && Lang >= dwarf::DW_LANG_lo_user)) &&
"Invalid Language tag");
assert(!Filename.empty() &&
"Unable to create compile unit without filename");
Metadata *TElts[] = {HeaderBuilder::get(DW_TAG_base_type).get(VMContext)};
- TempEnumTypes = MDNode::getTemporary(VMContext, TElts);
+ TempEnumTypes = MDNode::getTemporary(VMContext, TElts).release();
- TempRetainTypes = MDNode::getTemporary(VMContext, TElts);
+ TempRetainTypes = MDNode::getTemporary(VMContext, TElts).release();
- TempSubprograms = MDNode::getTemporary(VMContext, TElts);
+ TempSubprograms = MDNode::getTemporary(VMContext, TElts).release();
- TempGVs = MDNode::getTemporary(VMContext, TElts);
+ TempGVs = MDNode::getTemporary(VMContext, TElts).release();
- TempImportedModules = MDNode::getTemporary(VMContext, TElts);
+ TempImportedModules = MDNode::getTemporary(VMContext, TElts).release();
Metadata *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_compile_unit)
.concat(Lang)
.concat(Flags)
.get(VMContext),
nullptr, Ty.getRef(), BaseTy.getRef()};
- return DIDerivedType(MDNode::get(VMContext, Elts));
+ auto R = DIDerivedType(MDNode::get(VMContext, Elts));
+ trackIfUnresolved(R);
+ return R;
}
DIDerivedType DIBuilder::createMemberType(DIDescriptor Scope, StringRef Name,
Flags = 0;
Flags |= FlagsToSet;
- return HeaderBuilder(Twine(I.getPrefix())).concat(Flags).concat(
- I.getSuffix());
+ return HeaderBuilder()
+ .concat(I.getPrefix())
+ .concat(Flags)
+ .concat(I.getSuffix());
}
static DIType createTypeWithFlags(LLVMContext &Context, DIType Ty,
return RetTy;
}
-DICompositeType DIBuilder::createReplaceableForwardDecl(
+DICompositeType DIBuilder::createReplaceableCompositeType(
unsigned Tag, StringRef Name, DIDescriptor Scope, DIFile F, unsigned Line,
unsigned RuntimeLang, uint64_t SizeInBits, uint64_t AlignInBits,
- StringRef UniqueIdentifier) {
+ unsigned Flags, StringRef UniqueIdentifier) {
// Create a temporary MDNode.
Metadata *Elts[] = {
HeaderBuilder::get(Tag)
.concat(SizeInBits)
.concat(AlignInBits)
.concat(0) // Offset
- .concat(DIDescriptor::FlagFwdDecl)
+ .concat(Flags)
.concat(RuntimeLang)
.get(VMContext),
F.getFileNode(), DIScope(getNonCompileUnitScope(Scope)).getRef(), nullptr,
nullptr, // TemplateParams
UniqueIdentifier.empty() ? nullptr
: MDString::get(VMContext, UniqueIdentifier)};
- DICompositeType RetTy(MDNode::getTemporary(VMContext, Elts));
+ DICompositeType RetTy(MDNode::getTemporary(VMContext, Elts).release());
assert(RetTy.isCompositeType() &&
"createReplaceableForwardDecl result should be a DIType");
if (!UniqueIdentifier.empty())
return createGlobalVariableHelper(VMContext, Context, Name, LinkageName, F,
LineNumber, Ty, isLocalToUnit, Val, Decl,
false, [&](ArrayRef<Metadata *> Elts) {
- return MDNode::getTemporary(VMContext, Elts);
+ return MDNode::getTemporary(VMContext, Elts).release();
});
}
return RetVar;
}
-DIExpression DIBuilder::createExpression(ArrayRef<int64_t> Addr) {
+DIExpression DIBuilder::createExpression(ArrayRef<uint64_t> Addr) {
auto Header = HeaderBuilder::get(DW_TAG_expression);
- for (int64_t I : Addr)
+ for (uint64_t I : Addr)
Header.concat(I);
Metadata *Elts[] = {Header.get(VMContext)};
return DIExpression(MDNode::get(VMContext, Elts));
}
-DIExpression DIBuilder::createPieceExpression(unsigned OffsetInBytes,
- unsigned SizeInBytes) {
- int64_t Addr[] = {dwarf::DW_OP_piece, OffsetInBytes, SizeInBytes};
+DIExpression DIBuilder::createExpression(ArrayRef<int64_t> Signed) {
+ // TODO: Remove the callers of this signed version and delete.
+ SmallVector<uint64_t, 8> Addr(Signed.begin(), Signed.end());
+ return createExpression(Addr);
+}
+
+DIExpression DIBuilder::createBitPieceExpression(unsigned OffsetInBits,
+ unsigned SizeInBits) {
+ int64_t Addr[] = {dwarf::DW_OP_bit_piece, OffsetInBits, SizeInBits};
return createExpression(Addr);
}
return createFunctionHelper(VMContext, Context, Name, LinkageName, File,
LineNo, Ty, isLocalToUnit, isDefinition,
ScopeLine, Flags, isOptimized, Fn, TParams, Decl,
- MDNode::getTemporary(VMContext, None),
+ MDNode::getTemporary(VMContext, None).release(),
[&](ArrayRef<Metadata *> Elts) -> MDNode *{
MDNode *Node = MDNode::get(VMContext, Elts);
// Create a named metadata so that we
LineNo, Ty, isLocalToUnit, isDefinition,
ScopeLine, Flags, isOptimized, Fn, TParams, Decl,
nullptr, [&](ArrayRef<Metadata *> Elts) {
- return MDNode::getTemporary(VMContext, Elts);
+ return MDNode::getTemporary(VMContext, Elts).release();
});
}
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);
+ // Look for unresolved operands. T will drop RAUW support, orphaning any
+ // cycles underneath it.
+ if (T->isResolved())
+ for (const MDOperand &O : T->operands())
+ if (auto *N = dyn_cast_or_null<MDNode>(O))
+ trackIfUnresolved(N);
}
void DIBuilder::replaceArrays(DICompositeType &T, DIArray Elements,