Skip to content

Commit 94a19f6

Browse files
committed
[CIR] Use custom FuncType parser to handle optional return type
The default MLIR parser for optional parameters requires an optional anchor we do not have in the syntax.
1 parent d07ce82 commit 94a19f6

File tree

2 files changed

+62
-12
lines changed

2 files changed

+62
-12
lines changed

clang/include/clang/CIR/Dialect/IR/CIRTypes.td

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -387,10 +387,12 @@ def CIR_FuncType : CIR_Type<"Func", "func"> {
387387
}];
388388

389389
let parameters = (ins ArrayRefParameter<"mlir::Type">:$inputs,
390-
OptionalParameter<"mlir::Type">:$optionalReturnType,
390+
"mlir::Type":$optionalReturnType,
391391
"bool":$varArg);
392+
// Use a custom parser to handle the optional return and argument types
393+
// without an optional anchor.
392394
let assemblyFormat = [{
393-
`<` ($optionalReturnType^ ` `)? `(` custom<FuncTypeArgs>($inputs, $varArg) `>`
395+
`<` custom<FuncType>($optionalReturnType, $inputs, $varArg) `>`
394396
}];
395397

396398
let builders = [

clang/lib/CIR/Dialect/IR/CIRTypes.cpp

Lines changed: 58 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,13 @@ using cir::MissingFeatures;
4242
// CIR Custom Parser/Printer Signatures
4343
//===----------------------------------------------------------------------===//
4444

45-
static mlir::ParseResult
46-
parseFuncTypeArgs(mlir::AsmParser &p, llvm::SmallVector<mlir::Type> &params,
47-
bool &isVarArg);
48-
static void printFuncTypeArgs(mlir::AsmPrinter &p,
49-
mlir::ArrayRef<mlir::Type> params, bool isVarArg);
45+
static mlir::ParseResult parseFuncType(mlir::AsmParser &p,
46+
mlir::Type &optionalReturnTypes,
47+
llvm::SmallVector<mlir::Type> &params,
48+
bool &isVarArg);
5049

50+
static void printFuncType(mlir::AsmPrinter &p, mlir::Type optionalReturnTypes,
51+
mlir::ArrayRef<mlir::Type> params, bool isVarArg);
5152
static mlir::ParseResult parsePointerAddrSpace(mlir::AsmParser &p,
5253
mlir::Attribute &addrSpaceAttr);
5354
static void printPointerAddrSpace(mlir::AsmPrinter &p,
@@ -914,9 +915,38 @@ FuncType FuncType::clone(TypeRange inputs, TypeRange results) const {
914915
return get(llvm::to_vector(inputs), results[0], isVarArg());
915916
}
916917

917-
mlir::ParseResult parseFuncTypeArgs(mlir::AsmParser &p,
918-
llvm::SmallVector<mlir::Type> &params,
919-
bool &isVarArg) {
918+
// A special parser is needed for function returning void to handle the missing
919+
// type.
920+
static mlir::ParseResult parseFuncTypeReturn(mlir::AsmParser &p,
921+
mlir::Type &optionalReturnType) {
922+
if (succeeded(p.parseOptionalLParen())) {
923+
// If we have already a '(', the function has no return type
924+
optionalReturnType = {};
925+
return mlir::success();
926+
}
927+
mlir::Type type;
928+
if (p.parseType(type))
929+
return mlir::failure();
930+
if (isa<cir::VoidType>(type))
931+
// An explicit !cir.void means also no return type.
932+
optionalReturnType = {};
933+
else
934+
// Otherwise use the actual type.
935+
optionalReturnType = type;
936+
return p.parseLParen();
937+
}
938+
939+
// A special pretty-printer for function returning or not a result.
940+
static void printFuncTypeReturn(mlir::AsmPrinter &p,
941+
mlir::Type optionalReturnType) {
942+
if (optionalReturnType)
943+
p << optionalReturnType << ' ';
944+
p << '(';
945+
}
946+
947+
static mlir::ParseResult
948+
parseFuncTypeArgs(mlir::AsmParser &p, llvm::SmallVector<mlir::Type> &params,
949+
bool &isVarArg) {
920950
isVarArg = false;
921951
// `(` `)`
922952
if (succeeded(p.parseOptionalRParen()))
@@ -946,8 +976,9 @@ mlir::ParseResult parseFuncTypeArgs(mlir::AsmParser &p,
946976
return p.parseRParen();
947977
}
948978

949-
void printFuncTypeArgs(mlir::AsmPrinter &p, mlir::ArrayRef<mlir::Type> params,
950-
bool isVarArg) {
979+
static void printFuncTypeArgs(mlir::AsmPrinter &p,
980+
mlir::ArrayRef<mlir::Type> params,
981+
bool isVarArg) {
951982
llvm::interleaveComma(params, p,
952983
[&p](mlir::Type type) { p.printType(type); });
953984
if (isVarArg) {
@@ -958,6 +989,23 @@ void printFuncTypeArgs(mlir::AsmPrinter &p, mlir::ArrayRef<mlir::Type> params,
958989
p << ')';
959990
}
960991

992+
// Use a custom parser to handle the optional return and argument types without
993+
// an optional anchor.
994+
static mlir::ParseResult parseFuncType(mlir::AsmParser &p,
995+
mlir::Type &optionalReturnTypes,
996+
llvm::SmallVector<mlir::Type> &params,
997+
bool &isVarArg) {
998+
if (failed(parseFuncTypeReturn(p, optionalReturnTypes)))
999+
return failure();
1000+
return parseFuncTypeArgs(p, params, isVarArg);
1001+
}
1002+
1003+
static void printFuncType(mlir::AsmPrinter &p, mlir::Type optionalReturnTypes,
1004+
mlir::ArrayRef<mlir::Type> params, bool isVarArg) {
1005+
printFuncTypeReturn(p, optionalReturnTypes);
1006+
printFuncTypeArgs(p, params, isVarArg);
1007+
}
1008+
9611009
// Return the actual return type or an explicit !cir.void if the function does
9621010
// not return anything
9631011
mlir::Type FuncType::getReturnType() const {

0 commit comments

Comments
 (0)