Skip to content

Commit

Permalink
[OpenCL] Allow addr space spelling without __ prefix in C++.
Browse files Browse the repository at this point in the history
For backwards compatibility we allow alternative spelling of address
spaces - 'private', 'local', 'global', 'constant', 'generic'.

In order to accept 'private' correctly, parsing has been changed to
understand different use cases - access specifier vs address space.

Fixes PR40707 and PR41011!

Differential Revision: https://reviews.llvm.org/D59603

llvm-svn: 356888
  • Loading branch information
Anastasia Stulova committed Mar 25, 2019
1 parent 62590fe commit 948e37c
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 21 deletions.
8 changes: 4 additions & 4 deletions clang/include/clang/Basic/TokenKinds.def
Original file line number Diff line number Diff line change
Expand Up @@ -539,11 +539,11 @@ KEYWORD(__local , KEYOPENCLC | KEYOPENCLCXX)
KEYWORD(__constant , KEYOPENCLC | KEYOPENCLCXX)
KEYWORD(__private , KEYOPENCLC | KEYOPENCLCXX)
KEYWORD(__generic , KEYOPENCLC | KEYOPENCLCXX)
ALIAS("global", __global , KEYOPENCLC)
ALIAS("local", __local , KEYOPENCLC)
ALIAS("constant", __constant , KEYOPENCLC)
ALIAS("global", __global , KEYOPENCLC | KEYOPENCLCXX)
ALIAS("local", __local , KEYOPENCLC | KEYOPENCLCXX)
ALIAS("constant", __constant , KEYOPENCLC | KEYOPENCLCXX)
ALIAS("private", __private , KEYOPENCLC)
ALIAS("generic", __generic , KEYOPENCLC)
ALIAS("generic", __generic , KEYOPENCLC | KEYOPENCLCXX)
// OpenCL function qualifiers
KEYWORD(__kernel , KEYOPENCLC | KEYOPENCLCXX)
ALIAS("kernel", __kernel , KEYOPENCLC | KEYOPENCLCXX)
Expand Down
4 changes: 4 additions & 0 deletions clang/lib/Parse/ParseDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3824,6 +3824,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
break;
};
LLVM_FALLTHROUGH;
case tok::kw_private:
case tok::kw___private:
case tok::kw___global:
case tok::kw___local:
Expand Down Expand Up @@ -4790,6 +4791,7 @@ bool Parser::isTypeSpecifierQualifier() {

case tok::kw___kindof:

case tok::kw_private:
case tok::kw___private:
case tok::kw___local:
case tok::kw___global:
Expand Down Expand Up @@ -4980,6 +4982,7 @@ bool Parser::isDeclarationSpecifier(bool DisambiguatingWithExpression) {

case tok::kw___kindof:

case tok::kw_private:
case tok::kw___private:
case tok::kw___local:
case tok::kw___global:
Expand Down Expand Up @@ -5192,6 +5195,7 @@ void Parser::ParseTypeQualifierListOpt(
break;

// OpenCL qualifiers:
case tok::kw_private:
case tok::kw___private:
case tok::kw___global:
case tok::kw___local:
Expand Down
9 changes: 7 additions & 2 deletions clang/lib/Parse/ParseDeclCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3047,9 +3047,14 @@ Parser::DeclGroupPtrTy Parser::ParseCXXClassMemberDeclarationWithPragmas(
DiagnoseUnexpectedNamespace(cast<NamedDecl>(TagDecl));
return nullptr;

case tok::kw_private:
// FIXME: We don't accept GNU attributes on access specifiers in OpenCL mode
// yet.
if (getLangOpts().OpenCL && !NextToken().is(tok::colon))
return ParseCXXClassMemberDeclaration(AS, AccessAttrs);
LLVM_FALLTHROUGH;
case tok::kw_public:
case tok::kw_protected:
case tok::kw_private: {
case tok::kw_protected: {
AccessSpecifier NewAS = getAccessSpecifierIfPresent();
assert(NewAS != AS_none);
// Current token is a C++ access specifier.
Expand Down
1 change: 1 addition & 0 deletions clang/lib/Parse/ParseTentative.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1411,6 +1411,7 @@ Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult,
case tok::kw_const:
case tok::kw_volatile:
// OpenCL address space qualifiers
case tok::kw_private:
case tok::kw___private:
case tok::kw___local:
case tok::kw___global:
Expand Down
32 changes: 17 additions & 15 deletions clang/test/Parser/opencl-cxx-keywords.cl
Original file line number Diff line number Diff line change
Expand Up @@ -19,32 +19,34 @@ kernel void test_exceptions() {
// Test that only __-prefixed address space qualifiers are accepted.
struct test_address_space_qualifiers {
global int *g;
// expected-error@-1 {{unknown type name 'global'}}
// expected-error@-2 {{expected member name or ';' after declaration specifiers}}
__global int *uug;
int global; // should be fine in OpenCL C++
int global; // expected-warning{{declaration does not declare anything}}

local int *l;
// expected-error@-1 {{unknown type name 'local'}}
// expected-error@-2 {{expected member name or ';' after declaration specifiers}}
__local int *uul;
int local; // should be fine in OpenCL C++
int local; // expected-warning{{declaration does not declare anything}}

private int *p;
// expected-error@-1 {{expected ':'}}
__private int *uup;
int private; // 'private' is a keyword in C++14 and thus in OpenCL C++
// expected-error@-1 {{expected member name or ';' after declaration specifiers}}
int private; // expected-warning{{declaration does not declare anything}}

constant int *c;
// expected-error@-1 {{unknown type name 'constant'}}
// expected-error@-2 {{expected member name or ';' after declaration specifiers}}
__constant int *uuc;
int constant; // should be fine in OpenCL C++
int constant; // expected-warning{{declaration does not declare anything}}

generic int *ge;
// expected-error@-1 {{unknown type name 'generic'}}
// expected-error@-2 {{expected member name or ';' after declaration specifiers}}
__generic int *uuge;
int generic; // should be fine in OpenCL C++
int generic; // expected-warning{{declaration does not declare anything}}
};

// Test that 'private' can be parsed as an access qualifier and an address space too.
class A{
private:
private int i; //expected-error{{field may not be qualified with an address space}}
};

private ::A i; //expected-error{{program scope variable must reside in global or constant address space}}

void foo(private int i);

private int bar(); //expected-error{{return value cannot be qualified with address space}}

0 comments on commit 948e37c

Please sign in to comment.