@@ -117,11 +117,8 @@ static DINodeT *getDistinctOrUnique(bool isDistinct, Ts &&...args) {
117
117
}
118
118
119
119
llvm::DICompositeType *
120
- DebugTranslation::translateImpl (DICompositeTypeAttr attr) {
121
- SmallVector<llvm::Metadata *> elements;
122
- for (auto member : attr.getElements ())
123
- elements.push_back (translate (member));
124
-
120
+ DebugTranslation::translateImpl (DICompositeTypeAttr attr,
121
+ SetRecursivePlaceholderFn setRec) {
125
122
// TODO: Use distinct attributes to model this, once they have landed.
126
123
// Depending on the tag, composite types must be distinct.
127
124
bool isDistinct = false ;
@@ -133,15 +130,26 @@ DebugTranslation::translateImpl(DICompositeTypeAttr attr) {
133
130
isDistinct = true ;
134
131
}
135
132
136
- return getDistinctOrUnique<llvm::DICompositeType>(
137
- isDistinct, llvmCtx, attr.getTag (), getMDStringOrNull (attr.getName ()),
138
- translate (attr.getFile ()), attr.getLine (), translate (attr.getScope ()),
139
- translate (attr.getBaseType ()), attr.getSizeInBits (),
140
- attr.getAlignInBits (),
141
- /* OffsetInBits=*/ 0 ,
142
- /* Flags=*/ static_cast <llvm::DINode::DIFlags>(attr.getFlags ()),
143
- llvm::MDNode::get (llvmCtx, elements),
144
- /* RuntimeLang=*/ 0 , /* VTableHolder=*/ nullptr );
133
+ llvm::DICompositeType *placeholder =
134
+ getDistinctOrUnique<llvm::DICompositeType>(
135
+ isDistinct, llvmCtx, attr.getTag (), getMDStringOrNull (attr.getName ()),
136
+ translate (attr.getFile ()), attr.getLine (), translate (attr.getScope ()),
137
+ translate (attr.getBaseType ()), attr.getSizeInBits (),
138
+ attr.getAlignInBits (),
139
+ /* OffsetInBits=*/ 0 ,
140
+ /* Flags=*/ static_cast <llvm::DINode::DIFlags>(attr.getFlags ()),
141
+ /* Elements=*/ nullptr , /* RuntimeLang=*/ 0 , /* VTableHolder=*/ nullptr );
142
+
143
+ if (setRec)
144
+ setRec (placeholder);
145
+
146
+ SmallVector<llvm::Metadata *> elements;
147
+ for (auto member : attr.getElements ())
148
+ elements.push_back (translate (member));
149
+
150
+ placeholder->replaceElements (llvm::MDNode::get (llvmCtx, elements));
151
+
152
+ return placeholder;
145
153
}
146
154
147
155
llvm::DIDerivedType *DebugTranslation::translateImpl (DIDerivedTypeAttr attr) {
@@ -200,22 +208,66 @@ DebugTranslation::translateImpl(DIGlobalVariableAttr attr) {
200
208
attr.getIsDefined (), nullptr , nullptr , attr.getAlignInBits (), nullptr );
201
209
}
202
210
211
+ llvm::DIType *DebugTranslation::translateImpl (DIRecursiveTypeAttr attr) {
212
+ if (attr.isRecSelf ()) {
213
+ auto *iter = recursiveTypeMap.find (attr.getId ());
214
+ assert (iter != recursiveTypeMap.end () && " unbound DI recursive self type" );
215
+ return iter->second ;
216
+ }
217
+
218
+ size_t recursiveStackSize = recursiveTypeMap.size ();
219
+ auto setRecursivePlaceholderFn = [&](llvm::DIType *node) {
220
+ auto [iter, inserted] = recursiveTypeMap.try_emplace (attr.getId (), node);
221
+ assert (inserted && " illegal reuse of recursive id" );
222
+ };
223
+
224
+ llvm::DIType *node =
225
+ TypeSwitch<DITypeAttr, llvm::DIType *>(attr.getBaseType ())
226
+ .Case <DICompositeTypeAttr>([&](auto attr) {
227
+ return translateImpl (attr, setRecursivePlaceholderFn);
228
+ });
229
+
230
+ assert ((recursiveStackSize + 1 == recursiveTypeMap.size ()) &&
231
+ " internal inconsistency: unexpected recursive translation stack" );
232
+ recursiveTypeMap.pop_back ();
233
+
234
+ return node;
235
+ }
236
+
203
237
llvm::DIScope *DebugTranslation::translateImpl (DIScopeAttr attr) {
204
238
return cast<llvm::DIScope>(translate (DINodeAttr (attr)));
205
239
}
206
240
207
241
llvm::DISubprogram *DebugTranslation::translateImpl (DISubprogramAttr attr) {
242
+ if (auto iter = distinctAttrToNode.find (attr.getId ());
243
+ iter != distinctAttrToNode.end ())
244
+ return cast<llvm::DISubprogram>(iter->second );
245
+
246
+ llvm::DIScope *scope = translate (attr.getScope ());
247
+ llvm::DIFile *file = translate (attr.getFile ());
248
+ llvm::DIType *type = translate (attr.getType ());
249
+ llvm::DICompileUnit *compileUnit = translate (attr.getCompileUnit ());
250
+
251
+ // Check again after recursive calls in case this distinct node recurses back
252
+ // to itself.
253
+ if (auto iter = distinctAttrToNode.find (attr.getId ());
254
+ iter != distinctAttrToNode.end ())
255
+ return cast<llvm::DISubprogram>(iter->second );
256
+
208
257
bool isDefinition = static_cast <bool >(attr.getSubprogramFlags () &
209
258
LLVM::DISubprogramFlags::Definition);
210
- return getDistinctOrUnique<llvm::DISubprogram>(
211
- isDefinition, llvmCtx, translate (attr.getScope ()),
212
- getMDStringOrNull (attr.getName ()),
213
- getMDStringOrNull (attr.getLinkageName ()), translate (attr.getFile ()),
214
- attr.getLine (), translate (attr.getType ()), attr.getScopeLine (),
259
+ llvm::DISubprogram *node = getDistinctOrUnique<llvm::DISubprogram>(
260
+ isDefinition, llvmCtx, scope, getMDStringOrNull (attr.getName ()),
261
+ getMDStringOrNull (attr.getLinkageName ()), file, attr.getLine (), type,
262
+ attr.getScopeLine (),
215
263
/* ContainingType=*/ nullptr , /* VirtualIndex=*/ 0 ,
216
264
/* ThisAdjustment=*/ 0 , llvm::DINode::FlagZero,
217
265
static_cast <llvm::DISubprogram::DISPFlags>(attr.getSubprogramFlags ()),
218
- translate (attr.getCompileUnit ()));
266
+ compileUnit);
267
+
268
+ if (attr.getId ())
269
+ distinctAttrToNode.try_emplace (attr.getId (), node);
270
+ return node;
219
271
}
220
272
221
273
llvm::DIModule *DebugTranslation::translateImpl (DIModuleAttr attr) {
@@ -274,8 +326,8 @@ llvm::DINode *DebugTranslation::translate(DINodeAttr attr) {
274
326
DIDerivedTypeAttr, DIFileAttr, DIGlobalVariableAttr,
275
327
DILabelAttr, DILexicalBlockAttr, DILexicalBlockFileAttr,
276
328
DILocalVariableAttr, DIModuleAttr, DINamespaceAttr,
277
- DINullTypeAttr, DISubprogramAttr, DISubrangeAttr ,
278
- DISubroutineTypeAttr>(
329
+ DINullTypeAttr, DIRecursiveTypeAttr, DISubprogramAttr ,
330
+ DISubrangeAttr, DISubroutineTypeAttr>(
279
331
[&](auto attr) { return translateImpl (attr); });
280
332
attrToNode.insert ({attr, node});
281
333
return node;
0 commit comments