[flang] Non-type-bound defined IO lowering

Generate supporting data structures and calls to new runtime IO functions
for defined IO that accesses non-type-bound procedures, such as `wft` in:

module m1
  type t
    integer n
  end type
  interface write(formatted)
    module procedure wft
  end interface
 contains
  subroutine wft(dtv, unit, iotype, v_list, iostat, iomsg)
    class(t), intent(in) :: dtv
    integer, intent(in) :: unit
    character(*), intent(in) :: iotype
    integer, intent(in) :: v_list(:)
    integer, intent(out) :: iostat
    character(*), intent(inout) :: iomsg
    iostat = 0
    write(unit,*,iostat=iostat,iomsg=iomsg) 'wft was called: ', dtv%n
  end subroutine
end module

module m2
 contains
  subroutine test1
    use m1
    print *, 'test1, should call wft: ', t(1)
  end subroutine
  subroutine test2
    use m1, only: t
    print *, 'test2, should not call wft: ', t(2)
  end subroutine
end module

use m1
use m2
call test1
call test2
print *, 'main, should call wft: ', t(3)
end
diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp
index 19ae957..ea34da2 100644
--- a/flang/lib/Lower/Bridge.cpp
+++ b/flang/lib/Lower/Bridge.cpp
@@ -743,6 +743,10 @@
     return genUnknownLocation();
   }
 
+  const Fortran::semantics::Scope &getCurrentScope() override final {
+    return bridge.getSemanticsContext().FindScope(currentPosition);
+  }
+
   fir::FirOpBuilder &getFirOpBuilder() override final { return *builder; }
 
   mlir::ModuleOp &getModuleOp() override final { return bridge.getModule(); }
@@ -758,7 +762,10 @@
       const Fortran::semantics::DerivedTypeSpec &derivedType) override final {
     return Fortran::lower::mangle::mangleName(derivedType, scopeBlockIdMap);
   }
-
+  std::string mangleName(std::string &name) override final {
+    return Fortran::lower::mangle::mangleName(name, getCurrentScope(),
+                                              scopeBlockIdMap);
+  }
   const fir::KindMapping &getKindMap() override final {
     return bridge.getKindMap();
   }