@@ -32,6 +32,21 @@ using namespace fir;
3232
3333namespace {
3434
35+ static llvm::StringRef getVolatileKeyword () { return " volatile" ; }
36+
37+ static mlir::ParseResult parseOptionalCommaAndKeyword (mlir::AsmParser &parser,
38+ mlir::StringRef keyword,
39+ bool &parsedKeyword) {
40+ if (!parser.parseOptionalComma ()) {
41+ if (parser.parseKeyword (keyword))
42+ return mlir::failure ();
43+ parsedKeyword = true ;
44+ return mlir::success ();
45+ }
46+ parsedKeyword = false ;
47+ return mlir::success ();
48+ }
49+
3550template <typename TYPE>
3651TYPE parseIntSingleton (mlir::AsmParser &parser) {
3752 int kind = 0 ;
@@ -215,6 +230,19 @@ mlir::Type getDerivedType(mlir::Type ty) {
215230 .Default ([](mlir::Type t) { return t; });
216231}
217232
233+ mlir::Type updateTypeWithVolatility (mlir::Type type, bool isVolatile) {
234+ // If we already have the volatility we asked for, return the type unchanged.
235+ if (fir::isa_volatile_type (type) == isVolatile)
236+ return type;
237+ return mlir::TypeSwitch<mlir::Type, mlir::Type>(type)
238+ .Case <fir::BoxType, fir::ClassType, fir::ReferenceType>(
239+ [&](auto ty) -> mlir::Type {
240+ using TYPE = decltype (ty);
241+ return TYPE::get (ty.getEleTy (), isVolatile);
242+ })
243+ .Default ([&](mlir::Type t) -> mlir::Type { return t; });
244+ }
245+
218246mlir::Type dyn_cast_ptrEleTy (mlir::Type t) {
219247 return llvm::TypeSwitch<mlir::Type, mlir::Type>(t)
220248 .Case <fir::ReferenceType, fir::PointerType, fir::HeapType,
@@ -701,6 +729,13 @@ bool fir::isa_unknown_size_box(mlir::Type t) {
701729 return false ;
702730}
703731
732+ bool fir::isa_volatile_type (mlir::Type t) {
733+ return llvm::TypeSwitch<mlir::Type, bool >(t)
734+ .Case <fir::ReferenceType, fir::BoxType, fir::ClassType>(
735+ [](auto t) { return t.isVolatile (); })
736+ .Default ([](mlir::Type) { return false ; });
737+ }
738+
704739// ===----------------------------------------------------------------------===//
705740// BoxProcType
706741// ===----------------------------------------------------------------------===//
@@ -738,9 +773,31 @@ static bool cannotBePointerOrHeapElementType(mlir::Type eleTy) {
738773// BoxType
739774// ===----------------------------------------------------------------------===//
740775
776+ // `box` `<` type (`, volatile` $volatile^)? `>`
777+ mlir::Type fir::BoxType::parse (mlir::AsmParser &parser) {
778+ mlir::Type eleTy;
779+ auto location = parser.getCurrentLocation ();
780+ auto *context = parser.getContext ();
781+ bool isVolatile = false ;
782+ if (parser.parseLess () || parser.parseType (eleTy))
783+ return {};
784+ if (parseOptionalCommaAndKeyword (parser, getVolatileKeyword (), isVolatile))
785+ return {};
786+ if (parser.parseGreater ())
787+ return {};
788+ return parser.getChecked <fir::BoxType>(location, context, eleTy, isVolatile);
789+ }
790+
791+ void fir::BoxType::print (mlir::AsmPrinter &printer) const {
792+ printer << " <" << getEleTy ();
793+ if (isVolatile ())
794+ printer << " , " << getVolatileKeyword ();
795+ printer << ' >' ;
796+ }
797+
741798llvm::LogicalResult
742799fir::BoxType::verify (llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
743- mlir::Type eleTy) {
800+ mlir::Type eleTy, bool isVolatile ) {
744801 if (mlir::isa<fir::BaseBoxType>(eleTy))
745802 return emitError () << " invalid element type\n " ;
746803 // TODO
@@ -807,9 +864,32 @@ void fir::CharacterType::print(mlir::AsmPrinter &printer) const {
807864// ClassType
808865// ===----------------------------------------------------------------------===//
809866
867+ // `class` `<` type (`, volatile` $volatile^)? `>`
868+ mlir::Type fir::ClassType::parse (mlir::AsmParser &parser) {
869+ mlir::Type eleTy;
870+ auto location = parser.getCurrentLocation ();
871+ auto *context = parser.getContext ();
872+ bool isVolatile = false ;
873+ if (parser.parseLess () || parser.parseType (eleTy))
874+ return {};
875+ if (parseOptionalCommaAndKeyword (parser, getVolatileKeyword (), isVolatile))
876+ return {};
877+ if (parser.parseGreater ())
878+ return {};
879+ return parser.getChecked <fir::ClassType>(location, context, eleTy,
880+ isVolatile);
881+ }
882+
883+ void fir::ClassType::print (mlir::AsmPrinter &printer) const {
884+ printer << " <" << getEleTy ();
885+ if (isVolatile ())
886+ printer << " , " << getVolatileKeyword ();
887+ printer << ' >' ;
888+ }
889+
810890llvm::LogicalResult
811891fir::ClassType::verify (llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
812- mlir::Type eleTy) {
892+ mlir::Type eleTy, bool isVolatile ) {
813893 if (mlir::isa<fir::RecordType, fir::SequenceType, fir::HeapType,
814894 fir::PointerType, mlir::NoneType, mlir::IntegerType,
815895 mlir::FloatType, fir::CharacterType, fir::LogicalType,
@@ -1057,18 +1137,32 @@ unsigned fir::RecordType::getFieldIndex(llvm::StringRef ident) {
10571137// ReferenceType
10581138// ===----------------------------------------------------------------------===//
10591139
1060- // `ref` `<` type `>`
1140+ // `ref` `<` type (`, volatile` $volatile^)? `>`
10611141mlir::Type fir::ReferenceType::parse (mlir::AsmParser &parser) {
1062- return parseTypeSingleton<fir::ReferenceType>(parser);
1142+ auto location = parser.getCurrentLocation ();
1143+ auto *context = parser.getContext ();
1144+ mlir::Type eleTy;
1145+ bool isVolatile = false ;
1146+ if (parser.parseLess () || parser.parseType (eleTy))
1147+ return {};
1148+ if (parseOptionalCommaAndKeyword (parser, getVolatileKeyword (), isVolatile))
1149+ return {};
1150+ if (parser.parseGreater ())
1151+ return {};
1152+ return parser.getChecked <fir::ReferenceType>(location, context, eleTy,
1153+ isVolatile);
10631154}
10641155
10651156void fir::ReferenceType::print (mlir::AsmPrinter &printer) const {
1066- printer << " <" << getEleTy () << ' >' ;
1157+ printer << " <" << getEleTy ();
1158+ if (isVolatile ())
1159+ printer << " , " << getVolatileKeyword ();
1160+ printer << ' >' ;
10671161}
10681162
10691163llvm::LogicalResult fir::ReferenceType::verify (
1070- llvm::function_ref<mlir::InFlightDiagnostic()> emitError,
1071- mlir::Type eleTy ) {
1164+ llvm::function_ref<mlir::InFlightDiagnostic()> emitError, mlir::Type eleTy,
1165+ bool isVolatile ) {
10721166 if (mlir::isa<ShapeType, ShapeShiftType, SliceType, FieldType, LenType,
10731167 ReferenceType, TypeDescType>(eleTy))
10741168 return emitError () << " cannot build a reference to type: " << eleTy << ' \n ' ;
0 commit comments