Skip to content

Commit 6d3bb85

Browse files
[OpenMP] Parse and Sema support for declare target in local scope (#83223)
- adds Parse and Sema support for the `declare target` directive inside a function scope.
1 parent 1fc5e50 commit 6d3bb85

File tree

5 files changed

+61
-1
lines changed

5 files changed

+61
-1
lines changed

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11352,6 +11352,8 @@ def err_omp_device_type_mismatch : Error<
1135211352
def err_omp_wrong_device_function_call : Error<
1135311353
"function with 'device_type(%0)' is not available on %select{device|host}1">;
1135411354
def note_omp_marked_device_type_here : Note<"marked as 'device_type(%0)' here">;
11355+
def err_omp_declare_target_has_local_vars : Error<
11356+
"local variable '%0' should not be used in 'declare target' directive; ">;
1135511357
def warn_omp_declare_target_after_first_use : Warning<
1135611358
"declaration marked as declare target after first use, it may lead to incorrect results">,
1135711359
InGroup<OpenMPTarget>;

clang/lib/Parse/ParseOpenMP.cpp

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2984,8 +2984,29 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
29842984
OMPDirectiveScope.Exit();
29852985
break;
29862986
}
2987+
case OMPD_declare_target: {
2988+
SourceLocation DTLoc = ConsumeAnyToken();
2989+
bool HasClauses = Tok.isNot(tok::annot_pragma_openmp_end);
2990+
Sema::DeclareTargetContextInfo DTCI(DKind, DTLoc);
2991+
if (HasClauses)
2992+
ParseOMPDeclareTargetClauses(DTCI);
2993+
bool HasImplicitMappings =
2994+
!HasClauses || (DTCI.ExplicitlyMapped.empty() && DTCI.Indirect);
2995+
2996+
if (HasImplicitMappings) {
2997+
Diag(Tok, diag::err_omp_unexpected_directive)
2998+
<< 1 << getOpenMPDirectiveName(DKind);
2999+
SkipUntil(tok::annot_pragma_openmp_end);
3000+
break;
3001+
}
3002+
3003+
// Skip the last annot_pragma_openmp_end.
3004+
ConsumeAnyToken();
3005+
3006+
Actions.ActOnFinishedOpenMPDeclareTargetContext(DTCI);
3007+
break;
3008+
}
29873009
case OMPD_declare_simd:
2988-
case OMPD_declare_target:
29893010
case OMPD_begin_declare_target:
29903011
case OMPD_end_declare_target:
29913012
case OMPD_requires:

clang/lib/Sema/SemaOpenMP.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23353,6 +23353,15 @@ void Sema::ActOnOpenMPDeclareTargetName(NamedDecl *ND, SourceLocation Loc,
2335323353
isa<FunctionTemplateDecl>(ND)) &&
2335423354
"Expected variable, function or function template.");
2335523355

23356+
if (auto *VD = dyn_cast<VarDecl>(ND)) {
23357+
// Only global variables can be marked as declare target.
23358+
if (!VD->isFileVarDecl() && !VD->isStaticLocal() &&
23359+
!VD->isStaticDataMember()) {
23360+
Diag(Loc, diag::err_omp_declare_target_has_local_vars)
23361+
<< VD->getNameAsString();
23362+
return;
23363+
}
23364+
}
2335623365
// Diagnose marking after use as it may lead to incorrect diagnosis and
2335723366
// codegen.
2335823367
if (LangOpts.OpenMP >= 50 &&

clang/test/OpenMP/declare_target_ast_print.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,13 +360,32 @@ int inner_link;
360360
// CHECK-NEXT: int inner_link;
361361
// CHECK-NEXT: #pragma omp end declare target
362362

363+
void foo2() { return ;}
364+
// CHECK: #pragma omp declare target
365+
// CHECK-NEXT: void foo2() {
366+
// CHECK-NEXT: return;
367+
// CHECK-NEXT: }
368+
369+
int x;
370+
// CHECK: #pragma omp declare target link
371+
// CHECK-NEXT: int x;
372+
// CHECK-NEXT: #pragma omp end declare target
373+
363374
int main (int argc, char **argv) {
364375
foo();
365376
foo_c();
366377
foo_cpp();
367378
test1();
368379
baz<float>();
369380
baz<int>();
381+
382+
#if _OPENMP == 202111
383+
#pragma omp declare target enter(foo2)
384+
#else
385+
#pragma omp declare target to (foo2)
386+
#endif
387+
388+
#pragma omp declare target link(x)
370389
return (0);
371390
}
372391

clang/test/OpenMP/declare_target_messages.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,11 +182,20 @@ struct S {
182182
#pragma omp end declare target
183183
};
184184

185+
void foo3() {
186+
return;
187+
}
188+
189+
int *y;
190+
int **w = &y;
185191
int main (int argc, char **argv) {
192+
int a = 2;
186193
#pragma omp declare target // expected-error {{unexpected OpenMP directive '#pragma omp declare target'}}
187194
int v;
188195
#pragma omp end declare target // expected-error {{unexpected OpenMP directive '#pragma omp end declare target'}}
189196
foo(v);
197+
#pragma omp declare target to(foo3) link(w) // omp52-error {{unexpected 'to' clause, use 'enter' instead}} omp52-error {{expected at least one 'enter', 'link' or 'indirect' clause}}
198+
#pragma omp declare target to(a) //omp45-error {{local variable 'a' should not be used in 'declare target' directive}} omp5-error {{local variable 'a' should not be used in 'declare target' directive}} omp51-error {{local variable 'a' should not be used in 'declare target' directive}} omp52-error {{unexpected 'to' clause, use 'enter' instead}} omp52-error {{expected at least one 'enter', 'link' or 'indirect' clause}}
190199
return (0);
191200
}
192201

0 commit comments

Comments
 (0)