Skip to content

Commit

Permalink
[OpenMP] Parse and Sema support for declare target in local scope (#8…
Browse files Browse the repository at this point in the history
…3223)

- adds Parse and Sema support for the `declare target` directive inside
a function scope.
  • Loading branch information
sandeepkosuri committed Mar 6, 2024
1 parent 1fc5e50 commit 6d3bb85
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 1 deletion.
2 changes: 2 additions & 0 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -11352,6 +11352,8 @@ def err_omp_device_type_mismatch : Error<
def err_omp_wrong_device_function_call : Error<
"function with 'device_type(%0)' is not available on %select{device|host}1">;
def note_omp_marked_device_type_here : Note<"marked as 'device_type(%0)' here">;
def err_omp_declare_target_has_local_vars : Error<
"local variable '%0' should not be used in 'declare target' directive; ">;
def warn_omp_declare_target_after_first_use : Warning<
"declaration marked as declare target after first use, it may lead to incorrect results">,
InGroup<OpenMPTarget>;
Expand Down
23 changes: 22 additions & 1 deletion clang/lib/Parse/ParseOpenMP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2984,8 +2984,29 @@ StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective(
OMPDirectiveScope.Exit();
break;
}
case OMPD_declare_target: {
SourceLocation DTLoc = ConsumeAnyToken();
bool HasClauses = Tok.isNot(tok::annot_pragma_openmp_end);
Sema::DeclareTargetContextInfo DTCI(DKind, DTLoc);
if (HasClauses)
ParseOMPDeclareTargetClauses(DTCI);
bool HasImplicitMappings =
!HasClauses || (DTCI.ExplicitlyMapped.empty() && DTCI.Indirect);

if (HasImplicitMappings) {
Diag(Tok, diag::err_omp_unexpected_directive)
<< 1 << getOpenMPDirectiveName(DKind);
SkipUntil(tok::annot_pragma_openmp_end);
break;
}

// Skip the last annot_pragma_openmp_end.
ConsumeAnyToken();

Actions.ActOnFinishedOpenMPDeclareTargetContext(DTCI);
break;
}
case OMPD_declare_simd:
case OMPD_declare_target:
case OMPD_begin_declare_target:
case OMPD_end_declare_target:
case OMPD_requires:
Expand Down
9 changes: 9 additions & 0 deletions clang/lib/Sema/SemaOpenMP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23353,6 +23353,15 @@ void Sema::ActOnOpenMPDeclareTargetName(NamedDecl *ND, SourceLocation Loc,
isa<FunctionTemplateDecl>(ND)) &&
"Expected variable, function or function template.");

if (auto *VD = dyn_cast<VarDecl>(ND)) {
// Only global variables can be marked as declare target.
if (!VD->isFileVarDecl() && !VD->isStaticLocal() &&
!VD->isStaticDataMember()) {
Diag(Loc, diag::err_omp_declare_target_has_local_vars)
<< VD->getNameAsString();
return;
}
}
// Diagnose marking after use as it may lead to incorrect diagnosis and
// codegen.
if (LangOpts.OpenMP >= 50 &&
Expand Down
19 changes: 19 additions & 0 deletions clang/test/OpenMP/declare_target_ast_print.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -360,13 +360,32 @@ int inner_link;
// CHECK-NEXT: int inner_link;
// CHECK-NEXT: #pragma omp end declare target

void foo2() { return ;}
// CHECK: #pragma omp declare target
// CHECK-NEXT: void foo2() {
// CHECK-NEXT: return;
// CHECK-NEXT: }

int x;
// CHECK: #pragma omp declare target link
// CHECK-NEXT: int x;
// CHECK-NEXT: #pragma omp end declare target

int main (int argc, char **argv) {
foo();
foo_c();
foo_cpp();
test1();
baz<float>();
baz<int>();

#if _OPENMP == 202111
#pragma omp declare target enter(foo2)
#else
#pragma omp declare target to (foo2)
#endif

#pragma omp declare target link(x)
return (0);
}

Expand Down
9 changes: 9 additions & 0 deletions clang/test/OpenMP/declare_target_messages.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -182,11 +182,20 @@ struct S {
#pragma omp end declare target
};

void foo3() {
return;
}

int *y;
int **w = &y;
int main (int argc, char **argv) {
int a = 2;
#pragma omp declare target // expected-error {{unexpected OpenMP directive '#pragma omp declare target'}}
int v;
#pragma omp end declare target // expected-error {{unexpected OpenMP directive '#pragma omp end declare target'}}
foo(v);
#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}}
#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}}
return (0);
}

Expand Down

0 comments on commit 6d3bb85

Please sign in to comment.