diff --git a/flang/include/flang/Optimizer/Dialect/FIROpsSupport.h b/flang/include/flang/Optimizer/Dialect/FIROpsSupport.h --- a/flang/include/flang/Optimizer/Dialect/FIROpsSupport.h +++ b/flang/include/flang/Optimizer/Dialect/FIROpsSupport.h @@ -31,18 +31,18 @@ mlir::isa(op); } -/// return true iff the Operation is a fir::CallOp, fir::DispatchOp, +/// Return true iff the Operation is a fir::CallOp, fir::DispatchOp, /// mlir::CallOp, or mlir::CallIndirectOp and not pure -/// NB: this is not the same as `!pureCall(op)` +/// NB: This is not the same as `!pureCall(op)`. inline bool impureCall(mlir::Operation *op) { // Should we also auto-detect that the called function is pure if its // arguments are not references? For now, rely on a "pure" attribute. return op && isaCall(op) && !op->getAttr("pure"); } -/// return true iff the Operation is a fir::CallOp, fir::DispatchOp, +/// Return true iff the Operation is a fir::CallOp, fir::DispatchOp, /// mlir::CallOp, or mlir::CallIndirectOp and is also pure. -/// NB: this is not the same as `!impureCall(op)` +/// NB: This is not the same as `!impureCall(op)`. inline bool pureCall(mlir::Operation *op) { // Should we also auto-detect that the called function is pure if its // arguments are not references? For now, rely on a "pure" attribute. @@ -79,7 +79,9 @@ } /// Attribute to keep track of Fortran scoping information for a symbol. -static constexpr llvm::StringRef getSymbolAttrName() { return "fir.sym_name"; } +static constexpr llvm::StringRef getSymbolAttrName() { + return "fir.bindc_name"; +} /// Attribute to mark a function that takes a host associations argument. static constexpr llvm::StringRef getHostAssocAttrName() { diff --git a/flang/include/flang/Optimizer/Dialect/FIRType.h b/flang/include/flang/Optimizer/Dialect/FIRType.h --- a/flang/include/flang/Optimizer/Dialect/FIRType.h +++ b/flang/include/flang/Optimizer/Dialect/FIRType.h @@ -61,8 +61,8 @@ /// Is `t` a FIR dialect type that implies a memory (de)reference? inline bool isa_ref_type(mlir::Type t) { - return t.isa() || t.isa() || t.isa() || - t.isa(); + return t.isa(); } /// Is `t` a boxed type? @@ -255,11 +255,11 @@ /// Return true iff `ty` is a RecordType with type parameters. inline bool isRecordWithTypeParameters(mlir::Type ty) { if (auto recTy = ty.dyn_cast_or_null()) - return recTy.getNumLenParams() != 0; + return recTy.isDependentType(); return false; } -/// Is this tuple type holding a character function and its result length ? +/// Is this tuple type holding a character function and its result length? bool isCharacterProcedureTuple(mlir::Type type, bool acceptRawFunc = true); /// Apply the components specified by `path` to `rootTy` to determine the type @@ -267,8 +267,8 @@ /// Returns null on error. mlir::Type applyPathToType(mlir::Type rootTy, mlir::ValueRange path); -/// Does this function type have a result that requires binding the result value -/// with storage in a fir.save_result operation in order to use the result? +/// Does this function type has a result that requires binding the result value +/// with a storage in a fir.save_result operation in order to use the result? bool hasAbstractResult(mlir::FunctionType ty); /// Convert llvm::Type::TypeID to mlir::Type diff --git a/flang/include/flang/Optimizer/Dialect/FIRTypes.td b/flang/include/flang/Optimizer/Dialect/FIRTypes.td --- a/flang/include/flang/Optimizer/Dialect/FIRTypes.td +++ b/flang/include/flang/Optimizer/Dialect/FIRTypes.td @@ -333,6 +333,7 @@ } unsigned getNumFields() { return getTypeList().size(); } unsigned getNumLenParams() { return getLenParamList().size(); } + bool isDependentType() { return getNumLenParams(); } void finalize(llvm::ArrayRef lenPList, llvm::ArrayRef typeList); @@ -451,7 +452,7 @@ let extraClassDeclaration = [{ using Extent = int64_t; - using Shape = llvm::SmallVector; + using Shape = llvm::SmallVector; using ShapeRef = llvm::ArrayRef; unsigned getConstantRows() const; diff --git a/flang/test/Lower/program-units-fir-mangling.f90 b/flang/test/Lower/program-units-fir-mangling.f90 --- a/flang/test/Lower/program-units-fir-mangling.f90 +++ b/flang/test/Lower/program-units-fir-mangling.f90 @@ -136,22 +136,22 @@ end subroutine end program -! CHECK-LABEL: func @omp_get_num_threads() -> f32 attributes {fir.sym_name = "omp_get_num_threads"} { +! CHECK-LABEL: func @omp_get_num_threads() -> f32 attributes {fir.bindc_name = "omp_get_num_threads"} { function omp_get_num_threads() bind(c) ! CHECK: } end function -! CHECK-LABEL: func @get_threads() -> f32 attributes {fir.sym_name = "get_threads"} { +! CHECK-LABEL: func @get_threads() -> f32 attributes {fir.bindc_name = "get_threads"} { function omp_get_num_threads_1() bind(c, name ="get_threads") ! CHECK: } end function -! CHECK-LABEL: func @bEtA() -> f32 attributes {fir.sym_name = "bEtA"} { +! CHECK-LABEL: func @bEtA() -> f32 attributes {fir.bindc_name = "bEtA"} { function alpha() bind(c, name =" bEtA ") ! CHECK: } end function -! CHECK-LABEL: func @bc1() attributes {fir.sym_name = "bc1"} { +! CHECK-LABEL: func @bc1() attributes {fir.bindc_name = "bc1"} { subroutine bind_c_s() Bind(C,Name='bc1') ! CHECK: return end subroutine bind_c_s @@ -177,11 +177,11 @@ ! Test that BIND(C) label is taken into account for ENTRY symbols. ! CHECK-LABEL: func @_QPsub_with_entries() { subroutine sub_with_entries -! CHECK-LABEL: func @bar() attributes {fir.sym_name = "bar"} { +! CHECK-LABEL: func @bar() attributes {fir.bindc_name = "bar"} { entry some_entry() bind(c, name="bar") ! CHECK-LABEL: func @_QPnormal_entry() { entry normal_entry() -! CHECK-LABEL: func @some_other_entry() attributes {fir.sym_name = "some_other_entry"} { +! CHECK-LABEL: func @some_other_entry() attributes {fir.bindc_name = "some_other_entry"} { entry some_other_entry() bind(c) end subroutine @@ -198,24 +198,24 @@ end subroutine end interface contains -! CHECK-LABEL: func @ok3() -> f32 attributes {fir.sym_name = "ok3"} { +! CHECK-LABEL: func @ok3() -> f32 attributes {fir.bindc_name = "ok3"} { real function f2() bind(c,name=foo//'3') character*(*), parameter :: foo = ok ! CHECK: fir.call @ok1() : () -> f32 -! CHECK-LABEL: func @ok4() -> f32 attributes {fir.sym_name = "ok4"} { +! CHECK-LABEL: func @ok4() -> f32 attributes {fir.bindc_name = "ok4"} { entry f3() bind(c,name=foo//'4') ! CHECK: fir.call @ok1() : () -> f32 f2 = f1() end function -! CHECK-LABEL: func @ok5() attributes {fir.sym_name = "ok5"} { +! CHECK-LABEL: func @ok5() attributes {fir.bindc_name = "ok5"} { subroutine s2() bind(c,name=foo//'5') character*(*), parameter :: foo = ok ! CHECK: fir.call @ok2() : () -> () -! CHECK-LABEL: func @ok6() attributes {fir.sym_name = "ok6"} { +! CHECK-LABEL: func @ok6() attributes {fir.bindc_name = "ok6"} { entry s3() bind(c,name=foo//'6') ! CHECK: fir.call @ok2() : () -> () continue ! force end of specification part -! CHECK-LABEL: func @ok7() attributes {fir.sym_name = "ok7"} { +! CHECK-LABEL: func @ok7() attributes {fir.bindc_name = "ok7"} { entry s4() bind(c,name=foo//'7') ! CHECK: fir.call @ok2() : () -> () call s1