2121// ===----------------------------------------------------------------------===//
2222
2323static mlir::ParseResult
24- parseFuncTypeArgs (mlir::AsmParser &p, llvm::SmallVector<mlir::Type> ¶ms,
25- bool &isVarArg);
26- static void printFuncTypeArgs (mlir::AsmPrinter &p,
27- mlir::ArrayRef<mlir::Type> params, bool isVarArg);
24+ parseFuncTypeParams (mlir::AsmParser &p, llvm::SmallVector<mlir::Type> ¶ms,
25+ bool &isVarArg);
26+ static void printFuncTypeParams (mlir::AsmPrinter &p,
27+ mlir::ArrayRef<mlir::Type> params,
28+ bool isVarArg);
2829
2930// ===----------------------------------------------------------------------===//
3031// Get autogenerated stuff
@@ -282,40 +283,32 @@ FuncType FuncType::clone(TypeRange inputs, TypeRange results) const {
282283 return get (llvm::to_vector (inputs), results[0 ], isVarArg ());
283284}
284285
285- mlir::ParseResult parseFuncTypeArgs (mlir::AsmParser &p,
286- llvm::SmallVector<mlir::Type> ¶ms,
287- bool &isVarArg) {
286+ // Custom parser that parses function parameters of form `(<type>*, ...)`.
287+ static mlir::ParseResult
288+ parseFuncTypeParams (mlir::AsmParser &p, llvm::SmallVector<mlir::Type> ¶ms,
289+ bool &isVarArg) {
288290 isVarArg = false ;
289- // `(` `)`
290- if (succeeded (p.parseOptionalRParen ()))
291- return mlir::success ();
292-
293- // `(` `...` `)`
294- if (succeeded (p.parseOptionalEllipsis ())) {
295- isVarArg = true ;
296- return p.parseRParen ();
297- }
298-
299- // type (`,` type)* (`,` `...`)?
300- mlir::Type type;
301- if (p.parseType (type))
302- return mlir::failure ();
303- params.push_back (type);
304- while (succeeded (p.parseOptionalComma ())) {
305- if (succeeded (p.parseOptionalEllipsis ())) {
306- isVarArg = true ;
307- return p.parseRParen ();
308- }
309- if (p.parseType (type))
310- return mlir::failure ();
311- params.push_back (type);
312- }
313-
314- return p.parseRParen ();
315- }
316-
317- void printFuncTypeArgs (mlir::AsmPrinter &p, mlir::ArrayRef<mlir::Type> params,
318- bool isVarArg) {
291+ return p.parseCommaSeparatedList (
292+ AsmParser::Delimiter::Paren, [&]() -> mlir::ParseResult {
293+ if (isVarArg)
294+ return p.emitError (p.getCurrentLocation (),
295+ " variadic `...` must be the last parameter" );
296+ if (succeeded (p.parseOptionalEllipsis ())) {
297+ isVarArg = true ;
298+ return success ();
299+ }
300+ mlir::Type type;
301+ if (failed (p.parseType (type)))
302+ return failure ();
303+ params.push_back (type);
304+ return success ();
305+ });
306+ }
307+
308+ static void printFuncTypeParams (mlir::AsmPrinter &p,
309+ mlir::ArrayRef<mlir::Type> params,
310+ bool isVarArg) {
311+ p << ' (' ;
319312 llvm::interleaveComma (params, p,
320313 [&p](mlir::Type type) { p.printType (type); });
321314 if (isVarArg) {
@@ -326,11 +319,39 @@ void printFuncTypeArgs(mlir::AsmPrinter &p, mlir::ArrayRef<mlir::Type> params,
326319 p << ' )' ;
327320}
328321
322+ // / Get the C-style return type of the function, which is !cir.void if the
323+ // / function returns nothing and the actual return type otherwise.
324+ mlir::Type FuncType::getReturnType () const {
325+ if (hasVoidReturn ())
326+ return cir::VoidType::get (getContext ());
327+ return getOptionalReturnType ();
328+ }
329+
330+ // / Get the MLIR-style return type of the function, which is an empty
331+ // / ArrayRef if the function returns nothing and a single-element ArrayRef
332+ // / with the actual return type otherwise.
329333llvm::ArrayRef<mlir::Type> FuncType::getReturnTypes () const {
330- return static_cast <detail::FuncTypeStorage *>(getImpl ())->returnType ;
334+ if (hasVoidReturn ())
335+ return {};
336+ // Can't use getOptionalReturnType() here because llvm::ArrayRef hold a
337+ // pointer to its elements and doesn't do lifetime extension. That would
338+ // result in returning a pointer to a temporary that has gone out of scope.
339+ return getImpl ()->optionalReturnType ;
331340}
332341
333- bool FuncType::isVoid () const { return mlir::isa<VoidType>(getReturnType ()); }
342+ // Does the fuction type return nothing?
343+ bool FuncType::hasVoidReturn () const { return !getOptionalReturnType (); }
344+
345+ mlir::LogicalResult
346+ FuncType::verify (llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
347+ llvm::ArrayRef<mlir::Type> argTypes, mlir::Type returnType,
348+ bool isVarArg) {
349+ if (returnType && mlir::isa<cir::VoidType>(returnType)) {
350+ emitError () << " !cir.func cannot have an explicit 'void' return type" ;
351+ return mlir::failure ();
352+ }
353+ return mlir::success ();
354+ }
334355
335356// ===----------------------------------------------------------------------===//
336357// BoolType
0 commit comments