[flang][OpenACC] Propagate acc.declare attribute to fir.global for USEd module variables (#192141)

When a module with `!$acc declare` is compiled separately from the
program that USEs it, `declareGlobal()` creates `fir.global` without the
`acc.declare` attribute. This causes implicit data mappings to override
device data that should already be present via `acc declare`.

The fix reads the symbol's `AccDeclare`/`AccCreate`/`AccCopyIn`/etc.
flags (already set from the `.mod` file by semantics) and attaches the
`acc.declare` attribute to the `fir.global`.
diff --git a/flang/lib/Lower/ConvertVariable.cpp b/flang/lib/Lower/ConvertVariable.cpp
index 0ededb3..bc11647 100644
--- a/flang/lib/Lower/ConvertVariable.cpp
+++ b/flang/lib/Lower/ConvertVariable.cpp
@@ -44,6 +44,7 @@
 #include "flang/Runtime/allocator-registry-consts.h"
 #include "flang/Semantics/runtime-type-info.h"
 #include "flang/Semantics/tools.h"
+#include "mlir/Dialect/OpenACC/OpenACC.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Debug.h"
 #include <optional>
@@ -160,6 +161,38 @@
   return converter.getCurrentLocation();
 }
 
+/// If \p sym has acc declare flags, attach the acc.declare attribute to
+/// \p global so that the variable is recognized as already managed by
+/// OpenACC declare directives (and should not be implicitly copied to
+/// the device).
+static void attachAccDeclareAttribute(fir::FirOpBuilder &builder,
+                                      fir::GlobalOp global,
+                                      const Fortran::semantics::Symbol &sym) {
+  using Flag = Fortran::semantics::Symbol::Flag;
+  const Fortran::semantics::Symbol &ultimate = sym.GetUltimate();
+  if (!ultimate.test(Flag::AccDeclare))
+    return;
+  mlir::acc::DataClause clause = mlir::acc::DataClause::acc_create;
+  if (ultimate.test(Flag::AccCopy))
+    clause = mlir::acc::DataClause::acc_copy;
+  else if (ultimate.test(Flag::AccCopyIn))
+    clause = mlir::acc::DataClause::acc_copyin;
+  else if (ultimate.test(Flag::AccCopyOut))
+    clause = mlir::acc::DataClause::acc_copyout;
+  else if (ultimate.test(Flag::AccCreate))
+    clause = mlir::acc::DataClause::acc_create;
+  else if (ultimate.test(Flag::AccPresent))
+    clause = mlir::acc::DataClause::acc_present;
+  else if (ultimate.test(Flag::AccDeviceResident))
+    clause = mlir::acc::DataClause::acc_declare_device_resident;
+  else if (ultimate.test(Flag::AccLink))
+    clause = mlir::acc::DataClause::acc_declare_link;
+  global->setAttr(mlir::acc::getDeclareAttrName(),
+                  mlir::acc::DeclareAttr::get(
+                      builder.getContext(), mlir::acc::DataClauseAttr::get(
+                                                builder.getContext(), clause)));
+}
+
 /// Create the global op declaration without any initializer
 static fir::GlobalOp declareGlobal(Fortran::lower::AbstractConverter &converter,
                                    const Fortran::lower::pft::Variable &var,
@@ -185,9 +218,11 @@
       !Fortran::semantics::IsProcedurePointer(ultimate))
     mlir::emitError(loc, "processing global declaration: symbol '")
         << toStringRef(sym.name()) << "' has unexpected details\n";
-  return builder.createGlobal(loc, converter.genType(var), globalName, linkage,
-                              mlir::Attribute{}, isConstant(ultimate),
-                              var.isTarget(), dataAttr);
+  fir::GlobalOp global = builder.createGlobal(
+      loc, converter.genType(var), globalName, linkage, mlir::Attribute{},
+      isConstant(ultimate), var.isTarget(), dataAttr);
+  attachAccDeclareAttribute(builder, global, sym);
+  return global;
 }
 
 /// Temporary helper to catch todos in initial data target lowering.
diff --git a/flang/test/Lower/OpenACC/acc-declare-use-associated.f90 b/flang/test/Lower/OpenACC/acc-declare-use-associated.f90
new file mode 100644
index 0000000..cd700ae
--- /dev/null
+++ b/flang/test/Lower/OpenACC/acc-declare-use-associated.f90
@@ -0,0 +1,29 @@
+! Test that acc.declare attributes are propagated to fir.global when
+! a module with !$acc declare is USEd from a separately compiled file.
+
+! RUN: split-file %s %t
+! RUN: bbc -fopenacc -emit-hlfir %t/mod.f90 -o %t/mod.mlir --module=%t
+! RUN: bbc -fopenacc -emit-hlfir %t/use.f90 -o - -I %t | FileCheck %s
+
+//--- mod.f90
+module acc_declare_mod
+  integer, parameter :: n = 100
+  real, dimension(n) :: aa, bb
+  real :: coef
+  !$acc declare create(aa)
+  !$acc declare copyin(coef)
+end module
+
+//--- use.f90
+subroutine use_mod()
+  use acc_declare_mod
+  implicit none
+  integer :: i
+  !$acc parallel loop
+  do i = 1, n
+    aa(i) = bb(i) + coef
+  end do
+end subroutine
+
+! CHECK: fir.global @_QMacc_declare_modEaa {acc.declare = #acc.declare<dataClause = acc_create>} : !fir.array<100xf32>
+! CHECK: fir.global @_QMacc_declare_modEcoef {acc.declare = #acc.declare<dataClause = acc_copyin>} : f32