diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -1283,7 +1283,7 @@ InitBuiltinType(ObjCBuiltinClassTy, BuiltinType::ObjCClass); InitBuiltinType(ObjCBuiltinSelTy, BuiltinType::ObjCSel); - if (LangOpts.OpenCL) { + if (LangOpts.OpenCL || LangOpts.SYCLIsDevice) { #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ InitBuiltinType(SingletonId, BuiltinType::Id); #include "clang/Basic/OpenCLImageTypes.def" diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -129,7 +129,7 @@ if (LangOpts.ObjC) createObjCRuntime(); - if (LangOpts.OpenCL) + if (LangOpts.OpenCL || LangOpts.SYCLIsDevice) createOpenCLRuntime(); if (LangOpts.OpenMP) createOpenMPRuntime(); diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp --- a/clang/lib/Sema/Sema.cpp +++ b/clang/lib/Sema/Sema.cpp @@ -263,6 +263,10 @@ addImplicitTypedef("size_t", Context.getSizeType()); } + if (getLangOpts().SYCLIsDevice) { + addImplicitTypedef("__ocl_sampler_t", Context.OCLSamplerTy); + } + // Initialize predefined OpenCL types and supported extensions and (optional) // core features. if (getLangOpts().OpenCL) { diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -6351,6 +6351,26 @@ return nullptr; } + if (R->isSamplerT()) { + // OpenCL v1.2 s6.9.b p4: + // The sampler type cannot be used with the __local and __global address + // space qualifiers. + if (R.getAddressSpace() == LangAS::opencl_local || + R.getAddressSpace() == LangAS::opencl_global) { + Diag(D.getIdentifierLoc(), diag::err_wrong_sampler_addressspace); + } + + // OpenCL v1.2 s6.12.14.1: + // A global sampler must be declared with either the constant address + // space qualifier or with the const qualifier. + if (DC->isTranslationUnit() && + !(R.getAddressSpace() == LangAS::opencl_constant || + R.isConstQualified())) { + Diag(D.getIdentifierLoc(), diag::err_opencl_nonconst_global_sampler); + D.setInvalidType(); + } + } + if (getLangOpts().OpenCL) { // OpenCL v2.0 s6.9.b - Image type can only be used as a function argument. // OpenCL v2.0 s6.13.16.1 - Pipe type can only be used as a function @@ -6396,26 +6416,6 @@ } } - if (R->isSamplerT()) { - // OpenCL v1.2 s6.9.b p4: - // The sampler type cannot be used with the __local and __global address - // space qualifiers. - if (R.getAddressSpace() == LangAS::opencl_local || - R.getAddressSpace() == LangAS::opencl_global) { - Diag(D.getIdentifierLoc(), diag::err_wrong_sampler_addressspace); - } - - // OpenCL v1.2 s6.12.14.1: - // A global sampler must be declared with either the constant address - // space qualifier or with the const qualifier. - if (DC->isTranslationUnit() && - !(R.getAddressSpace() == LangAS::opencl_constant || - R.isConstQualified())) { - Diag(D.getIdentifierLoc(), diag::err_opencl_nonconst_global_sampler); - D.setInvalidType(); - } - } - // OpenCL v1.2 s6.9.r: // The event type cannot be used with the __local, __constant and __global // address space qualifiers. diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -13082,7 +13082,7 @@ bool CanOverflow = false; bool ConvertHalfVec = false; - if (getLangOpts().OpenCL) { + if (getLangOpts().OpenCL || getLangOpts().SYCLIsDevice) { QualType Ty = InputExpr->getType(); // The only legal unary operation for atomics is '&'. if ((Opc != UO_AddrOf && Ty->isAtomicType()) || diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -5325,9 +5325,9 @@ InitializationSequence &Sequence, QualType DestType, Expr *Initializer) { - if (!S.getLangOpts().OpenCL || !DestType->isSamplerT() || + if (!DestType->isSamplerT() || (!Initializer->isIntegerConstantExpr(S.Context) && - !Initializer->getType()->isSamplerT())) + !Initializer->getType()->isSamplerT())) return false; Sequence.AddOCLSamplerInitStep(DestType); @@ -5640,6 +5640,9 @@ bool allowObjCWritebackConversion = S.getLangOpts().ObjCAutoRefCount && Entity.isParameterKind(); + if (TryOCLSamplerInitialization(S, *this, DestType, Initializer)) + return; + // We're at the end of the line for C: it's either a write-back conversion // or it's a C assignment. There's no need to check anything else. if (!S.getLangOpts().CPlusPlus) { @@ -5649,9 +5652,6 @@ return; } - if (TryOCLSamplerInitialization(S, *this, DestType, Initializer)) - return; - if (TryOCLZeroOpaqueTypeInitialization(S, *this, DestType, Initializer)) return; diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -2320,7 +2320,7 @@ // OpenCL v2.0 s6.12.5 - Arrays of blocks are not supported. // OpenCL v2.0 s6.16.13.1 - Arrays of pipe type are not supported. // OpenCL v2.0 s6.9.b - Arrays of image/sampler type are not supported. - if (getLangOpts().OpenCL) { + if (getLangOpts().OpenCL || getLangOpts().SYCLIsDevice) { const QualType ArrType = Context.getBaseElementType(T); if (ArrType->isBlockPointerType() || ArrType->isPipeType() || ArrType->isSamplerT() || ArrType->isImageType()) { @@ -4407,7 +4407,7 @@ // OpenCL v2.0 s6.9b - Pointer to image/sampler cannot be used. // OpenCL v2.0 s6.13.16.1 - Pointer to pipe cannot be used. // OpenCL v2.0 s6.12.5 - Pointers to Blocks are not allowed. - if (LangOpts.OpenCL) { + if (LangOpts.OpenCL || LangOpts.SYCLIsDevice) { if (T->isImageType() || T->isSamplerT() || T->isPipeType() || T->isBlockPointerType()) { S.Diag(D.getIdentifierLoc(), diag::err_opencl_pointer_to_type) << T; @@ -4605,7 +4605,7 @@ } } - if (LangOpts.OpenCL) { + if (LangOpts.OpenCL || LangOpts.SYCLIsDevice) { // OpenCL v2.0 s6.12.5 - A block cannot be the return value of a // function. if (T->isBlockPointerType() || T->isImageType() || T->isSamplerT() || @@ -4617,7 +4617,9 @@ // OpenCL doesn't support variadic functions and blocks // (s6.9.e and s6.12.5 OpenCL v2.0) except for printf. // We also allow here any toolchain reserved identifiers. + // FIXME: Use deferred diagnostics engine to skip host side issues. if (FTI.isVariadic && + !LangOpts.SYCLIsDevice && !(D.getIdentifier() && ((D.getIdentifier()->getName() == "printf" && (LangOpts.OpenCLCPlusPlus || LangOpts.OpenCLVersion >= 120)) || diff --git a/clang/test/CodeGenSYCL/ocl_sampler.cpp b/clang/test/CodeGenSYCL/ocl_sampler.cpp new file mode 100644 --- /dev/null +++ b/clang/test/CodeGenSYCL/ocl_sampler.cpp @@ -0,0 +1,6 @@ +// RUN: %clang_cc1 -triple spir64-unknown-unknown -std=c++11 -fsycl-is-device -S -emit-llvm %s -o - | FileCheck %s + +// CHECK: %opencl.sampler_t = type opaque + +void foo(__ocl_sampler_t s) {} +// CHECK: define spir_func void @{{.*}}foo{{.*}}(%opencl.sampler_t addrspace(2)* diff --git a/clang/test/SemaSYCL/ocl_sampler.cpp b/clang/test/SemaSYCL/ocl_sampler.cpp new file mode 100644 --- /dev/null +++ b/clang/test/SemaSYCL/ocl_sampler.cpp @@ -0,0 +1,22 @@ +// RUN: %clang_cc1 -std=c++11 -fsycl-is-device -fsyntax-only -verify %s + +#define CLK_ADDRESS_CLAMP_TO_EDGE 2 +#define CLK_NORMALIZED_COORDS_TRUE 1 +#define CLK_FILTER_NEAREST 0x10 +#define CLK_FILTER_LINEAR 0x20 + +__ocl_sampler_t global_nonconst_smp = 0; // expected-error {{global sampler requires a const or constant address space qualifier}} +const __ocl_sampler_t glb_smp = CLK_ADDRESS_CLAMP_TO_EDGE | CLK_NORMALIZED_COORDS_TRUE | CLK_FILTER_LINEAR; + +void foo(__ocl_sampler_t argsmp) { + __ocl_sampler_t smp1 = CLK_ADDRESS_CLAMP_TO_EDGE | CLK_NORMALIZED_COORDS_TRUE | CLK_FILTER_LINEAR; + __ocl_sampler_t smp2 = CLK_ADDRESS_CLAMP_TO_EDGE | CLK_NORMALIZED_COORDS_TRUE | CLK_FILTER_NEAREST; + &smp1; //expected-error{{invalid argument type '__ocl_sampler_t' (aka 'sampler_t') to unary expression}} + *smp2; //expected-error{{invalid argument type '__ocl_sampler_t' (aka 'sampler_t') to unary expression}} + + const __ocl_sampler_t const_smp6 = 0x100000000LL; // expected-error{{sampler_t initialization requires 32-bit integer, not 'long long'}} + + __ocl_sampler_t sa[] = {argsmp, glb_smp}; // expected-error {{array of '__ocl_sampler_t' (aka 'sampler_t') type is invalid in OpenCL}} +} + +void foo_smplr_ptr(__ocl_sampler_t*); // expected-error{{pointer to type '__ocl_sampler_t' (aka 'sampler_t') is invalid in OpenCL}}