10b57cec5SDimitry Andric //===--- DIBuilder.cpp - Debug Information Builder ------------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file implements the DIBuilder. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #include "llvm/IR/DIBuilder.h" 140b57cec5SDimitry Andric #include "LLVMContextImpl.h" 1506c3fb27SDimitry Andric #include "llvm/ADT/APInt.h" 1606c3fb27SDimitry Andric #include "llvm/ADT/APSInt.h" 170b57cec5SDimitry Andric #include "llvm/BinaryFormat/Dwarf.h" 180b57cec5SDimitry Andric #include "llvm/IR/Constants.h" 190b57cec5SDimitry Andric #include "llvm/IR/DebugInfo.h" 20480093f4SDimitry Andric #include "llvm/IR/IRBuilder.h" 210b57cec5SDimitry Andric #include "llvm/IR/Module.h" 22480093f4SDimitry Andric #include "llvm/Support/CommandLine.h" 23bdd1243dSDimitry Andric #include <optional> 240b57cec5SDimitry Andric 250b57cec5SDimitry Andric using namespace llvm; 260b57cec5SDimitry Andric using namespace llvm::dwarf; 270b57cec5SDimitry Andric 280b57cec5SDimitry Andric DIBuilder::DIBuilder(Module &m, bool AllowUnresolvedNodes, DICompileUnit *CU) 29349cc55cSDimitry Andric : M(m), VMContext(M.getContext()), CUNode(CU), DeclareFn(nullptr), 3006c3fb27SDimitry Andric ValueFn(nullptr), LabelFn(nullptr), AssignFn(nullptr), 314824e7fdSDimitry Andric AllowUnresolvedNodes(AllowUnresolvedNodes) { 324824e7fdSDimitry Andric if (CUNode) { 334824e7fdSDimitry Andric if (const auto &ETs = CUNode->getEnumTypes()) 344824e7fdSDimitry Andric AllEnumTypes.assign(ETs.begin(), ETs.end()); 354824e7fdSDimitry Andric if (const auto &RTs = CUNode->getRetainedTypes()) 364824e7fdSDimitry Andric AllRetainTypes.assign(RTs.begin(), RTs.end()); 374824e7fdSDimitry Andric if (const auto &GVs = CUNode->getGlobalVariables()) 384824e7fdSDimitry Andric AllGVs.assign(GVs.begin(), GVs.end()); 394824e7fdSDimitry Andric if (const auto &IMs = CUNode->getImportedEntities()) 4006c3fb27SDimitry Andric ImportedModules.assign(IMs.begin(), IMs.end()); 414824e7fdSDimitry Andric if (const auto &MNs = CUNode->getMacros()) 424824e7fdSDimitry Andric AllMacrosPerParent.insert({nullptr, {MNs.begin(), MNs.end()}}); 434824e7fdSDimitry Andric } 444824e7fdSDimitry Andric } 450b57cec5SDimitry Andric 460b57cec5SDimitry Andric void DIBuilder::trackIfUnresolved(MDNode *N) { 470b57cec5SDimitry Andric if (!N) 480b57cec5SDimitry Andric return; 490b57cec5SDimitry Andric if (N->isResolved()) 500b57cec5SDimitry Andric return; 510b57cec5SDimitry Andric 520b57cec5SDimitry Andric assert(AllowUnresolvedNodes && "Cannot handle unresolved nodes"); 530b57cec5SDimitry Andric UnresolvedNodes.emplace_back(N); 540b57cec5SDimitry Andric } 550b57cec5SDimitry Andric 560b57cec5SDimitry Andric void DIBuilder::finalizeSubprogram(DISubprogram *SP) { 5706c3fb27SDimitry Andric auto PN = SubprogramTrackedNodes.find(SP); 5806c3fb27SDimitry Andric if (PN != SubprogramTrackedNodes.end()) 5906c3fb27SDimitry Andric SP->replaceRetainedNodes( 6006c3fb27SDimitry Andric MDTuple::get(VMContext, SmallVector<Metadata *, 16>(PN->second.begin(), 6106c3fb27SDimitry Andric PN->second.end()))); 620b57cec5SDimitry Andric } 630b57cec5SDimitry Andric 640b57cec5SDimitry Andric void DIBuilder::finalize() { 650b57cec5SDimitry Andric if (!CUNode) { 660b57cec5SDimitry Andric assert(!AllowUnresolvedNodes && 670b57cec5SDimitry Andric "creating type nodes without a CU is not supported"); 680b57cec5SDimitry Andric return; 690b57cec5SDimitry Andric } 700b57cec5SDimitry Andric 71349cc55cSDimitry Andric if (!AllEnumTypes.empty()) 72bdd1243dSDimitry Andric CUNode->replaceEnumTypes(MDTuple::get( 73bdd1243dSDimitry Andric VMContext, SmallVector<Metadata *, 16>(AllEnumTypes.begin(), 74bdd1243dSDimitry Andric AllEnumTypes.end()))); 750b57cec5SDimitry Andric 760b57cec5SDimitry Andric SmallVector<Metadata *, 16> RetainValues; 770b57cec5SDimitry Andric // Declarations and definitions of the same type may be retained. Some 780b57cec5SDimitry Andric // clients RAUW these pairs, leaving duplicates in the retained types 790b57cec5SDimitry Andric // list. Use a set to remove the duplicates while we transform the 800b57cec5SDimitry Andric // TrackingVHs back into Values. 810b57cec5SDimitry Andric SmallPtrSet<Metadata *, 16> RetainSet; 82*0fca6ea1SDimitry Andric for (const TrackingMDNodeRef &N : AllRetainTypes) 83*0fca6ea1SDimitry Andric if (RetainSet.insert(N).second) 84*0fca6ea1SDimitry Andric RetainValues.push_back(N); 850b57cec5SDimitry Andric 860b57cec5SDimitry Andric if (!RetainValues.empty()) 870b57cec5SDimitry Andric CUNode->replaceRetainedTypes(MDTuple::get(VMContext, RetainValues)); 880b57cec5SDimitry Andric 8906c3fb27SDimitry Andric for (auto *SP : AllSubprograms) 900b57cec5SDimitry Andric finalizeSubprogram(SP); 910b57cec5SDimitry Andric for (auto *N : RetainValues) 920b57cec5SDimitry Andric if (auto *SP = dyn_cast<DISubprogram>(N)) 930b57cec5SDimitry Andric finalizeSubprogram(SP); 940b57cec5SDimitry Andric 950b57cec5SDimitry Andric if (!AllGVs.empty()) 960b57cec5SDimitry Andric CUNode->replaceGlobalVariables(MDTuple::get(VMContext, AllGVs)); 970b57cec5SDimitry Andric 9806c3fb27SDimitry Andric if (!ImportedModules.empty()) 990b57cec5SDimitry Andric CUNode->replaceImportedEntities(MDTuple::get( 10006c3fb27SDimitry Andric VMContext, SmallVector<Metadata *, 16>(ImportedModules.begin(), 10106c3fb27SDimitry Andric ImportedModules.end()))); 1020b57cec5SDimitry Andric 1030b57cec5SDimitry Andric for (const auto &I : AllMacrosPerParent) { 1040b57cec5SDimitry Andric // DIMacroNode's with nullptr parent are DICompileUnit direct children. 1050b57cec5SDimitry Andric if (!I.first) { 1060b57cec5SDimitry Andric CUNode->replaceMacros(MDTuple::get(VMContext, I.second.getArrayRef())); 1070b57cec5SDimitry Andric continue; 1080b57cec5SDimitry Andric } 1090b57cec5SDimitry Andric // Otherwise, it must be a temporary DIMacroFile that need to be resolved. 1100b57cec5SDimitry Andric auto *TMF = cast<DIMacroFile>(I.first); 1110b57cec5SDimitry Andric auto *MF = DIMacroFile::get(VMContext, dwarf::DW_MACINFO_start_file, 1120b57cec5SDimitry Andric TMF->getLine(), TMF->getFile(), 1130b57cec5SDimitry Andric getOrCreateMacroArray(I.second.getArrayRef())); 1140b57cec5SDimitry Andric replaceTemporary(llvm::TempDIMacroNode(TMF), MF); 1150b57cec5SDimitry Andric } 1160b57cec5SDimitry Andric 1170b57cec5SDimitry Andric // Now that all temp nodes have been replaced or deleted, resolve remaining 1180b57cec5SDimitry Andric // cycles. 1190b57cec5SDimitry Andric for (const auto &N : UnresolvedNodes) 1200b57cec5SDimitry Andric if (N && !N->isResolved()) 1210b57cec5SDimitry Andric N->resolveCycles(); 1220b57cec5SDimitry Andric UnresolvedNodes.clear(); 1230b57cec5SDimitry Andric 1240b57cec5SDimitry Andric // Can't handle unresolved nodes anymore. 1250b57cec5SDimitry Andric AllowUnresolvedNodes = false; 1260b57cec5SDimitry Andric } 1270b57cec5SDimitry Andric 1280b57cec5SDimitry Andric /// If N is compile unit return NULL otherwise return N. 1290b57cec5SDimitry Andric static DIScope *getNonCompileUnitScope(DIScope *N) { 1300b57cec5SDimitry Andric if (!N || isa<DICompileUnit>(N)) 1310b57cec5SDimitry Andric return nullptr; 1320b57cec5SDimitry Andric return cast<DIScope>(N); 1330b57cec5SDimitry Andric } 1340b57cec5SDimitry Andric 1350b57cec5SDimitry Andric DICompileUnit *DIBuilder::createCompileUnit( 1360b57cec5SDimitry Andric unsigned Lang, DIFile *File, StringRef Producer, bool isOptimized, 1370b57cec5SDimitry Andric StringRef Flags, unsigned RunTimeVer, StringRef SplitName, 1380b57cec5SDimitry Andric DICompileUnit::DebugEmissionKind Kind, uint64_t DWOId, 1390b57cec5SDimitry Andric bool SplitDebugInlining, bool DebugInfoForProfiling, 1405ffd83dbSDimitry Andric DICompileUnit::DebugNameTableKind NameTableKind, bool RangesBaseAddress, 1415ffd83dbSDimitry Andric StringRef SysRoot, StringRef SDK) { 1420b57cec5SDimitry Andric 14306c3fb27SDimitry Andric assert(((Lang <= dwarf::DW_LANG_Mojo && Lang >= dwarf::DW_LANG_C89) || 1440b57cec5SDimitry Andric (Lang <= dwarf::DW_LANG_hi_user && Lang >= dwarf::DW_LANG_lo_user)) && 1450b57cec5SDimitry Andric "Invalid Language tag"); 1460b57cec5SDimitry Andric 1470b57cec5SDimitry Andric assert(!CUNode && "Can only make one compile unit per DIBuilder instance"); 1480b57cec5SDimitry Andric CUNode = DICompileUnit::getDistinct( 1490b57cec5SDimitry Andric VMContext, Lang, File, Producer, isOptimized, Flags, RunTimeVer, 1500b57cec5SDimitry Andric SplitName, Kind, nullptr, nullptr, nullptr, nullptr, nullptr, DWOId, 1510b57cec5SDimitry Andric SplitDebugInlining, DebugInfoForProfiling, NameTableKind, 1525ffd83dbSDimitry Andric RangesBaseAddress, SysRoot, SDK); 1530b57cec5SDimitry Andric 1540b57cec5SDimitry Andric // Create a named metadata so that it is easier to find cu in a module. 1550b57cec5SDimitry Andric NamedMDNode *NMD = M.getOrInsertNamedMetadata("llvm.dbg.cu"); 1560b57cec5SDimitry Andric NMD->addOperand(CUNode); 1570b57cec5SDimitry Andric trackIfUnresolved(CUNode); 1580b57cec5SDimitry Andric return CUNode; 1590b57cec5SDimitry Andric } 1600b57cec5SDimitry Andric 1610b57cec5SDimitry Andric static DIImportedEntity * 1620b57cec5SDimitry Andric createImportedModule(LLVMContext &C, dwarf::Tag Tag, DIScope *Context, 1630b57cec5SDimitry Andric Metadata *NS, DIFile *File, unsigned Line, StringRef Name, 164349cc55cSDimitry Andric DINodeArray Elements, 16506c3fb27SDimitry Andric SmallVectorImpl<TrackingMDNodeRef> &ImportedModules) { 1660b57cec5SDimitry Andric if (Line) 1670b57cec5SDimitry Andric assert(File && "Source location has line number but no file"); 1680b57cec5SDimitry Andric unsigned EntitiesCount = C.pImpl->DIImportedEntitys.size(); 1690b57cec5SDimitry Andric auto *M = DIImportedEntity::get(C, Tag, Context, cast_or_null<DINode>(NS), 170349cc55cSDimitry Andric File, Line, Name, Elements); 1710b57cec5SDimitry Andric if (EntitiesCount < C.pImpl->DIImportedEntitys.size()) 1720b57cec5SDimitry Andric // A new Imported Entity was just added to the context. 1730b57cec5SDimitry Andric // Add it to the Imported Modules list. 17406c3fb27SDimitry Andric ImportedModules.emplace_back(M); 1750b57cec5SDimitry Andric return M; 1760b57cec5SDimitry Andric } 1770b57cec5SDimitry Andric 1780b57cec5SDimitry Andric DIImportedEntity *DIBuilder::createImportedModule(DIScope *Context, 1790b57cec5SDimitry Andric DINamespace *NS, DIFile *File, 180349cc55cSDimitry Andric unsigned Line, 181349cc55cSDimitry Andric DINodeArray Elements) { 1820b57cec5SDimitry Andric return ::createImportedModule(VMContext, dwarf::DW_TAG_imported_module, 183349cc55cSDimitry Andric Context, NS, File, Line, StringRef(), Elements, 18406c3fb27SDimitry Andric getImportTrackingVector(Context)); 1850b57cec5SDimitry Andric } 1860b57cec5SDimitry Andric 1870b57cec5SDimitry Andric DIImportedEntity *DIBuilder::createImportedModule(DIScope *Context, 1880b57cec5SDimitry Andric DIImportedEntity *NS, 189349cc55cSDimitry Andric DIFile *File, unsigned Line, 190349cc55cSDimitry Andric DINodeArray Elements) { 1910b57cec5SDimitry Andric return ::createImportedModule(VMContext, dwarf::DW_TAG_imported_module, 192349cc55cSDimitry Andric Context, NS, File, Line, StringRef(), Elements, 19306c3fb27SDimitry Andric getImportTrackingVector(Context)); 1940b57cec5SDimitry Andric } 1950b57cec5SDimitry Andric 1960b57cec5SDimitry Andric DIImportedEntity *DIBuilder::createImportedModule(DIScope *Context, DIModule *M, 197349cc55cSDimitry Andric DIFile *File, unsigned Line, 198349cc55cSDimitry Andric DINodeArray Elements) { 1990b57cec5SDimitry Andric return ::createImportedModule(VMContext, dwarf::DW_TAG_imported_module, 200349cc55cSDimitry Andric Context, M, File, Line, StringRef(), Elements, 20106c3fb27SDimitry Andric getImportTrackingVector(Context)); 2020b57cec5SDimitry Andric } 2030b57cec5SDimitry Andric 204349cc55cSDimitry Andric DIImportedEntity * 205349cc55cSDimitry Andric DIBuilder::createImportedDeclaration(DIScope *Context, DINode *Decl, 206349cc55cSDimitry Andric DIFile *File, unsigned Line, 207349cc55cSDimitry Andric StringRef Name, DINodeArray Elements) { 2080b57cec5SDimitry Andric // Make sure to use the unique identifier based metadata reference for 2090b57cec5SDimitry Andric // types that have one. 2100b57cec5SDimitry Andric return ::createImportedModule(VMContext, dwarf::DW_TAG_imported_declaration, 211349cc55cSDimitry Andric Context, Decl, File, Line, Name, Elements, 21206c3fb27SDimitry Andric getImportTrackingVector(Context)); 2130b57cec5SDimitry Andric } 2140b57cec5SDimitry Andric 2150b57cec5SDimitry Andric DIFile *DIBuilder::createFile(StringRef Filename, StringRef Directory, 216bdd1243dSDimitry Andric std::optional<DIFile::ChecksumInfo<StringRef>> CS, 217bdd1243dSDimitry Andric std::optional<StringRef> Source) { 2180b57cec5SDimitry Andric return DIFile::get(VMContext, Filename, Directory, CS, Source); 2190b57cec5SDimitry Andric } 2200b57cec5SDimitry Andric 2210b57cec5SDimitry Andric DIMacro *DIBuilder::createMacro(DIMacroFile *Parent, unsigned LineNumber, 2220b57cec5SDimitry Andric unsigned MacroType, StringRef Name, 2230b57cec5SDimitry Andric StringRef Value) { 2240b57cec5SDimitry Andric assert(!Name.empty() && "Unable to create macro without name"); 2250b57cec5SDimitry Andric assert((MacroType == dwarf::DW_MACINFO_undef || 2260b57cec5SDimitry Andric MacroType == dwarf::DW_MACINFO_define) && 2270b57cec5SDimitry Andric "Unexpected macro type"); 2280b57cec5SDimitry Andric auto *M = DIMacro::get(VMContext, MacroType, LineNumber, Name, Value); 2290b57cec5SDimitry Andric AllMacrosPerParent[Parent].insert(M); 2300b57cec5SDimitry Andric return M; 2310b57cec5SDimitry Andric } 2320b57cec5SDimitry Andric 2330b57cec5SDimitry Andric DIMacroFile *DIBuilder::createTempMacroFile(DIMacroFile *Parent, 2340b57cec5SDimitry Andric unsigned LineNumber, DIFile *File) { 2350b57cec5SDimitry Andric auto *MF = DIMacroFile::getTemporary(VMContext, dwarf::DW_MACINFO_start_file, 2360b57cec5SDimitry Andric LineNumber, File, DIMacroNodeArray()) 2370b57cec5SDimitry Andric .release(); 2380b57cec5SDimitry Andric AllMacrosPerParent[Parent].insert(MF); 2390b57cec5SDimitry Andric // Add the new temporary DIMacroFile to the macro per parent map as a parent. 2400b57cec5SDimitry Andric // This is needed to assure DIMacroFile with no children to have an entry in 2410b57cec5SDimitry Andric // the map. Otherwise, it will not be resolved in DIBuilder::finalize(). 2420b57cec5SDimitry Andric AllMacrosPerParent.insert({MF, {}}); 2430b57cec5SDimitry Andric return MF; 2440b57cec5SDimitry Andric } 2450b57cec5SDimitry Andric 246fe6060f1SDimitry Andric DIEnumerator *DIBuilder::createEnumerator(StringRef Name, uint64_t Val, 2470b57cec5SDimitry Andric bool IsUnsigned) { 2480b57cec5SDimitry Andric assert(!Name.empty() && "Unable to create enumerator without name"); 2495ffd83dbSDimitry Andric return DIEnumerator::get(VMContext, APInt(64, Val, !IsUnsigned), IsUnsigned, 2505ffd83dbSDimitry Andric Name); 2510b57cec5SDimitry Andric } 2520b57cec5SDimitry Andric 253349cc55cSDimitry Andric DIEnumerator *DIBuilder::createEnumerator(StringRef Name, const APSInt &Value) { 254fe6060f1SDimitry Andric assert(!Name.empty() && "Unable to create enumerator without name"); 255fe6060f1SDimitry Andric return DIEnumerator::get(VMContext, APInt(Value), Value.isUnsigned(), Name); 256fe6060f1SDimitry Andric } 257fe6060f1SDimitry Andric 2580b57cec5SDimitry Andric DIBasicType *DIBuilder::createUnspecifiedType(StringRef Name) { 2590b57cec5SDimitry Andric assert(!Name.empty() && "Unable to create type without name"); 2600b57cec5SDimitry Andric return DIBasicType::get(VMContext, dwarf::DW_TAG_unspecified_type, Name); 2610b57cec5SDimitry Andric } 2620b57cec5SDimitry Andric 2630b57cec5SDimitry Andric DIBasicType *DIBuilder::createNullPtrType() { 2640b57cec5SDimitry Andric return createUnspecifiedType("decltype(nullptr)"); 2650b57cec5SDimitry Andric } 2660b57cec5SDimitry Andric 2670b57cec5SDimitry Andric DIBasicType *DIBuilder::createBasicType(StringRef Name, uint64_t SizeInBits, 2680b57cec5SDimitry Andric unsigned Encoding, 2690b57cec5SDimitry Andric DINode::DIFlags Flags) { 2700b57cec5SDimitry Andric assert(!Name.empty() && "Unable to create type without name"); 2710b57cec5SDimitry Andric return DIBasicType::get(VMContext, dwarf::DW_TAG_base_type, Name, SizeInBits, 2720b57cec5SDimitry Andric 0, Encoding, Flags); 2730b57cec5SDimitry Andric } 2740b57cec5SDimitry Andric 275e8d8bef9SDimitry Andric DIStringType *DIBuilder::createStringType(StringRef Name, uint64_t SizeInBits) { 276e8d8bef9SDimitry Andric assert(!Name.empty() && "Unable to create type without name"); 277e8d8bef9SDimitry Andric return DIStringType::get(VMContext, dwarf::DW_TAG_string_type, Name, 278e8d8bef9SDimitry Andric SizeInBits, 0); 279e8d8bef9SDimitry Andric } 280e8d8bef9SDimitry Andric 28181ad6265SDimitry Andric DIStringType *DIBuilder::createStringType(StringRef Name, 28281ad6265SDimitry Andric DIVariable *StringLength, 28381ad6265SDimitry Andric DIExpression *StrLocationExp) { 28481ad6265SDimitry Andric assert(!Name.empty() && "Unable to create type without name"); 28581ad6265SDimitry Andric return DIStringType::get(VMContext, dwarf::DW_TAG_string_type, Name, 28681ad6265SDimitry Andric StringLength, nullptr, StrLocationExp, 0, 0, 0); 28781ad6265SDimitry Andric } 28881ad6265SDimitry Andric 28981ad6265SDimitry Andric DIStringType *DIBuilder::createStringType(StringRef Name, 29081ad6265SDimitry Andric DIExpression *StringLengthExp, 29181ad6265SDimitry Andric DIExpression *StrLocationExp) { 29281ad6265SDimitry Andric assert(!Name.empty() && "Unable to create type without name"); 29381ad6265SDimitry Andric return DIStringType::get(VMContext, dwarf::DW_TAG_string_type, Name, nullptr, 29481ad6265SDimitry Andric StringLengthExp, StrLocationExp, 0, 0, 0); 29581ad6265SDimitry Andric } 29681ad6265SDimitry Andric 2970b57cec5SDimitry Andric DIDerivedType *DIBuilder::createQualifiedType(unsigned Tag, DIType *FromTy) { 2980b57cec5SDimitry Andric return DIDerivedType::get(VMContext, Tag, "", nullptr, 0, nullptr, FromTy, 0, 299*0fca6ea1SDimitry Andric 0, 0, std::nullopt, std::nullopt, DINode::FlagZero); 300*0fca6ea1SDimitry Andric } 301*0fca6ea1SDimitry Andric 302*0fca6ea1SDimitry Andric DIDerivedType *DIBuilder::createPtrAuthQualifiedType( 303*0fca6ea1SDimitry Andric DIType *FromTy, unsigned Key, bool IsAddressDiscriminated, 304*0fca6ea1SDimitry Andric unsigned ExtraDiscriminator, bool IsaPointer, 305*0fca6ea1SDimitry Andric bool AuthenticatesNullValues) { 306*0fca6ea1SDimitry Andric return DIDerivedType::get(VMContext, dwarf::DW_TAG_LLVM_ptrauth_type, "", 307*0fca6ea1SDimitry Andric nullptr, 0, nullptr, FromTy, 0, 0, 0, std::nullopt, 308*0fca6ea1SDimitry Andric std::optional<DIDerivedType::PtrAuthData>( 309*0fca6ea1SDimitry Andric std::in_place, Key, IsAddressDiscriminated, 310*0fca6ea1SDimitry Andric ExtraDiscriminator, IsaPointer, 311*0fca6ea1SDimitry Andric AuthenticatesNullValues), 312*0fca6ea1SDimitry Andric DINode::FlagZero); 3130b57cec5SDimitry Andric } 3140b57cec5SDimitry Andric 315349cc55cSDimitry Andric DIDerivedType * 316349cc55cSDimitry Andric DIBuilder::createPointerType(DIType *PointeeTy, uint64_t SizeInBits, 3170b57cec5SDimitry Andric uint32_t AlignInBits, 318bdd1243dSDimitry Andric std::optional<unsigned> DWARFAddressSpace, 319349cc55cSDimitry Andric StringRef Name, DINodeArray Annotations) { 3200b57cec5SDimitry Andric // FIXME: Why is there a name here? 3210b57cec5SDimitry Andric return DIDerivedType::get(VMContext, dwarf::DW_TAG_pointer_type, Name, 3220b57cec5SDimitry Andric nullptr, 0, nullptr, PointeeTy, SizeInBits, 323*0fca6ea1SDimitry Andric AlignInBits, 0, DWARFAddressSpace, std::nullopt, 324*0fca6ea1SDimitry Andric DINode::FlagZero, nullptr, Annotations); 3250b57cec5SDimitry Andric } 3260b57cec5SDimitry Andric 3270b57cec5SDimitry Andric DIDerivedType *DIBuilder::createMemberPointerType(DIType *PointeeTy, 3280b57cec5SDimitry Andric DIType *Base, 3290b57cec5SDimitry Andric uint64_t SizeInBits, 3300b57cec5SDimitry Andric uint32_t AlignInBits, 3310b57cec5SDimitry Andric DINode::DIFlags Flags) { 3320b57cec5SDimitry Andric return DIDerivedType::get(VMContext, dwarf::DW_TAG_ptr_to_member_type, "", 3330b57cec5SDimitry Andric nullptr, 0, nullptr, PointeeTy, SizeInBits, 334*0fca6ea1SDimitry Andric AlignInBits, 0, std::nullopt, std::nullopt, Flags, 335*0fca6ea1SDimitry Andric Base); 3360b57cec5SDimitry Andric } 3370b57cec5SDimitry Andric 338349cc55cSDimitry Andric DIDerivedType * 339349cc55cSDimitry Andric DIBuilder::createReferenceType(unsigned Tag, DIType *RTy, uint64_t SizeInBits, 3400b57cec5SDimitry Andric uint32_t AlignInBits, 341bdd1243dSDimitry Andric std::optional<unsigned> DWARFAddressSpace) { 3420b57cec5SDimitry Andric assert(RTy && "Unable to create reference type"); 3430b57cec5SDimitry Andric return DIDerivedType::get(VMContext, Tag, "", nullptr, 0, nullptr, RTy, 344*0fca6ea1SDimitry Andric SizeInBits, AlignInBits, 0, DWARFAddressSpace, {}, 3450b57cec5SDimitry Andric DINode::FlagZero); 3460b57cec5SDimitry Andric } 3470b57cec5SDimitry Andric 3480b57cec5SDimitry Andric DIDerivedType *DIBuilder::createTypedef(DIType *Ty, StringRef Name, 3490b57cec5SDimitry Andric DIFile *File, unsigned LineNo, 350349cc55cSDimitry Andric DIScope *Context, uint32_t AlignInBits, 351bdd1243dSDimitry Andric DINode::DIFlags Flags, 352349cc55cSDimitry Andric DINodeArray Annotations) { 3530b57cec5SDimitry Andric return DIDerivedType::get(VMContext, dwarf::DW_TAG_typedef, Name, File, 354480093f4SDimitry Andric LineNo, getNonCompileUnitScope(Context), Ty, 0, 355*0fca6ea1SDimitry Andric AlignInBits, 0, std::nullopt, std::nullopt, Flags, 356*0fca6ea1SDimitry Andric nullptr, Annotations); 357*0fca6ea1SDimitry Andric } 358*0fca6ea1SDimitry Andric 359*0fca6ea1SDimitry Andric DIDerivedType * 360*0fca6ea1SDimitry Andric DIBuilder::createTemplateAlias(DIType *Ty, StringRef Name, DIFile *File, 361*0fca6ea1SDimitry Andric unsigned LineNo, DIScope *Context, 362*0fca6ea1SDimitry Andric DINodeArray TParams, uint32_t AlignInBits, 363*0fca6ea1SDimitry Andric DINode::DIFlags Flags, DINodeArray Annotations) { 364*0fca6ea1SDimitry Andric return DIDerivedType::get(VMContext, dwarf::DW_TAG_template_alias, Name, File, 365*0fca6ea1SDimitry Andric LineNo, getNonCompileUnitScope(Context), Ty, 0, 366*0fca6ea1SDimitry Andric AlignInBits, 0, std::nullopt, std::nullopt, Flags, 367*0fca6ea1SDimitry Andric TParams.get(), Annotations); 3680b57cec5SDimitry Andric } 3690b57cec5SDimitry Andric 3700b57cec5SDimitry Andric DIDerivedType *DIBuilder::createFriend(DIType *Ty, DIType *FriendTy) { 3710b57cec5SDimitry Andric assert(Ty && "Invalid type!"); 3720b57cec5SDimitry Andric assert(FriendTy && "Invalid friend type!"); 3730b57cec5SDimitry Andric return DIDerivedType::get(VMContext, dwarf::DW_TAG_friend, "", nullptr, 0, Ty, 374*0fca6ea1SDimitry Andric FriendTy, 0, 0, 0, std::nullopt, std::nullopt, 375*0fca6ea1SDimitry Andric DINode::FlagZero); 3760b57cec5SDimitry Andric } 3770b57cec5SDimitry Andric 3780b57cec5SDimitry Andric DIDerivedType *DIBuilder::createInheritance(DIType *Ty, DIType *BaseTy, 3790b57cec5SDimitry Andric uint64_t BaseOffset, 3800b57cec5SDimitry Andric uint32_t VBPtrOffset, 3810b57cec5SDimitry Andric DINode::DIFlags Flags) { 3820b57cec5SDimitry Andric assert(Ty && "Unable to create inheritance"); 3830b57cec5SDimitry Andric Metadata *ExtraData = ConstantAsMetadata::get( 3840b57cec5SDimitry Andric ConstantInt::get(IntegerType::get(VMContext, 32), VBPtrOffset)); 3850b57cec5SDimitry Andric return DIDerivedType::get(VMContext, dwarf::DW_TAG_inheritance, "", nullptr, 386bdd1243dSDimitry Andric 0, Ty, BaseTy, 0, 0, BaseOffset, std::nullopt, 387*0fca6ea1SDimitry Andric std::nullopt, Flags, ExtraData); 3880b57cec5SDimitry Andric } 3890b57cec5SDimitry Andric 390349cc55cSDimitry Andric DIDerivedType *DIBuilder::createMemberType( 391349cc55cSDimitry Andric DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNumber, 392349cc55cSDimitry Andric uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, 393349cc55cSDimitry Andric DINode::DIFlags Flags, DIType *Ty, DINodeArray Annotations) { 3940b57cec5SDimitry Andric return DIDerivedType::get(VMContext, dwarf::DW_TAG_member, Name, File, 3950b57cec5SDimitry Andric LineNumber, getNonCompileUnitScope(Scope), Ty, 396bdd1243dSDimitry Andric SizeInBits, AlignInBits, OffsetInBits, std::nullopt, 397*0fca6ea1SDimitry Andric std::nullopt, Flags, nullptr, Annotations); 3980b57cec5SDimitry Andric } 3990b57cec5SDimitry Andric 4000b57cec5SDimitry Andric static ConstantAsMetadata *getConstantOrNull(Constant *C) { 4010b57cec5SDimitry Andric if (C) 4020b57cec5SDimitry Andric return ConstantAsMetadata::get(C); 4030b57cec5SDimitry Andric return nullptr; 4040b57cec5SDimitry Andric } 4050b57cec5SDimitry Andric 4060b57cec5SDimitry Andric DIDerivedType *DIBuilder::createVariantMemberType( 4070b57cec5SDimitry Andric DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNumber, 4080b57cec5SDimitry Andric uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, 4090b57cec5SDimitry Andric Constant *Discriminant, DINode::DIFlags Flags, DIType *Ty) { 410*0fca6ea1SDimitry Andric return DIDerivedType::get( 411*0fca6ea1SDimitry Andric VMContext, dwarf::DW_TAG_member, Name, File, LineNumber, 412*0fca6ea1SDimitry Andric getNonCompileUnitScope(Scope), Ty, SizeInBits, AlignInBits, OffsetInBits, 413*0fca6ea1SDimitry Andric std::nullopt, std::nullopt, Flags, getConstantOrNull(Discriminant)); 4140b57cec5SDimitry Andric } 4150b57cec5SDimitry Andric 4160b57cec5SDimitry Andric DIDerivedType *DIBuilder::createBitFieldMemberType( 4170b57cec5SDimitry Andric DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNumber, 4180b57cec5SDimitry Andric uint64_t SizeInBits, uint64_t OffsetInBits, uint64_t StorageOffsetInBits, 419349cc55cSDimitry Andric DINode::DIFlags Flags, DIType *Ty, DINodeArray Annotations) { 4200b57cec5SDimitry Andric Flags |= DINode::FlagBitField; 4210b57cec5SDimitry Andric return DIDerivedType::get( 4220b57cec5SDimitry Andric VMContext, dwarf::DW_TAG_member, Name, File, LineNumber, 423349cc55cSDimitry Andric getNonCompileUnitScope(Scope), Ty, SizeInBits, /*AlignInBits=*/0, 424*0fca6ea1SDimitry Andric OffsetInBits, std::nullopt, std::nullopt, Flags, 4250b57cec5SDimitry Andric ConstantAsMetadata::get(ConstantInt::get(IntegerType::get(VMContext, 64), 426349cc55cSDimitry Andric StorageOffsetInBits)), 427349cc55cSDimitry Andric Annotations); 4280b57cec5SDimitry Andric } 4290b57cec5SDimitry Andric 4300b57cec5SDimitry Andric DIDerivedType * 4310b57cec5SDimitry Andric DIBuilder::createStaticMemberType(DIScope *Scope, StringRef Name, DIFile *File, 4320b57cec5SDimitry Andric unsigned LineNumber, DIType *Ty, 4330b57cec5SDimitry Andric DINode::DIFlags Flags, llvm::Constant *Val, 4345f757f3fSDimitry Andric unsigned Tag, uint32_t AlignInBits) { 4350b57cec5SDimitry Andric Flags |= DINode::FlagStaticMember; 4365f757f3fSDimitry Andric return DIDerivedType::get(VMContext, Tag, Name, File, LineNumber, 4375f757f3fSDimitry Andric getNonCompileUnitScope(Scope), Ty, 0, AlignInBits, 438*0fca6ea1SDimitry Andric 0, std::nullopt, std::nullopt, Flags, 439*0fca6ea1SDimitry Andric getConstantOrNull(Val)); 4400b57cec5SDimitry Andric } 4410b57cec5SDimitry Andric 4420b57cec5SDimitry Andric DIDerivedType * 4430b57cec5SDimitry Andric DIBuilder::createObjCIVar(StringRef Name, DIFile *File, unsigned LineNumber, 4440b57cec5SDimitry Andric uint64_t SizeInBits, uint32_t AlignInBits, 4450b57cec5SDimitry Andric uint64_t OffsetInBits, DINode::DIFlags Flags, 4460b57cec5SDimitry Andric DIType *Ty, MDNode *PropertyNode) { 4470b57cec5SDimitry Andric return DIDerivedType::get(VMContext, dwarf::DW_TAG_member, Name, File, 4480b57cec5SDimitry Andric LineNumber, getNonCompileUnitScope(File), Ty, 449bdd1243dSDimitry Andric SizeInBits, AlignInBits, OffsetInBits, std::nullopt, 450*0fca6ea1SDimitry Andric std::nullopt, Flags, PropertyNode); 4510b57cec5SDimitry Andric } 4520b57cec5SDimitry Andric 4530b57cec5SDimitry Andric DIObjCProperty * 4540b57cec5SDimitry Andric DIBuilder::createObjCProperty(StringRef Name, DIFile *File, unsigned LineNumber, 4550b57cec5SDimitry Andric StringRef GetterName, StringRef SetterName, 4560b57cec5SDimitry Andric unsigned PropertyAttributes, DIType *Ty) { 4570b57cec5SDimitry Andric return DIObjCProperty::get(VMContext, Name, File, LineNumber, GetterName, 4580b57cec5SDimitry Andric SetterName, PropertyAttributes, Ty); 4590b57cec5SDimitry Andric } 4600b57cec5SDimitry Andric 4610b57cec5SDimitry Andric DITemplateTypeParameter * 4620b57cec5SDimitry Andric DIBuilder::createTemplateTypeParameter(DIScope *Context, StringRef Name, 4635ffd83dbSDimitry Andric DIType *Ty, bool isDefault) { 4640b57cec5SDimitry Andric assert((!Context || isa<DICompileUnit>(Context)) && "Expected compile unit"); 4655ffd83dbSDimitry Andric return DITemplateTypeParameter::get(VMContext, Name, Ty, isDefault); 4660b57cec5SDimitry Andric } 4670b57cec5SDimitry Andric 4680b57cec5SDimitry Andric static DITemplateValueParameter * 4690b57cec5SDimitry Andric createTemplateValueParameterHelper(LLVMContext &VMContext, unsigned Tag, 4700b57cec5SDimitry Andric DIScope *Context, StringRef Name, DIType *Ty, 4715ffd83dbSDimitry Andric bool IsDefault, Metadata *MD) { 4720b57cec5SDimitry Andric assert((!Context || isa<DICompileUnit>(Context)) && "Expected compile unit"); 4735ffd83dbSDimitry Andric return DITemplateValueParameter::get(VMContext, Tag, Name, Ty, IsDefault, MD); 4740b57cec5SDimitry Andric } 4750b57cec5SDimitry Andric 4760b57cec5SDimitry Andric DITemplateValueParameter * 4770b57cec5SDimitry Andric DIBuilder::createTemplateValueParameter(DIScope *Context, StringRef Name, 4785ffd83dbSDimitry Andric DIType *Ty, bool isDefault, 4795ffd83dbSDimitry Andric Constant *Val) { 4800b57cec5SDimitry Andric return createTemplateValueParameterHelper( 4810b57cec5SDimitry Andric VMContext, dwarf::DW_TAG_template_value_parameter, Context, Name, Ty, 4825ffd83dbSDimitry Andric isDefault, getConstantOrNull(Val)); 4830b57cec5SDimitry Andric } 4840b57cec5SDimitry Andric 4850b57cec5SDimitry Andric DITemplateValueParameter * 4860b57cec5SDimitry Andric DIBuilder::createTemplateTemplateParameter(DIScope *Context, StringRef Name, 487bdd1243dSDimitry Andric DIType *Ty, StringRef Val, 488bdd1243dSDimitry Andric bool IsDefault) { 4890b57cec5SDimitry Andric return createTemplateValueParameterHelper( 4900b57cec5SDimitry Andric VMContext, dwarf::DW_TAG_GNU_template_template_param, Context, Name, Ty, 491bdd1243dSDimitry Andric IsDefault, MDString::get(VMContext, Val)); 4920b57cec5SDimitry Andric } 4930b57cec5SDimitry Andric 4940b57cec5SDimitry Andric DITemplateValueParameter * 4950b57cec5SDimitry Andric DIBuilder::createTemplateParameterPack(DIScope *Context, StringRef Name, 4960b57cec5SDimitry Andric DIType *Ty, DINodeArray Val) { 4970b57cec5SDimitry Andric return createTemplateValueParameterHelper( 4980b57cec5SDimitry Andric VMContext, dwarf::DW_TAG_GNU_template_parameter_pack, Context, Name, Ty, 4995ffd83dbSDimitry Andric false, Val.get()); 5000b57cec5SDimitry Andric } 5010b57cec5SDimitry Andric 5020b57cec5SDimitry Andric DICompositeType *DIBuilder::createClassType( 5030b57cec5SDimitry Andric DIScope *Context, StringRef Name, DIFile *File, unsigned LineNumber, 5040b57cec5SDimitry Andric uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits, 5050b57cec5SDimitry Andric DINode::DIFlags Flags, DIType *DerivedFrom, DINodeArray Elements, 5065f757f3fSDimitry Andric unsigned RunTimeLang, DIType *VTableHolder, MDNode *TemplateParams, 5075f757f3fSDimitry Andric StringRef UniqueIdentifier) { 5080b57cec5SDimitry Andric assert((!Context || isa<DIScope>(Context)) && 5090b57cec5SDimitry Andric "createClassType should be called with a valid Context"); 5100b57cec5SDimitry Andric 5110b57cec5SDimitry Andric auto *R = DICompositeType::get( 5120b57cec5SDimitry Andric VMContext, dwarf::DW_TAG_structure_type, Name, File, LineNumber, 5130b57cec5SDimitry Andric getNonCompileUnitScope(Context), DerivedFrom, SizeInBits, AlignInBits, 5145f757f3fSDimitry Andric OffsetInBits, Flags, Elements, RunTimeLang, VTableHolder, 5150b57cec5SDimitry Andric cast_or_null<MDTuple>(TemplateParams), UniqueIdentifier); 5160b57cec5SDimitry Andric trackIfUnresolved(R); 5170b57cec5SDimitry Andric return R; 5180b57cec5SDimitry Andric } 5190b57cec5SDimitry Andric 5200b57cec5SDimitry Andric DICompositeType *DIBuilder::createStructType( 5210b57cec5SDimitry Andric DIScope *Context, StringRef Name, DIFile *File, unsigned LineNumber, 5220b57cec5SDimitry Andric uint64_t SizeInBits, uint32_t AlignInBits, DINode::DIFlags Flags, 5230b57cec5SDimitry Andric DIType *DerivedFrom, DINodeArray Elements, unsigned RunTimeLang, 5240b57cec5SDimitry Andric DIType *VTableHolder, StringRef UniqueIdentifier) { 5250b57cec5SDimitry Andric auto *R = DICompositeType::get( 5260b57cec5SDimitry Andric VMContext, dwarf::DW_TAG_structure_type, Name, File, LineNumber, 5270b57cec5SDimitry Andric getNonCompileUnitScope(Context), DerivedFrom, SizeInBits, AlignInBits, 0, 5280b57cec5SDimitry Andric Flags, Elements, RunTimeLang, VTableHolder, nullptr, UniqueIdentifier); 5290b57cec5SDimitry Andric trackIfUnresolved(R); 5300b57cec5SDimitry Andric return R; 5310b57cec5SDimitry Andric } 5320b57cec5SDimitry Andric 5330b57cec5SDimitry Andric DICompositeType *DIBuilder::createUnionType( 5340b57cec5SDimitry Andric DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNumber, 5350b57cec5SDimitry Andric uint64_t SizeInBits, uint32_t AlignInBits, DINode::DIFlags Flags, 5360b57cec5SDimitry Andric DINodeArray Elements, unsigned RunTimeLang, StringRef UniqueIdentifier) { 5370b57cec5SDimitry Andric auto *R = DICompositeType::get( 5380b57cec5SDimitry Andric VMContext, dwarf::DW_TAG_union_type, Name, File, LineNumber, 5390b57cec5SDimitry Andric getNonCompileUnitScope(Scope), nullptr, SizeInBits, AlignInBits, 0, Flags, 5400b57cec5SDimitry Andric Elements, RunTimeLang, nullptr, nullptr, UniqueIdentifier); 5410b57cec5SDimitry Andric trackIfUnresolved(R); 5420b57cec5SDimitry Andric return R; 5430b57cec5SDimitry Andric } 5440b57cec5SDimitry Andric 545349cc55cSDimitry Andric DICompositeType * 546349cc55cSDimitry Andric DIBuilder::createVariantPart(DIScope *Scope, StringRef Name, DIFile *File, 547349cc55cSDimitry Andric unsigned LineNumber, uint64_t SizeInBits, 548349cc55cSDimitry Andric uint32_t AlignInBits, DINode::DIFlags Flags, 549349cc55cSDimitry Andric DIDerivedType *Discriminator, DINodeArray Elements, 550349cc55cSDimitry Andric StringRef UniqueIdentifier) { 5510b57cec5SDimitry Andric auto *R = DICompositeType::get( 5520b57cec5SDimitry Andric VMContext, dwarf::DW_TAG_variant_part, Name, File, LineNumber, 5530b57cec5SDimitry Andric getNonCompileUnitScope(Scope), nullptr, SizeInBits, AlignInBits, 0, Flags, 5540b57cec5SDimitry Andric Elements, 0, nullptr, nullptr, UniqueIdentifier, Discriminator); 5550b57cec5SDimitry Andric trackIfUnresolved(R); 5560b57cec5SDimitry Andric return R; 5570b57cec5SDimitry Andric } 5580b57cec5SDimitry Andric 5590b57cec5SDimitry Andric DISubroutineType *DIBuilder::createSubroutineType(DITypeRefArray ParameterTypes, 5600b57cec5SDimitry Andric DINode::DIFlags Flags, 5610b57cec5SDimitry Andric unsigned CC) { 5620b57cec5SDimitry Andric return DISubroutineType::get(VMContext, Flags, CC, ParameterTypes); 5630b57cec5SDimitry Andric } 5640b57cec5SDimitry Andric 5655f757f3fSDimitry Andric DICompositeType * 5665f757f3fSDimitry Andric DIBuilder::createEnumerationType(DIScope *Scope, StringRef Name, DIFile *File, 5675f757f3fSDimitry Andric unsigned LineNumber, uint64_t SizeInBits, 5685f757f3fSDimitry Andric uint32_t AlignInBits, DINodeArray Elements, 5695f757f3fSDimitry Andric DIType *UnderlyingType, unsigned RunTimeLang, 5705f757f3fSDimitry Andric StringRef UniqueIdentifier, bool IsScoped) { 5710b57cec5SDimitry Andric auto *CTy = DICompositeType::get( 5720b57cec5SDimitry Andric VMContext, dwarf::DW_TAG_enumeration_type, Name, File, LineNumber, 5730b57cec5SDimitry Andric getNonCompileUnitScope(Scope), UnderlyingType, SizeInBits, AlignInBits, 0, 5745f757f3fSDimitry Andric IsScoped ? DINode::FlagEnumClass : DINode::FlagZero, Elements, 5755f757f3fSDimitry Andric RunTimeLang, nullptr, nullptr, UniqueIdentifier); 576bdd1243dSDimitry Andric AllEnumTypes.emplace_back(CTy); 5770b57cec5SDimitry Andric trackIfUnresolved(CTy); 5780b57cec5SDimitry Andric return CTy; 5790b57cec5SDimitry Andric } 5800b57cec5SDimitry Andric 581fe6060f1SDimitry Andric DIDerivedType *DIBuilder::createSetType(DIScope *Scope, StringRef Name, 582fe6060f1SDimitry Andric DIFile *File, unsigned LineNo, 583fe6060f1SDimitry Andric uint64_t SizeInBits, 584fe6060f1SDimitry Andric uint32_t AlignInBits, DIType *Ty) { 585*0fca6ea1SDimitry Andric auto *R = DIDerivedType::get(VMContext, dwarf::DW_TAG_set_type, Name, File, 586*0fca6ea1SDimitry Andric LineNo, getNonCompileUnitScope(Scope), Ty, 587*0fca6ea1SDimitry Andric SizeInBits, AlignInBits, 0, std::nullopt, 588*0fca6ea1SDimitry Andric std::nullopt, DINode::FlagZero); 589fe6060f1SDimitry Andric trackIfUnresolved(R); 590fe6060f1SDimitry Andric return R; 591fe6060f1SDimitry Andric } 592fe6060f1SDimitry Andric 593349cc55cSDimitry Andric DICompositeType * 594349cc55cSDimitry Andric DIBuilder::createArrayType(uint64_t Size, uint32_t AlignInBits, DIType *Ty, 595349cc55cSDimitry Andric DINodeArray Subscripts, 596e8d8bef9SDimitry Andric PointerUnion<DIExpression *, DIVariable *> DL, 597e8d8bef9SDimitry Andric PointerUnion<DIExpression *, DIVariable *> AS, 598e8d8bef9SDimitry Andric PointerUnion<DIExpression *, DIVariable *> AL, 599e8d8bef9SDimitry Andric PointerUnion<DIExpression *, DIVariable *> RK) { 600e8d8bef9SDimitry Andric auto *R = DICompositeType::get( 601349cc55cSDimitry Andric VMContext, dwarf::DW_TAG_array_type, "", nullptr, 0, nullptr, Ty, Size, 602349cc55cSDimitry Andric AlignInBits, 0, DINode::FlagZero, Subscripts, 0, nullptr, nullptr, "", 603349cc55cSDimitry Andric nullptr, 60406c3fb27SDimitry Andric isa<DIExpression *>(DL) ? (Metadata *)cast<DIExpression *>(DL) 60506c3fb27SDimitry Andric : (Metadata *)cast<DIVariable *>(DL), 60606c3fb27SDimitry Andric isa<DIExpression *>(AS) ? (Metadata *)cast<DIExpression *>(AS) 60706c3fb27SDimitry Andric : (Metadata *)cast<DIVariable *>(AS), 60806c3fb27SDimitry Andric isa<DIExpression *>(AL) ? (Metadata *)cast<DIExpression *>(AL) 60906c3fb27SDimitry Andric : (Metadata *)cast<DIVariable *>(AL), 61006c3fb27SDimitry Andric isa<DIExpression *>(RK) ? (Metadata *)cast<DIExpression *>(RK) 61106c3fb27SDimitry Andric : (Metadata *)cast<DIVariable *>(RK)); 6120b57cec5SDimitry Andric trackIfUnresolved(R); 6130b57cec5SDimitry Andric return R; 6140b57cec5SDimitry Andric } 6150b57cec5SDimitry Andric 6160b57cec5SDimitry Andric DICompositeType *DIBuilder::createVectorType(uint64_t Size, 6170b57cec5SDimitry Andric uint32_t AlignInBits, DIType *Ty, 6180b57cec5SDimitry Andric DINodeArray Subscripts) { 6190b57cec5SDimitry Andric auto *R = DICompositeType::get(VMContext, dwarf::DW_TAG_array_type, "", 6200b57cec5SDimitry Andric nullptr, 0, nullptr, Ty, Size, AlignInBits, 0, 6210b57cec5SDimitry Andric DINode::FlagVector, Subscripts, 0, nullptr); 6220b57cec5SDimitry Andric trackIfUnresolved(R); 6230b57cec5SDimitry Andric return R; 6240b57cec5SDimitry Andric } 6250b57cec5SDimitry Andric 6260b57cec5SDimitry Andric DISubprogram *DIBuilder::createArtificialSubprogram(DISubprogram *SP) { 6270b57cec5SDimitry Andric auto NewSP = SP->cloneWithFlags(SP->getFlags() | DINode::FlagArtificial); 6280b57cec5SDimitry Andric return MDNode::replaceWithDistinct(std::move(NewSP)); 6290b57cec5SDimitry Andric } 6300b57cec5SDimitry Andric 6310b57cec5SDimitry Andric static DIType *createTypeWithFlags(const DIType *Ty, 6320b57cec5SDimitry Andric DINode::DIFlags FlagsToSet) { 6330b57cec5SDimitry Andric auto NewTy = Ty->cloneWithFlags(Ty->getFlags() | FlagsToSet); 6340b57cec5SDimitry Andric return MDNode::replaceWithUniqued(std::move(NewTy)); 6350b57cec5SDimitry Andric } 6360b57cec5SDimitry Andric 6370b57cec5SDimitry Andric DIType *DIBuilder::createArtificialType(DIType *Ty) { 6380b57cec5SDimitry Andric // FIXME: Restrict this to the nodes where it's valid. 6390b57cec5SDimitry Andric if (Ty->isArtificial()) 6400b57cec5SDimitry Andric return Ty; 6410b57cec5SDimitry Andric return createTypeWithFlags(Ty, DINode::FlagArtificial); 6420b57cec5SDimitry Andric } 6430b57cec5SDimitry Andric 6440b57cec5SDimitry Andric DIType *DIBuilder::createObjectPointerType(DIType *Ty) { 6450b57cec5SDimitry Andric // FIXME: Restrict this to the nodes where it's valid. 6460b57cec5SDimitry Andric if (Ty->isObjectPointer()) 6470b57cec5SDimitry Andric return Ty; 6480b57cec5SDimitry Andric DINode::DIFlags Flags = DINode::FlagObjectPointer | DINode::FlagArtificial; 6490b57cec5SDimitry Andric return createTypeWithFlags(Ty, Flags); 6500b57cec5SDimitry Andric } 6510b57cec5SDimitry Andric 6520b57cec5SDimitry Andric void DIBuilder::retainType(DIScope *T) { 6530b57cec5SDimitry Andric assert(T && "Expected non-null type"); 6540b57cec5SDimitry Andric assert((isa<DIType>(T) || (isa<DISubprogram>(T) && 6550b57cec5SDimitry Andric cast<DISubprogram>(T)->isDefinition() == false)) && 6560b57cec5SDimitry Andric "Expected type or subprogram declaration"); 6570b57cec5SDimitry Andric AllRetainTypes.emplace_back(T); 6580b57cec5SDimitry Andric } 6590b57cec5SDimitry Andric 6600b57cec5SDimitry Andric DIBasicType *DIBuilder::createUnspecifiedParameter() { return nullptr; } 6610b57cec5SDimitry Andric 6620b57cec5SDimitry Andric DICompositeType * 6630b57cec5SDimitry Andric DIBuilder::createForwardDecl(unsigned Tag, StringRef Name, DIScope *Scope, 6640b57cec5SDimitry Andric DIFile *F, unsigned Line, unsigned RuntimeLang, 6650b57cec5SDimitry Andric uint64_t SizeInBits, uint32_t AlignInBits, 6660b57cec5SDimitry Andric StringRef UniqueIdentifier) { 6670b57cec5SDimitry Andric // FIXME: Define in terms of createReplaceableForwardDecl() by calling 6680b57cec5SDimitry Andric // replaceWithUniqued(). 6690b57cec5SDimitry Andric auto *RetTy = DICompositeType::get( 6700b57cec5SDimitry Andric VMContext, Tag, Name, F, Line, getNonCompileUnitScope(Scope), nullptr, 6710b57cec5SDimitry Andric SizeInBits, AlignInBits, 0, DINode::FlagFwdDecl, nullptr, RuntimeLang, 6720b57cec5SDimitry Andric nullptr, nullptr, UniqueIdentifier); 6730b57cec5SDimitry Andric trackIfUnresolved(RetTy); 6740b57cec5SDimitry Andric return RetTy; 6750b57cec5SDimitry Andric } 6760b57cec5SDimitry Andric 6770b57cec5SDimitry Andric DICompositeType *DIBuilder::createReplaceableCompositeType( 6780b57cec5SDimitry Andric unsigned Tag, StringRef Name, DIScope *Scope, DIFile *F, unsigned Line, 6790b57cec5SDimitry Andric unsigned RuntimeLang, uint64_t SizeInBits, uint32_t AlignInBits, 680349cc55cSDimitry Andric DINode::DIFlags Flags, StringRef UniqueIdentifier, 681349cc55cSDimitry Andric DINodeArray Annotations) { 6820b57cec5SDimitry Andric auto *RetTy = 6830b57cec5SDimitry Andric DICompositeType::getTemporary( 6840b57cec5SDimitry Andric VMContext, Tag, Name, F, Line, getNonCompileUnitScope(Scope), nullptr, 6850b57cec5SDimitry Andric SizeInBits, AlignInBits, 0, Flags, nullptr, RuntimeLang, nullptr, 686349cc55cSDimitry Andric nullptr, UniqueIdentifier, nullptr, nullptr, nullptr, nullptr, 687349cc55cSDimitry Andric nullptr, Annotations) 6880b57cec5SDimitry Andric .release(); 6890b57cec5SDimitry Andric trackIfUnresolved(RetTy); 6900b57cec5SDimitry Andric return RetTy; 6910b57cec5SDimitry Andric } 6920b57cec5SDimitry Andric 6930b57cec5SDimitry Andric DINodeArray DIBuilder::getOrCreateArray(ArrayRef<Metadata *> Elements) { 6940b57cec5SDimitry Andric return MDTuple::get(VMContext, Elements); 6950b57cec5SDimitry Andric } 6960b57cec5SDimitry Andric 6970b57cec5SDimitry Andric DIMacroNodeArray 6980b57cec5SDimitry Andric DIBuilder::getOrCreateMacroArray(ArrayRef<Metadata *> Elements) { 6990b57cec5SDimitry Andric return MDTuple::get(VMContext, Elements); 7000b57cec5SDimitry Andric } 7010b57cec5SDimitry Andric 7020b57cec5SDimitry Andric DITypeRefArray DIBuilder::getOrCreateTypeArray(ArrayRef<Metadata *> Elements) { 7030b57cec5SDimitry Andric SmallVector<llvm::Metadata *, 16> Elts; 7040eae32dcSDimitry Andric for (Metadata *E : Elements) { 7050eae32dcSDimitry Andric if (isa_and_nonnull<MDNode>(E)) 7060eae32dcSDimitry Andric Elts.push_back(cast<DIType>(E)); 7070b57cec5SDimitry Andric else 7080eae32dcSDimitry Andric Elts.push_back(E); 7090b57cec5SDimitry Andric } 7100b57cec5SDimitry Andric return DITypeRefArray(MDNode::get(VMContext, Elts)); 7110b57cec5SDimitry Andric } 7120b57cec5SDimitry Andric 7130b57cec5SDimitry Andric DISubrange *DIBuilder::getOrCreateSubrange(int64_t Lo, int64_t Count) { 7145ffd83dbSDimitry Andric auto *LB = ConstantAsMetadata::get( 7155ffd83dbSDimitry Andric ConstantInt::getSigned(Type::getInt64Ty(VMContext), Lo)); 7165ffd83dbSDimitry Andric auto *CountNode = ConstantAsMetadata::get( 7175ffd83dbSDimitry Andric ConstantInt::getSigned(Type::getInt64Ty(VMContext), Count)); 7185ffd83dbSDimitry Andric return DISubrange::get(VMContext, CountNode, LB, nullptr, nullptr); 7190b57cec5SDimitry Andric } 7200b57cec5SDimitry Andric 7210b57cec5SDimitry Andric DISubrange *DIBuilder::getOrCreateSubrange(int64_t Lo, Metadata *CountNode) { 7225ffd83dbSDimitry Andric auto *LB = ConstantAsMetadata::get( 7235ffd83dbSDimitry Andric ConstantInt::getSigned(Type::getInt64Ty(VMContext), Lo)); 7245ffd83dbSDimitry Andric return DISubrange::get(VMContext, CountNode, LB, nullptr, nullptr); 7255ffd83dbSDimitry Andric } 7265ffd83dbSDimitry Andric 7275ffd83dbSDimitry Andric DISubrange *DIBuilder::getOrCreateSubrange(Metadata *CountNode, Metadata *LB, 7285ffd83dbSDimitry Andric Metadata *UB, Metadata *Stride) { 7295ffd83dbSDimitry Andric return DISubrange::get(VMContext, CountNode, LB, UB, Stride); 7300b57cec5SDimitry Andric } 7310b57cec5SDimitry Andric 732e8d8bef9SDimitry Andric DIGenericSubrange *DIBuilder::getOrCreateGenericSubrange( 733e8d8bef9SDimitry Andric DIGenericSubrange::BoundType CountNode, DIGenericSubrange::BoundType LB, 734e8d8bef9SDimitry Andric DIGenericSubrange::BoundType UB, DIGenericSubrange::BoundType Stride) { 735e8d8bef9SDimitry Andric auto ConvToMetadata = [&](DIGenericSubrange::BoundType Bound) -> Metadata * { 73606c3fb27SDimitry Andric return isa<DIExpression *>(Bound) ? (Metadata *)cast<DIExpression *>(Bound) 73706c3fb27SDimitry Andric : (Metadata *)cast<DIVariable *>(Bound); 738e8d8bef9SDimitry Andric }; 739e8d8bef9SDimitry Andric return DIGenericSubrange::get(VMContext, ConvToMetadata(CountNode), 740e8d8bef9SDimitry Andric ConvToMetadata(LB), ConvToMetadata(UB), 741e8d8bef9SDimitry Andric ConvToMetadata(Stride)); 742e8d8bef9SDimitry Andric } 743e8d8bef9SDimitry Andric 7440b57cec5SDimitry Andric static void checkGlobalVariableScope(DIScope *Context) { 7450b57cec5SDimitry Andric #ifndef NDEBUG 7460b57cec5SDimitry Andric if (auto *CT = 7470b57cec5SDimitry Andric dyn_cast_or_null<DICompositeType>(getNonCompileUnitScope(Context))) 7480b57cec5SDimitry Andric assert(CT->getIdentifier().empty() && 7490b57cec5SDimitry Andric "Context of a global variable should not be a type with identifier"); 7500b57cec5SDimitry Andric #endif 7510b57cec5SDimitry Andric } 7520b57cec5SDimitry Andric 7530b57cec5SDimitry Andric DIGlobalVariableExpression *DIBuilder::createGlobalVariableExpression( 7540b57cec5SDimitry Andric DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *F, 755349cc55cSDimitry Andric unsigned LineNumber, DIType *Ty, bool IsLocalToUnit, bool isDefined, 756349cc55cSDimitry Andric DIExpression *Expr, MDNode *Decl, MDTuple *TemplateParams, 757349cc55cSDimitry Andric uint32_t AlignInBits, DINodeArray Annotations) { 7580b57cec5SDimitry Andric checkGlobalVariableScope(Context); 7590b57cec5SDimitry Andric 7600b57cec5SDimitry Andric auto *GV = DIGlobalVariable::getDistinct( 7610b57cec5SDimitry Andric VMContext, cast_or_null<DIScope>(Context), Name, LinkageName, F, 762349cc55cSDimitry Andric LineNumber, Ty, IsLocalToUnit, isDefined, 763349cc55cSDimitry Andric cast_or_null<DIDerivedType>(Decl), TemplateParams, AlignInBits, 764349cc55cSDimitry Andric Annotations); 7650b57cec5SDimitry Andric if (!Expr) 7660b57cec5SDimitry Andric Expr = createExpression(); 7670b57cec5SDimitry Andric auto *N = DIGlobalVariableExpression::get(VMContext, GV, Expr); 7680b57cec5SDimitry Andric AllGVs.push_back(N); 7690b57cec5SDimitry Andric return N; 7700b57cec5SDimitry Andric } 7710b57cec5SDimitry Andric 7720b57cec5SDimitry Andric DIGlobalVariable *DIBuilder::createTempGlobalVariableFwdDecl( 7730b57cec5SDimitry Andric DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *F, 774480093f4SDimitry Andric unsigned LineNumber, DIType *Ty, bool IsLocalToUnit, MDNode *Decl, 775480093f4SDimitry Andric MDTuple *TemplateParams, uint32_t AlignInBits) { 7760b57cec5SDimitry Andric checkGlobalVariableScope(Context); 7770b57cec5SDimitry Andric 7780b57cec5SDimitry Andric return DIGlobalVariable::getTemporary( 7790b57cec5SDimitry Andric VMContext, cast_or_null<DIScope>(Context), Name, LinkageName, F, 780480093f4SDimitry Andric LineNumber, Ty, IsLocalToUnit, false, 781349cc55cSDimitry Andric cast_or_null<DIDerivedType>(Decl), TemplateParams, AlignInBits, 782349cc55cSDimitry Andric nullptr) 7830b57cec5SDimitry Andric .release(); 7840b57cec5SDimitry Andric } 7850b57cec5SDimitry Andric 7860b57cec5SDimitry Andric static DILocalVariable *createLocalVariable( 7870b57cec5SDimitry Andric LLVMContext &VMContext, 78806c3fb27SDimitry Andric SmallVectorImpl<TrackingMDNodeRef> &PreservedNodes, 78906c3fb27SDimitry Andric DIScope *Context, StringRef Name, unsigned ArgNo, DIFile *File, 7900b57cec5SDimitry Andric unsigned LineNo, DIType *Ty, bool AlwaysPreserve, DINode::DIFlags Flags, 791349cc55cSDimitry Andric uint32_t AlignInBits, DINodeArray Annotations = nullptr) { 7920b57cec5SDimitry Andric // FIXME: Why doesn't this check for a subprogram or lexical block (AFAICT 7930b57cec5SDimitry Andric // the only valid scopes)? 79406c3fb27SDimitry Andric auto *Scope = cast<DILocalScope>(Context); 79506c3fb27SDimitry Andric auto *Node = DILocalVariable::get(VMContext, Scope, Name, File, LineNo, Ty, 796349cc55cSDimitry Andric ArgNo, Flags, AlignInBits, Annotations); 7970b57cec5SDimitry Andric if (AlwaysPreserve) { 7980b57cec5SDimitry Andric // The optimizer may remove local variables. If there is an interest 7990b57cec5SDimitry Andric // to preserve variable info in such situation then stash it in a 8000b57cec5SDimitry Andric // named mdnode. 80106c3fb27SDimitry Andric PreservedNodes.emplace_back(Node); 8020b57cec5SDimitry Andric } 8030b57cec5SDimitry Andric return Node; 8040b57cec5SDimitry Andric } 8050b57cec5SDimitry Andric 8060b57cec5SDimitry Andric DILocalVariable *DIBuilder::createAutoVariable(DIScope *Scope, StringRef Name, 8070b57cec5SDimitry Andric DIFile *File, unsigned LineNo, 8080b57cec5SDimitry Andric DIType *Ty, bool AlwaysPreserve, 8090b57cec5SDimitry Andric DINode::DIFlags Flags, 8100b57cec5SDimitry Andric uint32_t AlignInBits) { 81106c3fb27SDimitry Andric assert(Scope && isa<DILocalScope>(Scope) && 81206c3fb27SDimitry Andric "Unexpected scope for a local variable."); 81306c3fb27SDimitry Andric return createLocalVariable( 81406c3fb27SDimitry Andric VMContext, getSubprogramNodesTrackingVector(Scope), Scope, Name, 81506c3fb27SDimitry Andric /* ArgNo */ 0, File, LineNo, Ty, AlwaysPreserve, Flags, AlignInBits); 8160b57cec5SDimitry Andric } 8170b57cec5SDimitry Andric 8180b57cec5SDimitry Andric DILocalVariable *DIBuilder::createParameterVariable( 8190b57cec5SDimitry Andric DIScope *Scope, StringRef Name, unsigned ArgNo, DIFile *File, 820349cc55cSDimitry Andric unsigned LineNo, DIType *Ty, bool AlwaysPreserve, DINode::DIFlags Flags, 821349cc55cSDimitry Andric DINodeArray Annotations) { 8220b57cec5SDimitry Andric assert(ArgNo && "Expected non-zero argument number for parameter"); 82306c3fb27SDimitry Andric assert(Scope && isa<DILocalScope>(Scope) && 82406c3fb27SDimitry Andric "Unexpected scope for a local variable."); 82506c3fb27SDimitry Andric return createLocalVariable( 82606c3fb27SDimitry Andric VMContext, getSubprogramNodesTrackingVector(Scope), Scope, Name, ArgNo, 82706c3fb27SDimitry Andric File, LineNo, Ty, AlwaysPreserve, Flags, /*AlignInBits=*/0, Annotations); 8280b57cec5SDimitry Andric } 8290b57cec5SDimitry Andric 83006c3fb27SDimitry Andric DILabel *DIBuilder::createLabel(DIScope *Context, StringRef Name, DIFile *File, 8310b57cec5SDimitry Andric unsigned LineNo, bool AlwaysPreserve) { 83206c3fb27SDimitry Andric auto *Scope = cast<DILocalScope>(Context); 83306c3fb27SDimitry Andric auto *Node = DILabel::get(VMContext, Scope, Name, File, LineNo); 8340b57cec5SDimitry Andric 8350b57cec5SDimitry Andric if (AlwaysPreserve) { 8360b57cec5SDimitry Andric /// The optimizer may remove labels. If there is an interest 8370b57cec5SDimitry Andric /// to preserve label info in such situation then append it to 8380b57cec5SDimitry Andric /// the list of retained nodes of the DISubprogram. 83906c3fb27SDimitry Andric getSubprogramNodesTrackingVector(Scope).emplace_back(Node); 8400b57cec5SDimitry Andric } 8410b57cec5SDimitry Andric return Node; 8420b57cec5SDimitry Andric } 8430b57cec5SDimitry Andric 8440b57cec5SDimitry Andric DIExpression *DIBuilder::createExpression(ArrayRef<uint64_t> Addr) { 8450b57cec5SDimitry Andric return DIExpression::get(VMContext, Addr); 8460b57cec5SDimitry Andric } 8470b57cec5SDimitry Andric 8480b57cec5SDimitry Andric template <class... Ts> 8490b57cec5SDimitry Andric static DISubprogram *getSubprogram(bool IsDistinct, Ts &&...Args) { 8500b57cec5SDimitry Andric if (IsDistinct) 8510b57cec5SDimitry Andric return DISubprogram::getDistinct(std::forward<Ts>(Args)...); 8520b57cec5SDimitry Andric return DISubprogram::get(std::forward<Ts>(Args)...); 8530b57cec5SDimitry Andric } 8540b57cec5SDimitry Andric 8550b57cec5SDimitry Andric DISubprogram *DIBuilder::createFunction( 8560b57cec5SDimitry Andric DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *File, 8570b57cec5SDimitry Andric unsigned LineNo, DISubroutineType *Ty, unsigned ScopeLine, 8580b57cec5SDimitry Andric DINode::DIFlags Flags, DISubprogram::DISPFlags SPFlags, 8590b57cec5SDimitry Andric DITemplateParameterArray TParams, DISubprogram *Decl, 86081ad6265SDimitry Andric DITypeArray ThrownTypes, DINodeArray Annotations, 86181ad6265SDimitry Andric StringRef TargetFuncName) { 8620b57cec5SDimitry Andric bool IsDefinition = SPFlags & DISubprogram::SPFlagDefinition; 8630b57cec5SDimitry Andric auto *Node = getSubprogram( 8640b57cec5SDimitry Andric /*IsDistinct=*/IsDefinition, VMContext, getNonCompileUnitScope(Context), 8650b57cec5SDimitry Andric Name, LinkageName, File, LineNo, Ty, ScopeLine, nullptr, 0, 0, Flags, 86606c3fb27SDimitry Andric SPFlags, IsDefinition ? CUNode : nullptr, TParams, Decl, nullptr, 86706c3fb27SDimitry Andric ThrownTypes, Annotations, TargetFuncName); 8680b57cec5SDimitry Andric 8690b57cec5SDimitry Andric if (IsDefinition) 8700b57cec5SDimitry Andric AllSubprograms.push_back(Node); 8710b57cec5SDimitry Andric trackIfUnresolved(Node); 8720b57cec5SDimitry Andric return Node; 8730b57cec5SDimitry Andric } 8740b57cec5SDimitry Andric 8750b57cec5SDimitry Andric DISubprogram *DIBuilder::createTempFunctionFwdDecl( 8760b57cec5SDimitry Andric DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *File, 8770b57cec5SDimitry Andric unsigned LineNo, DISubroutineType *Ty, unsigned ScopeLine, 8780b57cec5SDimitry Andric DINode::DIFlags Flags, DISubprogram::DISPFlags SPFlags, 8790b57cec5SDimitry Andric DITemplateParameterArray TParams, DISubprogram *Decl, 8800b57cec5SDimitry Andric DITypeArray ThrownTypes) { 8810b57cec5SDimitry Andric bool IsDefinition = SPFlags & DISubprogram::SPFlagDefinition; 8820b57cec5SDimitry Andric return DISubprogram::getTemporary(VMContext, getNonCompileUnitScope(Context), 8830b57cec5SDimitry Andric Name, LinkageName, File, LineNo, Ty, 8840b57cec5SDimitry Andric ScopeLine, nullptr, 0, 0, Flags, SPFlags, 8850b57cec5SDimitry Andric IsDefinition ? CUNode : nullptr, TParams, 8860b57cec5SDimitry Andric Decl, nullptr, ThrownTypes) 8870b57cec5SDimitry Andric .release(); 8880b57cec5SDimitry Andric } 8890b57cec5SDimitry Andric 8900b57cec5SDimitry Andric DISubprogram *DIBuilder::createMethod( 8910b57cec5SDimitry Andric DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *F, 8920b57cec5SDimitry Andric unsigned LineNo, DISubroutineType *Ty, unsigned VIndex, int ThisAdjustment, 8930b57cec5SDimitry Andric DIType *VTableHolder, DINode::DIFlags Flags, 8940b57cec5SDimitry Andric DISubprogram::DISPFlags SPFlags, DITemplateParameterArray TParams, 8950b57cec5SDimitry Andric DITypeArray ThrownTypes) { 8960b57cec5SDimitry Andric assert(getNonCompileUnitScope(Context) && 8970b57cec5SDimitry Andric "Methods should have both a Context and a context that isn't " 8980b57cec5SDimitry Andric "the compile unit."); 8990b57cec5SDimitry Andric // FIXME: Do we want to use different scope/lines? 9000b57cec5SDimitry Andric bool IsDefinition = SPFlags & DISubprogram::SPFlagDefinition; 9010b57cec5SDimitry Andric auto *SP = getSubprogram( 9020b57cec5SDimitry Andric /*IsDistinct=*/IsDefinition, VMContext, cast<DIScope>(Context), Name, 9030b57cec5SDimitry Andric LinkageName, F, LineNo, Ty, LineNo, VTableHolder, VIndex, ThisAdjustment, 9040b57cec5SDimitry Andric Flags, SPFlags, IsDefinition ? CUNode : nullptr, TParams, nullptr, 9050b57cec5SDimitry Andric nullptr, ThrownTypes); 9060b57cec5SDimitry Andric 9070b57cec5SDimitry Andric if (IsDefinition) 9080b57cec5SDimitry Andric AllSubprograms.push_back(SP); 9090b57cec5SDimitry Andric trackIfUnresolved(SP); 9100b57cec5SDimitry Andric return SP; 9110b57cec5SDimitry Andric } 9120b57cec5SDimitry Andric 913349cc55cSDimitry Andric DICommonBlock *DIBuilder::createCommonBlock(DIScope *Scope, 914349cc55cSDimitry Andric DIGlobalVariable *Decl, 915349cc55cSDimitry Andric StringRef Name, DIFile *File, 9160b57cec5SDimitry Andric unsigned LineNo) { 917349cc55cSDimitry Andric return DICommonBlock::get(VMContext, Scope, Decl, Name, File, LineNo); 9180b57cec5SDimitry Andric } 9190b57cec5SDimitry Andric 9200b57cec5SDimitry Andric DINamespace *DIBuilder::createNameSpace(DIScope *Scope, StringRef Name, 9210b57cec5SDimitry Andric bool ExportSymbols) { 9220b57cec5SDimitry Andric 9230b57cec5SDimitry Andric // It is okay to *not* make anonymous top-level namespaces distinct, because 9240b57cec5SDimitry Andric // all nodes that have an anonymous namespace as their parent scope are 9250b57cec5SDimitry Andric // guaranteed to be unique and/or are linked to their containing 9260b57cec5SDimitry Andric // DICompileUnit. This decision is an explicit tradeoff of link time versus 9270b57cec5SDimitry Andric // memory usage versus code simplicity and may get revisited in the future. 9280b57cec5SDimitry Andric return DINamespace::get(VMContext, getNonCompileUnitScope(Scope), Name, 9290b57cec5SDimitry Andric ExportSymbols); 9300b57cec5SDimitry Andric } 9310b57cec5SDimitry Andric 9320b57cec5SDimitry Andric DIModule *DIBuilder::createModule(DIScope *Scope, StringRef Name, 9330b57cec5SDimitry Andric StringRef ConfigurationMacros, 9345ffd83dbSDimitry Andric StringRef IncludePath, StringRef APINotesFile, 935e8d8bef9SDimitry Andric DIFile *File, unsigned LineNo, bool IsDecl) { 9365ffd83dbSDimitry Andric return DIModule::get(VMContext, File, getNonCompileUnitScope(Scope), Name, 937e8d8bef9SDimitry Andric ConfigurationMacros, IncludePath, APINotesFile, LineNo, 938e8d8bef9SDimitry Andric IsDecl); 9390b57cec5SDimitry Andric } 9400b57cec5SDimitry Andric 9410b57cec5SDimitry Andric DILexicalBlockFile *DIBuilder::createLexicalBlockFile(DIScope *Scope, 9420b57cec5SDimitry Andric DIFile *File, 9430b57cec5SDimitry Andric unsigned Discriminator) { 9440b57cec5SDimitry Andric return DILexicalBlockFile::get(VMContext, Scope, File, Discriminator); 9450b57cec5SDimitry Andric } 9460b57cec5SDimitry Andric 9470b57cec5SDimitry Andric DILexicalBlock *DIBuilder::createLexicalBlock(DIScope *Scope, DIFile *File, 9480b57cec5SDimitry Andric unsigned Line, unsigned Col) { 9490b57cec5SDimitry Andric // Make these distinct, to avoid merging two lexical blocks on the same 9500b57cec5SDimitry Andric // file/line/column. 9510b57cec5SDimitry Andric return DILexicalBlock::getDistinct(VMContext, getNonCompileUnitScope(Scope), 9520b57cec5SDimitry Andric File, Line, Col); 9530b57cec5SDimitry Andric } 9540b57cec5SDimitry Andric 955*0fca6ea1SDimitry Andric DbgInstPtr DIBuilder::insertDeclare(Value *Storage, DILocalVariable *VarInfo, 9560b57cec5SDimitry Andric DIExpression *Expr, const DILocation *DL, 9570b57cec5SDimitry Andric Instruction *InsertBefore) { 9580b57cec5SDimitry Andric return insertDeclare(Storage, VarInfo, Expr, DL, InsertBefore->getParent(), 9590b57cec5SDimitry Andric InsertBefore); 9600b57cec5SDimitry Andric } 9610b57cec5SDimitry Andric 962*0fca6ea1SDimitry Andric DbgInstPtr DIBuilder::insertDeclare(Value *Storage, DILocalVariable *VarInfo, 9630b57cec5SDimitry Andric DIExpression *Expr, const DILocation *DL, 9640b57cec5SDimitry Andric BasicBlock *InsertAtEnd) { 9650b57cec5SDimitry Andric // If this block already has a terminator then insert this intrinsic before 9660b57cec5SDimitry Andric // the terminator. Otherwise, put it at the end of the block. 9670b57cec5SDimitry Andric Instruction *InsertBefore = InsertAtEnd->getTerminator(); 9680b57cec5SDimitry Andric return insertDeclare(Storage, VarInfo, Expr, DL, InsertAtEnd, InsertBefore); 9690b57cec5SDimitry Andric } 9700b57cec5SDimitry Andric 971*0fca6ea1SDimitry Andric DbgInstPtr DIBuilder::insertDbgAssign(Instruction *LinkedInstr, Value *Val, 972*0fca6ea1SDimitry Andric DILocalVariable *SrcVar, 973*0fca6ea1SDimitry Andric DIExpression *ValExpr, Value *Addr, 974*0fca6ea1SDimitry Andric DIExpression *AddrExpr, 975bdd1243dSDimitry Andric const DILocation *DL) { 976*0fca6ea1SDimitry Andric auto *Link = cast_or_null<DIAssignID>( 977*0fca6ea1SDimitry Andric LinkedInstr->getMetadata(LLVMContext::MD_DIAssignID)); 978*0fca6ea1SDimitry Andric assert(Link && "Linked instruction must have DIAssign metadata attached"); 979*0fca6ea1SDimitry Andric 980*0fca6ea1SDimitry Andric if (M.IsNewDbgInfoFormat) { 981*0fca6ea1SDimitry Andric DbgVariableRecord *DVR = DbgVariableRecord::createDVRAssign( 982*0fca6ea1SDimitry Andric Val, SrcVar, ValExpr, Link, Addr, AddrExpr, DL); 983*0fca6ea1SDimitry Andric BasicBlock *InsertBB = LinkedInstr->getParent(); 984*0fca6ea1SDimitry Andric // Insert after LinkedInstr. 985*0fca6ea1SDimitry Andric BasicBlock::iterator NextIt = std::next(LinkedInstr->getIterator()); 986*0fca6ea1SDimitry Andric Instruction *InsertBefore = NextIt == InsertBB->end() ? nullptr : &*NextIt; 987*0fca6ea1SDimitry Andric insertDbgVariableRecord(DVR, InsertBB, InsertBefore, true); 988*0fca6ea1SDimitry Andric return DVR; 989*0fca6ea1SDimitry Andric } 990*0fca6ea1SDimitry Andric 991bdd1243dSDimitry Andric LLVMContext &Ctx = LinkedInstr->getContext(); 992bdd1243dSDimitry Andric Module *M = LinkedInstr->getModule(); 993bdd1243dSDimitry Andric if (!AssignFn) 994bdd1243dSDimitry Andric AssignFn = Intrinsic::getDeclaration(M, Intrinsic::dbg_assign); 995bdd1243dSDimitry Andric 996bdd1243dSDimitry Andric std::array<Value *, 6> Args = { 997bdd1243dSDimitry Andric MetadataAsValue::get(Ctx, ValueAsMetadata::get(Val)), 998bdd1243dSDimitry Andric MetadataAsValue::get(Ctx, SrcVar), 999bdd1243dSDimitry Andric MetadataAsValue::get(Ctx, ValExpr), 1000bdd1243dSDimitry Andric MetadataAsValue::get(Ctx, Link), 1001bdd1243dSDimitry Andric MetadataAsValue::get(Ctx, ValueAsMetadata::get(Addr)), 1002bdd1243dSDimitry Andric MetadataAsValue::get(Ctx, AddrExpr), 1003bdd1243dSDimitry Andric }; 1004bdd1243dSDimitry Andric 1005bdd1243dSDimitry Andric IRBuilder<> B(Ctx); 1006bdd1243dSDimitry Andric B.SetCurrentDebugLocation(DL); 1007bdd1243dSDimitry Andric 1008bdd1243dSDimitry Andric auto *DVI = cast<DbgAssignIntrinsic>(B.CreateCall(AssignFn, Args)); 1009bdd1243dSDimitry Andric DVI->insertAfter(LinkedInstr); 1010bdd1243dSDimitry Andric return DVI; 1011bdd1243dSDimitry Andric } 1012bdd1243dSDimitry Andric 1013*0fca6ea1SDimitry Andric DbgInstPtr DIBuilder::insertLabel(DILabel *LabelInfo, const DILocation *DL, 10140b57cec5SDimitry Andric Instruction *InsertBefore) { 1015349cc55cSDimitry Andric return insertLabel(LabelInfo, DL, 1016349cc55cSDimitry Andric InsertBefore ? InsertBefore->getParent() : nullptr, 10170b57cec5SDimitry Andric InsertBefore); 10180b57cec5SDimitry Andric } 10190b57cec5SDimitry Andric 1020*0fca6ea1SDimitry Andric DbgInstPtr DIBuilder::insertLabel(DILabel *LabelInfo, const DILocation *DL, 10210b57cec5SDimitry Andric BasicBlock *InsertAtEnd) { 10220b57cec5SDimitry Andric return insertLabel(LabelInfo, DL, InsertAtEnd, nullptr); 10230b57cec5SDimitry Andric } 10240b57cec5SDimitry Andric 1025*0fca6ea1SDimitry Andric DbgInstPtr DIBuilder::insertDbgValueIntrinsic(Value *V, 10260b57cec5SDimitry Andric DILocalVariable *VarInfo, 10270b57cec5SDimitry Andric DIExpression *Expr, 10280b57cec5SDimitry Andric const DILocation *DL, 10290b57cec5SDimitry Andric Instruction *InsertBefore) { 1030*0fca6ea1SDimitry Andric DbgInstPtr DVI = insertDbgValueIntrinsic( 10310b57cec5SDimitry Andric V, VarInfo, Expr, DL, InsertBefore ? InsertBefore->getParent() : nullptr, 10320b57cec5SDimitry Andric InsertBefore); 1033*0fca6ea1SDimitry Andric if (DVI.is<Instruction *>()) 1034*0fca6ea1SDimitry Andric cast<CallInst>(DVI.get<Instruction *>())->setTailCall(); 10355f757f3fSDimitry Andric return DVI; 10360b57cec5SDimitry Andric } 10370b57cec5SDimitry Andric 1038*0fca6ea1SDimitry Andric DbgInstPtr DIBuilder::insertDbgValueIntrinsic(Value *V, 10390b57cec5SDimitry Andric DILocalVariable *VarInfo, 10400b57cec5SDimitry Andric DIExpression *Expr, 10410b57cec5SDimitry Andric const DILocation *DL, 10420b57cec5SDimitry Andric BasicBlock *InsertAtEnd) { 10430b57cec5SDimitry Andric return insertDbgValueIntrinsic(V, VarInfo, Expr, DL, InsertAtEnd, nullptr); 10440b57cec5SDimitry Andric } 10450b57cec5SDimitry Andric 10465ffd83dbSDimitry Andric /// Initialize IRBuilder for inserting dbg.declare and dbg.value intrinsics. 10475ffd83dbSDimitry Andric /// This abstracts over the various ways to specify an insert position. 10485ffd83dbSDimitry Andric static void initIRBuilder(IRBuilder<> &Builder, const DILocation *DL, 10495ffd83dbSDimitry Andric BasicBlock *InsertBB, Instruction *InsertBefore) { 10500b57cec5SDimitry Andric if (InsertBefore) 10515ffd83dbSDimitry Andric Builder.SetInsertPoint(InsertBefore); 10520b57cec5SDimitry Andric else if (InsertBB) 10535ffd83dbSDimitry Andric Builder.SetInsertPoint(InsertBB); 10545ffd83dbSDimitry Andric Builder.SetCurrentDebugLocation(DL); 10550b57cec5SDimitry Andric } 10560b57cec5SDimitry Andric 10570b57cec5SDimitry Andric static Value *getDbgIntrinsicValueImpl(LLVMContext &VMContext, Value *V) { 10580b57cec5SDimitry Andric assert(V && "no value passed to dbg intrinsic"); 10590b57cec5SDimitry Andric return MetadataAsValue::get(VMContext, ValueAsMetadata::get(V)); 10600b57cec5SDimitry Andric } 10610b57cec5SDimitry Andric 10620b57cec5SDimitry Andric static Function *getDeclareIntrin(Module &M) { 106306c3fb27SDimitry Andric return Intrinsic::getDeclaration(&M, Intrinsic::dbg_declare); 10640b57cec5SDimitry Andric } 10650b57cec5SDimitry Andric 1066*0fca6ea1SDimitry Andric DbgInstPtr DIBuilder::insertDbgValueIntrinsic( 106704eeddc0SDimitry Andric llvm::Value *Val, DILocalVariable *VarInfo, DIExpression *Expr, 106804eeddc0SDimitry Andric const DILocation *DL, BasicBlock *InsertBB, Instruction *InsertBefore) { 1069*0fca6ea1SDimitry Andric if (M.IsNewDbgInfoFormat) { 1070*0fca6ea1SDimitry Andric DbgVariableRecord *DVR = 1071*0fca6ea1SDimitry Andric DbgVariableRecord::createDbgVariableRecord(Val, VarInfo, Expr, DL); 1072*0fca6ea1SDimitry Andric insertDbgVariableRecord(DVR, InsertBB, InsertBefore); 1073*0fca6ea1SDimitry Andric return DVR; 1074*0fca6ea1SDimitry Andric } 1075*0fca6ea1SDimitry Andric 107604eeddc0SDimitry Andric if (!ValueFn) 107704eeddc0SDimitry Andric ValueFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_value); 107804eeddc0SDimitry Andric return insertDbgIntrinsic(ValueFn, Val, VarInfo, Expr, DL, InsertBB, 107904eeddc0SDimitry Andric InsertBefore); 108004eeddc0SDimitry Andric } 108104eeddc0SDimitry Andric 1082*0fca6ea1SDimitry Andric DbgInstPtr DIBuilder::insertDeclare(Value *Storage, DILocalVariable *VarInfo, 10830b57cec5SDimitry Andric DIExpression *Expr, const DILocation *DL, 1084349cc55cSDimitry Andric BasicBlock *InsertBB, 1085349cc55cSDimitry Andric Instruction *InsertBefore) { 10860b57cec5SDimitry Andric assert(VarInfo && "empty or invalid DILocalVariable* passed to dbg.declare"); 10870b57cec5SDimitry Andric assert(DL && "Expected debug loc"); 10880b57cec5SDimitry Andric assert(DL->getScope()->getSubprogram() == 10890b57cec5SDimitry Andric VarInfo->getScope()->getSubprogram() && 10900b57cec5SDimitry Andric "Expected matching subprograms"); 1091*0fca6ea1SDimitry Andric 1092*0fca6ea1SDimitry Andric if (M.IsNewDbgInfoFormat) { 1093*0fca6ea1SDimitry Andric DbgVariableRecord *DVR = 1094*0fca6ea1SDimitry Andric DbgVariableRecord::createDVRDeclare(Storage, VarInfo, Expr, DL); 1095*0fca6ea1SDimitry Andric insertDbgVariableRecord(DVR, InsertBB, InsertBefore); 1096*0fca6ea1SDimitry Andric return DVR; 1097*0fca6ea1SDimitry Andric } 1098*0fca6ea1SDimitry Andric 10990b57cec5SDimitry Andric if (!DeclareFn) 11000b57cec5SDimitry Andric DeclareFn = getDeclareIntrin(M); 11010b57cec5SDimitry Andric 11020b57cec5SDimitry Andric trackIfUnresolved(VarInfo); 11030b57cec5SDimitry Andric trackIfUnresolved(Expr); 11040b57cec5SDimitry Andric Value *Args[] = {getDbgIntrinsicValueImpl(VMContext, Storage), 11050b57cec5SDimitry Andric MetadataAsValue::get(VMContext, VarInfo), 11060b57cec5SDimitry Andric MetadataAsValue::get(VMContext, Expr)}; 11070b57cec5SDimitry Andric 11085ffd83dbSDimitry Andric IRBuilder<> B(DL->getContext()); 11095ffd83dbSDimitry Andric initIRBuilder(B, DL, InsertBB, InsertBefore); 11100b57cec5SDimitry Andric return B.CreateCall(DeclareFn, Args); 11110b57cec5SDimitry Andric } 11120b57cec5SDimitry Andric 1113*0fca6ea1SDimitry Andric void DIBuilder::insertDbgVariableRecord(DbgVariableRecord *DVR, 1114*0fca6ea1SDimitry Andric BasicBlock *InsertBB, 1115*0fca6ea1SDimitry Andric Instruction *InsertBefore, 1116*0fca6ea1SDimitry Andric bool InsertAtHead) { 1117*0fca6ea1SDimitry Andric assert(InsertBefore || InsertBB); 1118*0fca6ea1SDimitry Andric trackIfUnresolved(DVR->getVariable()); 1119*0fca6ea1SDimitry Andric trackIfUnresolved(DVR->getExpression()); 1120*0fca6ea1SDimitry Andric if (DVR->isDbgAssign()) 1121*0fca6ea1SDimitry Andric trackIfUnresolved(DVR->getAddressExpression()); 1122*0fca6ea1SDimitry Andric 1123*0fca6ea1SDimitry Andric BasicBlock::iterator InsertPt; 1124*0fca6ea1SDimitry Andric if (InsertBB && InsertBefore) 1125*0fca6ea1SDimitry Andric InsertPt = InsertBefore->getIterator(); 1126*0fca6ea1SDimitry Andric else if (InsertBB) 1127*0fca6ea1SDimitry Andric InsertPt = InsertBB->end(); 1128*0fca6ea1SDimitry Andric InsertPt.setHeadBit(InsertAtHead); 1129*0fca6ea1SDimitry Andric InsertBB->insertDbgRecordBefore(DVR, InsertPt); 1130*0fca6ea1SDimitry Andric } 1131*0fca6ea1SDimitry Andric 113204eeddc0SDimitry Andric Instruction *DIBuilder::insertDbgIntrinsic(llvm::Function *IntrinsicFn, 113304eeddc0SDimitry Andric Value *V, DILocalVariable *VarInfo, 113404eeddc0SDimitry Andric DIExpression *Expr, 113504eeddc0SDimitry Andric const DILocation *DL, 113604eeddc0SDimitry Andric BasicBlock *InsertBB, 113704eeddc0SDimitry Andric Instruction *InsertBefore) { 113804eeddc0SDimitry Andric assert(IntrinsicFn && "must pass a non-null intrinsic function"); 113904eeddc0SDimitry Andric assert(V && "must pass a value to a dbg intrinsic"); 114004eeddc0SDimitry Andric assert(VarInfo && 114104eeddc0SDimitry Andric "empty or invalid DILocalVariable* passed to debug intrinsic"); 11420b57cec5SDimitry Andric assert(DL && "Expected debug loc"); 11430b57cec5SDimitry Andric assert(DL->getScope()->getSubprogram() == 11440b57cec5SDimitry Andric VarInfo->getScope()->getSubprogram() && 11450b57cec5SDimitry Andric "Expected matching subprograms"); 11460b57cec5SDimitry Andric 11470b57cec5SDimitry Andric trackIfUnresolved(VarInfo); 11480b57cec5SDimitry Andric trackIfUnresolved(Expr); 11490b57cec5SDimitry Andric Value *Args[] = {getDbgIntrinsicValueImpl(VMContext, V), 11500b57cec5SDimitry Andric MetadataAsValue::get(VMContext, VarInfo), 11510b57cec5SDimitry Andric MetadataAsValue::get(VMContext, Expr)}; 11520b57cec5SDimitry Andric 11535ffd83dbSDimitry Andric IRBuilder<> B(DL->getContext()); 11545ffd83dbSDimitry Andric initIRBuilder(B, DL, InsertBB, InsertBefore); 115504eeddc0SDimitry Andric return B.CreateCall(IntrinsicFn, Args); 11560b57cec5SDimitry Andric } 11570b57cec5SDimitry Andric 1158*0fca6ea1SDimitry Andric DbgInstPtr DIBuilder::insertLabel(DILabel *LabelInfo, const DILocation *DL, 1159349cc55cSDimitry Andric BasicBlock *InsertBB, 1160349cc55cSDimitry Andric Instruction *InsertBefore) { 11610b57cec5SDimitry Andric assert(LabelInfo && "empty or invalid DILabel* passed to dbg.label"); 11620b57cec5SDimitry Andric assert(DL && "Expected debug loc"); 11630b57cec5SDimitry Andric assert(DL->getScope()->getSubprogram() == 11640b57cec5SDimitry Andric LabelInfo->getScope()->getSubprogram() && 11650b57cec5SDimitry Andric "Expected matching subprograms"); 1166*0fca6ea1SDimitry Andric 1167*0fca6ea1SDimitry Andric trackIfUnresolved(LabelInfo); 1168*0fca6ea1SDimitry Andric if (M.IsNewDbgInfoFormat) { 1169*0fca6ea1SDimitry Andric DbgLabelRecord *DLR = new DbgLabelRecord(LabelInfo, DL); 1170*0fca6ea1SDimitry Andric if (InsertBB && InsertBefore) 1171*0fca6ea1SDimitry Andric InsertBB->insertDbgRecordBefore(DLR, InsertBefore->getIterator()); 1172*0fca6ea1SDimitry Andric else if (InsertBB) 1173*0fca6ea1SDimitry Andric InsertBB->insertDbgRecordBefore(DLR, InsertBB->end()); 1174*0fca6ea1SDimitry Andric return DLR; 1175*0fca6ea1SDimitry Andric } 1176*0fca6ea1SDimitry Andric 11770b57cec5SDimitry Andric if (!LabelFn) 11780b57cec5SDimitry Andric LabelFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_label); 11790b57cec5SDimitry Andric 11800b57cec5SDimitry Andric Value *Args[] = {MetadataAsValue::get(VMContext, LabelInfo)}; 11810b57cec5SDimitry Andric 11825ffd83dbSDimitry Andric IRBuilder<> B(DL->getContext()); 11835ffd83dbSDimitry Andric initIRBuilder(B, DL, InsertBB, InsertBefore); 11840b57cec5SDimitry Andric return B.CreateCall(LabelFn, Args); 11850b57cec5SDimitry Andric } 11860b57cec5SDimitry Andric 1187349cc55cSDimitry Andric void DIBuilder::replaceVTableHolder(DICompositeType *&T, DIType *VTableHolder) { 11880b57cec5SDimitry Andric { 11890b57cec5SDimitry Andric TypedTrackingMDRef<DICompositeType> N(T); 11900b57cec5SDimitry Andric N->replaceVTableHolder(VTableHolder); 11910b57cec5SDimitry Andric T = N.get(); 11920b57cec5SDimitry Andric } 11930b57cec5SDimitry Andric 11940b57cec5SDimitry Andric // If this didn't create a self-reference, just return. 11950b57cec5SDimitry Andric if (T != VTableHolder) 11960b57cec5SDimitry Andric return; 11970b57cec5SDimitry Andric 11980b57cec5SDimitry Andric // Look for unresolved operands. T will drop RAUW support, orphaning any 11990b57cec5SDimitry Andric // cycles underneath it. 12000b57cec5SDimitry Andric if (T->isResolved()) 12010b57cec5SDimitry Andric for (const MDOperand &O : T->operands()) 12020b57cec5SDimitry Andric if (auto *N = dyn_cast_or_null<MDNode>(O)) 12030b57cec5SDimitry Andric trackIfUnresolved(N); 12040b57cec5SDimitry Andric } 12050b57cec5SDimitry Andric 12060b57cec5SDimitry Andric void DIBuilder::replaceArrays(DICompositeType *&T, DINodeArray Elements, 12070b57cec5SDimitry Andric DINodeArray TParams) { 12080b57cec5SDimitry Andric { 12090b57cec5SDimitry Andric TypedTrackingMDRef<DICompositeType> N(T); 12100b57cec5SDimitry Andric if (Elements) 12110b57cec5SDimitry Andric N->replaceElements(Elements); 12120b57cec5SDimitry Andric if (TParams) 12130b57cec5SDimitry Andric N->replaceTemplateParams(DITemplateParameterArray(TParams)); 12140b57cec5SDimitry Andric T = N.get(); 12150b57cec5SDimitry Andric } 12160b57cec5SDimitry Andric 12170b57cec5SDimitry Andric // If T isn't resolved, there's no problem. 12180b57cec5SDimitry Andric if (!T->isResolved()) 12190b57cec5SDimitry Andric return; 12200b57cec5SDimitry Andric 12210b57cec5SDimitry Andric // If T is resolved, it may be due to a self-reference cycle. Track the 12220b57cec5SDimitry Andric // arrays explicitly if they're unresolved, or else the cycles will be 12230b57cec5SDimitry Andric // orphaned. 12240b57cec5SDimitry Andric if (Elements) 12250b57cec5SDimitry Andric trackIfUnresolved(Elements.get()); 12260b57cec5SDimitry Andric if (TParams) 12270b57cec5SDimitry Andric trackIfUnresolved(TParams.get()); 12280b57cec5SDimitry Andric } 1229