Skip to content

Commit a47d48e

Browse files
xlaukolanza
authored andcommitted
[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 d33063b commit a47d48e

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,
@@ -827,54 +827,31 @@ FuncType FuncType::clone(TypeRange inputs, TypeRange results) const {
827827
return get(llvm::to_vector(inputs), results[0], isVarArg());
828828
}
829829

830-
// A special parser is needed for function returning void to handle the missing
831-
// type.
832-
static mlir::ParseResult parseFuncTypeReturn(mlir::AsmParser &p,
833-
mlir::Type &optionalReturnType) {
834-
if (succeeded(p.parseOptionalArrow())) {
835-
// `->` found. It must be followed by the return type.
836-
return p.parseType(optionalReturnType);
837-
}
838-
// Function has `void` return in C++, no return in MLIR.
839-
optionalReturnType = {};
840-
return success();
841-
}
842-
843-
// A special pretty-printer for function returning or not a result.
844-
static void printFuncTypeReturn(mlir::AsmPrinter &p,
845-
mlir::Type optionalReturnType) {
846-
if (optionalReturnType)
847-
p << " -> " << optionalReturnType;
848-
}
849-
830+
// Custom parser that parses function parameters of form `(<type>*, ...)`.
850831
static mlir::ParseResult
851-
parseFuncTypeArgs(mlir::AsmParser &p, llvm::SmallVector<mlir::Type> &params,
852-
bool &isVarArg) {
832+
parseFuncTypeParams(mlir::AsmParser &p, llvm::SmallVector<mlir::Type> &params,
833+
bool &isVarArg) {
853834
isVarArg = false;
854-
if (failed(p.parseLParen()))
855-
return failure();
856-
if (succeeded(p.parseOptionalRParen())) {
857-
// `()` empty argument list
858-
return mlir::success();
859-
}
860-
do {
861-
if (succeeded(p.parseOptionalEllipsis())) {
862-
// `...`, which must be the last thing in the list.
863-
isVarArg = true;
864-
break;
865-
} else {
866-
mlir::Type argType;
867-
if (failed(p.parseType(argType)))
868-
return failure();
869-
params.push_back(argType);
870-
}
871-
} while (succeeded(p.parseOptionalComma()));
872-
return p.parseRParen();
835+
return p.parseCommaSeparatedList(
836+
AsmParser::Delimiter::Paren, [&]() -> mlir::ParseResult {
837+
if (isVarArg)
838+
return p.emitError(p.getCurrentLocation(),
839+
"variadic `...` must be the last parameter");
840+
if (succeeded(p.parseOptionalEllipsis())) {
841+
isVarArg = true;
842+
return success();
843+
}
844+
mlir::Type type;
845+
if (failed(p.parseType(type)))
846+
return failure();
847+
params.push_back(type);
848+
return success();
849+
});
873850
}
874851

875-
static void printFuncTypeArgs(mlir::AsmPrinter &p,
876-
mlir::ArrayRef<mlir::Type> params,
877-
bool isVarArg) {
852+
static void printFuncTypeParams(mlir::AsmPrinter &p,
853+
mlir::ArrayRef<mlir::Type> params,
854+
bool isVarArg) {
878855
p << '(';
879856
llvm::interleaveComma(params, p,
880857
[&p](mlir::Type type) { p.printType(type); });
@@ -886,23 +863,6 @@ static void printFuncTypeArgs(mlir::AsmPrinter &p,
886863
p << ')';
887864
}
888865

889-
// Use a custom parser to handle the optional return and argument types without
890-
// an optional anchor.
891-
static mlir::ParseResult parseFuncType(mlir::AsmParser &p,
892-
mlir::Type &optionalReturnType,
893-
llvm::SmallVector<mlir::Type> &params,
894-
bool &isVarArg) {
895-
if (failed(parseFuncTypeArgs(p, params, isVarArg)))
896-
return failure();
897-
return parseFuncTypeReturn(p, optionalReturnType);
898-
}
899-
900-
static void printFuncType(mlir::AsmPrinter &p, mlir::Type optionalReturnType,
901-
mlir::ArrayRef<mlir::Type> params, bool isVarArg) {
902-
printFuncTypeArgs(p, params, isVarArg);
903-
printFuncTypeReturn(p, optionalReturnType);
904-
}
905-
906866
/// Get the C-style return type of the function, which is !cir.void if the
907867
/// function returns nothing and the actual return type otherwise.
908868
mlir::Type FuncType::getReturnType() const {

clang/test/CIR/IR/invalid.cir

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

0 commit comments

Comments
 (0)