diff --git a/clang/include/clang/Basic/OpenCLImageTypes.def b/clang/include/clang/Basic/OpenCLImageTypes.def --- a/clang/include/clang/Basic/OpenCLImageTypes.def +++ b/clang/include/clang/Basic/OpenCLImageTypes.def @@ -65,7 +65,7 @@ IMAGE_WRITE_TYPE(image2d_array_msaa, OCLImage2dArrayMSAA, "cl_khr_gl_msaa_sharing") IMAGE_WRITE_TYPE(image2d_msaa_depth, OCLImage2dMSAADepth, "cl_khr_gl_msaa_sharing") IMAGE_WRITE_TYPE(image2d_array_msaa_depth, OCLImage2dArrayMSAADepth, "cl_khr_gl_msaa_sharing") -IMAGE_WRITE_TYPE(image3d, OCLImage3d, "cl_khr_3d_image_writes") +IMAGE_WRITE_TYPE(image3d, OCLImage3d, "") IMAGE_READ_WRITE_TYPE(image1d, OCLImage1d, "") IMAGE_READ_WRITE_TYPE(image1d_array, OCLImage1dArray, "") diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -3071,6 +3071,19 @@ SourceLocation Loc = Tok.getLocation(); + // Helper for image types in OpenCL. + auto handleOpenCLImageKW = [&] (StringRef Ext, TypeSpecifierType ImageTypeSpec) { + // Check if the image type is supported and otherwise turn the keyword into an identifier + // because image types from extensions are not reserved identifiers. + if (!StringRef(Ext).empty() && !getActions().getOpenCLOptions().isSupported(Ext, getLangOpts())) { + Tok.getIdentifierInfo()->revertTokenIDToIdentifier(); + Tok.setKind(tok::identifier); + return false; + } + isInvalid = DS.SetTypeSpecType(ImageTypeSpec, Loc, PrevSpec, DiagID, Policy); + return true; + }; + switch (Tok.getKind()) { default: DoneWithDeclSpec: @@ -3935,11 +3948,14 @@ } isInvalid = DS.SetTypePipe(true, Loc, PrevSpec, DiagID, Policy); break; -#define GENERIC_IMAGE_TYPE(ImgType, Id) \ - case tok::kw_##ImgType##_t: \ - isInvalid = DS.SetTypeSpecType(DeclSpec::TST_##ImgType##_t, Loc, PrevSpec, \ - DiagID, Policy); \ - break; +// We only need to enumerate each image type once. +#define IMAGE_READ_WRITE_TYPE(Type, Id, Ext) +#define IMAGE_WRITE_TYPE(Type, Id, Ext) +#define IMAGE_READ_TYPE(ImgType, Id, Ext) \ + case tok::kw_##ImgType##_t: \ + if (!handleOpenCLImageKW(Ext, DeclSpec::TST_##ImgType##_t)) \ + goto DoneWithDeclSpec; \ + break; #include "clang/Basic/OpenCLImageTypes.def" case tok::kw___unknown_anytype: isInvalid = DS.SetTypeSpecType(TST_unknown_anytype, Loc, diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp --- a/clang/lib/Sema/Sema.cpp +++ b/clang/lib/Sema/Sema.cpp @@ -368,9 +368,6 @@ setOpenCLExtensionForType(Context.DoubleTy, "cl_khr_fp64"); -#define GENERIC_IMAGE_TYPE_EXT(Type, Id, Ext) \ - setOpenCLExtensionForType(Context.Id, Ext); -#include "clang/Basic/OpenCLImageTypes.def" #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \ if (getOpenCLOptions().isSupported(#Ext, getLangOpts())) { \ addImplicitTypedef(#ExtType, Context.Id##Ty); \ diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -1713,6 +1713,13 @@ if (Result->containsErrors()) declarator.setInvalidType(); + if (S.getLangOpts().OpenCL && Result->isOCLImage3dWOType() && + !S.getOpenCLOptions().isSupported("cl_khr_3d_image_writes", S.getLangOpts())) { + S.Diag(DS.getTypeSpecTypeLoc(), diag::err_opencl_requires_extension) + << 0 << Result << "cl_khr_3d_image_writes"; + declarator.setInvalidType(); + } + if (S.getLangOpts().OpenCL && S.checkOpenCLDisabledTypeDeclSpec(DS, Result)) declarator.setInvalidType(true); diff --git a/clang/test/SemaOpenCL/access-qualifier.cl b/clang/test/SemaOpenCL/access-qualifier.cl --- a/clang/test/SemaOpenCL/access-qualifier.cl +++ b/clang/test/SemaOpenCL/access-qualifier.cl @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -verify -pedantic -fsyntax-only -cl-std=CL1.2 %s +// RUN: %clang_cc1 -verify -pedantic -fsyntax-only -cl-std=CL1.2 %s -cl-ext=-cl_khr_3d_image_writes // RUN: %clang_cc1 -verify -pedantic -fsyntax-only -cl-std=CL2.0 %s typedef image1d_t img1d_ro_default; // expected-note {{previously declared 'read_only' here}} diff --git a/clang/test/SemaOpenCL/invalid-image.cl b/clang/test/SemaOpenCL/invalid-image.cl --- a/clang/test/SemaOpenCL/invalid-image.cl +++ b/clang/test/SemaOpenCL/invalid-image.cl @@ -1,5 +1,6 @@ // RUN: %clang_cc1 -verify -cl-std=clc++ %s -// RUN: %clang_cc1 -verify %s +// RUN: %clang_cc1 -verify %s -cl-ext=+cl_khr_gl_msaa_sharing +// RUN: %clang_cc1 -verify %s -cl-ext=-cl_khr_gl_msaa_sharing // RUN: %clang_cc1 -verify -D=ATTR_TEST -fms-compatibility %s void test1(image1d_t *i) {} // expected-error-re{{pointer to type '{{__generic __read_only|__read_only}} image1d_t' is invalid in OpenCL}} @@ -19,3 +20,24 @@ // Test case for an infinite loop bug. kernel void foob(read_only __ptr32 image2d_t i) { } // expected-error{{'__ptr32' attribute only applies to pointer arguments}} #endif + +typedef int image1d_t; // expected-error{{cannot combine with previous 'int' declaration specifier}} expected-warning{{typedef requires a name}} +typedef int image2d_t; // expected-error{{cannot combine with previous 'int' declaration specifier}} expected-warning{{typedef requires a name}} +typedef int image3d_t; // expected-error{{cannot combine with previous 'int' declaration specifier}} expected-warning{{typedef requires a name}} +typedef int image1d_array_t; // expected-error{{cannot combine with previous 'int' declaration specifier}} expected-warning{{typedef requires a name}} +typedef int image2d_array_t; // expected-error{{cannot combine with previous 'int' declaration specifier}} expected-warning{{typedef requires a name}} +typedef int image2d_depth_t; // expected-error{{cannot combine with previous 'int' declaration specifier}} expected-warning{{typedef requires a name}} +typedef int image1d_buffer_t; // expected-error{{cannot combine with previous 'int' declaration specifier}} expected-warning{{typedef requires a name}} + +// Image types from 'cl_khr_gl_msaa_sharing' are not reserved identifiers. +typedef int image2d_msaa_t; +typedef int image2d_array_msaa_t; +typedef int image2d_msaa_depth_t; +typedef int image2d_array_msaa_depth_t; +#ifdef cl_khr_gl_msaa_sharing +// expected-error@-5{{cannot combine with previous 'int' declaration specifier}} expected-warning@-5{{typedef requires a name}} +// expected-error@-5{{cannot combine with previous 'int' declaration specifier}} expected-warning@-5{{typedef requires a name}} +// expected-error@-5{{cannot combine with previous 'int' declaration specifier}} expected-warning@-5{{typedef requires a name}} +// expected-error@-5{{cannot combine with previous 'int' declaration specifier}} expected-warning@-5{{typedef requires a name}} +#endif +void foo(image2d_msaa_t i);