|
17 | 17 | #include "llvm-c/Types.h"
|
18 | 18 | #include "llvm/ADT/ArrayRef.h"
|
19 | 19 | #include "llvm/ADT/None.h"
|
| 20 | +#include "llvm/ADT/STLExtras.h" |
20 | 21 | #include "llvm/ADT/StringRef.h"
|
21 | 22 | #include "llvm/ADT/Twine.h"
|
22 | 23 | #include "llvm/IR/BasicBlock.h"
|
23 | 24 | #include "llvm/IR/Constant.h"
|
24 | 25 | #include "llvm/IR/ConstantFolder.h"
|
25 | 26 | #include "llvm/IR/Constants.h"
|
26 | 27 | #include "llvm/IR/DataLayout.h"
|
| 28 | +#include "llvm/IR/DebugInfoMetadata.h" |
27 | 29 | #include "llvm/IR/DebugLoc.h"
|
28 | 30 | #include "llvm/IR/DerivedTypes.h"
|
29 | 31 | #include "llvm/IR/Function.h"
|
@@ -91,7 +93,28 @@ class IRBuilderCallbackInserter : public IRBuilderDefaultInserter {
|
91 | 93 |
|
92 | 94 | /// Common base class shared among various IRBuilders.
|
93 | 95 | class IRBuilderBase {
|
94 |
| - DebugLoc CurDbgLocation; |
| 96 | + /// Pairs of (metadata kind, MDNode *) that should be added to all newly |
| 97 | + /// created instructions, like !dbg metadata. |
| 98 | + SmallVector<std::pair<unsigned, MDNode *>, 2> MetadataToCopy; |
| 99 | + |
| 100 | + /// Add or update the an entry (Kind, MD) to MetadataToCopy, if \p MD is not |
| 101 | + /// null. If \p MD is null, remove the entry with \p Kind. |
| 102 | + void AddOrRemoveMetadataToCopy(unsigned Kind, MDNode *MD) { |
| 103 | + if (!MD) { |
| 104 | + erase_if(MetadataToCopy, [Kind](const std::pair<unsigned, MDNode *> &KV) { |
| 105 | + return KV.first == Kind; |
| 106 | + }); |
| 107 | + return; |
| 108 | + } |
| 109 | + |
| 110 | + for (auto &KV : MetadataToCopy) |
| 111 | + if (KV.first == Kind) { |
| 112 | + KV.second = MD; |
| 113 | + return; |
| 114 | + } |
| 115 | + |
| 116 | + MetadataToCopy.emplace_back(Kind, MD); |
| 117 | + } |
95 | 118 |
|
96 | 119 | protected:
|
97 | 120 | BasicBlock *BB;
|
@@ -125,7 +148,7 @@ class IRBuilderBase {
|
125 | 148 | template<typename InstTy>
|
126 | 149 | InstTy *Insert(InstTy *I, const Twine &Name = "") const {
|
127 | 150 | Inserter.InsertHelper(I, Name, BB, InsertPt);
|
128 |
| - SetInstDebugLocation(I); |
| 151 | + AddMetadataToInst(I); |
129 | 152 | return I;
|
130 | 153 | }
|
131 | 154 |
|
@@ -182,16 +205,42 @@ class IRBuilderBase {
|
182 | 205 | }
|
183 | 206 |
|
184 | 207 | /// Set location information used by debugging information.
|
185 |
| - void SetCurrentDebugLocation(DebugLoc L) { CurDbgLocation = std::move(L); } |
| 208 | + void SetCurrentDebugLocation(DebugLoc L) { |
| 209 | + AddOrRemoveMetadataToCopy(LLVMContext::MD_dbg, L.getAsMDNode()); |
| 210 | + } |
| 211 | + |
| 212 | + /// Collect metadata with IDs \p MetadataKinds from \p Src which should be |
| 213 | + /// added to all created instructions. Entries present in MedataDataToCopy but |
| 214 | + /// not on \p Src will be dropped from MetadataToCopy. |
| 215 | + void CollectMetadataToCopy(Instruction *Src, |
| 216 | + ArrayRef<unsigned> MetadataKinds) { |
| 217 | + for (unsigned K : MetadataKinds) |
| 218 | + AddOrRemoveMetadataToCopy(K, Src->getMetadata(K)); |
| 219 | + } |
186 | 220 |
|
187 | 221 | /// Get location information used by debugging information.
|
188 |
| - const DebugLoc &getCurrentDebugLocation() const { return CurDbgLocation; } |
| 222 | + DebugLoc getCurrentDebugLocation() const { |
| 223 | + for (auto &KV : MetadataToCopy) |
| 224 | + if (KV.first == LLVMContext::MD_dbg) |
| 225 | + return {cast<DILocation>(KV.second)}; |
| 226 | + |
| 227 | + return {}; |
| 228 | + } |
189 | 229 |
|
190 | 230 | /// If this builder has a current debug location, set it on the
|
191 | 231 | /// specified instruction.
|
192 | 232 | void SetInstDebugLocation(Instruction *I) const {
|
193 |
| - if (CurDbgLocation) |
194 |
| - I->setDebugLoc(CurDbgLocation); |
| 233 | + for (const auto &KV : MetadataToCopy) |
| 234 | + if (KV.first == LLVMContext::MD_dbg) { |
| 235 | + I->setDebugLoc(DebugLoc(KV.second)); |
| 236 | + return; |
| 237 | + } |
| 238 | + } |
| 239 | + |
| 240 | + /// Add all entries in MetadataToCopy to \p I. |
| 241 | + void AddMetadataToInst(Instruction *I) const { |
| 242 | + for (auto &KV : MetadataToCopy) |
| 243 | + I->setMetadata(KV.first, KV.second); |
195 | 244 | }
|
196 | 245 |
|
197 | 246 | /// Get the return type of the current function that we're emitting
|
|
0 commit comments