[flang] [llvm] [flang][OpenMP] Support custom mappers in target update to/from clauses (PR #169673)
Krish Gupta via llvm-commits
llvm-commits at lists.llvm.org
Mon Mar 2 00:50:33 PST 2026
https://github.com/KrxGu updated https://github.com/llvm/llvm-project/pull/169673
>From 7931bfe472971bb47324c673e7111ee94bc985d1 Mon Sep 17 00:00:00 2001
From: Krish Gupta <krishgupta at Krishs-MacBook-Air.local>
Date: Wed, 26 Nov 2025 21:43:27 +0530
Subject: [PATCH 01/11] [flang][OpenMP] Support mappers in target update
to/from
Fixes #168701
---
flang/lib/Semantics/resolve-names.cpp | 60 +++++++++++++++++++
.../Lower/OpenMP/target-update-mapper.f90 | 52 ++++++++++++++++
.../Semantics/OpenMP/target-update-mapper.f90 | 54 +++++++++++++++++
3 files changed, 166 insertions(+)
create mode 100644 flang/test/Lower/OpenMP/target-update-mapper.f90
create mode 100644 flang/test/Semantics/OpenMP/target-update-mapper.f90
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index 057fa1db239c1..0aa3134d37838 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -1634,6 +1634,8 @@ class OmpVisitor : public virtual DeclarationVisitor {
return true;
}
bool Pre(const parser::OmpMapClause &);
+ bool Pre(const parser::OmpClause::To &);
+ bool Pre(const parser::OmpClause::From &);
bool Pre(const parser::OpenMPSectionsConstruct &) {
PushScope(Scope::Kind::OtherConstruct, nullptr);
@@ -1879,6 +1881,64 @@ bool OmpVisitor::Pre(const parser::OmpMapClause &x) {
return true;
}
+bool OmpVisitor::Pre(const parser::OmpClause::To &x) {
+ // Resolve mapper names in "to" clauses (e.g., for target update)
+ auto &mods{OmpGetModifiers(x.v)};
+ if (auto *mapper{OmpGetUniqueModifier<parser::OmpMapper>(mods)}) {
+ if (auto *symbol{FindSymbol(currScope(), mapper->v)}) {
+ auto &ultimate{symbol->GetUltimate()};
+ auto *misc{ultimate.detailsIf<MiscDetails>()};
+ auto *md{ultimate.detailsIf<MapperDetails>()};
+ if (!md && (!misc || misc->kind() != MiscDetails::Kind::ConstructName))
+ context().Say(mapper->v.source,
+ "Name '%s' should be a mapper name"_err_en_US, mapper->v.source);
+ else
+ mapper->v.symbol = symbol;
+ } else {
+ // Allow the special 'default' mapper identifier without prior
+ // declaration so lowering can recognize and handle it. Emit an
+ // error for any other missing mapper identifier.
+ if (mapper->v.source.ToString() == "default") {
+ mapper->v.symbol = &MakeSymbol(
+ mapper->v, MiscDetails{MiscDetails::Kind::ConstructName});
+ } else {
+ context().Say(
+ mapper->v.source, "'%s' not declared"_err_en_US, mapper->v.source);
+ }
+ }
+ }
+ return true;
+}
+
+bool OmpVisitor::Pre(const parser::OmpClause::From &x) {
+ // Resolve mapper names in "from" clauses (e.g., for target update)
+ auto &mods{OmpGetModifiers(x.v)};
+ if (auto *mapper{OmpGetUniqueModifier<parser::OmpMapper>(mods)}) {
+ if (auto *symbol{FindSymbol(currScope(), mapper->v)}) {
+ auto &ultimate{symbol->GetUltimate()};
+ auto *misc{ultimate.detailsIf<MiscDetails>()};
+ auto *md{ultimate.detailsIf<MapperDetails>()};
+ if (!md && (!misc || misc->kind() != MiscDetails::Kind::ConstructName))
+ context().Say(mapper->v.source,
+ "Name '%s' should be a mapper name"_err_en_US, mapper->v.source);
+ else
+ mapper->v.symbol = symbol;
+ } else {
+ // Allow the special 'default' mapper identifier without prior
+ // declaration so lowering can recognize and handle it. Emit an
+ // error for any other missing mapper identifier.
+ if (mapper->v.source.ToString() == "default") {
+ mapper->v.symbol = &MakeSymbol(
+ mapper->v, MiscDetails{MiscDetails::Kind::ConstructName});
+ } else {
+ context().Say(
+ mapper->v.source, "'%s' not declared"_err_en_US, mapper->v.source);
+ }
+ }
+ }
+ return true;
+}
+
void OmpVisitor::ProcessMapperSpecifier(const parser::OmpMapperSpecifier &spec,
const parser::OmpClauseList &clauses) {
// This "manually" walks the tree of the construct, because we need
diff --git a/flang/test/Lower/OpenMP/target-update-mapper.f90 b/flang/test/Lower/OpenMP/target-update-mapper.f90
new file mode 100644
index 0000000000000..d49ad51343679
--- /dev/null
+++ b/flang/test/Lower/OpenMP/target-update-mapper.f90
@@ -0,0 +1,52 @@
+! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=52 %s -o - | FileCheck %s
+
+! Test mapper usage in target update to/from clauses
+
+program target_update_mapper
+ implicit none
+
+ integer, parameter :: n = 4
+
+ type :: typ
+ integer, allocatable :: a(:)
+ integer, allocatable :: b(:)
+ end type typ
+
+ !$omp declare mapper(custom: typ :: t) map(t%a)
+
+ ! CHECK-LABEL: omp.declare_mapper @_QQFcustom : !fir.type<_QFTtyp{a:!fir.box<!fir.heap<!fir.array<?xi32>>>,b:!fir.box<!fir.heap<!fir.array<?xi32>>>}>
+
+ type(typ) :: t
+
+ allocate(t%a(n), source=1)
+ allocate(t%b(n), source=2)
+
+ !$omp target enter data map(alloc: t)
+
+ ! Test target update to with custom mapper
+ ! CHECK: %[[T_VAR:.*]] = fir.declare %{{.*}} {uniq_name = "_QFtarget_update_mapperEt"} : (!fir.ref<!fir.type<_QFTtyp{a:!fir.box<!fir.heap<!fir.array<?xi32>>>,b:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>) -> !fir.ref<!fir.type<_QFTtyp{a:!fir.box<!fir.heap<!fir.array<?xi32>>>,b:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>
+ ! CHECK: %[[MAP_INFO:.*]] = omp.map.info var_ptr(%[[T_VAR]] : {{.*}}, {{.*}}) map_clauses(to) capture(ByRef) mapper(@_QQFcustom) -> {{.*}}
+ ! CHECK: omp.target_update motion_entries(%[[MAP_INFO]] : {{.*}})
+ t%a = 42
+ !$omp target update to(mapper(custom): t)
+
+ !$omp target
+ t%a(:) = t%a(:) / 2
+ t%b(:) = -1
+ !$omp end target
+
+ ! Test target update from with custom mapper
+ ! CHECK: %[[MAP_INFO2:.*]] = omp.map.info var_ptr(%{{.*}} : {{.*}}, {{.*}}) map_clauses(from) capture(ByRef) mapper(@_QQFcustom) -> {{.*}}
+ ! CHECK: omp.target_update motion_entries(%[[MAP_INFO2]] : {{.*}})
+ !$omp target update from(mapper(custom): t)
+
+ ! Test target update to with default mapper
+ ! CHECK: %[[MAP_INFO3:.*]] = omp.map.info var_ptr(%{{.*}} : {{.*}}, {{.*}}) map_clauses(to) capture(ByRef) mapper(@_QQFtyp_omp_default_mapper) -> {{.*}}
+ ! CHECK: omp.target_update motion_entries(%[[MAP_INFO3]] : {{.*}})
+ !$omp target update to(mapper(default): t)
+
+ !$omp target exit data map(delete: t)
+ deallocate(t%a)
+ deallocate(t%b)
+
+end program target_update_mapper
diff --git a/flang/test/Semantics/OpenMP/target-update-mapper.f90 b/flang/test/Semantics/OpenMP/target-update-mapper.f90
new file mode 100644
index 0000000000000..f03496e155568
--- /dev/null
+++ b/flang/test/Semantics/OpenMP/target-update-mapper.f90
@@ -0,0 +1,54 @@
+! RUN: %python %S/../test_errors.py %s %flang -fopenmp -fopenmp-version=52
+
+! Test mapper usage in target update to/from clauses
+
+program target_update_mapper
+ implicit none
+
+ integer, parameter :: n = 4
+
+ type :: typ
+ integer, allocatable :: a(:)
+ integer, allocatable :: b(:)
+ end type typ
+
+ !$omp declare mapper(custom: typ :: t) map(t%a)
+
+ type(typ) :: t
+ integer :: not_a_mapper
+ allocate(t%a(n), source=1)
+ allocate(t%b(n), source=2)
+
+ !$omp target enter data map(alloc: t)
+
+ ! Valid: using custom mapper with target update to
+ t%a = 42
+ !$omp target update to(mapper(custom): t)
+
+ !$omp target
+ t%a(:) = t%a(:) / 2
+ t%b(:) = -1
+ !$omp end target
+
+ ! Valid: using custom mapper with target update from
+ !$omp target update from(mapper(custom): t)
+
+ ! Valid: using default mapper explicitly
+ !$omp target update to(mapper(default): t)
+
+ print*, t%a
+ print*, t%b
+
+ !$omp target exit data map(delete: t)
+ deallocate(t%a)
+ deallocate(t%b)
+
+ ! Test error case: undefined mapper
+ !ERROR: 'undefined_mapper' not declared
+ !$omp target update to(mapper(undefined_mapper): t)
+
+ ! Test error case: wrong kind of symbol
+ !ERROR: Name 'not_a_mapper' should be a mapper name
+ !$omp target update from(mapper(not_a_mapper): t)
+
+end program target_update_mapper
>From 9bc3e079224a8a82f52a4b07087ebc9f54a3ff5a Mon Sep 17 00:00:00 2001
From: Krish Gupta <krishgupta at Krishs-MacBook-Air.local>
Date: Wed, 26 Nov 2025 22:37:45 +0530
Subject: [PATCH 02/11] [flang][OpenMP] Implement mapper lowering for target
update
Support mapper modifier in processMotionClauses for to/from clauses
---
flang/lib/Lower/OpenMP/ClauseProcessor.cpp | 29 ++++++++++++++-----
.../Lower/OpenMP/target-update-mapper.f90 | 9 +++---
2 files changed, 25 insertions(+), 13 deletions(-)
diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
index 51458b2a281d5..6cc38e907a45c 100644
--- a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
+++ b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
@@ -1545,21 +1545,34 @@ bool ClauseProcessor::processMotionClauses(lower::StatementContext &stmtCtx,
mlir::Location clauseLocation = converter.genLocation(source);
const auto &[expectation, mapper, iterator, objects] = clause.t;
- // TODO Support motion modifiers: mapper, iterator.
- if (mapper) {
- TODO(clauseLocation, "Mapper modifier is not supported yet");
- } else if (iterator) {
- TODO(clauseLocation, "Iterator modifier is not supported yet");
- }
-
mlir::omp::ClauseMapFlags mapTypeBits =
std::is_same_v<llvm::remove_cvref_t<decltype(clause)>, omp::clause::To>
? mlir::omp::ClauseMapFlags::to
: mlir::omp::ClauseMapFlags::from;
if (expectation && *expectation == omp::clause::To::Expectation::Present)
mapTypeBits |= mlir::omp::ClauseMapFlags::present;
+
+ // Support motion modifiers: mapper, iterator.
+ std::string mapperIdName = "__implicit_mapper";
+ if (mapper) {
+ // Only one mapper is allowed by the parser here.
+ assert(mapper->size() == 1 && "more than one mapper");
+ const semantics::Symbol *mapperSym = mapper->front().v.id().symbol;
+ mapperIdName = mapperSym->name().ToString();
+ if (mapperIdName != "default") {
+ // Mangle with the ultimate owner so that use-associated mapper
+ // identifiers resolve to the same symbol as their defining scope.
+ const semantics::Symbol &ultimate = mapperSym->GetUltimate();
+ mapperIdName = converter.mangleName(mapperIdName, ultimate.owner());
+ }
+ }
+ if (iterator) {
+ TODO(clauseLocation, "Iterator modifier is not supported yet");
+ }
+
processMapObjects(stmtCtx, clauseLocation, objects, mapTypeBits,
- parentMemberIndices, result.mapVars, mapSymbols);
+ parentMemberIndices, result.mapVars, mapSymbols,
+ mapperIdName);
};
bool clauseFound = findRepeatableClause<omp::clause::To>(callbackFn);
diff --git a/flang/test/Lower/OpenMP/target-update-mapper.f90 b/flang/test/Lower/OpenMP/target-update-mapper.f90
index d49ad51343679..df23ea79c08f2 100644
--- a/flang/test/Lower/OpenMP/target-update-mapper.f90
+++ b/flang/test/Lower/OpenMP/target-update-mapper.f90
@@ -24,9 +24,8 @@ program target_update_mapper
!$omp target enter data map(alloc: t)
! Test target update to with custom mapper
- ! CHECK: %[[T_VAR:.*]] = fir.declare %{{.*}} {uniq_name = "_QFtarget_update_mapperEt"} : (!fir.ref<!fir.type<_QFTtyp{a:!fir.box<!fir.heap<!fir.array<?xi32>>>,b:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>) -> !fir.ref<!fir.type<_QFTtyp{a:!fir.box<!fir.heap<!fir.array<?xi32>>>,b:!fir.box<!fir.heap<!fir.array<?xi32>>>}>>
- ! CHECK: %[[MAP_INFO:.*]] = omp.map.info var_ptr(%[[T_VAR]] : {{.*}}, {{.*}}) map_clauses(to) capture(ByRef) mapper(@_QQFcustom) -> {{.*}}
- ! CHECK: omp.target_update motion_entries(%[[MAP_INFO]] : {{.*}})
+ ! CHECK: %[[MAP_INFO:.*]] = omp.map.info var_ptr(%{{.*}} : {{.*}}, {{.*}}) map_clauses(to) capture(ByRef) mapper(@_QQFcustom) -> {{.*}}
+ ! CHECK: omp.target_update map_entries(%[[MAP_INFO]] : {{.*}})
t%a = 42
!$omp target update to(mapper(custom): t)
@@ -37,12 +36,12 @@ program target_update_mapper
! Test target update from with custom mapper
! CHECK: %[[MAP_INFO2:.*]] = omp.map.info var_ptr(%{{.*}} : {{.*}}, {{.*}}) map_clauses(from) capture(ByRef) mapper(@_QQFcustom) -> {{.*}}
- ! CHECK: omp.target_update motion_entries(%[[MAP_INFO2]] : {{.*}})
+ ! CHECK: omp.target_update map_entries(%[[MAP_INFO2]] : {{.*}})
!$omp target update from(mapper(custom): t)
! Test target update to with default mapper
! CHECK: %[[MAP_INFO3:.*]] = omp.map.info var_ptr(%{{.*}} : {{.*}}, {{.*}}) map_clauses(to) capture(ByRef) mapper(@_QQFtyp_omp_default_mapper) -> {{.*}}
- ! CHECK: omp.target_update motion_entries(%[[MAP_INFO3]] : {{.*}})
+ ! CHECK: omp.target_update map_entries(%[[MAP_INFO3]] : {{.*}})
!$omp target update to(mapper(default): t)
!$omp target exit data map(delete: t)
>From 80569fbb398fab4dfc21854a499395dafc4dd8e4 Mon Sep 17 00:00:00 2001
From: Krish Gupta <krishgupta at Krishs-MacBook-Air.local>
Date: Fri, 28 Nov 2025 00:32:22 +0530
Subject: [PATCH 03/11] [flang][OpenMP] Refactor mapper resolution per review
Extract ResolveMapperModifier helper and simplify tests
---
flang/lib/Semantics/resolve-names.cpp | 94 ++++++-------------
flang/test/Lower/OpenMP/declare-mapper.f90 | 34 +++++++
.../Lower/OpenMP/target-update-mapper.f90 | 51 ----------
.../Semantics/OpenMP/target-update-mapper.f90 | 36 ++-----
4 files changed, 67 insertions(+), 148 deletions(-)
delete mode 100644 flang/test/Lower/OpenMP/target-update-mapper.f90
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index 0aa3134d37838..63da425dfe840 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -1782,6 +1782,7 @@ class OmpVisitor : public virtual DeclarationVisitor {
}
private:
+ void ResolveMapperModifier(parser::OmpMapper &mapper);
void ProcessMapperSpecifier(const parser::OmpMapperSpecifier &spec,
const parser::OmpClauseList &clauses);
void ProcessReductionSpecifier(const parser::OmpReductionSpecifier &spec,
@@ -1853,90 +1854,49 @@ void OmpVisitor::Post(const parser::OmpStylizedInstance &x) { //
bool OmpVisitor::Pre(const parser::OmpMapClause &x) {
auto &mods{OmpGetModifiers(x)};
if (auto *mapper{OmpGetUniqueModifier<parser::OmpMapper>(mods)}) {
- if (auto *symbol{FindSymbol(currScope(), mapper->v)}) {
- // TODO: Do we need a specific flag or type here, to distinghuish against
- // other ConstructName things? Leaving this for the full implementation
- // of mapper lowering.
- auto &ultimate{symbol->GetUltimate()};
- auto *misc{ultimate.detailsIf<MiscDetails>()};
- auto *md{ultimate.detailsIf<MapperDetails>()};
- if (!md && (!misc || misc->kind() != MiscDetails::Kind::ConstructName))
- context().Say(mapper->v.source,
- "Name '%s' should be a mapper name"_err_en_US, mapper->v.source);
- else
- mapper->v.symbol = symbol;
- } else {
- // Allow the special 'default' mapper identifier without prior
- // declaration so lowering can recognize and handle it. Emit an
- // error for any other missing mapper identifier.
- if (mapper->v.source.ToString() == "default") {
- mapper->v.symbol = &MakeSymbol(
- mapper->v, MiscDetails{MiscDetails::Kind::ConstructName});
- } else {
- context().Say(
- mapper->v.source, "'%s' not declared"_err_en_US, mapper->v.source);
- }
- }
+ ResolveMapperModifier(const_cast<parser::OmpMapper &>(*mapper));
}
return true;
}
bool OmpVisitor::Pre(const parser::OmpClause::To &x) {
- // Resolve mapper names in "to" clauses (e.g., for target update)
auto &mods{OmpGetModifiers(x.v)};
if (auto *mapper{OmpGetUniqueModifier<parser::OmpMapper>(mods)}) {
- if (auto *symbol{FindSymbol(currScope(), mapper->v)}) {
- auto &ultimate{symbol->GetUltimate()};
- auto *misc{ultimate.detailsIf<MiscDetails>()};
- auto *md{ultimate.detailsIf<MapperDetails>()};
- if (!md && (!misc || misc->kind() != MiscDetails::Kind::ConstructName))
- context().Say(mapper->v.source,
- "Name '%s' should be a mapper name"_err_en_US, mapper->v.source);
- else
- mapper->v.symbol = symbol;
- } else {
- // Allow the special 'default' mapper identifier without prior
- // declaration so lowering can recognize and handle it. Emit an
- // error for any other missing mapper identifier.
- if (mapper->v.source.ToString() == "default") {
- mapper->v.symbol = &MakeSymbol(
- mapper->v, MiscDetails{MiscDetails::Kind::ConstructName});
- } else {
- context().Say(
- mapper->v.source, "'%s' not declared"_err_en_US, mapper->v.source);
- }
- }
+ ResolveMapperModifier(const_cast<parser::OmpMapper &>(*mapper));
}
return true;
}
bool OmpVisitor::Pre(const parser::OmpClause::From &x) {
- // Resolve mapper names in "from" clauses (e.g., for target update)
auto &mods{OmpGetModifiers(x.v)};
if (auto *mapper{OmpGetUniqueModifier<parser::OmpMapper>(mods)}) {
- if (auto *symbol{FindSymbol(currScope(), mapper->v)}) {
- auto &ultimate{symbol->GetUltimate()};
- auto *misc{ultimate.detailsIf<MiscDetails>()};
- auto *md{ultimate.detailsIf<MapperDetails>()};
- if (!md && (!misc || misc->kind() != MiscDetails::Kind::ConstructName))
- context().Say(mapper->v.source,
- "Name '%s' should be a mapper name"_err_en_US, mapper->v.source);
- else
- mapper->v.symbol = symbol;
+ ResolveMapperModifier(const_cast<parser::OmpMapper &>(*mapper));
+ }
+ return true;
+}
+
+void OmpVisitor::ResolveMapperModifier(parser::OmpMapper &mapper) {
+ if (auto *symbol{FindSymbol(currScope(), mapper.v)}) {
+ auto &ultimate{symbol->GetUltimate()};
+ auto *misc{ultimate.detailsIf<MiscDetails>()};
+ auto *md{ultimate.detailsIf<MapperDetails>()};
+ if (!md && (!misc || misc->kind() != MiscDetails::Kind::ConstructName))
+ context().Say(mapper.v.source,
+ "Name '%s' should be a mapper name"_err_en_US, mapper.v.source);
+ else
+ mapper.v.symbol = symbol;
+ } else {
+ // Allow the special 'default' mapper identifier without prior
+ // declaration so lowering can recognize and handle it. Emit an
+ // error for any other missing mapper identifier.
+ if (mapper.v.source.ToString() == "default") {
+ mapper.v.symbol = &MakeSymbol(
+ mapper.v, MiscDetails{MiscDetails::Kind::ConstructName});
} else {
- // Allow the special 'default' mapper identifier without prior
- // declaration so lowering can recognize and handle it. Emit an
- // error for any other missing mapper identifier.
- if (mapper->v.source.ToString() == "default") {
- mapper->v.symbol = &MakeSymbol(
- mapper->v, MiscDetails{MiscDetails::Kind::ConstructName});
- } else {
- context().Say(
- mapper->v.source, "'%s' not declared"_err_en_US, mapper->v.source);
- }
+ context().Say(
+ mapper.v.source, "'%s' not declared"_err_en_US, mapper.v.source);
}
}
- return true;
}
void OmpVisitor::ProcessMapperSpecifier(const parser::OmpMapperSpecifier &spec,
diff --git a/flang/test/Lower/OpenMP/declare-mapper.f90 b/flang/test/Lower/OpenMP/declare-mapper.f90
index 7eda1a4c497be..a2f228811e8f9 100644
--- a/flang/test/Lower/OpenMP/declare-mapper.f90
+++ b/flang/test/Lower/OpenMP/declare-mapper.f90
@@ -11,6 +11,7 @@
! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=50 -J %t %t/omp-declare-mapper-7.use.f90 -o - | FileCheck %t/omp-declare-mapper-7.use.f90
! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=50 -module-dir %t %t/omp-declare-mapper-8.mod.f90 -o - >/dev/null
! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=50 -J %t %t/omp-declare-mapper-8.use.f90 -o - | FileCheck %t/omp-declare-mapper-8.use.f90
+! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=52 %t/omp-declare-mapper-9.f90 -o - | FileCheck %t/omp-declare-mapper-9.f90
!--- omp-declare-mapper-1.f90
subroutine declare_mapper_1
@@ -360,3 +361,36 @@ program use_module_default_mapper
a%x = 8
!$omp end target
end program use_module_default_mapper
+
+!--- omp-declare-mapper-9.f90
+! Test mapper usage in target update to/from clauses
+program target_update_mapper
+ type :: typ
+ integer :: a
+ integer :: b
+ end type typ
+
+ !CHECK: omp.declare_mapper @_QQFtarget_update_mapperFtyp_omp_default_mapper : !fir.type<_QFtarget_update_mapperTtyp{a:i32,b:i32}>
+ !CHECK: omp.declare_mapper @_QQFtarget_update_mapperFcustom : !fir.type<_QFtarget_update_mapperTtyp{a:i32,b:i32}>
+
+ !$omp declare mapper(typ :: t) map(t%a, t%b)
+ !$omp declare mapper(custom: typ :: t) map(t%a)
+
+ type(typ) :: t
+
+ ! Test target update to with custom mapper
+ !CHECK: %[[MAP_INFO:.*]] = omp.map.info var_ptr(%{{.*}} : {{.*}}, {{.*}}) map_clauses(to) capture(ByRef) mapper(@_QQFtarget_update_mapperFcustom) -> {{.*}}
+ !CHECK: omp.target_update map_entries(%[[MAP_INFO]] : {{.*}})
+ !$omp target update to(mapper(custom): t)
+
+ ! Test target update from with custom mapper
+ !CHECK: %[[MAP_INFO2:.*]] = omp.map.info var_ptr(%{{.*}} : {{.*}}, {{.*}}) map_clauses(from) capture(ByRef) mapper(@_QQFtarget_update_mapperFcustom) -> {{.*}}
+ !CHECK: omp.target_update map_entries(%[[MAP_INFO2]] : {{.*}})
+ !$omp target update from(mapper(custom): t)
+
+ ! Test target update to with default mapper
+ !CHECK: %[[MAP_INFO3:.*]] = omp.map.info var_ptr(%{{.*}} : {{.*}}, {{.*}}) map_clauses(to) capture(ByRef) mapper(@_QQFtarget_update_mapperFtyp_omp_default_mapper) -> {{.*}}
+ !CHECK: omp.target_update map_entries(%[[MAP_INFO3]] : {{.*}})
+ !$omp target update to(mapper(default): t)
+
+end program target_update_mapper
diff --git a/flang/test/Lower/OpenMP/target-update-mapper.f90 b/flang/test/Lower/OpenMP/target-update-mapper.f90
deleted file mode 100644
index df23ea79c08f2..0000000000000
--- a/flang/test/Lower/OpenMP/target-update-mapper.f90
+++ /dev/null
@@ -1,51 +0,0 @@
-! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=52 %s -o - | FileCheck %s
-
-! Test mapper usage in target update to/from clauses
-
-program target_update_mapper
- implicit none
-
- integer, parameter :: n = 4
-
- type :: typ
- integer, allocatable :: a(:)
- integer, allocatable :: b(:)
- end type typ
-
- !$omp declare mapper(custom: typ :: t) map(t%a)
-
- ! CHECK-LABEL: omp.declare_mapper @_QQFcustom : !fir.type<_QFTtyp{a:!fir.box<!fir.heap<!fir.array<?xi32>>>,b:!fir.box<!fir.heap<!fir.array<?xi32>>>}>
-
- type(typ) :: t
-
- allocate(t%a(n), source=1)
- allocate(t%b(n), source=2)
-
- !$omp target enter data map(alloc: t)
-
- ! Test target update to with custom mapper
- ! CHECK: %[[MAP_INFO:.*]] = omp.map.info var_ptr(%{{.*}} : {{.*}}, {{.*}}) map_clauses(to) capture(ByRef) mapper(@_QQFcustom) -> {{.*}}
- ! CHECK: omp.target_update map_entries(%[[MAP_INFO]] : {{.*}})
- t%a = 42
- !$omp target update to(mapper(custom): t)
-
- !$omp target
- t%a(:) = t%a(:) / 2
- t%b(:) = -1
- !$omp end target
-
- ! Test target update from with custom mapper
- ! CHECK: %[[MAP_INFO2:.*]] = omp.map.info var_ptr(%{{.*}} : {{.*}}, {{.*}}) map_clauses(from) capture(ByRef) mapper(@_QQFcustom) -> {{.*}}
- ! CHECK: omp.target_update map_entries(%[[MAP_INFO2]] : {{.*}})
- !$omp target update from(mapper(custom): t)
-
- ! Test target update to with default mapper
- ! CHECK: %[[MAP_INFO3:.*]] = omp.map.info var_ptr(%{{.*}} : {{.*}}, {{.*}}) map_clauses(to) capture(ByRef) mapper(@_QQFtyp_omp_default_mapper) -> {{.*}}
- ! CHECK: omp.target_update map_entries(%[[MAP_INFO3]] : {{.*}})
- !$omp target update to(mapper(default): t)
-
- !$omp target exit data map(delete: t)
- deallocate(t%a)
- deallocate(t%b)
-
-end program target_update_mapper
diff --git a/flang/test/Semantics/OpenMP/target-update-mapper.f90 b/flang/test/Semantics/OpenMP/target-update-mapper.f90
index f03496e155568..f37d288670594 100644
--- a/flang/test/Semantics/OpenMP/target-update-mapper.f90
+++ b/flang/test/Semantics/OpenMP/target-update-mapper.f90
@@ -1,53 +1,29 @@
! RUN: %python %S/../test_errors.py %s %flang -fopenmp -fopenmp-version=52
-! Test mapper usage in target update to/from clauses
+! Test mapper name resolution in target update to/from clauses
program target_update_mapper
- implicit none
-
- integer, parameter :: n = 4
-
type :: typ
- integer, allocatable :: a(:)
- integer, allocatable :: b(:)
+ integer :: a
end type typ
!$omp declare mapper(custom: typ :: t) map(t%a)
type(typ) :: t
integer :: not_a_mapper
- allocate(t%a(n), source=1)
- allocate(t%b(n), source=2)
- !$omp target enter data map(alloc: t)
-
- ! Valid: using custom mapper with target update to
- t%a = 42
+ ! Valid: using custom mapper
!$omp target update to(mapper(custom): t)
-
- !$omp target
- t%a(:) = t%a(:) / 2
- t%b(:) = -1
- !$omp end target
-
- ! Valid: using custom mapper with target update from
!$omp target update from(mapper(custom): t)
- ! Valid: using default mapper explicitly
+ ! Valid: using default mapper
!$omp target update to(mapper(default): t)
- print*, t%a
- print*, t%b
-
- !$omp target exit data map(delete: t)
- deallocate(t%a)
- deallocate(t%b)
-
- ! Test error case: undefined mapper
+ ! Error: undefined mapper
!ERROR: 'undefined_mapper' not declared
!$omp target update to(mapper(undefined_mapper): t)
- ! Test error case: wrong kind of symbol
+ ! Error: wrong kind of symbol
!ERROR: Name 'not_a_mapper' should be a mapper name
!$omp target update from(mapper(not_a_mapper): t)
>From 4408121b8ce233a969bb4b724e5f8326f726f6e9 Mon Sep 17 00:00:00 2001
From: Krish Gupta <krishgupta at Krishs-MacBook-Air.local>
Date: Fri, 28 Nov 2025 00:40:38 +0530
Subject: [PATCH 04/11] [flang] Fix clang-format issues
---
flang/lib/Semantics/resolve-names.cpp | 91 +++++++++++++--------------
1 file changed, 45 insertions(+), 46 deletions(-)
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index 63da425dfe840..5377e93a6ca9d 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -1890,8 +1890,8 @@ void OmpVisitor::ResolveMapperModifier(parser::OmpMapper &mapper) {
// declaration so lowering can recognize and handle it. Emit an
// error for any other missing mapper identifier.
if (mapper.v.source.ToString() == "default") {
- mapper.v.symbol = &MakeSymbol(
- mapper.v, MiscDetails{MiscDetails::Kind::ConstructName});
+ mapper.v.symbol =
+ &MakeSymbol(mapper.v, MiscDetails{MiscDetails::Kind::ConstructName});
} else {
context().Say(
mapper.v.source, "'%s' not declared"_err_en_US, mapper.v.source);
@@ -2407,7 +2407,7 @@ void AttrsVisitor::SetBindNameOn(Symbol &symbol) {
}
symbol.SetBindName(std::move(*label));
if (!oldBindName.empty()) {
- if (const std::string * newBindName{symbol.GetBindName()}) {
+ if (const std::string *newBindName{symbol.GetBindName()}) {
if (oldBindName != *newBindName) {
Say(symbol.name(),
"The entity '%s' has multiple BIND names ('%s' and '%s')"_err_en_US,
@@ -2533,7 +2533,7 @@ void DeclTypeSpecVisitor::Post(const parser::TypeSpec &typeSpec) {
// expression semantics if the DeclTypeSpec is a valid TypeSpec.
// The grammar ensures that it's an intrinsic or derived type spec,
// not TYPE(*) or CLASS(*) or CLASS(T).
- if (const DeclTypeSpec * spec{state_.declTypeSpec}) {
+ if (const DeclTypeSpec *spec{state_.declTypeSpec}) {
switch (spec->category()) {
case DeclTypeSpec::Numeric:
case DeclTypeSpec::Logical:
@@ -2541,7 +2541,7 @@ void DeclTypeSpecVisitor::Post(const parser::TypeSpec &typeSpec) {
typeSpec.declTypeSpec = spec;
break;
case DeclTypeSpec::TypeDerived:
- if (const DerivedTypeSpec * derived{spec->AsDerived()}) {
+ if (const DerivedTypeSpec *derived{spec->AsDerived()}) {
CheckForAbstractType(derived->typeSymbol()); // C703
typeSpec.declTypeSpec = spec;
}
@@ -3132,8 +3132,8 @@ Symbol &ScopeHandler::MakeSymbol(const parser::Name &name, Attrs attrs) {
Symbol &ScopeHandler::MakeHostAssocSymbol(
const parser::Name &name, const Symbol &hostSymbol) {
Symbol &symbol{*NonDerivedTypeScope()
- .try_emplace(name.source, HostAssocDetails{hostSymbol})
- .first->second};
+ .try_emplace(name.source, HostAssocDetails{hostSymbol})
+ .first->second};
name.symbol = &symbol;
symbol.attrs() = hostSymbol.attrs(); // TODO: except PRIVATE, PUBLIC?
// These attributes can be redundantly reapplied without error
@@ -3221,7 +3221,7 @@ void ScopeHandler::ApplyImplicitRules(
if (context().HasError(symbol) || !NeedsType(symbol)) {
return;
}
- if (const DeclTypeSpec * type{GetImplicitType(symbol)}) {
+ if (const DeclTypeSpec *type{GetImplicitType(symbol)}) {
if (!skipImplicitTyping_) {
symbol.set(Symbol::Flag::Implicit);
symbol.SetType(*type);
@@ -3321,7 +3321,7 @@ const DeclTypeSpec *ScopeHandler::GetImplicitType(
const auto *type{implicitRulesMap_->at(scope).GetType(
symbol.name(), respectImplicitNoneType)};
if (type) {
- if (const DerivedTypeSpec * derived{type->AsDerived()}) {
+ if (const DerivedTypeSpec *derived{type->AsDerived()}) {
// Resolve any forward-referenced derived type; a quick no-op else.
auto &instantiatable{*const_cast<DerivedTypeSpec *>(derived)};
instantiatable.Instantiate(currScope());
@@ -4342,7 +4342,7 @@ Scope *ModuleVisitor::FindModule(const parser::Name &name,
if (scope) {
if (DoesScopeContain(scope, currScope())) { // 14.2.2(1)
std::optional<SourceName> submoduleName;
- if (const Scope * container{FindModuleOrSubmoduleContaining(currScope())};
+ if (const Scope *container{FindModuleOrSubmoduleContaining(currScope())};
container && container->IsSubmodule()) {
submoduleName = container->GetName();
}
@@ -4447,7 +4447,7 @@ bool InterfaceVisitor::isAbstract() const {
void InterfaceVisitor::AddSpecificProcs(
const std::list<parser::Name> &names, ProcedureKind kind) {
- if (Symbol * symbol{GetGenericInfo().symbol};
+ if (Symbol *symbol{GetGenericInfo().symbol};
symbol && symbol->has<GenericDetails>()) {
for (const auto &name : names) {
specificsForGenericProcs_.emplace(symbol, std::make_pair(&name, kind));
@@ -4547,7 +4547,7 @@ void GenericHandler::DeclaredPossibleSpecificProc(Symbol &proc) {
}
void InterfaceVisitor::ResolveNewSpecifics() {
- if (Symbol * generic{genericInfo_.top().symbol};
+ if (Symbol *generic{genericInfo_.top().symbol};
generic && generic->has<GenericDetails>()) {
ResolveSpecificsInGeneric(*generic, false);
}
@@ -4633,7 +4633,7 @@ bool SubprogramVisitor::HandleStmtFunction(const parser::StmtFunctionStmt &x) {
name.source);
MakeSymbol(name, Attrs{}, UnknownDetails{});
} else if (auto *entity{ultimate.detailsIf<EntityDetails>()};
- entity && !ultimate.has<ProcEntityDetails>()) {
+ entity && !ultimate.has<ProcEntityDetails>()) {
resultType = entity->type();
ultimate.details() = UnknownDetails{}; // will be replaced below
} else {
@@ -5232,7 +5232,7 @@ Symbol *ScopeHandler::FindSeparateModuleProcedureInterface(
symbol = generic->specific();
}
}
- if (const Symbol * defnIface{FindSeparateModuleSubprogramInterface(symbol)}) {
+ if (const Symbol *defnIface{FindSeparateModuleSubprogramInterface(symbol)}) {
// Error recovery in case of multiple definitions
symbol = const_cast<Symbol *>(defnIface);
}
@@ -5372,8 +5372,8 @@ bool SubprogramVisitor::HandlePreviousCalls(
return generic->specific() &&
HandlePreviousCalls(name, *generic->specific(), subpFlag);
} else if (const auto *proc{symbol.detailsIf<ProcEntityDetails>()}; proc &&
- !proc->isDummy() &&
- !symbol.attrs().HasAny(Attrs{Attr::INTRINSIC, Attr::POINTER})) {
+ !proc->isDummy() &&
+ !symbol.attrs().HasAny(Attrs{Attr::INTRINSIC, Attr::POINTER})) {
// There's a symbol created for previous calls to this subprogram or
// ENTRY's name. We have to replace that symbol in situ to avoid the
// obligation to rewrite symbol pointers in the parse tree.
@@ -5415,7 +5415,7 @@ const Symbol *SubprogramVisitor::CheckExtantProc(
if (prev) {
if (IsDummy(*prev)) {
} else if (auto *entity{prev->detailsIf<EntityDetails>()};
- IsPointer(*prev) && entity && !entity->type()) {
+ IsPointer(*prev) && entity && !entity->type()) {
// POINTER attribute set before interface
} else if (inInterfaceBlock() && currScope() != prev->owner()) {
// Procedures in an INTERFACE block do not resolve to symbols
@@ -5487,7 +5487,7 @@ Symbol *SubprogramVisitor::PushSubprogramScope(const parser::Name &name,
}
set_inheritFromParent(false); // interfaces don't inherit, even if MODULE
}
- if (Symbol * found{FindSymbol(name)};
+ if (Symbol *found{FindSymbol(name)};
found && found->has<HostAssocDetails>()) {
found->set(subpFlag); // PushScope() created symbol
}
@@ -6339,9 +6339,9 @@ void DeclarationVisitor::Post(const parser::VectorTypeSpec &x) {
vectorDerivedType.CookParameters(GetFoldingContext());
}
- if (const DeclTypeSpec *
- extant{ppcBuiltinTypesScope->FindInstantiatedDerivedType(
- vectorDerivedType, DeclTypeSpec::Category::TypeDerived)}) {
+ if (const DeclTypeSpec *extant{
+ ppcBuiltinTypesScope->FindInstantiatedDerivedType(
+ vectorDerivedType, DeclTypeSpec::Category::TypeDerived)}) {
// This derived type and parameter expressions (if any) are already present
// in the __ppc_intrinsics scope.
SetDeclTypeSpec(*extant);
@@ -6362,8 +6362,8 @@ bool DeclarationVisitor::Pre(const parser::DeclarationTypeSpec::Type &) {
}
void DeclarationVisitor::Post(const parser::DeclarationTypeSpec::Type &type) {
- const parser::Name &derivedName{std::get<parser::Name>(type.v.t)};
- if (const Symbol * derivedSymbol{derivedName.symbol}) {
+ const parser::Name &derivedName{std::get<parser::Name>(type.derived.t)};
+ if (const Symbol *derivedSymbol{derivedName.symbol}) {
CheckForAbstractType(*derivedSymbol); // C706
}
}
@@ -6432,8 +6432,8 @@ void DeclarationVisitor::Post(const parser::DerivedTypeSpec &x) {
if (!spec->MightBeParameterized()) {
spec->EvaluateParameters(context());
}
- if (const DeclTypeSpec *
- extant{currScope().FindInstantiatedDerivedType(*spec, category)}) {
+ if (const DeclTypeSpec *extant{
+ currScope().FindInstantiatedDerivedType(*spec, category)}) {
// This derived type and parameter expressions (if any) are already present
// in this scope.
SetDeclTypeSpec(*extant);
@@ -6464,8 +6464,7 @@ void DeclarationVisitor::Post(const parser::DeclarationTypeSpec::Record &rec) {
if (auto spec{ResolveDerivedType(typeName)}) {
spec->CookParameters(GetFoldingContext());
spec->EvaluateParameters(context());
- if (const DeclTypeSpec *
- extant{currScope().FindInstantiatedDerivedType(
+ if (const DeclTypeSpec *extant{currScope().FindInstantiatedDerivedType(
*spec, DeclTypeSpec::TypeDerived)}) {
SetDeclTypeSpec(*extant);
} else {
@@ -7483,7 +7482,7 @@ bool DeclarationVisitor::PassesLocalityChecks(
"Coarray '%s' not allowed in a %s locality-spec"_err_en_US, specName);
return false;
}
- if (const DeclTypeSpec * type{symbol.GetType()}) {
+ if (const DeclTypeSpec *type{symbol.GetType()}) {
if (type->IsPolymorphic() && IsDummy(symbol) && !IsPointer(symbol) &&
!isReduce) { // F'2023 C1130
SayWithDecl(name, symbol,
@@ -7717,7 +7716,7 @@ Symbol *DeclarationVisitor::NoteInterfaceName(const parser::Name &name) {
}
void DeclarationVisitor::CheckExplicitInterface(const parser::Name &name) {
- if (const Symbol * symbol{name.symbol}) {
+ if (const Symbol *symbol{name.symbol}) {
const Symbol &ultimate{symbol->GetUltimate()};
if (!context().HasError(*symbol) && !context().HasError(ultimate) &&
!BypassGeneric(ultimate).HasExplicitInterface()) {
@@ -8183,15 +8182,15 @@ void ConstructVisitor::Post(const parser::SelectTypeStmt &x) {
}
}
} else {
- if (const Symbol *
- whole{UnwrapWholeSymbolDataRef(association.selector.expr)}) {
+ if (const Symbol *whole{
+ UnwrapWholeSymbolDataRef(association.selector.expr)}) {
ConvertToObjectEntity(const_cast<Symbol &>(*whole));
if (!IsVariableName(*whole)) {
Say(association.selector.source, // C901
"Selector is not a variable"_err_en_US);
association = {};
}
- if (const DeclTypeSpec * type{whole->GetType()}) {
+ if (const DeclTypeSpec *type{whole->GetType()}) {
if (!type->IsPolymorphic()) { // C1159
Say(association.selector.source,
"Selector '%s' in SELECT TYPE statement must be "
@@ -8331,8 +8330,8 @@ Symbol *ConstructVisitor::MakeAssocEntity() {
"The associate name '%s' is already used in this associate statement"_err_en_US);
return nullptr;
}
- } else if (const Symbol *
- whole{UnwrapWholeSymbolDataRef(association.selector.expr)}) {
+ } else if (const Symbol *whole{
+ UnwrapWholeSymbolDataRef(association.selector.expr)}) {
symbol = &MakeSymbol(whole->name());
} else {
return nullptr;
@@ -8955,7 +8954,7 @@ bool DeclarationVisitor::CheckForHostAssociatedImplicit(
if (name.symbol) {
ApplyImplicitRules(*name.symbol, true);
}
- if (Scope * host{GetHostProcedure()}; host && !isImplicitNoneType(*host)) {
+ if (Scope *host{GetHostProcedure()}; host && !isImplicitNoneType(*host)) {
Symbol *hostSymbol{nullptr};
if (!name.symbol) {
if (currScope().CanImport(name.source)) {
@@ -9026,7 +9025,7 @@ const parser::Name *DeclarationVisitor::FindComponent(
if (!type) {
return nullptr; // should have already reported error
}
- if (const IntrinsicTypeSpec * intrinsic{type->AsIntrinsic()}) {
+ if (const IntrinsicTypeSpec *intrinsic{type->AsIntrinsic()}) {
auto category{intrinsic->category()};
MiscDetails::Kind miscKind{MiscDetails::Kind::None};
if (component.source == "kind") {
@@ -9048,7 +9047,7 @@ const parser::Name *DeclarationVisitor::FindComponent(
}
} else if (DerivedTypeSpec * derived{type->AsDerived()}) {
derived->Instantiate(currScope()); // in case of forward referenced type
- if (const Scope * scope{derived->scope()}) {
+ if (const Scope *scope{derived->scope()}) {
if (Resolve(component, scope->FindComponent(component.source))) {
if (auto msg{CheckAccessibleSymbol(currScope(), *component.symbol)}) {
context().Say(component.source, *msg);
@@ -9205,8 +9204,8 @@ void DeclarationVisitor::PointerInitialization(
if (evaluate::IsNullProcedurePointer(&*expr)) {
CHECK(!details->init());
details->set_init(nullptr);
- } else if (const Symbol *
- targetSymbol{evaluate::UnwrapWholeSymbolDataRef(*expr)}) {
+ } else if (const Symbol *targetSymbol{
+ evaluate::UnwrapWholeSymbolDataRef(*expr)}) {
CHECK(!details->init());
details->set_init(*targetSymbol);
} else {
@@ -9810,7 +9809,7 @@ void ResolveNamesVisitor::EarlyDummyTypeDeclaration(
for (const auto &ent : entities) {
const auto &objName{std::get<parser::ObjectName>(ent.t)};
Resolve(objName, FindInScope(currScope(), objName));
- if (Symbol * symbol{objName.symbol};
+ if (Symbol *symbol{objName.symbol};
symbol && IsDummy(*symbol) && NeedsType(*symbol)) {
if (!type) {
type = ProcessTypeSpec(declTypeSpec);
@@ -9952,7 +9951,7 @@ void ResolveNamesVisitor::FinishSpecificationPart(
if (auto *proc{symbol.detailsIf<ProcEntityDetails>()}; proc &&
!proc->isDummy() && !IsPointer(symbol) &&
!symbol.attrs().test(Attr::BIND_C)) {
- if (const Symbol * iface{proc->procInterface()};
+ if (const Symbol *iface{proc->procInterface()};
iface && IsBindCProcedure(*iface)) {
SetImplicitAttr(symbol, Attr::BIND_C);
SetBindNameOn(symbol);
@@ -10092,7 +10091,7 @@ bool ResolveNamesVisitor::Pre(const parser::PointerAssignmentStmt &x) {
Symbol *ptrSymbol{parser::GetLastName(dataRef).symbol};
Walk(bounds);
// Resolve unrestricted specific intrinsic procedures as in "p => cos".
- if (const parser::Name * name{parser::Unwrap<parser::Name>(expr)}) {
+ if (const parser::Name *name{parser::Unwrap<parser::Name>(expr)}) {
if (NameIsKnownOrIntrinsic(*name)) {
if (Symbol * symbol{name->symbol}) {
if (IsProcedurePointer(ptrSymbol) &&
@@ -10553,8 +10552,8 @@ void ResolveNamesVisitor::ResolveSpecificationParts(ProgramTree &node) {
// implied SAVE so that evaluate::IsSaved() will return true.
if (node.scope()->kind() == Scope::Kind::MainProgram) {
if (const auto *object{symbol.detailsIf<ObjectEntityDetails>()}) {
- if (const DeclTypeSpec * type{object->type()}) {
- if (const DerivedTypeSpec * derived{type->AsDerived()}) {
+ if (const DeclTypeSpec *type{object->type()}) {
+ if (const DerivedTypeSpec *derived{type->AsDerived()}) {
if (!IsSaved(symbol) && FindCoarrayPotentialComponent(*derived)) {
SetImplicitAttr(symbol, Attr::SAVE);
}
@@ -10814,7 +10813,7 @@ void ResolveNamesVisitor::FinishDerivedTypeInstantiation(Scope &scope) {
if (DerivedTypeSpec * spec{scope.derivedTypeSpec()}) {
spec->Instantiate(currScope());
const Symbol &origTypeSymbol{spec->typeSymbol()};
- if (const Scope * origTypeScope{origTypeSymbol.scope()}) {
+ if (const Scope *origTypeScope{origTypeSymbol.scope()}) {
CHECK(origTypeScope->IsDerivedType() &&
origTypeScope->symbol() == &origTypeSymbol);
auto &foldingContext{GetFoldingContext()};
@@ -10825,7 +10824,7 @@ void ResolveNamesVisitor::FinishDerivedTypeInstantiation(Scope &scope) {
if (IsPointer(comp)) {
if (auto *details{comp.detailsIf<ObjectEntityDetails>()}) {
auto origDetails{origComp.get<ObjectEntityDetails>()};
- if (const MaybeExpr & init{origDetails.init()}) {
+ if (const MaybeExpr &init{origDetails.init()}) {
SomeExpr newInit{*init};
MaybeExpr folded{FoldExpr(std::move(newInit))};
details->set_init(std::move(folded));
>From 68557d83c1b28535bc9ea9425094d1884a1daae1 Mon Sep 17 00:00:00 2001
From: Krish Gupta <krishgupta at Krishs-MacBook-Air.local>
Date: Fri, 28 Nov 2025 01:06:13 +0530
Subject: [PATCH 05/11] [flang] Fix test expectations for program-scoped mapper
names
---
flang/test/Lower/OpenMP/declare-mapper.f90 | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/flang/test/Lower/OpenMP/declare-mapper.f90 b/flang/test/Lower/OpenMP/declare-mapper.f90
index a2f228811e8f9..18de556e2ce7d 100644
--- a/flang/test/Lower/OpenMP/declare-mapper.f90
+++ b/flang/test/Lower/OpenMP/declare-mapper.f90
@@ -370,8 +370,8 @@ program target_update_mapper
integer :: b
end type typ
- !CHECK: omp.declare_mapper @_QQFtarget_update_mapperFtyp_omp_default_mapper : !fir.type<_QFtarget_update_mapperTtyp{a:i32,b:i32}>
- !CHECK: omp.declare_mapper @_QQFtarget_update_mapperFcustom : !fir.type<_QFtarget_update_mapperTtyp{a:i32,b:i32}>
+ !CHECK: omp.declare_mapper @_QQFcustom : !fir.type<_QFTtyp{a:i32,b:i32}>
+ !CHECK: omp.declare_mapper @_QQFtyp_omp_default_mapper : !fir.type<_QFTtyp{a:i32,b:i32}>
!$omp declare mapper(typ :: t) map(t%a, t%b)
!$omp declare mapper(custom: typ :: t) map(t%a)
@@ -379,17 +379,17 @@ program target_update_mapper
type(typ) :: t
! Test target update to with custom mapper
- !CHECK: %[[MAP_INFO:.*]] = omp.map.info var_ptr(%{{.*}} : {{.*}}, {{.*}}) map_clauses(to) capture(ByRef) mapper(@_QQFtarget_update_mapperFcustom) -> {{.*}}
+ !CHECK: %[[MAP_INFO:.*]] = omp.map.info var_ptr(%{{.*}} : {{.*}}, {{.*}}) map_clauses(to) capture(ByRef) mapper(@_QQFcustom) -> {{.*}}
!CHECK: omp.target_update map_entries(%[[MAP_INFO]] : {{.*}})
!$omp target update to(mapper(custom): t)
! Test target update from with custom mapper
- !CHECK: %[[MAP_INFO2:.*]] = omp.map.info var_ptr(%{{.*}} : {{.*}}, {{.*}}) map_clauses(from) capture(ByRef) mapper(@_QQFtarget_update_mapperFcustom) -> {{.*}}
+ !CHECK: %[[MAP_INFO2:.*]] = omp.map.info var_ptr(%{{.*}} : {{.*}}, {{.*}}) map_clauses(from) capture(ByRef) mapper(@_QQFcustom) -> {{.*}}
!CHECK: omp.target_update map_entries(%[[MAP_INFO2]] : {{.*}})
!$omp target update from(mapper(custom): t)
! Test target update to with default mapper
- !CHECK: %[[MAP_INFO3:.*]] = omp.map.info var_ptr(%{{.*}} : {{.*}}, {{.*}}) map_clauses(to) capture(ByRef) mapper(@_QQFtarget_update_mapperFtyp_omp_default_mapper) -> {{.*}}
+ !CHECK: %[[MAP_INFO3:.*]] = omp.map.info var_ptr(%{{.*}} : {{.*}}, {{.*}}) map_clauses(to) capture(ByRef) mapper(@_QQFtyp_omp_default_mapper) -> {{.*}}
!CHECK: omp.target_update map_entries(%[[MAP_INFO3]] : {{.*}})
!$omp target update to(mapper(default): t)
>From b5b04a0540c077e76d0d38b3ab39c9ec9378bd80 Mon Sep 17 00:00:00 2001
From: Krish Gupta <krishgupta at Krishs-MacBook-Air.local>
Date: Thu, 4 Dec 2025 23:45:07 +0530
Subject: [PATCH 06/11] [flang] Extract mapper resolution into helper function
---
flang/lib/Lower/OpenMP/ClauseProcessor.cpp | 61 +++++++++++++---------
1 file changed, 37 insertions(+), 24 deletions(-)
diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
index 6cc38e907a45c..087e68febe476 100644
--- a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
+++ b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
@@ -1443,6 +1443,41 @@ void ClauseProcessor::processMapObjects(
}
}
+/// Extract and mangle the mapper identifier name from a mapper clause.
+/// Returns "__implicit_mapper" if no mapper is specified, or "default" if
+/// the default mapper is specified, otherwise returns the mangled mapper name.
+/// This handles both the Map clause (which uses a vector of mappers) and
+/// To/From clauses (which use a DefinedOperator).
+template <typename MapperType>
+static std::string
+getMapperIdentifier(lower::AbstractConverter &converter,
+ const std::optional<MapperType> &mapper) {
+ std::string mapperIdName = "__implicit_mapper";
+ if (mapper) {
+ const semantics::Symbol *mapperSym = nullptr;
+
+ // Handle different mapper types
+ if constexpr (std::is_same_v<MapperType, omp::clause::DefinedOperator>) {
+ // For To/From clauses: mapper is a DefinedOperator
+ assert(mapper->size() == 1 && "more than one mapper");
+ mapperSym = mapper->front().v.id().symbol;
+ } else {
+ // For Map clause: mappers is a vector
+ assert(mapper->size() == 1 && "more than one mapper");
+ mapperSym = mapper->front().v.id().symbol;
+ }
+
+ mapperIdName = mapperSym->name().ToString();
+ if (mapperIdName != "default") {
+ // Mangle with the ultimate owner so that use-associated mapper
+ // identifiers resolve to the same symbol as their defining scope.
+ const semantics::Symbol &ultimate = mapperSym->GetUltimate();
+ mapperIdName = converter.mangleName(mapperIdName, ultimate.owner());
+ }
+ }
+ return mapperIdName;
+}
+
bool ClauseProcessor::processMap(
mlir::Location currentLocation, lower::StatementContext &stmtCtx,
mlir::omp::MapClauseOps &result, llvm::omp::Directive directive,
@@ -1511,17 +1546,7 @@ bool ClauseProcessor::processMap(
TODO(currentLocation,
"Support for iterator modifiers is not implemented yet");
}
- if (mappers) {
- assert(mappers->size() == 1 && "more than one mapper");
- const semantics::Symbol *mapperSym = mappers->front().v.id().symbol;
- mapperIdName = mapperSym->name().ToString();
- if (mapperIdName != "default") {
- // Mangle with the ultimate owner so that use-associated mapper
- // identifiers resolve to the same symbol as their defining scope.
- const semantics::Symbol &ultimate = mapperSym->GetUltimate();
- mapperIdName = converter.mangleName(mapperIdName, ultimate.owner());
- }
- }
+ mapperIdName = getMapperIdentifier(converter, mappers);
processMapObjects(stmtCtx, clauseLocation,
std::get<omp::ObjectList>(clause.t), mapTypeBits,
@@ -1553,19 +1578,7 @@ bool ClauseProcessor::processMotionClauses(lower::StatementContext &stmtCtx,
mapTypeBits |= mlir::omp::ClauseMapFlags::present;
// Support motion modifiers: mapper, iterator.
- std::string mapperIdName = "__implicit_mapper";
- if (mapper) {
- // Only one mapper is allowed by the parser here.
- assert(mapper->size() == 1 && "more than one mapper");
- const semantics::Symbol *mapperSym = mapper->front().v.id().symbol;
- mapperIdName = mapperSym->name().ToString();
- if (mapperIdName != "default") {
- // Mangle with the ultimate owner so that use-associated mapper
- // identifiers resolve to the same symbol as their defining scope.
- const semantics::Symbol &ultimate = mapperSym->GetUltimate();
- mapperIdName = converter.mangleName(mapperIdName, ultimate.owner());
- }
- }
+ std::string mapperIdName = getMapperIdentifier(converter, mapper);
if (iterator) {
TODO(clauseLocation, "Iterator modifier is not supported yet");
}
>From 6cc832128f997f0ccd0c83bbf589b12d4ced0326 Mon Sep 17 00:00:00 2001
From: KrxGu <krishom70 at gmail.com>
Date: Thu, 15 Jan 2026 21:21:08 +0530
Subject: [PATCH 07/11] Refactor mapper code based on review feedback
- Use early return in getMapperIdentifier to reduce nesting
- Remove redundant if constexpr with identical branches
- Make ResolveMapperModifier parameter const
- Remove unnecessary const_cast at call sites
---
flang/lib/Lower/OpenMP/ClauseProcessor.cpp | 35 ++++++++--------------
flang/lib/Semantics/resolve-names.cpp | 14 ++++-----
2 files changed, 20 insertions(+), 29 deletions(-)
diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
index 087e68febe476..fc5f9fd2badd9 100644
--- a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
+++ b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp
@@ -1452,28 +1452,19 @@ template <typename MapperType>
static std::string
getMapperIdentifier(lower::AbstractConverter &converter,
const std::optional<MapperType> &mapper) {
- std::string mapperIdName = "__implicit_mapper";
- if (mapper) {
- const semantics::Symbol *mapperSym = nullptr;
-
- // Handle different mapper types
- if constexpr (std::is_same_v<MapperType, omp::clause::DefinedOperator>) {
- // For To/From clauses: mapper is a DefinedOperator
- assert(mapper->size() == 1 && "more than one mapper");
- mapperSym = mapper->front().v.id().symbol;
- } else {
- // For Map clause: mappers is a vector
- assert(mapper->size() == 1 && "more than one mapper");
- mapperSym = mapper->front().v.id().symbol;
- }
-
- mapperIdName = mapperSym->name().ToString();
- if (mapperIdName != "default") {
- // Mangle with the ultimate owner so that use-associated mapper
- // identifiers resolve to the same symbol as their defining scope.
- const semantics::Symbol &ultimate = mapperSym->GetUltimate();
- mapperIdName = converter.mangleName(mapperIdName, ultimate.owner());
- }
+ if (!mapper)
+ return "__implicit_mapper";
+
+ // Handle mapper types (both have the same structure)
+ assert(mapper->size() == 1 && "more than one mapper");
+ const semantics::Symbol *mapperSym = mapper->front().v.id().symbol;
+
+ std::string mapperIdName = mapperSym->name().ToString();
+ if (mapperIdName != "default") {
+ // Mangle with the ultimate owner so that use-associated mapper
+ // identifiers resolve to the same symbol as their defining scope.
+ const semantics::Symbol &ultimate = mapperSym->GetUltimate();
+ mapperIdName = converter.mangleName(mapperIdName, ultimate.owner());
}
return mapperIdName;
}
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index 5377e93a6ca9d..33d5e5de04f6a 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -1782,7 +1782,7 @@ class OmpVisitor : public virtual DeclarationVisitor {
}
private:
- void ResolveMapperModifier(parser::OmpMapper &mapper);
+ void ResolveMapperModifier(const parser::OmpMapper &mapper);
void ProcessMapperSpecifier(const parser::OmpMapperSpecifier &spec,
const parser::OmpClauseList &clauses);
void ProcessReductionSpecifier(const parser::OmpReductionSpecifier &spec,
@@ -1854,7 +1854,7 @@ void OmpVisitor::Post(const parser::OmpStylizedInstance &x) { //
bool OmpVisitor::Pre(const parser::OmpMapClause &x) {
auto &mods{OmpGetModifiers(x)};
if (auto *mapper{OmpGetUniqueModifier<parser::OmpMapper>(mods)}) {
- ResolveMapperModifier(const_cast<parser::OmpMapper &>(*mapper));
+ ResolveMapperModifier(*mapper);
}
return true;
}
@@ -1862,7 +1862,7 @@ bool OmpVisitor::Pre(const parser::OmpMapClause &x) {
bool OmpVisitor::Pre(const parser::OmpClause::To &x) {
auto &mods{OmpGetModifiers(x.v)};
if (auto *mapper{OmpGetUniqueModifier<parser::OmpMapper>(mods)}) {
- ResolveMapperModifier(const_cast<parser::OmpMapper &>(*mapper));
+ ResolveMapperModifier(*mapper);
}
return true;
}
@@ -1870,12 +1870,12 @@ bool OmpVisitor::Pre(const parser::OmpClause::To &x) {
bool OmpVisitor::Pre(const parser::OmpClause::From &x) {
auto &mods{OmpGetModifiers(x.v)};
if (auto *mapper{OmpGetUniqueModifier<parser::OmpMapper>(mods)}) {
- ResolveMapperModifier(const_cast<parser::OmpMapper &>(*mapper));
+ ResolveMapperModifier(*mapper);
}
return true;
}
-void OmpVisitor::ResolveMapperModifier(parser::OmpMapper &mapper) {
+void OmpVisitor::ResolveMapperModifier(const parser::OmpMapper &mapper) {
if (auto *symbol{FindSymbol(currScope(), mapper.v)}) {
auto &ultimate{symbol->GetUltimate()};
auto *misc{ultimate.detailsIf<MiscDetails>()};
@@ -1884,13 +1884,13 @@ void OmpVisitor::ResolveMapperModifier(parser::OmpMapper &mapper) {
context().Say(mapper.v.source,
"Name '%s' should be a mapper name"_err_en_US, mapper.v.source);
else
- mapper.v.symbol = symbol;
+ const_cast<parser::OmpMapper &>(mapper).v.symbol = symbol;
} else {
// Allow the special 'default' mapper identifier without prior
// declaration so lowering can recognize and handle it. Emit an
// error for any other missing mapper identifier.
if (mapper.v.source.ToString() == "default") {
- mapper.v.symbol =
+ const_cast<parser::OmpMapper &>(mapper).v.symbol =
&MakeSymbol(mapper.v, MiscDetails{MiscDetails::Kind::ConstructName});
} else {
context().Say(
>From 49fba1ac360f396c2574002447c603efea70524b Mon Sep 17 00:00:00 2001
From: KrxGu <krishom70 at gmail.com>
Date: Thu, 15 Jan 2026 21:30:08 +0530
Subject: [PATCH 08/11] Remove unnecessary const_cast for mutable symbol member
The symbol field is already marked mutable in the Name struct,
so it can be modified directly through a const reference.
---
flang/lib/Semantics/resolve-names.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index 33d5e5de04f6a..701d2c269ce77 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -1884,13 +1884,13 @@ void OmpVisitor::ResolveMapperModifier(const parser::OmpMapper &mapper) {
context().Say(mapper.v.source,
"Name '%s' should be a mapper name"_err_en_US, mapper.v.source);
else
- const_cast<parser::OmpMapper &>(mapper).v.symbol = symbol;
+ mapper.v.symbol = symbol;
} else {
// Allow the special 'default' mapper identifier without prior
// declaration so lowering can recognize and handle it. Emit an
// error for any other missing mapper identifier.
if (mapper.v.source.ToString() == "default") {
- const_cast<parser::OmpMapper &>(mapper).v.symbol =
+ mapper.v.symbol =
&MakeSymbol(mapper.v, MiscDetails{MiscDetails::Kind::ConstructName});
} else {
context().Say(
>From 734c56f18bdc2508bce19cd5b6ca87fd5dc94ef8 Mon Sep 17 00:00:00 2001
From: KrxGu <krishom70 at gmail.com>
Date: Fri, 16 Jan 2026 00:11:16 +0530
Subject: [PATCH 09/11] Add offloading test for target update with custom
mappers
Use separate objects (obj1, obj2) for custom and default mapper
tests to avoid device memory mapping conflicts.
---
.../fortran/target-update-custom-mapper.f90 | 85 +++++++++++++++++++
1 file changed, 85 insertions(+)
create mode 100644 offload/test/offloading/fortran/target-update-custom-mapper.f90
diff --git a/offload/test/offloading/fortran/target-update-custom-mapper.f90 b/offload/test/offloading/fortran/target-update-custom-mapper.f90
new file mode 100644
index 0000000000000..e3384c2911d47
--- /dev/null
+++ b/offload/test/offloading/fortran/target-update-custom-mapper.f90
@@ -0,0 +1,85 @@
+! Test custom mappers with target update to/from clauses
+! REQUIRES: flang, amdgpu
+
+! RUN: %libomptarget-compile-fortran-run-and-check-generic
+
+program target_update_mapper_test
+ implicit none
+ integer, parameter :: n = 100
+
+ type :: my_type
+ integer :: a(n)
+ integer :: b(n)
+ end type my_type
+
+ ! Declare custom mapper that only maps field 'a'
+ !$omp declare mapper(custom : my_type :: t) map(t%a)
+
+ ! Declare default mapper that maps both fields
+ !$omp declare mapper(my_type :: t) map(t%a, t%b)
+
+ type(my_type) :: obj1, obj2
+ integer :: i, sum_a, sum_b
+
+ ! ========== Test 1: Custom mapper (field 'a' only) ==========
+
+ ! Initialize data on host
+ do i = 1, n
+ obj1%a(i) = i
+ obj1%b(i) = i * 2
+ end do
+
+ ! Allocate and update using custom mapper (only 'a')
+ !$omp target enter data map(mapper(custom), alloc: obj1)
+
+ obj1%a = 10
+ !$omp target update to(mapper(custom): obj1)
+
+ obj1%a = 0
+ !$omp target update from(mapper(custom): obj1)
+
+ sum_a = sum(obj1%a)
+ sum_b = sum(obj1%b)
+
+ ! CHECK: Sum of a (custom mapper): 1000
+ print *, "Sum of a (custom mapper):", sum_a
+
+ ! Field 'b' was never mapped with custom mapper
+ ! CHECK: Sum of b (never mapped): 10100
+ print *, "Sum of b (never mapped):", sum_b
+
+ !$omp target exit data map(mapper(custom), delete: obj1)
+
+ ! ========== Test 2: Default mapper (both fields) ==========
+
+ ! Initialize separate object for default mapper test
+ do i = 1, n
+ obj2%a(i) = 20
+ obj2%b(i) = 30
+ end do
+
+ ! Allocate and update using default mapper (both 'a' and 'b')
+ !$omp target enter data map(mapper(default), alloc: obj2)
+
+ !$omp target update to(mapper(default): obj2)
+
+ obj2%a = 0
+ obj2%b = 0
+
+ !$omp target update from(mapper(default): obj2)
+
+ sum_a = sum(obj2%a)
+ sum_b = sum(obj2%b)
+
+ ! CHECK: Sum of a (default mapper): 2000
+ print *, "Sum of a (default mapper):", sum_a
+
+ ! CHECK: Sum of b (default mapper): 3000
+ print *, "Sum of b (default mapper):", sum_b
+
+ !$omp target exit data map(mapper(default), delete: obj2)
+
+ ! CHECK: Test passed!
+ print *, "Test passed!"
+
+end program target_update_mapper_test
>From 3743961a3f1b633188d281cff09600d764285a17 Mon Sep 17 00:00:00 2001
From: KrxGu <krishom70 at gmail.com>
Date: Fri, 16 Jan 2026 01:23:44 +0530
Subject: [PATCH 10/11] Fix parser API usage: type.derived.t -> type.v.t
DeclarationTypeSpec::Type is a WRAPPER_CLASS with member 'v',
not 'derived'. Corrects build failure on CI.
---
flang/lib/Semantics/resolve-names.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index 701d2c269ce77..aaa34cfc944e4 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -6362,7 +6362,7 @@ bool DeclarationVisitor::Pre(const parser::DeclarationTypeSpec::Type &) {
}
void DeclarationVisitor::Post(const parser::DeclarationTypeSpec::Type &type) {
- const parser::Name &derivedName{std::get<parser::Name>(type.derived.t)};
+ const parser::Name &derivedName{std::get<parser::Name>(type.v.t)};
if (const Symbol *derivedSymbol{derivedName.symbol}) {
CheckForAbstractType(*derivedSymbol); // C706
}
>From 84020e0aa732d6ab55b8ef0a8e40bfbfe287cc30 Mon Sep 17 00:00:00 2001
From: KrxGu <krishom70 at gmail.com>
Date: Fri, 16 Jan 2026 21:16:02 +0530
Subject: [PATCH 11/11] Remove unrelated formatting changes from rebase
Per review feedback, removed all pointer-style and indentation
changes that were picked up during rebase. Kept only functional
changes for mapper support in target update.
---
flang/lib/Semantics/resolve-names.cpp | 85 ++++++++++++++-------------
1 file changed, 43 insertions(+), 42 deletions(-)
diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp
index aaa34cfc944e4..9966aedca9925 100644
--- a/flang/lib/Semantics/resolve-names.cpp
+++ b/flang/lib/Semantics/resolve-names.cpp
@@ -2407,7 +2407,7 @@ void AttrsVisitor::SetBindNameOn(Symbol &symbol) {
}
symbol.SetBindName(std::move(*label));
if (!oldBindName.empty()) {
- if (const std::string *newBindName{symbol.GetBindName()}) {
+ if (const std::string * newBindName{symbol.GetBindName()}) {
if (oldBindName != *newBindName) {
Say(symbol.name(),
"The entity '%s' has multiple BIND names ('%s' and '%s')"_err_en_US,
@@ -2533,7 +2533,7 @@ void DeclTypeSpecVisitor::Post(const parser::TypeSpec &typeSpec) {
// expression semantics if the DeclTypeSpec is a valid TypeSpec.
// The grammar ensures that it's an intrinsic or derived type spec,
// not TYPE(*) or CLASS(*) or CLASS(T).
- if (const DeclTypeSpec *spec{state_.declTypeSpec}) {
+ if (const DeclTypeSpec * spec{state_.declTypeSpec}) {
switch (spec->category()) {
case DeclTypeSpec::Numeric:
case DeclTypeSpec::Logical:
@@ -2541,7 +2541,7 @@ void DeclTypeSpecVisitor::Post(const parser::TypeSpec &typeSpec) {
typeSpec.declTypeSpec = spec;
break;
case DeclTypeSpec::TypeDerived:
- if (const DerivedTypeSpec *derived{spec->AsDerived()}) {
+ if (const DerivedTypeSpec * derived{spec->AsDerived()}) {
CheckForAbstractType(derived->typeSymbol()); // C703
typeSpec.declTypeSpec = spec;
}
@@ -3132,8 +3132,8 @@ Symbol &ScopeHandler::MakeSymbol(const parser::Name &name, Attrs attrs) {
Symbol &ScopeHandler::MakeHostAssocSymbol(
const parser::Name &name, const Symbol &hostSymbol) {
Symbol &symbol{*NonDerivedTypeScope()
- .try_emplace(name.source, HostAssocDetails{hostSymbol})
- .first->second};
+ .try_emplace(name.source, HostAssocDetails{hostSymbol})
+ .first->second};
name.symbol = &symbol;
symbol.attrs() = hostSymbol.attrs(); // TODO: except PRIVATE, PUBLIC?
// These attributes can be redundantly reapplied without error
@@ -3221,7 +3221,7 @@ void ScopeHandler::ApplyImplicitRules(
if (context().HasError(symbol) || !NeedsType(symbol)) {
return;
}
- if (const DeclTypeSpec *type{GetImplicitType(symbol)}) {
+ if (const DeclTypeSpec * type{GetImplicitType(symbol)}) {
if (!skipImplicitTyping_) {
symbol.set(Symbol::Flag::Implicit);
symbol.SetType(*type);
@@ -3321,7 +3321,7 @@ const DeclTypeSpec *ScopeHandler::GetImplicitType(
const auto *type{implicitRulesMap_->at(scope).GetType(
symbol.name(), respectImplicitNoneType)};
if (type) {
- if (const DerivedTypeSpec *derived{type->AsDerived()}) {
+ if (const DerivedTypeSpec * derived{type->AsDerived()}) {
// Resolve any forward-referenced derived type; a quick no-op else.
auto &instantiatable{*const_cast<DerivedTypeSpec *>(derived)};
instantiatable.Instantiate(currScope());
@@ -4342,7 +4342,7 @@ Scope *ModuleVisitor::FindModule(const parser::Name &name,
if (scope) {
if (DoesScopeContain(scope, currScope())) { // 14.2.2(1)
std::optional<SourceName> submoduleName;
- if (const Scope *container{FindModuleOrSubmoduleContaining(currScope())};
+ if (const Scope * container{FindModuleOrSubmoduleContaining(currScope())};
container && container->IsSubmodule()) {
submoduleName = container->GetName();
}
@@ -4447,7 +4447,7 @@ bool InterfaceVisitor::isAbstract() const {
void InterfaceVisitor::AddSpecificProcs(
const std::list<parser::Name> &names, ProcedureKind kind) {
- if (Symbol *symbol{GetGenericInfo().symbol};
+ if (Symbol * symbol{GetGenericInfo().symbol};
symbol && symbol->has<GenericDetails>()) {
for (const auto &name : names) {
specificsForGenericProcs_.emplace(symbol, std::make_pair(&name, kind));
@@ -4547,7 +4547,7 @@ void GenericHandler::DeclaredPossibleSpecificProc(Symbol &proc) {
}
void InterfaceVisitor::ResolveNewSpecifics() {
- if (Symbol *generic{genericInfo_.top().symbol};
+ if (Symbol * generic{genericInfo_.top().symbol};
generic && generic->has<GenericDetails>()) {
ResolveSpecificsInGeneric(*generic, false);
}
@@ -4633,7 +4633,7 @@ bool SubprogramVisitor::HandleStmtFunction(const parser::StmtFunctionStmt &x) {
name.source);
MakeSymbol(name, Attrs{}, UnknownDetails{});
} else if (auto *entity{ultimate.detailsIf<EntityDetails>()};
- entity && !ultimate.has<ProcEntityDetails>()) {
+ entity && !ultimate.has<ProcEntityDetails>()) {
resultType = entity->type();
ultimate.details() = UnknownDetails{}; // will be replaced below
} else {
@@ -5232,7 +5232,7 @@ Symbol *ScopeHandler::FindSeparateModuleProcedureInterface(
symbol = generic->specific();
}
}
- if (const Symbol *defnIface{FindSeparateModuleSubprogramInterface(symbol)}) {
+ if (const Symbol * defnIface{FindSeparateModuleSubprogramInterface(symbol)}) {
// Error recovery in case of multiple definitions
symbol = const_cast<Symbol *>(defnIface);
}
@@ -5372,8 +5372,8 @@ bool SubprogramVisitor::HandlePreviousCalls(
return generic->specific() &&
HandlePreviousCalls(name, *generic->specific(), subpFlag);
} else if (const auto *proc{symbol.detailsIf<ProcEntityDetails>()}; proc &&
- !proc->isDummy() &&
- !symbol.attrs().HasAny(Attrs{Attr::INTRINSIC, Attr::POINTER})) {
+ !proc->isDummy() &&
+ !symbol.attrs().HasAny(Attrs{Attr::INTRINSIC, Attr::POINTER})) {
// There's a symbol created for previous calls to this subprogram or
// ENTRY's name. We have to replace that symbol in situ to avoid the
// obligation to rewrite symbol pointers in the parse tree.
@@ -5415,7 +5415,7 @@ const Symbol *SubprogramVisitor::CheckExtantProc(
if (prev) {
if (IsDummy(*prev)) {
} else if (auto *entity{prev->detailsIf<EntityDetails>()};
- IsPointer(*prev) && entity && !entity->type()) {
+ IsPointer(*prev) && entity && !entity->type()) {
// POINTER attribute set before interface
} else if (inInterfaceBlock() && currScope() != prev->owner()) {
// Procedures in an INTERFACE block do not resolve to symbols
@@ -5487,7 +5487,7 @@ Symbol *SubprogramVisitor::PushSubprogramScope(const parser::Name &name,
}
set_inheritFromParent(false); // interfaces don't inherit, even if MODULE
}
- if (Symbol *found{FindSymbol(name)};
+ if (Symbol * found{FindSymbol(name)};
found && found->has<HostAssocDetails>()) {
found->set(subpFlag); // PushScope() created symbol
}
@@ -6339,9 +6339,9 @@ void DeclarationVisitor::Post(const parser::VectorTypeSpec &x) {
vectorDerivedType.CookParameters(GetFoldingContext());
}
- if (const DeclTypeSpec *extant{
- ppcBuiltinTypesScope->FindInstantiatedDerivedType(
- vectorDerivedType, DeclTypeSpec::Category::TypeDerived)}) {
+ if (const DeclTypeSpec *
+ extant{ppcBuiltinTypesScope->FindInstantiatedDerivedType(
+ vectorDerivedType, DeclTypeSpec::Category::TypeDerived)}) {
// This derived type and parameter expressions (if any) are already present
// in the __ppc_intrinsics scope.
SetDeclTypeSpec(*extant);
@@ -6363,7 +6363,7 @@ bool DeclarationVisitor::Pre(const parser::DeclarationTypeSpec::Type &) {
void DeclarationVisitor::Post(const parser::DeclarationTypeSpec::Type &type) {
const parser::Name &derivedName{std::get<parser::Name>(type.v.t)};
- if (const Symbol *derivedSymbol{derivedName.symbol}) {
+ if (const Symbol * derivedSymbol{derivedName.symbol}) {
CheckForAbstractType(*derivedSymbol); // C706
}
}
@@ -6432,8 +6432,8 @@ void DeclarationVisitor::Post(const parser::DerivedTypeSpec &x) {
if (!spec->MightBeParameterized()) {
spec->EvaluateParameters(context());
}
- if (const DeclTypeSpec *extant{
- currScope().FindInstantiatedDerivedType(*spec, category)}) {
+ if (const DeclTypeSpec *
+ extant{currScope().FindInstantiatedDerivedType(*spec, category)}) {
// This derived type and parameter expressions (if any) are already present
// in this scope.
SetDeclTypeSpec(*extant);
@@ -6464,7 +6464,8 @@ void DeclarationVisitor::Post(const parser::DeclarationTypeSpec::Record &rec) {
if (auto spec{ResolveDerivedType(typeName)}) {
spec->CookParameters(GetFoldingContext());
spec->EvaluateParameters(context());
- if (const DeclTypeSpec *extant{currScope().FindInstantiatedDerivedType(
+ if (const DeclTypeSpec *
+ extant{currScope().FindInstantiatedDerivedType(
*spec, DeclTypeSpec::TypeDerived)}) {
SetDeclTypeSpec(*extant);
} else {
@@ -7482,7 +7483,7 @@ bool DeclarationVisitor::PassesLocalityChecks(
"Coarray '%s' not allowed in a %s locality-spec"_err_en_US, specName);
return false;
}
- if (const DeclTypeSpec *type{symbol.GetType()}) {
+ if (const DeclTypeSpec * type{symbol.GetType()}) {
if (type->IsPolymorphic() && IsDummy(symbol) && !IsPointer(symbol) &&
!isReduce) { // F'2023 C1130
SayWithDecl(name, symbol,
@@ -7716,7 +7717,7 @@ Symbol *DeclarationVisitor::NoteInterfaceName(const parser::Name &name) {
}
void DeclarationVisitor::CheckExplicitInterface(const parser::Name &name) {
- if (const Symbol *symbol{name.symbol}) {
+ if (const Symbol * symbol{name.symbol}) {
const Symbol &ultimate{symbol->GetUltimate()};
if (!context().HasError(*symbol) && !context().HasError(ultimate) &&
!BypassGeneric(ultimate).HasExplicitInterface()) {
@@ -8182,15 +8183,15 @@ void ConstructVisitor::Post(const parser::SelectTypeStmt &x) {
}
}
} else {
- if (const Symbol *whole{
- UnwrapWholeSymbolDataRef(association.selector.expr)}) {
+ if (const Symbol *
+ whole{UnwrapWholeSymbolDataRef(association.selector.expr)}) {
ConvertToObjectEntity(const_cast<Symbol &>(*whole));
if (!IsVariableName(*whole)) {
Say(association.selector.source, // C901
"Selector is not a variable"_err_en_US);
association = {};
}
- if (const DeclTypeSpec *type{whole->GetType()}) {
+ if (const DeclTypeSpec * type{whole->GetType()}) {
if (!type->IsPolymorphic()) { // C1159
Say(association.selector.source,
"Selector '%s' in SELECT TYPE statement must be "
@@ -8330,8 +8331,8 @@ Symbol *ConstructVisitor::MakeAssocEntity() {
"The associate name '%s' is already used in this associate statement"_err_en_US);
return nullptr;
}
- } else if (const Symbol *whole{
- UnwrapWholeSymbolDataRef(association.selector.expr)}) {
+ } else if (const Symbol *
+ whole{UnwrapWholeSymbolDataRef(association.selector.expr)}) {
symbol = &MakeSymbol(whole->name());
} else {
return nullptr;
@@ -8954,7 +8955,7 @@ bool DeclarationVisitor::CheckForHostAssociatedImplicit(
if (name.symbol) {
ApplyImplicitRules(*name.symbol, true);
}
- if (Scope *host{GetHostProcedure()}; host && !isImplicitNoneType(*host)) {
+ if (Scope * host{GetHostProcedure()}; host && !isImplicitNoneType(*host)) {
Symbol *hostSymbol{nullptr};
if (!name.symbol) {
if (currScope().CanImport(name.source)) {
@@ -9025,7 +9026,7 @@ const parser::Name *DeclarationVisitor::FindComponent(
if (!type) {
return nullptr; // should have already reported error
}
- if (const IntrinsicTypeSpec *intrinsic{type->AsIntrinsic()}) {
+ if (const IntrinsicTypeSpec * intrinsic{type->AsIntrinsic()}) {
auto category{intrinsic->category()};
MiscDetails::Kind miscKind{MiscDetails::Kind::None};
if (component.source == "kind") {
@@ -9047,7 +9048,7 @@ const parser::Name *DeclarationVisitor::FindComponent(
}
} else if (DerivedTypeSpec * derived{type->AsDerived()}) {
derived->Instantiate(currScope()); // in case of forward referenced type
- if (const Scope *scope{derived->scope()}) {
+ if (const Scope * scope{derived->scope()}) {
if (Resolve(component, scope->FindComponent(component.source))) {
if (auto msg{CheckAccessibleSymbol(currScope(), *component.symbol)}) {
context().Say(component.source, *msg);
@@ -9204,8 +9205,8 @@ void DeclarationVisitor::PointerInitialization(
if (evaluate::IsNullProcedurePointer(&*expr)) {
CHECK(!details->init());
details->set_init(nullptr);
- } else if (const Symbol *targetSymbol{
- evaluate::UnwrapWholeSymbolDataRef(*expr)}) {
+ } else if (const Symbol *
+ targetSymbol{evaluate::UnwrapWholeSymbolDataRef(*expr)}) {
CHECK(!details->init());
details->set_init(*targetSymbol);
} else {
@@ -9809,7 +9810,7 @@ void ResolveNamesVisitor::EarlyDummyTypeDeclaration(
for (const auto &ent : entities) {
const auto &objName{std::get<parser::ObjectName>(ent.t)};
Resolve(objName, FindInScope(currScope(), objName));
- if (Symbol *symbol{objName.symbol};
+ if (Symbol * symbol{objName.symbol};
symbol && IsDummy(*symbol) && NeedsType(*symbol)) {
if (!type) {
type = ProcessTypeSpec(declTypeSpec);
@@ -9951,7 +9952,7 @@ void ResolveNamesVisitor::FinishSpecificationPart(
if (auto *proc{symbol.detailsIf<ProcEntityDetails>()}; proc &&
!proc->isDummy() && !IsPointer(symbol) &&
!symbol.attrs().test(Attr::BIND_C)) {
- if (const Symbol *iface{proc->procInterface()};
+ if (const Symbol * iface{proc->procInterface()};
iface && IsBindCProcedure(*iface)) {
SetImplicitAttr(symbol, Attr::BIND_C);
SetBindNameOn(symbol);
@@ -10091,7 +10092,7 @@ bool ResolveNamesVisitor::Pre(const parser::PointerAssignmentStmt &x) {
Symbol *ptrSymbol{parser::GetLastName(dataRef).symbol};
Walk(bounds);
// Resolve unrestricted specific intrinsic procedures as in "p => cos".
- if (const parser::Name *name{parser::Unwrap<parser::Name>(expr)}) {
+ if (const parser::Name * name{parser::Unwrap<parser::Name>(expr)}) {
if (NameIsKnownOrIntrinsic(*name)) {
if (Symbol * symbol{name->symbol}) {
if (IsProcedurePointer(ptrSymbol) &&
@@ -10552,8 +10553,8 @@ void ResolveNamesVisitor::ResolveSpecificationParts(ProgramTree &node) {
// implied SAVE so that evaluate::IsSaved() will return true.
if (node.scope()->kind() == Scope::Kind::MainProgram) {
if (const auto *object{symbol.detailsIf<ObjectEntityDetails>()}) {
- if (const DeclTypeSpec *type{object->type()}) {
- if (const DerivedTypeSpec *derived{type->AsDerived()}) {
+ if (const DeclTypeSpec * type{object->type()}) {
+ if (const DerivedTypeSpec * derived{type->AsDerived()}) {
if (!IsSaved(symbol) && FindCoarrayPotentialComponent(*derived)) {
SetImplicitAttr(symbol, Attr::SAVE);
}
@@ -10813,7 +10814,7 @@ void ResolveNamesVisitor::FinishDerivedTypeInstantiation(Scope &scope) {
if (DerivedTypeSpec * spec{scope.derivedTypeSpec()}) {
spec->Instantiate(currScope());
const Symbol &origTypeSymbol{spec->typeSymbol()};
- if (const Scope *origTypeScope{origTypeSymbol.scope()}) {
+ if (const Scope * origTypeScope{origTypeSymbol.scope()}) {
CHECK(origTypeScope->IsDerivedType() &&
origTypeScope->symbol() == &origTypeSymbol);
auto &foldingContext{GetFoldingContext()};
@@ -10824,7 +10825,7 @@ void ResolveNamesVisitor::FinishDerivedTypeInstantiation(Scope &scope) {
if (IsPointer(comp)) {
if (auto *details{comp.detailsIf<ObjectEntityDetails>()}) {
auto origDetails{origComp.get<ObjectEntityDetails>()};
- if (const MaybeExpr &init{origDetails.init()}) {
+ if (const MaybeExpr & init{origDetails.init()}) {
SomeExpr newInit{*init};
MaybeExpr folded{FoldExpr(std::move(newInit))};
details->set_init(std::move(folded));
More information about the llvm-commits
mailing list