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. 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/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/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/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/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/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/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: 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: 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/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 # 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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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 \ + (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/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/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: 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: 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/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/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: 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)