forked from OSchip/llvm-project
[OpenCL] Allow addr space spelling without __ prefix in C++.
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
This commit is contained in:
parent
62590fee89
commit
948e37c8ca
|
@ -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)
|
||||
|
|
|
@ -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:
|
||||
|
@ -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:
|
||||
|
@ -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:
|
||||
|
@ -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:
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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}}
|
||||
|
|
Loading…
Reference in New Issue