Skip to content

Commit 1efc6c0

Browse files
author
urvi-rav
committed
Implement new syntax for uses_allocators clause
1 parent 3821885 commit 1efc6c0

File tree

3 files changed

+97
-4
lines changed

3 files changed

+97
-4
lines changed

clang/include/clang/Basic/DiagnosticParseKinds.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1497,6 +1497,11 @@ def err_omp_multiple_step_or_linear_modifier : Error<
14971497
"multiple %select{'step size'|'linear modifier'}0 found in linear clause">;
14981498
def err_omp_deprecate_old_syntax: Error<
14991499
"old syntax '%0' on '%1' clause was deprecated, use new syntax '%2'">;
1500+
def warn_omp_deprecate_old_syntax: Warning<
1501+
"old syntax '%0' on '%1' clause was deprecated, use new syntax '%2'">,
1502+
InGroup<Deprecated>;
1503+
def err_omp_allocator_comma_separator :
1504+
Error<"',' not allowed as separator in 'uses_allocators' clause, use ';' instead">;
15001505
def warn_omp_future_directive_spelling: Warning<
15011506
"directive spelling '%0' is introduced in a later OpenMP version">,
15021507
InGroup<OpenMPFuture>;

clang/lib/Parse/ParseOpenMP.cpp

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2959,6 +2959,69 @@ OMPClause *Parser::ParseOpenMPUsesAllocatorClause(OpenMPDirectiveKind DKind) {
29592959
return nullptr;
29602960
SmallVector<SemaOpenMP::UsesAllocatorsData, 4> Data;
29612961
do {
2962+
// Parse 'traits(expr) : Allocator' for >=5.2
2963+
if (getLangOpts().OpenMP >= 52 &&
2964+
Tok.is(tok::identifier) &&
2965+
Tok.getIdentifierInfo()->getName() == "traits") {
2966+
2967+
SemaOpenMP::UsesAllocatorsData &D = Data.emplace_back();
2968+
2969+
ConsumeToken();
2970+
2971+
// Parse '(' <expr> ')'
2972+
BalancedDelimiterTracker TraitParens(*this, tok::l_paren, tok::annot_pragma_openmp_end);
2973+
TraitParens.consumeOpen();
2974+
ExprResult AllocatorTraits =
2975+
getLangOpts().CPlusPlus ? ParseCXXIdExpression() : ParseExpression();
2976+
TraitParens.consumeClose();
2977+
2978+
if (AllocatorTraits.isInvalid()) {
2979+
SkipUntil({tok::comma, tok::semi, tok::r_paren, tok::annot_pragma_openmp_end},
2980+
StopBeforeMatch);
2981+
break;
2982+
}
2983+
2984+
// Expect ':'
2985+
if (Tok.isNot(tok::colon)) {
2986+
Diag(Tok, diag::err_expected) << tok::colon;
2987+
SkipUntil({tok::comma, tok::semi, tok::r_paren, tok::annot_pragma_openmp_end},
2988+
StopBeforeMatch);
2989+
continue;
2990+
}
2991+
ConsumeToken();
2992+
2993+
CXXScopeSpec SS;
2994+
Token Replacement;
2995+
ExprResult AllocatorExpr =
2996+
getLangOpts().CPlusPlus
2997+
? ParseCXXIdExpression()
2998+
: tryParseCXXIdExpression(SS, /*isAddressOfOperand=*/false, Replacement);
2999+
3000+
if (AllocatorExpr.isInvalid()) {
3001+
SkipUntil({tok::comma, tok::semi, tok::r_paren, tok::annot_pragma_openmp_end},
3002+
StopBeforeMatch);
3003+
break;
3004+
}
3005+
3006+
D.Allocator = AllocatorExpr.get();
3007+
D.AllocatorTraits = AllocatorTraits.get();
3008+
D.LParenLoc = TraitParens.getOpenLocation();
3009+
D.RParenLoc = TraitParens.getCloseLocation();
3010+
3011+
// Separator handling(;)
3012+
if (Tok.is(tok::comma)) {
3013+
// In 5.2, comma is invalid
3014+
Diag(Tok.getLocation(), diag::err_omp_allocator_comma_separator)
3015+
<< FixItHint::CreateReplacement(Tok.getLocation(), ";");
3016+
ConsumeAnyToken();
3017+
} else if (Tok.is(tok::semi)) {
3018+
ConsumeAnyToken(); // valid separator
3019+
}
3020+
3021+
continue;
3022+
}
3023+
3024+
// Parse 'Allocator(expr)' for <5.2
29623025
CXXScopeSpec SS;
29633026
Token Replacement;
29643027
ExprResult Allocator =
@@ -2988,6 +3051,14 @@ OMPClause *Parser::ParseOpenMPUsesAllocatorClause(OpenMPDirectiveKind DKind) {
29883051
D.AllocatorTraits = AllocatorTraits.get();
29893052
D.LParenLoc = T.getOpenLocation();
29903053
D.RParenLoc = T.getCloseLocation();
3054+
3055+
// Deprecation diagnostic in >= 5.2
3056+
if (getLangOpts().OpenMP >= 52) {
3057+
Diag(Loc, diag::warn_omp_deprecate_old_syntax)
3058+
<< "allocator(expr)" // %0: old form
3059+
<< "uses_allocators" // %1: clause name
3060+
<< "traits(expr): alloc"; // %2: suggested new form
3061+
}
29913062
}
29923063
if (Tok.isNot(tok::comma) && Tok.isNot(tok::r_paren))
29933064
Diag(Tok, diag::err_omp_expected_punc) << "uses_allocators" << 0;

clang/test/OpenMP/target_uses_allocators_messages.cpp

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
// RUN: %clang_cc1 -verify -fopenmp-simd %s -Wuninitialized
44

5+
// RUN: %clang_cc1 -DOMP52 -verify=omp52 -fopenmp -fopenmp-version=52 %s -Wuninitialized
6+
7+
// RUN: %clang_cc1 -DOMP52 -verify=omp52 -fopenmp-simd -fopenmp-version=52 %s -Wuninitialized
8+
59
struct omp_alloctrait_t {};
610

711
typedef void **omp_allocator_handle_t;
@@ -16,10 +20,15 @@ extern const omp_allocator_handle_t omp_pteam_mem_alloc;
1620
extern const omp_allocator_handle_t omp_thread_mem_alloc;
1721

1822
int main(int argc, char **argv) {
19-
omp_alloctrait_t traits[10];
23+
omp_alloctrait_t my_traits[10];
2024
omp_alloctrait_t *ptraits;
2125
omp_allocator_handle_t my_alloc = nullptr;
2226
const omp_allocator_handle_t c_my_alloc = my_alloc;
27+
omp_alloctrait_t aligned_traits[10];
28+
omp_allocator_handle_t aligned_alloc;
29+
30+
#ifndef OMP52
31+
2332
#pragma omp target uses_allocators // expected-error {{expected '(' after 'uses_allocator'}}
2433
{}
2534
#pragma omp target uses_allocators( // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{expected unqualified-id}}
@@ -34,7 +43,7 @@ int main(int argc, char **argv) {
3443
{}
3544
#pragma omp target uses_allocators(omp_default_mem_alloc, omp_large_cap_mem_alloc, omp_const_mem_alloc, omp_high_bw_mem_alloc, omp_low_lat_mem_alloc, omp_cgroup_mem_alloc, omp_pteam_mem_alloc, omp_thread_mem_alloc)
3645
{}
37-
#pragma omp target uses_allocators(omp_default_mem_alloc(traits), omp_large_cap_mem_alloc(traits), omp_const_mem_alloc(traits), omp_high_bw_mem_alloc(traits), omp_low_lat_mem_alloc(traits), omp_cgroup_mem_alloc(traits), omp_pteam_mem_alloc(traits), omp_thread_mem_alloc(traits)) // expected-error 8 {{predefined allocator cannot have traits specified}} expected-note-re 8 {{predefined trait '{{omp_default_mem_alloc|omp_large_cap_mem_alloc|omp_const_mem_alloc|omp_high_bw_mem_alloc|omp_low_lat_mem_alloc|omp_cgroup_mem_alloc|omp_pteam_mem_alloc|omp_thread_mem_alloc}}' used here}}
46+
#pragma omp target uses_allocators(omp_default_mem_alloc(my_traits), omp_large_cap_mem_alloc(my_traits), omp_const_mem_alloc(my_traits), omp_high_bw_mem_alloc(my_traits), omp_low_lat_mem_alloc(my_traits), omp_cgroup_mem_alloc(my_traits), omp_pteam_mem_alloc(my_traits), omp_thread_mem_alloc(my_traits)) // expected-error 8 {{predefined allocator cannot have traits specified}} expected-note-re 8 {{predefined trait '{{omp_default_mem_alloc|omp_large_cap_mem_alloc|omp_const_mem_alloc|omp_high_bw_mem_alloc|omp_low_lat_mem_alloc|omp_cgroup_mem_alloc|omp_pteam_mem_alloc|omp_thread_mem_alloc}}' used here}}
3847
{}
3948
#pragma omp target uses_allocators(my_alloc, c_my_alloc) // expected-error {{non-predefined allocator must have traits specified}} expected-error {{expected variable of the 'omp_allocator_handle_t' type, not 'const omp_allocator_handle_t' (aka 'void **const')}}
4049
{}
@@ -46,10 +55,18 @@ int main(int argc, char **argv) {
4655
{}
4756
#pragma omp target uses_allocators(my_alloc(ptraits)) // expected-error {{expected constant sized array of 'omp_alloctrait_t' elements, not 'omp_alloctrait_t *'}}
4857
{}
49-
#pragma omp target uses_allocators(my_alloc(traits)) private(my_alloc) // expected-error {{allocators used in 'uses_allocators' clause cannot appear in other data-sharing or data-mapping attribute clauses}} expected-note {{defined as private}}
58+
#pragma omp target uses_allocators(my_alloc(my_traits)) private(my_alloc) // expected-error {{allocators used in 'uses_allocators' clause cannot appear in other data-sharing or data-mapping attribute clauses}} expected-note {{defined as private}}
59+
{}
60+
#pragma omp target map(my_alloc, my_traits) uses_allocators(my_alloc(my_traits)) // expected-error {{allocators used in 'uses_allocators' clause cannot appear in other data-sharing or data-mapping attribute clauses}} expected-note {{used here}}
61+
{}
62+
#else
63+
#pragma omp target teams uses_allocators(traits(my_traits): my_alloc; traits(aligned_traits): aligned_alloc)
64+
{}
65+
#pragma omp target teams uses_allocators(traits(my_traits): my_alloc, traits(aligned_traits): aligned_alloc) // omp52-error {{',' not allowed as separator in 'uses_allocators' clause, use ';' instead}}
5066
{}
51-
#pragma omp target map(my_alloc, traits) uses_allocators(my_alloc(traits)) // expected-error {{allocators used in 'uses_allocators' clause cannot appear in other data-sharing or data-mapping attribute clauses}} expected-note {{used here}}
67+
#pragma omp target teams uses_allocators(my_alloc(my_traits), aligned_alloc(aligned_traits)) // omp52-warning {{old syntax 'allocator(expr)' on 'uses_allocators' clause was deprecated, use new syntax 'traits(expr): alloc'}} //omp52-warning {{old syntax 'allocator(expr)' on 'uses_allocators' clause was deprecated, use new syntax 'traits(expr): alloc'}}
5268
{}
69+
#endif
5370
return 0;
5471
}
5572

0 commit comments

Comments
 (0)