@@ -223,8 +223,37 @@ class HlfirDesignatorBuilder {
223223 designatorNode, getConverter ().getFoldingContext (),
224224 /* namedConstantSectionsAreAlwaysContiguous=*/ false ))
225225 return fir::BoxType::get (resultValueType);
226+
227+ // TODO: handle async references
228+ bool isVolatile = false , isAsync = false ;
229+
230+ // Check if the base type is volatile
231+ if (partInfo.base .has_value ()) {
232+ mlir::Type baseType = partInfo.base .value ().getType ();
233+ isVolatile = fir::isa_volatile_ref_type (baseType);
234+ }
235+
236+ auto isVolatileSymbol = [&](const Fortran::semantics::Symbol &symbol) {
237+ return symbol.GetUltimate ().attrs ().test (Fortran::semantics::Attr::VOLATILE);
238+ };
239+
240+ // Check if this should be a volatile reference
241+ if constexpr (std::is_same_v<std::decay_t <T>,
242+ Fortran::evaluate::SymbolRef>) {
243+ if (isVolatileSymbol (designatorNode.get ()))
244+ isVolatile = true ;
245+ } else if constexpr (std::is_same_v<std::decay_t <T>,
246+ Fortran::evaluate::Component>) {
247+ if (isVolatileSymbol (designatorNode.GetLastSymbol ()))
248+ isVolatile = true ;
249+ }
250+
251+ // If it's a reference to a ref, account for it
252+ if (auto refTy = mlir::dyn_cast<fir::ReferenceType>(resultValueType))
253+ resultValueType = refTy.getEleTy ();
254+
226255 // Other designators can be handled as raw addresses.
227- return fir::ReferenceType::get (resultValueType);
256+ return fir::ReferenceType::get (resultValueType, isVolatile, isAsync );
228257 }
229258
230259 template <typename T>
@@ -269,6 +298,7 @@ class HlfirDesignatorBuilder {
269298 partInfo.componentName , partInfo.componentShape , partInfo.subscripts ,
270299 partInfo.substring , partInfo.complexPart , partInfo.resultShape ,
271300 partInfo.typeParams , attributes);
301+ llvm::dbgs () << __FILE__ << " :" << __LINE__ << " \n " << designate << " \n " << designatorType << " \n " ;
272302 if (auto elementalAddrOp = getVectorSubscriptElementAddrOp ())
273303 builder.setInsertionPoint (*elementalAddrOp);
274304 return mlir::cast<fir::FortranVariableOpInterface>(
@@ -414,10 +444,13 @@ class HlfirDesignatorBuilder {
414444 .Case <fir::SequenceType>([&](fir::SequenceType seqTy) -> mlir::Type {
415445 return fir::SequenceType::get (seqTy.getShape (), newEleTy);
416446 })
417- .Case <fir::PointerType, fir::HeapType, fir::ReferenceType, fir::BoxType,
418- fir::ClassType>([&](auto t) -> mlir::Type {
419- using FIRT = decltype (t);
420- return FIRT::get (changeElementType (t.getEleTy (), newEleTy));
447+ .Case <fir::PointerType, fir::HeapType, fir::BoxType, fir::ClassType>(
448+ [&](auto t) -> mlir::Type {
449+ using FIRT = decltype (t);
450+ return FIRT::get (changeElementType (t.getEleTy (), newEleTy));
451+ })
452+ .Case <fir::ReferenceType>([&](fir::ReferenceType refTy) -> mlir::Type {
453+ return fir::ReferenceType::get (changeElementType (refTy.getEleTy (), newEleTy), refTy.isVolatile ());
421454 })
422455 .Default ([newEleTy](mlir::Type t) -> mlir::Type { return newEleTy; });
423456 }
@@ -1796,6 +1829,7 @@ class HlfirBuilder {
17961829 /* complexPart=*/ std::nullopt ,
17971830 /* shape=*/ mlir::Value{}, /* typeParams=*/ mlir::ValueRange{},
17981831 fir::FortranVariableFlagsAttr{});
1832+ llvm::dbgs () << __LINE__ << " " << newParent << " \n " ;
17991833 currentParent = hlfir::EntityWithAttributes{newParent};
18001834 }
18011835 valuesAndParents.emplace_back (
@@ -1808,6 +1842,7 @@ class HlfirBuilder {
18081842 auto &expr = std::get<const Fortran::lower::SomeExpr &>(iter);
18091843 auto &baseOp = std::get<hlfir::EntityWithAttributes>(iter);
18101844 std::string name = converter.getRecordTypeFieldName (sym);
1845+ const bool isVolatile = fir::isa_volatile_ref_type (baseOp.getType ());
18111846
18121847 // Generate DesignateOp for the component.
18131848 // The designator's result type is just a reference to the component type,
@@ -1818,7 +1853,6 @@ class HlfirBuilder {
18181853 assert (compType && " failed to retrieve component type" );
18191854 mlir::Value compShape =
18201855 designatorBuilder.genComponentShape (sym, compType);
1821- mlir::Type designatorType = builder.getRefType (compType);
18221856
18231857 mlir::Type fieldElemType = hlfir::getFortranElementType (compType);
18241858 llvm::SmallVector<mlir::Value, 1 > typeParams;
@@ -1839,6 +1873,7 @@ class HlfirBuilder {
18391873 // Convert component symbol attributes to variable attributes.
18401874 fir::FortranVariableFlagsAttr attrs =
18411875 Fortran::lower::translateSymbolAttributes (builder.getContext (), sym);
1876+ mlir::Type designatorType = builder.getRefType (compType, isVolatile);
18421877
18431878 // Get the component designator.
18441879 auto lhs = builder.create <hlfir::DesignateOp>(
@@ -1847,6 +1882,7 @@ class HlfirBuilder {
18471882 /* substring=*/ mlir::ValueRange{},
18481883 /* complexPart=*/ std::nullopt ,
18491884 /* shape=*/ compShape, typeParams, attrs);
1885+ llvm::dbgs () << __LINE__ << " " << lhs << " \n " ;
18501886
18511887 if (attrs && bitEnumContainsAny (attrs.getFlags (),
18521888 fir::FortranVariableFlagsEnum::pointer)) {
0 commit comments