33
33
#include " llvm/ADT/TypeSwitch.h"
34
34
#include " llvm/Support/ErrorHandling.h"
35
35
#include " llvm/Support/MathExtras.h"
36
+ #include < cassert>
36
37
#include < optional>
37
38
38
39
using cir::MissingFeatures;
@@ -42,13 +43,16 @@ using cir::MissingFeatures;
42
43
// ===----------------------------------------------------------------------===//
43
44
44
45
static mlir::ParseResult
45
- parseFuncTypeArgs (mlir::AsmParser &p, llvm::SmallVector<mlir::Type> ¶ms,
46
- bool &isVarArg);
47
- static void printFuncTypeArgs (mlir::AsmPrinter &p,
48
- mlir::ArrayRef<mlir::Type> params, bool isVarArg);
46
+ parseFuncType (mlir::AsmParser &p, llvm::SmallVector<mlir::Type> &returnTypes,
47
+ llvm::SmallVector<mlir::Type> ¶ms, bool &isVarArg);
48
+
49
+ static void printFuncType (mlir::AsmPrinter &p,
50
+ mlir::ArrayRef<mlir::Type> returnTypes,
51
+ mlir::ArrayRef<mlir::Type> params, bool isVarArg);
49
52
50
53
static mlir::ParseResult parsePointerAddrSpace (mlir::AsmParser &p,
51
54
mlir::Attribute &addrSpaceAttr);
55
+
52
56
static void printPointerAddrSpace (mlir::AsmPrinter &p,
53
57
mlir::Attribute addrSpaceAttr);
54
58
@@ -813,9 +817,46 @@ FuncType FuncType::clone(TypeRange inputs, TypeRange results) const {
813
817
return get (llvm::to_vector (inputs), results[0 ], isVarArg ());
814
818
}
815
819
816
- mlir::ParseResult parseFuncTypeArgs (mlir::AsmParser &p,
817
- llvm::SmallVector<mlir::Type> ¶ms,
818
- bool &isVarArg) {
820
+ // A special parser is needed for function returning void to consume the "!void"
821
+ // returned type in the case there is no alias defined.
822
+ static mlir::ParseResult
823
+ parseFuncTypeReturn (mlir::AsmParser &p,
824
+ llvm::SmallVector<mlir::Type> &returnTypes) {
825
+ if (p.parseOptionalExclamationKeyword (" !void" ).succeeded ())
826
+ // !void means no return type.
827
+ return p.parseLParen ();
828
+ if (succeeded (p.parseOptionalLParen ()))
829
+ // If we have already a '(', the function has no return type
830
+ return mlir::success ();
831
+
832
+ mlir::Type type;
833
+ auto result = p.parseOptionalType (type);
834
+ if (!result.has_value ())
835
+ return mlir::failure ();
836
+ if (failed (*result) || isa<cir::VoidType>(type))
837
+ // No return type specified.
838
+ return p.parseLParen ();
839
+ // Otherwise use the actual type.
840
+ returnTypes.push_back (type);
841
+ return p.parseLParen ();
842
+ }
843
+
844
+ // A special pretty-printer for function returning void to emit a "!void"
845
+ // returned type. Note that there is no real type used here since it does not
846
+ // appear in the IR and thus the alias might not be defined and cannot be
847
+ // referred to. This is why this is a pure syntactic-sugar string which is used.
848
+ static void printFuncTypeReturn (mlir::AsmPrinter &p,
849
+ mlir::ArrayRef<mlir::Type> returnTypes) {
850
+ if (returnTypes.empty ())
851
+ // Pretty-print no return type as "!void"
852
+ p << " !void " ;
853
+ else
854
+ p << returnTypes << ' ' ;
855
+ }
856
+
857
+ static mlir::ParseResult
858
+ parseFuncTypeArgs (mlir::AsmParser &p, llvm::SmallVector<mlir::Type> ¶ms,
859
+ bool &isVarArg) {
819
860
isVarArg = false ;
820
861
// `(` `)`
821
862
if (succeeded (p.parseOptionalRParen ()))
@@ -845,8 +886,10 @@ mlir::ParseResult parseFuncTypeArgs(mlir::AsmParser &p,
845
886
return p.parseRParen ();
846
887
}
847
888
848
- void printFuncTypeArgs (mlir::AsmPrinter &p, mlir::ArrayRef<mlir::Type> params,
849
- bool isVarArg) {
889
+ static void printFuncTypeArgs (mlir::AsmPrinter &p,
890
+ mlir::ArrayRef<mlir::Type> params,
891
+ bool isVarArg) {
892
+ p << ' (' ;
850
893
llvm::interleaveComma (params, p,
851
894
[&p](mlir::Type type) { p.printType (type); });
852
895
if (isVarArg) {
@@ -857,11 +900,37 @@ void printFuncTypeArgs(mlir::AsmPrinter &p, mlir::ArrayRef<mlir::Type> params,
857
900
p << ' )' ;
858
901
}
859
902
860
- llvm::ArrayRef<mlir::Type> FuncType::getReturnTypes () const {
861
- return static_cast <detail::FuncTypeStorage *>(getImpl ())->returnType ;
903
+ static mlir::ParseResult
904
+ parseFuncType (mlir::AsmParser &p, llvm::SmallVector<mlir::Type> &returnTypes,
905
+ llvm::SmallVector<mlir::Type> ¶ms, bool &isVarArg) {
906
+ if (failed (parseFuncTypeReturn (p, returnTypes)))
907
+ return failure ();
908
+ return parseFuncTypeArgs (p, params, isVarArg);
909
+ }
910
+
911
+ static void printFuncType (mlir::AsmPrinter &p,
912
+ mlir::ArrayRef<mlir::Type> returnTypes,
913
+ mlir::ArrayRef<mlir::Type> params, bool isVarArg) {
914
+ printFuncTypeReturn (p, returnTypes);
915
+ printFuncTypeArgs (p, params, isVarArg);
862
916
}
863
917
864
- bool FuncType::isVoid () const { return mlir::isa<VoidType>(getReturnType ()); }
918
+ // Return the actual return type or an explicit !cir.void if the function does
919
+ // not return anything
920
+ mlir::Type FuncType::getReturnType () const {
921
+ if (isVoid ())
922
+ return cir::VoidType::get (getContext ());
923
+ return static_cast <detail::FuncTypeStorage *>(getImpl ())->returnTypes .front ();
924
+ }
925
+
926
+ bool FuncType::isVoid () const {
927
+ auto rt = static_cast <detail::FuncTypeStorage *>(getImpl ())->returnTypes ;
928
+ assert (rt.empty () ||
929
+ !mlir::isa<cir::VoidType>(rt.front ()) &&
930
+ " The return type for a function returning void should be empty "
931
+ " instead of a real !cir.void" );
932
+ return rt.empty ();
933
+ }
865
934
866
935
// ===----------------------------------------------------------------------===//
867
936
// MethodType Definitions
0 commit comments