brintos

brintos / llvm-project-archived public Read only

0
0
Text · 55.8 KiB · b01860d Raw
1264 lines · cpp
1//===--- DIBuilder.cpp - Debug Information Builder ------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file implements the DIBuilder.10//11//===----------------------------------------------------------------------===//12 13#include "llvm/IR/DIBuilder.h"14#include "LLVMContextImpl.h"15#include "llvm/ADT/APInt.h"16#include "llvm/ADT/APSInt.h"17#include "llvm/BinaryFormat/Dwarf.h"18#include "llvm/IR/Constants.h"19#include "llvm/IR/DebugInfo.h"20#include "llvm/IR/IRBuilder.h"21#include "llvm/IR/Module.h"22#include <optional>23 24using namespace llvm;25using namespace llvm::dwarf;26 27DIBuilder::DIBuilder(Module &m, bool AllowUnresolvedNodes, DICompileUnit *CU)28    : M(m), VMContext(M.getContext()), CUNode(CU),29      AllowUnresolvedNodes(AllowUnresolvedNodes) {30  if (CUNode) {31    if (const auto &ETs = CUNode->getEnumTypes())32      AllEnumTypes.assign(ETs.begin(), ETs.end());33    if (const auto &RTs = CUNode->getRetainedTypes())34      AllRetainTypes.assign(RTs.begin(), RTs.end());35    if (const auto &GVs = CUNode->getGlobalVariables())36      AllGVs.assign(GVs.begin(), GVs.end());37    if (const auto &IMs = CUNode->getImportedEntities())38      ImportedModules.assign(IMs.begin(), IMs.end());39    if (const auto &MNs = CUNode->getMacros())40      AllMacrosPerParent.insert({nullptr, {llvm::from_range, MNs}});41  }42}43 44void DIBuilder::trackIfUnresolved(MDNode *N) {45  if (!N)46    return;47  if (N->isResolved())48    return;49 50  assert(AllowUnresolvedNodes && "Cannot handle unresolved nodes");51  UnresolvedNodes.emplace_back(N);52}53 54void DIBuilder::finalizeSubprogram(DISubprogram *SP) {55  auto PN = SubprogramTrackedNodes.find(SP);56  if (PN != SubprogramTrackedNodes.end())57    SP->replaceRetainedNodes(58        MDTuple::get(VMContext, SmallVector<Metadata *, 16>(PN->second.begin(),59                                                            PN->second.end())));60}61 62void DIBuilder::finalize() {63  if (!CUNode) {64    assert(!AllowUnresolvedNodes &&65           "creating type nodes without a CU is not supported");66    return;67  }68 69  if (!AllEnumTypes.empty())70    CUNode->replaceEnumTypes(MDTuple::get(71        VMContext, SmallVector<Metadata *, 16>(AllEnumTypes.begin(),72                                               AllEnumTypes.end())));73 74  SmallVector<Metadata *, 16> RetainValues;75  // Declarations and definitions of the same type may be retained. Some76  // clients RAUW these pairs, leaving duplicates in the retained types77  // list. Use a set to remove the duplicates while we transform the78  // TrackingVHs back into Values.79  SmallPtrSet<Metadata *, 16> RetainSet;80  for (const TrackingMDNodeRef &N : AllRetainTypes)81    if (RetainSet.insert(N).second)82      RetainValues.push_back(N);83 84  if (!RetainValues.empty())85    CUNode->replaceRetainedTypes(MDTuple::get(VMContext, RetainValues));86 87  for (auto *SP : AllSubprograms)88    finalizeSubprogram(SP);89  for (auto *N : RetainValues)90    if (auto *SP = dyn_cast<DISubprogram>(N))91      finalizeSubprogram(SP);92 93  if (!AllGVs.empty())94    CUNode->replaceGlobalVariables(MDTuple::get(VMContext, AllGVs));95 96  if (!ImportedModules.empty())97    CUNode->replaceImportedEntities(MDTuple::get(98        VMContext, SmallVector<Metadata *, 16>(ImportedModules.begin(),99                                               ImportedModules.end())));100 101  for (const auto &I : AllMacrosPerParent) {102    // DIMacroNode's with nullptr parent are DICompileUnit direct children.103    if (!I.first) {104      CUNode->replaceMacros(MDTuple::get(VMContext, I.second.getArrayRef()));105      continue;106    }107    // Otherwise, it must be a temporary DIMacroFile that need to be resolved.108    auto *TMF = cast<DIMacroFile>(I.first);109    auto *MF = DIMacroFile::get(VMContext, dwarf::DW_MACINFO_start_file,110                                TMF->getLine(), TMF->getFile(),111                                getOrCreateMacroArray(I.second.getArrayRef()));112    replaceTemporary(llvm::TempDIMacroNode(TMF), MF);113  }114 115  // Now that all temp nodes have been replaced or deleted, resolve remaining116  // cycles.117  for (const auto &N : UnresolvedNodes)118    if (N && !N->isResolved())119      N->resolveCycles();120  UnresolvedNodes.clear();121 122  // Can't handle unresolved nodes anymore.123  AllowUnresolvedNodes = false;124}125 126/// If N is compile unit return NULL otherwise return N.127static DIScope *getNonCompileUnitScope(DIScope *N) {128  if (!N || isa<DICompileUnit>(N))129    return nullptr;130  return cast<DIScope>(N);131}132 133DICompileUnit *DIBuilder::createCompileUnit(134    DISourceLanguageName Lang, DIFile *File, StringRef Producer,135    bool isOptimized, StringRef Flags, unsigned RunTimeVer, StringRef SplitName,136    DICompileUnit::DebugEmissionKind Kind, uint64_t DWOId,137    bool SplitDebugInlining, bool DebugInfoForProfiling,138    DICompileUnit::DebugNameTableKind NameTableKind, bool RangesBaseAddress,139    StringRef SysRoot, StringRef SDK) {140 141  assert(!CUNode && "Can only make one compile unit per DIBuilder instance");142  CUNode = DICompileUnit::getDistinct(143      VMContext, Lang, File, Producer, isOptimized, Flags, RunTimeVer,144      SplitName, Kind, nullptr, nullptr, nullptr, nullptr, nullptr, DWOId,145      SplitDebugInlining, DebugInfoForProfiling, NameTableKind,146      RangesBaseAddress, SysRoot, SDK);147 148  // Create a named metadata so that it is easier to find cu in a module.149  NamedMDNode *NMD = M.getOrInsertNamedMetadata("llvm.dbg.cu");150  NMD->addOperand(CUNode);151  trackIfUnresolved(CUNode);152  return CUNode;153}154 155static DIImportedEntity *156createImportedModule(LLVMContext &C, dwarf::Tag Tag, DIScope *Context,157                     Metadata *NS, DIFile *File, unsigned Line, StringRef Name,158                     DINodeArray Elements,159                     SmallVectorImpl<TrackingMDNodeRef> &ImportedModules) {160  if (Line)161    assert(File && "Source location has line number but no file");162  unsigned EntitiesCount = C.pImpl->DIImportedEntitys.size();163  auto *M = DIImportedEntity::get(C, Tag, Context, cast_or_null<DINode>(NS),164                                  File, Line, Name, Elements);165  if (EntitiesCount < C.pImpl->DIImportedEntitys.size())166    // A new Imported Entity was just added to the context.167    // Add it to the Imported Modules list.168    ImportedModules.emplace_back(M);169  return M;170}171 172DIImportedEntity *DIBuilder::createImportedModule(DIScope *Context,173                                                  DINamespace *NS, DIFile *File,174                                                  unsigned Line,175                                                  DINodeArray Elements) {176  return ::createImportedModule(VMContext, dwarf::DW_TAG_imported_module,177                                Context, NS, File, Line, StringRef(), Elements,178                                getImportTrackingVector(Context));179}180 181DIImportedEntity *DIBuilder::createImportedModule(DIScope *Context,182                                                  DIImportedEntity *NS,183                                                  DIFile *File, unsigned Line,184                                                  DINodeArray Elements) {185  return ::createImportedModule(VMContext, dwarf::DW_TAG_imported_module,186                                Context, NS, File, Line, StringRef(), Elements,187                                getImportTrackingVector(Context));188}189 190DIImportedEntity *DIBuilder::createImportedModule(DIScope *Context, DIModule *M,191                                                  DIFile *File, unsigned Line,192                                                  DINodeArray Elements) {193  return ::createImportedModule(VMContext, dwarf::DW_TAG_imported_module,194                                Context, M, File, Line, StringRef(), Elements,195                                getImportTrackingVector(Context));196}197 198DIImportedEntity *199DIBuilder::createImportedDeclaration(DIScope *Context, DINode *Decl,200                                     DIFile *File, unsigned Line,201                                     StringRef Name, DINodeArray Elements) {202  // Make sure to use the unique identifier based metadata reference for203  // types that have one.204  return ::createImportedModule(VMContext, dwarf::DW_TAG_imported_declaration,205                                Context, Decl, File, Line, Name, Elements,206                                getImportTrackingVector(Context));207}208 209DIFile *DIBuilder::createFile(StringRef Filename, StringRef Directory,210                              std::optional<DIFile::ChecksumInfo<StringRef>> CS,211                              std::optional<StringRef> Source) {212  return DIFile::get(VMContext, Filename, Directory, CS, Source);213}214 215DIMacro *DIBuilder::createMacro(DIMacroFile *Parent, unsigned LineNumber,216                                unsigned MacroType, StringRef Name,217                                StringRef Value) {218  assert(!Name.empty() && "Unable to create macro without name");219  assert((MacroType == dwarf::DW_MACINFO_undef ||220          MacroType == dwarf::DW_MACINFO_define) &&221         "Unexpected macro type");222  auto *M = DIMacro::get(VMContext, MacroType, LineNumber, Name, Value);223  AllMacrosPerParent[Parent].insert(M);224  return M;225}226 227DIMacroFile *DIBuilder::createTempMacroFile(DIMacroFile *Parent,228                                            unsigned LineNumber, DIFile *File) {229  auto *MF = DIMacroFile::getTemporary(VMContext, dwarf::DW_MACINFO_start_file,230                                       LineNumber, File, DIMacroNodeArray())231                 .release();232  AllMacrosPerParent[Parent].insert(MF);233  // Add the new temporary DIMacroFile to the macro per parent map as a parent.234  // This is needed to assure DIMacroFile with no children to have an entry in235  // the map. Otherwise, it will not be resolved in DIBuilder::finalize().236  AllMacrosPerParent.insert({MF, {}});237  return MF;238}239 240DIEnumerator *DIBuilder::createEnumerator(StringRef Name, uint64_t Val,241                                          bool IsUnsigned) {242  assert(!Name.empty() && "Unable to create enumerator without name");243  return DIEnumerator::get(VMContext, APInt(64, Val, !IsUnsigned), IsUnsigned,244                           Name);245}246 247DIEnumerator *DIBuilder::createEnumerator(StringRef Name, const APSInt &Value) {248  assert(!Name.empty() && "Unable to create enumerator without name");249  return DIEnumerator::get(VMContext, APInt(Value), Value.isUnsigned(), Name);250}251 252DIBasicType *DIBuilder::createUnspecifiedType(StringRef Name) {253  assert(!Name.empty() && "Unable to create type without name");254  return DIBasicType::get(VMContext, dwarf::DW_TAG_unspecified_type, Name);255}256 257DIBasicType *DIBuilder::createNullPtrType() {258  return createUnspecifiedType("decltype(nullptr)");259}260 261DIBasicType *DIBuilder::createBasicType(StringRef Name, uint64_t SizeInBits,262                                        unsigned Encoding,263                                        DINode::DIFlags Flags,264                                        uint32_t NumExtraInhabitants,265                                        uint32_t DataSizeInBits) {266  assert(!Name.empty() && "Unable to create type without name");267  return DIBasicType::get(VMContext, dwarf::DW_TAG_base_type, Name, SizeInBits,268                          0, Encoding, NumExtraInhabitants, DataSizeInBits,269                          Flags);270}271 272DIFixedPointType *273DIBuilder::createBinaryFixedPointType(StringRef Name, uint64_t SizeInBits,274                                      uint32_t AlignInBits, unsigned Encoding,275                                      DINode::DIFlags Flags, int Factor) {276  return DIFixedPointType::get(VMContext, dwarf::DW_TAG_base_type, Name,277                               SizeInBits, AlignInBits, Encoding, Flags,278                               DIFixedPointType::FixedPointBinary, Factor,279                               APInt(), APInt());280}281 282DIFixedPointType *283DIBuilder::createDecimalFixedPointType(StringRef Name, uint64_t SizeInBits,284                                       uint32_t AlignInBits, unsigned Encoding,285                                       DINode::DIFlags Flags, int Factor) {286  return DIFixedPointType::get(VMContext, dwarf::DW_TAG_base_type, Name,287                               SizeInBits, AlignInBits, Encoding, Flags,288                               DIFixedPointType::FixedPointDecimal, Factor,289                               APInt(), APInt());290}291 292DIFixedPointType *293DIBuilder::createRationalFixedPointType(StringRef Name, uint64_t SizeInBits,294                                        uint32_t AlignInBits, unsigned Encoding,295                                        DINode::DIFlags Flags, APInt Numerator,296                                        APInt Denominator) {297  return DIFixedPointType::get(VMContext, dwarf::DW_TAG_base_type, Name,298                               SizeInBits, AlignInBits, Encoding, Flags,299                               DIFixedPointType::FixedPointRational, 0,300                               Numerator, Denominator);301}302 303DIStringType *DIBuilder::createStringType(StringRef Name, uint64_t SizeInBits) {304  assert(!Name.empty() && "Unable to create type without name");305  return DIStringType::get(VMContext, dwarf::DW_TAG_string_type, Name,306                           SizeInBits, 0);307}308 309DIStringType *DIBuilder::createStringType(StringRef Name,310                                          DIVariable *StringLength,311                                          DIExpression *StrLocationExp) {312  assert(!Name.empty() && "Unable to create type without name");313  return DIStringType::get(VMContext, dwarf::DW_TAG_string_type, Name,314                           StringLength, nullptr, StrLocationExp, 0, 0, 0);315}316 317DIStringType *DIBuilder::createStringType(StringRef Name,318                                          DIExpression *StringLengthExp,319                                          DIExpression *StrLocationExp) {320  assert(!Name.empty() && "Unable to create type without name");321  return DIStringType::get(VMContext, dwarf::DW_TAG_string_type, Name, nullptr,322                           StringLengthExp, StrLocationExp, 0, 0, 0);323}324 325DIDerivedType *DIBuilder::createQualifiedType(unsigned Tag, DIType *FromTy) {326  return DIDerivedType::get(VMContext, Tag, "", nullptr, 0, nullptr, FromTy,327                            (uint64_t)0, 0, (uint64_t)0, std::nullopt,328                            std::nullopt, DINode::FlagZero);329}330 331DIDerivedType *DIBuilder::createPtrAuthQualifiedType(332    DIType *FromTy, unsigned Key, bool IsAddressDiscriminated,333    unsigned ExtraDiscriminator, bool IsaPointer,334    bool AuthenticatesNullValues) {335  return DIDerivedType::get(336      VMContext, dwarf::DW_TAG_LLVM_ptrauth_type, "", nullptr, 0, nullptr,337      FromTy, (uint64_t)0, 0, (uint64_t)0, std::nullopt,338      std::optional<DIDerivedType::PtrAuthData>(339          std::in_place, Key, IsAddressDiscriminated, ExtraDiscriminator,340          IsaPointer, AuthenticatesNullValues),341      DINode::FlagZero);342}343 344DIDerivedType *345DIBuilder::createPointerType(DIType *PointeeTy, uint64_t SizeInBits,346                             uint32_t AlignInBits,347                             std::optional<unsigned> DWARFAddressSpace,348                             StringRef Name, DINodeArray Annotations) {349  // FIXME: Why is there a name here?350  return DIDerivedType::get(VMContext, dwarf::DW_TAG_pointer_type, Name,351                            nullptr, 0, nullptr, PointeeTy, SizeInBits,352                            AlignInBits, 0, DWARFAddressSpace, std::nullopt,353                            DINode::FlagZero, nullptr, Annotations);354}355 356DIDerivedType *DIBuilder::createMemberPointerType(DIType *PointeeTy,357                                                  DIType *Base,358                                                  uint64_t SizeInBits,359                                                  uint32_t AlignInBits,360                                                  DINode::DIFlags Flags) {361  return DIDerivedType::get(VMContext, dwarf::DW_TAG_ptr_to_member_type, "",362                            nullptr, 0, nullptr, PointeeTy, SizeInBits,363                            AlignInBits, 0, std::nullopt, std::nullopt, Flags,364                            Base);365}366 367DIDerivedType *368DIBuilder::createReferenceType(unsigned Tag, DIType *RTy, uint64_t SizeInBits,369                               uint32_t AlignInBits,370                               std::optional<unsigned> DWARFAddressSpace) {371  assert(RTy && "Unable to create reference type");372  return DIDerivedType::get(VMContext, Tag, "", nullptr, 0, nullptr, RTy,373                            SizeInBits, AlignInBits, 0, DWARFAddressSpace, {},374                            DINode::FlagZero);375}376 377DIDerivedType *DIBuilder::createTypedef(DIType *Ty, StringRef Name,378                                        DIFile *File, unsigned LineNo,379                                        DIScope *Context, uint32_t AlignInBits,380                                        DINode::DIFlags Flags,381                                        DINodeArray Annotations) {382  return DIDerivedType::get(VMContext, dwarf::DW_TAG_typedef, Name, File,383                            LineNo, getNonCompileUnitScope(Context), Ty,384                            (uint64_t)0, AlignInBits, (uint64_t)0, std::nullopt,385                            std::nullopt, Flags, nullptr, Annotations);386}387 388DIDerivedType *389DIBuilder::createTemplateAlias(DIType *Ty, StringRef Name, DIFile *File,390                               unsigned LineNo, DIScope *Context,391                               DINodeArray TParams, uint32_t AlignInBits,392                               DINode::DIFlags Flags, DINodeArray Annotations) {393  return DIDerivedType::get(VMContext, dwarf::DW_TAG_template_alias, Name, File,394                            LineNo, getNonCompileUnitScope(Context), Ty,395                            (uint64_t)0, AlignInBits, (uint64_t)0, std::nullopt,396                            std::nullopt, Flags, TParams.get(), Annotations);397}398 399DIDerivedType *DIBuilder::createFriend(DIType *Ty, DIType *FriendTy) {400  assert(Ty && "Invalid type!");401  assert(FriendTy && "Invalid friend type!");402  return DIDerivedType::get(VMContext, dwarf::DW_TAG_friend, "", nullptr, 0, Ty,403                            FriendTy, (uint64_t)0, 0, (uint64_t)0, std::nullopt,404                            std::nullopt, DINode::FlagZero);405}406 407DIDerivedType *DIBuilder::createInheritance(DIType *Ty, DIType *BaseTy,408                                            uint64_t BaseOffset,409                                            uint32_t VBPtrOffset,410                                            DINode::DIFlags Flags) {411  assert(Ty && "Unable to create inheritance");412  Metadata *ExtraData = ConstantAsMetadata::get(413      ConstantInt::get(IntegerType::get(VMContext, 32), VBPtrOffset));414  return DIDerivedType::get(VMContext, dwarf::DW_TAG_inheritance, "", nullptr,415                            0, Ty, BaseTy, 0, 0, BaseOffset, std::nullopt,416                            std::nullopt, Flags, ExtraData);417}418 419DIDerivedType *DIBuilder::createMemberType(420    DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNumber,421    uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits,422    DINode::DIFlags Flags, DIType *Ty, DINodeArray Annotations) {423  return DIDerivedType::get(VMContext, dwarf::DW_TAG_member, Name, File,424                            LineNumber, getNonCompileUnitScope(Scope), Ty,425                            SizeInBits, AlignInBits, OffsetInBits, std::nullopt,426                            std::nullopt, Flags, nullptr, Annotations);427}428 429DIDerivedType *DIBuilder::createMemberType(430    DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNumber,431    Metadata *SizeInBits, uint32_t AlignInBits, Metadata *OffsetInBits,432    DINode::DIFlags Flags, DIType *Ty, DINodeArray Annotations) {433  return DIDerivedType::get(VMContext, dwarf::DW_TAG_member, Name, File,434                            LineNumber, getNonCompileUnitScope(Scope), Ty,435                            SizeInBits, AlignInBits, OffsetInBits, std::nullopt,436                            std::nullopt, Flags, nullptr, Annotations);437}438 439static ConstantAsMetadata *getConstantOrNull(Constant *C) {440  if (C)441    return ConstantAsMetadata::get(C);442  return nullptr;443}444 445DIDerivedType *DIBuilder::createVariantMemberType(446    DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNumber,447    uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits,448    Constant *Discriminant, DINode::DIFlags Flags, DIType *Ty) {449  // "ExtraData" is overloaded for bit fields and for variants, so450  // make sure to disallow this.451  assert((Flags & DINode::FlagBitField) == 0);452  return DIDerivedType::get(453      VMContext, dwarf::DW_TAG_member, Name, File, LineNumber,454      getNonCompileUnitScope(Scope), Ty, SizeInBits, AlignInBits, OffsetInBits,455      std::nullopt, std::nullopt, Flags, getConstantOrNull(Discriminant));456}457 458DIDerivedType *DIBuilder::createVariantMemberType(DIScope *Scope,459                                                  DINodeArray Elements,460                                                  Constant *Discriminant,461                                                  DIType *Ty) {462  auto *V = DICompositeType::get(VMContext, dwarf::DW_TAG_variant, {}, nullptr,463                                 0, getNonCompileUnitScope(Scope), {},464                                 (uint64_t)0, 0, (uint64_t)0, DINode::FlagZero,465                                 Elements, 0, {}, nullptr);466 467  trackIfUnresolved(V);468  return createVariantMemberType(Scope, {}, nullptr, 0, 0, 0, 0, Discriminant,469                                 DINode::FlagZero, V);470}471 472DIDerivedType *DIBuilder::createBitFieldMemberType(473    DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNumber,474    Metadata *SizeInBits, Metadata *OffsetInBits, uint64_t StorageOffsetInBits,475    DINode::DIFlags Flags, DIType *Ty, DINodeArray Annotations) {476  Flags |= DINode::FlagBitField;477  return DIDerivedType::get(478      VMContext, dwarf::DW_TAG_member, Name, File, LineNumber,479      getNonCompileUnitScope(Scope), Ty, SizeInBits, /*AlignInBits=*/0,480      OffsetInBits, std::nullopt, std::nullopt, Flags,481      ConstantAsMetadata::get(ConstantInt::get(IntegerType::get(VMContext, 64),482                                               StorageOffsetInBits)),483      Annotations);484}485 486DIDerivedType *DIBuilder::createBitFieldMemberType(487    DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNumber,488    uint64_t SizeInBits, uint64_t OffsetInBits, uint64_t StorageOffsetInBits,489    DINode::DIFlags Flags, DIType *Ty, DINodeArray Annotations) {490  Flags |= DINode::FlagBitField;491  return DIDerivedType::get(492      VMContext, dwarf::DW_TAG_member, Name, File, LineNumber,493      getNonCompileUnitScope(Scope), Ty, SizeInBits, /*AlignInBits=*/0,494      OffsetInBits, std::nullopt, std::nullopt, Flags,495      ConstantAsMetadata::get(ConstantInt::get(IntegerType::get(VMContext, 64),496                                               StorageOffsetInBits)),497      Annotations);498}499 500DIDerivedType *501DIBuilder::createStaticMemberType(DIScope *Scope, StringRef Name, DIFile *File,502                                  unsigned LineNumber, DIType *Ty,503                                  DINode::DIFlags Flags, llvm::Constant *Val,504                                  unsigned Tag, uint32_t AlignInBits) {505  Flags |= DINode::FlagStaticMember;506  return DIDerivedType::get(VMContext, Tag, Name, File, LineNumber,507                            getNonCompileUnitScope(Scope), Ty, (uint64_t)0,508                            AlignInBits, (uint64_t)0, std::nullopt,509                            std::nullopt, Flags, getConstantOrNull(Val));510}511 512DIDerivedType *513DIBuilder::createObjCIVar(StringRef Name, DIFile *File, unsigned LineNumber,514                          uint64_t SizeInBits, uint32_t AlignInBits,515                          uint64_t OffsetInBits, DINode::DIFlags Flags,516                          DIType *Ty, MDNode *PropertyNode) {517  return DIDerivedType::get(VMContext, dwarf::DW_TAG_member, Name, File,518                            LineNumber, getNonCompileUnitScope(File), Ty,519                            SizeInBits, AlignInBits, OffsetInBits, std::nullopt,520                            std::nullopt, Flags, PropertyNode);521}522 523DIObjCProperty *524DIBuilder::createObjCProperty(StringRef Name, DIFile *File, unsigned LineNumber,525                              StringRef GetterName, StringRef SetterName,526                              unsigned PropertyAttributes, DIType *Ty) {527  return DIObjCProperty::get(VMContext, Name, File, LineNumber, GetterName,528                             SetterName, PropertyAttributes, Ty);529}530 531DITemplateTypeParameter *532DIBuilder::createTemplateTypeParameter(DIScope *Context, StringRef Name,533                                       DIType *Ty, bool isDefault) {534  assert((!Context || isa<DICompileUnit>(Context)) && "Expected compile unit");535  return DITemplateTypeParameter::get(VMContext, Name, Ty, isDefault);536}537 538static DITemplateValueParameter *539createTemplateValueParameterHelper(LLVMContext &VMContext, unsigned Tag,540                                   DIScope *Context, StringRef Name, DIType *Ty,541                                   bool IsDefault, Metadata *MD) {542  assert((!Context || isa<DICompileUnit>(Context)) && "Expected compile unit");543  return DITemplateValueParameter::get(VMContext, Tag, Name, Ty, IsDefault, MD);544}545 546DITemplateValueParameter *547DIBuilder::createTemplateValueParameter(DIScope *Context, StringRef Name,548                                        DIType *Ty, bool isDefault,549                                        Constant *Val) {550  return createTemplateValueParameterHelper(551      VMContext, dwarf::DW_TAG_template_value_parameter, Context, Name, Ty,552      isDefault, getConstantOrNull(Val));553}554 555DITemplateValueParameter *556DIBuilder::createTemplateTemplateParameter(DIScope *Context, StringRef Name,557                                           DIType *Ty, StringRef Val,558                                           bool IsDefault) {559  return createTemplateValueParameterHelper(560      VMContext, dwarf::DW_TAG_GNU_template_template_param, Context, Name, Ty,561      IsDefault, MDString::get(VMContext, Val));562}563 564DITemplateValueParameter *565DIBuilder::createTemplateParameterPack(DIScope *Context, StringRef Name,566                                       DIType *Ty, DINodeArray Val) {567  return createTemplateValueParameterHelper(568      VMContext, dwarf::DW_TAG_GNU_template_parameter_pack, Context, Name, Ty,569      false, Val.get());570}571 572DICompositeType *DIBuilder::createClassType(573    DIScope *Context, StringRef Name, DIFile *File, unsigned LineNumber,574    uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits,575    DINode::DIFlags Flags, DIType *DerivedFrom, DINodeArray Elements,576    unsigned RunTimeLang, DIType *VTableHolder, MDNode *TemplateParams,577    StringRef UniqueIdentifier) {578  assert((!Context || isa<DIScope>(Context)) &&579         "createClassType should be called with a valid Context");580 581  auto *R = DICompositeType::get(582      VMContext, dwarf::DW_TAG_class_type, Name, File, LineNumber,583      getNonCompileUnitScope(Context), DerivedFrom, SizeInBits, AlignInBits,584      OffsetInBits, Flags, Elements, RunTimeLang, /*EnumKind=*/std::nullopt,585      VTableHolder, cast_or_null<MDTuple>(TemplateParams), UniqueIdentifier);586  trackIfUnresolved(R);587  return R;588}589 590DICompositeType *DIBuilder::createStructType(591    DIScope *Context, StringRef Name, DIFile *File, unsigned LineNumber,592    Metadata *SizeInBits, uint32_t AlignInBits, DINode::DIFlags Flags,593    DIType *DerivedFrom, DINodeArray Elements, unsigned RunTimeLang,594    DIType *VTableHolder, StringRef UniqueIdentifier, DIType *Specification,595    uint32_t NumExtraInhabitants) {596  auto *R = DICompositeType::get(597      VMContext, dwarf::DW_TAG_structure_type, Name, File, LineNumber,598      getNonCompileUnitScope(Context), DerivedFrom, SizeInBits, AlignInBits, 0,599      Flags, Elements, RunTimeLang, /*EnumKind=*/std::nullopt, VTableHolder,600      nullptr, UniqueIdentifier, nullptr, nullptr, nullptr, nullptr, nullptr,601      nullptr, Specification, NumExtraInhabitants);602  trackIfUnresolved(R);603  return R;604}605 606DICompositeType *DIBuilder::createStructType(607    DIScope *Context, StringRef Name, DIFile *File, unsigned LineNumber,608    uint64_t SizeInBits, uint32_t AlignInBits, DINode::DIFlags Flags,609    DIType *DerivedFrom, DINodeArray Elements, unsigned RunTimeLang,610    DIType *VTableHolder, StringRef UniqueIdentifier, DIType *Specification,611    uint32_t NumExtraInhabitants) {612  auto *R = DICompositeType::get(613      VMContext, dwarf::DW_TAG_structure_type, Name, File, LineNumber,614      getNonCompileUnitScope(Context), DerivedFrom, SizeInBits, AlignInBits, 0,615      Flags, Elements, RunTimeLang, /*EnumKind=*/std::nullopt, VTableHolder,616      nullptr, UniqueIdentifier, nullptr, nullptr, nullptr, nullptr, nullptr,617      nullptr, Specification, NumExtraInhabitants);618  trackIfUnresolved(R);619  return R;620}621 622DICompositeType *DIBuilder::createUnionType(623    DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNumber,624    uint64_t SizeInBits, uint32_t AlignInBits, DINode::DIFlags Flags,625    DINodeArray Elements, unsigned RunTimeLang, StringRef UniqueIdentifier) {626  auto *R = DICompositeType::get(627      VMContext, dwarf::DW_TAG_union_type, Name, File, LineNumber,628      getNonCompileUnitScope(Scope), nullptr, SizeInBits, AlignInBits, 0, Flags,629      Elements, RunTimeLang, /*EnumKind=*/std::nullopt, nullptr, nullptr,630      UniqueIdentifier);631  trackIfUnresolved(R);632  return R;633}634 635DICompositeType *636DIBuilder::createVariantPart(DIScope *Scope, StringRef Name, DIFile *File,637                             unsigned LineNumber, uint64_t SizeInBits,638                             uint32_t AlignInBits, DINode::DIFlags Flags,639                             DIDerivedType *Discriminator, DINodeArray Elements,640                             StringRef UniqueIdentifier) {641  auto *R = DICompositeType::get(642      VMContext, dwarf::DW_TAG_variant_part, Name, File, LineNumber,643      getNonCompileUnitScope(Scope), nullptr, SizeInBits, AlignInBits, 0, Flags,644      Elements, 0, /*EnumKind=*/std::nullopt, nullptr, nullptr,645      UniqueIdentifier, Discriminator);646  trackIfUnresolved(R);647  return R;648}649 650DISubroutineType *DIBuilder::createSubroutineType(DITypeRefArray ParameterTypes,651                                                  DINode::DIFlags Flags,652                                                  unsigned CC) {653  return DISubroutineType::get(VMContext, Flags, CC, ParameterTypes);654}655 656DICompositeType *DIBuilder::createEnumerationType(657    DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNumber,658    uint64_t SizeInBits, uint32_t AlignInBits, DINodeArray Elements,659    DIType *UnderlyingType, unsigned RunTimeLang, StringRef UniqueIdentifier,660    bool IsScoped, std::optional<uint32_t> EnumKind) {661  auto *CTy = DICompositeType::get(662      VMContext, dwarf::DW_TAG_enumeration_type, Name, File, LineNumber,663      getNonCompileUnitScope(Scope), UnderlyingType, SizeInBits, AlignInBits, 0,664      IsScoped ? DINode::FlagEnumClass : DINode::FlagZero, Elements,665      RunTimeLang, EnumKind, nullptr, nullptr, UniqueIdentifier);666  AllEnumTypes.emplace_back(CTy);667  trackIfUnresolved(CTy);668  return CTy;669}670 671DIDerivedType *DIBuilder::createSetType(DIScope *Scope, StringRef Name,672                                        DIFile *File, unsigned LineNo,673                                        uint64_t SizeInBits,674                                        uint32_t AlignInBits, DIType *Ty) {675  auto *R = DIDerivedType::get(VMContext, dwarf::DW_TAG_set_type, Name, File,676                               LineNo, getNonCompileUnitScope(Scope), Ty,677                               SizeInBits, AlignInBits, 0, std::nullopt,678                               std::nullopt, DINode::FlagZero);679  trackIfUnresolved(R);680  return R;681}682 683DICompositeType *684DIBuilder::createArrayType(uint64_t Size, uint32_t AlignInBits, DIType *Ty,685                           DINodeArray Subscripts,686                           PointerUnion<DIExpression *, DIVariable *> DL,687                           PointerUnion<DIExpression *, DIVariable *> AS,688                           PointerUnion<DIExpression *, DIVariable *> AL,689                           PointerUnion<DIExpression *, DIVariable *> RK) {690  return createArrayType(nullptr, StringRef(), nullptr, 0, Size, AlignInBits,691                         Ty, Subscripts, DL, AS, AL, RK);692}693 694DICompositeType *DIBuilder::createArrayType(695    DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNumber,696    uint64_t Size, uint32_t AlignInBits, DIType *Ty, DINodeArray Subscripts,697    PointerUnion<DIExpression *, DIVariable *> DL,698    PointerUnion<DIExpression *, DIVariable *> AS,699    PointerUnion<DIExpression *, DIVariable *> AL,700    PointerUnion<DIExpression *, DIVariable *> RK, Metadata *BitStride) {701  auto *R = DICompositeType::get(702      VMContext, dwarf::DW_TAG_array_type, Name, File, LineNumber,703      getNonCompileUnitScope(Scope), Ty, Size, AlignInBits, 0, DINode::FlagZero,704      Subscripts, 0, /*EnumKind=*/std::nullopt, nullptr, nullptr, "", nullptr,705      isa<DIExpression *>(DL) ? (Metadata *)cast<DIExpression *>(DL)706                              : (Metadata *)cast<DIVariable *>(DL),707      isa<DIExpression *>(AS) ? (Metadata *)cast<DIExpression *>(AS)708                              : (Metadata *)cast<DIVariable *>(AS),709      isa<DIExpression *>(AL) ? (Metadata *)cast<DIExpression *>(AL)710                              : (Metadata *)cast<DIVariable *>(AL),711      isa<DIExpression *>(RK) ? (Metadata *)cast<DIExpression *>(RK)712                              : (Metadata *)cast<DIVariable *>(RK),713      nullptr, nullptr, 0, BitStride);714  trackIfUnresolved(R);715  return R;716}717 718DICompositeType *DIBuilder::createVectorType(uint64_t Size,719                                             uint32_t AlignInBits, DIType *Ty,720                                             DINodeArray Subscripts,721                                             Metadata *BitStride) {722  auto *R = DICompositeType::get(723      VMContext, dwarf::DW_TAG_array_type, /*Name=*/"",724      /*File=*/nullptr, /*Line=*/0, /*Scope=*/nullptr, /*BaseType=*/Ty,725      /*SizeInBits=*/Size, /*AlignInBits=*/AlignInBits, /*OffsetInBits=*/0,726      /*Flags=*/DINode::FlagVector, /*Elements=*/Subscripts,727      /*RuntimeLang=*/0, /*EnumKind=*/std::nullopt, /*VTableHolder=*/nullptr,728      /*TemplateParams=*/nullptr, /*Identifier=*/"",729      /*Discriminator=*/nullptr, /*DataLocation=*/nullptr,730      /*Associated=*/nullptr, /*Allocated=*/nullptr, /*Rank=*/nullptr,731      /*Annotations=*/nullptr, /*Specification=*/nullptr,732      /*NumExtraInhabitants=*/0,733      /*BitStride=*/BitStride);734  trackIfUnresolved(R);735  return R;736}737 738DISubprogram *DIBuilder::createArtificialSubprogram(DISubprogram *SP) {739  auto NewSP = SP->cloneWithFlags(SP->getFlags() | DINode::FlagArtificial);740  return MDNode::replaceWithDistinct(std::move(NewSP));741}742 743static DIType *createTypeWithFlags(const DIType *Ty,744                                   DINode::DIFlags FlagsToSet) {745  auto NewTy = Ty->cloneWithFlags(Ty->getFlags() | FlagsToSet);746  return MDNode::replaceWithUniqued(std::move(NewTy));747}748 749DIType *DIBuilder::createArtificialType(DIType *Ty) {750  // FIXME: Restrict this to the nodes where it's valid.751  if (Ty->isArtificial())752    return Ty;753  return createTypeWithFlags(Ty, DINode::FlagArtificial);754}755 756DIType *DIBuilder::createObjectPointerType(DIType *Ty, bool Implicit) {757  // FIXME: Restrict this to the nodes where it's valid.758  if (Ty->isObjectPointer())759    return Ty;760  DINode::DIFlags Flags = DINode::FlagObjectPointer;761 762  if (Implicit)763    Flags |= DINode::FlagArtificial;764 765  return createTypeWithFlags(Ty, Flags);766}767 768void DIBuilder::retainType(DIScope *T) {769  assert(T && "Expected non-null type");770  assert((isa<DIType>(T) || (isa<DISubprogram>(T) &&771                             cast<DISubprogram>(T)->isDefinition() == false)) &&772         "Expected type or subprogram declaration");773  AllRetainTypes.emplace_back(T);774}775 776DIBasicType *DIBuilder::createUnspecifiedParameter() { return nullptr; }777 778DICompositeType *DIBuilder::createForwardDecl(779    unsigned Tag, StringRef Name, DIScope *Scope, DIFile *F, unsigned Line,780    unsigned RuntimeLang, uint64_t SizeInBits, uint32_t AlignInBits,781    StringRef UniqueIdentifier, std::optional<uint32_t> EnumKind) {782  // FIXME: Define in terms of createReplaceableForwardDecl() by calling783  // replaceWithUniqued().784  auto *RetTy = DICompositeType::get(785      VMContext, Tag, Name, F, Line, getNonCompileUnitScope(Scope), nullptr,786      SizeInBits, AlignInBits, 0, DINode::FlagFwdDecl, nullptr, RuntimeLang,787      /*EnumKind=*/EnumKind, nullptr, nullptr, UniqueIdentifier);788  trackIfUnresolved(RetTy);789  return RetTy;790}791 792DICompositeType *DIBuilder::createReplaceableCompositeType(793    unsigned Tag, StringRef Name, DIScope *Scope, DIFile *F, unsigned Line,794    unsigned RuntimeLang, uint64_t SizeInBits, uint32_t AlignInBits,795    DINode::DIFlags Flags, StringRef UniqueIdentifier, DINodeArray Annotations,796    std::optional<uint32_t> EnumKind) {797  auto *RetTy =798      DICompositeType::getTemporary(799          VMContext, Tag, Name, F, Line, getNonCompileUnitScope(Scope), nullptr,800          SizeInBits, AlignInBits, 0, Flags, nullptr, RuntimeLang, EnumKind,801          nullptr, nullptr, UniqueIdentifier, nullptr, nullptr, nullptr,802          nullptr, nullptr, Annotations)803          .release();804  trackIfUnresolved(RetTy);805  return RetTy;806}807 808DINodeArray DIBuilder::getOrCreateArray(ArrayRef<Metadata *> Elements) {809  return MDTuple::get(VMContext, Elements);810}811 812DIMacroNodeArray813DIBuilder::getOrCreateMacroArray(ArrayRef<Metadata *> Elements) {814  return MDTuple::get(VMContext, Elements);815}816 817DITypeRefArray DIBuilder::getOrCreateTypeArray(ArrayRef<Metadata *> Elements) {818  SmallVector<llvm::Metadata *, 16> Elts;819  for (Metadata *E : Elements) {820    if (isa_and_nonnull<MDNode>(E))821      Elts.push_back(cast<DIType>(E));822    else823      Elts.push_back(E);824  }825  return DITypeRefArray(MDNode::get(VMContext, Elts));826}827 828DISubrange *DIBuilder::getOrCreateSubrange(int64_t Lo, int64_t Count) {829  auto *LB = ConstantAsMetadata::get(830      ConstantInt::getSigned(Type::getInt64Ty(VMContext), Lo));831  auto *CountNode = ConstantAsMetadata::get(832      ConstantInt::getSigned(Type::getInt64Ty(VMContext), Count));833  return DISubrange::get(VMContext, CountNode, LB, nullptr, nullptr);834}835 836DISubrange *DIBuilder::getOrCreateSubrange(int64_t Lo, Metadata *CountNode) {837  auto *LB = ConstantAsMetadata::get(838      ConstantInt::getSigned(Type::getInt64Ty(VMContext), Lo));839  return DISubrange::get(VMContext, CountNode, LB, nullptr, nullptr);840}841 842DISubrange *DIBuilder::getOrCreateSubrange(Metadata *CountNode, Metadata *LB,843                                           Metadata *UB, Metadata *Stride) {844  return DISubrange::get(VMContext, CountNode, LB, UB, Stride);845}846 847DIGenericSubrange *DIBuilder::getOrCreateGenericSubrange(848    DIGenericSubrange::BoundType CountNode, DIGenericSubrange::BoundType LB,849    DIGenericSubrange::BoundType UB, DIGenericSubrange::BoundType Stride) {850  auto ConvToMetadata = [&](DIGenericSubrange::BoundType Bound) -> Metadata * {851    return isa<DIExpression *>(Bound) ? (Metadata *)cast<DIExpression *>(Bound)852                                      : (Metadata *)cast<DIVariable *>(Bound);853  };854  return DIGenericSubrange::get(VMContext, ConvToMetadata(CountNode),855                                ConvToMetadata(LB), ConvToMetadata(UB),856                                ConvToMetadata(Stride));857}858 859DISubrangeType *DIBuilder::createSubrangeType(860    StringRef Name, DIFile *File, unsigned LineNo, DIScope *Scope,861    uint64_t SizeInBits, uint32_t AlignInBits, DINode::DIFlags Flags,862    DIType *Ty, Metadata *LowerBound, Metadata *UpperBound, Metadata *Stride,863    Metadata *Bias) {864  return DISubrangeType::get(VMContext, Name, File, LineNo, Scope, SizeInBits,865                             AlignInBits, Flags, Ty, LowerBound, UpperBound,866                             Stride, Bias);867}868 869static void checkGlobalVariableScope(DIScope *Context) {870#ifndef NDEBUG871  if (auto *CT =872          dyn_cast_or_null<DICompositeType>(getNonCompileUnitScope(Context)))873    assert(CT->getIdentifier().empty() &&874           "Context of a global variable should not be a type with identifier");875#endif876}877 878DIGlobalVariableExpression *DIBuilder::createGlobalVariableExpression(879    DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *F,880    unsigned LineNumber, DIType *Ty, bool IsLocalToUnit, bool isDefined,881    DIExpression *Expr, MDNode *Decl, MDTuple *TemplateParams,882    uint32_t AlignInBits, DINodeArray Annotations) {883  checkGlobalVariableScope(Context);884 885  auto *GV = DIGlobalVariable::getDistinct(886      VMContext, cast_or_null<DIScope>(Context), Name, LinkageName, F,887      LineNumber, Ty, IsLocalToUnit, isDefined,888      cast_or_null<DIDerivedType>(Decl), TemplateParams, AlignInBits,889      Annotations);890  if (!Expr)891    Expr = createExpression();892  auto *N = DIGlobalVariableExpression::get(VMContext, GV, Expr);893  AllGVs.push_back(N);894  return N;895}896 897DIGlobalVariable *DIBuilder::createTempGlobalVariableFwdDecl(898    DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *F,899    unsigned LineNumber, DIType *Ty, bool IsLocalToUnit, MDNode *Decl,900    MDTuple *TemplateParams, uint32_t AlignInBits) {901  checkGlobalVariableScope(Context);902 903  return DIGlobalVariable::getTemporary(904             VMContext, cast_or_null<DIScope>(Context), Name, LinkageName, F,905             LineNumber, Ty, IsLocalToUnit, false,906             cast_or_null<DIDerivedType>(Decl), TemplateParams, AlignInBits,907             nullptr)908      .release();909}910 911static DILocalVariable *createLocalVariable(912    LLVMContext &VMContext,913    SmallVectorImpl<TrackingMDNodeRef> &PreservedNodes,914    DIScope *Context, StringRef Name, unsigned ArgNo, DIFile *File,915    unsigned LineNo, DIType *Ty, bool AlwaysPreserve, DINode::DIFlags Flags,916    uint32_t AlignInBits, DINodeArray Annotations = nullptr) {917  // FIXME: Why doesn't this check for a subprogram or lexical block (AFAICT918  // the only valid scopes)?919  auto *Scope = cast<DILocalScope>(Context);920  auto *Node = DILocalVariable::get(VMContext, Scope, Name, File, LineNo, Ty,921                                    ArgNo, Flags, AlignInBits, Annotations);922  if (AlwaysPreserve) {923    // The optimizer may remove local variables. If there is an interest924    // to preserve variable info in such situation then stash it in a925    // named mdnode.926    PreservedNodes.emplace_back(Node);927  }928  return Node;929}930 931DILocalVariable *DIBuilder::createAutoVariable(DIScope *Scope, StringRef Name,932                                               DIFile *File, unsigned LineNo,933                                               DIType *Ty, bool AlwaysPreserve,934                                               DINode::DIFlags Flags,935                                               uint32_t AlignInBits) {936  assert(Scope && isa<DILocalScope>(Scope) &&937         "Unexpected scope for a local variable.");938  return createLocalVariable(939      VMContext, getSubprogramNodesTrackingVector(Scope), Scope, Name,940      /* ArgNo */ 0, File, LineNo, Ty, AlwaysPreserve, Flags, AlignInBits);941}942 943DILocalVariable *DIBuilder::createParameterVariable(944    DIScope *Scope, StringRef Name, unsigned ArgNo, DIFile *File,945    unsigned LineNo, DIType *Ty, bool AlwaysPreserve, DINode::DIFlags Flags,946    DINodeArray Annotations) {947  assert(ArgNo && "Expected non-zero argument number for parameter");948  assert(Scope && isa<DILocalScope>(Scope) &&949         "Unexpected scope for a local variable.");950  return createLocalVariable(951      VMContext, getSubprogramNodesTrackingVector(Scope), Scope, Name, ArgNo,952      File, LineNo, Ty, AlwaysPreserve, Flags, /*AlignInBits=*/0, Annotations);953}954 955DILabel *DIBuilder::createLabel(DIScope *Context, StringRef Name, DIFile *File,956                                unsigned LineNo, unsigned Column,957                                bool IsArtificial,958                                std::optional<unsigned> CoroSuspendIdx,959                                bool AlwaysPreserve) {960  auto *Scope = cast<DILocalScope>(Context);961  auto *Node = DILabel::get(VMContext, Scope, Name, File, LineNo, Column,962                            IsArtificial, CoroSuspendIdx);963 964  if (AlwaysPreserve) {965    /// The optimizer may remove labels. If there is an interest966    /// to preserve label info in such situation then append it to967    /// the list of retained nodes of the DISubprogram.968    getSubprogramNodesTrackingVector(Scope).emplace_back(Node);969  }970  return Node;971}972 973DIExpression *DIBuilder::createExpression(ArrayRef<uint64_t> Addr) {974  return DIExpression::get(VMContext, Addr);975}976 977template <class... Ts>978static DISubprogram *getSubprogram(bool IsDistinct, Ts &&...Args) {979  if (IsDistinct)980    return DISubprogram::getDistinct(std::forward<Ts>(Args)...);981  return DISubprogram::get(std::forward<Ts>(Args)...);982}983 984DISubprogram *DIBuilder::createFunction(985    DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *File,986    unsigned LineNo, DISubroutineType *Ty, unsigned ScopeLine,987    DINode::DIFlags Flags, DISubprogram::DISPFlags SPFlags,988    DITemplateParameterArray TParams, DISubprogram *Decl,989    DITypeArray ThrownTypes, DINodeArray Annotations, StringRef TargetFuncName,990    bool UseKeyInstructions) {991  bool IsDefinition = SPFlags & DISubprogram::SPFlagDefinition;992  auto *Node = getSubprogram(993      /*IsDistinct=*/IsDefinition, VMContext, getNonCompileUnitScope(Context),994      Name, LinkageName, File, LineNo, Ty, ScopeLine, nullptr, 0, 0, Flags,995      SPFlags, IsDefinition ? CUNode : nullptr, TParams, Decl, nullptr,996      ThrownTypes, Annotations, TargetFuncName, UseKeyInstructions);997 998  AllSubprograms.push_back(Node);999  trackIfUnresolved(Node);1000  return Node;1001}1002 1003DISubprogram *DIBuilder::createTempFunctionFwdDecl(1004    DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *File,1005    unsigned LineNo, DISubroutineType *Ty, unsigned ScopeLine,1006    DINode::DIFlags Flags, DISubprogram::DISPFlags SPFlags,1007    DITemplateParameterArray TParams, DISubprogram *Decl,1008    DITypeArray ThrownTypes) {1009  bool IsDefinition = SPFlags & DISubprogram::SPFlagDefinition;1010  return DISubprogram::getTemporary(VMContext, getNonCompileUnitScope(Context),1011                                    Name, LinkageName, File, LineNo, Ty,1012                                    ScopeLine, nullptr, 0, 0, Flags, SPFlags,1013                                    IsDefinition ? CUNode : nullptr, TParams,1014                                    Decl, nullptr, ThrownTypes)1015      .release();1016}1017 1018DISubprogram *DIBuilder::createMethod(1019    DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *F,1020    unsigned LineNo, DISubroutineType *Ty, unsigned VIndex, int ThisAdjustment,1021    DIType *VTableHolder, DINode::DIFlags Flags,1022    DISubprogram::DISPFlags SPFlags, DITemplateParameterArray TParams,1023    DITypeArray ThrownTypes, bool UseKeyInstructions) {1024  assert(getNonCompileUnitScope(Context) &&1025         "Methods should have both a Context and a context that isn't "1026         "the compile unit.");1027  // FIXME: Do we want to use different scope/lines?1028  bool IsDefinition = SPFlags & DISubprogram::SPFlagDefinition;1029  auto *SP = getSubprogram(1030      /*IsDistinct=*/IsDefinition, VMContext, cast<DIScope>(Context), Name,1031      LinkageName, F, LineNo, Ty, LineNo, VTableHolder, VIndex, ThisAdjustment,1032      Flags, SPFlags, IsDefinition ? CUNode : nullptr, TParams, nullptr,1033      nullptr, ThrownTypes, nullptr, "", IsDefinition && UseKeyInstructions);1034 1035  AllSubprograms.push_back(SP);1036  trackIfUnresolved(SP);1037  return SP;1038}1039 1040DICommonBlock *DIBuilder::createCommonBlock(DIScope *Scope,1041                                            DIGlobalVariable *Decl,1042                                            StringRef Name, DIFile *File,1043                                            unsigned LineNo) {1044  return DICommonBlock::get(VMContext, Scope, Decl, Name, File, LineNo);1045}1046 1047DINamespace *DIBuilder::createNameSpace(DIScope *Scope, StringRef Name,1048                                        bool ExportSymbols) {1049 1050  // It is okay to *not* make anonymous top-level namespaces distinct, because1051  // all nodes that have an anonymous namespace as their parent scope are1052  // guaranteed to be unique and/or are linked to their containing1053  // DICompileUnit. This decision is an explicit tradeoff of link time versus1054  // memory usage versus code simplicity and may get revisited in the future.1055  return DINamespace::get(VMContext, getNonCompileUnitScope(Scope), Name,1056                          ExportSymbols);1057}1058 1059DIModule *DIBuilder::createModule(DIScope *Scope, StringRef Name,1060                                  StringRef ConfigurationMacros,1061                                  StringRef IncludePath, StringRef APINotesFile,1062                                  DIFile *File, unsigned LineNo, bool IsDecl) {1063  return DIModule::get(VMContext, File, getNonCompileUnitScope(Scope), Name,1064                       ConfigurationMacros, IncludePath, APINotesFile, LineNo,1065                       IsDecl);1066}1067 1068DILexicalBlockFile *DIBuilder::createLexicalBlockFile(DIScope *Scope,1069                                                      DIFile *File,1070                                                      unsigned Discriminator) {1071  return DILexicalBlockFile::get(VMContext, Scope, File, Discriminator);1072}1073 1074DILexicalBlock *DIBuilder::createLexicalBlock(DIScope *Scope, DIFile *File,1075                                              unsigned Line, unsigned Col) {1076  // Make these distinct, to avoid merging two lexical blocks on the same1077  // file/line/column.1078  return DILexicalBlock::getDistinct(VMContext, getNonCompileUnitScope(Scope),1079                                     File, Line, Col);1080}1081 1082DbgInstPtr DIBuilder::insertDeclare(Value *Storage, DILocalVariable *VarInfo,1083                                    DIExpression *Expr, const DILocation *DL,1084                                    BasicBlock *InsertAtEnd) {1085  // If this block already has a terminator then insert this intrinsic before1086  // the terminator. Otherwise, put it at the end of the block.1087  Instruction *InsertBefore = InsertAtEnd->getTerminator();1088  return insertDeclare(Storage, VarInfo, Expr, DL,1089                       InsertBefore ? InsertBefore->getIterator()1090                                    : InsertAtEnd->end());1091}1092 1093DbgInstPtr DIBuilder::insertDbgAssign(Instruction *LinkedInstr, Value *Val,1094                                      DILocalVariable *SrcVar,1095                                      DIExpression *ValExpr, Value *Addr,1096                                      DIExpression *AddrExpr,1097                                      const DILocation *DL) {1098  auto *Link = cast_or_null<DIAssignID>(1099      LinkedInstr->getMetadata(LLVMContext::MD_DIAssignID));1100  assert(Link && "Linked instruction must have DIAssign metadata attached");1101 1102  DbgVariableRecord *DVR = DbgVariableRecord::createDVRAssign(1103      Val, SrcVar, ValExpr, Link, Addr, AddrExpr, DL);1104  // Insert after LinkedInstr.1105  BasicBlock::iterator NextIt = std::next(LinkedInstr->getIterator());1106  NextIt.setHeadBit(true);1107  insertDbgVariableRecord(DVR, NextIt);1108  return DVR;1109}1110 1111/// Initialize IRBuilder for inserting dbg.declare and dbg.value intrinsics.1112/// This abstracts over the various ways to specify an insert position.1113static void initIRBuilder(IRBuilder<> &Builder, const DILocation *DL,1114                          InsertPosition InsertPt) {1115  Builder.SetInsertPoint(InsertPt.getBasicBlock(), InsertPt);1116  Builder.SetCurrentDebugLocation(DL);1117}1118 1119static Value *getDbgIntrinsicValueImpl(LLVMContext &VMContext, Value *V) {1120  assert(V && "no value passed to dbg intrinsic");1121  return MetadataAsValue::get(VMContext, ValueAsMetadata::get(V));1122}1123 1124DbgInstPtr DIBuilder::insertDbgValueIntrinsic(llvm::Value *Val,1125                                              DILocalVariable *VarInfo,1126                                              DIExpression *Expr,1127                                              const DILocation *DL,1128                                              InsertPosition InsertPt) {1129  DbgVariableRecord *DVR =1130      DbgVariableRecord::createDbgVariableRecord(Val, VarInfo, Expr, DL);1131  insertDbgVariableRecord(DVR, InsertPt);1132  return DVR;1133}1134 1135DbgInstPtr DIBuilder::insertDeclare(Value *Storage, DILocalVariable *VarInfo,1136                                    DIExpression *Expr, const DILocation *DL,1137                                    InsertPosition InsertPt) {1138  assert(VarInfo && "empty or invalid DILocalVariable* passed to dbg.declare");1139  assert(DL && "Expected debug loc");1140  assert(DL->getScope()->getSubprogram() ==1141             VarInfo->getScope()->getSubprogram() &&1142         "Expected matching subprograms");1143 1144  DbgVariableRecord *DVR =1145      DbgVariableRecord::createDVRDeclare(Storage, VarInfo, Expr, DL);1146  insertDbgVariableRecord(DVR, InsertPt);1147  return DVR;1148}1149 1150DbgInstPtr DIBuilder::insertDeclareValue(Value *Storage,1151                                         DILocalVariable *VarInfo,1152                                         DIExpression *Expr,1153                                         const DILocation *DL,1154                                         InsertPosition InsertPt) {1155  assert(VarInfo &&1156         "empty or invalid DILocalVariable* passed to dbg.declare_value");1157  assert(DL && "Expected debug loc");1158  assert(DL->getScope()->getSubprogram() ==1159             VarInfo->getScope()->getSubprogram() &&1160         "Expected matching subprograms");1161 1162  DbgVariableRecord *DVR =1163      DbgVariableRecord::createDVRDeclareValue(Storage, VarInfo, Expr, DL);1164  insertDbgVariableRecord(DVR, InsertPt);1165  return DVR;1166}1167 1168void DIBuilder::insertDbgVariableRecord(DbgVariableRecord *DVR,1169                                        InsertPosition InsertPt) {1170  assert(InsertPt.isValid());1171  trackIfUnresolved(DVR->getVariable());1172  trackIfUnresolved(DVR->getExpression());1173  if (DVR->isDbgAssign())1174    trackIfUnresolved(DVR->getAddressExpression());1175 1176  auto *BB = InsertPt.getBasicBlock();1177  BB->insertDbgRecordBefore(DVR, InsertPt);1178}1179 1180Instruction *DIBuilder::insertDbgIntrinsic(llvm::Function *IntrinsicFn,1181                                           Value *V, DILocalVariable *VarInfo,1182                                           DIExpression *Expr,1183                                           const DILocation *DL,1184                                           InsertPosition InsertPt) {1185  assert(IntrinsicFn && "must pass a non-null intrinsic function");1186  assert(V && "must pass a value to a dbg intrinsic");1187  assert(VarInfo &&1188         "empty or invalid DILocalVariable* passed to debug intrinsic");1189  assert(DL && "Expected debug loc");1190  assert(DL->getScope()->getSubprogram() ==1191             VarInfo->getScope()->getSubprogram() &&1192         "Expected matching subprograms");1193 1194  trackIfUnresolved(VarInfo);1195  trackIfUnresolved(Expr);1196  Value *Args[] = {getDbgIntrinsicValueImpl(VMContext, V),1197                   MetadataAsValue::get(VMContext, VarInfo),1198                   MetadataAsValue::get(VMContext, Expr)};1199 1200  IRBuilder<> B(DL->getContext());1201  initIRBuilder(B, DL, InsertPt);1202  return B.CreateCall(IntrinsicFn, Args);1203}1204 1205DbgInstPtr DIBuilder::insertLabel(DILabel *LabelInfo, const DILocation *DL,1206                                  InsertPosition InsertPt) {1207  assert(LabelInfo && "empty or invalid DILabel* passed to dbg.label");1208  assert(DL && "Expected debug loc");1209  assert(DL->getScope()->getSubprogram() ==1210             LabelInfo->getScope()->getSubprogram() &&1211         "Expected matching subprograms");1212 1213  trackIfUnresolved(LabelInfo);1214  DbgLabelRecord *DLR = new DbgLabelRecord(LabelInfo, DL);1215  if (InsertPt.isValid()) {1216    auto *BB = InsertPt.getBasicBlock();1217    BB->insertDbgRecordBefore(DLR, InsertPt);1218  }1219  return DLR;1220}1221 1222void DIBuilder::replaceVTableHolder(DICompositeType *&T, DIType *VTableHolder) {1223  {1224    TypedTrackingMDRef<DICompositeType> N(T);1225    N->replaceVTableHolder(VTableHolder);1226    T = N.get();1227  }1228 1229  // If this didn't create a self-reference, just return.1230  if (T != VTableHolder)1231    return;1232 1233  // Look for unresolved operands.  T will drop RAUW support, orphaning any1234  // cycles underneath it.1235  if (T->isResolved())1236    for (const MDOperand &O : T->operands())1237      if (auto *N = dyn_cast_or_null<MDNode>(O))1238        trackIfUnresolved(N);1239}1240 1241void DIBuilder::replaceArrays(DICompositeType *&T, DINodeArray Elements,1242                              DINodeArray TParams) {1243  {1244    TypedTrackingMDRef<DICompositeType> N(T);1245    if (Elements)1246      N->replaceElements(Elements);1247    if (TParams)1248      N->replaceTemplateParams(DITemplateParameterArray(TParams));1249    T = N.get();1250  }1251 1252  // If T isn't resolved, there's no problem.1253  if (!T->isResolved())1254    return;1255 1256  // If T is resolved, it may be due to a self-reference cycle.  Track the1257  // arrays explicitly if they're unresolved, or else the cycles will be1258  // orphaned.1259  if (Elements)1260    trackIfUnresolved(Elements.get());1261  if (TParams)1262    trackIfUnresolved(TParams.get());1263}1264