Path: blob/main/contrib/llvm-project/llvm/lib/IR/DebugProgramInstruction.cpp
35232 views
//=====-- DebugProgramInstruction.cpp - Implement DbgRecords/DbgMarkers --====//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "llvm/IR/DebugInfoMetadata.h"9#include "llvm/IR/DebugProgramInstruction.h"10#include "llvm/IR/DIBuilder.h"11#include "llvm/IR/IntrinsicInst.h"1213namespace llvm {1415template <typename T>16DbgRecordParamRef<T>::DbgRecordParamRef(const T *Param)17: Ref(const_cast<T *>(Param)) {}18template <typename T>19DbgRecordParamRef<T>::DbgRecordParamRef(const MDNode *Param)20: Ref(const_cast<MDNode *>(Param)) {}2122template <typename T> T *DbgRecordParamRef<T>::get() const {23return cast<T>(Ref);24}2526template class DbgRecordParamRef<DIExpression>;27template class DbgRecordParamRef<DILabel>;28template class DbgRecordParamRef<DILocalVariable>;2930DbgVariableRecord::DbgVariableRecord(const DbgVariableIntrinsic *DVI)31: DbgRecord(ValueKind, DVI->getDebugLoc()),32DebugValueUser({DVI->getRawLocation(), nullptr, nullptr}),33Variable(DVI->getVariable()), Expression(DVI->getExpression()),34AddressExpression() {35switch (DVI->getIntrinsicID()) {36case Intrinsic::dbg_value:37Type = LocationType::Value;38break;39case Intrinsic::dbg_declare:40Type = LocationType::Declare;41break;42case Intrinsic::dbg_assign: {43Type = LocationType::Assign;44const DbgAssignIntrinsic *Assign =45static_cast<const DbgAssignIntrinsic *>(DVI);46resetDebugValue(1, Assign->getRawAddress());47AddressExpression = Assign->getAddressExpression();48setAssignId(Assign->getAssignID());49break;50}51default:52llvm_unreachable(53"Trying to create a DbgVariableRecord with an invalid intrinsic type!");54}55}5657DbgVariableRecord::DbgVariableRecord(const DbgVariableRecord &DVR)58: DbgRecord(ValueKind, DVR.getDebugLoc()), DebugValueUser(DVR.DebugValues),59Type(DVR.getType()), Variable(DVR.getVariable()),60Expression(DVR.getExpression()),61AddressExpression(DVR.AddressExpression) {}6263DbgVariableRecord::DbgVariableRecord(Metadata *Location, DILocalVariable *DV,64DIExpression *Expr, const DILocation *DI,65LocationType Type)66: DbgRecord(ValueKind, DI), DebugValueUser({Location, nullptr, nullptr}),67Type(Type), Variable(DV), Expression(Expr) {}6869DbgVariableRecord::DbgVariableRecord(Metadata *Value, DILocalVariable *Variable,70DIExpression *Expression,71DIAssignID *AssignID, Metadata *Address,72DIExpression *AddressExpression,73const DILocation *DI)74: DbgRecord(ValueKind, DI), DebugValueUser({Value, Address, AssignID}),75Type(LocationType::Assign), Variable(Variable), Expression(Expression),76AddressExpression(AddressExpression) {}7778void DbgRecord::deleteRecord() {79switch (RecordKind) {80case ValueKind:81delete cast<DbgVariableRecord>(this);82return;83case LabelKind:84delete cast<DbgLabelRecord>(this);85return;86}87llvm_unreachable("unsupported DbgRecord kind");88}8990void DbgRecord::print(raw_ostream &O, bool IsForDebug) const {91switch (RecordKind) {92case ValueKind:93cast<DbgVariableRecord>(this)->print(O, IsForDebug);94return;95case LabelKind:96cast<DbgLabelRecord>(this)->print(O, IsForDebug);97return;98};99llvm_unreachable("unsupported DbgRecord kind");100}101102void DbgRecord::print(raw_ostream &O, ModuleSlotTracker &MST,103bool IsForDebug) const {104switch (RecordKind) {105case ValueKind:106cast<DbgVariableRecord>(this)->print(O, MST, IsForDebug);107return;108case LabelKind:109cast<DbgLabelRecord>(this)->print(O, MST, IsForDebug);110return;111};112llvm_unreachable("unsupported DbgRecord kind");113}114115bool DbgRecord::isIdenticalToWhenDefined(const DbgRecord &R) const {116if (RecordKind != R.RecordKind)117return false;118switch (RecordKind) {119case ValueKind:120return cast<DbgVariableRecord>(this)->isIdenticalToWhenDefined(121*cast<DbgVariableRecord>(&R));122case LabelKind:123return cast<DbgLabelRecord>(this)->getLabel() ==124cast<DbgLabelRecord>(R).getLabel();125};126llvm_unreachable("unsupported DbgRecord kind");127}128129bool DbgRecord::isEquivalentTo(const DbgRecord &R) const {130return getDebugLoc() == R.getDebugLoc() && isIdenticalToWhenDefined(R);131}132133DbgInfoIntrinsic *134DbgRecord::createDebugIntrinsic(Module *M, Instruction *InsertBefore) const {135switch (RecordKind) {136case ValueKind:137return cast<DbgVariableRecord>(this)->createDebugIntrinsic(M, InsertBefore);138case LabelKind:139return cast<DbgLabelRecord>(this)->createDebugIntrinsic(M, InsertBefore);140};141llvm_unreachable("unsupported DbgRecord kind");142}143144DbgLabelRecord::DbgLabelRecord(MDNode *Label, MDNode *DL)145: DbgRecord(LabelKind, DebugLoc(DL)), Label(Label) {146assert(Label && "Unexpected nullptr");147assert((isa<DILabel>(Label) || Label->isTemporary()) &&148"Label type must be or resolve to a DILabel");149}150DbgLabelRecord::DbgLabelRecord(DILabel *Label, DebugLoc DL)151: DbgRecord(LabelKind, DL), Label(Label) {152assert(Label && "Unexpected nullptr");153}154155DbgLabelRecord *DbgLabelRecord::createUnresolvedDbgLabelRecord(MDNode *Label,156MDNode *DL) {157return new DbgLabelRecord(Label, DL);158}159160DbgVariableRecord::DbgVariableRecord(DbgVariableRecord::LocationType Type,161Metadata *Val, MDNode *Variable,162MDNode *Expression, MDNode *AssignID,163Metadata *Address,164MDNode *AddressExpression, MDNode *DI)165: DbgRecord(ValueKind, DebugLoc(DI)),166DebugValueUser({Val, Address, AssignID}), Type(Type), Variable(Variable),167Expression(Expression), AddressExpression(AddressExpression) {}168169DbgVariableRecord *DbgVariableRecord::createUnresolvedDbgVariableRecord(170DbgVariableRecord::LocationType Type, Metadata *Val, MDNode *Variable,171MDNode *Expression, MDNode *AssignID, Metadata *Address,172MDNode *AddressExpression, MDNode *DI) {173return new DbgVariableRecord(Type, Val, Variable, Expression, AssignID,174Address, AddressExpression, DI);175}176177DbgVariableRecord *178DbgVariableRecord::createDbgVariableRecord(Value *Location, DILocalVariable *DV,179DIExpression *Expr,180const DILocation *DI) {181return new DbgVariableRecord(ValueAsMetadata::get(Location), DV, Expr, DI,182LocationType::Value);183}184185DbgVariableRecord *DbgVariableRecord::createDbgVariableRecord(186Value *Location, DILocalVariable *DV, DIExpression *Expr,187const DILocation *DI, DbgVariableRecord &InsertBefore) {188auto *NewDbgVariableRecord = createDbgVariableRecord(Location, DV, Expr, DI);189NewDbgVariableRecord->insertBefore(&InsertBefore);190return NewDbgVariableRecord;191}192193DbgVariableRecord *DbgVariableRecord::createDVRDeclare(Value *Address,194DILocalVariable *DV,195DIExpression *Expr,196const DILocation *DI) {197return new DbgVariableRecord(ValueAsMetadata::get(Address), DV, Expr, DI,198LocationType::Declare);199}200201DbgVariableRecord *202DbgVariableRecord::createDVRDeclare(Value *Address, DILocalVariable *DV,203DIExpression *Expr, const DILocation *DI,204DbgVariableRecord &InsertBefore) {205auto *NewDVRDeclare = createDVRDeclare(Address, DV, Expr, DI);206NewDVRDeclare->insertBefore(&InsertBefore);207return NewDVRDeclare;208}209210DbgVariableRecord *DbgVariableRecord::createDVRAssign(211Value *Val, DILocalVariable *Variable, DIExpression *Expression,212DIAssignID *AssignID, Value *Address, DIExpression *AddressExpression,213const DILocation *DI) {214return new DbgVariableRecord(ValueAsMetadata::get(Val), Variable, Expression,215AssignID, ValueAsMetadata::get(Address),216AddressExpression, DI);217}218219DbgVariableRecord *DbgVariableRecord::createLinkedDVRAssign(220Instruction *LinkedInstr, Value *Val, DILocalVariable *Variable,221DIExpression *Expression, Value *Address, DIExpression *AddressExpression,222const DILocation *DI) {223auto *Link = LinkedInstr->getMetadata(LLVMContext::MD_DIAssignID);224assert(Link && "Linked instruction must have DIAssign metadata attached");225auto *NewDVRAssign = DbgVariableRecord::createDVRAssign(226Val, Variable, Expression, cast<DIAssignID>(Link), Address,227AddressExpression, DI);228LinkedInstr->getParent()->insertDbgRecordAfter(NewDVRAssign, LinkedInstr);229return NewDVRAssign;230}231232iterator_range<DbgVariableRecord::location_op_iterator>233DbgVariableRecord::location_ops() const {234auto *MD = getRawLocation();235// If a Value has been deleted, the "location" for this DbgVariableRecord will236// be replaced by nullptr. Return an empty range.237if (!MD)238return {location_op_iterator(static_cast<ValueAsMetadata *>(nullptr)),239location_op_iterator(static_cast<ValueAsMetadata *>(nullptr))};240241// If operand is ValueAsMetadata, return a range over just that operand.242if (auto *VAM = dyn_cast<ValueAsMetadata>(MD))243return {location_op_iterator(VAM), location_op_iterator(VAM + 1)};244245// If operand is DIArgList, return a range over its args.246if (auto *AL = dyn_cast<DIArgList>(MD))247return {location_op_iterator(AL->args_begin()),248location_op_iterator(AL->args_end())};249250// Operand is an empty metadata tuple, so return empty iterator.251assert(cast<MDNode>(MD)->getNumOperands() == 0);252return {location_op_iterator(static_cast<ValueAsMetadata *>(nullptr)),253location_op_iterator(static_cast<ValueAsMetadata *>(nullptr))};254}255256unsigned DbgVariableRecord::getNumVariableLocationOps() const {257if (hasArgList())258return cast<DIArgList>(getRawLocation())->getArgs().size();259return 1;260}261262Value *DbgVariableRecord::getVariableLocationOp(unsigned OpIdx) const {263auto *MD = getRawLocation();264if (!MD)265return nullptr;266267if (auto *AL = dyn_cast<DIArgList>(MD))268return AL->getArgs()[OpIdx]->getValue();269if (isa<MDNode>(MD))270return nullptr;271assert(isa<ValueAsMetadata>(MD) &&272"Attempted to get location operand from DbgVariableRecord with none.");273auto *V = cast<ValueAsMetadata>(MD);274assert(OpIdx == 0 && "Operand Index must be 0 for a debug intrinsic with a "275"single location operand.");276return V->getValue();277}278279static ValueAsMetadata *getAsMetadata(Value *V) {280return isa<MetadataAsValue>(V) ? dyn_cast<ValueAsMetadata>(281cast<MetadataAsValue>(V)->getMetadata())282: ValueAsMetadata::get(V);283}284285void DbgVariableRecord::replaceVariableLocationOp(Value *OldValue,286Value *NewValue,287bool AllowEmpty) {288assert(NewValue && "Values must be non-null");289290bool DbgAssignAddrReplaced = isDbgAssign() && OldValue == getAddress();291if (DbgAssignAddrReplaced)292setAddress(NewValue);293294auto Locations = location_ops();295auto OldIt = find(Locations, OldValue);296if (OldIt == Locations.end()) {297if (AllowEmpty || DbgAssignAddrReplaced)298return;299llvm_unreachable("OldValue must be a current location");300}301302if (!hasArgList()) {303// Set our location to be the MAV wrapping the new Value.304setRawLocation(isa<MetadataAsValue>(NewValue)305? cast<MetadataAsValue>(NewValue)->getMetadata()306: ValueAsMetadata::get(NewValue));307return;308}309310// We must be referring to a DIArgList, produce a new operands vector with the311// old value replaced, generate a new DIArgList and set it as our location.312SmallVector<ValueAsMetadata *, 4> MDs;313ValueAsMetadata *NewOperand = getAsMetadata(NewValue);314for (auto *VMD : Locations)315MDs.push_back(VMD == *OldIt ? NewOperand : getAsMetadata(VMD));316setRawLocation(DIArgList::get(getVariableLocationOp(0)->getContext(), MDs));317}318319void DbgVariableRecord::replaceVariableLocationOp(unsigned OpIdx,320Value *NewValue) {321assert(OpIdx < getNumVariableLocationOps() && "Invalid Operand Index");322323if (!hasArgList()) {324setRawLocation(isa<MetadataAsValue>(NewValue)325? cast<MetadataAsValue>(NewValue)->getMetadata()326: ValueAsMetadata::get(NewValue));327return;328}329330SmallVector<ValueAsMetadata *, 4> MDs;331ValueAsMetadata *NewOperand = getAsMetadata(NewValue);332for (unsigned Idx = 0; Idx < getNumVariableLocationOps(); ++Idx)333MDs.push_back(Idx == OpIdx ? NewOperand334: getAsMetadata(getVariableLocationOp(Idx)));335336setRawLocation(DIArgList::get(getVariableLocationOp(0)->getContext(), MDs));337}338339void DbgVariableRecord::addVariableLocationOps(ArrayRef<Value *> NewValues,340DIExpression *NewExpr) {341assert(NewExpr->hasAllLocationOps(getNumVariableLocationOps() +342NewValues.size()) &&343"NewExpr for debug variable intrinsic does not reference every "344"location operand.");345assert(!is_contained(NewValues, nullptr) && "New values must be non-null");346setExpression(NewExpr);347SmallVector<ValueAsMetadata *, 4> MDs;348for (auto *VMD : location_ops())349MDs.push_back(getAsMetadata(VMD));350for (auto *VMD : NewValues)351MDs.push_back(getAsMetadata(VMD));352setRawLocation(DIArgList::get(getVariableLocationOp(0)->getContext(), MDs));353}354355void DbgVariableRecord::setKillLocation() {356// TODO: When/if we remove duplicate values from DIArgLists, we don't need357// this set anymore.358SmallPtrSet<Value *, 4> RemovedValues;359for (Value *OldValue : location_ops()) {360if (!RemovedValues.insert(OldValue).second)361continue;362Value *Poison = PoisonValue::get(OldValue->getType());363replaceVariableLocationOp(OldValue, Poison);364}365}366367bool DbgVariableRecord::isKillLocation() const {368return (!hasArgList() && isa<MDNode>(getRawLocation())) ||369(getNumVariableLocationOps() == 0 && !getExpression()->isComplex()) ||370any_of(location_ops(), [](Value *V) { return isa<UndefValue>(V); });371}372373std::optional<DbgVariableFragmentInfo> DbgVariableRecord::getFragment() const {374return getExpression()->getFragmentInfo();375}376377std::optional<uint64_t> DbgVariableRecord::getFragmentSizeInBits() const {378if (auto Fragment = getExpression()->getFragmentInfo())379return Fragment->SizeInBits;380return getVariable()->getSizeInBits();381}382383DbgRecord *DbgRecord::clone() const {384switch (RecordKind) {385case ValueKind:386return cast<DbgVariableRecord>(this)->clone();387case LabelKind:388return cast<DbgLabelRecord>(this)->clone();389};390llvm_unreachable("unsupported DbgRecord kind");391}392393DbgVariableRecord *DbgVariableRecord::clone() const {394return new DbgVariableRecord(*this);395}396397DbgLabelRecord *DbgLabelRecord::clone() const {398return new DbgLabelRecord(getLabel(), getDebugLoc());399}400401DbgVariableIntrinsic *402DbgVariableRecord::createDebugIntrinsic(Module *M,403Instruction *InsertBefore) const {404[[maybe_unused]] DICompileUnit *Unit =405getDebugLoc()->getScope()->getSubprogram()->getUnit();406assert(M && Unit &&407"Cannot clone from BasicBlock that is not part of a Module or "408"DICompileUnit!");409LLVMContext &Context = getDebugLoc()->getContext();410Function *IntrinsicFn;411412// Work out what sort of intrinsic we're going to produce.413switch (getType()) {414case DbgVariableRecord::LocationType::Declare:415IntrinsicFn = Intrinsic::getDeclaration(M, Intrinsic::dbg_declare);416break;417case DbgVariableRecord::LocationType::Value:418IntrinsicFn = Intrinsic::getDeclaration(M, Intrinsic::dbg_value);419break;420case DbgVariableRecord::LocationType::Assign:421IntrinsicFn = Intrinsic::getDeclaration(M, Intrinsic::dbg_assign);422break;423case DbgVariableRecord::LocationType::End:424case DbgVariableRecord::LocationType::Any:425llvm_unreachable("Invalid LocationType");426}427428// Create the intrinsic from this DbgVariableRecord's information, optionally429// insert into the target location.430DbgVariableIntrinsic *DVI;431assert(getRawLocation() &&432"DbgVariableRecord's RawLocation should be non-null.");433if (isDbgAssign()) {434Value *AssignArgs[] = {435MetadataAsValue::get(Context, getRawLocation()),436MetadataAsValue::get(Context, getVariable()),437MetadataAsValue::get(Context, getExpression()),438MetadataAsValue::get(Context, getAssignID()),439MetadataAsValue::get(Context, getRawAddress()),440MetadataAsValue::get(Context, getAddressExpression())};441DVI = cast<DbgVariableIntrinsic>(CallInst::Create(442IntrinsicFn->getFunctionType(), IntrinsicFn, AssignArgs));443} else {444Value *Args[] = {MetadataAsValue::get(Context, getRawLocation()),445MetadataAsValue::get(Context, getVariable()),446MetadataAsValue::get(Context, getExpression())};447DVI = cast<DbgVariableIntrinsic>(448CallInst::Create(IntrinsicFn->getFunctionType(), IntrinsicFn, Args));449}450DVI->setTailCall();451DVI->setDebugLoc(getDebugLoc());452if (InsertBefore)453DVI->insertBefore(InsertBefore);454455return DVI;456}457458DbgLabelInst *459DbgLabelRecord::createDebugIntrinsic(Module *M,460Instruction *InsertBefore) const {461auto *LabelFn = Intrinsic::getDeclaration(M, Intrinsic::dbg_label);462Value *Args[] = {463MetadataAsValue::get(getDebugLoc()->getContext(), getLabel())};464DbgLabelInst *DbgLabel = cast<DbgLabelInst>(465CallInst::Create(LabelFn->getFunctionType(), LabelFn, Args));466DbgLabel->setTailCall();467DbgLabel->setDebugLoc(getDebugLoc());468if (InsertBefore)469DbgLabel->insertBefore(InsertBefore);470return DbgLabel;471}472473Value *DbgVariableRecord::getAddress() const {474auto *MD = getRawAddress();475if (auto *V = dyn_cast_or_null<ValueAsMetadata>(MD))476return V->getValue();477478// When the value goes to null, it gets replaced by an empty MDNode.479assert(!MD ||480!cast<MDNode>(MD)->getNumOperands() && "Expected an empty MDNode");481return nullptr;482}483484DIAssignID *DbgVariableRecord::getAssignID() const {485return cast<DIAssignID>(DebugValues[2]);486}487488void DbgVariableRecord::setAssignId(DIAssignID *New) {489resetDebugValue(2, New);490}491492void DbgVariableRecord::setKillAddress() {493resetDebugValue(4941, ValueAsMetadata::get(UndefValue::get(getAddress()->getType())));495}496497bool DbgVariableRecord::isKillAddress() const {498Value *Addr = getAddress();499return !Addr || isa<UndefValue>(Addr);500}501502const Instruction *DbgRecord::getInstruction() const {503return Marker->MarkedInstr;504}505506const BasicBlock *DbgRecord::getParent() const {507return Marker->MarkedInstr->getParent();508}509510BasicBlock *DbgRecord::getParent() { return Marker->MarkedInstr->getParent(); }511512BasicBlock *DbgRecord::getBlock() { return Marker->getParent(); }513514const BasicBlock *DbgRecord::getBlock() const { return Marker->getParent(); }515516Function *DbgRecord::getFunction() { return getBlock()->getParent(); }517518const Function *DbgRecord::getFunction() const {519return getBlock()->getParent();520}521522Module *DbgRecord::getModule() { return getFunction()->getParent(); }523524const Module *DbgRecord::getModule() const {525return getFunction()->getParent();526}527528LLVMContext &DbgRecord::getContext() { return getBlock()->getContext(); }529530const LLVMContext &DbgRecord::getContext() const {531return getBlock()->getContext();532}533534void DbgRecord::insertBefore(DbgRecord *InsertBefore) {535assert(!getMarker() &&536"Cannot insert a DbgRecord that is already has a DbgMarker!");537assert(InsertBefore->getMarker() &&538"Cannot insert a DbgRecord before a DbgRecord that does not have a "539"DbgMarker!");540InsertBefore->getMarker()->insertDbgRecord(this, InsertBefore);541}542void DbgRecord::insertAfter(DbgRecord *InsertAfter) {543assert(!getMarker() &&544"Cannot insert a DbgRecord that is already has a DbgMarker!");545assert(InsertAfter->getMarker() &&546"Cannot insert a DbgRecord after a DbgRecord that does not have a "547"DbgMarker!");548InsertAfter->getMarker()->insertDbgRecordAfter(this, InsertAfter);549}550void DbgRecord::moveBefore(DbgRecord *MoveBefore) {551assert(getMarker() &&552"Canot move a DbgRecord that does not currently have a DbgMarker!");553removeFromParent();554insertBefore(MoveBefore);555}556void DbgRecord::moveAfter(DbgRecord *MoveAfter) {557assert(getMarker() &&558"Canot move a DbgRecord that does not currently have a DbgMarker!");559removeFromParent();560insertAfter(MoveAfter);561}562563///////////////////////////////////////////////////////////////////////////////564565// An empty, global, DbgMarker for the purpose of describing empty ranges of566// DbgRecords.567DbgMarker DbgMarker::EmptyDbgMarker;568569void DbgMarker::dropDbgRecords() {570while (!StoredDbgRecords.empty()) {571auto It = StoredDbgRecords.begin();572DbgRecord *DR = &*It;573StoredDbgRecords.erase(It);574DR->deleteRecord();575}576}577578void DbgMarker::dropOneDbgRecord(DbgRecord *DR) {579assert(DR->getMarker() == this);580StoredDbgRecords.erase(DR->getIterator());581DR->deleteRecord();582}583584const BasicBlock *DbgMarker::getParent() const {585return MarkedInstr->getParent();586}587588BasicBlock *DbgMarker::getParent() { return MarkedInstr->getParent(); }589590void DbgMarker::removeMarker() {591// Are there any DbgRecords in this DbgMarker? If not, nothing to preserve.592Instruction *Owner = MarkedInstr;593if (StoredDbgRecords.empty()) {594eraseFromParent();595Owner->DebugMarker = nullptr;596return;597}598599// The attached DbgRecords need to be preserved; attach them to the next600// instruction. If there isn't a next instruction, put them on the601// "trailing" list.602DbgMarker *NextMarker = Owner->getParent()->getNextMarker(Owner);603if (NextMarker) {604NextMarker->absorbDebugValues(*this, true);605eraseFromParent();606} else {607// We can avoid a deallocation -- just store this marker onto the next608// instruction. Unless we're at the end of the block, in which case this609// marker becomes the trailing marker of a degenerate block.610BasicBlock::iterator NextIt = std::next(Owner->getIterator());611if (NextIt == getParent()->end()) {612getParent()->setTrailingDbgRecords(this);613MarkedInstr = nullptr;614} else {615NextIt->DebugMarker = this;616MarkedInstr = &*NextIt;617}618}619Owner->DebugMarker = nullptr;620}621622void DbgMarker::removeFromParent() {623MarkedInstr->DebugMarker = nullptr;624MarkedInstr = nullptr;625}626627void DbgMarker::eraseFromParent() {628if (MarkedInstr)629removeFromParent();630dropDbgRecords();631delete this;632}633634iterator_range<DbgRecord::self_iterator> DbgMarker::getDbgRecordRange() {635return make_range(StoredDbgRecords.begin(), StoredDbgRecords.end());636}637iterator_range<DbgRecord::const_self_iterator>638DbgMarker::getDbgRecordRange() const {639return make_range(StoredDbgRecords.begin(), StoredDbgRecords.end());640}641642void DbgRecord::removeFromParent() {643getMarker()->StoredDbgRecords.erase(getIterator());644Marker = nullptr;645}646647void DbgRecord::eraseFromParent() {648removeFromParent();649deleteRecord();650}651652void DbgMarker::insertDbgRecord(DbgRecord *New, bool InsertAtHead) {653auto It = InsertAtHead ? StoredDbgRecords.begin() : StoredDbgRecords.end();654StoredDbgRecords.insert(It, *New);655New->setMarker(this);656}657void DbgMarker::insertDbgRecord(DbgRecord *New, DbgRecord *InsertBefore) {658assert(InsertBefore->getMarker() == this &&659"DbgRecord 'InsertBefore' must be contained in this DbgMarker!");660StoredDbgRecords.insert(InsertBefore->getIterator(), *New);661New->setMarker(this);662}663void DbgMarker::insertDbgRecordAfter(DbgRecord *New, DbgRecord *InsertAfter) {664assert(InsertAfter->getMarker() == this &&665"DbgRecord 'InsertAfter' must be contained in this DbgMarker!");666StoredDbgRecords.insert(++(InsertAfter->getIterator()), *New);667New->setMarker(this);668}669670void DbgMarker::absorbDebugValues(DbgMarker &Src, bool InsertAtHead) {671auto It = InsertAtHead ? StoredDbgRecords.begin() : StoredDbgRecords.end();672for (DbgRecord &DVR : Src.StoredDbgRecords)673DVR.setMarker(this);674675StoredDbgRecords.splice(It, Src.StoredDbgRecords);676}677678void DbgMarker::absorbDebugValues(679iterator_range<DbgRecord::self_iterator> Range, DbgMarker &Src,680bool InsertAtHead) {681for (DbgRecord &DR : Range)682DR.setMarker(this);683684auto InsertPos =685(InsertAtHead) ? StoredDbgRecords.begin() : StoredDbgRecords.end();686687StoredDbgRecords.splice(InsertPos, Src.StoredDbgRecords, Range.begin(),688Range.end());689}690691iterator_range<simple_ilist<DbgRecord>::iterator> DbgMarker::cloneDebugInfoFrom(692DbgMarker *From, std::optional<simple_ilist<DbgRecord>::iterator> from_here,693bool InsertAtHead) {694DbgRecord *First = nullptr;695// Work out what range of DbgRecords to clone: normally all the contents of696// the "From" marker, optionally we can start from the from_here position down697// to end().698auto Range =699make_range(From->StoredDbgRecords.begin(), From->StoredDbgRecords.end());700if (from_here.has_value())701Range = make_range(*from_here, From->StoredDbgRecords.end());702703// Clone each DbgVariableRecord and insert into StoreDbgVariableRecords;704// optionally place them at the start or the end of the list.705auto Pos = (InsertAtHead) ? StoredDbgRecords.begin() : StoredDbgRecords.end();706for (DbgRecord &DR : Range) {707DbgRecord *New = DR.clone();708New->setMarker(this);709StoredDbgRecords.insert(Pos, *New);710if (!First)711First = New;712}713714if (!First)715return {StoredDbgRecords.end(), StoredDbgRecords.end()};716717if (InsertAtHead)718// If InsertAtHead is set, we cloned a range onto the front of of the719// StoredDbgRecords collection, return that range.720return {StoredDbgRecords.begin(), Pos};721else722// We inserted a block at the end, return that range.723return {First->getIterator(), StoredDbgRecords.end()};724}725726} // end namespace llvm727728729