diff --git a/mlir/include/mlir/IR/OpImplementation.h b/mlir/include/mlir/IR/OpImplementation.h --- a/mlir/include/mlir/IR/OpImplementation.h +++ b/mlir/include/mlir/IR/OpImplementation.h @@ -327,6 +327,11 @@ using AsmPrinter::AsmPrinter; ~OpAsmPrinter() override; + /// Print a loc(...) specifier if printing debug info is enabled. Locations + /// may be deferred with an alias. + virtual void printOptionalLocationSpecifier(Location loc, + bool allowAlias = true) = 0; + /// Print a newline and indent the printer to the start of the current /// operation. virtual void printNewline() = 0; diff --git a/mlir/lib/IR/AsmPrinter.cpp b/mlir/lib/IR/AsmPrinter.cpp --- a/mlir/lib/IR/AsmPrinter.cpp +++ b/mlir/lib/IR/AsmPrinter.cpp @@ -564,6 +564,7 @@ void printAffineMapOfSSAIds(AffineMapAttr, ValueRange) override {} void printAffineExprOfSSAIds(AffineExpr, ValueRange, ValueRange) override {} void printNewline() override {} + void printOptionalLocationSpecifier(Location loc, bool allowAlias) override {} void printOperand(Value) override {} void printOperand(Value, raw_ostream &os) override { // Users expect the output string to have at least the prefixed % to signal @@ -2682,6 +2683,12 @@ // OpAsmPrinter methods //===--------------------------------------------------------------------===// + /// Print a loc(...) specifier if printing debug info is enabled. Locations + /// may be deferred with an alias. + void printOptionalLocationSpecifier(Location loc, bool allowAlias) override { + printTrailingLocation(loc, allowAlias); + } + /// Print a newline and indent the printer to the start of the current /// operation. void printNewline() override { diff --git a/mlir/test/IR/locations.mlir b/mlir/test/IR/locations.mlir --- a/mlir/test/IR/locations.mlir +++ b/mlir/test/IR/locations.mlir @@ -82,3 +82,10 @@ // CHECK-ALIAS: #[[LOC]] = loc("out_of_line_location") #loc = loc("out_of_line_location") + +// CHECK-LABEL: @optional_location_specifier +// CHECK: test.attr_with_loc("foo" loc("foo_loc")) +func.func @optional_location_specifier() { + test.attr_with_loc("foo" loc("foo_loc")) + return +} diff --git a/mlir/test/lib/Dialect/Test/TestDialect.cpp b/mlir/test/lib/Dialect/Test/TestDialect.cpp --- a/mlir/test/lib/Dialect/Test/TestDialect.cpp +++ b/mlir/test/lib/Dialect/Test/TestDialect.cpp @@ -1030,6 +1030,26 @@ } } +//===----------------------------------------------------------------------===// +// TestAttrWithLoc - parse/printOptionalLocationSpecifier +//===----------------------------------------------------------------------===// + +static ParseResult parseOptionalLoc(OpAsmParser &p, Attribute &loc) { + Optional result; + Location sourceLoc = p.getEncodedSourceLoc(p.getCurrentLocation()); + if (p.parseOptionalLocationSpecifier(result)) + return failure(); + if (result) + loc = *result; + else + loc = sourceLoc; + return success(); +} + +static void printOptionalLoc(OpAsmPrinter &p, Operation *op, Attribute loc) { + p.printOptionalLocationSpecifier(loc.cast()); +} + //===----------------------------------------------------------------------===// // Test removing op with inner ops. //===----------------------------------------------------------------------===// diff --git a/mlir/test/lib/Dialect/Test/TestOps.td b/mlir/test/lib/Dialect/Test/TestOps.td --- a/mlir/test/lib/Dialect/Test/TestOps.td +++ b/mlir/test/lib/Dialect/Test/TestOps.td @@ -1911,6 +1911,12 @@ let hasCustomAssemblyFormat = 1; } +def TestAttrWithLoc : TEST_Op<"attr_with_loc"> { + let summary = "op's attribute has a location"; + let arguments = (ins AnyAttr:$loc, AnyAttr:$value); + let assemblyFormat = "`(` $value `` custom($loc) `)` attr-dict"; +} + //===----------------------------------------------------------------------===// // Test OpAsmInterface.