Skip to content

[OpenMP][clang] declare mapper: fix handling of nested types #143504

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 14, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion clang/include/clang/Sema/SemaOpenMP.h
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ class SemaOpenMP : public SemaBase {
/// mapper' construct.
QualType ActOnOpenMPDeclareMapperType(SourceLocation TyLoc,
TypeResult ParsedType);
/// Called on start of '#pragma omp declare mapper'.
/// Called for '#pragma omp declare mapper'.
DeclGroupPtrTy ActOnOpenMPDeclareMapperDirective(
Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType,
SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS,
Expand Down
12 changes: 9 additions & 3 deletions clang/lib/Parse/ParseOpenMP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -576,6 +576,7 @@ Parser::ParseOpenMPDeclareMapperDirective(AccessSpecifier AS) {
return DeclGroupPtrTy();
}

Scope *OuterScope = getCurScope();
// Enter scope.
DeclarationNameInfo DirName;
SourceLocation Loc = Tok.getLocation();
Expand Down Expand Up @@ -614,12 +615,17 @@ Parser::ParseOpenMPDeclareMapperDirective(AccessSpecifier AS) {
IsCorrect = false;
}

// This needs to be called within the scope because
// processImplicitMapsWithDefaultMappers may add clauses when analyzing nested
// types. The scope used for calling ActOnOpenMPDeclareMapperDirective,
// however, needs to be the outer one, otherwise declared mappers don't become
// visible.
DeclGroupPtrTy DG = Actions.OpenMP().ActOnOpenMPDeclareMapperDirective(
OuterScope, Actions.getCurLexicalContext(), MapperId, MapperType,
Range.getBegin(), VName, AS, MapperVarRef.get(), Clauses);
// Exit scope.
Actions.OpenMP().EndOpenMPDSABlock(nullptr);
OMPDirectiveScope.Exit();
DeclGroupPtrTy DG = Actions.OpenMP().ActOnOpenMPDeclareMapperDirective(
getCurScope(), Actions.getCurLexicalContext(), MapperId, MapperType,
Range.getBegin(), VName, AS, MapperVarRef.get(), Clauses);
if (!IsCorrect)
return DeclGroupPtrTy();

Expand Down
25 changes: 25 additions & 0 deletions clang/test/OpenMP/declare_mapper_ast_print.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,23 @@ struct dat {
#pragma omp declare mapper(struct dat d) map(to: d.d)
// CHECK: #pragma omp declare mapper (default : struct dat d) map(to: d.d){{$}}

// Verify that nested default mappers do not lead to a crash during parsing / sema.
// CHECK: struct inner {
struct inner {
int size;
int *data;
};
#pragma omp declare mapper(struct inner i) map(i, i.data[0 : i.size])
// CHECK: #pragma omp declare mapper (default : struct inner i) map(tofrom: default::i,i.data[0:i.size]){{$}}

// CHECK: struct outer {
struct outer {
int a;
struct inner i;
};
#pragma omp declare mapper(struct outer o) map(o)
// CHECK: #pragma omp declare mapper (default : struct outer o) map(tofrom: default::o) map(tofrom: o.i){{$}}

// CHECK: int main(void) {
int main(void) {
#pragma omp declare mapper(id: struct vec v) map(v.len)
Expand Down Expand Up @@ -77,6 +94,14 @@ int main(void) {
#pragma omp declare mapper(id1: struct vec vvec) map(iterator(it=0:vvec.len:2), tofrom:vvec.data[it])
// OMP52: #pragma omp declare mapper (id1 : struct vec vvec) map(iterator(int it = 0:vvec.len:2),tofrom: vvec.data[it]);
#endif

{
struct outer outer;
#pragma omp target map(outer)
// CHECK: #pragma omp target map(tofrom: outer)
{ }
}

return 0;
}
// CHECK: }
Expand Down
26 changes: 26 additions & 0 deletions clang/test/OpenMP/declare_mapper_ast_print.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,28 @@ class vecchild : public vec {
// CHECK: }
// CHECK: ;

// Verify that nested default mappers do not lead to a crash during parsing / sema.
// CHECK: namespace N2 {
namespace N2
{
// CHECK: struct inner {
struct inner {
int size;
int *data;
};
#pragma omp declare mapper(struct inner i) map(i, i.data[0 : i.size])
// CHECK: #pragma omp declare mapper (default : struct inner i) map(tofrom: N2::default::i,i.data[0:i.size]){{$}}

// CHECK: struct outer {
struct outer {
int a;
struct inner i;
};
#pragma omp declare mapper(struct outer o) map(o)
// CHECK: #pragma omp declare mapper (default : struct outer o) map(tofrom: N2::default::o) map(tofrom: o.i){{$}}
} // namespace N2
// CHECK: }

template <class T>
class dat {
public:
Expand Down Expand Up @@ -122,6 +144,7 @@ T foo(T a) {
int main() {
N1::vec vv, vvv;
N1::vecchild vc;
N2::outer outer;
dat<double> dd;
#pragma omp target map(mapper(N1::id) tofrom: vv) map(mapper(dat<double>::id) alloc: vvv)
// CHECK: #pragma omp target map(mapper(N1::id),tofrom: vv) map(mapper(dat<double>::id),alloc: vvv)
Expand All @@ -132,6 +155,9 @@ int main() {
#pragma omp target map(mapper(default) tofrom: dd)
// CHECK: #pragma omp target map(mapper(default),tofrom: dd)
{ dd.d++; }
#pragma omp target map(outer)
// CHECK: #pragma omp target map(tofrom: outer)
{ }

#pragma omp target update to(mapper(N1::id) : vc)
// CHECK: #pragma omp target update to(mapper(N1::id): vc)
Expand Down
Loading