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