Anastasia created this revision. Anastasia added a reviewer: bader. Anastasia added subscribers: cfe-commits, pekka.jaaskelainen, yaxunl.
Follow up from the earlier discussion via cfe-dev regarding incomplete images support in Clang: http://lists.llvm.org/pipermail/cfe-dev/2016-February/047187.html This review is based on older code base (around Clang version 3.5) and is uploaded for quick preview and possible discussions aiming to correct functionality of OpenCL images. I. Current implementation of images is not conformant to spec in the following points: 1. It makes no distinction with respect to access qualifiers and therefore allows to use images with different access type interchangeably. The following code would compile just fine: void write_image(write_only image2d_t img); kernel void foo(read_only image2d_t img) { write_image(img); // Accepted code } which is disallowed according to s6.13.14. 2. It discards access qualifier on generated code, which leads to generated code for the above example: call void @write_image(%opencl.image2d_t* %img); In OpenCL2.0 however we can have different calls into write_image with read_only and wite_only images. Also generally following compiler steps have no easy way to take different path depending on the image access: linking to the right implementation of image types, performing IR opts and backend codegen differently. 3. Image types are language keywords and can't be redeclared s6.1.9, which can happen currently as they are just typedef names. 4. Default access qualifier read_only is to be added if not provided explicitly. II. This patch corrects the above points as follows: 1. All images are encapsulated into a separate .def file that is inserted in different points where image handling is required. This avoid a lot of code repetition as all images are handled the same way in the code with no distinction of their exact type. 2. The Cartesian product of image types and image access qualifiers is added to the builtin types. This simplifies a lot handling of access type mismatch as no operations are allowed by default on distinct Builtin types. Also spec intended access qualifier as special type qualifier that are combined with an image type to form a distinct type (see statement above - images can't be created w/o access qualifiers). 3. Improves testing of images in Clang. This patch would require rebasing, fixing formatting, and also addition of OpenCL2.0 images and pipes, to be committed. http://reviews.llvm.org/D17821 Files: include/clang/AST/ASTContext.h include/clang/AST/BuiltinTypes.def include/clang/AST/OpenCLImageTypes.def include/clang/AST/Type.h include/clang/Basic/Specifiers.h include/clang/Basic/TokenKinds.def include/clang/Sema/DeclSpec.h include/clang/Serialization/ASTBitCodes.h lib/AST/ASTContext.cpp lib/AST/ASTImporter.cpp lib/AST/ItaniumMangle.cpp lib/AST/MicrosoftMangle.cpp lib/AST/NSAPI.cpp lib/AST/Type.cpp lib/AST/TypeLoc.cpp lib/Analysis/PrintfFormatString.cpp lib/CodeGen/CGDebugInfo.cpp lib/CodeGen/CGDebugInfo.h lib/CodeGen/CGOpenCLRuntime.cpp lib/CodeGen/CodeGenTypes.cpp lib/CodeGen/ItaniumCXXABI.cpp lib/Index/USRGeneration.cpp lib/Parse/ParseDecl.cpp lib/Parse/ParseExpr.cpp lib/Parse/ParseTentative.cpp lib/Sema/DeclSpec.cpp lib/Sema/Sema.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaTemplateVariadic.cpp lib/Sema/SemaType.cpp lib/Serialization/ASTCommon.cpp lib/Serialization/ASTReader.cpp test/CodeGenOpenCL/images.cl test/CodeGenOpenCL/opencl_types.cl test/SemaOpenCL/images.cl test/SemaOpenCL/invalid-kernel-parameters.cl tools/libclang/CIndex.cpp
Index: tools/libclang/CIndex.cpp =================================================================== --- tools/libclang/CIndex.cpp +++ tools/libclang/CIndex.cpp @@ -1419,12 +1419,9 @@ case BuiltinType::Void: case BuiltinType::NullPtr: case BuiltinType::Dependent: - case BuiltinType::OCLImage1d: - case BuiltinType::OCLImage1dArray: - case BuiltinType::OCLImage1dBuffer: - case BuiltinType::OCLImage2d: - case BuiltinType::OCLImage2dArray: - case BuiltinType::OCLImage3d: +#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ + case BuiltinType::Id: +#include "clang/AST/OpenCLImageTypes.def" case BuiltinType::OCLSampler: case BuiltinType::OCLEvent: #define BUILTIN_TYPE(Id, SingletonId) Index: test/SemaOpenCL/invalid-kernel-parameters.cl =================================================================== --- test/SemaOpenCL/invalid-kernel-parameters.cl +++ test/SemaOpenCL/invalid-kernel-parameters.cl @@ -24,7 +24,7 @@ typedef struct FooImage2D // expected-note{{within field of type 'FooImage2D' declared here}} { - image2d_t imageField; // expected-note{{field of illegal type 'image2d_t' declared here}} + image2d_t imageField; // expected-note{{field of illegal type '__read_only image2d_t' declared here}} } FooImage2D; kernel void image_in_struct_arg(FooImage2D arg) { } // expected-error{{struct kernel parameters may not contain pointers}} Index: test/SemaOpenCL/images.cl =================================================================== --- /dev/null +++ test/SemaOpenCL/images.cl @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only + +void img2d_ro(__read_only image2d_t img) {} // expected-note{{passing argument to parameter 'img' here}} expected-note{{passing argument to parameter 'img' here}} + +void imgage_access_test(image2d_t img2dro, write_only image2d_t img2dwo, image3d_t img3dro) { + img2d_ro(img2dro); + img2d_ro(img2dwo); // expected-error{{passing '__write_only image2d_t' to parameter of incompatible type '__read_only image2d_t'}} + img2d_ro(img3dro); // expected-error{{passing '__read_only image3d_t' to parameter of incompatible type '__read_only image2d_t'}} +} Index: test/CodeGenOpenCL/opencl_types.cl =================================================================== --- test/CodeGenOpenCL/opencl_types.cl +++ test/CodeGenOpenCL/opencl_types.cl @@ -4,22 +4,22 @@ // CHECK: constant i32 7 void fnc1(image1d_t img) {} -// CHECK: @fnc1(%opencl.image1d_t* +// CHECK: @fnc1(%opencl.image1d_ro_t* void fnc1arr(image1d_array_t img) {} -// CHECK: @fnc1arr(%opencl.image1d_array_t* +// CHECK: @fnc1arr(%opencl.image1d_array_ro_t* void fnc1buff(image1d_buffer_t img) {} -// CHECK: @fnc1buff(%opencl.image1d_buffer_t* +// CHECK: @fnc1buff(%opencl.image1d_buffer_ro_t* void fnc2(image2d_t img) {} -// CHECK: @fnc2(%opencl.image2d_t* +// CHECK: @fnc2(%opencl.image2d_ro_t* void fnc2arr(image2d_array_t img) {} -// CHECK: @fnc2arr(%opencl.image2d_array_t* +// CHECK: @fnc2arr(%opencl.image2d_array_ro_t* void fnc3(image3d_t img) {} -// CHECK: @fnc3(%opencl.image3d_t* +// CHECK: @fnc3(%opencl.image3d_ro_t* void fnc4smp(sampler_t s) {} // CHECK-LABEL: define void @fnc4smp(i32 @@ -37,4 +37,4 @@ } void __attribute__((overloadable)) bad1(image1d_t *b, image2d_t *c, image2d_t *d) {} -// CHECK-LABEL: @{{_Z4bad1P11ocl_image1dP11ocl_image2dS2_|"\\01\?bad1@@YAXPE?APAUocl_image1d@@PE?APAUocl_image2d@@1@Z"}} +// CHECK-LABEL: @{{_Z4bad1P14ocl_image1d_roP14ocl_image2d_roS2_|"\\01\?bad1@@YAXPE?APAUocl_image1d_ro@@PE?APAUocl_image2d_ro@@1@Z"}} Index: test/CodeGenOpenCL/images.cl =================================================================== --- /dev/null +++ test/CodeGenOpenCL/images.cl @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 %s -triple x86_64-unknown-linux-gnu -O0 -emit-llvm -o - | FileCheck %s + +__attribute__((overloadable)) void read_image(read_only image1d_t img_ro); +__attribute__((overloadable)) void read_image(write_only image1d_t img_wo); + +kernel void test_read_image(read_only image1d_t img_ro, write_only image1d_t img_wo){ +// CHECK: call void @_Z10read_image14ocl_image1d_ro(%opencl.image1d_ro_t* %{{[0-9]+}}) + read_image(img_ro); +// CHECK: call void @_Z10read_image14ocl_image1d_wo(%opencl.image1d_wo_t* %{{[0-9]+}}) + read_image(img_wo); +} Index: lib/Serialization/ASTReader.cpp =================================================================== --- lib/Serialization/ASTReader.cpp +++ lib/Serialization/ASTReader.cpp @@ -5948,12 +5948,9 @@ case PREDEF_TYPE_OBJC_ID: T = Context.ObjCBuiltinIdTy; break; case PREDEF_TYPE_OBJC_CLASS: T = Context.ObjCBuiltinClassTy; break; case PREDEF_TYPE_OBJC_SEL: T = Context.ObjCBuiltinSelTy; break; - case PREDEF_TYPE_IMAGE1D_ID: T = Context.OCLImage1dTy; break; - case PREDEF_TYPE_IMAGE1D_ARR_ID: T = Context.OCLImage1dArrayTy; break; - case PREDEF_TYPE_IMAGE1D_BUFF_ID: T = Context.OCLImage1dBufferTy; break; - case PREDEF_TYPE_IMAGE2D_ID: T = Context.OCLImage2dTy; break; - case PREDEF_TYPE_IMAGE2D_ARR_ID: T = Context.OCLImage2dArrayTy; break; - case PREDEF_TYPE_IMAGE3D_ID: T = Context.OCLImage3dTy; break; +#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ + case PREDEF_TYPE_##Id##_ID: T = Context.SingletonId; break; +#include "clang/AST/OpenCLImageTypes.def" case PREDEF_TYPE_SAMPLER_ID: T = Context.OCLSamplerTy; break; case PREDEF_TYPE_EVENT_ID: T = Context.OCLEventTy; break; case PREDEF_TYPE_AUTO_DEDUCT: T = Context.getAutoDeductType(); break; Index: lib/Serialization/ASTCommon.cpp =================================================================== --- lib/Serialization/ASTCommon.cpp +++ lib/Serialization/ASTCommon.cpp @@ -62,12 +62,9 @@ case BuiltinType::ObjCId: ID = PREDEF_TYPE_OBJC_ID; break; case BuiltinType::ObjCClass: ID = PREDEF_TYPE_OBJC_CLASS; break; case BuiltinType::ObjCSel: ID = PREDEF_TYPE_OBJC_SEL; break; - case BuiltinType::OCLImage1d: ID = PREDEF_TYPE_IMAGE1D_ID; break; - case BuiltinType::OCLImage1dArray: ID = PREDEF_TYPE_IMAGE1D_ARR_ID; break; - case BuiltinType::OCLImage1dBuffer: ID = PREDEF_TYPE_IMAGE1D_BUFF_ID; break; - case BuiltinType::OCLImage2d: ID = PREDEF_TYPE_IMAGE2D_ID; break; - case BuiltinType::OCLImage2dArray: ID = PREDEF_TYPE_IMAGE2D_ARR_ID; break; - case BuiltinType::OCLImage3d: ID = PREDEF_TYPE_IMAGE3D_ID; break; +#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ + case BuiltinType::Id: ID = PREDEF_TYPE_##Id##_ID; break; +#include "clang/AST/OpenCLImageTypes.def" case BuiltinType::OCLSampler: ID = PREDEF_TYPE_SAMPLER_ID; break; case BuiltinType::OCLEvent: ID = PREDEF_TYPE_EVENT_ID; break; case BuiltinType::BuiltinFn: Index: lib/Sema/SemaType.cpp =================================================================== --- lib/Sema/SemaType.cpp +++ lib/Sema/SemaType.cpp @@ -32,6 +32,7 @@ #include "clang/Sema/Template.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallString.h" +#include "llvm/ADT/StringSwitch.h" #include "llvm/Support/ErrorHandling.h" using namespace clang; @@ -689,6 +690,20 @@ state.setCurrentChunkIndex(declarator.getNumTypeObjects()); } +static StringRef getImageAccessAttrStr(AttributeList *attrs){ + if (attrs) { + AttributeList *next; + do { + AttributeList &attr = *attrs; + next = attr.getNext(); + if (attr.getKind() == AttributeList::AT_OpenCLImageAccess){ + return attr.getName()->getName(); + } + } while(next); + } + return ""; +} + /// \brief Convert the specified declspec to the appropriate type /// object. /// \param state Specifies the declarator containing the declaration specifier @@ -875,6 +890,7 @@ } break; case DeclSpec::TST_bool: Result = Context.BoolTy; break; // _Bool or bool + break; case DeclSpec::TST_decimal32: // _Decimal32 case DeclSpec::TST_decimal64: // _Decimal64 case DeclSpec::TST_decimal128: // _Decimal128 @@ -1060,7 +1076,17 @@ declarator.setInvalidType(true); } break; - + +#define GENERIC_IMAGE_TYPE(ImgType, Id) \ + case DeclSpec::TST_##ImgType##_t: \ + Result = llvm::StringSwitch<QualType> \ + (getImageAccessAttrStr(DS.getAttributes().getList())) \ + .Cases("write_only", "__write_only", Context.Id##WOTy) \ + .Cases("read_write", "__read_write", Context.Id##RWTy) \ + .Default(Context.Id##ROTy); \ + break; +#include "clang/AST/OpenCLImageTypes.def" + case DeclSpec::TST_error: Result = Context.IntTy; declarator.setInvalidType(true); Index: lib/Sema/SemaTemplateVariadic.cpp =================================================================== --- lib/Sema/SemaTemplateVariadic.cpp +++ lib/Sema/SemaTemplateVariadic.cpp @@ -743,6 +743,8 @@ case TST_class: case TST_auto: case TST_decltype_auto: +#define GENERIC_IMAGE_TYPE(ImgType, Id) case TST_##ImgType##_t: +#include "clang/AST/OpenCLImageTypes.def" case TST_unknown_anytype: case TST_error: break; Index: lib/Sema/SemaExpr.cpp =================================================================== --- lib/Sema/SemaExpr.cpp +++ lib/Sema/SemaExpr.cpp @@ -4508,6 +4508,8 @@ switch (placeholder->getKind()) { // Ignore all the non-placeholder types. +#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) case BuiltinType::Id: +#include "clang/AST/OpenCLImageTypes.def" #define PLACEHOLDER_TYPE(ID, SINGLETON_ID) #define BUILTIN_TYPE(ID, SINGLETON_ID) case BuiltinType::ID: #include "clang/AST/BuiltinTypes.def" @@ -13766,6 +13768,9 @@ } // Everything else should be impossible. +#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ + case BuiltinType::Id: +#include "clang/AST/OpenCLImageTypes.def" #define BUILTIN_TYPE(Id, SingletonId) \ case BuiltinType::Id: #define PLACEHOLDER_TYPE(Id, SingletonId) Index: lib/Sema/Sema.cpp =================================================================== --- lib/Sema/Sema.cpp +++ lib/Sema/Sema.cpp @@ -202,15 +202,8 @@ addImplicitTypedef("size_t", Context.getSizeType()); } - // Initialize predefined OpenCL types. if (PP.getLangOpts().OpenCL) { - addImplicitTypedef("image1d_t", Context.OCLImage1dTy); - addImplicitTypedef("image1d_array_t", Context.OCLImage1dArrayTy); - addImplicitTypedef("image1d_buffer_t", Context.OCLImage1dBufferTy); - addImplicitTypedef("image2d_t", Context.OCLImage2dTy); - addImplicitTypedef("image2d_array_t", Context.OCLImage2dArrayTy); - addImplicitTypedef("image3d_t", Context.OCLImage3dTy); addImplicitTypedef("sampler_t", Context.OCLSamplerTy); addImplicitTypedef("event_t", Context.OCLEventTy); } Index: lib/Sema/DeclSpec.cpp =================================================================== --- lib/Sema/DeclSpec.cpp +++ lib/Sema/DeclSpec.cpp @@ -309,6 +309,8 @@ case TST_unspecified: case TST_void: case TST_wchar: +#define GENERIC_IMAGE_TYPE(ImgType, Id) case TST_##ImgType##_t: +#include "clang/AST/OpenCLImageTypes.def" return false; case TST_decltype_auto: @@ -474,6 +476,8 @@ case DeclSpec::TST_underlyingType: return "__underlying_type"; case DeclSpec::TST_unknown_anytype: return "__unknown_anytype"; case DeclSpec::TST_atomic: return "_Atomic"; +#define GENERIC_IMAGE_TYPE(ImgType, Id) case DeclSpec::TST_##ImgType##_t: return #ImgType "_t"; +#include "clang/AST/OpenCLImageTypes.def" case DeclSpec::TST_error: return "(error)"; } llvm_unreachable("Unknown typespec!"); Index: lib/Parse/ParseTentative.cpp =================================================================== --- lib/Parse/ParseTentative.cpp +++ lib/Parse/ParseTentative.cpp @@ -993,6 +993,8 @@ case tok::kw___vector: case tok::kw___pixel: case tok::kw__Atomic: +#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t: +#include "clang/AST/OpenCLImageTypes.def" case tok::kw___unknown_anytype: return TPResult::False; Index: lib/Parse/ParseExpr.cpp =================================================================== --- lib/Parse/ParseExpr.cpp +++ lib/Parse/ParseExpr.cpp @@ -1096,7 +1096,10 @@ case tok::kw_void: case tok::kw_typename: case tok::kw_typeof: - case tok::kw___vector: { + case tok::kw___vector: +#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t: +#include "clang/AST/OpenCLImageTypes.def" + { if (!getLangOpts().CPlusPlus) { Diag(Tok, diag::err_expected_expression); return ExprError(); Index: lib/Parse/ParseDecl.cpp =================================================================== --- lib/Parse/ParseDecl.cpp +++ lib/Parse/ParseDecl.cpp @@ -3200,6 +3200,12 @@ case tok::kw___pixel: isInvalid = DS.SetTypeAltiVecPixel(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; +#include "clang/AST/OpenCLImageTypes.def" case tok::kw___unknown_anytype: isInvalid = DS.SetTypeSpecType(TST_unknown_anytype, Loc, PrevSpec, DiagID, Policy); @@ -4085,6 +4091,8 @@ case tok::kw__Decimal64: case tok::kw__Decimal128: case tok::kw___vector: +#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t: +#include "clang/AST/OpenCLImageTypes.def" // struct-or-union-specifier (C99) or class-specifier (C++) case tok::kw_class: @@ -4157,6 +4165,8 @@ case tok::kw__Decimal64: case tok::kw__Decimal128: case tok::kw___vector: +#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t: +#include "clang/AST/OpenCLImageTypes.def" // struct-or-union-specifier (C99) or class-specifier (C++) case tok::kw_class: @@ -4299,6 +4309,8 @@ case tok::kw__Decimal64: case tok::kw__Decimal128: case tok::kw___vector: +#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t: +#include "clang/AST/OpenCLImageTypes.def" // struct-or-union-specifier (C99) or class-specifier (C++) case tok::kw_class: Index: lib/Index/USRGeneration.cpp =================================================================== --- lib/Index/USRGeneration.cpp +++ lib/Index/USRGeneration.cpp @@ -608,12 +608,9 @@ #define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id: #include "clang/AST/BuiltinTypes.def" case BuiltinType::Dependent: - case BuiltinType::OCLImage1d: - case BuiltinType::OCLImage1dArray: - case BuiltinType::OCLImage1dBuffer: - case BuiltinType::OCLImage2d: - case BuiltinType::OCLImage2dArray: - case BuiltinType::OCLImage3d: +#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ + case BuiltinType::Id: +#include "clang/AST/OpenCLImageTypes.def" case BuiltinType::OCLEvent: case BuiltinType::OCLSampler: IgnoreResults = true; Index: lib/CodeGen/ItaniumCXXABI.cpp =================================================================== --- lib/CodeGen/ItaniumCXXABI.cpp +++ lib/CodeGen/ItaniumCXXABI.cpp @@ -2254,12 +2254,9 @@ case BuiltinType::Char32: case BuiltinType::Int128: case BuiltinType::UInt128: - case BuiltinType::OCLImage1d: - case BuiltinType::OCLImage1dArray: - case BuiltinType::OCLImage1dBuffer: - case BuiltinType::OCLImage2d: - case BuiltinType::OCLImage2dArray: - case BuiltinType::OCLImage3d: +#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ + case BuiltinType::Id: +#include "clang/AST/OpenCLImageTypes.def" case BuiltinType::OCLSampler: case BuiltinType::OCLEvent: return true; Index: lib/CodeGen/CodeGenTypes.cpp =================================================================== --- lib/CodeGen/CodeGenTypes.cpp +++ lib/CodeGen/CodeGenTypes.cpp @@ -382,12 +382,9 @@ ResultType = llvm::IntegerType::get(getLLVMContext(), 128); break; - case BuiltinType::OCLImage1d: - case BuiltinType::OCLImage1dArray: - case BuiltinType::OCLImage1dBuffer: - case BuiltinType::OCLImage2d: - case BuiltinType::OCLImage2dArray: - case BuiltinType::OCLImage3d: +#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ + case BuiltinType::Id: +#include "clang/AST/OpenCLImageTypes.def" case BuiltinType::OCLSampler: case BuiltinType::OCLEvent: ResultType = CGM.getOpenCLRuntime().convertOpenCLSpecificType(Ty); Index: lib/CodeGen/CGOpenCLRuntime.cpp =================================================================== --- lib/CodeGen/CGOpenCLRuntime.cpp +++ lib/CodeGen/CGOpenCLRuntime.cpp @@ -40,24 +40,12 @@ default: llvm_unreachable("Unexpected opencl builtin type!"); return nullptr; - case BuiltinType::OCLImage1d: - return llvm::PointerType::get(llvm::StructType::create( - Ctx, "opencl.image1d_t"), ImgAddrSpc); - case BuiltinType::OCLImage1dArray: - return llvm::PointerType::get(llvm::StructType::create( - Ctx, "opencl.image1d_array_t"), ImgAddrSpc); - case BuiltinType::OCLImage1dBuffer: - return llvm::PointerType::get(llvm::StructType::create( - Ctx, "opencl.image1d_buffer_t"), ImgAddrSpc); - case BuiltinType::OCLImage2d: - return llvm::PointerType::get(llvm::StructType::create( - Ctx, "opencl.image2d_t"), ImgAddrSpc); - case BuiltinType::OCLImage2dArray: - return llvm::PointerType::get(llvm::StructType::create( - Ctx, "opencl.image2d_array_t"), ImgAddrSpc); - case BuiltinType::OCLImage3d: - return llvm::PointerType::get(llvm::StructType::create( - Ctx, "opencl.image3d_t"), ImgAddrSpc); +#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ + case BuiltinType::Id: \ + return llvm::PointerType::get(llvm::StructType::create( \ + Ctx, "opencl." #ImgType "_" #Suffix "_t"), \ + ImgAddrSpc); +#include "clang/AST/OpenCLImageTypes.def" case BuiltinType::OCLSampler: return llvm::IntegerType::get(Ctx, 32); case BuiltinType::OCLEvent: Index: lib/CodeGen/CGDebugInfo.h =================================================================== --- lib/CodeGen/CGDebugInfo.h +++ lib/CodeGen/CGDebugInfo.h @@ -58,9 +58,9 @@ llvm::DIType ClassTy; llvm::DICompositeType ObjTy; llvm::DIType SelTy; - llvm::DIType OCLImage1dDITy, OCLImage1dArrayDITy, OCLImage1dBufferDITy; - llvm::DIType OCLImage2dDITy, OCLImage2dArrayDITy; - llvm::DIType OCLImage3dDITy; +#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ + llvm::DIType SingletonId; +#include "clang/AST/OpenCLImageTypes.def" llvm::DIType OCLEventDITy; llvm::DIType BlockLiteralGeneric; Index: lib/CodeGen/CGDebugInfo.cpp =================================================================== --- lib/CodeGen/CGDebugInfo.cpp +++ lib/CodeGen/CGDebugInfo.cpp @@ -428,23 +428,12 @@ getOrCreateMainFile(), 0); return SelTy; } - - case BuiltinType::OCLImage1d: - return getOrCreateStructPtrType("opencl_image1d_t", OCLImage1dDITy); - case BuiltinType::OCLImage1dArray: - return getOrCreateStructPtrType("opencl_image1d_array_t", - OCLImage1dArrayDITy); - case BuiltinType::OCLImage1dBuffer: - return getOrCreateStructPtrType("opencl_image1d_buffer_t", - OCLImage1dBufferDITy); - case BuiltinType::OCLImage2d: - return getOrCreateStructPtrType("opencl_image2d_t", OCLImage2dDITy); - case BuiltinType::OCLImage2dArray: - return getOrCreateStructPtrType("opencl_image2d_array_t", - OCLImage2dArrayDITy); - case BuiltinType::OCLImage3d: - return getOrCreateStructPtrType("opencl_image3d_t", OCLImage3dDITy); - case BuiltinType::OCLSampler: + +#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ + case BuiltinType::Id: \ + return getOrCreateStructPtrType("opencl_" #ImgType "_" #Suffix "_t", SingletonId); +#include "clang/AST/OpenCLImageTypes.def" + case BuiltinType::OCLSampler: return DBuilder.createBasicType( "opencl_sampler_t", CGM.getContext().getTypeSize(BT), CGM.getContext().getTypeAlign(BT), llvm::dwarf::DW_ATE_unsigned); Index: lib/Analysis/PrintfFormatString.cpp =================================================================== --- lib/Analysis/PrintfFormatString.cpp +++ lib/Analysis/PrintfFormatString.cpp @@ -528,7 +528,10 @@ case BuiltinType::Half: // Various types which are non-trivial to correct. return false; - + +#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ + case BuiltinType::Id: +#include "clang/AST/OpenCLImageTypes.def" #define SIGNED_TYPE(Id, SingletonId) #define UNSIGNED_TYPE(Id, SingletonId) #define FLOATING_TYPE(Id, SingletonId) Index: lib/AST/TypeLoc.cpp =================================================================== --- lib/AST/TypeLoc.cpp +++ lib/AST/TypeLoc.cpp @@ -291,12 +291,9 @@ case BuiltinType::ObjCId: case BuiltinType::ObjCClass: case BuiltinType::ObjCSel: - case BuiltinType::OCLImage1d: - case BuiltinType::OCLImage1dArray: - case BuiltinType::OCLImage1dBuffer: - case BuiltinType::OCLImage2d: - case BuiltinType::OCLImage2dArray: - case BuiltinType::OCLImage3d: +#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ + case BuiltinType::Id: +#include "clang/AST/OpenCLImageTypes.def" case BuiltinType::OCLSampler: case BuiltinType::OCLEvent: case BuiltinType::BuiltinFn: Index: lib/AST/Type.cpp =================================================================== --- lib/AST/Type.cpp +++ lib/AST/Type.cpp @@ -1545,12 +1545,9 @@ case ObjCId: return "id"; case ObjCClass: return "Class"; case ObjCSel: return "SEL"; - case OCLImage1d: return "image1d_t"; - case OCLImage1dArray: return "image1d_array_t"; - case OCLImage1dBuffer: return "image1d_buffer_t"; - case OCLImage2d: return "image2d_t"; - case OCLImage2dArray: return "image2d_array_t"; - case OCLImage3d: return "image3d_t"; +#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ + case Id: return "__" #Access " " #ImgType"_t"; +#include "clang/AST/OpenCLImageTypes.def" case OCLSampler: return "sampler_t"; case OCLEvent: return "event_t"; } Index: lib/AST/NSAPI.cpp =================================================================== --- lib/AST/NSAPI.cpp +++ lib/AST/NSAPI.cpp @@ -349,12 +349,9 @@ case BuiltinType::ObjCClass: case BuiltinType::ObjCId: case BuiltinType::ObjCSel: - case BuiltinType::OCLImage1d: - case BuiltinType::OCLImage1dArray: - case BuiltinType::OCLImage1dBuffer: - case BuiltinType::OCLImage2d: - case BuiltinType::OCLImage2dArray: - case BuiltinType::OCLImage3d: +#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ + case BuiltinType::Id: +#include "clang/AST/OpenCLImageTypes.def" case BuiltinType::OCLSampler: case BuiltinType::OCLEvent: case BuiltinType::BoundMember: Index: lib/AST/MicrosoftMangle.cpp =================================================================== --- lib/AST/MicrosoftMangle.cpp +++ lib/AST/MicrosoftMangle.cpp @@ -1501,12 +1501,9 @@ case BuiltinType::ObjCClass: Out << "PAUobjc_class@@"; break; case BuiltinType::ObjCSel: Out << "PAUobjc_selector@@"; break; - case BuiltinType::OCLImage1d: Out << "PAUocl_image1d@@"; break; - case BuiltinType::OCLImage1dArray: Out << "PAUocl_image1darray@@"; break; - case BuiltinType::OCLImage1dBuffer: Out << "PAUocl_image1dbuffer@@"; break; - case BuiltinType::OCLImage2d: Out << "PAUocl_image2d@@"; break; - case BuiltinType::OCLImage2dArray: Out << "PAUocl_image2darray@@"; break; - case BuiltinType::OCLImage3d: Out << "PAUocl_image3d@@"; break; +#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ + case BuiltinType::Id: Out << "PAUocl_" #ImgType "_" #Suffix "@@"; break; +#include "clang/AST/OpenCLImageTypes.def" case BuiltinType::OCLSampler: Out << "PAUocl_sampler@@"; break; case BuiltinType::OCLEvent: Out << "PAUocl_event@@"; break; Index: lib/AST/ItaniumMangle.cpp =================================================================== --- lib/AST/ItaniumMangle.cpp +++ lib/AST/ItaniumMangle.cpp @@ -1952,6 +1952,7 @@ // ::= Ds # char16_t // ::= Dn # std::nullptr_t (i.e., decltype(nullptr)) // ::= u <source-name> # vendor extended type + std::string type_name; switch (T->getKind()) { case BuiltinType::Void: Out << 'v'; break; case BuiltinType::Bool: Out << 'b'; break; @@ -1987,12 +1988,10 @@ case BuiltinType::ObjCId: Out << "11objc_object"; break; case BuiltinType::ObjCClass: Out << "10objc_class"; break; case BuiltinType::ObjCSel: Out << "13objc_selector"; break; - case BuiltinType::OCLImage1d: Out << "11ocl_image1d"; break; - case BuiltinType::OCLImage1dArray: Out << "16ocl_image1darray"; break; - case BuiltinType::OCLImage1dBuffer: Out << "17ocl_image1dbuffer"; break; - case BuiltinType::OCLImage2d: Out << "11ocl_image2d"; break; - case BuiltinType::OCLImage2dArray: Out << "16ocl_image2darray"; break; - case BuiltinType::OCLImage3d: Out << "11ocl_image3d"; break; +#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ + case BuiltinType::Id: type_name = "ocl_" #ImgType "_" #Suffix; \ + Out << type_name.size() << type_name; break; +#include "clang/AST/OpenCLImageTypes.def" case BuiltinType::OCLSampler: Out << "11ocl_sampler"; break; case BuiltinType::OCLEvent: Out << "9ocl_event"; break; } Index: lib/AST/ASTImporter.cpp =================================================================== --- lib/AST/ASTImporter.cpp +++ lib/AST/ASTImporter.cpp @@ -1428,6 +1428,9 @@ QualType ASTNodeImporter::VisitBuiltinType(const BuiltinType *T) { switch (T->getKind()) { +#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ + case BuiltinType::Id: return Importer.getToContext().SingletonId; +#include "clang/AST/OpenCLImageTypes.def" #define SHARED_SINGLETON_TYPE(Expansion) #define BUILTIN_TYPE(Id, SingletonId) \ case BuiltinType::Id: return Importer.getToContext().SingletonId; Index: lib/AST/ASTContext.cpp =================================================================== --- lib/AST/ASTContext.cpp +++ lib/AST/ASTContext.cpp @@ -1018,13 +1018,10 @@ InitBuiltinType(ObjCBuiltinClassTy, BuiltinType::ObjCClass); InitBuiltinType(ObjCBuiltinSelTy, BuiltinType::ObjCSel); - if (LangOpts.OpenCL) { - InitBuiltinType(OCLImage1dTy, BuiltinType::OCLImage1d); - InitBuiltinType(OCLImage1dArrayTy, BuiltinType::OCLImage1dArray); - InitBuiltinType(OCLImage1dBufferTy, BuiltinType::OCLImage1dBuffer); - InitBuiltinType(OCLImage2dTy, BuiltinType::OCLImage2d); - InitBuiltinType(OCLImage2dArrayTy, BuiltinType::OCLImage2dArray); - InitBuiltinType(OCLImage3dTy, BuiltinType::OCLImage3d); + if (LangOpts.OpenCL) { +#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ + InitBuiltinType(SingletonId, BuiltinType::Id); +#include "clang/AST/OpenCLImageTypes.def" InitBuiltinType(OCLSamplerTy, BuiltinType::OCLSampler); InitBuiltinType(OCLEventTy, BuiltinType::OCLEvent); @@ -1594,12 +1591,9 @@ Align = Target->getIntAlign(); break; case BuiltinType::OCLEvent: - case BuiltinType::OCLImage1d: - case BuiltinType::OCLImage1dArray: - case BuiltinType::OCLImage1dBuffer: - case BuiltinType::OCLImage2d: - case BuiltinType::OCLImage2dArray: - case BuiltinType::OCLImage3d: +#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ + case BuiltinType::Id: +#include "clang/AST/OpenCLImageTypes.def" // Currently these types are pointers to opaque types. Width = Target->getPointerWidth(0); Align = Target->getPointerAlign(0); @@ -5225,12 +5219,9 @@ llvm_unreachable("@encoding ObjC primitive type"); // OpenCL and placeholder types don't need @encodings. - case BuiltinType::OCLImage1d: - case BuiltinType::OCLImage1dArray: - case BuiltinType::OCLImage1dBuffer: - case BuiltinType::OCLImage2d: - case BuiltinType::OCLImage2dArray: - case BuiltinType::OCLImage3d: +#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ + case BuiltinType::Id: +#include "clang/AST/OpenCLImageTypes.def" case BuiltinType::OCLEvent: case BuiltinType::OCLSampler: case BuiltinType::Dependent: Index: include/clang/Serialization/ASTBitCodes.h =================================================================== --- include/clang/Serialization/ASTBitCodes.h +++ include/clang/Serialization/ASTBitCodes.h @@ -749,22 +749,14 @@ PREDEF_TYPE_VA_LIST_TAG = 36, /// \brief The placeholder type for builtin functions. PREDEF_TYPE_BUILTIN_FN = 37, - /// \brief OpenCL 1d image type. - PREDEF_TYPE_IMAGE1D_ID = 38, - /// \brief OpenCL 1d image array type. - PREDEF_TYPE_IMAGE1D_ARR_ID = 39, - /// \brief OpenCL 1d image buffer type. - PREDEF_TYPE_IMAGE1D_BUFF_ID = 40, - /// \brief OpenCL 2d image type. - PREDEF_TYPE_IMAGE2D_ID = 41, - /// \brief OpenCL 2d image array type. - PREDEF_TYPE_IMAGE2D_ARR_ID = 42, - /// \brief OpenCL 3d image type. - PREDEF_TYPE_IMAGE3D_ID = 43, /// \brief OpenCL event type. - PREDEF_TYPE_EVENT_ID = 44, + PREDEF_TYPE_EVENT_ID = 38, /// \brief OpenCL sampler type. - PREDEF_TYPE_SAMPLER_ID = 45 + PREDEF_TYPE_SAMPLER_ID = 39, + /// \brief OpenCL image types with auto numeration +#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ + PREDEF_TYPE_##Id##_ID, +#include "clang/AST/OpenCLImageTypes.def" }; /// \brief The number of predefined type IDs that are reserved for Index: include/clang/Sema/DeclSpec.h =================================================================== --- include/clang/Sema/DeclSpec.h +++ include/clang/Sema/DeclSpec.h @@ -302,6 +302,9 @@ static const TST TST_auto = clang::TST_auto; static const TST TST_unknown_anytype = clang::TST_unknown_anytype; static const TST TST_atomic = clang::TST_atomic; +#define GENERIC_IMAGE_TYPE(ImgType, Id) \ + static const TST TST_##ImgType##_t = clang::TST_##ImgType##_t; +#include "clang/AST/OpenCLImageTypes.def" static const TST TST_error = clang::TST_error; // type-qualifiers Index: include/clang/Basic/TokenKinds.def =================================================================== --- include/clang/Basic/TokenKinds.def +++ include/clang/Basic/TokenKinds.def @@ -490,6 +490,8 @@ // OpenCL builtins KEYWORD(__builtin_astype , KEYOPENCL) KEYWORD(vec_step , KEYOPENCL|KEYALTIVEC) +#define GENERIC_IMAGE_TYPE(ImgType, Id) KEYWORD(ImgType##_t, KEYOPENCL) +#include "clang/AST/OpenCLImageTypes.def" // Borland Extensions. KEYWORD(__pascal , KEYALL) Index: include/clang/Basic/Specifiers.h =================================================================== --- include/clang/Basic/Specifiers.h +++ include/clang/Basic/Specifiers.h @@ -63,6 +63,8 @@ TST_decltype_auto, // C++1y decltype(auto) TST_unknown_anytype, // __unknown_anytype extension TST_atomic, // C11 _Atomic +#define GENERIC_IMAGE_TYPE(ImgType, Id) TST_##ImgType##_t, // OpenCL image types +#include "clang/AST/OpenCLImageTypes.def" TST_error // erroneous type }; Index: include/clang/AST/Type.h =================================================================== --- include/clang/AST/Type.h +++ include/clang/AST/Type.h @@ -1592,12 +1592,10 @@ bool isNullPtrType() const; // C++0x nullptr_t bool isAtomicType() const; // C11 _Atomic() - bool isImage1dT() const; // OpenCL image1d_t - bool isImage1dArrayT() const; // OpenCL image1d_array_t - bool isImage1dBufferT() const; // OpenCL image1d_buffer_t - bool isImage2dT() const; // OpenCL image2d_t - bool isImage2dArrayT() const; // OpenCL image2d_array_t - bool isImage3dT() const; // OpenCL image3d_t + +#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ + bool is##Id##Type() const; +#include "clang/AST/OpenCLImageTypes.def" bool isImageType() const; // Any OpenCL image type @@ -1860,6 +1858,10 @@ class BuiltinType : public Type { public: enum Kind { +// OpenCL image types +#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) Id, +#include "clang/AST/OpenCLImageTypes.def" +// All other builtin types #define BUILTIN_TYPE(Id, SingletonId) Id, #define LAST_BUILTIN_TYPE(Id) LastKind = Id #include "clang/AST/BuiltinTypes.def" @@ -5044,29 +5046,11 @@ return isObjCIdType() || isObjCClassType() || isObjCSelType(); } -inline bool Type::isImage1dT() const { - return isSpecificBuiltinType(BuiltinType::OCLImage1d); -} - -inline bool Type::isImage1dArrayT() const { - return isSpecificBuiltinType(BuiltinType::OCLImage1dArray); -} - -inline bool Type::isImage1dBufferT() const { - return isSpecificBuiltinType(BuiltinType::OCLImage1dBuffer); -} - -inline bool Type::isImage2dT() const { - return isSpecificBuiltinType(BuiltinType::OCLImage2d); -} - -inline bool Type::isImage2dArrayT() const { - return isSpecificBuiltinType(BuiltinType::OCLImage2dArray); -} - -inline bool Type::isImage3dT() const { - return isSpecificBuiltinType(BuiltinType::OCLImage3d); +#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ +inline bool Type::is##Id##Type() const { \ + return isSpecificBuiltinType(BuiltinType::Id); \ } +#include "clang/AST/OpenCLImageTypes.def" inline bool Type::isSamplerT() const { return isSpecificBuiltinType(BuiltinType::OCLSampler); @@ -5077,9 +5061,12 @@ } inline bool Type::isImageType() const { - return isImage3dT() || - isImage2dT() || isImage2dArrayT() || - isImage1dT() || isImage1dArrayT() || isImage1dBufferT(); +#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ + is##Id##Type() || + return +#include "clang/AST/OpenCLImageTypes.def" + 0; // end boolean or operation + } inline bool Type::isOpenCLSpecificType() const { Index: include/clang/AST/OpenCLImageTypes.def =================================================================== --- /dev/null +++ include/clang/AST/OpenCLImageTypes.def @@ -0,0 +1,64 @@ +//===-- OpenCLImageTypes.def - Metadata about BuiltinTypes ------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// This file extends builtin types database with OpenCL image singleton types. +// Custom code should define one of those two macros: +// GENERIC_IMAGE_TYPE(Type, Id) - a generic image with its Id without an +// access type +// IMAGE_TYPE(Type, Id, SingletonId, AccessType, CGSuffix) - an image type +// with given ID, singleton ID access type and a codegen suffix + +#ifdef GENERIC_IMAGE_TYPE + +#define IMAGE_READ_TYPE(Type, Id) GENERIC_IMAGE_TYPE(Type, Id) +#define IMAGE_WRITE_TYPE(Type, Id) +#define IMAGE_READ_WRITE_TYPE(Type, Id) + +#else + +#ifndef IMAGE_READ_TYPE +#define IMAGE_READ_TYPE(Type, Id) \ + IMAGE_TYPE(Type, Id##RO, Id##ROTy, read_only, ro) +#endif +#ifndef IMAGE_WRITE_TYPE +#define IMAGE_WRITE_TYPE(Type, Id) \ + IMAGE_TYPE(Type, Id##WO, Id##WOTy, write_only, wo) +#endif +#ifndef IMAGE_READ_WRITE_TYPE +#define IMAGE_READ_WRITE_TYPE(Type, Id) \ + IMAGE_TYPE(Type, Id##RW, Id##RWTy, read_write, rw) +#endif + +#endif + +IMAGE_READ_TYPE(image1d, OCLImage1d) +IMAGE_READ_TYPE(image1d_array, OCLImage1dArray) +IMAGE_READ_TYPE(image1d_buffer, OCLImage1dBuffer) +IMAGE_READ_TYPE(image2d, OCLImage2d) +IMAGE_READ_TYPE(image2d_array, OCLImage2dArray) +IMAGE_READ_TYPE(image3d, OCLImage3d) + +IMAGE_WRITE_TYPE(image1d, OCLImage1d) +IMAGE_WRITE_TYPE(image1d_array, OCLImage1dArray) +IMAGE_WRITE_TYPE(image1d_buffer, OCLImage1dBuffer) +IMAGE_WRITE_TYPE(image2d, OCLImage2d) +IMAGE_WRITE_TYPE(image2d_array, OCLImage2dArray) +IMAGE_WRITE_TYPE(image3d, OCLImage3d) + +IMAGE_READ_WRITE_TYPE(image1d, OCLImage1d) +IMAGE_READ_WRITE_TYPE(image1d_array, OCLImage1dArray) +IMAGE_READ_WRITE_TYPE(image1d_buffer, OCLImage1dBuffer) +IMAGE_READ_WRITE_TYPE(image2d, OCLImage2d) +IMAGE_READ_WRITE_TYPE(image2d_array, OCLImage2dArray) +IMAGE_READ_WRITE_TYPE(image3d, OCLImage3d) + +#undef IMAGE_TYPE +#undef GENERIC_IMAGE_TYPE +#undef IMAGE_READ_TYPE +#undef IMAGE_WRITE_TYPE +#undef IMAGE_READ_WRITE_TYPE \ No newline at end of file Index: include/clang/AST/BuiltinTypes.def =================================================================== --- include/clang/AST/BuiltinTypes.def +++ include/clang/AST/BuiltinTypes.def @@ -154,14 +154,6 @@ // type is a typedef of a PointerType to this. BUILTIN_TYPE(ObjCSel, ObjCBuiltinSelTy) -// OpenCL image types. -BUILTIN_TYPE(OCLImage1d, OCLImage1dTy) -BUILTIN_TYPE(OCLImage1dArray, OCLImage1dArrayTy) -BUILTIN_TYPE(OCLImage1dBuffer, OCLImage1dBufferTy) -BUILTIN_TYPE(OCLImage2d, OCLImage2dTy) -BUILTIN_TYPE(OCLImage2dArray, OCLImage2dArrayTy) -BUILTIN_TYPE(OCLImage3d, OCLImage3dTy) - // OpenCL sampler_t. BUILTIN_TYPE(OCLSampler, OCLSamplerTy) Index: include/clang/AST/ASTContext.h =================================================================== --- include/clang/AST/ASTContext.h +++ include/clang/AST/ASTContext.h @@ -804,9 +804,9 @@ CanQualType PseudoObjectTy, ARCUnbridgedCastTy; CanQualType ObjCBuiltinIdTy, ObjCBuiltinClassTy, ObjCBuiltinSelTy; CanQualType ObjCBuiltinBoolTy; - CanQualType OCLImage1dTy, OCLImage1dArrayTy, OCLImage1dBufferTy; - CanQualType OCLImage2dTy, OCLImage2dArrayTy; - CanQualType OCLImage3dTy; +#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ + CanQualType SingletonId; +#include "clang/AST/OpenCLImageTypes.def" CanQualType OCLSamplerTy, OCLEventTy; // Types for deductions in C++0x [stmt.ranged]'s desugaring. Built on demand.
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits