Index: include/clang/Basic/TokenKinds.def =================================================================== --- include/clang/Basic/TokenKinds.def +++ include/clang/Basic/TokenKinds.def @@ -537,11 +537,11 @@ 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) Index: lib/Parse/ParseDecl.cpp =================================================================== --- lib/Parse/ParseDecl.cpp +++ lib/Parse/ParseDecl.cpp @@ -3824,6 +3824,7 @@ break; }; LLVM_FALLTHROUGH; + case tok::kw_private: case tok::kw___private: case tok::kw___global: case tok::kw___local: @@ -4790,6 +4791,7 @@ case tok::kw___kindof: + case tok::kw_private: case tok::kw___private: case tok::kw___local: case tok::kw___global: @@ -4980,6 +4982,7 @@ case tok::kw___kindof: + case tok::kw_private: case tok::kw___private: case tok::kw___local: case tok::kw___global: @@ -5192,6 +5195,7 @@ break; // OpenCL qualifiers: + case tok::kw_private: case tok::kw___private: case tok::kw___global: case tok::kw___local: Index: lib/Parse/ParseDeclCXX.cpp =================================================================== --- lib/Parse/ParseDeclCXX.cpp +++ lib/Parse/ParseDeclCXX.cpp @@ -3047,9 +3047,14 @@ DiagnoseUnexpectedNamespace(cast(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. Index: lib/Parse/ParseTentative.cpp =================================================================== --- lib/Parse/ParseTentative.cpp +++ lib/Parse/ParseTentative.cpp @@ -1411,6 +1411,7 @@ 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: Index: test/Parser/opencl-cxx-keywords.cl =================================================================== --- test/Parser/opencl-cxx-keywords.cl +++ test/Parser/opencl-cxx-keywords.cl @@ -19,32 +19,34 @@ // 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 int 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}}