/// Parses function arguments using `parser`. The `allowVariadic` argument
/// indicates whether functions with variadic arguments are supported. The
-/// trailing arguments are populated by this function with names, types and
-/// attributes of the arguments.
+/// trailing arguments are populated by this function with names, types,
+/// attributes and locations of the arguments.
ParseResult parseFunctionArgumentList(
OpAsmParser &parser, bool allowAttributes, bool allowVariadic,
SmallVectorImpl<OpAsmParser::OperandType> &argNames,
SmallVectorImpl<Type> &argTypes, SmallVectorImpl<NamedAttrList> &argAttrs,
- bool &isVariadic);
+ SmallVectorImpl<Optional<Location>> &argLocations, bool &isVariadic);
/// Parses a function signature using `parser`. The `allowVariadic` argument
/// indicates whether functions with variadic arguments are supported. The
-/// trailing arguments are populated by this function with names, types and
-/// attributes of the arguments and those of the results.
+/// trailing arguments are populated by this function with names, types,
+/// attributes and locations of the arguments and those of the results.
ParseResult
parseFunctionSignature(OpAsmParser &parser, bool allowVariadic,
SmallVectorImpl<OpAsmParser::OperandType> &argNames,
SmallVectorImpl<Type> &argTypes,
SmallVectorImpl<NamedAttrList> &argAttrs,
+ SmallVectorImpl<Optional<Location>> &argLocations,
bool &isVariadic, SmallVectorImpl<Type> &resultTypes,
SmallVectorImpl<NamedAttrList> &resultAttrs);
/// Parses a region. Any parsed blocks are appended to 'region' and must be
/// moved to the op regions after the op is created. The first block of the
- /// region takes 'arguments' of types 'argTypes'. If 'enableNameShadowing' is
- /// set to true, the argument names are allowed to shadow the names of other
- /// existing SSA values defined above the region scope. 'enableNameShadowing'
- /// can only be set to true for regions attached to operations that are
- /// 'IsolatedFromAbove.
- virtual ParseResult parseRegion(Region ®ion,
- ArrayRef<OperandType> arguments = {},
- ArrayRef<Type> argTypes = {},
- bool enableNameShadowing = false) = 0;
+ /// region takes 'arguments' of types 'argTypes'. If `argLocations` is
+ /// non-empty it contains an optional location to be attached to each
+ /// argument. If 'enableNameShadowing' is set to true, the argument names are
+ /// allowed to shadow the names of other existing SSA values defined above the
+ /// region scope. 'enableNameShadowing' can only be set to true for regions
+ /// attached to operations that are 'IsolatedFromAbove'.
+ virtual ParseResult
+ parseRegion(Region ®ion, ArrayRef<OperandType> arguments = {},
+ ArrayRef<Type> argTypes = {},
+ ArrayRef<Optional<Location>> argLocations = {},
+ bool enableNameShadowing = false) = 0;
/// Parses a region if present.
virtual OptionalParseResult
parseOptionalRegion(Region ®ion, ArrayRef<OperandType> arguments = {},
ArrayRef<Type> argTypes = {},
+ ArrayRef<Optional<Location>> argLocations = {},
bool enableNameShadowing = false) = 0;
/// Parses a region if present. If the region is present, a new region is
Region *body = result.addRegion();
if (parser.parseRegion(*body, /*arguments=*/{unwrappedArgs},
/*argTypes=*/{unwrappedTypes},
+ /*argLocations=*/{},
/*enableNameShadowing=*/false))
return failure();
SmallVectorImpl<Type> &argTypes) {
if (parser.parseOptionalKeyword("args"))
return success();
- SmallVector<NamedAttrList, 4> argAttrs;
+ SmallVector<NamedAttrList> argAttrs;
+ SmallVector<Optional<Location>> argLocations;
bool isVariadic = false;
return function_interface_impl::parseFunctionArgumentList(
parser, /*allowAttributes=*/false,
- /*allowVariadic=*/false, argNames, argTypes, argAttrs, isVariadic);
+ /*allowVariadic=*/false, argNames, argTypes, argAttrs, argLocations,
+ isVariadic);
}
static void printLaunchFuncOperands(OpAsmPrinter &printer, Operation *,
/// (`->` function-result-list)? memory-attribution `kernel`?
/// function-attributes? region
static ParseResult parseGPUFuncOp(OpAsmParser &parser, OperationState &result) {
- SmallVector<OpAsmParser::OperandType, 8> entryArgs;
- SmallVector<NamedAttrList, 1> argAttrs;
- SmallVector<NamedAttrList, 1> resultAttrs;
- SmallVector<Type, 8> argTypes;
- SmallVector<Type, 4> resultTypes;
+ SmallVector<OpAsmParser::OperandType> entryArgs;
+ SmallVector<NamedAttrList> argAttrs;
+ SmallVector<NamedAttrList> resultAttrs;
+ SmallVector<Type> argTypes;
+ SmallVector<Type> resultTypes;
+ SmallVector<Optional<Location>> argLocations;
bool isVariadic;
// Parse the function name.
auto signatureLocation = parser.getCurrentLocation();
if (failed(function_interface_impl::parseFunctionSignature(
parser, /*allowVariadic=*/false, entryArgs, argTypes, argAttrs,
- isVariadic, resultTypes, resultAttrs)))
+ argLocations, isVariadic, resultTypes, resultAttrs)))
return failure();
if (entryArgs.empty() && !argTypes.empty())
parser, result, LLVM::Linkage::External)));
StringAttr nameAttr;
- SmallVector<OpAsmParser::OperandType, 8> entryArgs;
- SmallVector<NamedAttrList, 1> argAttrs;
- SmallVector<NamedAttrList, 1> resultAttrs;
- SmallVector<Type, 8> argTypes;
- SmallVector<Type, 4> resultTypes;
+ SmallVector<OpAsmParser::OperandType> entryArgs;
+ SmallVector<NamedAttrList> argAttrs;
+ SmallVector<NamedAttrList> resultAttrs;
+ SmallVector<Type> argTypes;
+ SmallVector<Type> resultTypes;
+ SmallVector<Optional<Location>> argLocations;
bool isVariadic;
auto signatureLocation = parser.getCurrentLocation();
result.attributes) ||
function_interface_impl::parseFunctionSignature(
parser, /*allowVariadic=*/true, entryArgs, argTypes, argAttrs,
- isVariadic, resultTypes, resultAttrs))
+ argLocations, isVariadic, resultTypes, resultAttrs))
return failure();
auto type =
//===----------------------------------------------------------------------===//
static ParseResult parseFuncOp(OpAsmParser &parser, OperationState &state) {
- SmallVector<OpAsmParser::OperandType, 4> entryArgs;
- SmallVector<NamedAttrList, 4> argAttrs;
- SmallVector<NamedAttrList, 4> resultAttrs;
- SmallVector<Type, 4> argTypes;
- SmallVector<Type, 4> resultTypes;
+ SmallVector<OpAsmParser::OperandType> entryArgs;
+ SmallVector<NamedAttrList> argAttrs;
+ SmallVector<NamedAttrList> resultAttrs;
+ SmallVector<Type> argTypes;
+ SmallVector<Type> resultTypes;
+ SmallVector<Optional<Location>> argLocations;
auto &builder = parser.getBuilder();
// Parse the name as a symbol.
bool isVariadic = false;
if (function_interface_impl::parseFunctionSignature(
parser, /*allowVariadic=*/false, entryArgs, argTypes, argAttrs,
- isVariadic, resultTypes, resultAttrs))
+ argLocations, isVariadic, resultTypes, resultAttrs))
return failure();
auto fnType = builder.getFunctionType(argTypes, resultTypes);
OpAsmParser &parser, bool allowAttributes, bool allowVariadic,
SmallVectorImpl<OpAsmParser::OperandType> &argNames,
SmallVectorImpl<Type> &argTypes, SmallVectorImpl<NamedAttrList> &argAttrs,
- bool &isVariadic) {
+ SmallVectorImpl<Optional<Location>> &argLocations, bool &isVariadic) {
if (parser.parseLParen())
return failure();
return parser.emitError(loc, "expected arguments without attributes");
argAttrs.push_back(attrs);
- // Parse a location if specified. TODO: Don't drop it on the floor.
+ // Parse a location if specified.
Optional<Location> explicitLoc;
if (!argument.name.empty() &&
parser.parseOptionalLocationSpecifier(explicitLoc))
return failure();
+ argLocations.push_back(explicitLoc);
return success();
};
OpAsmParser &parser, bool allowVariadic,
SmallVectorImpl<OpAsmParser::OperandType> &argNames,
SmallVectorImpl<Type> &argTypes, SmallVectorImpl<NamedAttrList> &argAttrs,
- bool &isVariadic, SmallVectorImpl<Type> &resultTypes,
+ SmallVectorImpl<Optional<Location>> &argLocations, bool &isVariadic,
+ SmallVectorImpl<Type> &resultTypes,
SmallVectorImpl<NamedAttrList> &resultAttrs) {
bool allowArgAttrs = true;
if (parseFunctionArgumentList(parser, allowArgAttrs, allowVariadic, argNames,
- argTypes, argAttrs, isVariadic))
+ argTypes, argAttrs, argLocations, isVariadic))
return failure();
if (succeeded(parser.parseOptionalArrow()))
return parseFunctionResultList(parser, resultTypes, resultAttrs);
ParseResult mlir::function_interface_impl::parseFunctionOp(
OpAsmParser &parser, OperationState &result, bool allowVariadic,
FuncTypeBuilder funcTypeBuilder) {
- SmallVector<OpAsmParser::OperandType, 4> entryArgs;
- SmallVector<NamedAttrList, 4> argAttrs;
- SmallVector<NamedAttrList, 4> resultAttrs;
- SmallVector<Type, 4> argTypes;
- SmallVector<Type, 4> resultTypes;
+ SmallVector<OpAsmParser::OperandType> entryArgs;
+ SmallVector<NamedAttrList> argAttrs;
+ SmallVector<NamedAttrList> resultAttrs;
+ SmallVector<Type> argTypes;
+ SmallVector<Type> resultTypes;
+ SmallVector<Optional<Location>> argLocations;
auto &builder = parser.getBuilder();
// Parse visibility.
llvm::SMLoc signatureLocation = parser.getCurrentLocation();
bool isVariadic = false;
if (parseFunctionSignature(parser, allowVariadic, entryArgs, argTypes,
- argAttrs, isVariadic, resultTypes, resultAttrs))
+ argAttrs, argLocations, isVariadic, resultTypes,
+ resultAttrs))
return failure();
std::string errorMessage;
llvm::SMLoc loc = parser.getCurrentLocation();
OptionalParseResult parseResult = parser.parseOptionalRegion(
*body, entryArgs, entryArgs.empty() ? ArrayRef<Type>() : argTypes,
+ entryArgs.empty() ? ArrayRef<Optional<Location>>() : argLocations,
/*enableNameShadowing=*/false);
if (parseResult.hasValue()) {
if (failed(*parseResult))
//===--------------------------------------------------------------------===//
/// Parse a region into 'region' with the provided entry block arguments.
- /// 'isIsolatedNameScope' indicates if the naming scope of this region is
- /// isolated from those above.
+ /// If non-empty, 'argLocations' contains an optional locations for each
+ /// argument. 'isIsolatedNameScope' indicates if the naming scope of this
+ /// region is isolated from those above.
ParseResult parseRegion(Region ®ion,
ArrayRef<std::pair<SSAUseInfo, Type>> entryArguments,
+ ArrayRef<Optional<Location>> argLocations = {},
bool isIsolatedNameScope = false);
/// Parse a region body into 'region'.
ParseResult
parseRegionBody(Region ®ion, llvm::SMLoc startLoc,
ArrayRef<std::pair<SSAUseInfo, Type>> entryArguments,
+ ArrayRef<Optional<Location>> argLocations,
bool isIsolatedNameScope);
//===--------------------------------------------------------------------===//
/// effectively defines the SSA values of `arguments` and assigns their type.
ParseResult parseRegion(Region ®ion, ArrayRef<OperandType> arguments,
ArrayRef<Type> argTypes,
+ ArrayRef<Optional<Location>> argLocations,
bool enableNameShadowing) override {
assert(arguments.size() == argTypes.size() &&
"mismatching number of arguments and types");
(void)isIsolatedFromAbove;
assert((!enableNameShadowing || isIsolatedFromAbove) &&
"name shadowing is only allowed on isolated regions");
- if (parser.parseRegion(region, regionArguments, enableNameShadowing))
+ if (parser.parseRegion(region, regionArguments, argLocations,
+ enableNameShadowing))
return failure();
return success();
}
/// Parses a region if present.
- OptionalParseResult parseOptionalRegion(Region ®ion,
- ArrayRef<OperandType> arguments,
- ArrayRef<Type> argTypes,
- bool enableNameShadowing) override {
+ OptionalParseResult
+ parseOptionalRegion(Region ®ion, ArrayRef<OperandType> arguments,
+ ArrayRef<Type> argTypes,
+ ArrayRef<Optional<Location>> argLocations,
+ bool enableNameShadowing) override {
if (parser.getToken().isNot(Token::l_brace))
return llvm::None;
- return parseRegion(region, arguments, argTypes, enableNameShadowing);
+ return parseRegion(region, arguments, argTypes, argLocations,
+ enableNameShadowing);
}
/// Parses a region if present. If the region is present, a new region is
if (parser.getToken().isNot(Token::l_brace))
return llvm::None;
std::unique_ptr<Region> newRegion = std::make_unique<Region>();
- if (parseRegion(*newRegion, arguments, argTypes, enableNameShadowing))
+ if (parseRegion(*newRegion, arguments, argTypes, /*argLocations=*/{},
+ enableNameShadowing))
return failure();
region = std::move(newRegion);
ParseResult OperationParser::parseRegion(
Region ®ion,
ArrayRef<std::pair<OperationParser::SSAUseInfo, Type>> entryArguments,
- bool isIsolatedNameScope) {
+ ArrayRef<Optional<Location>> argLocations, bool isIsolatedNameScope) {
// Parse the '{'.
Token lBraceTok = getToken();
if (parseToken(Token::l_brace, "expected '{' to begin a region"))
// Parse the region body.
if ((!entryArguments.empty() || getToken().isNot(Token::r_brace)) &&
- parseRegionBody(region, lBraceTok.getLoc(), entryArguments,
+ parseRegionBody(region, lBraceTok.getLoc(), entryArguments, argLocations,
isIsolatedNameScope)) {
return failure();
}
ParseResult OperationParser::parseRegionBody(
Region ®ion, llvm::SMLoc startLoc,
ArrayRef<std::pair<OperationParser::SSAUseInfo, Type>> entryArguments,
- bool isIsolatedNameScope) {
+ ArrayRef<Optional<Location>> argLocations, bool isIsolatedNameScope) {
+ assert(argLocations.empty() || argLocations.size() == entryArguments.size());
auto currentPt = opBuilder.saveInsertionPoint();
// Push a new named value scope.
if (getToken().is(Token::caret_identifier))
return emitError("invalid block name in region with named arguments");
- for (auto &placeholderArgPair : entryArguments) {
+ for (const auto &it : llvm::enumerate(entryArguments)) {
+ size_t argIndex = it.index();
+ auto &placeholderArgPair = it.value();
auto &argInfo = placeholderArgPair.first;
// Ensure that the argument was not already defined.
.attachNote(getEncodedSourceLocation(*defLoc))
<< "previously referenced here";
}
- auto loc = getEncodedSourceLocation(placeholderArgPair.first.loc);
+ Location loc =
+ (!argLocations.empty() && argLocations[argIndex])
+ ? *argLocations[argIndex]
+ : getEncodedSourceLocation(placeholderArgPair.first.loc);
BlockArgument arg = block->addArgument(placeholderArgPair.second, loc);
// Add a definition of this arg to the assembly state if provided.
// CHECK-LABEL: func @argLocs(
// CHECK-SAME: %arg0: i32 loc({{.*}}locations.mlir":[[# @LINE+1]]:15),
func @argLocs(%x: i32,
-// CHECK-SAME: %arg1: i64 loc({{.*}}locations.mlir":[[# @LINE+1]]:15))
+// CHECK-SAME: %arg1: i64 loc("hotdog")
%y: i64 loc("hotdog")) {
return
}
// Parse the body region, and reuse the operand info as the argument info.
Region *body = result.addRegion();
- return parser.parseRegion(*body, argInfo, argType,
+ return parser.parseRegion(*body, argInfo, argType, /*argLocations=*/{},
/*enableNameShadowing=*/true);
}