Skip to content

Commit c35a706

Browse files
authored
[CIR] Simplify FuncType printer/parser (#1413)
This uses the assembly format for the optional return type and keeps a custom printer/parser only for function parameters, which still require a custom form for ellipses.
1 parent 4ea0083 commit c35a706

File tree

3 files changed

+38
-70
lines changed

3 files changed

+38
-70
lines changed

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

+3-3
Original file line numberDiff line numberDiff line change
@@ -385,11 +385,11 @@ def CIR_FuncType : CIR_Type<"Func", "func"> {
385385
}];
386386

387387
let parameters = (ins ArrayRefParameter<"mlir::Type">:$inputs,
388-
"mlir::Type":$optionalReturnType,
388+
OptionalParameter<"mlir::Type">:$optionalReturnType,
389389
"bool":$varArg);
390-
// Use a custom parser to handle the optional return and argument types
390+
// Use a custom parser to handle argument types with variadic elipsis.
391391
let assemblyFormat = [{
392-
`<` custom<FuncType>($optionalReturnType, $inputs, $varArg) `>`
392+
`<` custom<FuncTypeParams>($inputs, $varArg) (`->` $optionalReturnType^)? `>`
393393
}];
394394

395395
let builders = [

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

+27-67
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,13 @@ using cir::MissingFeatures;
4242
// CIR Custom Parser/Printer Signatures
4343
//===----------------------------------------------------------------------===//
4444

45-
static mlir::ParseResult parseFuncType(mlir::AsmParser &p,
46-
mlir::Type &optionalReturnTypes,
47-
llvm::SmallVector<mlir::Type> &params,
48-
bool &isVarArg);
45+
static mlir::ParseResult
46+
parseFuncTypeParams(mlir::AsmParser &p, llvm::SmallVector<mlir::Type> &params,
47+
bool &isVarArg);
4948

50-
static void printFuncType(mlir::AsmPrinter &p, mlir::Type optionalReturnTypes,
51-
mlir::ArrayRef<mlir::Type> params, bool isVarArg);
49+
static void printFuncTypeParams(mlir::AsmPrinter &p,
50+
mlir::ArrayRef<mlir::Type> params,
51+
bool isVarArg);
5252
static mlir::ParseResult parsePointerAddrSpace(mlir::AsmParser &p,
5353
mlir::Attribute &addrSpaceAttr);
5454
static void printPointerAddrSpace(mlir::AsmPrinter &p,
@@ -927,54 +927,31 @@ FuncType FuncType::clone(TypeRange inputs, TypeRange results) const {
927927
return get(llvm::to_vector(inputs), results[0], isVarArg());
928928
}
929929

930-
// A special parser is needed for function returning void to handle the missing
931-
// type.
932-
static mlir::ParseResult parseFuncTypeReturn(mlir::AsmParser &p,
933-
mlir::Type &optionalReturnType) {
934-
if (succeeded(p.parseOptionalArrow())) {
935-
// `->` found. It must be followed by the return type.
936-
return p.parseType(optionalReturnType);
937-
}
938-
// Function has `void` return in C++, no return in MLIR.
939-
optionalReturnType = {};
940-
return success();
941-
}
942-
943-
// A special pretty-printer for function returning or not a result.
944-
static void printFuncTypeReturn(mlir::AsmPrinter &p,
945-
mlir::Type optionalReturnType) {
946-
if (optionalReturnType)
947-
p << " -> " << optionalReturnType;
948-
}
949-
930+
// Custom parser that parses function parameters of form `(<type>*, ...)`.
950931
static mlir::ParseResult
951-
parseFuncTypeArgs(mlir::AsmParser &p, llvm::SmallVector<mlir::Type> &params,
952-
bool &isVarArg) {
932+
parseFuncTypeParams(mlir::AsmParser &p, llvm::SmallVector<mlir::Type> &params,
933+
bool &isVarArg) {
953934
isVarArg = false;
954-
if (failed(p.parseLParen()))
955-
return failure();
956-
if (succeeded(p.parseOptionalRParen())) {
957-
// `()` empty argument list
958-
return mlir::success();
959-
}
960-
do {
961-
if (succeeded(p.parseOptionalEllipsis())) {
962-
// `...`, which must be the last thing in the list.
963-
isVarArg = true;
964-
break;
965-
} else {
966-
mlir::Type argType;
967-
if (failed(p.parseType(argType)))
968-
return failure();
969-
params.push_back(argType);
970-
}
971-
} while (succeeded(p.parseOptionalComma()));
972-
return p.parseRParen();
935+
return p.parseCommaSeparatedList(
936+
AsmParser::Delimiter::Paren, [&]() -> mlir::ParseResult {
937+
if (isVarArg)
938+
return p.emitError(p.getCurrentLocation(),
939+
"variadic `...` must be the last parameter");
940+
if (succeeded(p.parseOptionalEllipsis())) {
941+
isVarArg = true;
942+
return success();
943+
}
944+
mlir::Type type;
945+
if (failed(p.parseType(type)))
946+
return failure();
947+
params.push_back(type);
948+
return success();
949+
});
973950
}
974951

975-
static void printFuncTypeArgs(mlir::AsmPrinter &p,
976-
mlir::ArrayRef<mlir::Type> params,
977-
bool isVarArg) {
952+
static void printFuncTypeParams(mlir::AsmPrinter &p,
953+
mlir::ArrayRef<mlir::Type> params,
954+
bool isVarArg) {
978955
p << '(';
979956
llvm::interleaveComma(params, p,
980957
[&p](mlir::Type type) { p.printType(type); });
@@ -986,23 +963,6 @@ static void printFuncTypeArgs(mlir::AsmPrinter &p,
986963
p << ')';
987964
}
988965

989-
// Use a custom parser to handle the optional return and argument types without
990-
// an optional anchor.
991-
static mlir::ParseResult parseFuncType(mlir::AsmParser &p,
992-
mlir::Type &optionalReturnType,
993-
llvm::SmallVector<mlir::Type> &params,
994-
bool &isVarArg) {
995-
if (failed(parseFuncTypeArgs(p, params, isVarArg)))
996-
return failure();
997-
return parseFuncTypeReturn(p, optionalReturnType);
998-
}
999-
1000-
static void printFuncType(mlir::AsmPrinter &p, mlir::Type optionalReturnType,
1001-
mlir::ArrayRef<mlir::Type> params, bool isVarArg) {
1002-
printFuncTypeArgs(p, params, isVarArg);
1003-
printFuncTypeReturn(p, optionalReturnType);
1004-
}
1005-
1006966
/// Get the C-style return type of the function, which is !cir.void if the
1007967
/// function returns nothing and the actual return type otherwise.
1008968
mlir::Type FuncType::getReturnType() const {

clang/test/CIR/IR/invalid.cir

+8
Original file line numberDiff line numberDiff line change
@@ -1500,3 +1500,11 @@ cir.func @cast0(%arg0: !s32i, %arg1: !s32i) {
15001500
// expected-error @below {{!cir.func cannot have an explicit 'void' return type}}
15011501
// expected-error @below {{failed to parse CIR_PointerType parameter}}
15021502
cir.global external dsolocal @vfp = #cir.ptr<null> : !cir.ptr<!cir.func<(!s32i) -> !cir.void>>
1503+
1504+
// -----
1505+
1506+
// Verify that variadic functions do not allow an ellipsis anywhere except at
1507+
// the end of the parameter list.
1508+
1509+
// expected-error @below {{variadic `...` must be the last parameter}}
1510+
!fty = !cir.func<(..., !s32i)>

0 commit comments

Comments
 (0)