1//===- DebugInfo.cpp - Debug Information Helper Classes -------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements the helper classes used to build and interpret debug
10// information in LLVM IR form.
11//
12//===----------------------------------------------------------------------===//
13
14#include "llvm-c/DebugInfo.h"
15#include "LLVMContextImpl.h"
16#include "llvm/ADT/APSInt.h"
17#include "llvm/ADT/DenseMap.h"
18#include "llvm/ADT/DenseSet.h"
19#include "llvm/ADT/STLExtras.h"
20#include "llvm/ADT/SmallPtrSet.h"
21#include "llvm/ADT/SmallVector.h"
22#include "llvm/ADT/StringRef.h"
23#include "llvm/IR/BasicBlock.h"
24#include "llvm/IR/Constants.h"
25#include "llvm/IR/DIBuilder.h"
26#include "llvm/IR/DebugInfo.h"
27#include "llvm/IR/DebugInfoMetadata.h"
28#include "llvm/IR/DebugLoc.h"
29#include "llvm/IR/DebugProgramInstruction.h"
30#include "llvm/IR/Function.h"
31#include "llvm/IR/GVMaterializer.h"
32#include "llvm/IR/Instruction.h"
33#include "llvm/IR/IntrinsicInst.h"
34#include "llvm/IR/LLVMContext.h"
35#include "llvm/IR/Metadata.h"
36#include "llvm/IR/Module.h"
37#include "llvm/IR/PassManager.h"
38#include "llvm/Support/Casting.h"
39#include "llvm/Support/TimeProfiler.h"
40#include <algorithm>
41#include <cassert>
42#include <optional>
43
44using namespace llvm;
45using namespace llvm::at;
46using namespace llvm::dwarf;
47
48TinyPtrVector<DbgVariableRecord *> llvm::findDVRDeclares(Value *V) {
49 // This function is hot. Check whether the value has any metadata to avoid a
50 // DenseMap lookup. This check is a bitfield datamember lookup.
51 if (!V->isUsedByMetadata())
52 return {};
53 auto *L = ValueAsMetadata::getIfExists(V);
54 if (!L)
55 return {};
56
57 TinyPtrVector<DbgVariableRecord *> Declares;
58 for (DbgVariableRecord *DVR : L->getAllDbgVariableRecordUsers())
59 if (DVR->getType() == DbgVariableRecord::LocationType::Declare)
60 Declares.push_back(NewVal: DVR);
61
62 return Declares;
63}
64
65TinyPtrVector<DbgVariableRecord *> llvm::findDVRDeclareValues(Value *V) {
66 // This function is hot. Check whether the value has any metadata to avoid a
67 // DenseMap lookup. This check is a bitfield datamember lookup.
68 if (!V->isUsedByMetadata())
69 return {};
70 auto *L = ValueAsMetadata::getIfExists(V);
71 if (!L)
72 return {};
73
74 TinyPtrVector<DbgVariableRecord *> DEclareValues;
75 for (DbgVariableRecord *DVR : L->getAllDbgVariableRecordUsers())
76 if (DVR->getType() == DbgVariableRecord::LocationType::DeclareValue)
77 DEclareValues.push_back(NewVal: DVR);
78
79 return DEclareValues;
80}
81
82TinyPtrVector<DbgVariableRecord *> llvm::findDVRValues(Value *V) {
83 // This function is hot. Check whether the value has any metadata to avoid a
84 // DenseMap lookup. This check is a bitfield datamember lookup.
85 if (!V->isUsedByMetadata())
86 return {};
87 auto *L = ValueAsMetadata::getIfExists(V);
88 if (!L)
89 return {};
90
91 TinyPtrVector<DbgVariableRecord *> Values;
92 for (DbgVariableRecord *DVR : L->getAllDbgVariableRecordUsers())
93 if (DVR->isValueOfVariable())
94 Values.push_back(NewVal: DVR);
95
96 return Values;
97}
98
99template <bool DbgAssignAndValuesOnly>
100static void
101findDbgIntrinsics(Value *V,
102 SmallVectorImpl<DbgVariableRecord *> &DbgVariableRecords) {
103 // This function is hot. Check whether the value has any metadata to avoid a
104 // DenseMap lookup.
105 if (!V->isUsedByMetadata())
106 return;
107
108 // TODO: If this value appears multiple times in a DIArgList, we should still
109 // only add the owning dbg.value once; use this set to track ArgListUsers.
110 // This behaviour can be removed when we can automatically remove duplicates.
111 // V will also appear twice in a dbg.assign if its used in the both the value
112 // and address components.
113 SmallPtrSet<DbgVariableRecord *, 4> EncounteredDbgVariableRecords;
114
115 /// Append users of MetadataAsValue(MD).
116 auto AppendUsers = [&EncounteredDbgVariableRecords,
117 &DbgVariableRecords](Metadata *MD) {
118 // Get DbgVariableRecords that use this as a single value.
119 if (LocalAsMetadata *L = dyn_cast<LocalAsMetadata>(Val: MD)) {
120 for (DbgVariableRecord *DVR : L->getAllDbgVariableRecordUsers()) {
121 if (!DbgAssignAndValuesOnly || DVR->isDbgValue() || DVR->isDbgAssign())
122 if (EncounteredDbgVariableRecords.insert(Ptr: DVR).second)
123 DbgVariableRecords.push_back(Elt: DVR);
124 }
125 }
126 };
127
128 if (auto *L = LocalAsMetadata::getIfExists(Local: V)) {
129 AppendUsers(L);
130 for (Metadata *AL : L->getAllArgListUsers()) {
131 AppendUsers(AL);
132 DIArgList *DI = cast<DIArgList>(Val: AL);
133 for (DbgVariableRecord *DVR : DI->getAllDbgVariableRecordUsers())
134 if (!DbgAssignAndValuesOnly || DVR->isDbgValue() || DVR->isDbgAssign())
135 if (EncounteredDbgVariableRecords.insert(Ptr: DVR).second)
136 DbgVariableRecords.push_back(Elt: DVR);
137 }
138 }
139}
140
141void llvm::findDbgValues(
142 Value *V, SmallVectorImpl<DbgVariableRecord *> &DbgVariableRecords) {
143 findDbgIntrinsics</*DbgAssignAndValuesOnly=*/true>(V, DbgVariableRecords);
144}
145
146void llvm::findDbgUsers(
147 Value *V, SmallVectorImpl<DbgVariableRecord *> &DbgVariableRecords) {
148 findDbgIntrinsics</*DbgAssignAndValuesOnly=*/false>(V, DbgVariableRecords);
149}
150
151DISubprogram *llvm::getDISubprogram(const MDNode *Scope) {
152 if (auto *LocalScope = dyn_cast_or_null<DILocalScope>(Val: Scope))
153 return LocalScope->getSubprogram();
154 return nullptr;
155}
156
157DebugLoc llvm::getDebugValueLoc(DbgVariableRecord *DVR) {
158 // Original dbg.declare must have a location.
159 const DebugLoc &DeclareLoc = DVR->getDebugLoc();
160 MDNode *Scope = DeclareLoc.getScope();
161 DILocation *InlinedAt = DeclareLoc.getInlinedAt();
162 // Because no machine insts can come from debug intrinsics, only the scope
163 // and inlinedAt is significant. Zero line numbers are used in case this
164 // DebugLoc leaks into any adjacent instructions. Produce an unknown location
165 // with the correct scope / inlinedAt fields.
166 return DILocation::get(Context&: DVR->getContext(), Line: 0, Column: 0, Scope, InlinedAt);
167}
168
169//===----------------------------------------------------------------------===//
170// DebugInfoFinder implementations.
171//===----------------------------------------------------------------------===//
172
173void DebugInfoFinder::reset() {
174 CUs.clear();
175 SPs.clear();
176 GVs.clear();
177 TYs.clear();
178 Scopes.clear();
179 Macros.clear();
180 NodesSeen.clear();
181}
182
183void DebugInfoFinder::processModule(const Module &M) {
184 for (auto *CU : M.debug_compile_units())
185 processCompileUnit(CU);
186 for (auto &F : M.functions()) {
187 if (auto *SP = cast_or_null<DISubprogram>(Val: F.getSubprogram()))
188 processSubprogram(SP);
189 // There could be subprograms from inlined functions referenced from
190 // instructions only. Walk the function to find them.
191 for (const BasicBlock &BB : F)
192 for (const Instruction &I : BB)
193 processInstruction(M, I);
194 }
195}
196
197void DebugInfoFinder::processCompileUnit(DICompileUnit *CU) {
198 if (!addCompileUnit(CU))
199 return;
200 for (auto *GVE : CU->getGlobalVariables())
201 processGlobalVariableExpression(GVE);
202 for (auto *ET : CU->getEnumTypes())
203 processType(DT: ET);
204 for (auto *RT : CU->getRetainedTypes())
205 if (auto *T = dyn_cast<DIType>(Val: RT))
206 processType(DT: T);
207 else
208 processSubprogram(SP: cast<DISubprogram>(Val: RT));
209 for (auto *Import : CU->getImportedEntities())
210 processImportedEntity(Import);
211 for (auto *Macro : CU->getMacros())
212 processMacroNode(Macro, CurrentMacroFile: nullptr);
213}
214
215void DebugInfoFinder::processGlobalVariableExpression(
216 DIGlobalVariableExpression *GVE) {
217 if (!addGlobalVariable(DIG: GVE))
218 return;
219 auto *GV = GVE->getVariable();
220 processScope(Scope: GV->getScope());
221 processType(DT: GV->getType());
222}
223
224void DebugInfoFinder::processInstruction(const Module &M,
225 const Instruction &I) {
226 if (auto *DVI = dyn_cast<DbgVariableIntrinsic>(Val: &I))
227 processVariable(DVI: DVI->getVariable());
228
229 if (auto DbgLoc = I.getDebugLoc())
230 processLocation(M, Loc: DbgLoc.get());
231
232 for (const DbgRecord &DPR : I.getDbgRecordRange())
233 processDbgRecord(M, DR: DPR);
234}
235
236void DebugInfoFinder::processLocation(const Module &M, const DILocation *Loc) {
237 if (!Loc)
238 return;
239 processScope(Scope: Loc->getScope());
240 processLocation(M, Loc: Loc->getInlinedAt());
241}
242
243void DebugInfoFinder::processDbgRecord(const Module &M, const DbgRecord &DR) {
244 if (const DbgVariableRecord *DVR = dyn_cast<const DbgVariableRecord>(Val: &DR))
245 processVariable(DVI: DVR->getVariable());
246 processLocation(M, Loc: DR.getDebugLoc().get());
247}
248
249void DebugInfoFinder::processVariable(DIVariable *DV) {
250 if (auto *DLV = dyn_cast_or_null<DILocalVariable>(Val: DV))
251 processVariable(DVI: DLV);
252}
253
254void DebugInfoFinder::processType(DIType *DT) {
255 if (!addType(DT))
256 return;
257 processScope(Scope: DT->getScope());
258 if (auto *ST = dyn_cast<DISubroutineType>(Val: DT)) {
259 for (DIType *Ref : ST->getTypeArray())
260 processType(DT: Ref);
261 return;
262 }
263 if (auto *DCT = dyn_cast<DICompositeType>(Val: DT)) {
264 processType(DT: DCT->getBaseType());
265 processType(DT: DCT->getVTableHolder());
266 processType(DT: DCT->getDiscriminator());
267 processType(DT: DCT->getSpecification());
268 processVariable(DV: DCT->getDataLocation());
269 processVariable(DV: DCT->getAssociated());
270 processVariable(DV: DCT->getAllocated());
271 for (Metadata *D : DCT->getElements()) {
272 if (auto *T = dyn_cast<DIType>(Val: D))
273 processType(DT: T);
274 else if (auto *SP = dyn_cast<DISubprogram>(Val: D))
275 processSubprogram(SP);
276 else if (auto *P = dyn_cast<DIProperty>(Val: D))
277 processType(DT: P->getType());
278 else if (auto *SR = dyn_cast_or_null<DISubrange>(Val: D)) {
279 auto VisitBound = [&](DISubrange::BoundType Bound) {
280 if (auto *BV = dyn_cast_if_present<DIVariable *>(Val&: Bound))
281 processVariable(DV: BV);
282 };
283 VisitBound(SR->getLowerBound());
284 VisitBound(SR->getCount());
285 VisitBound(SR->getUpperBound());
286 VisitBound(SR->getStride());
287 } else if (auto *GSR = dyn_cast_or_null<DIGenericSubrange>(Val: D)) {
288 auto VisitBound = [&](DIGenericSubrange::BoundType Bound) {
289 if (auto *BV = dyn_cast_if_present<DIVariable *>(Val&: Bound))
290 processVariable(DV: BV);
291 };
292 VisitBound(GSR->getLowerBound());
293 VisitBound(GSR->getCount());
294 VisitBound(GSR->getUpperBound());
295 VisitBound(GSR->getStride());
296 }
297 }
298 return;
299 }
300 if (auto *ST = dyn_cast<DIStringType>(Val: DT)) {
301 processVariable(DV: ST->getStringLength());
302 return;
303 }
304 if (auto *SRT = dyn_cast<DISubrangeType>(Val: DT)) {
305 processType(DT: SRT->getBaseType());
306 auto VisitBound = [&](DISubrangeType::BoundType Bound) {
307 if (auto *V = dyn_cast_if_present<DIVariable *>(Val&: Bound))
308 processVariable(DV: V);
309 else if (auto *T = dyn_cast_if_present<DIDerivedType *>(Val&: Bound))
310 processType(DT: T);
311 };
312 VisitBound(SRT->getLowerBound());
313 VisitBound(SRT->getUpperBound());
314 VisitBound(SRT->getStride());
315 VisitBound(SRT->getBias());
316 return;
317 }
318 if (auto *DDT = dyn_cast<DIDerivedType>(Val: DT)) {
319 processType(DT: DDT->getBaseType());
320 }
321}
322
323void DebugInfoFinder::processImportedEntity(const DIImportedEntity *Import) {
324 auto *Entity = Import->getEntity();
325 if (auto *T = dyn_cast<DIType>(Val: Entity))
326 processType(DT: T);
327 else if (auto *SP = dyn_cast<DISubprogram>(Val: Entity))
328 processSubprogram(SP);
329 else if (auto *NS = dyn_cast<DINamespace>(Val: Entity))
330 processScope(Scope: NS->getScope());
331 else if (auto *M = dyn_cast<DIModule>(Val: Entity))
332 processScope(Scope: M->getScope());
333}
334
335/// Process a macro debug info node (DIMacroNode).
336///
337/// A DIMacroNode is one of two types:
338/// - DIMacro: A single macro definition. Add it to the Macros list along with
339/// its containing DIMacroFile.
340/// - DIMacroFile: A file containing macros. Recursively process all nested
341/// macro nodes within it (avoiding duplicates by tracking visited nodes).
342void DebugInfoFinder::processMacroNode(DIMacroNode *Macro,
343 DIMacroFile *CurrentMacroFile) {
344 if (!Macro)
345 return;
346
347 if (auto *M = dyn_cast<DIMacro>(Val: Macro)) {
348 addMacro(Macro: M, MacroFile: CurrentMacroFile);
349 return;
350 }
351
352 auto *MF = dyn_cast<DIMacroFile>(Val: Macro);
353 assert(MF &&
354 "Expected a DIMacroFile (it can't be any other type at this point)");
355
356 // Check if we've already seen this macro file to avoid infinite recursion
357 if (!NodesSeen.insert(Ptr: MF).second)
358 return;
359
360 // Recursively process nested macros in the macro file
361 for (auto *Element : MF->getElements())
362 processMacroNode(Macro: Element, CurrentMacroFile: MF);
363}
364
365void DebugInfoFinder::processScope(DIScope *Scope) {
366 if (!Scope)
367 return;
368 if (auto *Ty = dyn_cast<DIType>(Val: Scope)) {
369 processType(DT: Ty);
370 return;
371 }
372 if (auto *CU = dyn_cast<DICompileUnit>(Val: Scope)) {
373 addCompileUnit(CU);
374 return;
375 }
376 if (auto *SP = dyn_cast<DISubprogram>(Val: Scope)) {
377 processSubprogram(SP);
378 return;
379 }
380 if (!addScope(Scope))
381 return;
382 if (auto *LB = dyn_cast<DILexicalBlockBase>(Val: Scope)) {
383 processScope(Scope: LB->getScope());
384 } else if (auto *NS = dyn_cast<DINamespace>(Val: Scope)) {
385 processScope(Scope: NS->getScope());
386 } else if (auto *M = dyn_cast<DIModule>(Val: Scope)) {
387 processScope(Scope: M->getScope());
388 }
389}
390
391void DebugInfoFinder::processSubprogram(DISubprogram *SP) {
392 if (!addSubprogram(SP))
393 return;
394 processScope(Scope: SP->getScope());
395 // Some of the users, e.g. CloneFunctionInto / CloneModule, need to set up a
396 // ValueMap containing identity mappings for all of the DICompileUnit's, not
397 // just DISubprogram's, referenced from anywhere within the Function being
398 // cloned prior to calling MapMetadata / RemapInstruction to avoid their
399 // duplication later as DICompileUnit's are also directly referenced by
400 // llvm.dbg.cu list. Therefore we need to collect DICompileUnit's here as
401 // well. Also, DICompileUnit's may reference DISubprogram's too and therefore
402 // need to be at least looked through.
403 processCompileUnit(CU: SP->getUnit());
404 processType(DT: SP->getType());
405 for (auto *Element : SP->getTemplateParams()) {
406 if (auto *TType = dyn_cast<DITemplateTypeParameter>(Val: Element)) {
407 processType(DT: TType->getType());
408 } else if (auto *TVal = dyn_cast<DITemplateValueParameter>(Val: Element)) {
409 processType(DT: TVal->getType());
410 }
411 }
412
413 SP->forEachRetainedNode(
414 FuncLV: [this](DILocalVariable *LV) { processVariable(DVI: LV); }, FuncLabel: [](DILabel *L) {},
415 FuncIE: [this](DIImportedEntity *IE) { processImportedEntity(Import: IE); },
416 FuncType: [this](DIType *T) { processType(DT: T); },
417 FuncGVE: [this](auto *GVE) { return processGlobalVariableExpression(GVE); });
418
419 // Not reached through the scope, type, or retained nodes.
420 if (DISubprogram *Decl = SP->getDeclaration())
421 processSubprogram(SP: Decl);
422}
423
424void DebugInfoFinder::processVariable(const DILocalVariable *DV) {
425 if (!NodesSeen.insert(Ptr: DV).second)
426 return;
427 processScope(Scope: DV->getScope());
428 processType(DT: DV->getType());
429}
430
431bool DebugInfoFinder::addType(DIType *DT) {
432 if (!DT)
433 return false;
434
435 if (!NodesSeen.insert(Ptr: DT).second)
436 return false;
437
438 TYs.push_back(Elt: DT);
439 return true;
440}
441
442bool DebugInfoFinder::addCompileUnit(DICompileUnit *CU) {
443 if (!CU)
444 return false;
445 if (!NodesSeen.insert(Ptr: CU).second)
446 return false;
447
448 CUs.push_back(Elt: CU);
449 return true;
450}
451
452bool DebugInfoFinder::addGlobalVariable(DIGlobalVariableExpression *DIG) {
453 if (!NodesSeen.insert(Ptr: DIG).second)
454 return false;
455
456 GVs.push_back(Elt: DIG);
457 return true;
458}
459
460bool DebugInfoFinder::addSubprogram(DISubprogram *SP) {
461 if (!SP)
462 return false;
463
464 if (!NodesSeen.insert(Ptr: SP).second)
465 return false;
466
467 SPs.push_back(Elt: SP);
468 return true;
469}
470
471bool DebugInfoFinder::addScope(DIScope *Scope) {
472 if (!Scope)
473 return false;
474 // FIXME: Ocaml binding generates a scope with no content, we treat it
475 // as null for now.
476 if (Scope->getNumOperands() == 0)
477 return false;
478 if (!NodesSeen.insert(Ptr: Scope).second)
479 return false;
480 Scopes.push_back(Elt: Scope);
481 return true;
482}
483
484bool DebugInfoFinder::addMacro(DIMacro *Macro, DIMacroFile *MacroFile) {
485 if (!Macro)
486 return false;
487
488 if (!NodesSeen.insert(Ptr: Macro).second)
489 return false;
490
491 Macros.push_back(Elt: std::make_pair(x&: Macro, y&: MacroFile));
492 return true;
493}
494
495/// Recursively handle DILocations in followup metadata etc.
496///
497/// TODO: If for example a followup loop metadata would reference itself this
498/// function would go into infinite recursion. We do not expect such cycles in
499/// the loop metadata (except for the self-referencing first element
500/// "LoopID"). However, we could at least handle such situations more gracefully
501/// somehow (e.g. by keeping track of visited nodes and dropping metadata).
502static Metadata *updateLoopMetadataDebugLocationsRecursive(
503 Metadata *MetadataIn, function_ref<Metadata *(Metadata *)> Updater) {
504 const MDTuple *M = dyn_cast_or_null<MDTuple>(Val: MetadataIn);
505 // The loop metadata options should start with a MDString.
506 if (!M || M->getNumOperands() < 1 || !isa<MDString>(Val: M->getOperand(I: 0)))
507 return MetadataIn;
508
509 bool Updated = false;
510 SmallVector<Metadata *, 4> MDs{M->getOperand(I: 0)};
511 for (Metadata *MD : llvm::drop_begin(RangeOrContainer: M->operands())) {
512 if (!MD) {
513 MDs.push_back(Elt: nullptr);
514 continue;
515 }
516 Metadata *NewMD =
517 Updater(updateLoopMetadataDebugLocationsRecursive(MetadataIn: MD, Updater));
518 if (NewMD)
519 MDs.push_back(Elt: NewMD);
520 Updated |= NewMD != MD;
521 }
522
523 assert(!M->isDistinct() && "M should not be distinct.");
524 return Updated ? MDNode::get(Context&: M->getContext(), MDs) : MetadataIn;
525}
526
527static MDNode *updateLoopMetadataDebugLocationsImpl(
528 MDNode *OrigLoopID, function_ref<Metadata *(Metadata *)> Updater) {
529 assert(OrigLoopID && OrigLoopID->getNumOperands() > 0 &&
530 "Loop ID needs at least one operand");
531 assert(OrigLoopID && OrigLoopID->getOperand(0).get() == OrigLoopID &&
532 "Loop ID should refer to itself");
533
534 // Save space for the self-referential LoopID.
535 SmallVector<Metadata *, 4> MDs = {nullptr};
536
537 for (Metadata *MD : llvm::drop_begin(RangeOrContainer: OrigLoopID->operands())) {
538 if (!MD)
539 MDs.push_back(Elt: nullptr);
540 else if (Metadata *NewMD = Updater(
541 updateLoopMetadataDebugLocationsRecursive(MetadataIn: MD, Updater)))
542 MDs.push_back(Elt: NewMD);
543 }
544
545 MDNode *NewLoopID = MDNode::getDistinct(Context&: OrigLoopID->getContext(), MDs);
546 // Insert the self-referential LoopID.
547 NewLoopID->replaceOperandWith(I: 0, New: NewLoopID);
548 return NewLoopID;
549}
550
551void llvm::updateLoopMetadataDebugLocations(
552 Instruction &I, function_ref<Metadata *(Metadata *)> Updater) {
553 MDNode *OrigLoopID = I.getMetadata(KindID: LLVMContext::MD_loop);
554 if (!OrigLoopID)
555 return;
556 MDNode *NewLoopID = updateLoopMetadataDebugLocationsImpl(OrigLoopID, Updater);
557 I.setMetadata(KindID: LLVMContext::MD_loop, Node: NewLoopID);
558}
559
560/// Return true if a node is a DILocation or if a DILocation is
561/// indirectly referenced by one of the node's children.
562static bool isDILocationReachable(SmallPtrSetImpl<Metadata *> &Visited,
563 SmallPtrSetImpl<Metadata *> &Reachable,
564 Metadata *MD) {
565 MDNode *N = dyn_cast_or_null<MDNode>(Val: MD);
566 if (!N)
567 return false;
568 if (isa<DILocation>(Val: N) || Reachable.count(Ptr: N))
569 return true;
570 if (!Visited.insert(Ptr: N).second)
571 return false;
572 for (auto &OpIt : N->operands()) {
573 Metadata *Op = OpIt.get();
574 if (isDILocationReachable(Visited, Reachable, MD: Op)) {
575 // Don't return just yet as we want to visit all MD's children to
576 // initialize DILocationReachable in stripDebugLocFromLoopID
577 Reachable.insert(Ptr: N);
578 }
579 }
580 return Reachable.count(Ptr: N);
581}
582
583static bool isAllDILocation(SmallPtrSetImpl<Metadata *> &Visited,
584 SmallPtrSetImpl<Metadata *> &AllDILocation,
585 const SmallPtrSetImpl<Metadata *> &DIReachable,
586 Metadata *MD) {
587 MDNode *N = dyn_cast_or_null<MDNode>(Val: MD);
588 if (!N)
589 return false;
590 if (isa<DILocation>(Val: N) || AllDILocation.count(Ptr: N))
591 return true;
592 if (!DIReachable.count(Ptr: N))
593 return false;
594 if (!Visited.insert(Ptr: N).second)
595 return false;
596 for (auto &OpIt : N->operands()) {
597 Metadata *Op = OpIt.get();
598 if (Op == MD)
599 continue;
600 if (!isAllDILocation(Visited, AllDILocation, DIReachable, MD: Op)) {
601 return false;
602 }
603 }
604 AllDILocation.insert(Ptr: N);
605 return true;
606}
607
608static Metadata *
609stripLoopMDLoc(const SmallPtrSetImpl<Metadata *> &AllDILocation,
610 const SmallPtrSetImpl<Metadata *> &DIReachable, Metadata *MD) {
611 if (isa<DILocation>(Val: MD) || AllDILocation.count(Ptr: MD))
612 return nullptr;
613
614 if (!DIReachable.count(Ptr: MD))
615 return MD;
616
617 MDNode *N = dyn_cast_or_null<MDNode>(Val: MD);
618 if (!N)
619 return MD;
620
621 SmallVector<Metadata *, 4> Args;
622 bool HasSelfRef = false;
623 for (unsigned i = 0; i < N->getNumOperands(); ++i) {
624 Metadata *A = N->getOperand(I: i);
625 if (!A) {
626 Args.push_back(Elt: nullptr);
627 } else if (A == MD) {
628 assert(i == 0 && "expected i==0 for self-reference");
629 HasSelfRef = true;
630 Args.push_back(Elt: nullptr);
631 } else if (Metadata *NewArg =
632 stripLoopMDLoc(AllDILocation, DIReachable, MD: A)) {
633 Args.push_back(Elt: NewArg);
634 }
635 }
636 if (Args.empty() || (HasSelfRef && Args.size() == 1))
637 return nullptr;
638
639 MDNode *NewMD = N->isDistinct() ? MDNode::getDistinct(Context&: N->getContext(), MDs: Args)
640 : MDNode::get(Context&: N->getContext(), MDs: Args);
641 if (HasSelfRef)
642 NewMD->replaceOperandWith(I: 0, New: NewMD);
643 return NewMD;
644}
645
646static MDNode *stripDebugLocFromLoopID(MDNode *N) {
647 assert(!N->operands().empty() && "Missing self reference?");
648 SmallPtrSet<Metadata *, 8> Visited, DILocationReachable, AllDILocation;
649 // If we already visited N, there is nothing to do.
650 if (!Visited.insert(Ptr: N).second)
651 return N;
652
653 // If there is no debug location, we do not have to rewrite this
654 // MDNode. This loop also initializes DILocationReachable, later
655 // needed by updateLoopMetadataDebugLocationsImpl; the use of
656 // count_if avoids an early exit.
657 if (!llvm::count_if(Range: llvm::drop_begin(RangeOrContainer: N->operands()),
658 P: [&Visited, &DILocationReachable](const MDOperand &Op) {
659 return isDILocationReachable(
660 Visited, Reachable&: DILocationReachable, MD: Op.get());
661 }))
662 return N;
663
664 Visited.clear();
665 // If there is only the debug location without any actual loop metadata, we
666 // can remove the metadata.
667 if (llvm::all_of(Range: llvm::drop_begin(RangeOrContainer: N->operands()),
668 P: [&Visited, &AllDILocation,
669 &DILocationReachable](const MDOperand &Op) {
670 return isAllDILocation(Visited, AllDILocation,
671 DIReachable: DILocationReachable, MD: Op.get());
672 }))
673 return nullptr;
674
675 return updateLoopMetadataDebugLocationsImpl(
676 OrigLoopID: N, Updater: [&AllDILocation, &DILocationReachable](Metadata *MD) -> Metadata * {
677 return stripLoopMDLoc(AllDILocation, DIReachable: DILocationReachable, MD);
678 });
679}
680
681bool llvm::stripDebugInfo(Function &F) {
682 bool Changed = false;
683 if (F.hasMetadata(KindID: LLVMContext::MD_dbg)) {
684 Changed = true;
685 F.setSubprogram(nullptr);
686 }
687
688 DenseMap<MDNode *, MDNode *> LoopIDsMap;
689 for (BasicBlock &BB : F) {
690 for (Instruction &I : llvm::make_early_inc_range(Range&: BB)) {
691 if (I.getDebugLoc()) {
692 Changed = true;
693 I.setDebugLoc(DebugLoc());
694 }
695 if (auto *LoopID = I.getMetadata(KindID: LLVMContext::MD_loop)) {
696 auto *NewLoopID = LoopIDsMap.lookup(Val: LoopID);
697 if (!NewLoopID)
698 NewLoopID = LoopIDsMap[LoopID] = stripDebugLocFromLoopID(N: LoopID);
699 if (NewLoopID != LoopID)
700 I.setMetadata(KindID: LLVMContext::MD_loop, Node: NewLoopID);
701 }
702 // Strip other attachments that are or use debug info.
703 if (I.hasMetadataOtherThanDebugLoc()) {
704 // Heapallocsites point into the DIType system.
705 I.setMetadata(Kind: "heapallocsite", Node: nullptr);
706 // DIAssignID are debug info metadata primitives.
707 I.setMetadata(KindID: LLVMContext::MD_DIAssignID, Node: nullptr);
708 }
709 I.dropDbgRecords();
710 }
711 }
712 return Changed;
713}
714
715bool llvm::StripDebugInfo(Module &M) {
716 llvm::TimeTraceScope timeScope("Strip debug info");
717 bool Changed = false;
718
719 for (NamedMDNode &NMD : llvm::make_early_inc_range(Range: M.named_metadata())) {
720 // We're stripping debug info, and without them, coverage information
721 // doesn't quite make sense.
722 if (NMD.getName().starts_with(Prefix: "llvm.dbg.") ||
723 NMD.getName() == "llvm.gcov") {
724 NMD.eraseFromParent();
725 Changed = true;
726 }
727 }
728
729 for (Function &F : M)
730 Changed |= stripDebugInfo(F);
731
732 for (auto &GV : M.globals()) {
733 Changed |= GV.eraseMetadata(KindID: LLVMContext::MD_dbg);
734 }
735
736 if (GVMaterializer *Materializer = M.getMaterializer())
737 Materializer->setStripDebugInfo();
738
739 return Changed;
740}
741
742namespace {
743
744/// Helper class to downgrade -g metadata to -gline-tables-only metadata.
745class DebugTypeInfoRemoval {
746 DenseMap<Metadata *, Metadata *> Replacements;
747
748public:
749 /// The (void)() type.
750 MDNode *EmptySubroutineType;
751
752private:
753 /// Remember what linkage name we originally had before stripping. If we end
754 /// up making two subprograms identical who originally had different linkage
755 /// names, then we need to make one of them distinct, to avoid them getting
756 /// uniqued. Maps the new node to the old linkage name.
757 DenseMap<DISubprogram *, StringRef> NewToLinkageName;
758
759 // TODO: Remember the distinct subprogram we created for a given linkage name,
760 // so that we can continue to unique whenever possible. Map <newly created
761 // node, old linkage name> to the first (possibly distinct) mdsubprogram
762 // created for that combination. This is not strictly needed for correctness,
763 // but can cut down on the number of MDNodes and let us diff cleanly with the
764 // output of -gline-tables-only.
765
766public:
767 DebugTypeInfoRemoval(LLVMContext &C)
768 : EmptySubroutineType(DISubroutineType::get(Context&: C, Flags: DINode::FlagZero, CC: 0,
769 TypeArray: MDNode::get(Context&: C, MDs: {}))) {}
770
771 Metadata *map(Metadata *M) {
772 if (!M)
773 return nullptr;
774 auto Replacement = Replacements.find(Val: M);
775 if (Replacement != Replacements.end())
776 return Replacement->second;
777
778 return M;
779 }
780 MDNode *mapNode(Metadata *N) { return dyn_cast_or_null<MDNode>(Val: map(M: N)); }
781
782 /// Recursively remap N and all its referenced children. Does a DF post-order
783 /// traversal, so as to remap bottoms up.
784 void traverseAndRemap(MDNode *N) { traverse(N); }
785
786private:
787 // Create a new DISubprogram, to replace the one given.
788 DISubprogram *getReplacementSubprogram(DISubprogram *MDS) {
789 auto *FileAndScope = cast_or_null<DIFile>(Val: map(M: MDS->getFile()));
790 DISubprogram *Declaration = nullptr;
791 auto *Type = cast_or_null<DISubroutineType>(Val: map(M: MDS->getType()));
792 DIType *ContainingType =
793 cast_or_null<DIType>(Val: map(M: MDS->getContainingType()));
794 auto *Unit = cast_or_null<DICompileUnit>(Val: map(M: MDS->getUnit()));
795 auto Variables = nullptr;
796 auto TemplateParams = nullptr;
797 // Keep linkage names for profiling CUs, as -gline-tables-only does.
798 StringRef LinkageName;
799 if (MDS->getName().empty() || (Unit && Unit->getDebugInfoForProfiling()))
800 LinkageName = MDS->getLinkageName();
801
802 // Make a distinct DISubprogram, for situations that warrant it.
803 auto distinctMDSubprogram = [&]() {
804 return DISubprogram::getDistinct(
805 Context&: MDS->getContext(), Scope: FileAndScope, Name: MDS->getName(), LinkageName,
806 File: FileAndScope, Line: MDS->getLine(), Type, ScopeLine: MDS->getScopeLine(),
807 ContainingType, VirtualIndex: MDS->getVirtualIndex(), ThisAdjustment: MDS->getThisAdjustment(),
808 Flags: MDS->getFlags(), SPFlags: MDS->getSPFlags(), Unit, TemplateParams, Declaration,
809 RetainedNodes: Variables);
810 };
811
812 if (MDS->isDistinct())
813 return distinctMDSubprogram();
814
815 auto *NewMDS = DISubprogram::get(
816 Context&: MDS->getContext(), Scope: FileAndScope, Name: MDS->getName(), LinkageName,
817 File: FileAndScope, Line: MDS->getLine(), Type, ScopeLine: MDS->getScopeLine(), ContainingType,
818 VirtualIndex: MDS->getVirtualIndex(), ThisAdjustment: MDS->getThisAdjustment(), Flags: MDS->getFlags(),
819 SPFlags: MDS->getSPFlags(), Unit, TemplateParams, Declaration, RetainedNodes: Variables);
820
821 StringRef OldLinkageName = MDS->getLinkageName();
822
823 // See if we need to make a distinct one.
824 auto OrigLinkage = NewToLinkageName.find(Val: NewMDS);
825 if (OrigLinkage != NewToLinkageName.end()) {
826 if (OrigLinkage->second == OldLinkageName)
827 // We're good.
828 return NewMDS;
829
830 // Otherwise, need to make a distinct one.
831 // TODO: Query the map to see if we already have one.
832 return distinctMDSubprogram();
833 }
834
835 NewToLinkageName.insert(KV: {NewMDS, MDS->getLinkageName()});
836 return NewMDS;
837 }
838
839 /// Create a new compile unit, to replace the one given
840 DICompileUnit *getReplacementCU(DICompileUnit *CU) {
841 // Drop skeleton CUs.
842 if (CU->getDWOId())
843 return nullptr;
844
845 auto *File = cast_or_null<DIFile>(Val: map(M: CU->getFile()));
846 MDTuple *EnumTypes = nullptr;
847 MDTuple *RetainedTypes = nullptr;
848 MDTuple *GlobalVariables = nullptr;
849 MDTuple *ImportedEntities = nullptr;
850 return DICompileUnit::getDistinct(
851 Context&: CU->getContext(), SourceLanguage: CU->getSourceLanguage(), File, Producer: CU->getProducer(),
852 IsOptimized: CU->isOptimized(), Flags: CU->getFlags(), RuntimeVersion: CU->getRuntimeVersion(),
853 SplitDebugFilename: CU->getSplitDebugFilename(), EmissionKind: DICompileUnit::LineTablesOnly, EnumTypes,
854 RetainedTypes, GlobalVariables, ImportedEntities, Macros: CU->getMacros(),
855 DWOId: CU->getDWOId(), SplitDebugInlining: CU->getSplitDebugInlining(),
856 DebugInfoForProfiling: CU->getDebugInfoForProfiling(), NameTableKind: CU->getNameTableKind(),
857 RangesBaseAddress: CU->getRangesBaseAddress(), SysRoot: CU->getSysRoot(), SDK: CU->getSDK());
858 }
859
860 DILocation *getReplacementMDLocation(DILocation *MLD) {
861 auto *Scope = map(M: MLD->getScope());
862 auto *InlinedAt = map(M: MLD->getInlinedAt());
863 if (MLD->isDistinct())
864 return DILocation::getDistinct(Context&: MLD->getContext(), Line: MLD->getLine(),
865 Column: MLD->getColumn(), Scope, InlinedAt);
866 return DILocation::get(Context&: MLD->getContext(), Line: MLD->getLine(), Column: MLD->getColumn(),
867 Scope, InlinedAt);
868 }
869
870 /// Create a new generic MDNode, to replace the one given
871 MDNode *getReplacementMDNode(MDNode *N) {
872 SmallVector<Metadata *, 8> Ops;
873 Ops.reserve(N: N->getNumOperands());
874 for (auto &I : N->operands())
875 if (I)
876 Ops.push_back(Elt: map(M: I));
877 auto *Ret = MDNode::get(Context&: N->getContext(), MDs: Ops);
878 return Ret;
879 }
880
881 /// Attempt to re-map N to a newly created node.
882 void remap(MDNode *N) {
883 if (Replacements.count(Val: N))
884 return;
885
886 auto doRemap = [&](MDNode *N) -> MDNode * {
887 if (!N)
888 return nullptr;
889 if (auto *MDSub = dyn_cast<DISubprogram>(Val: N)) {
890 remap(N: MDSub->getUnit());
891 return getReplacementSubprogram(MDS: MDSub);
892 }
893 if (isa<DISubroutineType>(Val: N))
894 return EmptySubroutineType;
895 if (auto *CU = dyn_cast<DICompileUnit>(Val: N))
896 return getReplacementCU(CU);
897 if (isa<DIFile>(Val: N))
898 return N;
899 if (auto *MDLB = dyn_cast<DILexicalBlockBase>(Val: N))
900 // Remap to our referenced scope (recursively).
901 return mapNode(N: MDLB->getScope());
902 if (auto *MLD = dyn_cast<DILocation>(Val: N))
903 return getReplacementMDLocation(MLD);
904
905 // Otherwise, if we see these, just drop them now. Not strictly necessary,
906 // but this speeds things up a little.
907 if (isa<DINode>(Val: N))
908 return nullptr;
909
910 return getReplacementMDNode(N);
911 };
912 // Separate recursive doRemap and operator [] into 2 lines to avoid
913 // out-of-order evaluations since both of them can access the same memory
914 // location in map Replacements.
915 auto Value = doRemap(N);
916 Replacements[N] = Value;
917 }
918
919 /// Do the remapping traversal.
920 void traverse(MDNode *);
921};
922
923} // end anonymous namespace
924
925void DebugTypeInfoRemoval::traverse(MDNode *N) {
926 if (!N || Replacements.count(Val: N))
927 return;
928
929 // To avoid cycles, as well as for efficiency sake, we will sometimes prune
930 // parts of the graph.
931 auto prune = [](MDNode *Parent, MDNode *Child) {
932 if (auto *MDS = dyn_cast<DISubprogram>(Val: Parent))
933 return Child == MDS->getRetainedNodes().get();
934 return false;
935 };
936
937 SmallVector<MDNode *, 16> ToVisit;
938 DenseSet<MDNode *> Opened;
939
940 // Visit each node starting at N in post order, and map them.
941 ToVisit.push_back(Elt: N);
942 while (!ToVisit.empty()) {
943 auto *N = ToVisit.back();
944 if (!Opened.insert(V: N).second) {
945 // Close it.
946 remap(N);
947 ToVisit.pop_back();
948 continue;
949 }
950 for (auto &I : N->operands())
951 if (auto *MDN = dyn_cast_or_null<MDNode>(Val: I))
952 if (!Opened.count(V: MDN) && !Replacements.count(Val: MDN) && !prune(N, MDN) &&
953 !isa<DICompileUnit>(Val: MDN))
954 ToVisit.push_back(Elt: MDN);
955 }
956}
957
958bool llvm::stripNonLineTableDebugInfo(Module &M) {
959 bool Changed = false;
960
961 // Delete non-CU debug info named metadata nodes.
962 for (auto NMI = M.named_metadata_begin(), NME = M.named_metadata_end();
963 NMI != NME;) {
964 NamedMDNode *NMD = &*NMI;
965 ++NMI;
966 // Specifically keep dbg.cu around.
967 if (NMD->getName() == "llvm.dbg.cu")
968 continue;
969 }
970
971 // Drop all dbg attachments from global variables.
972 for (auto &GV : M.globals())
973 GV.eraseMetadata(KindID: LLVMContext::MD_dbg);
974
975 DebugTypeInfoRemoval Mapper(M.getContext());
976 auto remap = [&](MDNode *Node) -> MDNode * {
977 if (!Node)
978 return nullptr;
979 Mapper.traverseAndRemap(N: Node);
980 auto *NewNode = Mapper.mapNode(N: Node);
981 Changed |= Node != NewNode;
982 Node = NewNode;
983 return NewNode;
984 };
985
986 // Rewrite the DebugLocs to be equivalent to what
987 // -gline-tables-only would have created.
988 for (auto &F : M) {
989 if (auto *SP = F.getSubprogram()) {
990 Mapper.traverseAndRemap(N: SP);
991 auto *NewSP = cast<DISubprogram>(Val: Mapper.mapNode(N: SP));
992 Changed |= SP != NewSP;
993 F.setSubprogram(NewSP);
994 }
995 for (auto &BB : F) {
996 for (auto &I : BB) {
997 auto remapDebugLoc = [&](const DebugLoc &DL) -> DebugLoc {
998 auto *Scope = DL.getScope();
999 MDNode *InlinedAt = DL.getInlinedAt();
1000 Scope = remap(Scope);
1001 InlinedAt = remap(InlinedAt);
1002 return DILocation::get(Context&: M.getContext(), Line: DL.getLine(), Column: DL.getCol(),
1003 Scope, InlinedAt);
1004 };
1005
1006 if (I.getDebugLoc() != DebugLoc())
1007 I.setDebugLoc(remapDebugLoc(I.getDebugLoc()));
1008
1009 // Remap DILocations in llvm.loop attachments.
1010 updateLoopMetadataDebugLocations(I, Updater: [&](Metadata *MD) -> Metadata * {
1011 if (auto *Loc = dyn_cast_or_null<DILocation>(Val: MD))
1012 return remapDebugLoc(Loc).get();
1013 return MD;
1014 });
1015
1016 // Strip heapallocsite attachments, they point into the DIType system.
1017 if (I.hasMetadataOtherThanDebugLoc())
1018 I.setMetadata(Kind: "heapallocsite", Node: nullptr);
1019
1020 // Strip any DbgRecords attached.
1021 I.dropDbgRecords();
1022 }
1023 }
1024 }
1025
1026 // Create a new llvm.dbg.cu, which is equivalent to the one
1027 // -gline-tables-only would have created.
1028 for (auto &NMD : M.named_metadata()) {
1029 SmallVector<MDNode *, 8> Ops;
1030 for (MDNode *Op : NMD.operands())
1031 Ops.push_back(Elt: remap(Op));
1032
1033 if (!Changed)
1034 continue;
1035
1036 NMD.clearOperands();
1037 for (auto *Op : Ops)
1038 if (Op)
1039 NMD.addOperand(M: Op);
1040 }
1041 return Changed;
1042}
1043
1044unsigned llvm::getDebugMetadataVersionFromModule(const Module &M) {
1045 if (auto *Val = mdconst::dyn_extract_or_null<ConstantInt>(
1046 MD: M.getModuleFlag(Key: "Debug Info Version")))
1047 return Val->getZExtValue();
1048 return 0;
1049}
1050
1051void Instruction::applyMergedLocation(DebugLoc LocA, DebugLoc LocB) {
1052 setDebugLoc(DebugLoc::getMergedLocation(LocA, LocB));
1053}
1054
1055void Instruction::mergeDIAssignID(
1056 ArrayRef<const Instruction *> SourceInstructions) {
1057 // Replace all uses (and attachments) of all the DIAssignIDs
1058 // on SourceInstructions with a single merged value.
1059 assert(getFunction() && "Uninserted instruction merged");
1060 // Collect up the DIAssignID tags.
1061 SmallVector<DIAssignID *, 4> IDs;
1062 for (const Instruction *I : SourceInstructions) {
1063 if (auto *MD = I->getMetadata(KindID: LLVMContext::MD_DIAssignID))
1064 IDs.push_back(Elt: cast<DIAssignID>(Val: MD));
1065 assert(getFunction() == I->getFunction() &&
1066 "Merging with instruction from another function not allowed");
1067 }
1068
1069 // Add this instruction's DIAssignID too, if it has one.
1070 if (auto *MD = getMetadata(KindID: LLVMContext::MD_DIAssignID))
1071 IDs.push_back(Elt: cast<DIAssignID>(Val: MD));
1072
1073 if (IDs.empty())
1074 return; // No DIAssignID tags to process.
1075
1076 DIAssignID *MergeID = IDs[0];
1077 for (DIAssignID *AssignID : drop_begin(RangeOrContainer&: IDs)) {
1078 if (AssignID != MergeID)
1079 at::RAUW(Old: AssignID, New: MergeID);
1080 }
1081 setMetadata(KindID: LLVMContext::MD_DIAssignID, Node: MergeID);
1082}
1083
1084void Instruction::updateLocationAfterHoist() { dropLocation(); }
1085
1086void Instruction::dropLocation() {
1087 const DebugLoc &DL = getDebugLoc();
1088 if (!DL) {
1089 setDebugLoc(DebugLoc::getDropped());
1090 return;
1091 }
1092
1093 // If this isn't a call, drop the location to allow a location from a
1094 // preceding instruction to propagate.
1095 bool MayLowerToCall = false;
1096 if (isa<CallBase>(Val: this)) {
1097 auto *II = dyn_cast<IntrinsicInst>(Val: this);
1098 MayLowerToCall =
1099 !II || IntrinsicInst::mayLowerToFunctionCall(IID: II->getIntrinsicID());
1100 }
1101
1102 if (!MayLowerToCall) {
1103 setDebugLoc(DebugLoc::getDropped());
1104 return;
1105 }
1106
1107 // Set a line 0 location for calls to preserve scope information in case
1108 // inlining occurs.
1109 DISubprogram *SP = getFunction()->getSubprogram();
1110 if (SP)
1111 // If a function scope is available, set it on the line 0 location. When
1112 // hoisting a call to a predecessor block, using the function scope avoids
1113 // making it look like the callee was reached earlier than it should be.
1114 setDebugLoc(DILocation::get(Context&: getContext(), Line: 0, Column: 0, Scope: SP));
1115 else
1116 // The parent function has no scope. Go ahead and drop the location. If
1117 // the parent function is inlined, and the callee has a subprogram, the
1118 // inliner will attach a location to the call.
1119 //
1120 // One alternative is to set a line 0 location with the existing scope and
1121 // inlinedAt info. The location might be sensitive to when inlining occurs.
1122 setDebugLoc(DebugLoc::getDropped());
1123}
1124
1125//===----------------------------------------------------------------------===//
1126// LLVM C API implementations.
1127//===----------------------------------------------------------------------===//
1128
1129static unsigned map_from_llvmDWARFsourcelanguage(LLVMDWARFSourceLanguage lang) {
1130 switch (lang) {
1131#define HANDLE_DW_LANG(ID, NAME, LOWER_BOUND, VERSION, VENDOR) \
1132 case LLVMDWARFSourceLanguage##NAME: \
1133 return ID;
1134#include "llvm/BinaryFormat/Dwarf.def"
1135#undef HANDLE_DW_LANG
1136 }
1137 llvm_unreachable("Unhandled Tag");
1138}
1139
1140template <typename DIT> DIT *unwrapDI(LLVMMetadataRef Ref) {
1141 return (DIT *)(Ref ? unwrap<MDNode>(P: Ref) : nullptr);
1142}
1143
1144static DINode::DIFlags map_from_llvmDIFlags(LLVMDIFlags Flags) {
1145 return static_cast<DINode::DIFlags>(Flags);
1146}
1147
1148static LLVMDIFlags map_to_llvmDIFlags(DINode::DIFlags Flags) {
1149 return static_cast<LLVMDIFlags>(Flags);
1150}
1151
1152static DISubprogram::DISPFlags
1153pack_into_DISPFlags(bool IsLocalToUnit, bool IsDefinition, bool IsOptimized) {
1154 return DISubprogram::toSPFlags(IsLocalToUnit, IsDefinition, IsOptimized);
1155}
1156
1157unsigned LLVMDebugMetadataVersion() {
1158 return DEBUG_METADATA_VERSION;
1159}
1160
1161LLVMDIBuilderRef LLVMCreateDIBuilderDisallowUnresolved(LLVMModuleRef M) {
1162 return wrap(P: new DIBuilder(*unwrap(P: M), false));
1163}
1164
1165LLVMDIBuilderRef LLVMCreateDIBuilder(LLVMModuleRef M) {
1166 return wrap(P: new DIBuilder(*unwrap(P: M)));
1167}
1168
1169unsigned LLVMGetModuleDebugMetadataVersion(LLVMModuleRef M) {
1170 return getDebugMetadataVersionFromModule(M: *unwrap(P: M));
1171}
1172
1173LLVMBool LLVMStripModuleDebugInfo(LLVMModuleRef M) {
1174 return StripDebugInfo(M&: *unwrap(P: M));
1175}
1176
1177void LLVMDisposeDIBuilder(LLVMDIBuilderRef Builder) {
1178 delete unwrap(P: Builder);
1179}
1180
1181void LLVMDIBuilderFinalize(LLVMDIBuilderRef Builder) {
1182 unwrap(P: Builder)->finalize();
1183}
1184
1185void LLVMDIBuilderFinalizeSubprogram(LLVMDIBuilderRef Builder,
1186 LLVMMetadataRef subprogram) {
1187 unwrap(P: Builder)->finalizeSubprogram(SP: unwrapDI<DISubprogram>(Ref: subprogram));
1188}
1189
1190LLVMMetadataRef LLVMDIBuilderCreateCompileUnit(
1191 LLVMDIBuilderRef Builder, LLVMDWARFSourceLanguage Lang,
1192 LLVMMetadataRef FileRef, const char *Producer, size_t ProducerLen,
1193 LLVMBool isOptimized, const char *Flags, size_t FlagsLen,
1194 unsigned RuntimeVer, const char *SplitName, size_t SplitNameLen,
1195 LLVMDWARFEmissionKind Kind, unsigned DWOId, LLVMBool SplitDebugInlining,
1196 LLVMBool DebugInfoForProfiling, const char *SysRoot, size_t SysRootLen,
1197 const char *SDK, size_t SDKLen) {
1198 auto File = unwrapDI<DIFile>(Ref: FileRef);
1199
1200 return wrap(P: unwrap(P: Builder)->createCompileUnit(
1201 Lang: DISourceLanguageName(map_from_llvmDWARFsourcelanguage(lang: Lang)), File,
1202 Producer: StringRef(Producer, ProducerLen), isOptimized, Flags: StringRef(Flags, FlagsLen),
1203 RV: RuntimeVer, SplitName: StringRef(SplitName, SplitNameLen),
1204 Kind: static_cast<DICompileUnit::DebugEmissionKind>(Kind), DWOId,
1205 SplitDebugInlining, DebugInfoForProfiling,
1206 NameTableKind: DICompileUnit::DebugNameTableKind::Default, RangesBaseAddress: false,
1207 SysRoot: StringRef(SysRoot, SysRootLen), SDK: StringRef(SDK, SDKLen)));
1208}
1209
1210LLVMMetadataRef
1211LLVMDIBuilderCreateFile(LLVMDIBuilderRef Builder, const char *Filename,
1212 size_t FilenameLen, const char *Directory,
1213 size_t DirectoryLen) {
1214 return wrap(P: unwrap(P: Builder)->createFile(Filename: StringRef(Filename, FilenameLen),
1215 Directory: StringRef(Directory, DirectoryLen)));
1216}
1217
1218static llvm::DIFile::ChecksumKind
1219map_from_llvmChecksumKind(LLVMChecksumKind CSKind) {
1220 switch (CSKind) {
1221 case LLVMChecksumKind::CSK_MD5:
1222 return llvm::DIFile::CSK_MD5;
1223 case LLVMChecksumKind::CSK_SHA1:
1224 return llvm::DIFile::CSK_SHA1;
1225 case LLVMChecksumKind::CSK_SHA256:
1226 return llvm::DIFile::CSK_SHA256;
1227 }
1228 llvm_unreachable("Unhandled Checksum Kind");
1229}
1230
1231LLVMMetadataRef LLVMDIBuilderCreateFileWithChecksum(
1232 LLVMDIBuilderRef Builder, const char *Filename, size_t FilenameLen,
1233 const char *Directory, size_t DirectoryLen, LLVMChecksumKind ChecksumKind,
1234 const char *Checksum, size_t ChecksumLen, const char *Source,
1235 size_t SourceLen) {
1236 StringRef ChkSum = StringRef(Checksum, ChecksumLen);
1237 auto CSK = map_from_llvmChecksumKind(CSKind: ChecksumKind);
1238 llvm::DIFile::ChecksumInfo<StringRef> CSInfo(CSK, ChkSum);
1239 std::optional<StringRef> Src;
1240 if (SourceLen > 0)
1241 Src = StringRef(Source, SourceLen);
1242 return wrap(P: unwrap(P: Builder)->createFile(Filename: StringRef(Filename, FilenameLen),
1243 Directory: StringRef(Directory, DirectoryLen),
1244 Checksum: CSInfo, Source: Src));
1245}
1246
1247LLVMMetadataRef
1248LLVMDIBuilderCreateModule(LLVMDIBuilderRef Builder, LLVMMetadataRef ParentScope,
1249 const char *Name, size_t NameLen,
1250 const char *ConfigMacros, size_t ConfigMacrosLen,
1251 const char *IncludePath, size_t IncludePathLen,
1252 const char *APINotesFile, size_t APINotesFileLen) {
1253 return wrap(P: unwrap(P: Builder)->createModule(
1254 Scope: unwrapDI<DIScope>(Ref: ParentScope), Name: StringRef(Name, NameLen),
1255 ConfigurationMacros: StringRef(ConfigMacros, ConfigMacrosLen),
1256 IncludePath: StringRef(IncludePath, IncludePathLen),
1257 APINotesFile: StringRef(APINotesFile, APINotesFileLen)));
1258}
1259
1260LLVMMetadataRef LLVMDIBuilderCreateNameSpace(LLVMDIBuilderRef Builder,
1261 LLVMMetadataRef ParentScope,
1262 const char *Name, size_t NameLen,
1263 LLVMBool ExportSymbols) {
1264 return wrap(P: unwrap(P: Builder)->createNameSpace(
1265 Scope: unwrapDI<DIScope>(Ref: ParentScope), Name: StringRef(Name, NameLen), ExportSymbols));
1266}
1267
1268LLVMMetadataRef LLVMDIBuilderCreateFunction(
1269 LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
1270 size_t NameLen, const char *LinkageName, size_t LinkageNameLen,
1271 LLVMMetadataRef File, unsigned LineNo, LLVMMetadataRef Ty,
1272 LLVMBool IsLocalToUnit, LLVMBool IsDefinition,
1273 unsigned ScopeLine, LLVMDIFlags Flags, LLVMBool IsOptimized) {
1274 return wrap(P: unwrap(P: Builder)->createFunction(
1275 Scope: unwrapDI<DIScope>(Ref: Scope), Name: {Name, NameLen}, LinkageName: {LinkageName, LinkageNameLen},
1276 File: unwrapDI<DIFile>(Ref: File), LineNo, Ty: unwrapDI<DISubroutineType>(Ref: Ty), ScopeLine,
1277 Flags: map_from_llvmDIFlags(Flags),
1278 SPFlags: pack_into_DISPFlags(IsLocalToUnit, IsDefinition, IsOptimized), TParams: nullptr,
1279 Decl: nullptr, ThrownTypes: nullptr));
1280}
1281
1282
1283LLVMMetadataRef LLVMDIBuilderCreateLexicalBlock(
1284 LLVMDIBuilderRef Builder, LLVMMetadataRef Scope,
1285 LLVMMetadataRef File, unsigned Line, unsigned Col) {
1286 return wrap(P: unwrap(P: Builder)->createLexicalBlock(Scope: unwrapDI<DIScope>(Ref: Scope),
1287 File: unwrapDI<DIFile>(Ref: File),
1288 Line, Col));
1289}
1290
1291LLVMMetadataRef
1292LLVMDIBuilderCreateLexicalBlockFile(LLVMDIBuilderRef Builder,
1293 LLVMMetadataRef Scope,
1294 LLVMMetadataRef File,
1295 unsigned Discriminator) {
1296 return wrap(P: unwrap(P: Builder)->createLexicalBlockFile(Scope: unwrapDI<DIScope>(Ref: Scope),
1297 File: unwrapDI<DIFile>(Ref: File),
1298 Discriminator));
1299}
1300
1301LLVMMetadataRef
1302LLVMDIBuilderCreateImportedModuleFromNamespace(LLVMDIBuilderRef Builder,
1303 LLVMMetadataRef Scope,
1304 LLVMMetadataRef NS,
1305 LLVMMetadataRef File,
1306 unsigned Line) {
1307 return wrap(P: unwrap(P: Builder)->createImportedModule(Context: unwrapDI<DIScope>(Ref: Scope),
1308 NS: unwrapDI<DINamespace>(Ref: NS),
1309 File: unwrapDI<DIFile>(Ref: File),
1310 Line));
1311}
1312
1313LLVMMetadataRef LLVMDIBuilderCreateImportedModuleFromAlias(
1314 LLVMDIBuilderRef Builder, LLVMMetadataRef Scope,
1315 LLVMMetadataRef ImportedEntity, LLVMMetadataRef File, unsigned Line,
1316 LLVMMetadataRef *Elements, unsigned NumElements) {
1317 auto Elts =
1318 (NumElements > 0)
1319 ? unwrap(P: Builder)->getOrCreateArray(Elements: {unwrap(MDs: Elements), NumElements})
1320 : nullptr;
1321 return wrap(P: unwrap(P: Builder)->createImportedModule(
1322 Context: unwrapDI<DIScope>(Ref: Scope), NS: unwrapDI<DIImportedEntity>(Ref: ImportedEntity),
1323 File: unwrapDI<DIFile>(Ref: File), Line, Elements: Elts));
1324}
1325
1326LLVMMetadataRef LLVMDIBuilderCreateImportedModuleFromModule(
1327 LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, LLVMMetadataRef M,
1328 LLVMMetadataRef File, unsigned Line, LLVMMetadataRef *Elements,
1329 unsigned NumElements) {
1330 auto Elts =
1331 (NumElements > 0)
1332 ? unwrap(P: Builder)->getOrCreateArray(Elements: {unwrap(MDs: Elements), NumElements})
1333 : nullptr;
1334 return wrap(P: unwrap(P: Builder)->createImportedModule(
1335 Context: unwrapDI<DIScope>(Ref: Scope), M: unwrapDI<DIModule>(Ref: M), File: unwrapDI<DIFile>(Ref: File),
1336 Line, Elements: Elts));
1337}
1338
1339LLVMMetadataRef LLVMDIBuilderCreateImportedDeclaration(
1340 LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, LLVMMetadataRef Decl,
1341 LLVMMetadataRef File, unsigned Line, const char *Name, size_t NameLen,
1342 LLVMMetadataRef *Elements, unsigned NumElements) {
1343 auto Elts =
1344 (NumElements > 0)
1345 ? unwrap(P: Builder)->getOrCreateArray(Elements: {unwrap(MDs: Elements), NumElements})
1346 : nullptr;
1347 return wrap(P: unwrap(P: Builder)->createImportedDeclaration(
1348 Context: unwrapDI<DIScope>(Ref: Scope), Decl: unwrapDI<DINode>(Ref: Decl), File: unwrapDI<DIFile>(Ref: File),
1349 Line, Name: {Name, NameLen}, Elements: Elts));
1350}
1351
1352LLVMMetadataRef
1353LLVMDIBuilderCreateDebugLocation(LLVMContextRef Ctx, unsigned Line,
1354 unsigned Column, LLVMMetadataRef Scope,
1355 LLVMMetadataRef InlinedAt) {
1356 return wrap(P: DILocation::get(Context&: *unwrap(P: Ctx), Line, Column, Scope: unwrap(P: Scope),
1357 InlinedAt: unwrap(P: InlinedAt)));
1358}
1359
1360unsigned LLVMDILocationGetLine(LLVMMetadataRef Location) {
1361 return unwrapDI<DILocation>(Ref: Location)->getLine();
1362}
1363
1364unsigned LLVMDILocationGetColumn(LLVMMetadataRef Location) {
1365 return unwrapDI<DILocation>(Ref: Location)->getColumn();
1366}
1367
1368LLVMMetadataRef LLVMDILocationGetScope(LLVMMetadataRef Location) {
1369 return wrap(P: unwrapDI<DILocation>(Ref: Location)->getScope());
1370}
1371
1372LLVMMetadataRef LLVMDILocationGetInlinedAt(LLVMMetadataRef Location) {
1373 return wrap(P: unwrapDI<DILocation>(Ref: Location)->getInlinedAt());
1374}
1375
1376LLVMMetadataRef LLVMDIScopeGetFile(LLVMMetadataRef Scope) {
1377 return wrap(P: unwrapDI<DIScope>(Ref: Scope)->getFile());
1378}
1379
1380const char *LLVMDIFileGetDirectory(LLVMMetadataRef File, unsigned *Len) {
1381 auto Dir = unwrapDI<DIFile>(Ref: File)->getDirectory();
1382 *Len = Dir.size();
1383 return Dir.data();
1384}
1385
1386const char *LLVMDIFileGetFilename(LLVMMetadataRef File, unsigned *Len) {
1387 auto Name = unwrapDI<DIFile>(Ref: File)->getFilename();
1388 *Len = Name.size();
1389 return Name.data();
1390}
1391
1392const char *LLVMDIFileGetSource(LLVMMetadataRef File, unsigned *Len) {
1393 if (auto Src = unwrapDI<DIFile>(Ref: File)->getSource()) {
1394 *Len = Src->size();
1395 return Src->data();
1396 }
1397 *Len = 0;
1398 return "";
1399}
1400
1401LLVMMetadataRef LLVMDIBuilderCreateMacro(LLVMDIBuilderRef Builder,
1402 LLVMMetadataRef ParentMacroFile,
1403 unsigned Line,
1404 LLVMDWARFMacinfoRecordType RecordType,
1405 const char *Name, size_t NameLen,
1406 const char *Value, size_t ValueLen) {
1407 return wrap(
1408 P: unwrap(P: Builder)->createMacro(Parent: unwrapDI<DIMacroFile>(Ref: ParentMacroFile), Line,
1409 MacroType: static_cast<MacinfoRecordType>(RecordType),
1410 Name: {Name, NameLen}, Value: {Value, ValueLen}));
1411}
1412
1413LLVMMetadataRef
1414LLVMDIBuilderCreateTempMacroFile(LLVMDIBuilderRef Builder,
1415 LLVMMetadataRef ParentMacroFile, unsigned Line,
1416 LLVMMetadataRef File) {
1417 return wrap(P: unwrap(P: Builder)->createTempMacroFile(
1418 Parent: unwrapDI<DIMacroFile>(Ref: ParentMacroFile), Line, File: unwrapDI<DIFile>(Ref: File)));
1419}
1420
1421LLVMMetadataRef LLVMDIBuilderCreateEnumerator(LLVMDIBuilderRef Builder,
1422 const char *Name, size_t NameLen,
1423 int64_t Value,
1424 LLVMBool IsUnsigned) {
1425 return wrap(P: unwrap(P: Builder)->createEnumerator(Name: {Name, NameLen}, Val: Value,
1426 IsUnsigned: IsUnsigned != 0));
1427}
1428
1429LLVMMetadataRef LLVMDIBuilderCreateEnumeratorOfArbitraryPrecision(
1430 LLVMDIBuilderRef Builder, const char *Name, size_t NameLen,
1431 uint64_t SizeInBits, const uint64_t Words[], LLVMBool IsUnsigned) {
1432 uint64_t NumWords = (SizeInBits + 63) / 64;
1433 return wrap(P: unwrap(P: Builder)->createEnumerator(
1434 Name: {Name, NameLen},
1435 Value: APSInt(APInt(SizeInBits, ArrayRef(Words, NumWords)), IsUnsigned != 0)));
1436}
1437
1438LLVMMetadataRef LLVMDIBuilderCreateEnumerationType(
1439 LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
1440 size_t NameLen, LLVMMetadataRef File, unsigned LineNumber,
1441 uint64_t SizeInBits, uint32_t AlignInBits, LLVMMetadataRef *Elements,
1442 unsigned NumElements, LLVMMetadataRef ClassTy) {
1443auto Elts = unwrap(P: Builder)->getOrCreateArray(Elements: {unwrap(MDs: Elements),
1444 NumElements});
1445return wrap(P: unwrap(P: Builder)->createEnumerationType(
1446 Scope: unwrapDI<DIScope>(Ref: Scope), Name: {Name, NameLen}, File: unwrapDI<DIFile>(Ref: File),
1447 LineNumber, SizeInBits, AlignInBits, Elements: Elts, UnderlyingType: unwrapDI<DIType>(Ref: ClassTy)));
1448}
1449
1450LLVMMetadataRef LLVMDIBuilderCreateSetType(
1451 LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
1452 size_t NameLen, LLVMMetadataRef File, unsigned LineNumber,
1453 uint64_t SizeInBits, uint32_t AlignInBits, LLVMMetadataRef BaseTy) {
1454 return wrap(P: unwrap(P: Builder)->createSetType(
1455 Scope: unwrapDI<DIScope>(Ref: Scope), Name: {Name, NameLen}, File: unwrapDI<DIFile>(Ref: File),
1456 LineNo: LineNumber, SizeInBits, AlignInBits, Ty: unwrapDI<DIType>(Ref: BaseTy)));
1457}
1458
1459LLVMMetadataRef LLVMDIBuilderCreateSubrangeType(
1460 LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
1461 size_t NameLen, unsigned LineNo, LLVMMetadataRef File, uint64_t SizeInBits,
1462 uint32_t AlignInBits, LLVMDIFlags Flags, LLVMMetadataRef BaseTy,
1463 LLVMMetadataRef LowerBound, LLVMMetadataRef UpperBound,
1464 LLVMMetadataRef Stride, LLVMMetadataRef Bias) {
1465 return wrap(P: unwrap(P: Builder)->createSubrangeType(
1466 Name: {Name, NameLen}, File: unwrapDI<DIFile>(Ref: File), LineNo, Scope: unwrapDI<DIScope>(Ref: Scope),
1467 SizeInBits, AlignInBits, Flags: map_from_llvmDIFlags(Flags),
1468 Ty: unwrapDI<DIType>(Ref: BaseTy), LowerBound: unwrap(P: LowerBound), UpperBound: unwrap(P: UpperBound),
1469 Stride: unwrap(P: Stride), Bias: unwrap(P: Bias)));
1470}
1471
1472/// MD may be nullptr, a DIExpression or DIVariable.
1473PointerUnion<DIExpression *, DIVariable *> unwrapExprVar(LLVMMetadataRef MD) {
1474 if (!MD)
1475 return nullptr;
1476 MDNode *MDN = unwrapDI<MDNode>(Ref: MD);
1477 if (auto *E = dyn_cast<DIExpression>(Val: MDN))
1478 return E;
1479 assert(isa<DIVariable>(MDN) && "Expected DIExpression or DIVariable");
1480 return cast<DIVariable>(Val: MDN);
1481}
1482
1483LLVMMetadataRef LLVMDIBuilderCreateDynamicArrayType(
1484 LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
1485 size_t NameLen, unsigned LineNo, LLVMMetadataRef File, uint64_t Size,
1486 uint32_t AlignInBits, LLVMMetadataRef Ty, LLVMMetadataRef *Subscripts,
1487 unsigned NumSubscripts, LLVMMetadataRef DataLocation,
1488 LLVMMetadataRef Associated, LLVMMetadataRef Allocated, LLVMMetadataRef Rank,
1489 LLVMMetadataRef BitStride) {
1490 auto Subs =
1491 unwrap(P: Builder)->getOrCreateArray(Elements: {unwrap(MDs: Subscripts), NumSubscripts});
1492 return wrap(P: unwrap(P: Builder)->createArrayType(
1493 Scope: unwrapDI<DIScope>(Ref: Scope), Name: {Name, NameLen}, File: unwrapDI<DIFile>(Ref: File), LineNumber: LineNo,
1494 Size, AlignInBits, Ty: unwrapDI<DIType>(Ref: Ty), Subscripts: Subs,
1495 DataLocation: unwrapExprVar(MD: DataLocation), Associated: unwrapExprVar(MD: Associated),
1496 Allocated: unwrapExprVar(MD: Allocated), Rank: unwrapExprVar(MD: Rank), BitStride: unwrap(P: BitStride)));
1497}
1498
1499void LLVMReplaceArrays(LLVMDIBuilderRef Builder, LLVMMetadataRef *T,
1500 LLVMMetadataRef *Elements, unsigned NumElements) {
1501 auto CT = unwrap<DICompositeType>(P: *T);
1502 auto Elts =
1503 unwrap(P: Builder)->getOrCreateArray(Elements: {unwrap(MDs: Elements), NumElements});
1504 unwrap(P: Builder)->replaceArrays(T&: CT, Elements: Elts);
1505}
1506
1507LLVMMetadataRef LLVMDIBuilderCreateUnionType(
1508 LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
1509 size_t NameLen, LLVMMetadataRef File, unsigned LineNumber,
1510 uint64_t SizeInBits, uint32_t AlignInBits, LLVMDIFlags Flags,
1511 LLVMMetadataRef *Elements, unsigned NumElements, unsigned RunTimeLang,
1512 const char *UniqueId, size_t UniqueIdLen) {
1513 auto Elts = unwrap(P: Builder)->getOrCreateArray(Elements: {unwrap(MDs: Elements),
1514 NumElements});
1515 return wrap(P: unwrap(P: Builder)->createUnionType(
1516 Scope: unwrapDI<DIScope>(Ref: Scope), Name: {Name, NameLen}, File: unwrapDI<DIFile>(Ref: File),
1517 LineNumber, SizeInBits, AlignInBits, Flags: map_from_llvmDIFlags(Flags),
1518 Elements: Elts, RunTimeLang, UniqueIdentifier: {UniqueId, UniqueIdLen}));
1519}
1520
1521
1522LLVMMetadataRef
1523LLVMDIBuilderCreateArrayType(LLVMDIBuilderRef Builder, uint64_t Size,
1524 uint32_t AlignInBits, LLVMMetadataRef Ty,
1525 LLVMMetadataRef *Subscripts,
1526 unsigned NumSubscripts) {
1527 auto Subs = unwrap(P: Builder)->getOrCreateArray(Elements: {unwrap(MDs: Subscripts),
1528 NumSubscripts});
1529 return wrap(P: unwrap(P: Builder)->createArrayType(Size, AlignInBits,
1530 Ty: unwrapDI<DIType>(Ref: Ty), Subscripts: Subs));
1531}
1532
1533LLVMMetadataRef
1534LLVMDIBuilderCreateVectorType(LLVMDIBuilderRef Builder, uint64_t Size,
1535 uint32_t AlignInBits, LLVMMetadataRef Ty,
1536 LLVMMetadataRef *Subscripts,
1537 unsigned NumSubscripts) {
1538 auto Subs = unwrap(P: Builder)->getOrCreateArray(Elements: {unwrap(MDs: Subscripts),
1539 NumSubscripts});
1540 return wrap(P: unwrap(P: Builder)->createVectorType(Size, AlignInBits,
1541 Ty: unwrapDI<DIType>(Ref: Ty), Subscripts: Subs));
1542}
1543
1544LLVMMetadataRef
1545LLVMDIBuilderCreateBasicType(LLVMDIBuilderRef Builder, const char *Name,
1546 size_t NameLen, uint64_t SizeInBits,
1547 LLVMDWARFTypeEncoding Encoding,
1548 LLVMDIFlags Flags) {
1549 return wrap(P: unwrap(P: Builder)->createBasicType(Name: {Name, NameLen},
1550 SizeInBits, Encoding,
1551 Flags: map_from_llvmDIFlags(Flags)));
1552}
1553
1554LLVMMetadataRef LLVMDIBuilderCreatePointerType(
1555 LLVMDIBuilderRef Builder, LLVMMetadataRef PointeeTy,
1556 uint64_t SizeInBits, uint32_t AlignInBits, unsigned AddressSpace,
1557 const char *Name, size_t NameLen) {
1558 return wrap(P: unwrap(P: Builder)->createPointerType(
1559 PointeeTy: unwrapDI<DIType>(Ref: PointeeTy), SizeInBits, AlignInBits, DWARFAddressSpace: AddressSpace,
1560 Name: {Name, NameLen}));
1561}
1562
1563LLVMMetadataRef LLVMDIBuilderCreateStructType(
1564 LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
1565 size_t NameLen, LLVMMetadataRef File, unsigned LineNumber,
1566 uint64_t SizeInBits, uint32_t AlignInBits, LLVMDIFlags Flags,
1567 LLVMMetadataRef DerivedFrom, LLVMMetadataRef *Elements,
1568 unsigned NumElements, unsigned RunTimeLang, LLVMMetadataRef VTableHolder,
1569 const char *UniqueId, size_t UniqueIdLen) {
1570 auto Elts = unwrap(P: Builder)->getOrCreateArray(Elements: {unwrap(MDs: Elements),
1571 NumElements});
1572 return wrap(P: unwrap(P: Builder)->createStructType(
1573 Scope: unwrapDI<DIScope>(Ref: Scope), Name: {Name, NameLen}, File: unwrapDI<DIFile>(Ref: File),
1574 LineNumber, SizeInBits, AlignInBits, Flags: map_from_llvmDIFlags(Flags),
1575 DerivedFrom: unwrapDI<DIType>(Ref: DerivedFrom), Elements: Elts, RunTimeLang,
1576 VTableHolder: unwrapDI<DIType>(Ref: VTableHolder), UniqueIdentifier: {UniqueId, UniqueIdLen}));
1577}
1578
1579LLVMMetadataRef LLVMDIBuilderCreateMemberType(
1580 LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
1581 size_t NameLen, LLVMMetadataRef File, unsigned LineNo, uint64_t SizeInBits,
1582 uint32_t AlignInBits, uint64_t OffsetInBits, LLVMDIFlags Flags,
1583 LLVMMetadataRef Ty) {
1584 return wrap(P: unwrap(P: Builder)->createMemberType(Scope: unwrapDI<DIScope>(Ref: Scope),
1585 Name: {Name, NameLen}, File: unwrapDI<DIFile>(Ref: File), LineNo, SizeInBits, AlignInBits,
1586 OffsetInBits, Flags: map_from_llvmDIFlags(Flags), Ty: unwrapDI<DIType>(Ref: Ty)));
1587}
1588
1589LLVMMetadataRef
1590LLVMDIBuilderCreateUnspecifiedType(LLVMDIBuilderRef Builder, const char *Name,
1591 size_t NameLen) {
1592 return wrap(P: unwrap(P: Builder)->createUnspecifiedType(Name: {Name, NameLen}));
1593}
1594
1595LLVMMetadataRef LLVMDIBuilderCreateStaticMemberType(
1596 LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
1597 size_t NameLen, LLVMMetadataRef File, unsigned LineNumber,
1598 LLVMMetadataRef Type, LLVMDIFlags Flags, LLVMValueRef ConstantVal,
1599 uint32_t AlignInBits) {
1600 return wrap(P: unwrap(P: Builder)->createStaticMemberType(
1601 Scope: unwrapDI<DIScope>(Ref: Scope), Name: {Name, NameLen}, File: unwrapDI<DIFile>(Ref: File),
1602 LineNo: LineNumber, Ty: unwrapDI<DIType>(Ref: Type), Flags: map_from_llvmDIFlags(Flags),
1603 Val: unwrap<Constant>(P: ConstantVal), Tag: DW_TAG_member, AlignInBits));
1604}
1605
1606LLVMMetadataRef
1607LLVMDIBuilderCreateObjCIVar(LLVMDIBuilderRef Builder,
1608 const char *Name, size_t NameLen,
1609 LLVMMetadataRef File, unsigned LineNo,
1610 uint64_t SizeInBits, uint32_t AlignInBits,
1611 uint64_t OffsetInBits, LLVMDIFlags Flags,
1612 LLVMMetadataRef Ty, LLVMMetadataRef PropertyNode) {
1613 return wrap(P: unwrap(P: Builder)->createObjCIVar(
1614 Name: {Name, NameLen}, File: unwrapDI<DIFile>(Ref: File), LineNo,
1615 SizeInBits, AlignInBits, OffsetInBits,
1616 Flags: map_from_llvmDIFlags(Flags), Ty: unwrapDI<DIType>(Ref: Ty),
1617 PropertyNode: unwrapDI<MDNode>(Ref: PropertyNode)));
1618}
1619
1620LLVMMetadataRef
1621LLVMDIBuilderCreateObjCProperty(LLVMDIBuilderRef Builder,
1622 const char *Name, size_t NameLen,
1623 LLVMMetadataRef File, unsigned LineNo,
1624 const char *GetterName, size_t GetterNameLen,
1625 const char *SetterName, size_t SetterNameLen,
1626 unsigned PropertyAttributes,
1627 LLVMMetadataRef Ty) {
1628 return wrap(P: unwrap(P: Builder)->createObjCProperty(
1629 Name: {Name, NameLen}, File: unwrapDI<DIFile>(Ref: File), LineNumber: LineNo,
1630 GetterName: {GetterName, GetterNameLen}, SetterName: {SetterName, SetterNameLen},
1631 PropertyAttributes, Ty: unwrapDI<DIType>(Ref: Ty)));
1632}
1633
1634LLVMMetadataRef LLVMDIBuilderCreateObjectPointerType(LLVMDIBuilderRef Builder,
1635 LLVMMetadataRef Type,
1636 LLVMBool Implicit) {
1637 return wrap(P: unwrap(P: Builder)->createObjectPointerType(Ty: unwrapDI<DIType>(Ref: Type),
1638 Implicit));
1639}
1640
1641LLVMMetadataRef
1642LLVMDIBuilderCreateTypedef(LLVMDIBuilderRef Builder, LLVMMetadataRef Type,
1643 const char *Name, size_t NameLen,
1644 LLVMMetadataRef File, unsigned LineNo,
1645 LLVMMetadataRef Scope, uint32_t AlignInBits) {
1646 return wrap(P: unwrap(P: Builder)->createTypedef(
1647 Ty: unwrapDI<DIType>(Ref: Type), Name: {Name, NameLen}, File: unwrapDI<DIFile>(Ref: File), LineNo,
1648 Context: unwrapDI<DIScope>(Ref: Scope), AlignInBits));
1649}
1650
1651LLVMMetadataRef
1652LLVMDIBuilderCreateInheritance(LLVMDIBuilderRef Builder,
1653 LLVMMetadataRef Ty, LLVMMetadataRef BaseTy,
1654 uint64_t BaseOffset, uint32_t VBPtrOffset,
1655 LLVMDIFlags Flags) {
1656 return wrap(P: unwrap(P: Builder)->createInheritance(
1657 Ty: unwrapDI<DIType>(Ref: Ty), BaseTy: unwrapDI<DIType>(Ref: BaseTy),
1658 BaseOffset, VBPtrOffset, Flags: map_from_llvmDIFlags(Flags)));
1659}
1660
1661LLVMMetadataRef
1662LLVMDIBuilderCreateForwardDecl(
1663 LLVMDIBuilderRef Builder, unsigned Tag, const char *Name,
1664 size_t NameLen, LLVMMetadataRef Scope, LLVMMetadataRef File, unsigned Line,
1665 unsigned RuntimeLang, uint64_t SizeInBits, uint32_t AlignInBits,
1666 const char *UniqueIdentifier, size_t UniqueIdentifierLen) {
1667 return wrap(P: unwrap(P: Builder)->createForwardDecl(
1668 Tag, Name: {Name, NameLen}, Scope: unwrapDI<DIScope>(Ref: Scope),
1669 F: unwrapDI<DIFile>(Ref: File), Line, RuntimeLang, SizeInBits,
1670 AlignInBits, UniqueIdentifier: {UniqueIdentifier, UniqueIdentifierLen}));
1671}
1672
1673LLVMMetadataRef
1674LLVMDIBuilderCreateReplaceableCompositeType(
1675 LLVMDIBuilderRef Builder, unsigned Tag, const char *Name,
1676 size_t NameLen, LLVMMetadataRef Scope, LLVMMetadataRef File, unsigned Line,
1677 unsigned RuntimeLang, uint64_t SizeInBits, uint32_t AlignInBits,
1678 LLVMDIFlags Flags, const char *UniqueIdentifier,
1679 size_t UniqueIdentifierLen) {
1680 return wrap(P: unwrap(P: Builder)->createReplaceableCompositeType(
1681 Tag, Name: {Name, NameLen}, Scope: unwrapDI<DIScope>(Ref: Scope),
1682 F: unwrapDI<DIFile>(Ref: File), Line, RuntimeLang, SizeInBits,
1683 AlignInBits, Flags: map_from_llvmDIFlags(Flags),
1684 UniqueIdentifier: {UniqueIdentifier, UniqueIdentifierLen}));
1685}
1686
1687LLVMMetadataRef
1688LLVMDIBuilderCreateQualifiedType(LLVMDIBuilderRef Builder, unsigned Tag,
1689 LLVMMetadataRef Type) {
1690 return wrap(P: unwrap(P: Builder)->createQualifiedType(Tag,
1691 FromTy: unwrapDI<DIType>(Ref: Type)));
1692}
1693
1694LLVMMetadataRef
1695LLVMDIBuilderCreateReferenceType(LLVMDIBuilderRef Builder, unsigned Tag,
1696 LLVMMetadataRef Type) {
1697 return wrap(P: unwrap(P: Builder)->createReferenceType(Tag,
1698 RTy: unwrapDI<DIType>(Ref: Type)));
1699}
1700
1701LLVMMetadataRef
1702LLVMDIBuilderCreateNullPtrType(LLVMDIBuilderRef Builder) {
1703 return wrap(P: unwrap(P: Builder)->createNullPtrType());
1704}
1705
1706LLVMMetadataRef
1707LLVMDIBuilderCreateMemberPointerType(LLVMDIBuilderRef Builder,
1708 LLVMMetadataRef PointeeType,
1709 LLVMMetadataRef ClassType,
1710 uint64_t SizeInBits,
1711 uint32_t AlignInBits,
1712 LLVMDIFlags Flags) {
1713 return wrap(P: unwrap(P: Builder)->createMemberPointerType(
1714 PointeeTy: unwrapDI<DIType>(Ref: PointeeType),
1715 Class: unwrapDI<DIType>(Ref: ClassType), SizeInBits: AlignInBits, AlignInBits: SizeInBits,
1716 Flags: map_from_llvmDIFlags(Flags)));
1717}
1718
1719LLVMMetadataRef
1720LLVMDIBuilderCreateBitFieldMemberType(LLVMDIBuilderRef Builder,
1721 LLVMMetadataRef Scope,
1722 const char *Name, size_t NameLen,
1723 LLVMMetadataRef File, unsigned LineNumber,
1724 uint64_t SizeInBits,
1725 uint64_t OffsetInBits,
1726 uint64_t StorageOffsetInBits,
1727 LLVMDIFlags Flags, LLVMMetadataRef Type) {
1728 return wrap(P: unwrap(P: Builder)->createBitFieldMemberType(
1729 Scope: unwrapDI<DIScope>(Ref: Scope), Name: {Name, NameLen},
1730 File: unwrapDI<DIFile>(Ref: File), LineNo: LineNumber,
1731 SizeInBits, OffsetInBits, StorageOffsetInBits,
1732 Flags: map_from_llvmDIFlags(Flags), Ty: unwrapDI<DIType>(Ref: Type)));
1733}
1734
1735LLVMMetadataRef LLVMDIBuilderCreateClassType(LLVMDIBuilderRef Builder,
1736 LLVMMetadataRef Scope, const char *Name, size_t NameLen,
1737 LLVMMetadataRef File, unsigned LineNumber, uint64_t SizeInBits,
1738 uint32_t AlignInBits, uint64_t OffsetInBits, LLVMDIFlags Flags,
1739 LLVMMetadataRef DerivedFrom,
1740 LLVMMetadataRef *Elements, unsigned NumElements,
1741 LLVMMetadataRef VTableHolder, LLVMMetadataRef TemplateParamsNode,
1742 const char *UniqueIdentifier, size_t UniqueIdentifierLen) {
1743 auto Elts = unwrap(P: Builder)->getOrCreateArray(Elements: {unwrap(MDs: Elements),
1744 NumElements});
1745 return wrap(P: unwrap(P: Builder)->createClassType(
1746 Scope: unwrapDI<DIScope>(Ref: Scope), Name: {Name, NameLen}, File: unwrapDI<DIFile>(Ref: File),
1747 LineNumber, SizeInBits, AlignInBits, OffsetInBits,
1748 Flags: map_from_llvmDIFlags(Flags), DerivedFrom: unwrapDI<DIType>(Ref: DerivedFrom), Elements: Elts,
1749 /*RunTimeLang=*/0, VTableHolder: unwrapDI<DIType>(Ref: VTableHolder),
1750 TemplateParms: unwrapDI<MDNode>(Ref: TemplateParamsNode),
1751 UniqueIdentifier: {UniqueIdentifier, UniqueIdentifierLen}));
1752}
1753
1754LLVMMetadataRef
1755LLVMDIBuilderCreateArtificialType(LLVMDIBuilderRef Builder,
1756 LLVMMetadataRef Type) {
1757 return wrap(P: unwrap(P: Builder)->createArtificialType(Ty: unwrapDI<DIType>(Ref: Type)));
1758}
1759
1760uint16_t LLVMGetDINodeTag(LLVMMetadataRef MD) {
1761 return unwrapDI<DINode>(Ref: MD)->getTag();
1762}
1763
1764const char *LLVMDITypeGetName(LLVMMetadataRef DType, size_t *Length) {
1765 StringRef Str = unwrapDI<DIType>(Ref: DType)->getName();
1766 *Length = Str.size();
1767 return Str.data();
1768}
1769
1770uint64_t LLVMDITypeGetSizeInBits(LLVMMetadataRef DType) {
1771 return unwrapDI<DIType>(Ref: DType)->getSizeInBits();
1772}
1773
1774uint64_t LLVMDITypeGetOffsetInBits(LLVMMetadataRef DType) {
1775 return unwrapDI<DIType>(Ref: DType)->getOffsetInBits();
1776}
1777
1778uint32_t LLVMDITypeGetAlignInBits(LLVMMetadataRef DType) {
1779 return unwrapDI<DIType>(Ref: DType)->getAlignInBits();
1780}
1781
1782unsigned LLVMDITypeGetLine(LLVMMetadataRef DType) {
1783 return unwrapDI<DIType>(Ref: DType)->getLine();
1784}
1785
1786LLVMDIFlags LLVMDITypeGetFlags(LLVMMetadataRef DType) {
1787 return map_to_llvmDIFlags(Flags: unwrapDI<DIType>(Ref: DType)->getFlags());
1788}
1789
1790LLVMMetadataRef LLVMDIBuilderGetOrCreateTypeArray(LLVMDIBuilderRef Builder,
1791 LLVMMetadataRef *Types,
1792 size_t Length) {
1793 return wrap(
1794 P: unwrap(P: Builder)->getOrCreateTypeArray(Elements: {unwrap(MDs: Types), Length}).get());
1795}
1796
1797LLVMMetadataRef
1798LLVMDIBuilderCreateSubroutineType(LLVMDIBuilderRef Builder,
1799 LLVMMetadataRef File,
1800 LLVMMetadataRef *ParameterTypes,
1801 unsigned NumParameterTypes,
1802 LLVMDIFlags Flags) {
1803 auto Elts = unwrap(P: Builder)->getOrCreateTypeArray(Elements: {unwrap(MDs: ParameterTypes),
1804 NumParameterTypes});
1805 return wrap(P: unwrap(P: Builder)->createSubroutineType(
1806 ParameterTypes: Elts, Flags: map_from_llvmDIFlags(Flags)));
1807}
1808
1809LLVMMetadataRef LLVMDIBuilderCreateExpression(LLVMDIBuilderRef Builder,
1810 uint64_t *Addr, size_t Length) {
1811 return wrap(
1812 P: unwrap(P: Builder)->createExpression(Addr: ArrayRef<uint64_t>(Addr, Length)));
1813}
1814
1815LLVMMetadataRef
1816LLVMDIBuilderCreateConstantValueExpression(LLVMDIBuilderRef Builder,
1817 uint64_t Value) {
1818 return wrap(P: unwrap(P: Builder)->createConstantValueExpression(Val: Value));
1819}
1820
1821LLVMMetadataRef LLVMDIBuilderCreateGlobalVariableExpression(
1822 LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
1823 size_t NameLen, const char *Linkage, size_t LinkLen, LLVMMetadataRef File,
1824 unsigned LineNo, LLVMMetadataRef Ty, LLVMBool LocalToUnit,
1825 LLVMMetadataRef Expr, LLVMMetadataRef Decl, uint32_t AlignInBits) {
1826 return wrap(P: unwrap(P: Builder)->createGlobalVariableExpression(
1827 Context: unwrapDI<DIScope>(Ref: Scope), Name: {Name, NameLen}, LinkageName: {Linkage, LinkLen},
1828 File: unwrapDI<DIFile>(Ref: File), LineNo, Ty: unwrapDI<DIType>(Ref: Ty), IsLocalToUnit: LocalToUnit,
1829 isDefined: true, Expr: unwrap<DIExpression>(P: Expr), Decl: unwrapDI<MDNode>(Ref: Decl),
1830 TemplateParams: nullptr, AlignInBits));
1831}
1832
1833LLVMMetadataRef LLVMDIGlobalVariableExpressionGetVariable(LLVMMetadataRef GVE) {
1834 return wrap(P: unwrapDI<DIGlobalVariableExpression>(Ref: GVE)->getVariable());
1835}
1836
1837LLVMMetadataRef LLVMDIGlobalVariableExpressionGetExpression(
1838 LLVMMetadataRef GVE) {
1839 return wrap(P: unwrapDI<DIGlobalVariableExpression>(Ref: GVE)->getExpression());
1840}
1841
1842LLVMMetadataRef LLVMDIVariableGetFile(LLVMMetadataRef Var) {
1843 return wrap(P: unwrapDI<DIVariable>(Ref: Var)->getFile());
1844}
1845
1846LLVMMetadataRef LLVMDIVariableGetScope(LLVMMetadataRef Var) {
1847 return wrap(P: unwrapDI<DIVariable>(Ref: Var)->getScope());
1848}
1849
1850unsigned LLVMDIVariableGetLine(LLVMMetadataRef Var) {
1851 return unwrapDI<DIVariable>(Ref: Var)->getLine();
1852}
1853
1854LLVMMetadataRef LLVMTemporaryMDNode(LLVMContextRef Ctx, LLVMMetadataRef *Data,
1855 size_t Count) {
1856 return wrap(
1857 P: MDTuple::getTemporary(Context&: *unwrap(P: Ctx), MDs: {unwrap(MDs: Data), Count}).release());
1858}
1859
1860void LLVMDisposeTemporaryMDNode(LLVMMetadataRef TempNode) {
1861 MDNode::deleteTemporary(N: unwrapDI<MDNode>(Ref: TempNode));
1862}
1863
1864void LLVMMetadataReplaceAllUsesWith(LLVMMetadataRef TargetMetadata,
1865 LLVMMetadataRef Replacement) {
1866 auto *Node = unwrapDI<MDNode>(Ref: TargetMetadata);
1867 Node->replaceAllUsesWith(MD: unwrap(P: Replacement));
1868 MDNode::deleteTemporary(N: Node);
1869}
1870
1871LLVMMetadataRef LLVMDIBuilderCreateTempGlobalVariableFwdDecl(
1872 LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
1873 size_t NameLen, const char *Linkage, size_t LnkLen, LLVMMetadataRef File,
1874 unsigned LineNo, LLVMMetadataRef Ty, LLVMBool LocalToUnit,
1875 LLVMMetadataRef Decl, uint32_t AlignInBits) {
1876 return wrap(P: unwrap(P: Builder)->createTempGlobalVariableFwdDecl(
1877 Context: unwrapDI<DIScope>(Ref: Scope), Name: {Name, NameLen}, LinkageName: {Linkage, LnkLen},
1878 File: unwrapDI<DIFile>(Ref: File), LineNo, Ty: unwrapDI<DIType>(Ref: Ty), IsLocalToUnit: LocalToUnit,
1879 Decl: unwrapDI<MDNode>(Ref: Decl), TemplateParams: nullptr, AlignInBits));
1880}
1881
1882LLVMDbgRecordRef LLVMDIBuilderInsertDeclareRecordBefore(
1883 LLVMDIBuilderRef Builder, LLVMValueRef Storage, LLVMMetadataRef VarInfo,
1884 LLVMMetadataRef Expr, LLVMMetadataRef DL, LLVMValueRef Instr) {
1885 DbgRecord *DbgInst = unwrap(P: Builder)->insertDeclare(
1886 Storage: unwrap(P: Storage), VarInfo: unwrap<DILocalVariable>(P: VarInfo),
1887 Expr: unwrap<DIExpression>(P: Expr), DL: unwrap<DILocation>(P: DL),
1888 InsertPt: Instr ? InsertPosition(unwrap<Instruction>(P: Instr)->getIterator())
1889 : nullptr);
1890 return wrap(P: DbgInst);
1891}
1892
1893LLVMDbgRecordRef LLVMDIBuilderInsertDeclareRecordAtEnd(
1894 LLVMDIBuilderRef Builder, LLVMValueRef Storage, LLVMMetadataRef VarInfo,
1895 LLVMMetadataRef Expr, LLVMMetadataRef DL, LLVMBasicBlockRef Block) {
1896 DbgRecord *DbgInst = unwrap(P: Builder)->insertDeclare(
1897 Storage: unwrap(P: Storage), VarInfo: unwrap<DILocalVariable>(P: VarInfo),
1898 Expr: unwrap<DIExpression>(P: Expr), DL: unwrap<DILocation>(P: DL), InsertAtEnd: unwrap(P: Block));
1899 return wrap(P: DbgInst);
1900}
1901
1902LLVMDbgRecordRef LLVMDIBuilderInsertDbgValueRecordBefore(
1903 LLVMDIBuilderRef Builder, LLVMValueRef Val, LLVMMetadataRef VarInfo,
1904 LLVMMetadataRef Expr, LLVMMetadataRef DebugLoc, LLVMValueRef Instr) {
1905 DbgRecord *DbgInst = unwrap(P: Builder)->insertDbgValue(
1906 Val: unwrap(P: Val), VarInfo: unwrap<DILocalVariable>(P: VarInfo), Expr: unwrap<DIExpression>(P: Expr),
1907 DL: unwrap<DILocation>(P: DebugLoc),
1908 InsertPt: Instr ? InsertPosition(unwrap<Instruction>(P: Instr)->getIterator())
1909 : nullptr);
1910 return wrap(P: DbgInst);
1911}
1912
1913LLVMDbgRecordRef LLVMDIBuilderInsertDbgValueRecordAtEnd(
1914 LLVMDIBuilderRef Builder, LLVMValueRef Val, LLVMMetadataRef VarInfo,
1915 LLVMMetadataRef Expr, LLVMMetadataRef DebugLoc, LLVMBasicBlockRef Block) {
1916 DbgRecord *DbgInst = unwrap(P: Builder)->insertDbgValue(
1917 Val: unwrap(P: Val), VarInfo: unwrap<DILocalVariable>(P: VarInfo), Expr: unwrap<DIExpression>(P: Expr),
1918 DL: unwrap<DILocation>(P: DebugLoc),
1919 InsertPt: Block ? InsertPosition(unwrap(P: Block)->end()) : nullptr);
1920 return wrap(P: DbgInst);
1921}
1922
1923LLVMMetadataRef LLVMDIBuilderCreateAutoVariable(
1924 LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
1925 size_t NameLen, LLVMMetadataRef File, unsigned LineNo, LLVMMetadataRef Ty,
1926 LLVMBool AlwaysPreserve, LLVMDIFlags Flags, uint32_t AlignInBits) {
1927 return wrap(P: unwrap(P: Builder)->createAutoVariable(
1928 Scope: unwrap<DIScope>(P: Scope), Name: {Name, NameLen}, File: unwrap<DIFile>(P: File),
1929 LineNo, Ty: unwrap<DIType>(P: Ty), AlwaysPreserve,
1930 Flags: map_from_llvmDIFlags(Flags), AlignInBits));
1931}
1932
1933LLVMMetadataRef LLVMDIBuilderCreateParameterVariable(
1934 LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, const char *Name,
1935 size_t NameLen, unsigned ArgNo, LLVMMetadataRef File, unsigned LineNo,
1936 LLVMMetadataRef Ty, LLVMBool AlwaysPreserve, LLVMDIFlags Flags) {
1937 return wrap(P: unwrap(P: Builder)->createParameterVariable(
1938 Scope: unwrap<DIScope>(P: Scope), Name: {Name, NameLen}, ArgNo, File: unwrap<DIFile>(P: File),
1939 LineNo, Ty: unwrap<DIType>(P: Ty), AlwaysPreserve,
1940 Flags: map_from_llvmDIFlags(Flags)));
1941}
1942
1943LLVMMetadataRef LLVMDIBuilderGetOrCreateSubrange(LLVMDIBuilderRef Builder,
1944 int64_t Lo, int64_t Count) {
1945 return wrap(P: unwrap(P: Builder)->getOrCreateSubrange(Lo, Count));
1946}
1947
1948LLVMMetadataRef LLVMDIBuilderGetOrCreateArray(LLVMDIBuilderRef Builder,
1949 LLVMMetadataRef *Data,
1950 size_t Length) {
1951 Metadata **DataValue = unwrap(MDs: Data);
1952 return wrap(P: unwrap(P: Builder)->getOrCreateArray(Elements: {DataValue, Length}).get());
1953}
1954
1955LLVMMetadataRef LLVMGetSubprogram(LLVMValueRef Func) {
1956 return wrap(P: unwrap<Function>(P: Func)->getSubprogram());
1957}
1958
1959void LLVMSetSubprogram(LLVMValueRef Func, LLVMMetadataRef SP) {
1960 unwrap<Function>(P: Func)->setSubprogram(unwrap<DISubprogram>(P: SP));
1961}
1962
1963unsigned LLVMDISubprogramGetLine(LLVMMetadataRef Subprogram) {
1964 return unwrapDI<DISubprogram>(Ref: Subprogram)->getLine();
1965}
1966
1967void LLVMDISubprogramReplaceType(LLVMMetadataRef Subprogram,
1968 LLVMMetadataRef SubroutineType) {
1969 unwrapDI<DISubprogram>(Ref: Subprogram)
1970 ->replaceType(Ty: unwrapDI<DISubroutineType>(Ref: SubroutineType));
1971}
1972
1973LLVMMetadataRef LLVMInstructionGetDebugLoc(LLVMValueRef Inst) {
1974 return wrap(P: unwrap<Instruction>(P: Inst)->getDebugLoc().getAsMDNode());
1975}
1976
1977void LLVMInstructionSetDebugLoc(LLVMValueRef Inst, LLVMMetadataRef Loc) {
1978 if (Loc)
1979 unwrap<Instruction>(P: Inst)->setDebugLoc(DebugLoc(unwrap<DILocation>(P: Loc)));
1980 else
1981 unwrap<Instruction>(P: Inst)->setDebugLoc(DebugLoc());
1982}
1983
1984LLVMMetadataRef LLVMDIBuilderCreateLabel(LLVMDIBuilderRef Builder,
1985 LLVMMetadataRef Context,
1986 const char *Name, size_t NameLen,
1987 LLVMMetadataRef File, unsigned LineNo,
1988 LLVMBool AlwaysPreserve) {
1989 return wrap(P: unwrap(P: Builder)->createLabel(
1990 Scope: unwrapDI<DIScope>(Ref: Context), Name: StringRef(Name, NameLen),
1991 File: unwrapDI<DIFile>(Ref: File), LineNo, /*Column*/ 0, /*IsArtificial*/ false,
1992 /*CoroSuspendIdx*/ std::nullopt, AlwaysPreserve));
1993}
1994
1995LLVMDbgRecordRef LLVMDIBuilderInsertLabelBefore(LLVMDIBuilderRef Builder,
1996 LLVMMetadataRef LabelInfo,
1997 LLVMMetadataRef Location,
1998 LLVMValueRef InsertBefore) {
1999 DbgRecord *DbgInst = unwrap(P: Builder)->insertLabel(
2000 LabelInfo: unwrapDI<DILabel>(Ref: LabelInfo), DL: unwrapDI<DILocation>(Ref: Location),
2001 InsertPt: InsertBefore
2002 ? InsertPosition(unwrap<Instruction>(P: InsertBefore)->getIterator())
2003 : nullptr);
2004 return wrap(P: DbgInst);
2005}
2006
2007LLVMDbgRecordRef LLVMDIBuilderInsertLabelAtEnd(LLVMDIBuilderRef Builder,
2008 LLVMMetadataRef LabelInfo,
2009 LLVMMetadataRef Location,
2010 LLVMBasicBlockRef InsertAtEnd) {
2011 DbgRecord *DbgInst = unwrap(P: Builder)->insertLabel(
2012 LabelInfo: unwrapDI<DILabel>(Ref: LabelInfo), DL: unwrapDI<DILocation>(Ref: Location),
2013 InsertPt: InsertAtEnd ? InsertPosition(unwrap(P: InsertAtEnd)->end()) : nullptr);
2014 return wrap(P: DbgInst);
2015}
2016
2017LLVMMetadataKind LLVMGetMetadataKind(LLVMMetadataRef Metadata) {
2018 switch(unwrap(P: Metadata)->getMetadataID()) {
2019#define HANDLE_METADATA_LEAF(CLASS) \
2020 case Metadata::CLASS##Kind: \
2021 return (LLVMMetadataKind)LLVM##CLASS##MetadataKind;
2022#include "llvm/IR/Metadata.def"
2023 default:
2024 return (LLVMMetadataKind)LLVMGenericDINodeMetadataKind;
2025 }
2026}
2027
2028void at::deleteAssignmentMarkers(const Instruction *Inst) {
2029 for (auto *DVR : getDVRAssignmentMarkers(Inst))
2030 DVR->eraseFromParent();
2031}
2032
2033void at::RAUW(DIAssignID *Old, DIAssignID *New) {
2034 // Replace attachments.
2035 AssignmentInstRange InstRange = getAssignmentInsts(ID: Old);
2036 // Use intermediate storage for the instruction ptrs because the
2037 // getAssignmentInsts range iterators will be invalidated by adding and
2038 // removing DIAssignID attachments.
2039 SmallVector<Instruction *> InstVec(InstRange.begin(), InstRange.end());
2040 for (auto *I : InstVec)
2041 I->setMetadata(KindID: LLVMContext::MD_DIAssignID, Node: New);
2042
2043 for (DbgVariableRecord *DVR :
2044 SmallVector<DbgVariableRecord *>(Old->getRecords()))
2045 DVR->setAssignId(New);
2046}
2047
2048void at::deleteAll(Function *F) {
2049 for (BasicBlock &BB : *F) {
2050 for (Instruction &I : BB) {
2051 for (DbgVariableRecord &DVR :
2052 make_early_inc_range(Range: filterDbgVars(R: I.getDbgRecordRange())))
2053 if (DVR.isDbgAssign())
2054 DVR.eraseFromParent();
2055
2056 I.setMetadata(KindID: LLVMContext::MD_DIAssignID, Node: nullptr);
2057 }
2058 }
2059}
2060
2061bool at::calculateFragmentIntersect(
2062 const DataLayout &DL, const Value *Dest, uint64_t SliceOffsetInBits,
2063 uint64_t SliceSizeInBits, const DbgVariableRecord *AssignRecord,
2064 std::optional<DIExpression::FragmentInfo> &Result) {
2065 // No overlap if this DbgRecord describes a killed location.
2066 if (AssignRecord->isKillAddress())
2067 return false;
2068
2069 int64_t AddrOffsetInBits;
2070 {
2071 int64_t AddrOffsetInBytes;
2072 SmallVector<uint64_t> PostOffsetOps; //< Unused.
2073 // Bail if we can't find a constant offset (or none) in the expression.
2074 if (!AssignRecord->getAddressExpression()->extractLeadingOffset(
2075 OffsetInBytes&: AddrOffsetInBytes, RemainingOps&: PostOffsetOps))
2076 return false;
2077 AddrOffsetInBits = AddrOffsetInBytes * 8;
2078 }
2079
2080 Value *Addr = AssignRecord->getAddress();
2081 // FIXME: It may not always be zero.
2082 int64_t BitExtractOffsetInBits = 0;
2083 DIExpression::FragmentInfo VarFrag =
2084 AssignRecord->getFragmentOrEntireVariable();
2085
2086 int64_t OffsetFromLocationInBits; //< Unused.
2087 return DIExpression::calculateFragmentIntersect(
2088 DL, SliceStart: Dest, SliceOffsetInBits, SliceSizeInBits, DbgPtr: Addr, DbgPtrOffsetInBits: AddrOffsetInBits,
2089 DbgExtractOffsetInBits: BitExtractOffsetInBits, VarFrag, Result, OffsetFromLocationInBits);
2090}
2091
2092/// Update inlined instructions' DIAssignID metadata. We need to do this
2093/// otherwise a function inlined more than once into the same function
2094/// will cause DIAssignID to be shared by many instructions.
2095void at::remapAssignID(DenseMap<DIAssignID *, DIAssignID *> &Map,
2096 Instruction &I) {
2097 auto GetNewID = [&Map](Metadata *Old) {
2098 DIAssignID *OldID = cast<DIAssignID>(Val: Old);
2099 if (DIAssignID *NewID = Map.lookup(Val: OldID))
2100 return NewID;
2101 DIAssignID *NewID = DIAssignID::getDistinct(Context&: OldID->getContext());
2102 Map[OldID] = NewID;
2103 return NewID;
2104 };
2105 // If we find a DIAssignID attachment or use, replace it with a new version.
2106 for (DbgVariableRecord &DVR : filterDbgVars(R: I.getDbgRecordRange())) {
2107 if (DVR.isDbgAssign())
2108 DVR.setAssignId(GetNewID(DVR.getAssignID()));
2109 }
2110 if (auto *ID = I.getMetadata(KindID: LLVMContext::MD_DIAssignID))
2111 I.setMetadata(KindID: LLVMContext::MD_DIAssignID, Node: GetNewID(ID));
2112}
2113
2114/// Collect constant properties (base, size, offset) of \p StoreDest.
2115/// Return std::nullopt if any properties are not constants or the
2116/// offset from the base pointer is negative.
2117static std::optional<AssignmentInfo>
2118getAssignmentInfoImpl(const DataLayout &DL, const Value *StoreDest,
2119 TypeSize SizeInBits) {
2120 if (SizeInBits.isScalable())
2121 return std::nullopt;
2122 APInt GEPOffset(DL.getIndexTypeSizeInBits(Ty: StoreDest->getType()), 0);
2123 const Value *Base = StoreDest->stripAndAccumulateConstantOffsets(
2124 DL, Offset&: GEPOffset, /*AllowNonInbounds*/ true);
2125
2126 if (GEPOffset.isNegative())
2127 return std::nullopt;
2128
2129 uint64_t OffsetInBytes = GEPOffset.getLimitedValue();
2130 // Check for overflow.
2131 if (OffsetInBytes == UINT64_MAX)
2132 return std::nullopt;
2133 if (const auto *Alloca = dyn_cast<AllocaInst>(Val: Base))
2134 if (!Alloca->isScalable())
2135 return AssignmentInfo(DL, Alloca, OffsetInBytes * 8, SizeInBits);
2136 return std::nullopt;
2137}
2138
2139std::optional<AssignmentInfo> at::getAssignmentInfo(const DataLayout &DL,
2140 const MemIntrinsic *I) {
2141 const Value *StoreDest = I->getRawDest();
2142 // Assume 8 bit bytes.
2143 auto *ConstLengthInBytes = dyn_cast<ConstantInt>(Val: I->getLength());
2144 if (!ConstLengthInBytes)
2145 // We can't use a non-const size, bail.
2146 return std::nullopt;
2147 uint64_t SizeInBits = 8 * ConstLengthInBytes->getZExtValue();
2148 return getAssignmentInfoImpl(DL, StoreDest, SizeInBits: TypeSize::getFixed(ExactSize: SizeInBits));
2149}
2150
2151std::optional<AssignmentInfo> at::getAssignmentInfo(const DataLayout &DL,
2152 const StoreInst *SI) {
2153 TypeSize SizeInBits = DL.getTypeSizeInBits(Ty: SI->getValueOperand()->getType());
2154 return getAssignmentInfoImpl(DL, StoreDest: SI->getPointerOperand(), SizeInBits);
2155}
2156
2157std::optional<AssignmentInfo> at::getAssignmentInfo(const DataLayout &DL,
2158 const AllocaInst *AI) {
2159 TypeSize SizeInBits = DL.getTypeSizeInBits(Ty: AI->getAllocatedType());
2160 return getAssignmentInfoImpl(DL, StoreDest: AI, SizeInBits);
2161}
2162
2163/// Returns nullptr if the assignment shouldn't be attributed to this variable.
2164static void emitDbgAssign(AssignmentInfo Info, Value *Val, Value *Dest,
2165 Instruction &StoreLikeInst, const VarRecord &VarRec,
2166 DIBuilder &DIB) {
2167 auto *ID = StoreLikeInst.getMetadata(KindID: LLVMContext::MD_DIAssignID);
2168 assert(ID && "Store instruction must have DIAssignID metadata");
2169 (void)ID;
2170
2171 const uint64_t StoreStartBit = Info.OffsetInBits;
2172 const uint64_t StoreEndBit = Info.OffsetInBits + Info.SizeInBits;
2173
2174 uint64_t FragStartBit = StoreStartBit;
2175 uint64_t FragEndBit = StoreEndBit;
2176
2177 bool StoreToWholeVariable = Info.StoreToWholeAlloca;
2178 if (auto Size = VarRec.Var->getSizeInBits()) {
2179 // NOTE: trackAssignments doesn't understand base expressions yet, so all
2180 // variables that reach here are guaranteed to start at offset 0 in the
2181 // alloca.
2182 const uint64_t VarStartBit = 0;
2183 const uint64_t VarEndBit = *Size;
2184
2185 // FIXME: trim FragStartBit when nonzero VarStartBit is supported.
2186 FragEndBit = std::min(a: FragEndBit, b: VarEndBit);
2187
2188 // Discard stores to bits outside this variable.
2189 if (FragStartBit >= FragEndBit)
2190 return;
2191
2192 StoreToWholeVariable = FragStartBit <= VarStartBit && FragEndBit >= *Size;
2193 }
2194
2195 DIExpression *Expr = DIExpression::get(Context&: StoreLikeInst.getContext(), Elements: {});
2196 if (!StoreToWholeVariable) {
2197 auto R = DIExpression::createFragmentExpression(Expr, OffsetInBits: FragStartBit,
2198 SizeInBits: FragEndBit - FragStartBit);
2199 assert(R.has_value() && "failed to create fragment expression");
2200 Expr = *R;
2201 }
2202 DIExpression *AddrExpr = DIExpression::get(Context&: StoreLikeInst.getContext(), Elements: {});
2203 auto *Assign = DbgVariableRecord::createLinkedDVRAssign(
2204 LinkedInstr: &StoreLikeInst, Val, Variable: VarRec.Var, Expression: Expr, Address: Dest, AddressExpression: AddrExpr, DI: VarRec.DL);
2205 (void)Assign;
2206 LLVM_DEBUG(if (Assign) errs() << " > INSERT: " << *Assign << "\n");
2207}
2208
2209#undef DEBUG_TYPE // Silence redefinition warning (from ConstantsContext.h).
2210#define DEBUG_TYPE "assignment-tracking"
2211
2212void at::trackAssignments(Function::iterator Start, Function::iterator End,
2213 const StorageToVarsMap &Vars, const DataLayout &DL,
2214 bool DebugPrints) {
2215 // Early-exit if there are no interesting variables.
2216 if (Vars.empty())
2217 return;
2218
2219 auto &Ctx = Start->getContext();
2220 auto &Module = *Start->getModule();
2221
2222 // Poison type doesn't matter, so long as it isn't void. Let's just use i1.
2223 auto *Poison = PoisonValue::get(T: Type::getInt1Ty(C&: Ctx));
2224 DIBuilder DIB(Module, /*AllowUnresolved*/ false);
2225
2226 // Scan the instructions looking for stores to local variables' storage.
2227 LLVM_DEBUG(errs() << "# Scanning instructions\n");
2228 for (auto BBI = Start; BBI != End; ++BBI) {
2229 for (Instruction &I : *BBI) {
2230
2231 std::optional<AssignmentInfo> Info;
2232 Value *ValueComponent = nullptr;
2233 Value *DestComponent = nullptr;
2234 if (auto *AI = dyn_cast<AllocaInst>(Val: &I)) {
2235 // We want to track the variable's stack home from its alloca's
2236 // position onwards so we treat it as an assignment (where the stored
2237 // value is poison).
2238 Info = getAssignmentInfo(DL, AI);
2239 ValueComponent = Poison;
2240 DestComponent = AI;
2241 } else if (auto *SI = dyn_cast<StoreInst>(Val: &I)) {
2242 Info = getAssignmentInfo(DL, SI);
2243 ValueComponent = SI->getValueOperand();
2244 DestComponent = SI->getPointerOperand();
2245 } else if (auto *MI = dyn_cast<MemTransferInst>(Val: &I)) {
2246 Info = getAssignmentInfo(DL, I: MI);
2247 // May not be able to represent this value easily.
2248 ValueComponent = Poison;
2249 DestComponent = MI->getOperand(i_nocapture: 0);
2250 } else if (auto *MI = dyn_cast<MemSetInst>(Val: &I)) {
2251 Info = getAssignmentInfo(DL, I: MI);
2252 // If we're zero-initing we can state the assigned value is zero,
2253 // otherwise use undef.
2254 auto *ConstValue = dyn_cast<ConstantInt>(Val: MI->getOperand(i_nocapture: 1));
2255 if (ConstValue && ConstValue->isZero())
2256 ValueComponent = ConstValue;
2257 else
2258 ValueComponent = Poison;
2259 DestComponent = MI->getOperand(i_nocapture: 0);
2260 } else {
2261 // Not a store-like instruction.
2262 continue;
2263 }
2264
2265 assert(ValueComponent && DestComponent);
2266 LLVM_DEBUG(errs() << "SCAN: Found store-like: " << I << "\n");
2267
2268 // Check if getAssignmentInfo failed to understand this store.
2269 if (!Info.has_value()) {
2270 LLVM_DEBUG(
2271 errs()
2272 << " | SKIP: Untrackable store (e.g. through non-const gep)\n");
2273 continue;
2274 }
2275 LLVM_DEBUG(errs() << " | BASE: " << *Info->Base << "\n");
2276
2277 // Check if the store destination is a local variable with debug info.
2278 auto LocalIt = Vars.find(Val: Info->Base);
2279 if (LocalIt == Vars.end()) {
2280 LLVM_DEBUG(
2281 errs()
2282 << " | SKIP: Base address not associated with local variable\n");
2283 continue;
2284 }
2285
2286 DIAssignID *ID =
2287 cast_or_null<DIAssignID>(Val: I.getMetadata(KindID: LLVMContext::MD_DIAssignID));
2288 if (!ID) {
2289 ID = DIAssignID::getDistinct(Context&: Ctx);
2290 I.setMetadata(KindID: LLVMContext::MD_DIAssignID, Node: ID);
2291 }
2292
2293 for (const VarRecord &R : LocalIt->second)
2294 emitDbgAssign(Info: *Info, Val: ValueComponent, Dest: DestComponent, StoreLikeInst&: I, VarRec: R, DIB);
2295 }
2296 }
2297}
2298
2299bool AssignmentTrackingPass::runOnFunction(Function &F) {
2300 // No value in assignment tracking without optimisations.
2301 if (F.hasFnAttribute(Kind: Attribute::OptimizeNone))
2302 return /*Changed*/ false;
2303
2304 bool Changed = false;
2305 auto *DL = &F.getDataLayout();
2306 // Collect a map of {backing storage : dbg.declares} (currently "backing
2307 // storage" is limited to Allocas). We'll use this to find dbg.declares to
2308 // delete after running `trackAssignments`.
2309 DenseMap<const AllocaInst *, SmallPtrSet<DbgVariableRecord *, 2>> DVRDeclares;
2310 // Create another similar map of {storage : variables} that we'll pass to
2311 // trackAssignments.
2312 StorageToVarsMap Vars;
2313 auto ProcessDeclare = [&](DbgVariableRecord &Declare) {
2314 // FIXME: trackAssignments doesn't let you specify any modifiers to the
2315 // variable (e.g. fragment) or location (e.g. offset), so we have to
2316 // leave dbg.declares with non-empty expressions in place.
2317 if (Declare.getExpression()->getNumElements() != 0)
2318 return;
2319 if (!Declare.getAddress())
2320 return;
2321 if (AllocaInst *Alloca =
2322 dyn_cast<AllocaInst>(Val: Declare.getAddress()->stripPointerCasts())) {
2323 // FIXME: Skip VLAs for now (let these variables use dbg.declares).
2324 if (!Alloca->isStaticAlloca())
2325 return;
2326 // Similarly, skip scalable vectors (use dbg.declares instead).
2327 if (auto Sz = Alloca->getAllocationSize(DL: *DL); Sz && Sz->isScalable())
2328 return;
2329 DVRDeclares[Alloca].insert(Ptr: &Declare);
2330 Vars[Alloca].insert(X: VarRecord(&Declare));
2331 }
2332 };
2333 for (auto &BB : F) {
2334 for (auto &I : BB) {
2335 for (DbgVariableRecord &DVR : filterDbgVars(R: I.getDbgRecordRange())) {
2336 if (DVR.isDbgDeclare())
2337 ProcessDeclare(DVR);
2338 }
2339 }
2340 }
2341
2342 // FIXME: Locals can be backed by caller allocas (sret, byval).
2343 // Note: trackAssignments doesn't respect dbg.declare's IR positions (as it
2344 // doesn't "understand" dbg.declares). However, this doesn't appear to break
2345 // any rules given this description of dbg.declare from
2346 // llvm/docs/SourceLevelDebugging.md:
2347 //
2348 // It is not control-dependent, meaning that if a call to llvm.dbg.declare
2349 // exists and has a valid location argument, that address is considered to
2350 // be the true home of the variable across its entire lifetime.
2351 trackAssignments(Start: F.begin(), End: F.end(), Vars, DL: *DL);
2352
2353 // Delete dbg.declares for variables now tracked with assignment tracking.
2354 for (auto &[Insts, Declares] : DVRDeclares) {
2355 auto Markers = at::getDVRAssignmentMarkers(Inst: Insts);
2356 for (auto *Declare : Declares) {
2357 // Assert that the alloca that Declare uses is now linked to a dbg.assign
2358 // describing the same variable (i.e. check that this dbg.declare has
2359 // been replaced by a dbg.assign). Use DebugVariableAggregate to Discard
2360 // the fragment part because trackAssignments may alter the
2361 // fragment. e.g. if the alloca is smaller than the variable, then
2362 // trackAssignments will create an alloca-sized fragment for the
2363 // dbg.assign.
2364 assert(llvm::any_of(Markers, [Declare](auto *Assign) {
2365 return DebugVariableAggregate(Assign) ==
2366 DebugVariableAggregate(Declare);
2367 }));
2368 // Delete Declare because the variable location is now tracked using
2369 // assignment tracking.
2370 Declare->eraseFromParent();
2371 Changed = true;
2372 }
2373 };
2374 return Changed;
2375}
2376
2377static const char *AssignmentTrackingModuleFlag =
2378 "debug-info-assignment-tracking";
2379
2380static void setAssignmentTrackingModuleFlag(Module &M) {
2381 M.setModuleFlag(Behavior: Module::ModFlagBehavior::Max, Key: AssignmentTrackingModuleFlag,
2382 Val: ConstantAsMetadata::get(
2383 C: ConstantInt::get(Ty: Type::getInt1Ty(C&: M.getContext()), V: 1)));
2384}
2385
2386static bool getAssignmentTrackingModuleFlag(const Module &M) {
2387 Metadata *Value = M.getModuleFlag(Key: AssignmentTrackingModuleFlag);
2388 return Value && !cast<ConstantAsMetadata>(Val: Value)->getValue()->isNullValue();
2389}
2390
2391bool llvm::isAssignmentTrackingEnabled(const Module &M) {
2392 return getAssignmentTrackingModuleFlag(M);
2393}
2394
2395PreservedAnalyses AssignmentTrackingPass::run(Function &F,
2396 FunctionAnalysisManager &AM) {
2397 if (!runOnFunction(F))
2398 return PreservedAnalyses::all();
2399
2400 // Record that this module uses assignment tracking. It doesn't matter that
2401 // some functions in the module may not use it - the debug info in those
2402 // functions will still be handled properly.
2403 setAssignmentTrackingModuleFlag(*F.getParent());
2404
2405 // Q: Can we return a less conservative set than just CFGAnalyses? Can we
2406 // return PreservedAnalyses::all()?
2407 PreservedAnalyses PA;
2408 PA.preserveSet<CFGAnalyses>();
2409 return PA;
2410}
2411
2412PreservedAnalyses AssignmentTrackingPass::run(Module &M,
2413 ModuleAnalysisManager &AM) {
2414 bool Changed = false;
2415 for (auto &F : M)
2416 Changed |= runOnFunction(F);
2417
2418 if (!Changed)
2419 return PreservedAnalyses::all();
2420
2421 // Record that this module uses assignment tracking.
2422 setAssignmentTrackingModuleFlag(M);
2423
2424 // Q: Can we return a less conservative set than just CFGAnalyses? Can we
2425 // return PreservedAnalyses::all()?
2426 PreservedAnalyses PA;
2427 PA.preserveSet<CFGAnalyses>();
2428 return PA;
2429}
2430
2431#undef DEBUG_TYPE
2432