Skip to content
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
4 changes: 3 additions & 1 deletion clang/include/clang/Basic/DiagnosticGroups.td
Original file line number Diff line number Diff line change
Expand Up @@ -1530,9 +1530,11 @@ def OpenMPPre51Compat : DiagGroup<"pre-openmp-51-compat">;
def OpenMP51Ext : DiagGroup<"openmp-51-extensions">;
def OpenMPExtensions : DiagGroup<"openmp-extensions">;
def OpenMPTargetException : DiagGroup<"openmp-target-exception">;
def OpenMPFuture : DiagGroup<"openmp-future">;
def OpenMP : DiagGroup<"openmp", [
SourceUsesOpenMP, OpenMPClauses, OpenMPLoopForm, OpenMPTarget,
OpenMPMapping, OpenMP51Ext, OpenMPExtensions, OpenMPTargetException
OpenMPMapping, OpenMP51Ext, OpenMPExtensions, OpenMPTargetException,
OpenMPFuture
]>;

// OpenACC warnings.
Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/Basic/DiagnosticParseKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -1488,6 +1488,9 @@ def err_omp_multiple_step_or_linear_modifier : Error<
"multiple %select{'step size'|'linear modifier'}0 found in linear clause">;
def err_omp_deprecate_old_syntax: Error<
"old syntax '%0' on '%1' clause was deprecated, use new syntax '%2'">;
def warn_omp_future_directive_spelling: Warning<
"directive spelling '%0' is introduced in a later OpenMP version">,
InGroup<OpenMPFuture>;
def warn_pragma_expected_colon_r_paren : Warning<
"missing ':' or ')' after %0 - ignoring">, InGroup<IgnoredPragmas>;
def err_omp_unknown_directive : Error<
Expand Down
28 changes: 24 additions & 4 deletions clang/lib/Parse/ParseOpenMP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,21 @@ class DeclDirectiveListParserHelper final {
};
} // namespace

static OpenMPDirectiveKind checkOpenMPDirectiveName(Parser &P,
SourceLocation Loc,
OpenMPDirectiveKind Kind,
StringRef Name) {
unsigned Version = P.getLangOpts().OpenMP;
auto [D, VR] = getOpenMPDirectiveKindAndVersions(Name);
assert(D == Kind && "Directive kind mismatch");
// Ignore the case Version > VR.Max: In OpenMP 6.0 all prior spellings
// are explicitly allowed.
if (Version < VR.Min)
P.Diag(Loc, diag::warn_omp_future_directive_spelling) << Name;

return Kind;
}

static OpenMPDirectiveKind parseOpenMPDirectiveKind(Parser &P) {
static const DirectiveNameParser DirParser;

Expand All @@ -65,23 +80,28 @@ static OpenMPDirectiveKind parseOpenMPDirectiveKind(Parser &P) {
if (Tok.isAnnotation())
return OMPD_unknown;

S = DirParser.consume(S, P.getPreprocessor().getSpelling(Tok));
std::string Concat = P.getPreprocessor().getSpelling(Tok);
SourceLocation Loc = Tok.getLocation();

S = DirParser.consume(S, Concat);
if (S == nullptr)
return OMPD_unknown;

while (!Tok.isAnnotation()) {
OpenMPDirectiveKind DKind = S->Value;
Tok = P.getPreprocessor().LookAhead(0);
if (!Tok.isAnnotation()) {
S = DirParser.consume(S, P.getPreprocessor().getSpelling(Tok));
std::string TS = P.getPreprocessor().getSpelling(Tok);
S = DirParser.consume(S, TS);
if (S == nullptr)
return DKind;
return checkOpenMPDirectiveName(P, Loc, DKind, Concat);
Concat += ' ' + TS;
P.ConsumeToken();
}
}

assert(S && "Should have exited early");
return S->Value;
return checkOpenMPDirectiveName(P, Loc, S->Value, Concat);
}

static DeclarationName parseOpenMPReductionId(Parser &P) {
Expand Down
55 changes: 55 additions & 0 deletions clang/test/OpenMP/openmp-6-future-spellings.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=52 -ferror-limit 100 -o - %s

// expected-warning@+1 {{directive spelling 'begin declare_target' is introduced in a later OpenMP version}}
#pragma omp begin declare_target
void f0();
// expected-warning@+1 {{directive spelling 'end declare_target' is introduced in a later OpenMP version}}
#pragma omp end declare_target

// expected-warning@+1 {{directive spelling 'begin declare_variant' is introduced in a later OpenMP version}}
#pragma omp begin declare_variant match(user={condition(true)})
void f1();
// expected-warning@+1 {{directive spelling 'end declare_variant' is introduced in a later OpenMP version}}
#pragma omp end declare_variant

int x;
// expected-warning@+1 {{directive spelling 'declare_target' is introduced in a later OpenMP version}}
#pragma omp declare_target(x)

struct A {
int x, y;
};
// expected-warning@+1 {{directive spelling 'declare_mapper' is introduced in a later OpenMP version}}
#pragma omp declare_mapper(mymapper: A a) map(tofrom:a.x, a.y)
A add(A, A);
// expected-warning@+1 {{directive spelling 'declare_reduction' is introduced in a later OpenMP version}}
#pragma omp declare_reduction(+: A: omp_out = add(omp_in, omp_out))

// expected-warning@+1 {{directive spelling 'declare_simd' is introduced in a later OpenMP version}}
#pragma omp declare_simd
void f2();

void g3();
// expected-warning@+1 {{directive spelling 'declare_variant' is introduced in a later OpenMP version}}
#pragma omp declare_variant(g3) match(user={condition(true)})
void f3() {}

void fred() {
#pragma omp parallel
{
// expected-warning@+1 {{directive spelling 'cancellation_point' is introduced in a later OpenMP version}}
#pragma omp cancellation_point parallel
}

// expected-warning@+1 {{directive spelling 'target_data' is introduced in a later OpenMP version}}
#pragma omp target_data map(tofrom: x)
{}

// expected-warning@+1 {{directive spelling 'target_enter_data' is introduced in a later OpenMP version}}
#pragma omp target_enter_data map(to: x)
// expected-warning@+1 {{directive spelling 'target_exit_data' is introduced in a later OpenMP version}}
#pragma omp target_exit_data map(from: x)
// expected-warning@+1 {{directive spelling 'target_update' is introduced in a later OpenMP version}}
#pragma omp target_update from(x)
}

Loading