@@ -837,66 +837,51 @@ FuncType FuncType::clone(TypeRange inputs, TypeRange results) const {
837837// type.
838838static mlir::ParseResult parseFuncTypeReturn (mlir::AsmParser &p,
839839 mlir::Type &optionalReturnType) {
840- if (succeeded (p.parseOptionalLParen ())) {
841- // If we have already a '(', the function has no return type
842- optionalReturnType = {};
843- return mlir::success ();
840+ if (succeeded (p.parseOptionalArrow ())) {
841+ // `->` found. It must be followed by the return type.
842+ return p.parseType (optionalReturnType);
844843 }
845- mlir::Type type;
846- if (p.parseType (type))
847- return mlir::failure ();
848- if (isa<cir::VoidType>(type))
849- // An explicit !cir.void means also no return type.
850- optionalReturnType = {};
851- else
852- // Otherwise use the actual type.
853- optionalReturnType = type;
854- return p.parseLParen ();
844+ // Function has `void` return in C++, no return in MLIR.
845+ optionalReturnType = {};
846+ return success ();
855847}
856848
857849// A special pretty-printer for function returning or not a result.
858850static void printFuncTypeReturn (mlir::AsmPrinter &p,
859851 mlir::Type optionalReturnType) {
860852 if (optionalReturnType)
861- p << optionalReturnType << ' ' ;
862- p << ' (' ;
853+ p << " -> " << optionalReturnType;
863854}
864855
865856static mlir::ParseResult
866857parseFuncTypeArgs (mlir::AsmParser &p, llvm::SmallVector<mlir::Type> ¶ms,
867858 bool &isVarArg) {
868859 isVarArg = false ;
869- // `(` `)`
870- if (succeeded (p.parseOptionalRParen ()))
860+ if (failed (p.parseLParen ()))
861+ return failure ();
862+ if (succeeded (p.parseOptionalRParen ())) {
863+ // `()` empty argument list
871864 return mlir::success ();
872-
873- // `(` `...` `)`
874- if (succeeded (p.parseOptionalEllipsis ())) {
875- isVarArg = true ;
876- return p.parseRParen ();
877865 }
878-
879- // type (`,` type)* (`,` `...`)?
880- mlir::Type type;
881- if (p.parseType (type))
882- return mlir::failure ();
883- params.push_back (type);
884- while (succeeded (p.parseOptionalComma ())) {
866+ do {
885867 if (succeeded (p.parseOptionalEllipsis ())) {
868+ // `...`, which must be the last thing in the list.
886869 isVarArg = true ;
887- return p.parseRParen ();
870+ break ;
871+ } else {
872+ mlir::Type argType;
873+ if (failed (p.parseType (argType)))
874+ return failure ();
875+ params.push_back (argType);
888876 }
889- if (p.parseType (type))
890- return mlir::failure ();
891- params.push_back (type);
892- }
893-
877+ } while (succeeded (p.parseOptionalComma ()));
894878 return p.parseRParen ();
895879}
896880
897881static void printFuncTypeArgs (mlir::AsmPrinter &p,
898882 mlir::ArrayRef<mlir::Type> params,
899883 bool isVarArg) {
884+ p << ' (' ;
900885 llvm::interleaveComma (params, p,
901886 [&p](mlir::Type type) { p.printType (type); });
902887 if (isVarArg) {
@@ -910,45 +895,52 @@ static void printFuncTypeArgs(mlir::AsmPrinter &p,
910895// Use a custom parser to handle the optional return and argument types without
911896// an optional anchor.
912897static mlir::ParseResult parseFuncType (mlir::AsmParser &p,
913- mlir::Type &optionalReturnTypes ,
898+ mlir::Type &optionalReturnType ,
914899 llvm::SmallVector<mlir::Type> ¶ms,
915900 bool &isVarArg) {
916- if (failed (parseFuncTypeReturn (p, optionalReturnTypes )))
901+ if (failed (parseFuncTypeArgs (p, params, isVarArg )))
917902 return failure ();
918- return parseFuncTypeArgs (p, params, isVarArg );
903+ return parseFuncTypeReturn (p, optionalReturnType );
919904}
920905
921- static void printFuncType (mlir::AsmPrinter &p, mlir::Type optionalReturnTypes ,
906+ static void printFuncType (mlir::AsmPrinter &p, mlir::Type optionalReturnType ,
922907 mlir::ArrayRef<mlir::Type> params, bool isVarArg) {
923- printFuncTypeReturn (p, optionalReturnTypes);
924908 printFuncTypeArgs (p, params, isVarArg);
909+ printFuncTypeReturn (p, optionalReturnType);
925910}
926911
927- // Return the actual return type or an explicit !cir.void if the function does
928- // not return anything
912+ // / Get the C-style return type of the function, which is !cir.void if the
913+ // / function returns nothing and the actual return type otherwise.
929914mlir::Type FuncType::getReturnType () const {
930- if (isVoid ())
915+ if (hasVoidReturn ())
931916 return cir::VoidType::get (getContext ());
932- return static_cast <detail::FuncTypeStorage *>( getImpl ())-> optionalReturnType ;
917+ return getOptionalReturnType () ;
933918}
934919
935- // / Returns the result type of the function as an ArrayRef, enabling better
936- // / integration with generic MLIR utilities.
920+ // / Get the MLIR-style return type of the function, which is an empty
921+ // / ArrayRef if the function returns nothing and a single-element ArrayRef
922+ // / with the actual return type otherwise.
937923llvm::ArrayRef<mlir::Type> FuncType::getReturnTypes () const {
938- if (isVoid ())
924+ if (hasVoidReturn ())
939925 return {};
940- return static_cast <detail::FuncTypeStorage *>(getImpl ())->optionalReturnType ;
941- }
942-
943- // Whether the function returns void
944- bool FuncType::isVoid () const {
945- auto rt =
946- static_cast <detail::FuncTypeStorage *>(getImpl ())->optionalReturnType ;
947- assert (!rt ||
948- !mlir::isa<cir::VoidType>(rt) &&
949- " The return type for a function returning void should be empty "
950- " instead of a real !cir.void" );
951- return !rt;
926+ // Can't use getOptionalReturnType() here because llvm::ArrayRef hold a
927+ // pointer to its elements and doesn't do lifetime extension. That would
928+ // result in returning a pointer to a temporary that has gone out of scope.
929+ return getImpl ()->optionalReturnType ;
930+ }
931+
932+ // Does the fuction type return nothing?
933+ bool FuncType::hasVoidReturn () const { return !getOptionalReturnType (); }
934+
935+ mlir::LogicalResult
936+ FuncType::verify (llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
937+ llvm::ArrayRef<mlir::Type> argTypes, mlir::Type returnType,
938+ bool isVarArg) {
939+ if (returnType && mlir::isa<cir::VoidType>(returnType)) {
940+ emitError () << " !cir.func cannot have an explicit 'void' return type" ;
941+ return mlir::failure ();
942+ }
943+ return mlir::success ();
952944}
953945
954946// ===----------------------------------------------------------------------===//
0 commit comments