12
12
include "mlir/Dialect/LLVMIR/LLVMDialect.td"
13
13
include "mlir/IR/AttrTypeBase.td"
14
14
include "mlir/IR/CommonAttrConstraints.td"
15
+ include "mlir/Dialect/LLVMIR/LLVMInterfaces.td"
15
16
16
17
// All of the attributes will extend this class.
17
18
class LLVM_Attr<string name, string attrMnemonic,
@@ -238,41 +239,43 @@ def LoopAnnotationAttr : LLVM_Attr<"LoopAnnotation", "loop_annotation"> {
238
239
//===----------------------------------------------------------------------===//
239
240
240
241
class LLVM_DIParameter<string summary, string default, string parseName,
241
- string printName = parseName>
242
+ string errorCase, string printName = parseName>
242
243
: AttrOrTypeParameter<"unsigned", "debug info " # summary> {
243
244
let parser = [{ [&]() -> FailureOr<unsigned> {
244
245
SMLoc tagLoc = $_parser.getCurrentLocation();
245
246
StringRef name;
246
247
if ($_parser.parseKeyword(&name))
247
248
return failure();
248
249
249
- if (unsigned tag = llvm::dwarf::get}] # parseName # [{(name))
250
- return tag;
251
- return $_parser.emitError(tagLoc)
252
- << "invalid debug info }] # summary # [{ name: " << name;
250
+ unsigned tag = llvm::dwarf::get}] # parseName # [{(name);
251
+ if (tag == }] # errorCase # [{)
252
+ return $_parser.emitError(tagLoc)
253
+ << "invalid debug info }] # summary # [{ name: " << name;
254
+ return tag;
253
255
}() }];
254
256
let printer = "$_printer << llvm::dwarf::" # printName # "String($_self)";
255
257
let defaultValue = default;
256
258
}
257
259
258
260
def LLVM_DICallingConventionParameter : LLVM_DIParameter<
259
- "calling convention", /*default=*/"0", "CallingConvention", "Convention"
261
+ "calling convention", /*default=*/"0", "CallingConvention", /*errorCase=*/"0",
262
+ "Convention"
260
263
>;
261
264
262
265
def LLVM_DIEncodingParameter : LLVM_DIParameter<
263
- "encoding", /*default=*/"0", "AttributeEncoding"
266
+ "encoding", /*default=*/"0", "AttributeEncoding", /*errorCase=*/"0"
264
267
>;
265
268
266
269
def LLVM_DILanguageParameter : LLVM_DIParameter<
267
- "language", /*default=*/"", "Language"
270
+ "language", /*default=*/"", "Language", /*errorCase=*/"0"
268
271
>;
269
272
270
273
def LLVM_DITagParameter : LLVM_DIParameter<
271
- "tag", /*default=*/"", "Tag"
274
+ "tag", /*default=*/"", "Tag", /*errorCase=*/"llvm::dwarf::DW_TAG_invalid"
272
275
>;
273
276
274
277
def LLVM_DIOperationEncodingParameter : LLVM_DIParameter<
275
- "operation encoding", /*default=*/"", "OperationEncoding"
278
+ "operation encoding", /*default=*/"", "OperationEncoding", /*errorCase=*/"0"
276
279
>;
277
280
278
281
//===----------------------------------------------------------------------===//
@@ -301,70 +304,6 @@ def LLVM_DIExpressionAttr : LLVM_Attr<"DIExpression", "di_expression"> {
301
304
let assemblyFormat = "`<` ( `[` $operations^ `]` ) : (``)? `>`";
302
305
}
303
306
304
- //===----------------------------------------------------------------------===//
305
- // DIRecursiveTypeAttr
306
- //===----------------------------------------------------------------------===//
307
-
308
- def LLVM_DIRecursiveTypeAttr : LLVM_Attr<"DIRecursiveType", "di_recursive_type",
309
- /*traits=*/[], "DITypeAttr"> {
310
- let description = [{
311
- This attribute enables recursive DITypes. There are two modes for this
312
- attribute.
313
-
314
- 1. If `baseType` is present:
315
- - This type is considered a recursive declaration (rec-decl).
316
- - The `baseType` is a self-recursive type identified by the `recId` field.
317
-
318
- 2. If `baseType` is not present:
319
- - This type is considered a recursive self reference (rec-self).
320
- - This DIRecursiveType itself is a placeholder type that should be
321
- conceptually replaced with the closet parent DIRecursiveType with the
322
- same `recId` field.
323
-
324
- e.g. To represent a linked list struct:
325
-
326
- #rec_self = di_recursive_type<recId = 0>
327
- #ptr = di_derived_type<baseType: #rec_self, ...>
328
- #field = di_derived_type<name = "next", baseType: #ptr, ...>
329
- #struct = di_composite_type<name = "Node", elements: #field, ...>
330
- #rec = di_recursive_type<recId = 0, baseType: #struct>
331
-
332
- #var = di_local_variable<type = #struct_type, ...>
333
-
334
- Note that a rec-self without an outer rec-decl with the same recId is
335
- conceptually the same as an "unbound" variable. The context needs to provide
336
- meaning to the rec-self.
337
-
338
- This can be avoided by calling the `getUnfoldedBaseType()` method on a
339
- rec-decl, which returns the `baseType` with all matching rec-self instances
340
- replaced with this rec-decl again. This is useful, for example, for fetching
341
- a field out of a recursive struct and maintaining the legality of the field
342
- type.
343
- }];
344
-
345
- let parameters = (ins
346
- "DistinctAttr":$recId,
347
- OptionalParameter<"DITypeAttr">:$baseType
348
- );
349
-
350
- let builders = [
351
- AttrBuilderWithInferredContext<(ins "DistinctAttr":$recId), [{
352
- return $_get(recId.getContext(), recId, nullptr);
353
- }]>
354
- ];
355
-
356
- let extraClassDeclaration = [{
357
- /// Whether this node represents a self-reference.
358
- bool isRecSelf() { return !getBaseType(); }
359
-
360
- /// Get the `baseType` with all instances of the corresponding rec-self
361
- /// replaced with this attribute. This can only be called if `!isRecSelf()`.
362
- DITypeAttr getUnfoldedBaseType();
363
- }];
364
-
365
- let assemblyFormat = "`<` struct(params) `>`";
366
- }
367
-
368
307
//===----------------------------------------------------------------------===//
369
308
// DINullTypeAttr
370
309
//===----------------------------------------------------------------------===//
@@ -421,9 +360,11 @@ def LLVM_DICompileUnitAttr : LLVM_Attr<"DICompileUnit", "di_compile_unit",
421
360
//===----------------------------------------------------------------------===//
422
361
423
362
def LLVM_DICompositeTypeAttr : LLVM_Attr<"DICompositeType", "di_composite_type",
424
- /*traits=*/[], "DITypeAttr"> {
363
+ [LLVM_DIRecursiveTypeAttrInterface],
364
+ "DITypeAttr"> {
425
365
let parameters = (ins
426
366
LLVM_DITagParameter:$tag,
367
+ OptionalParameter<"DistinctAttr">:$recId,
427
368
OptionalParameter<"StringAttr">:$name,
428
369
OptionalParameter<"DIFileAttr">:$file,
429
370
OptionalParameter<"uint32_t">:$line,
@@ -435,6 +376,21 @@ def LLVM_DICompositeTypeAttr : LLVM_Attr<"DICompositeType", "di_composite_type",
435
376
OptionalArrayRefParameter<"DINodeAttr">:$elements
436
377
);
437
378
let assemblyFormat = "`<` struct(params) `>`";
379
+ let extraClassDeclaration = [{
380
+ /// Requirements of DIRecursiveTypeAttrInterface.
381
+ /// @{
382
+
383
+ /// Get whether this attr describes a recursive self reference.
384
+ bool isRecSelf() { return getTag() == 0; }
385
+
386
+ /// Get a copy of this type attr but with the recursive ID set to `recId`.
387
+ DIRecursiveTypeAttrInterface withRecId(DistinctAttr recId);
388
+
389
+ /// Build a rec-self instance using the provided recId.
390
+ static DIRecursiveTypeAttrInterface getRecSelf(DistinctAttr recId);
391
+
392
+ /// @}
393
+ }];
438
394
}
439
395
440
396
//===----------------------------------------------------------------------===//
@@ -590,15 +546,14 @@ def LLVM_DISubprogramAttr : LLVM_Attr<"DISubprogram", "di_subprogram",
590
546
OptionalParameter<"unsigned">:$line,
591
547
OptionalParameter<"unsigned">:$scopeLine,
592
548
"DISubprogramFlags":$subprogramFlags,
593
- OptionalParameter<"DIRecursiveTypeAttrOf< DISubroutineTypeAttr> ">:$type
549
+ OptionalParameter<"DISubroutineTypeAttr">:$type
594
550
);
595
551
let builders = [
596
552
AttrBuilderWithInferredContext<(ins
597
553
"DistinctAttr":$id, "DICompileUnitAttr":$compileUnit,
598
554
"DIScopeAttr":$scope, "StringRef":$name, "StringRef":$linkageName,
599
555
"DIFileAttr":$file, "unsigned":$line, "unsigned":$scopeLine,
600
- "DISubprogramFlags":$subprogramFlags,
601
- "DIRecursiveTypeAttrOf<DISubroutineTypeAttr>":$type
556
+ "DISubprogramFlags":$subprogramFlags, "DISubroutineTypeAttr":$type
602
557
), [{
603
558
MLIRContext *ctx = file.getContext();
604
559
return $_get(ctx, id, compileUnit, scope, StringAttr::get(ctx, name),
0 commit comments