@@ -937,66 +937,51 @@ FuncType FuncType::clone(TypeRange inputs, TypeRange results) const {
937
937
// type.
938
938
static mlir::ParseResult parseFuncTypeReturn (mlir::AsmParser &p,
939
939
mlir::Type &optionalReturnType) {
940
- if (succeeded (p.parseOptionalLParen ())) {
941
- // If we have already a '(', the function has no return type
942
- optionalReturnType = {};
943
- return mlir::success ();
940
+ if (succeeded (p.parseOptionalArrow ())) {
941
+ // `->` found. It must be followed by the return type.
942
+ return p.parseType (optionalReturnType);
944
943
}
945
- mlir::Type type;
946
- if (p.parseType (type))
947
- return mlir::failure ();
948
- if (isa<cir::VoidType>(type))
949
- // An explicit !cir.void means also no return type.
950
- optionalReturnType = {};
951
- else
952
- // Otherwise use the actual type.
953
- optionalReturnType = type;
954
- return p.parseLParen ();
944
+ // Function has `void` return in C++, no return in MLIR.
945
+ optionalReturnType = {};
946
+ return success ();
955
947
}
956
948
957
949
// A special pretty-printer for function returning or not a result.
958
950
static void printFuncTypeReturn (mlir::AsmPrinter &p,
959
951
mlir::Type optionalReturnType) {
960
952
if (optionalReturnType)
961
- p << optionalReturnType << ' ' ;
962
- p << ' (' ;
953
+ p << " -> " << optionalReturnType;
963
954
}
964
955
965
956
static mlir::ParseResult
966
957
parseFuncTypeArgs (mlir::AsmParser &p, llvm::SmallVector<mlir::Type> ¶ms,
967
958
bool &isVarArg) {
968
959
isVarArg = false ;
969
- // `(` `)`
970
- if (succeeded (p.parseOptionalRParen ()))
960
+ if (failed (p.parseLParen ()))
961
+ return failure ();
962
+ if (succeeded (p.parseOptionalRParen ())) {
963
+ // `()` empty argument list
971
964
return mlir::success ();
972
-
973
- // `(` `...` `)`
974
- if (succeeded (p.parseOptionalEllipsis ())) {
975
- isVarArg = true ;
976
- return p.parseRParen ();
977
965
}
978
-
979
- // type (`,` type)* (`,` `...`)?
980
- mlir::Type type;
981
- if (p.parseType (type))
982
- return mlir::failure ();
983
- params.push_back (type);
984
- while (succeeded (p.parseOptionalComma ())) {
966
+ do {
985
967
if (succeeded (p.parseOptionalEllipsis ())) {
968
+ // `...`, which must be the last thing in the list.
986
969
isVarArg = true ;
987
- return p.parseRParen ();
970
+ break ;
971
+ } else {
972
+ mlir::Type argType;
973
+ if (failed (p.parseType (argType)))
974
+ return failure ();
975
+ params.push_back (argType);
988
976
}
989
- if (p.parseType (type))
990
- return mlir::failure ();
991
- params.push_back (type);
992
- }
993
-
977
+ } while (succeeded (p.parseOptionalComma ()));
994
978
return p.parseRParen ();
995
979
}
996
980
997
981
static void printFuncTypeArgs (mlir::AsmPrinter &p,
998
982
mlir::ArrayRef<mlir::Type> params,
999
983
bool isVarArg) {
984
+ p << ' (' ;
1000
985
llvm::interleaveComma (params, p,
1001
986
[&p](mlir::Type type) { p.printType (type); });
1002
987
if (isVarArg) {
@@ -1010,45 +995,52 @@ static void printFuncTypeArgs(mlir::AsmPrinter &p,
1010
995
// Use a custom parser to handle the optional return and argument types without
1011
996
// an optional anchor.
1012
997
static mlir::ParseResult parseFuncType (mlir::AsmParser &p,
1013
- mlir::Type &optionalReturnTypes ,
998
+ mlir::Type &optionalReturnType ,
1014
999
llvm::SmallVector<mlir::Type> ¶ms,
1015
1000
bool &isVarArg) {
1016
- if (failed (parseFuncTypeReturn (p, optionalReturnTypes )))
1001
+ if (failed (parseFuncTypeArgs (p, params, isVarArg )))
1017
1002
return failure ();
1018
- return parseFuncTypeArgs (p, params, isVarArg );
1003
+ return parseFuncTypeReturn (p, optionalReturnType );
1019
1004
}
1020
1005
1021
- static void printFuncType (mlir::AsmPrinter &p, mlir::Type optionalReturnTypes ,
1006
+ static void printFuncType (mlir::AsmPrinter &p, mlir::Type optionalReturnType ,
1022
1007
mlir::ArrayRef<mlir::Type> params, bool isVarArg) {
1023
- printFuncTypeReturn (p, optionalReturnTypes);
1024
1008
printFuncTypeArgs (p, params, isVarArg);
1009
+ printFuncTypeReturn (p, optionalReturnType);
1025
1010
}
1026
1011
1027
- // Return the actual return type or an explicit !cir.void if the function does
1028
- // not return anything
1012
+ // / Get the C-style return type of the function, which is !cir.void if the
1013
+ // / function returns nothing and the actual return type otherwise.
1029
1014
mlir::Type FuncType::getReturnType () const {
1030
- if (isVoid ())
1015
+ if (hasVoidReturn ())
1031
1016
return cir::VoidType::get (getContext ());
1032
- return static_cast <detail::FuncTypeStorage *>( getImpl ())-> optionalReturnType ;
1017
+ return getOptionalReturnType () ;
1033
1018
}
1034
1019
1035
- // / Returns the result type of the function as an ArrayRef, enabling better
1036
- // / integration with generic MLIR utilities.
1020
+ // / Get the MLIR-style return type of the function, which is an empty
1021
+ // / ArrayRef if the function returns nothing and a single-element ArrayRef
1022
+ // / with the actual return type otherwise.
1037
1023
llvm::ArrayRef<mlir::Type> FuncType::getReturnTypes () const {
1038
- if (isVoid ())
1024
+ if (hasVoidReturn ())
1039
1025
return {};
1040
- return static_cast <detail::FuncTypeStorage *>(getImpl ())->optionalReturnType ;
1041
- }
1042
-
1043
- // Whether the function returns void
1044
- bool FuncType::isVoid () const {
1045
- auto rt =
1046
- static_cast <detail::FuncTypeStorage *>(getImpl ())->optionalReturnType ;
1047
- assert (!rt ||
1048
- !mlir::isa<cir::VoidType>(rt) &&
1049
- " The return type for a function returning void should be empty "
1050
- " instead of a real !cir.void" );
1051
- return !rt;
1026
+ // Can't use getOptionalReturnType() here because llvm::ArrayRef hold a
1027
+ // pointer to its elements and doesn't do lifetime extension. That would
1028
+ // result in returning a pointer to a temporary that has gone out of scope.
1029
+ return getImpl ()->optionalReturnType ;
1030
+ }
1031
+
1032
+ // Does the fuction type return nothing?
1033
+ bool FuncType::hasVoidReturn () const { return !getOptionalReturnType (); }
1034
+
1035
+ mlir::LogicalResult
1036
+ FuncType::verify (llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
1037
+ llvm::ArrayRef<mlir::Type> argTypes, mlir::Type returnType,
1038
+ bool isVarArg) {
1039
+ if (returnType && mlir::isa<cir::VoidType>(returnType)) {
1040
+ emitError () << " !cir.func cannot have an explicit 'void' return type" ;
1041
+ return mlir::failure ();
1042
+ }
1043
+ return mlir::success ();
1052
1044
}
1053
1045
1054
1046
// ===----------------------------------------------------------------------===//
0 commit comments