Index: include/clang/Basic/DiagnosticParseKinds.td =================================================================== --- include/clang/Basic/DiagnosticParseKinds.td +++ include/clang/Basic/DiagnosticParseKinds.td @@ -1133,8 +1133,6 @@ // OpenCL C++. def err_openclcxx_virtual_function : Error< "virtual functions are not supported in OpenCL C++">; -def err_openclcxx_reserved : Error< - "'%0' is a reserved keyword in OpenCL C++">; // OpenMP support. def warn_pragma_omp_ignored : Warning< Index: include/clang/Basic/TokenKinds.def =================================================================== --- include/clang/Basic/TokenKinds.def +++ include/clang/Basic/TokenKinds.def @@ -550,9 +550,9 @@ ALIAS("write_only", __write_only , KEYOPENCLC | KEYOPENCLCXX) ALIAS("read_write", __read_write , KEYOPENCLC | KEYOPENCLCXX) // OpenCL builtins -KEYWORD(__builtin_astype , KEYOPENCLC) +KEYWORD(__builtin_astype , KEYOPENCLC | KEYOPENCLCXX) KEYWORD(vec_step , KEYOPENCLC | KEYALTIVEC | KEYZVECTOR) -#define GENERIC_IMAGE_TYPE(ImgType, Id) KEYWORD(ImgType##_t, KEYOPENCLC) +#define GENERIC_IMAGE_TYPE(ImgType, Id) KEYWORD(ImgType##_t, KEYOPENCLC | KEYOPENCLCXX) #include "clang/Basic/OpenCLImageTypes.def" // OpenMP Type Traits Index: lib/Parse/ParseDecl.cpp =================================================================== --- lib/Parse/ParseDecl.cpp +++ lib/Parse/ParseDecl.cpp @@ -3808,19 +3808,6 @@ getLangOpts()); break; - // OpenCL access qualifiers: - case tok::kw___read_only: - case tok::kw___write_only: - case tok::kw___read_write: - // OpenCL C++ 1.0 s2.2: access qualifiers are reserved keywords. - if (Actions.getLangOpts().OpenCLCPlusPlus) { - DiagID = diag::err_openclcxx_reserved; - PrevSpec = Tok.getIdentifierInfo()->getNameStart(); - isInvalid = true; - } - ParseOpenCLQualifiers(DS.getAttributes()); - break; - // OpenCL address space qualifiers: case tok::kw___generic: // generic address space is introduced only in OpenCL v2.0 @@ -3837,6 +3824,10 @@ case tok::kw___global: case tok::kw___local: case tok::kw___constant: + // OpenCL access qualifiers: + case tok::kw___read_only: + case tok::kw___write_only: + case tok::kw___read_write: ParseOpenCLQualifiers(DS.getAttributes()); break; Index: lib/Parse/ParseExprCXX.cpp =================================================================== --- lib/Parse/ParseExprCXX.cpp +++ lib/Parse/ParseExprCXX.cpp @@ -1994,6 +1994,13 @@ case tok::kw_bool: DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec, DiagID, Policy); break; +#define GENERIC_IMAGE_TYPE(ImgType, Id) \ + case tok::kw_##ImgType##_t: \ + DS.SetTypeSpecType(DeclSpec::TST_##ImgType##_t, Loc, PrevSpec, DiagID, \ + Policy); \ + break; +#include "clang/Basic/OpenCLImageTypes.def" + case tok::annot_decltype: case tok::kw_decltype: DS.SetRangeEnd(ParseDecltypeSpecifier(DS)); Index: lib/Parse/ParseTentative.cpp =================================================================== --- lib/Parse/ParseTentative.cpp +++ lib/Parse/ParseTentative.cpp @@ -1410,11 +1410,16 @@ // cv-qualifier case tok::kw_const: case tok::kw_volatile: + // OpenCL address space qualifiers case tok::kw___private: case tok::kw___local: case tok::kw___global: case tok::kw___constant: case tok::kw___generic: + // OpenCL access qualifiers + case tok::kw___read_only: + case tok::kw___write_only: + case tok::kw___read_write: // GNU case tok::kw_restrict: @@ -1600,6 +1605,8 @@ case tok::kw___float128: case tok::kw_void: case tok::annot_decltype: +#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t: +#include "clang/Basic/OpenCLImageTypes.def" if (NextToken().is(tok::l_paren)) return TPResult::Ambiguous; @@ -1693,6 +1700,8 @@ case tok::kw_void: case tok::kw___unknown_anytype: case tok::kw___auto_type: +#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t: +#include "clang/Basic/OpenCLImageTypes.def" return true; case tok::kw_auto: Index: lib/Sema/SemaDeclAttr.cpp =================================================================== --- lib/Sema/SemaDeclAttr.cpp +++ lib/Sema/SemaDeclAttr.cpp @@ -6289,7 +6289,9 @@ if (const auto *PDecl = dyn_cast(D)) { const Type *DeclTy = PDecl->getType().getCanonicalType().getTypePtr(); if (AL.getName()->getName().find("read_write") != StringRef::npos) { - if (S.getLangOpts().OpenCLVersion < 200 || DeclTy->isPipeType()) { + if ((!S.getLangOpts().OpenCLCPlusPlus && + S.getLangOpts().OpenCLVersion < 200) || + DeclTy->isPipeType()) { S.Diag(AL.getLoc(), diag::err_opencl_invalid_read_write) << AL << PDecl->getType() << DeclTy->isImageType(); D->setInvalidDecl(true); Index: test/CodeGenOpenCL/images.cl =================================================================== --- test/CodeGenOpenCL/images.cl +++ test/CodeGenOpenCL/images.cl @@ -1,4 +1,5 @@ // RUN: %clang_cc1 %s -triple x86_64-unknown-linux-gnu -O0 -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 %s -triple x86_64-unknown-linux-gnu -O0 -emit-llvm -o - -cl-std=c++ | FileCheck %s __attribute__((overloadable)) void read_image(read_only image1d_t img_ro); __attribute__((overloadable)) void read_image(write_only image1d_t img_wo); Index: test/SemaOpenCL/invalid-image.cl =================================================================== --- test/SemaOpenCL/invalid-image.cl +++ test/SemaOpenCL/invalid-image.cl @@ -1,7 +1,8 @@ +// RUN: %clang_cc1 -verify -cl-std=c++ %s // RUN: %clang_cc1 -verify %s // RUN: %clang_cc1 -verify -D=ATTR_TEST -fms-compatibility %s -void test1(image1d_t *i) {} // expected-error{{pointer to type '__read_only image1d_t' is invalid in OpenCL}} +void test1(image1d_t *i) {} // expected-error-re{{pointer to type '{{__generic __read_only|__read_only}} image1d_t' is invalid in OpenCL}} void test2(image1d_t i) { image1d_t ti; // expected-error{{type '__read_only image1d_t' can only be used as a function parameter}} Index: test/SemaOpenCLCXX/restricted.cl =================================================================== --- test/SemaOpenCLCXX/restricted.cl +++ test/SemaOpenCLCXX/restricted.cl @@ -39,25 +39,3 @@ thread_local int y; // expected-error@-1 {{OpenCL C++ version 1.0 does not support the 'thread_local' storage class specifier}} } - -// Test that access qualifiers are reserved keywords. -kernel void test_access_qualifiers() { - int read_only; - // expected-error@-1 {{'read_only' is a reserved keyword in OpenCL C++}} - // expected-warning@-2 {{declaration does not declare anything}} - int __read_only; - // expected-error@-1 {{'__read_only' is a reserved keyword in OpenCL C++}} - // expected-warning@-2 {{declaration does not declare anything}} - int write_only; - // expected-error@-1 {{'write_only' is a reserved keyword in OpenCL C++}} - // expected-warning@-2 {{declaration does not declare anything}} - int __write_only; - // expected-error@-1 {{'__write_only' is a reserved keyword in OpenCL C++}} - // expected-warning@-2 {{declaration does not declare anything}} - int read_write; - // expected-error@-1 {{'read_write' is a reserved keyword in OpenCL C++}} - // expected-warning@-2 {{declaration does not declare anything}} - int __read_write; - // expected-error@-1 {{'__read_write' is a reserved keyword in OpenCL C++}} - // expected-warning@-2 {{declaration does not declare anything}} -}