Path: blob/main/contrib/llvm-project/llvm/lib/IR/DIBuilder.cpp
35233 views
//===--- DIBuilder.cpp - Debug Information Builder ------------------------===//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//===----------------------------------------------------------------------===//7//8// This file implements the DIBuilder.9//10//===----------------------------------------------------------------------===//1112#include "llvm/IR/DIBuilder.h"13#include "LLVMContextImpl.h"14#include "llvm/ADT/APInt.h"15#include "llvm/ADT/APSInt.h"16#include "llvm/BinaryFormat/Dwarf.h"17#include "llvm/IR/Constants.h"18#include "llvm/IR/DebugInfo.h"19#include "llvm/IR/IRBuilder.h"20#include "llvm/IR/Module.h"21#include "llvm/Support/CommandLine.h"22#include <optional>2324using namespace llvm;25using namespace llvm::dwarf;2627DIBuilder::DIBuilder(Module &m, bool AllowUnresolvedNodes, DICompileUnit *CU)28: M(m), VMContext(M.getContext()), CUNode(CU), DeclareFn(nullptr),29ValueFn(nullptr), LabelFn(nullptr), AssignFn(nullptr),30AllowUnresolvedNodes(AllowUnresolvedNodes) {31if (CUNode) {32if (const auto &ETs = CUNode->getEnumTypes())33AllEnumTypes.assign(ETs.begin(), ETs.end());34if (const auto &RTs = CUNode->getRetainedTypes())35AllRetainTypes.assign(RTs.begin(), RTs.end());36if (const auto &GVs = CUNode->getGlobalVariables())37AllGVs.assign(GVs.begin(), GVs.end());38if (const auto &IMs = CUNode->getImportedEntities())39ImportedModules.assign(IMs.begin(), IMs.end());40if (const auto &MNs = CUNode->getMacros())41AllMacrosPerParent.insert({nullptr, {MNs.begin(), MNs.end()}});42}43}4445void DIBuilder::trackIfUnresolved(MDNode *N) {46if (!N)47return;48if (N->isResolved())49return;5051assert(AllowUnresolvedNodes && "Cannot handle unresolved nodes");52UnresolvedNodes.emplace_back(N);53}5455void DIBuilder::finalizeSubprogram(DISubprogram *SP) {56auto PN = SubprogramTrackedNodes.find(SP);57if (PN != SubprogramTrackedNodes.end())58SP->replaceRetainedNodes(59MDTuple::get(VMContext, SmallVector<Metadata *, 16>(PN->second.begin(),60PN->second.end())));61}6263void DIBuilder::finalize() {64if (!CUNode) {65assert(!AllowUnresolvedNodes &&66"creating type nodes without a CU is not supported");67return;68}6970if (!AllEnumTypes.empty())71CUNode->replaceEnumTypes(MDTuple::get(72VMContext, SmallVector<Metadata *, 16>(AllEnumTypes.begin(),73AllEnumTypes.end())));7475SmallVector<Metadata *, 16> RetainValues;76// Declarations and definitions of the same type may be retained. Some77// clients RAUW these pairs, leaving duplicates in the retained types78// list. Use a set to remove the duplicates while we transform the79// TrackingVHs back into Values.80SmallPtrSet<Metadata *, 16> RetainSet;81for (const TrackingMDNodeRef &N : AllRetainTypes)82if (RetainSet.insert(N).second)83RetainValues.push_back(N);8485if (!RetainValues.empty())86CUNode->replaceRetainedTypes(MDTuple::get(VMContext, RetainValues));8788for (auto *SP : AllSubprograms)89finalizeSubprogram(SP);90for (auto *N : RetainValues)91if (auto *SP = dyn_cast<DISubprogram>(N))92finalizeSubprogram(SP);9394if (!AllGVs.empty())95CUNode->replaceGlobalVariables(MDTuple::get(VMContext, AllGVs));9697if (!ImportedModules.empty())98CUNode->replaceImportedEntities(MDTuple::get(99VMContext, SmallVector<Metadata *, 16>(ImportedModules.begin(),100ImportedModules.end())));101102for (const auto &I : AllMacrosPerParent) {103// DIMacroNode's with nullptr parent are DICompileUnit direct children.104if (!I.first) {105CUNode->replaceMacros(MDTuple::get(VMContext, I.second.getArrayRef()));106continue;107}108// Otherwise, it must be a temporary DIMacroFile that need to be resolved.109auto *TMF = cast<DIMacroFile>(I.first);110auto *MF = DIMacroFile::get(VMContext, dwarf::DW_MACINFO_start_file,111TMF->getLine(), TMF->getFile(),112getOrCreateMacroArray(I.second.getArrayRef()));113replaceTemporary(llvm::TempDIMacroNode(TMF), MF);114}115116// Now that all temp nodes have been replaced or deleted, resolve remaining117// cycles.118for (const auto &N : UnresolvedNodes)119if (N && !N->isResolved())120N->resolveCycles();121UnresolvedNodes.clear();122123// Can't handle unresolved nodes anymore.124AllowUnresolvedNodes = false;125}126127/// If N is compile unit return NULL otherwise return N.128static DIScope *getNonCompileUnitScope(DIScope *N) {129if (!N || isa<DICompileUnit>(N))130return nullptr;131return cast<DIScope>(N);132}133134DICompileUnit *DIBuilder::createCompileUnit(135unsigned Lang, DIFile *File, StringRef Producer, bool isOptimized,136StringRef Flags, unsigned RunTimeVer, StringRef SplitName,137DICompileUnit::DebugEmissionKind Kind, uint64_t DWOId,138bool SplitDebugInlining, bool DebugInfoForProfiling,139DICompileUnit::DebugNameTableKind NameTableKind, bool RangesBaseAddress,140StringRef SysRoot, StringRef SDK) {141142assert(((Lang <= dwarf::DW_LANG_Mojo && Lang >= dwarf::DW_LANG_C89) ||143(Lang <= dwarf::DW_LANG_hi_user && Lang >= dwarf::DW_LANG_lo_user)) &&144"Invalid Language tag");145146assert(!CUNode && "Can only make one compile unit per DIBuilder instance");147CUNode = DICompileUnit::getDistinct(148VMContext, Lang, File, Producer, isOptimized, Flags, RunTimeVer,149SplitName, Kind, nullptr, nullptr, nullptr, nullptr, nullptr, DWOId,150SplitDebugInlining, DebugInfoForProfiling, NameTableKind,151RangesBaseAddress, SysRoot, SDK);152153// Create a named metadata so that it is easier to find cu in a module.154NamedMDNode *NMD = M.getOrInsertNamedMetadata("llvm.dbg.cu");155NMD->addOperand(CUNode);156trackIfUnresolved(CUNode);157return CUNode;158}159160static DIImportedEntity *161createImportedModule(LLVMContext &C, dwarf::Tag Tag, DIScope *Context,162Metadata *NS, DIFile *File, unsigned Line, StringRef Name,163DINodeArray Elements,164SmallVectorImpl<TrackingMDNodeRef> &ImportedModules) {165if (Line)166assert(File && "Source location has line number but no file");167unsigned EntitiesCount = C.pImpl->DIImportedEntitys.size();168auto *M = DIImportedEntity::get(C, Tag, Context, cast_or_null<DINode>(NS),169File, Line, Name, Elements);170if (EntitiesCount < C.pImpl->DIImportedEntitys.size())171// A new Imported Entity was just added to the context.172// Add it to the Imported Modules list.173ImportedModules.emplace_back(M);174return M;175}176177DIImportedEntity *DIBuilder::createImportedModule(DIScope *Context,178DINamespace *NS, DIFile *File,179unsigned Line,180DINodeArray Elements) {181return ::createImportedModule(VMContext, dwarf::DW_TAG_imported_module,182Context, NS, File, Line, StringRef(), Elements,183getImportTrackingVector(Context));184}185186DIImportedEntity *DIBuilder::createImportedModule(DIScope *Context,187DIImportedEntity *NS,188DIFile *File, unsigned Line,189DINodeArray Elements) {190return ::createImportedModule(VMContext, dwarf::DW_TAG_imported_module,191Context, NS, File, Line, StringRef(), Elements,192getImportTrackingVector(Context));193}194195DIImportedEntity *DIBuilder::createImportedModule(DIScope *Context, DIModule *M,196DIFile *File, unsigned Line,197DINodeArray Elements) {198return ::createImportedModule(VMContext, dwarf::DW_TAG_imported_module,199Context, M, File, Line, StringRef(), Elements,200getImportTrackingVector(Context));201}202203DIImportedEntity *204DIBuilder::createImportedDeclaration(DIScope *Context, DINode *Decl,205DIFile *File, unsigned Line,206StringRef Name, DINodeArray Elements) {207// Make sure to use the unique identifier based metadata reference for208// types that have one.209return ::createImportedModule(VMContext, dwarf::DW_TAG_imported_declaration,210Context, Decl, File, Line, Name, Elements,211getImportTrackingVector(Context));212}213214DIFile *DIBuilder::createFile(StringRef Filename, StringRef Directory,215std::optional<DIFile::ChecksumInfo<StringRef>> CS,216std::optional<StringRef> Source) {217return DIFile::get(VMContext, Filename, Directory, CS, Source);218}219220DIMacro *DIBuilder::createMacro(DIMacroFile *Parent, unsigned LineNumber,221unsigned MacroType, StringRef Name,222StringRef Value) {223assert(!Name.empty() && "Unable to create macro without name");224assert((MacroType == dwarf::DW_MACINFO_undef ||225MacroType == dwarf::DW_MACINFO_define) &&226"Unexpected macro type");227auto *M = DIMacro::get(VMContext, MacroType, LineNumber, Name, Value);228AllMacrosPerParent[Parent].insert(M);229return M;230}231232DIMacroFile *DIBuilder::createTempMacroFile(DIMacroFile *Parent,233unsigned LineNumber, DIFile *File) {234auto *MF = DIMacroFile::getTemporary(VMContext, dwarf::DW_MACINFO_start_file,235LineNumber, File, DIMacroNodeArray())236.release();237AllMacrosPerParent[Parent].insert(MF);238// Add the new temporary DIMacroFile to the macro per parent map as a parent.239// This is needed to assure DIMacroFile with no children to have an entry in240// the map. Otherwise, it will not be resolved in DIBuilder::finalize().241AllMacrosPerParent.insert({MF, {}});242return MF;243}244245DIEnumerator *DIBuilder::createEnumerator(StringRef Name, uint64_t Val,246bool IsUnsigned) {247assert(!Name.empty() && "Unable to create enumerator without name");248return DIEnumerator::get(VMContext, APInt(64, Val, !IsUnsigned), IsUnsigned,249Name);250}251252DIEnumerator *DIBuilder::createEnumerator(StringRef Name, const APSInt &Value) {253assert(!Name.empty() && "Unable to create enumerator without name");254return DIEnumerator::get(VMContext, APInt(Value), Value.isUnsigned(), Name);255}256257DIBasicType *DIBuilder::createUnspecifiedType(StringRef Name) {258assert(!Name.empty() && "Unable to create type without name");259return DIBasicType::get(VMContext, dwarf::DW_TAG_unspecified_type, Name);260}261262DIBasicType *DIBuilder::createNullPtrType() {263return createUnspecifiedType("decltype(nullptr)");264}265266DIBasicType *DIBuilder::createBasicType(StringRef Name, uint64_t SizeInBits,267unsigned Encoding,268DINode::DIFlags Flags) {269assert(!Name.empty() && "Unable to create type without name");270return DIBasicType::get(VMContext, dwarf::DW_TAG_base_type, Name, SizeInBits,2710, Encoding, Flags);272}273274DIStringType *DIBuilder::createStringType(StringRef Name, uint64_t SizeInBits) {275assert(!Name.empty() && "Unable to create type without name");276return DIStringType::get(VMContext, dwarf::DW_TAG_string_type, Name,277SizeInBits, 0);278}279280DIStringType *DIBuilder::createStringType(StringRef Name,281DIVariable *StringLength,282DIExpression *StrLocationExp) {283assert(!Name.empty() && "Unable to create type without name");284return DIStringType::get(VMContext, dwarf::DW_TAG_string_type, Name,285StringLength, nullptr, StrLocationExp, 0, 0, 0);286}287288DIStringType *DIBuilder::createStringType(StringRef Name,289DIExpression *StringLengthExp,290DIExpression *StrLocationExp) {291assert(!Name.empty() && "Unable to create type without name");292return DIStringType::get(VMContext, dwarf::DW_TAG_string_type, Name, nullptr,293StringLengthExp, StrLocationExp, 0, 0, 0);294}295296DIDerivedType *DIBuilder::createQualifiedType(unsigned Tag, DIType *FromTy) {297return DIDerivedType::get(VMContext, Tag, "", nullptr, 0, nullptr, FromTy, 0,2980, 0, std::nullopt, std::nullopt, DINode::FlagZero);299}300301DIDerivedType *DIBuilder::createPtrAuthQualifiedType(302DIType *FromTy, unsigned Key, bool IsAddressDiscriminated,303unsigned ExtraDiscriminator, bool IsaPointer,304bool AuthenticatesNullValues) {305return DIDerivedType::get(VMContext, dwarf::DW_TAG_LLVM_ptrauth_type, "",306nullptr, 0, nullptr, FromTy, 0, 0, 0, std::nullopt,307std::optional<DIDerivedType::PtrAuthData>(308std::in_place, Key, IsAddressDiscriminated,309ExtraDiscriminator, IsaPointer,310AuthenticatesNullValues),311DINode::FlagZero);312}313314DIDerivedType *315DIBuilder::createPointerType(DIType *PointeeTy, uint64_t SizeInBits,316uint32_t AlignInBits,317std::optional<unsigned> DWARFAddressSpace,318StringRef Name, DINodeArray Annotations) {319// FIXME: Why is there a name here?320return DIDerivedType::get(VMContext, dwarf::DW_TAG_pointer_type, Name,321nullptr, 0, nullptr, PointeeTy, SizeInBits,322AlignInBits, 0, DWARFAddressSpace, std::nullopt,323DINode::FlagZero, nullptr, Annotations);324}325326DIDerivedType *DIBuilder::createMemberPointerType(DIType *PointeeTy,327DIType *Base,328uint64_t SizeInBits,329uint32_t AlignInBits,330DINode::DIFlags Flags) {331return DIDerivedType::get(VMContext, dwarf::DW_TAG_ptr_to_member_type, "",332nullptr, 0, nullptr, PointeeTy, SizeInBits,333AlignInBits, 0, std::nullopt, std::nullopt, Flags,334Base);335}336337DIDerivedType *338DIBuilder::createReferenceType(unsigned Tag, DIType *RTy, uint64_t SizeInBits,339uint32_t AlignInBits,340std::optional<unsigned> DWARFAddressSpace) {341assert(RTy && "Unable to create reference type");342return DIDerivedType::get(VMContext, Tag, "", nullptr, 0, nullptr, RTy,343SizeInBits, AlignInBits, 0, DWARFAddressSpace, {},344DINode::FlagZero);345}346347DIDerivedType *DIBuilder::createTypedef(DIType *Ty, StringRef Name,348DIFile *File, unsigned LineNo,349DIScope *Context, uint32_t AlignInBits,350DINode::DIFlags Flags,351DINodeArray Annotations) {352return DIDerivedType::get(VMContext, dwarf::DW_TAG_typedef, Name, File,353LineNo, getNonCompileUnitScope(Context), Ty, 0,354AlignInBits, 0, std::nullopt, std::nullopt, Flags,355nullptr, Annotations);356}357358DIDerivedType *359DIBuilder::createTemplateAlias(DIType *Ty, StringRef Name, DIFile *File,360unsigned LineNo, DIScope *Context,361DINodeArray TParams, uint32_t AlignInBits,362DINode::DIFlags Flags, DINodeArray Annotations) {363return DIDerivedType::get(VMContext, dwarf::DW_TAG_template_alias, Name, File,364LineNo, getNonCompileUnitScope(Context), Ty, 0,365AlignInBits, 0, std::nullopt, std::nullopt, Flags,366TParams.get(), Annotations);367}368369DIDerivedType *DIBuilder::createFriend(DIType *Ty, DIType *FriendTy) {370assert(Ty && "Invalid type!");371assert(FriendTy && "Invalid friend type!");372return DIDerivedType::get(VMContext, dwarf::DW_TAG_friend, "", nullptr, 0, Ty,373FriendTy, 0, 0, 0, std::nullopt, std::nullopt,374DINode::FlagZero);375}376377DIDerivedType *DIBuilder::createInheritance(DIType *Ty, DIType *BaseTy,378uint64_t BaseOffset,379uint32_t VBPtrOffset,380DINode::DIFlags Flags) {381assert(Ty && "Unable to create inheritance");382Metadata *ExtraData = ConstantAsMetadata::get(383ConstantInt::get(IntegerType::get(VMContext, 32), VBPtrOffset));384return DIDerivedType::get(VMContext, dwarf::DW_TAG_inheritance, "", nullptr,3850, Ty, BaseTy, 0, 0, BaseOffset, std::nullopt,386std::nullopt, Flags, ExtraData);387}388389DIDerivedType *DIBuilder::createMemberType(390DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNumber,391uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits,392DINode::DIFlags Flags, DIType *Ty, DINodeArray Annotations) {393return DIDerivedType::get(VMContext, dwarf::DW_TAG_member, Name, File,394LineNumber, getNonCompileUnitScope(Scope), Ty,395SizeInBits, AlignInBits, OffsetInBits, std::nullopt,396std::nullopt, Flags, nullptr, Annotations);397}398399static ConstantAsMetadata *getConstantOrNull(Constant *C) {400if (C)401return ConstantAsMetadata::get(C);402return nullptr;403}404405DIDerivedType *DIBuilder::createVariantMemberType(406DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNumber,407uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits,408Constant *Discriminant, DINode::DIFlags Flags, DIType *Ty) {409return DIDerivedType::get(410VMContext, dwarf::DW_TAG_member, Name, File, LineNumber,411getNonCompileUnitScope(Scope), Ty, SizeInBits, AlignInBits, OffsetInBits,412std::nullopt, std::nullopt, Flags, getConstantOrNull(Discriminant));413}414415DIDerivedType *DIBuilder::createBitFieldMemberType(416DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNumber,417uint64_t SizeInBits, uint64_t OffsetInBits, uint64_t StorageOffsetInBits,418DINode::DIFlags Flags, DIType *Ty, DINodeArray Annotations) {419Flags |= DINode::FlagBitField;420return DIDerivedType::get(421VMContext, dwarf::DW_TAG_member, Name, File, LineNumber,422getNonCompileUnitScope(Scope), Ty, SizeInBits, /*AlignInBits=*/0,423OffsetInBits, std::nullopt, std::nullopt, Flags,424ConstantAsMetadata::get(ConstantInt::get(IntegerType::get(VMContext, 64),425StorageOffsetInBits)),426Annotations);427}428429DIDerivedType *430DIBuilder::createStaticMemberType(DIScope *Scope, StringRef Name, DIFile *File,431unsigned LineNumber, DIType *Ty,432DINode::DIFlags Flags, llvm::Constant *Val,433unsigned Tag, uint32_t AlignInBits) {434Flags |= DINode::FlagStaticMember;435return DIDerivedType::get(VMContext, Tag, Name, File, LineNumber,436getNonCompileUnitScope(Scope), Ty, 0, AlignInBits,4370, std::nullopt, std::nullopt, Flags,438getConstantOrNull(Val));439}440441DIDerivedType *442DIBuilder::createObjCIVar(StringRef Name, DIFile *File, unsigned LineNumber,443uint64_t SizeInBits, uint32_t AlignInBits,444uint64_t OffsetInBits, DINode::DIFlags Flags,445DIType *Ty, MDNode *PropertyNode) {446return DIDerivedType::get(VMContext, dwarf::DW_TAG_member, Name, File,447LineNumber, getNonCompileUnitScope(File), Ty,448SizeInBits, AlignInBits, OffsetInBits, std::nullopt,449std::nullopt, Flags, PropertyNode);450}451452DIObjCProperty *453DIBuilder::createObjCProperty(StringRef Name, DIFile *File, unsigned LineNumber,454StringRef GetterName, StringRef SetterName,455unsigned PropertyAttributes, DIType *Ty) {456return DIObjCProperty::get(VMContext, Name, File, LineNumber, GetterName,457SetterName, PropertyAttributes, Ty);458}459460DITemplateTypeParameter *461DIBuilder::createTemplateTypeParameter(DIScope *Context, StringRef Name,462DIType *Ty, bool isDefault) {463assert((!Context || isa<DICompileUnit>(Context)) && "Expected compile unit");464return DITemplateTypeParameter::get(VMContext, Name, Ty, isDefault);465}466467static DITemplateValueParameter *468createTemplateValueParameterHelper(LLVMContext &VMContext, unsigned Tag,469DIScope *Context, StringRef Name, DIType *Ty,470bool IsDefault, Metadata *MD) {471assert((!Context || isa<DICompileUnit>(Context)) && "Expected compile unit");472return DITemplateValueParameter::get(VMContext, Tag, Name, Ty, IsDefault, MD);473}474475DITemplateValueParameter *476DIBuilder::createTemplateValueParameter(DIScope *Context, StringRef Name,477DIType *Ty, bool isDefault,478Constant *Val) {479return createTemplateValueParameterHelper(480VMContext, dwarf::DW_TAG_template_value_parameter, Context, Name, Ty,481isDefault, getConstantOrNull(Val));482}483484DITemplateValueParameter *485DIBuilder::createTemplateTemplateParameter(DIScope *Context, StringRef Name,486DIType *Ty, StringRef Val,487bool IsDefault) {488return createTemplateValueParameterHelper(489VMContext, dwarf::DW_TAG_GNU_template_template_param, Context, Name, Ty,490IsDefault, MDString::get(VMContext, Val));491}492493DITemplateValueParameter *494DIBuilder::createTemplateParameterPack(DIScope *Context, StringRef Name,495DIType *Ty, DINodeArray Val) {496return createTemplateValueParameterHelper(497VMContext, dwarf::DW_TAG_GNU_template_parameter_pack, Context, Name, Ty,498false, Val.get());499}500501DICompositeType *DIBuilder::createClassType(502DIScope *Context, StringRef Name, DIFile *File, unsigned LineNumber,503uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits,504DINode::DIFlags Flags, DIType *DerivedFrom, DINodeArray Elements,505unsigned RunTimeLang, DIType *VTableHolder, MDNode *TemplateParams,506StringRef UniqueIdentifier) {507assert((!Context || isa<DIScope>(Context)) &&508"createClassType should be called with a valid Context");509510auto *R = DICompositeType::get(511VMContext, dwarf::DW_TAG_structure_type, Name, File, LineNumber,512getNonCompileUnitScope(Context), DerivedFrom, SizeInBits, AlignInBits,513OffsetInBits, Flags, Elements, RunTimeLang, VTableHolder,514cast_or_null<MDTuple>(TemplateParams), UniqueIdentifier);515trackIfUnresolved(R);516return R;517}518519DICompositeType *DIBuilder::createStructType(520DIScope *Context, StringRef Name, DIFile *File, unsigned LineNumber,521uint64_t SizeInBits, uint32_t AlignInBits, DINode::DIFlags Flags,522DIType *DerivedFrom, DINodeArray Elements, unsigned RunTimeLang,523DIType *VTableHolder, StringRef UniqueIdentifier) {524auto *R = DICompositeType::get(525VMContext, dwarf::DW_TAG_structure_type, Name, File, LineNumber,526getNonCompileUnitScope(Context), DerivedFrom, SizeInBits, AlignInBits, 0,527Flags, Elements, RunTimeLang, VTableHolder, nullptr, UniqueIdentifier);528trackIfUnresolved(R);529return R;530}531532DICompositeType *DIBuilder::createUnionType(533DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNumber,534uint64_t SizeInBits, uint32_t AlignInBits, DINode::DIFlags Flags,535DINodeArray Elements, unsigned RunTimeLang, StringRef UniqueIdentifier) {536auto *R = DICompositeType::get(537VMContext, dwarf::DW_TAG_union_type, Name, File, LineNumber,538getNonCompileUnitScope(Scope), nullptr, SizeInBits, AlignInBits, 0, Flags,539Elements, RunTimeLang, nullptr, nullptr, UniqueIdentifier);540trackIfUnresolved(R);541return R;542}543544DICompositeType *545DIBuilder::createVariantPart(DIScope *Scope, StringRef Name, DIFile *File,546unsigned LineNumber, uint64_t SizeInBits,547uint32_t AlignInBits, DINode::DIFlags Flags,548DIDerivedType *Discriminator, DINodeArray Elements,549StringRef UniqueIdentifier) {550auto *R = DICompositeType::get(551VMContext, dwarf::DW_TAG_variant_part, Name, File, LineNumber,552getNonCompileUnitScope(Scope), nullptr, SizeInBits, AlignInBits, 0, Flags,553Elements, 0, nullptr, nullptr, UniqueIdentifier, Discriminator);554trackIfUnresolved(R);555return R;556}557558DISubroutineType *DIBuilder::createSubroutineType(DITypeRefArray ParameterTypes,559DINode::DIFlags Flags,560unsigned CC) {561return DISubroutineType::get(VMContext, Flags, CC, ParameterTypes);562}563564DICompositeType *565DIBuilder::createEnumerationType(DIScope *Scope, StringRef Name, DIFile *File,566unsigned LineNumber, uint64_t SizeInBits,567uint32_t AlignInBits, DINodeArray Elements,568DIType *UnderlyingType, unsigned RunTimeLang,569StringRef UniqueIdentifier, bool IsScoped) {570auto *CTy = DICompositeType::get(571VMContext, dwarf::DW_TAG_enumeration_type, Name, File, LineNumber,572getNonCompileUnitScope(Scope), UnderlyingType, SizeInBits, AlignInBits, 0,573IsScoped ? DINode::FlagEnumClass : DINode::FlagZero, Elements,574RunTimeLang, nullptr, nullptr, UniqueIdentifier);575AllEnumTypes.emplace_back(CTy);576trackIfUnresolved(CTy);577return CTy;578}579580DIDerivedType *DIBuilder::createSetType(DIScope *Scope, StringRef Name,581DIFile *File, unsigned LineNo,582uint64_t SizeInBits,583uint32_t AlignInBits, DIType *Ty) {584auto *R = DIDerivedType::get(VMContext, dwarf::DW_TAG_set_type, Name, File,585LineNo, getNonCompileUnitScope(Scope), Ty,586SizeInBits, AlignInBits, 0, std::nullopt,587std::nullopt, DINode::FlagZero);588trackIfUnresolved(R);589return R;590}591592DICompositeType *593DIBuilder::createArrayType(uint64_t Size, uint32_t AlignInBits, DIType *Ty,594DINodeArray Subscripts,595PointerUnion<DIExpression *, DIVariable *> DL,596PointerUnion<DIExpression *, DIVariable *> AS,597PointerUnion<DIExpression *, DIVariable *> AL,598PointerUnion<DIExpression *, DIVariable *> RK) {599auto *R = DICompositeType::get(600VMContext, dwarf::DW_TAG_array_type, "", nullptr, 0, nullptr, Ty, Size,601AlignInBits, 0, DINode::FlagZero, Subscripts, 0, nullptr, nullptr, "",602nullptr,603isa<DIExpression *>(DL) ? (Metadata *)cast<DIExpression *>(DL)604: (Metadata *)cast<DIVariable *>(DL),605isa<DIExpression *>(AS) ? (Metadata *)cast<DIExpression *>(AS)606: (Metadata *)cast<DIVariable *>(AS),607isa<DIExpression *>(AL) ? (Metadata *)cast<DIExpression *>(AL)608: (Metadata *)cast<DIVariable *>(AL),609isa<DIExpression *>(RK) ? (Metadata *)cast<DIExpression *>(RK)610: (Metadata *)cast<DIVariable *>(RK));611trackIfUnresolved(R);612return R;613}614615DICompositeType *DIBuilder::createVectorType(uint64_t Size,616uint32_t AlignInBits, DIType *Ty,617DINodeArray Subscripts) {618auto *R = DICompositeType::get(VMContext, dwarf::DW_TAG_array_type, "",619nullptr, 0, nullptr, Ty, Size, AlignInBits, 0,620DINode::FlagVector, Subscripts, 0, nullptr);621trackIfUnresolved(R);622return R;623}624625DISubprogram *DIBuilder::createArtificialSubprogram(DISubprogram *SP) {626auto NewSP = SP->cloneWithFlags(SP->getFlags() | DINode::FlagArtificial);627return MDNode::replaceWithDistinct(std::move(NewSP));628}629630static DIType *createTypeWithFlags(const DIType *Ty,631DINode::DIFlags FlagsToSet) {632auto NewTy = Ty->cloneWithFlags(Ty->getFlags() | FlagsToSet);633return MDNode::replaceWithUniqued(std::move(NewTy));634}635636DIType *DIBuilder::createArtificialType(DIType *Ty) {637// FIXME: Restrict this to the nodes where it's valid.638if (Ty->isArtificial())639return Ty;640return createTypeWithFlags(Ty, DINode::FlagArtificial);641}642643DIType *DIBuilder::createObjectPointerType(DIType *Ty) {644// FIXME: Restrict this to the nodes where it's valid.645if (Ty->isObjectPointer())646return Ty;647DINode::DIFlags Flags = DINode::FlagObjectPointer | DINode::FlagArtificial;648return createTypeWithFlags(Ty, Flags);649}650651void DIBuilder::retainType(DIScope *T) {652assert(T && "Expected non-null type");653assert((isa<DIType>(T) || (isa<DISubprogram>(T) &&654cast<DISubprogram>(T)->isDefinition() == false)) &&655"Expected type or subprogram declaration");656AllRetainTypes.emplace_back(T);657}658659DIBasicType *DIBuilder::createUnspecifiedParameter() { return nullptr; }660661DICompositeType *662DIBuilder::createForwardDecl(unsigned Tag, StringRef Name, DIScope *Scope,663DIFile *F, unsigned Line, unsigned RuntimeLang,664uint64_t SizeInBits, uint32_t AlignInBits,665StringRef UniqueIdentifier) {666// FIXME: Define in terms of createReplaceableForwardDecl() by calling667// replaceWithUniqued().668auto *RetTy = DICompositeType::get(669VMContext, Tag, Name, F, Line, getNonCompileUnitScope(Scope), nullptr,670SizeInBits, AlignInBits, 0, DINode::FlagFwdDecl, nullptr, RuntimeLang,671nullptr, nullptr, UniqueIdentifier);672trackIfUnresolved(RetTy);673return RetTy;674}675676DICompositeType *DIBuilder::createReplaceableCompositeType(677unsigned Tag, StringRef Name, DIScope *Scope, DIFile *F, unsigned Line,678unsigned RuntimeLang, uint64_t SizeInBits, uint32_t AlignInBits,679DINode::DIFlags Flags, StringRef UniqueIdentifier,680DINodeArray Annotations) {681auto *RetTy =682DICompositeType::getTemporary(683VMContext, Tag, Name, F, Line, getNonCompileUnitScope(Scope), nullptr,684SizeInBits, AlignInBits, 0, Flags, nullptr, RuntimeLang, nullptr,685nullptr, UniqueIdentifier, nullptr, nullptr, nullptr, nullptr,686nullptr, Annotations)687.release();688trackIfUnresolved(RetTy);689return RetTy;690}691692DINodeArray DIBuilder::getOrCreateArray(ArrayRef<Metadata *> Elements) {693return MDTuple::get(VMContext, Elements);694}695696DIMacroNodeArray697DIBuilder::getOrCreateMacroArray(ArrayRef<Metadata *> Elements) {698return MDTuple::get(VMContext, Elements);699}700701DITypeRefArray DIBuilder::getOrCreateTypeArray(ArrayRef<Metadata *> Elements) {702SmallVector<llvm::Metadata *, 16> Elts;703for (Metadata *E : Elements) {704if (isa_and_nonnull<MDNode>(E))705Elts.push_back(cast<DIType>(E));706else707Elts.push_back(E);708}709return DITypeRefArray(MDNode::get(VMContext, Elts));710}711712DISubrange *DIBuilder::getOrCreateSubrange(int64_t Lo, int64_t Count) {713auto *LB = ConstantAsMetadata::get(714ConstantInt::getSigned(Type::getInt64Ty(VMContext), Lo));715auto *CountNode = ConstantAsMetadata::get(716ConstantInt::getSigned(Type::getInt64Ty(VMContext), Count));717return DISubrange::get(VMContext, CountNode, LB, nullptr, nullptr);718}719720DISubrange *DIBuilder::getOrCreateSubrange(int64_t Lo, Metadata *CountNode) {721auto *LB = ConstantAsMetadata::get(722ConstantInt::getSigned(Type::getInt64Ty(VMContext), Lo));723return DISubrange::get(VMContext, CountNode, LB, nullptr, nullptr);724}725726DISubrange *DIBuilder::getOrCreateSubrange(Metadata *CountNode, Metadata *LB,727Metadata *UB, Metadata *Stride) {728return DISubrange::get(VMContext, CountNode, LB, UB, Stride);729}730731DIGenericSubrange *DIBuilder::getOrCreateGenericSubrange(732DIGenericSubrange::BoundType CountNode, DIGenericSubrange::BoundType LB,733DIGenericSubrange::BoundType UB, DIGenericSubrange::BoundType Stride) {734auto ConvToMetadata = [&](DIGenericSubrange::BoundType Bound) -> Metadata * {735return isa<DIExpression *>(Bound) ? (Metadata *)cast<DIExpression *>(Bound)736: (Metadata *)cast<DIVariable *>(Bound);737};738return DIGenericSubrange::get(VMContext, ConvToMetadata(CountNode),739ConvToMetadata(LB), ConvToMetadata(UB),740ConvToMetadata(Stride));741}742743static void checkGlobalVariableScope(DIScope *Context) {744#ifndef NDEBUG745if (auto *CT =746dyn_cast_or_null<DICompositeType>(getNonCompileUnitScope(Context)))747assert(CT->getIdentifier().empty() &&748"Context of a global variable should not be a type with identifier");749#endif750}751752DIGlobalVariableExpression *DIBuilder::createGlobalVariableExpression(753DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *F,754unsigned LineNumber, DIType *Ty, bool IsLocalToUnit, bool isDefined,755DIExpression *Expr, MDNode *Decl, MDTuple *TemplateParams,756uint32_t AlignInBits, DINodeArray Annotations) {757checkGlobalVariableScope(Context);758759auto *GV = DIGlobalVariable::getDistinct(760VMContext, cast_or_null<DIScope>(Context), Name, LinkageName, F,761LineNumber, Ty, IsLocalToUnit, isDefined,762cast_or_null<DIDerivedType>(Decl), TemplateParams, AlignInBits,763Annotations);764if (!Expr)765Expr = createExpression();766auto *N = DIGlobalVariableExpression::get(VMContext, GV, Expr);767AllGVs.push_back(N);768return N;769}770771DIGlobalVariable *DIBuilder::createTempGlobalVariableFwdDecl(772DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *F,773unsigned LineNumber, DIType *Ty, bool IsLocalToUnit, MDNode *Decl,774MDTuple *TemplateParams, uint32_t AlignInBits) {775checkGlobalVariableScope(Context);776777return DIGlobalVariable::getTemporary(778VMContext, cast_or_null<DIScope>(Context), Name, LinkageName, F,779LineNumber, Ty, IsLocalToUnit, false,780cast_or_null<DIDerivedType>(Decl), TemplateParams, AlignInBits,781nullptr)782.release();783}784785static DILocalVariable *createLocalVariable(786LLVMContext &VMContext,787SmallVectorImpl<TrackingMDNodeRef> &PreservedNodes,788DIScope *Context, StringRef Name, unsigned ArgNo, DIFile *File,789unsigned LineNo, DIType *Ty, bool AlwaysPreserve, DINode::DIFlags Flags,790uint32_t AlignInBits, DINodeArray Annotations = nullptr) {791// FIXME: Why doesn't this check for a subprogram or lexical block (AFAICT792// the only valid scopes)?793auto *Scope = cast<DILocalScope>(Context);794auto *Node = DILocalVariable::get(VMContext, Scope, Name, File, LineNo, Ty,795ArgNo, Flags, AlignInBits, Annotations);796if (AlwaysPreserve) {797// The optimizer may remove local variables. If there is an interest798// to preserve variable info in such situation then stash it in a799// named mdnode.800PreservedNodes.emplace_back(Node);801}802return Node;803}804805DILocalVariable *DIBuilder::createAutoVariable(DIScope *Scope, StringRef Name,806DIFile *File, unsigned LineNo,807DIType *Ty, bool AlwaysPreserve,808DINode::DIFlags Flags,809uint32_t AlignInBits) {810assert(Scope && isa<DILocalScope>(Scope) &&811"Unexpected scope for a local variable.");812return createLocalVariable(813VMContext, getSubprogramNodesTrackingVector(Scope), Scope, Name,814/* ArgNo */ 0, File, LineNo, Ty, AlwaysPreserve, Flags, AlignInBits);815}816817DILocalVariable *DIBuilder::createParameterVariable(818DIScope *Scope, StringRef Name, unsigned ArgNo, DIFile *File,819unsigned LineNo, DIType *Ty, bool AlwaysPreserve, DINode::DIFlags Flags,820DINodeArray Annotations) {821assert(ArgNo && "Expected non-zero argument number for parameter");822assert(Scope && isa<DILocalScope>(Scope) &&823"Unexpected scope for a local variable.");824return createLocalVariable(825VMContext, getSubprogramNodesTrackingVector(Scope), Scope, Name, ArgNo,826File, LineNo, Ty, AlwaysPreserve, Flags, /*AlignInBits=*/0, Annotations);827}828829DILabel *DIBuilder::createLabel(DIScope *Context, StringRef Name, DIFile *File,830unsigned LineNo, bool AlwaysPreserve) {831auto *Scope = cast<DILocalScope>(Context);832auto *Node = DILabel::get(VMContext, Scope, Name, File, LineNo);833834if (AlwaysPreserve) {835/// The optimizer may remove labels. If there is an interest836/// to preserve label info in such situation then append it to837/// the list of retained nodes of the DISubprogram.838getSubprogramNodesTrackingVector(Scope).emplace_back(Node);839}840return Node;841}842843DIExpression *DIBuilder::createExpression(ArrayRef<uint64_t> Addr) {844return DIExpression::get(VMContext, Addr);845}846847template <class... Ts>848static DISubprogram *getSubprogram(bool IsDistinct, Ts &&...Args) {849if (IsDistinct)850return DISubprogram::getDistinct(std::forward<Ts>(Args)...);851return DISubprogram::get(std::forward<Ts>(Args)...);852}853854DISubprogram *DIBuilder::createFunction(855DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *File,856unsigned LineNo, DISubroutineType *Ty, unsigned ScopeLine,857DINode::DIFlags Flags, DISubprogram::DISPFlags SPFlags,858DITemplateParameterArray TParams, DISubprogram *Decl,859DITypeArray ThrownTypes, DINodeArray Annotations,860StringRef TargetFuncName) {861bool IsDefinition = SPFlags & DISubprogram::SPFlagDefinition;862auto *Node = getSubprogram(863/*IsDistinct=*/IsDefinition, VMContext, getNonCompileUnitScope(Context),864Name, LinkageName, File, LineNo, Ty, ScopeLine, nullptr, 0, 0, Flags,865SPFlags, IsDefinition ? CUNode : nullptr, TParams, Decl, nullptr,866ThrownTypes, Annotations, TargetFuncName);867868if (IsDefinition)869AllSubprograms.push_back(Node);870trackIfUnresolved(Node);871return Node;872}873874DISubprogram *DIBuilder::createTempFunctionFwdDecl(875DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *File,876unsigned LineNo, DISubroutineType *Ty, unsigned ScopeLine,877DINode::DIFlags Flags, DISubprogram::DISPFlags SPFlags,878DITemplateParameterArray TParams, DISubprogram *Decl,879DITypeArray ThrownTypes) {880bool IsDefinition = SPFlags & DISubprogram::SPFlagDefinition;881return DISubprogram::getTemporary(VMContext, getNonCompileUnitScope(Context),882Name, LinkageName, File, LineNo, Ty,883ScopeLine, nullptr, 0, 0, Flags, SPFlags,884IsDefinition ? CUNode : nullptr, TParams,885Decl, nullptr, ThrownTypes)886.release();887}888889DISubprogram *DIBuilder::createMethod(890DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *F,891unsigned LineNo, DISubroutineType *Ty, unsigned VIndex, int ThisAdjustment,892DIType *VTableHolder, DINode::DIFlags Flags,893DISubprogram::DISPFlags SPFlags, DITemplateParameterArray TParams,894DITypeArray ThrownTypes) {895assert(getNonCompileUnitScope(Context) &&896"Methods should have both a Context and a context that isn't "897"the compile unit.");898// FIXME: Do we want to use different scope/lines?899bool IsDefinition = SPFlags & DISubprogram::SPFlagDefinition;900auto *SP = getSubprogram(901/*IsDistinct=*/IsDefinition, VMContext, cast<DIScope>(Context), Name,902LinkageName, F, LineNo, Ty, LineNo, VTableHolder, VIndex, ThisAdjustment,903Flags, SPFlags, IsDefinition ? CUNode : nullptr, TParams, nullptr,904nullptr, ThrownTypes);905906if (IsDefinition)907AllSubprograms.push_back(SP);908trackIfUnresolved(SP);909return SP;910}911912DICommonBlock *DIBuilder::createCommonBlock(DIScope *Scope,913DIGlobalVariable *Decl,914StringRef Name, DIFile *File,915unsigned LineNo) {916return DICommonBlock::get(VMContext, Scope, Decl, Name, File, LineNo);917}918919DINamespace *DIBuilder::createNameSpace(DIScope *Scope, StringRef Name,920bool ExportSymbols) {921922// It is okay to *not* make anonymous top-level namespaces distinct, because923// all nodes that have an anonymous namespace as their parent scope are924// guaranteed to be unique and/or are linked to their containing925// DICompileUnit. This decision is an explicit tradeoff of link time versus926// memory usage versus code simplicity and may get revisited in the future.927return DINamespace::get(VMContext, getNonCompileUnitScope(Scope), Name,928ExportSymbols);929}930931DIModule *DIBuilder::createModule(DIScope *Scope, StringRef Name,932StringRef ConfigurationMacros,933StringRef IncludePath, StringRef APINotesFile,934DIFile *File, unsigned LineNo, bool IsDecl) {935return DIModule::get(VMContext, File, getNonCompileUnitScope(Scope), Name,936ConfigurationMacros, IncludePath, APINotesFile, LineNo,937IsDecl);938}939940DILexicalBlockFile *DIBuilder::createLexicalBlockFile(DIScope *Scope,941DIFile *File,942unsigned Discriminator) {943return DILexicalBlockFile::get(VMContext, Scope, File, Discriminator);944}945946DILexicalBlock *DIBuilder::createLexicalBlock(DIScope *Scope, DIFile *File,947unsigned Line, unsigned Col) {948// Make these distinct, to avoid merging two lexical blocks on the same949// file/line/column.950return DILexicalBlock::getDistinct(VMContext, getNonCompileUnitScope(Scope),951File, Line, Col);952}953954DbgInstPtr DIBuilder::insertDeclare(Value *Storage, DILocalVariable *VarInfo,955DIExpression *Expr, const DILocation *DL,956Instruction *InsertBefore) {957return insertDeclare(Storage, VarInfo, Expr, DL, InsertBefore->getParent(),958InsertBefore);959}960961DbgInstPtr DIBuilder::insertDeclare(Value *Storage, DILocalVariable *VarInfo,962DIExpression *Expr, const DILocation *DL,963BasicBlock *InsertAtEnd) {964// If this block already has a terminator then insert this intrinsic before965// the terminator. Otherwise, put it at the end of the block.966Instruction *InsertBefore = InsertAtEnd->getTerminator();967return insertDeclare(Storage, VarInfo, Expr, DL, InsertAtEnd, InsertBefore);968}969970DbgInstPtr DIBuilder::insertDbgAssign(Instruction *LinkedInstr, Value *Val,971DILocalVariable *SrcVar,972DIExpression *ValExpr, Value *Addr,973DIExpression *AddrExpr,974const DILocation *DL) {975auto *Link = cast_or_null<DIAssignID>(976LinkedInstr->getMetadata(LLVMContext::MD_DIAssignID));977assert(Link && "Linked instruction must have DIAssign metadata attached");978979if (M.IsNewDbgInfoFormat) {980DbgVariableRecord *DVR = DbgVariableRecord::createDVRAssign(981Val, SrcVar, ValExpr, Link, Addr, AddrExpr, DL);982BasicBlock *InsertBB = LinkedInstr->getParent();983// Insert after LinkedInstr.984BasicBlock::iterator NextIt = std::next(LinkedInstr->getIterator());985Instruction *InsertBefore = NextIt == InsertBB->end() ? nullptr : &*NextIt;986insertDbgVariableRecord(DVR, InsertBB, InsertBefore, true);987return DVR;988}989990LLVMContext &Ctx = LinkedInstr->getContext();991Module *M = LinkedInstr->getModule();992if (!AssignFn)993AssignFn = Intrinsic::getDeclaration(M, Intrinsic::dbg_assign);994995std::array<Value *, 6> Args = {996MetadataAsValue::get(Ctx, ValueAsMetadata::get(Val)),997MetadataAsValue::get(Ctx, SrcVar),998MetadataAsValue::get(Ctx, ValExpr),999MetadataAsValue::get(Ctx, Link),1000MetadataAsValue::get(Ctx, ValueAsMetadata::get(Addr)),1001MetadataAsValue::get(Ctx, AddrExpr),1002};10031004IRBuilder<> B(Ctx);1005B.SetCurrentDebugLocation(DL);10061007auto *DVI = cast<DbgAssignIntrinsic>(B.CreateCall(AssignFn, Args));1008DVI->insertAfter(LinkedInstr);1009return DVI;1010}10111012DbgInstPtr DIBuilder::insertLabel(DILabel *LabelInfo, const DILocation *DL,1013Instruction *InsertBefore) {1014return insertLabel(LabelInfo, DL,1015InsertBefore ? InsertBefore->getParent() : nullptr,1016InsertBefore);1017}10181019DbgInstPtr DIBuilder::insertLabel(DILabel *LabelInfo, const DILocation *DL,1020BasicBlock *InsertAtEnd) {1021return insertLabel(LabelInfo, DL, InsertAtEnd, nullptr);1022}10231024DbgInstPtr DIBuilder::insertDbgValueIntrinsic(Value *V,1025DILocalVariable *VarInfo,1026DIExpression *Expr,1027const DILocation *DL,1028Instruction *InsertBefore) {1029DbgInstPtr DVI = insertDbgValueIntrinsic(1030V, VarInfo, Expr, DL, InsertBefore ? InsertBefore->getParent() : nullptr,1031InsertBefore);1032if (DVI.is<Instruction *>())1033cast<CallInst>(DVI.get<Instruction *>())->setTailCall();1034return DVI;1035}10361037DbgInstPtr DIBuilder::insertDbgValueIntrinsic(Value *V,1038DILocalVariable *VarInfo,1039DIExpression *Expr,1040const DILocation *DL,1041BasicBlock *InsertAtEnd) {1042return insertDbgValueIntrinsic(V, VarInfo, Expr, DL, InsertAtEnd, nullptr);1043}10441045/// Initialize IRBuilder for inserting dbg.declare and dbg.value intrinsics.1046/// This abstracts over the various ways to specify an insert position.1047static void initIRBuilder(IRBuilder<> &Builder, const DILocation *DL,1048BasicBlock *InsertBB, Instruction *InsertBefore) {1049if (InsertBefore)1050Builder.SetInsertPoint(InsertBefore);1051else if (InsertBB)1052Builder.SetInsertPoint(InsertBB);1053Builder.SetCurrentDebugLocation(DL);1054}10551056static Value *getDbgIntrinsicValueImpl(LLVMContext &VMContext, Value *V) {1057assert(V && "no value passed to dbg intrinsic");1058return MetadataAsValue::get(VMContext, ValueAsMetadata::get(V));1059}10601061static Function *getDeclareIntrin(Module &M) {1062return Intrinsic::getDeclaration(&M, Intrinsic::dbg_declare);1063}10641065DbgInstPtr DIBuilder::insertDbgValueIntrinsic(1066llvm::Value *Val, DILocalVariable *VarInfo, DIExpression *Expr,1067const DILocation *DL, BasicBlock *InsertBB, Instruction *InsertBefore) {1068if (M.IsNewDbgInfoFormat) {1069DbgVariableRecord *DVR =1070DbgVariableRecord::createDbgVariableRecord(Val, VarInfo, Expr, DL);1071insertDbgVariableRecord(DVR, InsertBB, InsertBefore);1072return DVR;1073}10741075if (!ValueFn)1076ValueFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_value);1077return insertDbgIntrinsic(ValueFn, Val, VarInfo, Expr, DL, InsertBB,1078InsertBefore);1079}10801081DbgInstPtr DIBuilder::insertDeclare(Value *Storage, DILocalVariable *VarInfo,1082DIExpression *Expr, const DILocation *DL,1083BasicBlock *InsertBB,1084Instruction *InsertBefore) {1085assert(VarInfo && "empty or invalid DILocalVariable* passed to dbg.declare");1086assert(DL && "Expected debug loc");1087assert(DL->getScope()->getSubprogram() ==1088VarInfo->getScope()->getSubprogram() &&1089"Expected matching subprograms");10901091if (M.IsNewDbgInfoFormat) {1092DbgVariableRecord *DVR =1093DbgVariableRecord::createDVRDeclare(Storage, VarInfo, Expr, DL);1094insertDbgVariableRecord(DVR, InsertBB, InsertBefore);1095return DVR;1096}10971098if (!DeclareFn)1099DeclareFn = getDeclareIntrin(M);11001101trackIfUnresolved(VarInfo);1102trackIfUnresolved(Expr);1103Value *Args[] = {getDbgIntrinsicValueImpl(VMContext, Storage),1104MetadataAsValue::get(VMContext, VarInfo),1105MetadataAsValue::get(VMContext, Expr)};11061107IRBuilder<> B(DL->getContext());1108initIRBuilder(B, DL, InsertBB, InsertBefore);1109return B.CreateCall(DeclareFn, Args);1110}11111112void DIBuilder::insertDbgVariableRecord(DbgVariableRecord *DVR,1113BasicBlock *InsertBB,1114Instruction *InsertBefore,1115bool InsertAtHead) {1116assert(InsertBefore || InsertBB);1117trackIfUnresolved(DVR->getVariable());1118trackIfUnresolved(DVR->getExpression());1119if (DVR->isDbgAssign())1120trackIfUnresolved(DVR->getAddressExpression());11211122BasicBlock::iterator InsertPt;1123if (InsertBB && InsertBefore)1124InsertPt = InsertBefore->getIterator();1125else if (InsertBB)1126InsertPt = InsertBB->end();1127InsertPt.setHeadBit(InsertAtHead);1128InsertBB->insertDbgRecordBefore(DVR, InsertPt);1129}11301131Instruction *DIBuilder::insertDbgIntrinsic(llvm::Function *IntrinsicFn,1132Value *V, DILocalVariable *VarInfo,1133DIExpression *Expr,1134const DILocation *DL,1135BasicBlock *InsertBB,1136Instruction *InsertBefore) {1137assert(IntrinsicFn && "must pass a non-null intrinsic function");1138assert(V && "must pass a value to a dbg intrinsic");1139assert(VarInfo &&1140"empty or invalid DILocalVariable* passed to debug intrinsic");1141assert(DL && "Expected debug loc");1142assert(DL->getScope()->getSubprogram() ==1143VarInfo->getScope()->getSubprogram() &&1144"Expected matching subprograms");11451146trackIfUnresolved(VarInfo);1147trackIfUnresolved(Expr);1148Value *Args[] = {getDbgIntrinsicValueImpl(VMContext, V),1149MetadataAsValue::get(VMContext, VarInfo),1150MetadataAsValue::get(VMContext, Expr)};11511152IRBuilder<> B(DL->getContext());1153initIRBuilder(B, DL, InsertBB, InsertBefore);1154return B.CreateCall(IntrinsicFn, Args);1155}11561157DbgInstPtr DIBuilder::insertLabel(DILabel *LabelInfo, const DILocation *DL,1158BasicBlock *InsertBB,1159Instruction *InsertBefore) {1160assert(LabelInfo && "empty or invalid DILabel* passed to dbg.label");1161assert(DL && "Expected debug loc");1162assert(DL->getScope()->getSubprogram() ==1163LabelInfo->getScope()->getSubprogram() &&1164"Expected matching subprograms");11651166trackIfUnresolved(LabelInfo);1167if (M.IsNewDbgInfoFormat) {1168DbgLabelRecord *DLR = new DbgLabelRecord(LabelInfo, DL);1169if (InsertBB && InsertBefore)1170InsertBB->insertDbgRecordBefore(DLR, InsertBefore->getIterator());1171else if (InsertBB)1172InsertBB->insertDbgRecordBefore(DLR, InsertBB->end());1173return DLR;1174}11751176if (!LabelFn)1177LabelFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_label);11781179Value *Args[] = {MetadataAsValue::get(VMContext, LabelInfo)};11801181IRBuilder<> B(DL->getContext());1182initIRBuilder(B, DL, InsertBB, InsertBefore);1183return B.CreateCall(LabelFn, Args);1184}11851186void DIBuilder::replaceVTableHolder(DICompositeType *&T, DIType *VTableHolder) {1187{1188TypedTrackingMDRef<DICompositeType> N(T);1189N->replaceVTableHolder(VTableHolder);1190T = N.get();1191}11921193// If this didn't create a self-reference, just return.1194if (T != VTableHolder)1195return;11961197// Look for unresolved operands. T will drop RAUW support, orphaning any1198// cycles underneath it.1199if (T->isResolved())1200for (const MDOperand &O : T->operands())1201if (auto *N = dyn_cast_or_null<MDNode>(O))1202trackIfUnresolved(N);1203}12041205void DIBuilder::replaceArrays(DICompositeType *&T, DINodeArray Elements,1206DINodeArray TParams) {1207{1208TypedTrackingMDRef<DICompositeType> N(T);1209if (Elements)1210N->replaceElements(Elements);1211if (TParams)1212N->replaceTemplateParams(DITemplateParameterArray(TParams));1213T = N.get();1214}12151216// If T isn't resolved, there's no problem.1217if (!T->isResolved())1218return;12191220// If T is resolved, it may be due to a self-reference cycle. Track the1221// arrays explicitly if they're unresolved, or else the cycles will be1222// orphaned.1223if (Elements)1224trackIfUnresolved(Elements.get());1225if (TParams)1226trackIfUnresolved(TParams.get());1227}122812291230