[flang-commits] [flang] [flang][OpenMP] Store DECLARE_TARGET information in WithOmpDeclarative (PR #201103)

Krzysztof Parzyszek via flang-commits flang-commits at lists.llvm.org
Wed Jun 3 06:49:31 PDT 2026


================
@@ -2191,19 +2191,84 @@ bool OmpAttributeVisitor::Pre(const parser::OpenMPCriticalConstruct &x) {
 bool OmpAttributeVisitor::Pre(const parser::OmpDeclareTargetDirective &x) {
   PushContext(x.source, llvm::omp::Directive::OMPD_declare_target);
 
+  unsigned version{context_.langOptions().OpenMPVersion};
+  using OmpClauseSet = WithOmpDeclarative::OmpClauseSet;
+  std::map<const Symbol *, WithOmpDeclarative> details;
+  std::optional<common::OmpDeviceType> device;
+
+  if (auto *devClause{
+          parser::omp::FindClause(x.v, llvm::omp::Clause::OMPC_device_type)}) {
+    device = parser::UnwrapRef<common::OmpDeviceType>(*devClause);
+  }
+
+  auto addClause{[&](const parser::OmpObject &object,
+                     llvm::omp::Clause clauseId) {
+    if (const Symbol *sym{omp::GetObjectSymbol(object)}) {
+      auto &clauseSet{const_cast<OmpClauseSet &>(details[sym].ompDeclTarget())};
+      clauseSet.set(clauseId);
+    }
+  }};
+
   for (const parser::OmpArgument &arg : x.v.Arguments().v) {
     if (auto *object{parser::omp::GetArgumentObject(arg)}) {
       ResolveOmpObject(*object, Symbol::Flag::OmpDeclareTarget);
+      // Always record this as "enter", even with older OpenMP versions
+      // (as opposed to "to").
+      addClause(*object, llvm::omp::Clause::OMPC_enter);
     }
   }
 
   for (const parser::OmpClause &clause : x.v.Clauses().v) {
     if (auto *objects{parser::omp::GetOmpObjectList(clause)}) {
       for (const parser::OmpObject &object : objects->v) {
         ResolveOmpObject(object, Symbol::Flag::OmpDeclareTarget);
+        addClause(object, clause.Id());
       }
     }
   }
+
+  if (x.v.Arguments().v.empty() && x.v.Clauses().v.empty()) {
+    // "!$omp declare_target" alone applies to the associated procedure.
+    const Scope &scope{omp::GetScopingUnit(context_.FindScope(x.source))};
+    if (auto *proc{const_cast<Symbol *>(scope.symbol())}) {
----------------
kparzysz wrote:

We tolerate bad code in symbol resolution (resolve-names.cpp and resolve-directives.cpp), leaving diagnostic checks to the check-omp-*.cpp files.

A simple check of where this can occur shows that we do diagnose this:
```
!$omp declare target
end
```
```
test.f90:1:7: error: DECLARE TARGET directive without arguments or clauses must appear in a subroutine or function
  !$omp declare target
        ^^^^^^^^^^^^^^
```

https://github.com/llvm/llvm-project/pull/201103


More information about the flang-commits mailing list