From 01e75646a5d4977a9e441e3db1042df0beccc4bb Mon Sep 17 00:00:00 2001 From: Jacques Pienaar Date: Sat, 23 Nov 2024 08:12:04 -0500 Subject: [PATCH] [mlir] Add FileRange location type. (#80213) This location type represents a contiguous range inside a file. It is effectively a pair of FileLineCols. Add new type and make FileLineCol a view for case where it matches existing previous one. The location includes filename and optional start line & col, and end line & col. Considered common cases are file:line, file:line:col, file:line:start_col to file:line:end_col and general range within same file. In memory its encoded as trailing objects. This keeps the memory requirement the same as FileLineColLoc today (makes the rather common File:Line cheaper) at the expense of extra work at decoding time. Kept the unsigned type. There was the option to always have file range be castable to FileLineColLoc. This cast would just drop other fields. That may result in some simpler staging. TBD. This is a rather minimal change, it does not yet add bindings (C or Python), lowering to LLVM debug locations etc. that supports end line:cols. --------- Co-authored-by: River Riddle --- mlir/include/mlir/IR/Builders.h | 1 + .../include/mlir/IR/BuiltinDialectBytecode.td | 24 ++- .../mlir/IR/BuiltinLocationAttributes.td | 84 +++++++-- mlir/include/mlir/IR/Location.h | 31 ++++ mlir/lib/AsmParser/LocationParser.cpp | 74 ++++++-- mlir/lib/AsmParser/Parser.h | 2 +- mlir/lib/IR/AsmPrinter.cpp | 15 +- mlir/lib/IR/BuiltinDialectBytecode.cpp | 71 ++++++- mlir/lib/IR/Location.cpp | 173 ++++++++++++++++-- mlir/test/IR/locations.mlir | 9 + 10 files changed, 434 insertions(+), 50 deletions(-) diff --git a/mlir/include/mlir/IR/Builders.h b/mlir/include/mlir/IR/Builders.h index 6fb71ccefda1..daea2a23d6fb 100644 --- a/mlir/include/mlir/IR/Builders.h +++ b/mlir/include/mlir/IR/Builders.h @@ -19,6 +19,7 @@ class AffineExpr; class IRMapping; class UnknownLoc; class FileLineColLoc; +class FileLineColRange; class Type; class PrimitiveType; class IntegerType; diff --git a/mlir/include/mlir/IR/BuiltinDialectBytecode.td b/mlir/include/mlir/IR/BuiltinDialectBytecode.td index f50b5dd7ad82..87da8fd3568f 100644 --- a/mlir/include/mlir/IR/BuiltinDialectBytecode.td +++ b/mlir/include/mlir/IR/BuiltinDialectBytecode.td @@ -95,11 +95,26 @@ def CallSiteLoc : DialectAttribute<(attr LocationAttr:$caller )>; +let cType = "FileLineColRange" in { +def FileLineColRange : DialectAttribute<(attr + StringAttr:$filename, + WithBuilder<"$_args", + WithType<"SmallVector", + WithParser<"succeeded(readFileLineColRangeLocs($_reader, $_var))", + WithPrinter<"writeFileLineColRangeLocs($_writer, $_name)">>>>:$rawLocData +)> { + let cBuilder = "getFileLineColRange(context, filename, rawLocData)"; + let printerPredicate = "!::llvm::isa($_val)"; +} + def FileLineColLoc : DialectAttribute<(attr StringAttr:$filename, - VarInt:$line, - VarInt:$column -)>; + VarInt:$start_line, + VarInt:$start_column +)> { + let printerPredicate = "::llvm::isa($_val)"; +} +} let cType = "FusedLoc", cBuilder = "cast(get(context, $_args))" in { @@ -321,7 +336,8 @@ def BuiltinDialectAttributes : DialectAttributes<"Builtin"> { DenseIntOrFPElementsAttr, DenseStringElementsAttr, SparseElementsAttr, - DistinctAttr + DistinctAttr, + FileLineColRange, ]; } diff --git a/mlir/include/mlir/IR/BuiltinLocationAttributes.td b/mlir/include/mlir/IR/BuiltinLocationAttributes.td index bbe566ce9777..fe4e61100872 100644 --- a/mlir/include/mlir/IR/BuiltinLocationAttributes.td +++ b/mlir/include/mlir/IR/BuiltinLocationAttributes.td @@ -60,46 +60,98 @@ def CallSiteLoc : Builtin_LocationAttr<"CallSiteLoc"> { } //===----------------------------------------------------------------------===// -// FileLineColLoc +// FileLineColRange //===----------------------------------------------------------------------===// -def FileLineColLoc : Builtin_LocationAttr<"FileLineColLoc"> { - let summary = "A file:line:column source location"; +def FileLineColRange : Builtin_LocationAttr<"FileLineColRange"> { + let summary = "A file:line:column source location range"; let description = [{ Syntax: ``` filelinecol-location ::= string-literal `:` integer-literal `:` integer-literal + (`to` (integer-literal ?) `:` integer-literal ?) ``` - An instance of this location represents a tuple of file, line number, and - column number. This is similar to the type of location that you get from - most source languages. + An instance of this location represents a tuple of file, start and end line + number, and start and end column number. It allows for the following + configurations: + + * A single file line location: `file:line`; + * A single file line col location: `file:line:column`; + * A single line range: `file:line:column to :column`; + * A single file range: `file:line:column to line:column`; Example: ```mlir - loc("mysource.cc":10:8) + loc("mysource.cc":10:8 to 12:18) ``` }]; - let parameters = (ins "StringAttr":$filename, "unsigned":$line, - "unsigned":$column); + + let parameters = (ins "StringAttr":$filename, + "unsigned":$start_line, "unsigned":$start_column, + "unsigned":$end_line, "unsigned":$end_column); let builders = [ + AttrBuilderWithInferredContext<(ins "StringAttr":$filename), [{ + return $_get(filename.getContext(), filename, ArrayRef{}); + }]>, + AttrBuilderWithInferredContext<(ins "StringAttr":$filename, + "unsigned":$line), [{ + return $_get(filename.getContext(), filename, + ArrayRef{line}); + }]>, AttrBuilderWithInferredContext<(ins "StringAttr":$filename, "unsigned":$line, "unsigned":$column), [{ - return $_get(filename.getContext(), filename, line, column); + return $_get(filename.getContext(), filename, + ArrayRef{line, column}); }]>, - AttrBuilder<(ins "StringRef":$filename, "unsigned":$line, - "unsigned":$column), [{ + AttrBuilder<(ins "::llvm::StringRef":$filename, + "unsigned":$start_line, + "unsigned":$start_column), [{ return $_get($_ctxt, - StringAttr::get($_ctxt, filename.empty() ? "-" : filename), - line, column); - }]> + StringAttr::get($_ctxt, filename.empty() ? "-" : filename), + ArrayRef{start_line, start_column}); + }]>, + AttrBuilderWithInferredContext<(ins "::mlir::StringAttr":$filename, + "unsigned":$line, + "unsigned":$start_column, + "unsigned":$end_column), [{ + return $_get(filename.getContext(), filename, + ArrayRef{line, start_column, end_column}); + }]>, + AttrBuilderWithInferredContext<(ins "::mlir::StringAttr":$filename, + "unsigned":$start_line, + "unsigned":$start_column, + "unsigned":$end_line, + "unsigned":$end_column), [{ + return $_get(filename.getContext(), filename, + ArrayRef{start_line, start_column, end_column, end_line}); + }]>, + AttrBuilder<(ins "::llvm::StringRef":$filename, + "unsigned":$start_line, + "unsigned":$start_column, + "unsigned":$end_line, + "unsigned":$end_column), [{ + return $_get($_ctxt, + StringAttr::get($_ctxt, filename.empty() ? "-" : filename), + ArrayRef{start_line, start_column, end_column, end_line}); + }]>, ]; + + let extraClassDeclaration = [{ + ::mlir::StringAttr getFilename() const; + unsigned getStartLine() const; + unsigned getStartColumn() const; + unsigned getEndColumn() const; + unsigned getEndLine() const; + }]; let skipDefaultBuilders = 1; - let attrName = "builtin.file_line_loc"; + let genAccessors = 0; + let genStorageClass = 0; + let attrName = "builtin.file_line_range"; } //===----------------------------------------------------------------------===// diff --git a/mlir/include/mlir/IR/Location.h b/mlir/include/mlir/IR/Location.h index 5eb1bfaf4afc..e206501f5ee6 100644 --- a/mlir/include/mlir/IR/Location.h +++ b/mlir/include/mlir/IR/Location.h @@ -136,6 +136,11 @@ inline ::llvm::hash_code hash_value(Location arg) { // Tablegen Attribute Declarations //===----------------------------------------------------------------------===// +// Forward declaration for class created later. +namespace mlir::detail { +struct FileLineColRangeAttrStorage; +} // namespace mlir::detail + #define GET_ATTRDEF_CLASSES #include "mlir/IR/BuiltinLocationAttributes.h.inc" @@ -164,6 +169,32 @@ public: } }; +//===----------------------------------------------------------------------===// +// FileLineColLoc +//===----------------------------------------------------------------------===// + +/// An instance of this location represents a tuple of file, line number, and +/// column number. This is similar to the type of location that you get from +/// most source languages. +/// +/// FileLineColLoc is a FileLineColRange with exactly one line and column. +class FileLineColLoc : public FileLineColRange { +public: + using FileLineColRange::FileLineColRange; + + static FileLineColLoc get(StringAttr filename, unsigned line, + unsigned column); + static FileLineColLoc get(MLIRContext *context, StringRef fileName, + unsigned line, unsigned column); + + StringAttr getFilename() const; + unsigned getLine() const; + unsigned getColumn() const; + + /// Methods for support type inquiry through isa, cast, and dyn_cast. + static bool classof(Attribute attr); +}; + //===----------------------------------------------------------------------===// // OpaqueLoc //===----------------------------------------------------------------------===// diff --git a/mlir/lib/AsmParser/LocationParser.cpp b/mlir/lib/AsmParser/LocationParser.cpp index 1365da03c7c3..fb0999bed201 100644 --- a/mlir/lib/AsmParser/LocationParser.cpp +++ b/mlir/lib/AsmParser/LocationParser.cpp @@ -12,6 +12,7 @@ #include "mlir/IR/BuiltinAttributes.h" #include "mlir/IR/Location.h" #include "mlir/Support/LLVM.h" +#include using namespace mlir; using namespace mlir::detail; @@ -97,37 +98,82 @@ ParseResult Parser::parseFusedLocation(LocationAttr &loc) { return success(); } -ParseResult Parser::parseNameOrFileLineColLocation(LocationAttr &loc) { +ParseResult Parser::parseNameOrFileLineColRange(LocationAttr &loc) { auto *ctx = getContext(); auto str = getToken().getStringValue(); consumeToken(Token::string); + std::optional startLine, startColumn, endLine, endColumn; + // If the next token is ':' this is a filelinecol location. if (consumeIf(Token::colon)) { // Parse the line number. if (getToken().isNot(Token::integer)) return emitWrongTokenError( - "expected integer line number in FileLineColLoc"); - auto line = getToken().getUnsignedIntegerValue(); - if (!line) + "expected integer line number in FileLineColRange"); + startLine = getToken().getUnsignedIntegerValue(); + if (!startLine) return emitWrongTokenError( - "expected integer line number in FileLineColLoc"); + "expected integer line number in FileLineColRange"); consumeToken(Token::integer); // Parse the ':'. - if (parseToken(Token::colon, "expected ':' in FileLineColLoc")) - return failure(); + if (getToken().isNot(Token::colon)) { + loc = FileLineColRange::get(StringAttr::get(ctx, str), *startLine); + return success(); + } + consumeToken(Token::colon); // Parse the column number. - if (getToken().isNot(Token::integer)) + if (getToken().isNot(Token::integer)) { return emitWrongTokenError( - "expected integer column number in FileLineColLoc"); - auto column = getToken().getUnsignedIntegerValue(); - if (!column.has_value()) - return emitError("expected integer column number in FileLineColLoc"); + "expected integer column number in FileLineColRange"); + } + startColumn = getToken().getUnsignedIntegerValue(); + if (!startColumn.has_value()) + return emitError("expected integer column number in FileLineColRange"); consumeToken(Token::integer); - loc = FileLineColLoc::get(ctx, str, *line, *column); + if (!isCurrentTokenAKeyword() || getTokenSpelling() != "to") { + loc = FileLineColLoc::get(ctx, str, *startLine, *startColumn); + return success(); + } + consumeToken(); + + // Parse the line number. + if (getToken().is(Token::integer)) { + endLine = getToken().getUnsignedIntegerValue(); + if (!endLine) { + return emitWrongTokenError( + "expected integer line number in FileLineColRange"); + } + consumeToken(Token::integer); + } + + // Parse the ':'. + if (getToken().isNot(Token::colon)) { + return emitWrongTokenError( + "expected either integer or `:` post `to` in FileLineColRange"); + } + consumeToken(Token::colon); + + // Parse the column number. + if (getToken().isNot(Token::integer)) { + return emitWrongTokenError( + "expected integer column number in FileLineColRange"); + } + endColumn = getToken().getUnsignedIntegerValue(); + if (!endColumn.has_value()) + return emitError("expected integer column number in FileLineColRange"); + consumeToken(Token::integer); + + if (endLine.has_value()) { + loc = FileLineColRange::get(StringAttr::get(ctx, str), *startLine, + *startColumn, *endLine, *endColumn); + } else { + loc = FileLineColRange::get(StringAttr::get(ctx, str), *startLine, + *startColumn, *endColumn); + } return success(); } @@ -166,7 +212,7 @@ ParseResult Parser::parseLocationInstance(LocationAttr &loc) { // Handle either name or filelinecol locations. if (getToken().is(Token::string)) - return parseNameOrFileLineColLocation(loc); + return parseNameOrFileLineColRange(loc); // Bare tokens required for other cases. if (!getToken().is(Token::bare_identifier)) diff --git a/mlir/lib/AsmParser/Parser.h b/mlir/lib/AsmParser/Parser.h index 4979cfc6e69e..37670bd789fe 100644 --- a/mlir/lib/AsmParser/Parser.h +++ b/mlir/lib/AsmParser/Parser.h @@ -310,7 +310,7 @@ public: ParseResult parseFusedLocation(LocationAttr &loc); /// Parse a name or FileLineCol location instance. - ParseResult parseNameOrFileLineColLocation(LocationAttr &loc); + ParseResult parseNameOrFileLineColRange(LocationAttr &loc); //===--------------------------------------------------------------------===// // Affine Parsing diff --git a/mlir/lib/IR/AsmPrinter.cpp b/mlir/lib/IR/AsmPrinter.cpp index a728425f2ec6..61b90bc9b0a7 100644 --- a/mlir/lib/IR/AsmPrinter.cpp +++ b/mlir/lib/IR/AsmPrinter.cpp @@ -2009,12 +2009,23 @@ void AsmPrinter::Impl::printLocationInternal(LocationAttr loc, bool pretty, else os << "unknown"; }) - .Case([&](FileLineColLoc loc) { + .Case([&](FileLineColRange loc) { if (pretty) os << loc.getFilename().getValue(); else printEscapedString(loc.getFilename()); - os << ':' << loc.getLine() << ':' << loc.getColumn(); + if (loc.getEndColumn() == loc.getStartColumn() && + loc.getStartLine() == loc.getEndLine()) { + os << ':' << loc.getStartLine() << ':' << loc.getStartColumn(); + return; + } + if (loc.getStartLine() == loc.getEndLine()) { + os << ':' << loc.getStartLine() << ':' << loc.getStartColumn() + << " to :" << loc.getEndColumn(); + return; + } + os << ':' << loc.getStartLine() << ':' << loc.getStartColumn() << " to " + << loc.getEndLine() << ':' << loc.getEndColumn(); }) .Case([&](NameLoc loc) { printEscapedString(loc.getName()); diff --git a/mlir/lib/IR/BuiltinDialectBytecode.cpp b/mlir/lib/IR/BuiltinDialectBytecode.cpp index 6131b7eae90c..6095c6bcb2ce 100644 --- a/mlir/lib/IR/BuiltinDialectBytecode.cpp +++ b/mlir/lib/IR/BuiltinDialectBytecode.cpp @@ -14,7 +14,10 @@ #include "mlir/IR/BuiltinTypes.h" #include "mlir/IR/Diagnostics.h" #include "mlir/IR/DialectResourceBlobManager.h" +#include "mlir/IR/Location.h" +#include "mlir/Support/LLVM.h" #include "llvm/ADT/TypeSwitch.h" +#include using namespace mlir; @@ -70,8 +73,8 @@ readPotentiallySplatString(DialectBytecodeReader &reader, ShapedType type, return success(); } -void writePotentiallySplatString(DialectBytecodeWriter &writer, - DenseStringElementsAttr attr) { +static void writePotentiallySplatString(DialectBytecodeWriter &writer, + DenseStringElementsAttr attr) { bool isSplat = attr.isSplat(); if (isSplat) return writer.writeOwnedString(attr.getRawStringData().front()); @@ -80,6 +83,70 @@ void writePotentiallySplatString(DialectBytecodeWriter &writer, writer.writeOwnedString(str); } +static FileLineColRange getFileLineColRange(MLIRContext *context, + StringAttr filename, + ArrayRef lineCols) { + switch (lineCols.size()) { + case 0: + return FileLineColRange::get(filename); + case 1: + return FileLineColRange::get(filename, lineCols[0]); + case 2: + return FileLineColRange::get(filename, lineCols[0], lineCols[1]); + case 3: + return FileLineColRange::get(filename, lineCols[0], lineCols[1], + lineCols[2]); + case 4: + return FileLineColRange::get(filename, lineCols[0], lineCols[1], + lineCols[2], lineCols[3]); + default: + return {}; + } +} + +static LogicalResult +readFileLineColRangeLocs(DialectBytecodeReader &reader, + SmallVectorImpl &lineCols) { + return reader.readList( + lineCols, [&reader](uint64_t &val) { return reader.readVarInt(val); }); +} + +static void writeFileLineColRangeLocs(DialectBytecodeWriter &writer, + FileLineColRange range) { + if (range.getStartLine() == 0 && range.getStartColumn() == 0 && + range.getEndLine() == 0 && range.getEndColumn() == 0) { + writer.writeVarInt(0); + return; + } + if (range.getStartColumn() == 0 && + range.getStartLine() == range.getEndLine()) { + writer.writeVarInt(1); + writer.writeVarInt(range.getStartLine()); + return; + } + // The single file:line:col is handled by other writer, but checked here for + // completeness. + if (range.getEndColumn() == range.getStartColumn() && + range.getStartLine() == range.getEndLine()) { + writer.writeVarInt(2); + writer.writeVarInt(range.getStartLine()); + writer.writeVarInt(range.getStartColumn()); + return; + } + if (range.getStartLine() == range.getEndLine()) { + writer.writeVarInt(3); + writer.writeVarInt(range.getStartLine()); + writer.writeVarInt(range.getStartColumn()); + writer.writeVarInt(range.getEndColumn()); + return; + } + writer.writeVarInt(4); + writer.writeVarInt(range.getStartLine()); + writer.writeVarInt(range.getStartColumn()); + writer.writeVarInt(range.getEndLine()); + writer.writeVarInt(range.getEndColumn()); +} + #include "mlir/IR/BuiltinDialectBytecode.cpp.inc" /// This class implements the bytecode interface for the builtin dialect. diff --git a/mlir/lib/IR/Location.cpp b/mlir/lib/IR/Location.cpp index dbd84912a865..ce78d30ee0a5 100644 --- a/mlir/lib/IR/Location.cpp +++ b/mlir/lib/IR/Location.cpp @@ -7,14 +7,112 @@ //===----------------------------------------------------------------------===// #include "mlir/IR/Location.h" +#include "mlir/IR/AttributeSupport.h" +#include "mlir/IR/BuiltinAttributes.h" #include "mlir/IR/BuiltinDialect.h" +#include "mlir/IR/MLIRContext.h" #include "mlir/IR/Visitors.h" +#include "mlir/Support/LLVM.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/Hashing.h" +#include "llvm/ADT/PointerIntPair.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SetVector.h" #include "llvm/ADT/TypeSwitch.h" +#include "llvm/Support/Casting.h" +#include "llvm/Support/TrailingObjects.h" +#include +#include +#include +#include +#include +#include using namespace mlir; using namespace mlir::detail; +namespace mlir::detail { +struct FileLineColRangeAttrStorage final + : public ::mlir::AttributeStorage, + public llvm::TrailingObjects { + using PointerPair = llvm::PointerIntPair; + using KeyTy = std::tuple>; + + FileLineColRangeAttrStorage(StringAttr filename, int numLocs) + : filenameAndTrailing(filename, numLocs) {} + + static FileLineColRangeAttrStorage * + construct(::mlir::AttributeStorageAllocator &allocator, KeyTy &&tblgenKey) { + auto numInArray = std::get<1>(tblgenKey).size(); + // Note: Considered asserting that numInArray is at least 1, but this + // is not needed in memory or in printed form. This should very rarely be + // 0 here as that means a NamedLoc would have been more efficient. But this + // does allow for location with just a file, and also having the interface + // be more uniform. + auto locEnc = numInArray == 0 ? 1 : numInArray; + // Allocate a new storage instance. + auto byteSize = + FileLineColRangeAttrStorage::totalSizeToAlloc(locEnc - 1); + auto *rawMem = + allocator.allocate(byteSize, alignof(FileLineColRangeAttrStorage)); + auto *result = ::new (rawMem) FileLineColRangeAttrStorage( + std::move(std::get<0>(tblgenKey)), locEnc - 1); + if (numInArray > 0) { + result->startLine = std::get<1>(tblgenKey)[0]; + // Copy in the element types into the trailing storage. + std::uninitialized_copy(std::next(std::get<1>(tblgenKey).begin()), + std::get<1>(tblgenKey).end(), + result->getTrailingObjects()); + } + return result; + } + + // Return the number of held types. + unsigned size() const { return filenameAndTrailing.getInt() + 1; } + + bool operator==(const KeyTy &tblgenKey) const { + return (filenameAndTrailing.getPointer() == std::get<0>(tblgenKey)) && + (size() == std::get<1>(tblgenKey).size()) && + (startLine == std::get<1>(tblgenKey)[0]) && + (ArrayRef{getTrailingObjects(), size() - 1} == + ArrayRef{std::get<1>(tblgenKey)}.drop_front()); + } + + unsigned getLineCols(unsigned index) const { + return getTrailingObjects()[index - 1]; + } + + unsigned getStartLine() const { return startLine; } + unsigned getStartColumn() const { + if (size() <= 1) + return 0; + return getLineCols(1); + } + unsigned getEndColumn() const { + if (size() <= 2) + return getStartColumn(); + return getLineCols(2); + } + unsigned getEndLine() const { + if (size() <= 3) + return getStartLine(); + return getLineCols(3); + } + + static ::llvm::hash_code hashKey(const KeyTy &tblgenKey) { + return ::llvm::hash_combine(std::get<0>(tblgenKey), std::get<1>(tblgenKey)); + } + + // Supports + // - 0 (file:line) + // - 1 (file:line:col) + // - 2 (file:line:start_col to file:line:end_col) and + // - 3 (file:start_line:start_col to file:end_line:end_col) + llvm::PointerIntPair filenameAndTrailing; + unsigned startLine = 0; +}; +} // namespace mlir::detail + //===----------------------------------------------------------------------===// /// Tablegen Attribute Definitions //===----------------------------------------------------------------------===// @@ -22,17 +120,6 @@ using namespace mlir::detail; #define GET_ATTRDEF_CLASSES #include "mlir/IR/BuiltinLocationAttributes.cpp.inc" -//===----------------------------------------------------------------------===// -// BuiltinDialect -//===----------------------------------------------------------------------===// - -void BuiltinDialect::registerLocationAttributes() { - addAttributes< -#define GET_ATTRDEF_LIST -#include "mlir/IR/BuiltinLocationAttributes.cpp.inc" - >(); -} - //===----------------------------------------------------------------------===// // LocationAttr //===----------------------------------------------------------------------===// @@ -66,6 +153,59 @@ CallSiteLoc CallSiteLoc::get(Location name, ArrayRef frames) { return CallSiteLoc::get(name, caller); } +//===----------------------------------------------------------------------===// +// FileLineColLoc +//===----------------------------------------------------------------------===// + +FileLineColLoc FileLineColLoc::get(StringAttr filename, unsigned line, + unsigned column) { + return llvm::cast( + FileLineColRange::get(filename, line, column)); +} + +FileLineColLoc FileLineColLoc::get(MLIRContext *context, StringRef fileName, + unsigned line, unsigned column) { + return llvm::cast( + FileLineColRange::get(context, fileName, line, column)); +} + +StringAttr FileLineColLoc::getFilename() const { + return FileLineColRange::getFilename(); +} + +unsigned FileLineColLoc::getLine() const { return getStartLine(); } + +unsigned FileLineColLoc::getColumn() const { return getStartColumn(); } + +bool FileLineColLoc::classof(Attribute attr) { + // This could also have been for <= 2. But given this is matching previous + // behavior, it is left as is. + if (auto range = mlir::dyn_cast(attr)) + return range.getImpl()->size() == 2; + return false; +} + +//===----------------------------------------------------------------------===// +// FileLineColRange +//===----------------------------------------------------------------------===// + +StringAttr FileLineColRange::getFilename() const { + return getImpl()->filenameAndTrailing.getPointer(); +} + +unsigned FileLineColRange::getStartLine() const { + return getImpl()->getStartLine(); +} +unsigned FileLineColRange::getStartColumn() const { + return getImpl()->getStartColumn(); +} +unsigned FileLineColRange::getEndColumn() const { + return getImpl()->getEndColumn(); +} +unsigned FileLineColRange::getEndLine() const { + return getImpl()->getEndLine(); +} + //===----------------------------------------------------------------------===// // FusedLoc //===----------------------------------------------------------------------===// @@ -107,3 +247,14 @@ Location FusedLoc::get(ArrayRef locs, Attribute metadata, return Base::get(context, locs, metadata); } + +//===----------------------------------------------------------------------===// +// BuiltinDialect +//===----------------------------------------------------------------------===// + +void BuiltinDialect::registerLocationAttributes() { + addAttributes< +#define GET_ATTRDEF_LIST +#include "mlir/IR/BuiltinLocationAttributes.cpp.inc" + >(); +} diff --git a/mlir/test/IR/locations.mlir b/mlir/test/IR/locations.mlir index 0c6426ebec87..b725307b420b 100644 --- a/mlir/test/IR/locations.mlir +++ b/mlir/test/IR/locations.mlir @@ -33,6 +33,15 @@ func.func @inline_notation() -> i32 { // CHECK-LABEL: func private @loc_attr(i1 {foo.loc_attr = loc(callsite("foo" at "mysource.cc":10:8))}) func.func private @loc_attr(i1 {foo.loc_attr = loc(callsite("foo" at "mysource.cc":10:8))}) +// CHECK-LABEL: func.func private @filelocrange_attr1(i1 {foo.loc_attr = loc("mysource.cc":10:0)}) +func.func private @filelocrange_attr1(i1 {foo.loc_attr = loc("mysource.cc":10)}) +// CHECK-LABEL: func.func private @filelocrange_attr2(i1 {foo.loc_attr = loc("mysource.cc":10:8)}) +func.func private @filelocrange_attr2(i1 {foo.loc_attr = loc("mysource.cc":10:8)}) +// CHECK-LABEL: func.func private @filelocrange_attr3(i1 {foo.loc_attr = loc("mysource.cc":10:8 to :12)}) +func.func private @filelocrange_attr3(i1 {foo.loc_attr = loc("mysource.cc":10:8 to :12)}) +// CHECK-LABEL: func.func private @filelocrange_attr4(i1 {foo.loc_attr = loc("mysource.cc":10:8 to 12:4)}) +func.func private @filelocrange_attr4(i1 {foo.loc_attr = loc("mysource.cc":10:8 to 12:4)}) + // Check that locations get properly escaped. // CHECK-LABEL: func @escape_strings() func.func @escape_strings() {