xref: /freebsd-src/contrib/llvm-project/llvm/lib/IR/DIBuilder.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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