From 610541989a524be452a5674cd3fb78304ce3fa8a Mon Sep 17 00:00:00 2001 From: Guy Benyei Date: Thu, 7 Feb 2013 10:55:47 +0000 Subject: [PATCH] Add OpenCL samplers as Clang builtin types and check sampler related restrictions. llvm-svn: 174601 --- clang/include/clang/AST/ASTContext.h | 2 +- clang/include/clang/AST/BuiltinTypes.def | 3 ++ clang/include/clang/AST/Type.h | 8 ++++- clang/include/clang/Basic/DiagnosticSemaKinds.td | 4 +++ clang/include/clang/Basic/Specifiers.h | 1 + clang/include/clang/Basic/TokenKinds.def | 1 + clang/include/clang/Sema/DeclSpec.h | 1 + clang/include/clang/Sema/Initialization.h | 6 ++++ clang/include/clang/Serialization/ASTBitCodes.h | 5 ++- clang/lib/AST/ASTContext.cpp | 7 ++++ clang/lib/AST/ItaniumMangle.cpp | 1 + clang/lib/AST/MicrosoftMangle.cpp | 1 + clang/lib/AST/NSAPI.cpp | 1 + clang/lib/AST/Type.cpp | 1 + clang/lib/AST/TypeLoc.cpp | 1 + clang/lib/CodeGen/CGDebugInfo.cpp | 5 +++ clang/lib/CodeGen/CGOpenCLRuntime.cpp | 2 ++ clang/lib/CodeGen/CGRTTI.cpp | 1 + clang/lib/CodeGen/CodeGenTypes.cpp | 1 + clang/lib/Parse/ParseDecl.cpp | 7 ++++ clang/lib/Parse/ParseExpr.cpp | 1 + clang/lib/Parse/ParseTentative.cpp | 1 + clang/lib/Sema/DeclSpec.cpp | 2 ++ clang/lib/Sema/SemaDecl.cpp | 8 +++++ clang/lib/Sema/SemaInit.cpp | 46 +++++++++++++++++++++++- clang/lib/Sema/SemaOverload.cpp | 4 ++- clang/lib/Sema/SemaTemplateVariadic.cpp | 1 + clang/lib/Sema/SemaType.cpp | 4 +++ clang/lib/Serialization/ASTCommon.cpp | 1 + clang/lib/Serialization/ASTReader.cpp | 1 + clang/test/CodeGenOpenCL/opencl_types.cl | 13 +++++++ clang/test/PCH/ocl_types.cl | 4 +++ clang/test/PCH/ocl_types.h | 3 ++ clang/test/SemaOpenCL/sampler_t.cl | 13 +++++++ clang/test/SemaOpenCL/sampler_t_overload.cl | 12 +++++++ clang/tools/libclang/CIndexUSRs.cpp | 1 + 36 files changed, 169 insertions(+), 5 deletions(-) create mode 100644 clang/test/SemaOpenCL/sampler_t.cl create mode 100644 clang/test/SemaOpenCL/sampler_t_overload.cl diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index eb14ff5..0e8f2b6 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -721,7 +721,7 @@ public: CanQualType OCLImage1dTy, OCLImage1dArrayTy, OCLImage1dBufferTy; CanQualType OCLImage2dTy, OCLImage2dArrayTy; CanQualType OCLImage3dTy; - CanQualType OCLEventTy; + CanQualType OCLSamplerTy, OCLEventTy; // Types for deductions in C++0x [stmt.ranged]'s desugaring. Built on demand. mutable QualType AutoDeductTy; // Deduction against 'auto'. diff --git a/clang/include/clang/AST/BuiltinTypes.def b/clang/include/clang/AST/BuiltinTypes.def index 503d963..488cace 100644 --- a/clang/include/clang/AST/BuiltinTypes.def +++ b/clang/include/clang/AST/BuiltinTypes.def @@ -162,6 +162,9 @@ BUILTIN_TYPE(OCLImage2d, OCLImage2dTy) BUILTIN_TYPE(OCLImage2dArray, OCLImage2dArrayTy) BUILTIN_TYPE(OCLImage3d, OCLImage3dTy) +// OpenCL sampler_t. +BUILTIN_TYPE(OCLSampler, OCLSamplerTy) + // OpenCL event_t. BUILTIN_TYPE(OCLEvent, OCLEventTy) diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index 1469746..3e6297a 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -1584,6 +1584,7 @@ public: bool isImageType() const; // Any OpenCL image type + bool isSamplerT() const; // OpenCL sampler_t bool isEventT() const; // OpenCL event_t bool isOpenCLSpecificType() const; // Any OpenCL specific type @@ -4918,6 +4919,11 @@ inline bool Type::isImage2dArrayT() const { inline bool Type::isImage3dT() const { return isSpecificBuiltinType(BuiltinType::OCLImage3d); } + +inline bool Type::isSamplerT() const { + return isSpecificBuiltinType(BuiltinType::OCLSampler); +} + inline bool Type::isEventT() const { return isSpecificBuiltinType(BuiltinType::OCLEvent); } @@ -4929,7 +4935,7 @@ inline bool Type::isImageType() const { } inline bool Type::isOpenCLSpecificType() const { - return isImageType() || isEventT(); + return isSamplerT() || isEventT() || isImageType(); } inline bool Type::isTemplateTypeParmType() const { diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index bcc33d1..e190d7b 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -6139,6 +6139,10 @@ def err_event_t_addr_space_qual : Error< "the event_t type can only be used with __private address space qualifier">; def err_expected_kernel_void_return_type : Error< "kernel must have void return type">; +def err_sampler_argument_required : Error< + "sampler_t variable required - got %0">; +def err_wrong_sampler_addressspace: Error< + "sampler type cannot be used with the __local and __global address space qualifiers">; } // end of sema category diff --git a/clang/include/clang/Basic/Specifiers.h b/clang/include/clang/Basic/Specifiers.h index 533cefe..8706179 100644 --- a/clang/include/clang/Basic/Specifiers.h +++ b/clang/include/clang/Basic/Specifiers.h @@ -68,6 +68,7 @@ namespace clang { TST_image2d_t, // OpenCL image2d_t TST_image2d_array_t, // OpenCL image2d_array_t TST_image3d_t, // OpenCL image3d_t + TST_sampler_t, // OpenCL sampler_t TST_event_t, // OpenCL event_t TST_error // erroneous type }; diff --git a/clang/include/clang/Basic/TokenKinds.def b/clang/include/clang/Basic/TokenKinds.def index 8008ca6..6850bd5 100644 --- a/clang/include/clang/Basic/TokenKinds.def +++ b/clang/include/clang/Basic/TokenKinds.def @@ -455,6 +455,7 @@ KEYWORD(image1d_buffer_t , KEYOPENCL) KEYWORD(image2d_t , KEYOPENCL) KEYWORD(image2d_array_t , KEYOPENCL) KEYWORD(image3d_t , KEYOPENCL) +KEYWORD(sampler_t , KEYOPENCL) KEYWORD(event_t , KEYOPENCL) // Borland Extensions. diff --git a/clang/include/clang/Sema/DeclSpec.h b/clang/include/clang/Sema/DeclSpec.h index fc43ed6..867c654 100644 --- a/clang/include/clang/Sema/DeclSpec.h +++ b/clang/include/clang/Sema/DeclSpec.h @@ -282,6 +282,7 @@ public: static const TST TST_image2d_t = clang::TST_image2d_t; static const TST TST_image2d_array_t = clang::TST_image2d_array_t; static const TST TST_image3d_t = clang::TST_image3d_t; + static const TST TST_sampler_t = clang::TST_sampler_t; static const TST TST_event_t = clang::TST_event_t; static const TST TST_error = clang::TST_error; diff --git a/clang/include/clang/Sema/Initialization.h b/clang/include/clang/Sema/Initialization.h index 002a126..e177374 100644 --- a/clang/include/clang/Sema/Initialization.h +++ b/clang/include/clang/Sema/Initialization.h @@ -625,6 +625,8 @@ public: SK_ProduceObjCObject, /// \brief Construct a std::initializer_list from an initializer list. SK_StdInitializerList, + /// \brief Initialize an OpenCL sampler from an integer. + SK_OCLSamplerInit, /// \brief Passing zero to a function where OpenCL event_t is expected. SK_OCLZeroEvent }; @@ -955,6 +957,10 @@ public: /// initializer list. void AddStdInitializerListConstructionStep(QualType T); + /// \brief Add a step to initialize an OpenCL sampler from an integer + /// constant. + void AddOCLSamplerInitStep(QualType T); + /// \brief Add a step to initialize an OpenCL event_t from a NULL /// constant. void AddOCLZeroEventStep(QualType T); diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h index 6f76367..a672c7e 100644 --- a/clang/include/clang/Serialization/ASTBitCodes.h +++ b/clang/include/clang/Serialization/ASTBitCodes.h @@ -720,7 +720,10 @@ namespace clang { PREDEF_TYPE_IMAGE2D_ARR_ID = 42, /// \brief OpenCL 3d image type. PREDEF_TYPE_IMAGE3D_ID = 43, - PREDEF_TYPE_EVENT_ID = 44 + /// \brief OpenCL event type. + PREDEF_TYPE_EVENT_ID = 44, + /// \brief OpenCL sampler type. + PREDEF_TYPE_SAMPLER_ID = 45 }; /// \brief The number of predefined type IDs that are reserved for diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index f97e6e9..bdb464c 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -906,6 +906,7 @@ void ASTContext::InitBuiltinTypes(const TargetInfo &Target) { InitBuiltinType(OCLImage2dArrayTy, BuiltinType::OCLImage2dArray); InitBuiltinType(OCLImage3dTy, BuiltinType::OCLImage3d); + InitBuiltinType(OCLSamplerTy, BuiltinType::OCLSampler); InitBuiltinType(OCLEventTy, BuiltinType::OCLEvent); } @@ -1448,6 +1449,11 @@ ASTContext::getTypeInfoImpl(const Type *T) const { Width = Target->getPointerWidth(0); Align = Target->getPointerAlign(0); break; + case BuiltinType::OCLSampler: + // Samplers are modeled as integers. + Width = Target->getIntWidth(); + Align = Target->getIntAlign(); + break; case BuiltinType::OCLEvent: case BuiltinType::OCLImage1d: case BuiltinType::OCLImage1dArray: @@ -4923,6 +4929,7 @@ static char getObjCEncodingForPrimitiveKind(const ASTContext *C, case BuiltinType::OCLImage2dArray: case BuiltinType::OCLImage3d: case BuiltinType::OCLEvent: + case BuiltinType::OCLSampler: case BuiltinType::Dependent: #define BUILTIN_TYPE(KIND, ID) #define PLACEHOLDER_TYPE(KIND, ID) \ diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index 926384d..792bda6 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -1886,6 +1886,7 @@ void CXXNameMangler::mangleType(const BuiltinType *T) { case BuiltinType::OCLImage2d: Out << "11ocl_image2d"; break; case BuiltinType::OCLImage2dArray: Out << "16ocl_image2darray"; break; case BuiltinType::OCLImage3d: Out << "11ocl_image3d"; break; + case BuiltinType::OCLSampler: Out << "11ocl_sampler"; break; case BuiltinType::OCLEvent: Out << "9ocl_event"; break; } } diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp index 0b77ac8..326b0d3 100644 --- a/clang/lib/AST/MicrosoftMangle.cpp +++ b/clang/lib/AST/MicrosoftMangle.cpp @@ -1060,6 +1060,7 @@ void MicrosoftCXXNameMangler::mangleType(const BuiltinType *T, case BuiltinType::OCLImage2d: Out << "PAUocl_image2d@@"; break; case BuiltinType::OCLImage2dArray: Out << "PAUocl_image2darray@@"; break; case BuiltinType::OCLImage3d: Out << "PAUocl_image3d@@"; break; + case BuiltinType::OCLSampler: Out << "PAUocl_sampler@@"; break; case BuiltinType::OCLEvent: Out << "PAUocl_event@@"; break; case BuiltinType::NullPtr: Out << "$$T"; break; diff --git a/clang/lib/AST/NSAPI.cpp b/clang/lib/AST/NSAPI.cpp index c8cf920..4c20235 100644 --- a/clang/lib/AST/NSAPI.cpp +++ b/clang/lib/AST/NSAPI.cpp @@ -351,6 +351,7 @@ NSAPI::getNSNumberFactoryMethodKind(QualType T) const { case BuiltinType::OCLImage2d: case BuiltinType::OCLImage2dArray: case BuiltinType::OCLImage3d: + case BuiltinType::OCLSampler: case BuiltinType::OCLEvent: case BuiltinType::BoundMember: case BuiltinType::Dependent: diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index 524d005..efd588a 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -1518,6 +1518,7 @@ StringRef BuiltinType::getName(const PrintingPolicy &Policy) const { case OCLImage2d: return "image2d_t"; case OCLImage2dArray: return "image2d_array_t"; case OCLImage3d: return "image3d_t"; + case OCLSampler: return "sampler_t"; case OCLEvent: return "event_t"; } diff --git a/clang/lib/AST/TypeLoc.cpp b/clang/lib/AST/TypeLoc.cpp index 3efa148..010ea2d 100644 --- a/clang/lib/AST/TypeLoc.cpp +++ b/clang/lib/AST/TypeLoc.cpp @@ -268,6 +268,7 @@ TypeSpecifierType BuiltinTypeLoc::getWrittenTypeSpec() const { case BuiltinType::OCLImage2d: case BuiltinType::OCLImage2dArray: case BuiltinType::OCLImage3d: + case BuiltinType::OCLSampler: case BuiltinType::OCLEvent: case BuiltinType::BuiltinFn: return TST_unspecified; diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index 5e60bd8..a4153d3 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -426,6 +426,11 @@ llvm::DIType CGDebugInfo::CreateType(const BuiltinType *BT) { case BuiltinType::OCLImage3d: return getOrCreateStructPtrType("opencl_image3d_t", OCLImage3dDITy); + case BuiltinType::OCLSampler: + return DBuilder.createBasicType("opencl_sampler_t", + CGM.getContext().getTypeSize(BT), + CGM.getContext().getTypeAlign(BT), + llvm::dwarf::DW_ATE_unsigned); case BuiltinType::OCLEvent: return getOrCreateStructPtrType("opencl_event_t", OCLEventDITy); diff --git a/clang/lib/CodeGen/CGOpenCLRuntime.cpp b/clang/lib/CodeGen/CGOpenCLRuntime.cpp index 215d096..7c454ac 100644 --- a/clang/lib/CodeGen/CGOpenCLRuntime.cpp +++ b/clang/lib/CodeGen/CGOpenCLRuntime.cpp @@ -55,6 +55,8 @@ llvm::Type *CGOpenCLRuntime::convertOpenCLSpecificType(const Type *T) { case BuiltinType::OCLImage3d: return llvm::PointerType::get(llvm::StructType::create( CGM.getLLVMContext(), "opencl.image3d_t"), 0); + case BuiltinType::OCLSampler: + return llvm::IntegerType::get(CGM.getLLVMContext(),32); case BuiltinType::OCLEvent: return llvm::PointerType::get(llvm::StructType::create( CGM.getLLVMContext(), "opencl.event_t"), 0); diff --git a/clang/lib/CodeGen/CGRTTI.cpp b/clang/lib/CodeGen/CGRTTI.cpp index 366ce29..869843c 100644 --- a/clang/lib/CodeGen/CGRTTI.cpp +++ b/clang/lib/CodeGen/CGRTTI.cpp @@ -197,6 +197,7 @@ static bool TypeInfoIsInStandardLibrary(const BuiltinType *Ty) { case BuiltinType::OCLImage2d: case BuiltinType::OCLImage2dArray: case BuiltinType::OCLImage3d: + case BuiltinType::OCLSampler: case BuiltinType::OCLEvent: return true; diff --git a/clang/lib/CodeGen/CodeGenTypes.cpp b/clang/lib/CodeGen/CodeGenTypes.cpp index e78cbab..c82e1d8 100644 --- a/clang/lib/CodeGen/CodeGenTypes.cpp +++ b/clang/lib/CodeGen/CodeGenTypes.cpp @@ -378,6 +378,7 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) { case BuiltinType::OCLImage2d: case BuiltinType::OCLImage2dArray: case BuiltinType::OCLImage3d: + case BuiltinType::OCLSampler: case BuiltinType::OCLEvent: ResultType = CGM.getOpenCLRuntime().convertOpenCLSpecificType(Ty); break; diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index e11fb91..8e24a14 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -2781,6 +2781,10 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, isInvalid = DS.SetTypeSpecType(DeclSpec::TST_image3d_t, Loc, PrevSpec, DiagID); break; + case tok::kw_sampler_t: + isInvalid = DS.SetTypeSpecType(DeclSpec::TST_sampler_t, Loc, + PrevSpec, DiagID); + break; case tok::kw_event_t: isInvalid = DS.SetTypeSpecType(DeclSpec::TST_event_t, Loc, PrevSpec, DiagID); @@ -3635,6 +3639,7 @@ bool Parser::isKnownToBeTypeSpecifier(const Token &Tok) const { case tok::kw_image2d_t: case tok::kw_image2d_array_t: case tok::kw_image3d_t: + case tok::kw_sampler_t: case tok::kw_event_t: // struct-or-union-specifier (C99) or class-specifier (C++) @@ -3716,6 +3721,7 @@ bool Parser::isTypeSpecifierQualifier() { case tok::kw_image2d_t: case tok::kw_image2d_array_t: case tok::kw_image3d_t: + case tok::kw_sampler_t: case tok::kw_event_t: // struct-or-union-specifier (C99) or class-specifier (C++) @@ -3869,6 +3875,7 @@ bool Parser::isDeclarationSpecifier(bool DisambiguatingWithExpression) { case tok::kw_image2d_t: case tok::kw_image2d_array_t: case tok::kw_image3d_t: + case tok::kw_sampler_t: case tok::kw_event_t: // struct-or-union-specifier (C99) or class-specifier (C++) diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp index 4ed0bd0..7775909 100644 --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/lib/Parse/ParseExpr.cpp @@ -1024,6 +1024,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression, case tok::kw_image2d_t: case tok::kw_image2d_array_t: case tok::kw_image3d_t: + case tok::kw_sampler_t: case tok::kw_event_t: { if (!getLangOpts().CPlusPlus) { Diag(Tok, diag::err_expected_expression); diff --git a/clang/lib/Parse/ParseTentative.cpp b/clang/lib/Parse/ParseTentative.cpp index 1116daa..b3cf983 100644 --- a/clang/lib/Parse/ParseTentative.cpp +++ b/clang/lib/Parse/ParseTentative.cpp @@ -843,6 +843,7 @@ Parser::isExpressionOrTypeSpecifierSimple(tok::TokenKind Kind) { case tok::kw_image2d_t: case tok::kw_image2d_array_t: case tok::kw_image3d_t: + case tok::kw_sampler_t: case tok::kw_event_t: case tok::kw___unknown_anytype: return TPResult::False(); diff --git a/clang/lib/Sema/DeclSpec.cpp b/clang/lib/Sema/DeclSpec.cpp index 6d30b89..569352e 100644 --- a/clang/lib/Sema/DeclSpec.cpp +++ b/clang/lib/Sema/DeclSpec.cpp @@ -286,6 +286,7 @@ bool Declarator::isDeclarationOfFunction() const { case TST_image2d_t: case TST_image2d_array_t: case TST_image3d_t: + case TST_sampler_t: case TST_event_t: return false; @@ -428,6 +429,7 @@ const char *DeclSpec::getSpecifierName(DeclSpec::TST T) { case DeclSpec::TST_image2d_t: return "image2d_t"; case DeclSpec::TST_image2d_array_t: return "image2d_array_t"; case DeclSpec::TST_image3d_t: return "image3d_t"; + case DeclSpec::TST_sampler_t: return "sampler_t"; case DeclSpec::TST_event_t: return "event_t"; case DeclSpec::TST_error: return "(error)"; } diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 45f7cae..7c31be6 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -4483,6 +4483,14 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, SCAsWritten = SC_OpenCLWorkGroupLocal; } + // OpenCL v1.2 s6.9.b p4: + // The sampler type cannot be used with the __local and __global address + // space qualifiers. + if (R->isSamplerT() && (R.getAddressSpace() == LangAS::opencl_local || + R.getAddressSpace() == LangAS::opencl_global)) { + Diag(D.getIdentifierLoc(), diag::err_wrong_sampler_addressspace); + } + // OpenCL 1.2 spec, p6.9 r: // The event type cannot be used to declare a program scope variable. // The event type cannot be used with the __local, __constant and __global diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index 87e6648..0612c73 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -2424,6 +2424,7 @@ void InitializationSequence::Step::Destroy() { case SK_PassByIndirectRestore: case SK_ProduceObjCObject: case SK_StdInitializerList: + case SK_OCLSamplerInit: case SK_OCLZeroEvent: break; @@ -2653,6 +2654,13 @@ void InitializationSequence::AddStdInitializerListConstructionStep(QualType T) { Steps.push_back(S); } +void InitializationSequence::AddOCLSamplerInitStep(QualType T) { + Step S; + S.Kind = SK_OCLSamplerInit; + S.Type = T; + Steps.push_back(S); +} + void InitializationSequence::AddOCLZeroEventStep(QualType T) { Step S; S.Kind = SK_OCLZeroEvent; @@ -4017,6 +4025,18 @@ static bool tryObjCWritebackConversion(Sema &S, return true; } +static bool TryOCLSamplerInitialization(Sema &S, + InitializationSequence &Sequence, + QualType DestType, + Expr *Initializer) { + if (!S.getLangOpts().OpenCL || !DestType->isSamplerT() || + !Initializer->isIntegerConstantExpr(S.getASTContext())) + return false; + + Sequence.AddOCLSamplerInitStep(DestType); + return true; +} + // // OpenCL 1.2 spec, s6.12.10 // @@ -4180,7 +4200,9 @@ InitializationSequence::InitializationSequence(Sema &S, tryObjCWritebackConversion(S, *this, Entity, Initializer)) { return; } - + + if (TryOCLSamplerInitialization(S, *this, DestType, Initializer)) + return; if (TryOCLZeroEventInitialization(S, *this, DestType, Initializer)) return; @@ -4974,6 +4996,7 @@ InitializationSequence::Perform(Sema &S, case SK_PassByIndirectRestore: case SK_ProduceObjCObject: case SK_StdInitializerList: + case SK_OCLSamplerInit: case SK_OCLZeroEvent: { assert(Args.size() == 1); CurInit = Args[0]; @@ -5490,6 +5513,23 @@ InitializationSequence::Perform(Sema &S, CurInit = S.Owned(Semantic); break; } + case SK_OCLSamplerInit: { + assert(Step->Type->isSamplerT() && + "Sampler initialization on non sampler type."); + + QualType SourceType = CurInit.get()->getType(); + InitializedEntity::EntityKind EntityKind = Entity.getKind(); + + if (EntityKind == InitializedEntity::EK_Parameter) { + if (!SourceType->isSamplerT()) + S.Diag(Kind.getLocation(), diag::err_sampler_argument_required) + << SourceType; + } else if (EntityKind != InitializedEntity::EK_Variable) { + llvm_unreachable("Invalid EntityKind!"); + } + + break; + } case SK_OCLZeroEvent: { assert(Step->Type->isEventT() && "Event initialization on non event type."); @@ -6186,6 +6226,10 @@ void InitializationSequence::dump(raw_ostream &OS) const { OS << "std::initializer_list from initializer list"; break; + case SK_OCLSamplerInit: + OS << "OpenCL sampler_t from integer constant"; + break; + case SK_OCLZeroEvent: OS << "OpenCL event_t from zero"; break; diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 2d4d159..ac9dec4 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -1664,7 +1664,9 @@ static bool IsStandardConversion(Sema &S, Expr* From, QualType ToType, == CanonTo.getLocalUnqualifiedType() && (CanonFrom.getLocalCVRQualifiers() != CanonTo.getLocalCVRQualifiers() || CanonFrom.getObjCGCAttr() != CanonTo.getObjCGCAttr() - || CanonFrom.getObjCLifetime() != CanonTo.getObjCLifetime())) { + || CanonFrom.getObjCLifetime() != CanonTo.getObjCLifetime() + || (CanonFrom->isSamplerT() && + CanonFrom.getAddressSpace() != CanonTo.getAddressSpace()))) { FromType = ToType; CanonFrom = CanonTo; } diff --git a/clang/lib/Sema/SemaTemplateVariadic.cpp b/clang/lib/Sema/SemaTemplateVariadic.cpp index 470896e..c13a2f6 100644 --- a/clang/lib/Sema/SemaTemplateVariadic.cpp +++ b/clang/lib/Sema/SemaTemplateVariadic.cpp @@ -737,6 +737,7 @@ bool Sema::containsUnexpandedParameterPacks(Declarator &D) { case TST_image2d_t: case TST_image2d_array_t: case TST_image3d_t: + case TST_sampler_t: case TST_event_t: case TST_error: break; diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index ae8d030..b257a59 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -952,6 +952,10 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) { Result = Context.OCLImage3dTy; break; + case DeclSpec::TST_sampler_t: + Result = Context.OCLSamplerTy; + break; + case DeclSpec::TST_event_t: Result = Context.OCLEventTy; break; diff --git a/clang/lib/Serialization/ASTCommon.cpp b/clang/lib/Serialization/ASTCommon.cpp index 955dc96..9f1514bd 100644 --- a/clang/lib/Serialization/ASTCommon.cpp +++ b/clang/lib/Serialization/ASTCommon.cpp @@ -67,6 +67,7 @@ serialization::TypeIdxFromBuiltin(const BuiltinType *BT) { 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; + case BuiltinType::OCLSampler: ID = PREDEF_TYPE_SAMPLER_ID; break; case BuiltinType::OCLEvent: ID = PREDEF_TYPE_EVENT_ID; break; case BuiltinType::BuiltinFn: ID = PREDEF_TYPE_BUILTIN_FN; break; diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 1213084..a00d406 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -4903,6 +4903,7 @@ QualType ASTReader::GetType(TypeID ID) { 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; + 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; diff --git a/clang/test/CodeGenOpenCL/opencl_types.cl b/clang/test/CodeGenOpenCL/opencl_types.cl index ab2ebe1..b1e558d 100644 --- a/clang/test/CodeGenOpenCL/opencl_types.cl +++ b/clang/test/CodeGenOpenCL/opencl_types.cl @@ -1,5 +1,8 @@ // RUN: %clang_cc1 %s -emit-llvm -o - -O0 | FileCheck %s +constant sampler_t glb_smp = 7; +// CHECK: global i32 7 + void fnc1(image1d_t img) {} // CHECK: @fnc1(%opencl.image1d_t* @@ -18,7 +21,17 @@ void fnc2arr(image2d_array_t img) {} void fnc3(image3d_t img) {} // CHECK: @fnc3(%opencl.image3d_t* +void fnc4smp(sampler_t s) {} +// CHECK: define void @fnc4smp(i32 + kernel void foo(image1d_t img) { + sampler_t smp = 5; +// CHECK: alloca i32 event_t evt; // CHECK: alloca %opencl.event_t* +// CHECK: store i32 5, + fnc4smp(smp); +// CHECK: call void @fnc4smp(i32 + fnc4smp(glb_smp); +// CHECK: call void @fnc4smp(i32 } diff --git a/clang/test/PCH/ocl_types.cl b/clang/test/PCH/ocl_types.cl index 29de5e3..d788a32 100644 --- a/clang/test/PCH/ocl_types.cl +++ b/clang/test/PCH/ocl_types.cl @@ -17,6 +17,10 @@ void foo5(img2darr_t img); void foo6(img3d_t img); +void foo7(smp_t smp) { + smp_t loc_smp; +} + void foo8(evt_t evt) { evt_t loc_evt; } diff --git a/clang/test/PCH/ocl_types.h b/clang/test/PCH/ocl_types.h index 829ea03..65c6acb 100644 --- a/clang/test/PCH/ocl_types.h +++ b/clang/test/PCH/ocl_types.h @@ -18,5 +18,8 @@ typedef image2d_array_t img2darr_t; // image3d_t typedef image3d_t img3d_t; +// sampler_t +typedef sampler_t smp_t; + // event_t typedef event_t evt_t; diff --git a/clang/test/SemaOpenCL/sampler_t.cl b/clang/test/SemaOpenCL/sampler_t.cl new file mode 100644 index 0000000..96f6dbf --- /dev/null +++ b/clang/test/SemaOpenCL/sampler_t.cl @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only + +constant sampler_t glb_smp = 5; + +void foo(sampler_t); + +void kernel ker(sampler_t argsmp) { + local sampler_t smp; // expected-error {{sampler type cannot be used with the __local and __global address space qualifiers}} + const sampler_t const_smp = 7; + foo(glb_smp); + foo(const_smp); + foo(5); // expected-error {{sampler_t variable required - got 'int'}} +} diff --git a/clang/test/SemaOpenCL/sampler_t_overload.cl b/clang/test/SemaOpenCL/sampler_t_overload.cl new file mode 100644 index 0000000..83a854f --- /dev/null +++ b/clang/test/SemaOpenCL/sampler_t_overload.cl @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 %s + +void __attribute__((overloadable)) foo(sampler_t, read_only image1d_t); +void __attribute__((overloadable)) foo(sampler_t, read_only image2d_t); + +constant sampler_t glb_smp = 5; + +void kernel ker(read_only image1d_t src1, read_only image2d_t src2) { + const sampler_t smp = 10; + foo(glb_smp, src1); + foo(smp, src2); +} diff --git a/clang/tools/libclang/CIndexUSRs.cpp b/clang/tools/libclang/CIndexUSRs.cpp index c6f4d7c..a911ce5 100644 --- a/clang/tools/libclang/CIndexUSRs.cpp +++ b/clang/tools/libclang/CIndexUSRs.cpp @@ -596,6 +596,7 @@ void USRGenerator::VisitType(QualType T) { case BuiltinType::OCLImage2dArray: case BuiltinType::OCLImage3d: case BuiltinType::OCLEvent: + case BuiltinType::OCLSampler: IgnoreResults = true; return; case BuiltinType::ObjCId: -- 2.7.4