From 95ea801956db549374496ef9aa8542f5e66a3965 Mon Sep 17 00:00:00 2001 From: rdeodhar Date: Wed, 27 May 2020 13:01:02 -0700 Subject: [PATCH 1/5] [SYCL] Changes to visitor model in preparation of array support. Signed-off-by: rdeodhar --- clang/lib/Sema/SemaSYCL.cpp | 166 +++++++++++++++++++++++++----------- 1 file changed, 116 insertions(+), 50 deletions(-) diff --git a/clang/lib/Sema/SemaSYCL.cpp b/clang/lib/Sema/SemaSYCL.cpp index 997c24bb9636c..86a8ebebeb166 100644 --- a/clang/lib/Sema/SemaSYCL.cpp +++ b/clang/lib/Sema/SemaSYCL.cpp @@ -686,22 +686,47 @@ static void VisitAccessorWrapper(CXXRecordDecl *Owner, ParentTy &Parent, CXXRecordDecl *Wrapper, Handlers &... handlers); +template +static void VisitField(CXXRecordDecl *Owner, RangeTy Item, QualType ItemTy, + Handlers &... handlers) { + if (Util::isSyclAccessorType(ItemTy)) { + (void)std::initializer_list{ + (handlers.handleSyclAccessorType(Item, ItemTy), 0)...}; + } else if (Util::isSyclStreamType(ItemTy)) + (void)std::initializer_list{ + (handlers.handleSyclStreamType(Item, ItemTy), 0)...}; + else { + if (ItemTy->isArrayType()) { + VisitArrayElements(Item, ItemTy, handlers...); + } else if (ItemTy->isStructureOrClassType()) { + VisitAccessorWrapper(Owner, Item, ItemTy->getAsCXXRecordDecl(), + handlers...); + } + } +} + +template +static void VisitArrayElements(RangeTy Item, QualType FieldTy, + Handlers &... handlers) { + const ConstantArrayType *CAT = cast(FieldTy); + QualType ET = CAT->getElementType(); + int64_t ElemCount = CAT->getSize().getSExtValue(); + std::initializer_list{(handlers.enterArray(), 0)...}; + for (int64_t Count = 0; Count < ElemCount; Count++) { + VisitField(nullptr, Item, ET, handlers...); + (void)std::initializer_list{(handlers.nextElement(ET), 0)...}; + } + (void)std::initializer_list{(handlers.leaveArray(ET, ElemCount), 0)...}; +} + template static void VisitAccessorWrapperHelper(CXXRecordDecl *Owner, RangeTy Range, Handlers &... handlers) { for (const auto &Item : Range) { QualType ItemTy = getItemType(Item); - if (Util::isSyclAccessorType(ItemTy)) - (void)std::initializer_list{ - (handlers.handleSyclAccessorType(Item, ItemTy), 0)...}; - else if (Util::isSyclStreamType(ItemTy)) { - VisitAccessorWrapper(Owner, Item, ItemTy->getAsCXXRecordDecl(), - handlers...); - (void)std::initializer_list{ - (handlers.handleSyclStreamType(Item, ItemTy), 0)...}; - } else if (ItemTy->isStructureOrClassType()) - VisitAccessorWrapper(Owner, Item, ItemTy->getAsCXXRecordDecl(), - handlers...); + (void)std::initializer_list{(handlers.enterField(Owner, Item), 0)...}; + VisitField(Owner, Item, ItemTy, handlers...); + (void)std::initializer_list{(handlers.leaveField(Owner, Item), 0)...}; } } @@ -728,6 +753,8 @@ static void VisitRecordFields(RecordDecl::field_range Fields, (void)std::initializer_list { (handlers.FUNC(Field, FieldTy), 0)... } for (const auto &Field : Fields) { + (void)std::initializer_list{ + (handlers.enterField(nullptr, Field), 0)...}; QualType FieldTy = Field->getType(); if (Util::isSyclAccessorType(FieldTy)) @@ -749,12 +776,15 @@ static void VisitRecordFields(RecordDecl::field_range Fields, KF_FOR_EACH(handleReferenceType); else if (FieldTy->isPointerType()) KF_FOR_EACH(handlePointerType); - else if (FieldTy->isArrayType()) + else if (FieldTy->isArrayType()) { KF_FOR_EACH(handleArrayType); - else if (FieldTy->isScalarType()) + VisitArrayElements(Field, FieldTy, handlers...); + } else if (FieldTy->isScalarType()) KF_FOR_EACH(handleScalarType); else KF_FOR_EACH(handleOtherType); + (void)std::initializer_list{ + (handlers.leaveField(nullptr, Field), 0)...}; } #undef KF_FOR_EACH } @@ -780,6 +810,7 @@ template class SyclKernelFieldHandler { virtual void handleStructType(FieldDecl *, QualType) {} virtual void handleReferenceType(FieldDecl *, QualType) {} virtual void handlePointerType(FieldDecl *, QualType) {} + virtual void handleArrayType(const CXXBaseSpecifier &, QualType) {} virtual void handleArrayType(FieldDecl *, QualType) {} virtual void handleScalarType(FieldDecl *, QualType) {} // Most handlers shouldn't be handling this, just the field checker. @@ -793,6 +824,17 @@ template class SyclKernelFieldHandler { virtual void leaveStruct(const CXXRecordDecl *, FieldDecl *) {} virtual void enterStruct(const CXXRecordDecl *, const CXXBaseSpecifier &) {} virtual void leaveStruct(const CXXRecordDecl *, const CXXBaseSpecifier &) {} + + // The following are used for stepping through array elements. + + virtual void enterField(const CXXRecordDecl *, const CXXBaseSpecifier &) {} + virtual void leaveField(const CXXRecordDecl *, const CXXBaseSpecifier &) {} + virtual void enterField(const CXXRecordDecl *, FieldDecl *) {} + virtual void leaveField(const CXXRecordDecl *, FieldDecl *) {} + virtual void enterArray(const CXXBaseSpecifier &) {} + virtual void enterArray() {} + virtual void nextElement(QualType) {} + virtual void leaveArray(QualType, int64_t) {} }; // A type to check the validity of all of the argument types. @@ -801,6 +843,43 @@ class SyclKernelFieldChecker bool IsInvalid = false; DiagnosticsEngine &Diag; + // Check whether the object is bit-wise copyable + bool copyableToKernel(const FieldDecl *FD, const QualType &FieldTy) { + // C++ lambda capture already flags non-constant array types. + // Here, we check copyability. + if (FieldTy->isConstantArrayType()) { + const ConstantArrayType *CAT = cast(FieldTy); + QualType ET = CAT->getElementType(); + return copyableToKernel(FD, ET); + } + if (SemaRef.getASTContext().getLangOpts().SYCLStdLayoutKernelParams) { + if (!FieldTy->isStandardLayoutType()) { + SemaRef.getASTContext().getDiagnostics().Report( + FD->getLocation(), diag::err_sycl_non_std_layout_type) + << FieldTy; + return false; + } + } + if (!FieldTy->isStructureOrClassType()) { + return true; + } + CXXRecordDecl *RD = + cast(FieldTy->getAs()->getDecl()); + if (!RD->hasTrivialCopyConstructor()) { + SemaRef.getASTContext().getDiagnostics().Report( + FD->getLocation(), diag::err_sycl_non_trivially_copy_ctor_dtor_type) + << 0 << FieldTy; + return false; + } + if (!RD->hasTrivialDestructor()) { + SemaRef.getASTContext().getDiagnostics().Report( + FD->getLocation(), diag::err_sycl_non_trivially_copy_ctor_dtor_type) + << 1 << FieldTy; + return false; + } + return true; + } + public: SyclKernelFieldChecker(Sema &S) : SyclKernelFieldHandler(S), Diag(S.getASTContext().getDiagnostics()) {} @@ -810,33 +889,17 @@ class SyclKernelFieldChecker IsInvalid = Diag.Report(FD->getLocation(), diag::err_bad_kernel_param_type) << FieldTy; } + void handleStructType(FieldDecl *FD, QualType FieldTy) final { - if (SemaRef.getASTContext().getLangOpts().SYCLStdLayoutKernelParams && - !FieldTy->isStandardLayoutType()) - IsInvalid = - Diag.Report(FD->getLocation(), diag::err_sycl_non_std_layout_type) - << FieldTy; - else { - CXXRecordDecl *RD = FieldTy->getAsCXXRecordDecl(); - if (!RD->hasTrivialCopyConstructor()) - - IsInvalid = - Diag.Report(FD->getLocation(), - diag::err_sycl_non_trivially_copy_ctor_dtor_type) - << 0 << FieldTy; - else if (!RD->hasTrivialDestructor()) - IsInvalid = - Diag.Report(FD->getLocation(), - diag::err_sycl_non_trivially_copy_ctor_dtor_type) - << 1 << FieldTy; - } + IsInvalid = !copyableToKernel(FD, FieldTy); + } + + void handleArrayType(const CXXBaseSpecifier &, QualType) final { + // FIXME } - // We should be able to handle this, so we made it part of the visitor, but - // this is 'to be implemented'. void handleArrayType(FieldDecl *FD, QualType FieldTy) final { - IsInvalid = Diag.Report(FD->getLocation(), diag::err_bad_kernel_param_type) - << FieldTy; + IsInvalid = !copyableToKernel(FD, FieldTy); } void handleOtherType(FieldDecl *FD, QualType FieldTy) final { @@ -1437,20 +1500,23 @@ void Sema::ConstructOpenCLKernel(FunctionDecl *KernelCallerFunc, : CalculatedName); SyclKernelFieldChecker checker(*this); - SyclKernelDeclCreator kernel_decl(*this, checker, KernelName, - KernelLambda->getLocation(), - KernelCallerFunc->isInlined()); - SyclKernelBodyCreator kernel_body(*this, kernel_decl, KernelLambda, - KernelCallerFunc); - SyclKernelIntHeaderCreator int_header( - *this, getSyclIntegrationHeader(), KernelLambda, - calculateKernelNameType(Context, KernelCallerFunc), KernelName, - StableName); - - ConstructingOpenCLKernel = true; - VisitRecordFields(KernelLambda->fields(), checker, kernel_decl, kernel_body, - int_header); - ConstructingOpenCLKernel = false; + VisitRecordFields(KernelLambda->fields(), checker); + if (checker.isValid()) { + SyclKernelDeclCreator kernel_decl(*this, checker, KernelName, + KernelLambda->getLocation(), + KernelCallerFunc->isInlined()); + SyclKernelBodyCreator kernel_body(*this, kernel_decl, KernelLambda, + KernelCallerFunc); + SyclKernelIntHeaderCreator int_header( + *this, getSyclIntegrationHeader(), KernelLambda, + calculateKernelNameType(Context, KernelCallerFunc), KernelName, + StableName); + + ConstructingOpenCLKernel = true; + VisitRecordFields(KernelLambda->fields(), kernel_decl, kernel_body, + int_header); + ConstructingOpenCLKernel = false; + } } void Sema::MarkDevice(void) { From c09dae42fb666a7a72e1114bc2e4602453349490 Mon Sep 17 00:00:00 2001 From: rdeodhar Date: Fri, 29 May 2020 18:03:45 -0700 Subject: [PATCH 2/5] Added conditional execution of handlers. --- .../clang/Basic/DiagnosticSemaKinds.td | 2 + clang/lib/Sema/SemaSYCL.cpp | 337 +++++++++++------- 2 files changed, 202 insertions(+), 137 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 5984ede3fcbb8..fc0f420ec27f2 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -10823,6 +10823,8 @@ def err_sycl_non_trivially_copy_ctor_dtor_type "constructible|destructible}0 class/struct type %1">; def err_sycl_non_std_layout_type : Error< "kernel parameter has non-standard layout class/struct type %0">; +def err_sycl_non_constant_array_type : Error< + "kernel parameter is not a constant size array %0">; def err_conflicting_sycl_kernel_attributes : Error< "conflicting attributes applied to a SYCL kernel">; def err_conflicting_sycl_function_attributes : Error< diff --git a/clang/lib/Sema/SemaSYCL.cpp b/clang/lib/Sema/SemaSYCL.cpp index 86a8ebebeb166..a007d039bb72f 100644 --- a/clang/lib/Sema/SemaSYCL.cpp +++ b/clang/lib/Sema/SemaSYCL.cpp @@ -680,6 +680,16 @@ namespace { QualType getItemType(const FieldDecl *FD) { return FD->getType(); } QualType getItemType(const CXXBaseSpecifier &BS) { return BS.getType(); } +// These enable handler execution only when previous handlers succeed. +template +static bool handleField(FieldDecl *FD, QualType FDTy, T &t) { + return (t.first->*t.second)(FD, FDTy); +} +template +static bool handleField(FieldDecl *FD, QualType FDTy, T &t, Tn &... tn) { + return (t.first->*t.second)(FD, FDTy) && handleField(FD, FDTy, tn...); +} + // Implements the 'for-each-visitor' pattern. template static void VisitAccessorWrapper(CXXRecordDecl *Owner, ParentTy &Parent, @@ -689,20 +699,17 @@ static void VisitAccessorWrapper(CXXRecordDecl *Owner, ParentTy &Parent, template static void VisitField(CXXRecordDecl *Owner, RangeTy Item, QualType ItemTy, Handlers &... handlers) { - if (Util::isSyclAccessorType(ItemTy)) { + if (Util::isSyclAccessorType(ItemTy)) (void)std::initializer_list{ (handlers.handleSyclAccessorType(Item, ItemTy), 0)...}; - } else if (Util::isSyclStreamType(ItemTy)) + if (Util::isSyclStreamType(ItemTy)) (void)std::initializer_list{ (handlers.handleSyclStreamType(Item, ItemTy), 0)...}; - else { - if (ItemTy->isArrayType()) { - VisitArrayElements(Item, ItemTy, handlers...); - } else if (ItemTy->isStructureOrClassType()) { - VisitAccessorWrapper(Owner, Item, ItemTy->getAsCXXRecordDecl(), - handlers...); - } - } + if (ItemTy->isStructureOrClassType()) + VisitAccessorWrapper(Owner, Item, ItemTy->getAsCXXRecordDecl(), + handlers...); + if (ItemTy->isArrayType()) + VisitArrayElements(Item, ItemTy, handlers...); } template @@ -731,9 +738,9 @@ static void VisitAccessorWrapperHelper(CXXRecordDecl *Owner, RangeTy Range, } // Parent contains the FieldDecl or CXXBaseSpecifier that was used to enter -// the Wrapper structure that we're currently visiting. Owner is the parent type -// (which doesn't exist in cases where it is a FieldDecl in the 'root'), and -// Wrapper is the current struct being unwrapped. +// the Wrapper structure that we're currently visiting. Owner is the parent +// type (which doesn't exist in cases where it is a FieldDecl in the +// 'root'), and Wrapper is the current struct being unwrapped. template static void VisitAccessorWrapper(CXXRecordDecl *Owner, ParentTy &Parent, CXXRecordDecl *Wrapper, @@ -749,8 +756,8 @@ static void VisitAccessorWrapper(CXXRecordDecl *Owner, ParentTy &Parent, template static void VisitRecordFields(RecordDecl::field_range Fields, Handlers &... handlers) { -#define KF_FOR_EACH(FUNC) \ - (void)std::initializer_list { (handlers.FUNC(Field, FieldTy), 0)... } + +#define KF_FOR_EACH(FUNC) handleField(Field, FieldTy, handlers.FUNC()...) for (const auto &Field : Fields) { (void)std::initializer_list{ @@ -758,36 +765,37 @@ static void VisitRecordFields(RecordDecl::field_range Fields, QualType FieldTy = Field->getType(); if (Util::isSyclAccessorType(FieldTy)) - KF_FOR_EACH(handleSyclAccessorType); + KF_FOR_EACH(processSyclAccessorType); else if (Util::isSyclSamplerType(FieldTy)) - KF_FOR_EACH(handleSyclSamplerType); + KF_FOR_EACH(processSyclSamplerType); else if (Util::isSyclSpecConstantType(FieldTy)) - KF_FOR_EACH(handleSyclSpecConstantType); + KF_FOR_EACH(processSyclSpecConstantType); else if (Util::isSyclStreamType(FieldTy)) { // Stream actually wraps accessors, so do recursion CXXRecordDecl *RD = FieldTy->getAsCXXRecordDecl(); VisitAccessorWrapper(nullptr, Field, RD, handlers...); - KF_FOR_EACH(handleSyclStreamType); + KF_FOR_EACH(processSyclStreamType); } else if (FieldTy->isStructureOrClassType()) { - KF_FOR_EACH(handleStructType); - CXXRecordDecl *RD = FieldTy->getAsCXXRecordDecl(); - VisitAccessorWrapper(nullptr, Field, RD, handlers...); + if (KF_FOR_EACH(processStructType)) { + CXXRecordDecl *RD = FieldTy->getAsCXXRecordDecl(); + VisitAccessorWrapper(nullptr, Field, RD, handlers...); + } } else if (FieldTy->isReferenceType()) - KF_FOR_EACH(handleReferenceType); + KF_FOR_EACH(processReferenceType); else if (FieldTy->isPointerType()) - KF_FOR_EACH(handlePointerType); + KF_FOR_EACH(processPointerType); else if (FieldTy->isArrayType()) { - KF_FOR_EACH(handleArrayType); - VisitArrayElements(Field, FieldTy, handlers...); + if (KF_FOR_EACH(processArrayType)) + VisitArrayElements(Field, FieldTy, handlers...); } else if (FieldTy->isScalarType()) - KF_FOR_EACH(handleScalarType); + KF_FOR_EACH(processScalarType); else - KF_FOR_EACH(handleOtherType); + KF_FOR_EACH(processOtherType); (void)std::initializer_list{ (handlers.leaveField(nullptr, Field), 0)...}; } #undef KF_FOR_EACH -} +} // namespace // A base type that the SYCL OpenCL Kernel construction task uses to implement // individual tasks. @@ -796,25 +804,45 @@ template class SyclKernelFieldHandler { Sema &SemaRef; SyclKernelFieldHandler(Sema &S) : SemaRef(S) {} + // The following capture a handler::function pair. + + typedef bool (SyclKernelFieldHandler::*SMemFn)(FieldDecl *, QualType); + using tuple = std::pair; + tuple pmfAccessor{this, &SyclKernelFieldHandler::handleSyclAccessorType}; + tuple pmfSampler{this, &SyclKernelFieldHandler::handleSyclSamplerType}; + tuple pmfConstant{this, &SyclKernelFieldHandler::handleSyclSpecConstantType}; + tuple pmfStream{this, &SyclKernelFieldHandler::handleSyclStreamType}; + tuple pmfStruct{this, &SyclKernelFieldHandler::handleStructType}; + tuple pmfReference{this, &SyclKernelFieldHandler::handleReferenceType}; + tuple pmfPointer{this, &SyclKernelFieldHandler::handlePointerType}; + tuple pmfScalar{this, &SyclKernelFieldHandler::handleScalarType}; + tuple pmfArray{this, &SyclKernelFieldHandler::handleArrayType}; + tuple pmfOther{this, &SyclKernelFieldHandler::handleOtherType}; + public: // Mark these virtual so that we can use override in the implementer classes, // despite virtual dispatch never being used. // Accessor can be a base class or a field decl, so both must be handled. - virtual void handleSyclAccessorType(const CXXBaseSpecifier &, QualType) {} - virtual void handleSyclAccessorType(FieldDecl *, QualType) {} - virtual void handleSyclSamplerType(FieldDecl *, QualType) {} - virtual void handleSyclSpecConstantType(FieldDecl *, QualType) {} - virtual void handleSyclStreamType(const CXXBaseSpecifier &, QualType) {} - virtual void handleSyclStreamType(FieldDecl *, QualType) {} - virtual void handleStructType(FieldDecl *, QualType) {} - virtual void handleReferenceType(FieldDecl *, QualType) {} - virtual void handlePointerType(FieldDecl *, QualType) {} - virtual void handleArrayType(const CXXBaseSpecifier &, QualType) {} - virtual void handleArrayType(FieldDecl *, QualType) {} - virtual void handleScalarType(FieldDecl *, QualType) {} + virtual bool handleSyclAccessorType(const CXXBaseSpecifier &, QualType) { + return true; + } + virtual bool handleSyclAccessorType(FieldDecl *, QualType) { return true; } + virtual bool handleSyclSamplerType(FieldDecl *, QualType) { return true; } + virtual bool handleSyclSpecConstantType(FieldDecl *, QualType) { + return true; + } + virtual bool handleSyclStreamType(const CXXBaseSpecifier &, QualType) { + return true; + } + virtual bool handleSyclStreamType(FieldDecl *, QualType) { return true; } + virtual bool handleStructType(FieldDecl *, QualType) { return true; } + virtual bool handleReferenceType(FieldDecl *, QualType) { return true; } + virtual bool handlePointerType(FieldDecl *, QualType) { return true; } + virtual bool handleArrayType(FieldDecl *, QualType) { return true; } + virtual bool handleScalarType(FieldDecl *, QualType) { return true; } // Most handlers shouldn't be handling this, just the field checker. - virtual void handleOtherType(FieldDecl *, QualType) {} + virtual bool handleOtherType(FieldDecl *, QualType) { return true; } // The following are only used for keeping track of where we are in the base // class/field graph. Int Headers use this to calculate offset, most others @@ -835,6 +863,19 @@ template class SyclKernelFieldHandler { virtual void enterArray() {} virtual void nextElement(QualType) {} virtual void leaveArray(QualType, int64_t) {} + + // The following return prebuilt handler::function pairs. + + virtual tuple &processSyclAccessorType() { return pmfAccessor; } + virtual tuple &processSyclSamplerType() { return pmfSampler; } + virtual tuple &processSyclSpecConstantType() { return pmfConstant; } + virtual tuple &processSyclStreamType() { return pmfStream; } + virtual tuple &processStructType() { return pmfStruct; } + virtual tuple &processReferenceType() { return pmfReference; } + virtual tuple &processPointerType() { return pmfPointer; } + virtual tuple &processScalarType() { return pmfScalar; } + virtual tuple &processArrayType() { return pmfArray; } + virtual tuple &processOtherType() { return pmfOther; } }; // A type to check the validity of all of the argument types. @@ -843,41 +884,40 @@ class SyclKernelFieldChecker bool IsInvalid = false; DiagnosticsEngine &Diag; - // Check whether the object is bit-wise copyable - bool copyableToKernel(const FieldDecl *FD, const QualType &FieldTy) { - // C++ lambda capture already flags non-constant array types. - // Here, we check copyability. - if (FieldTy->isConstantArrayType()) { - const ConstantArrayType *CAT = cast(FieldTy); - QualType ET = CAT->getElementType(); - return copyableToKernel(FD, ET); - } - if (SemaRef.getASTContext().getLangOpts().SYCLStdLayoutKernelParams) { - if (!FieldTy->isStandardLayoutType()) { - SemaRef.getASTContext().getDiagnostics().Report( - FD->getLocation(), diag::err_sycl_non_std_layout_type) - << FieldTy; - return false; - } - } - if (!FieldTy->isStructureOrClassType()) { - return true; + // Check whether the object should be disallowed from being copied to kernel. + // Return true if not copyable, false if copyable. + bool checkNotCopyableToKernel(const FieldDecl *FD, const QualType &FieldTy) { + if (FieldTy->isArrayType()) { + if (const auto *CAT = dyn_cast(FieldTy)) { + QualType ET = CAT->getElementType(); + return checkNotCopyableToKernel(FD, ET); + } else + return Diag.Report(FD->getLocation(), + diag::err_sycl_non_constant_array_type) + << FieldTy; } + + if (SemaRef.getASTContext().getLangOpts().SYCLStdLayoutKernelParams) + if (!FieldTy->isStandardLayoutType()) + return Diag.Report(FD->getLocation(), + diag::err_sycl_non_std_layout_type) + << FieldTy; + + if (!FieldTy->isStructureOrClassType()) + return false; + CXXRecordDecl *RD = cast(FieldTy->getAs()->getDecl()); - if (!RD->hasTrivialCopyConstructor()) { - SemaRef.getASTContext().getDiagnostics().Report( - FD->getLocation(), diag::err_sycl_non_trivially_copy_ctor_dtor_type) - << 0 << FieldTy; - return false; - } - if (!RD->hasTrivialDestructor()) { - SemaRef.getASTContext().getDiagnostics().Report( - FD->getLocation(), diag::err_sycl_non_trivially_copy_ctor_dtor_type) - << 1 << FieldTy; - return false; - } - return true; + if (!RD->hasTrivialCopyConstructor()) + return Diag.Report(FD->getLocation(), + diag::err_sycl_non_trivially_copy_ctor_dtor_type) + << 0 << FieldTy; + if (!RD->hasTrivialDestructor()) + return Diag.Report(FD->getLocation(), + diag::err_sycl_non_trivially_copy_ctor_dtor_type) + << 1 << FieldTy; + + return false; } public: @@ -885,26 +925,30 @@ class SyclKernelFieldChecker : SyclKernelFieldHandler(S), Diag(S.getASTContext().getDiagnostics()) {} bool isValid() { return !IsInvalid; } - void handleReferenceType(FieldDecl *FD, QualType FieldTy) final { - IsInvalid = Diag.Report(FD->getLocation(), diag::err_bad_kernel_param_type) - << FieldTy; - } - - void handleStructType(FieldDecl *FD, QualType FieldTy) final { - IsInvalid = !copyableToKernel(FD, FieldTy); + bool handleReferenceType(FieldDecl *FD, QualType FieldTy) final { + bool bad = Diag.Report(FD->getLocation(), diag::err_bad_kernel_param_type) + << FieldTy; + IsInvalid |= bad; + return !bad; } - void handleArrayType(const CXXBaseSpecifier &, QualType) final { - // FIXME + bool handleStructType(FieldDecl *FD, QualType FieldTy) final { + bool bad = checkNotCopyableToKernel(FD, FieldTy); + IsInvalid |= bad; + return !bad; } - void handleArrayType(FieldDecl *FD, QualType FieldTy) final { - IsInvalid = !copyableToKernel(FD, FieldTy); + bool handleArrayType(FieldDecl *FD, QualType FieldTy) final { + bool bad = checkNotCopyableToKernel(FD, FieldTy); + IsInvalid |= bad; + return !bad; } - void handleOtherType(FieldDecl *FD, QualType FieldTy) final { - IsInvalid = Diag.Report(FD->getLocation(), diag::err_bad_kernel_param_type) - << FieldTy; + bool handleOtherType(FieldDecl *FD, QualType FieldTy) final { + bool bad = Diag.Report(FD->getLocation(), diag::err_bad_kernel_param_type) + << FieldTy; + IsInvalid |= bad; + return !bad; } }; @@ -948,7 +992,7 @@ class SyclKernelDeclCreator // kernel parameters from __init method parameters. We will use __init method // and kernel parameters which we build here to initialize special objects in // the kernel body. - void handleSpecialType(FieldDecl *FD, QualType FieldTy) { + bool handleSpecialType(FieldDecl *FD, QualType FieldTy) { const auto *RecordDecl = FieldTy->getAsCXXRecordDecl(); assert(RecordDecl && "The accessor/sampler must be a RecordDecl"); CXXMethodDecl *InitMethod = getMethodByName(RecordDecl, InitMethodName); @@ -960,6 +1004,7 @@ class SyclKernelDeclCreator for (const ParmVarDecl *Param : InitMethod->parameters()) addParam(FD, Param->getType().getCanonicalType()); LastParamIndex = ParamIndex; + return true; } static void setKernelImplicitAttrs(ASTContext &Context, FunctionDecl *FD, @@ -1012,7 +1057,7 @@ class SyclKernelDeclCreator SemaRef.addSyclDeviceDecl(KernelDecl); } - void handleSyclAccessorType(const CXXBaseSpecifier &BS, + bool handleSyclAccessorType(const CXXBaseSpecifier &BS, QualType FieldTy) final { const auto *RecordDecl = FieldTy->getAsCXXRecordDecl(); assert(RecordDecl && "The accessor/sampler must be a RecordDecl"); @@ -1025,17 +1070,18 @@ class SyclKernelDeclCreator for (const ParmVarDecl *Param : InitMethod->parameters()) addParam(BS, Param->getType().getCanonicalType()); LastParamIndex = ParamIndex; + return true; } - void handleSyclAccessorType(FieldDecl *FD, QualType FieldTy) final { - handleSpecialType(FD, FieldTy); + bool handleSyclAccessorType(FieldDecl *FD, QualType FieldTy) final { + return handleSpecialType(FD, FieldTy); } - void handleSyclSamplerType(FieldDecl *FD, QualType FieldTy) final { - handleSpecialType(FD, FieldTy); + bool handleSyclSamplerType(FieldDecl *FD, QualType FieldTy) final { + return handleSpecialType(FD, FieldTy); } - void handlePointerType(FieldDecl *FD, QualType FieldTy) final { + bool handlePointerType(FieldDecl *FD, QualType FieldTy) final { // USM allows to use raw pointers instead of buffers/accessors, but these // pointers point to the specially allocated memory. For pointer fields we // add a kernel argument with the same type as field but global address @@ -1047,23 +1093,28 @@ class SyclKernelDeclCreator PointeeTy.getUnqualifiedType(), Quals); QualType ModTy = SemaRef.getASTContext().getPointerType(PointeeTy); addParam(FD, ModTy); + return true; } - void handleScalarType(FieldDecl *FD, QualType FieldTy) final { + bool handleScalarType(FieldDecl *FD, QualType FieldTy) final { addParam(FD, FieldTy); + return true; } - void handleStructType(FieldDecl *FD, QualType FieldTy) final { + bool handleStructType(FieldDecl *FD, QualType FieldTy) final { addParam(FD, FieldTy); + return true; } - void handleSyclStreamType(FieldDecl *FD, QualType FieldTy) final { + bool handleSyclStreamType(FieldDecl *FD, QualType FieldTy) final { addParam(FD, FieldTy); + return true; } - void handleSyclStreamType(const CXXBaseSpecifier &, QualType FieldTy) final { + bool handleSyclStreamType(const CXXBaseSpecifier &, QualType FieldTy) final { // FIXME SYCL stream should be usable as a base type // See https://github.com/intel/llvm/issues/1552 + return true; } void setBody(CompoundStmt *KB) { KernelDecl->setBody(KB); } @@ -1230,7 +1281,7 @@ class SyclKernelBodyCreator return VD; } - void handleSpecialType(FieldDecl *FD, QualType Ty) { + bool handleSpecialType(FieldDecl *FD, QualType Ty) { const auto *RecordDecl = Ty->getAsCXXRecordDecl(); // Perform initialization only if it is field of kernel object if (MemberExprBases.size() == 1) { @@ -1245,6 +1296,7 @@ class SyclKernelBodyCreator } createSpecialMethodCall(RecordDecl, MemberExprBases.back(), InitMethodName, FD); + return true; } public: @@ -1273,43 +1325,49 @@ class SyclKernelBodyCreator DeclCreator.setBody(KernelBody); } - void handleSyclAccessorType(FieldDecl *FD, QualType Ty) final { - handleSpecialType(FD, Ty); + bool handleSyclAccessorType(FieldDecl *FD, QualType Ty) final { + return handleSpecialType(FD, Ty); } - void handleSyclAccessorType(const CXXBaseSpecifier &BS, QualType Ty) final { + bool handleSyclAccessorType(const CXXBaseSpecifier &BS, QualType Ty) final { // FIXME SYCL accessor should be usable as a base type // See https://github.com/intel/llvm/issues/28. + return true; } - void handleSyclSamplerType(FieldDecl *FD, QualType Ty) final { - handleSpecialType(FD, Ty); + bool handleSyclSamplerType(FieldDecl *FD, QualType Ty) final { + return handleSpecialType(FD, Ty); } - void handleSyclStreamType(FieldDecl *FD, QualType Ty) final { + bool handleSyclStreamType(FieldDecl *FD, QualType Ty) final { const auto *StreamDecl = Ty->getAsCXXRecordDecl(); createExprForStructOrScalar(FD); createSpecialMethodCall(StreamDecl, MemberExprBases.back(), InitMethodName, FD); createSpecialMethodCall(StreamDecl, MemberExprBases.back(), FinalizeMethodName, FD); + return true; } - void handleSyclStreamType(const CXXBaseSpecifier &BS, QualType Ty) final { + bool handleSyclStreamType(const CXXBaseSpecifier &BS, QualType Ty) final { // FIXME SYCL stream should be usable as a base type // See https://github.com/intel/llvm/issues/1552 + return true; } - void handlePointerType(FieldDecl *FD, QualType FieldTy) final { + bool handlePointerType(FieldDecl *FD, QualType FieldTy) final { createExprForStructOrScalar(FD); + return true; } - void handleStructType(FieldDecl *FD, QualType FieldTy) final { + bool handleStructType(FieldDecl *FD, QualType FieldTy) final { createExprForStructOrScalar(FD); + return true; } - void handleScalarType(FieldDecl *FD, QualType FieldTy) final { + bool handleScalarType(FieldDecl *FD, QualType FieldTy) final { createExprForStructOrScalar(FD); + return true; } void enterStruct(const CXXRecordDecl *, FieldDecl *FD) final { @@ -1360,7 +1418,7 @@ class SyclKernelIntHeaderCreator Header.startKernel(Name, NameType, StableName, KernelLambda->getLocation()); } - void handleSyclAccessorType(const CXXBaseSpecifier &BC, + bool handleSyclAccessorType(const CXXBaseSpecifier &BC, QualType FieldTy) final { const auto *AccTy = cast(FieldTy->getAsRecordDecl()); @@ -1371,9 +1429,10 @@ class SyclKernelIntHeaderCreator int Info = getAccessTarget(AccTy) | (Dims << 11); Header.addParamDesc(SYCLIntegrationHeader::kind_accessor, Info, getOffset(BC.getType()->getAsCXXRecordDecl())); + return true; } - void handleSyclAccessorType(FieldDecl *FD, QualType FieldTy) final { + bool handleSyclAccessorType(FieldDecl *FD, QualType FieldTy) final { const auto *AccTy = cast(FieldTy->getAsRecordDecl()); assert(AccTy->getTemplateArgs().size() >= 2 && @@ -1383,9 +1442,10 @@ class SyclKernelIntHeaderCreator int Info = getAccessTarget(AccTy) | (Dims << 11); Header.addParamDesc(SYCLIntegrationHeader::kind_accessor, Info, getOffset(FD)); + return true; } - void handleSyclSamplerType(FieldDecl *FD, QualType FieldTy) final { + bool handleSyclSamplerType(FieldDecl *FD, QualType FieldTy) final { const auto *SamplerTy = FieldTy->getAsCXXRecordDecl(); assert(SamplerTy && "Sampler type must be a C++ record type"); CXXMethodDecl *InitMethod = getMethodByName(SamplerTy, InitMethodName); @@ -1396,9 +1456,10 @@ class SyclKernelIntHeaderCreator assert(SamplerArg && "sampler __init method must have sampler parameter"); addParam(FD, SamplerArg->getType(), SYCLIntegrationHeader::kind_sampler); + return true; } - void handleSyclSpecConstantType(FieldDecl *FD, QualType FieldTy) final { + bool handleSyclSpecConstantType(FieldDecl *FD, QualType FieldTy) final { const TemplateArgumentList &TemplateArgs = cast(FieldTy->getAsRecordDecl()) ->getTemplateInstantiationArgs(); @@ -1414,25 +1475,31 @@ class SyclKernelIntHeaderCreator SemaRef.getASTContext(), PredefinedExpr::UniqueStableNameType, SpecConstIDTy); Header.addSpecConstant(SpecConstName, SpecConstIDTy); + return true; } - void handlePointerType(FieldDecl *FD, QualType FieldTy) final { + bool handlePointerType(FieldDecl *FD, QualType FieldTy) final { addParam(FD, FieldTy, SYCLIntegrationHeader::kind_pointer); + return true; } - void handleStructType(FieldDecl *FD, QualType FieldTy) final { + bool handleStructType(FieldDecl *FD, QualType FieldTy) final { addParam(FD, FieldTy, SYCLIntegrationHeader::kind_std_layout); + return true; } - void handleScalarType(FieldDecl *FD, QualType FieldTy) final { + bool handleScalarType(FieldDecl *FD, QualType FieldTy) final { addParam(FD, FieldTy, SYCLIntegrationHeader::kind_std_layout); + return true; } - void handleSyclStreamType(FieldDecl *FD, QualType FieldTy) final { + bool handleSyclStreamType(FieldDecl *FD, QualType FieldTy) final { addParam(FD, FieldTy, SYCLIntegrationHeader::kind_std_layout); + return true; } - void handleSyclStreamType(const CXXBaseSpecifier &BC, + bool handleSyclStreamType(const CXXBaseSpecifier &BC, QualType FieldTy) final { // FIXME SYCL stream should be usable as a base type // See https://github.com/intel/llvm/issues/1552 + return true; } // Keep track of the current struct offset. @@ -1498,25 +1565,21 @@ void Sema::ConstructOpenCLKernel(FunctionDecl *KernelCallerFunc, constructKernelName(*this, KernelCallerFunc, MC); StringRef KernelName(getLangOpts().SYCLUnnamedLambda ? StableName : CalculatedName); - SyclKernelFieldChecker checker(*this); - VisitRecordFields(KernelLambda->fields(), checker); - if (checker.isValid()) { - SyclKernelDeclCreator kernel_decl(*this, checker, KernelName, - KernelLambda->getLocation(), - KernelCallerFunc->isInlined()); - SyclKernelBodyCreator kernel_body(*this, kernel_decl, KernelLambda, - KernelCallerFunc); - SyclKernelIntHeaderCreator int_header( - *this, getSyclIntegrationHeader(), KernelLambda, - calculateKernelNameType(Context, KernelCallerFunc), KernelName, - StableName); - - ConstructingOpenCLKernel = true; - VisitRecordFields(KernelLambda->fields(), kernel_decl, kernel_body, - int_header); - ConstructingOpenCLKernel = false; - } + SyclKernelDeclCreator kernel_decl(*this, checker, KernelName, + KernelLambda->getLocation(), + KernelCallerFunc->isInlined()); + SyclKernelBodyCreator kernel_body(*this, kernel_decl, KernelLambda, + KernelCallerFunc); + SyclKernelIntHeaderCreator int_header( + *this, getSyclIntegrationHeader(), KernelLambda, + calculateKernelNameType(Context, KernelCallerFunc), KernelName, + StableName); + + ConstructingOpenCLKernel = true; + VisitRecordFields(KernelLambda->fields(), checker, kernel_decl, kernel_body, + int_header); + ConstructingOpenCLKernel = false; } void Sema::MarkDevice(void) { From f1161d6275290cb468884cfd55d747a5ec99ed12 Mon Sep 17 00:00:00 2001 From: rdeodhar Date: Tue, 2 Jun 2020 14:55:48 -0700 Subject: [PATCH 3/5] Changes to visitor model to run handlers conditionally. --- clang/lib/Sema/SemaSYCL.cpp | 107 ++++++++++++++++++------------------ 1 file changed, 55 insertions(+), 52 deletions(-) diff --git a/clang/lib/Sema/SemaSYCL.cpp b/clang/lib/Sema/SemaSYCL.cpp index a007d039bb72f..cd7bef78ec0f5 100644 --- a/clang/lib/Sema/SemaSYCL.cpp +++ b/clang/lib/Sema/SemaSYCL.cpp @@ -27,8 +27,11 @@ #include "llvm/Support/raw_ostream.h" #include +#include +#include using namespace clang; +using namespace std::placeholders; using KernelParamKind = SYCLIntegrationHeader::kernel_param_kind_t; @@ -681,15 +684,47 @@ QualType getItemType(const FieldDecl *FD) { return FD->getType(); } QualType getItemType(const CXXBaseSpecifier &BS) { return BS.getType(); } // These enable handler execution only when previous handlers succeed. -template -static bool handleField(FieldDecl *FD, QualType FDTy, T &t) { - return (t.first->*t.second)(FD, FDTy); +template +static bool handleField(FieldDecl *FD, QualType FDTy, Tn &&... tn) { + bool result = true; + std::initializer_list{(result = result && tn(FD, FDTy), 0)...}; + return result; } -template -static bool handleField(FieldDecl *FD, QualType FDTy, T &t, Tn &... tn) { - return (t.first->*t.second)(FD, FDTy) && handleField(FD, FDTy, tn...); +template +static bool handleField(const CXXBaseSpecifier &BD, QualType BDTy, + Tn &&... tn) { + bool result = true; + std::initializer_list{(result = result && tn(BD, BDTy), 0)...}; + return result; } +template struct bind_param { using type = T; }; + +template <> struct bind_param { + using type = const CXXBaseSpecifier &; +}; + +template <> struct bind_param { using type = FieldDecl *; }; + +template <> struct bind_param { using type = FieldDecl *; }; + +template using bind_param_t = typename bind_param::type; + +// This definition using std::bind is necessary because of a gcc 7.x bug. +#define KF_FOR_EACH(FUNC, Item, Qt) \ + handleField( \ + Item, Qt, \ + std::bind(static_cast::*)( \ + bind_param_t, QualType)>( \ + &std::decay_t::FUNC), \ + std::ref(handlers), _1, _2)...) + +// The following simpler definition works with gcc 8.x and later. +//#define KF_FOR_EACH(FUNC) \ +// handleField(Field, FieldTy, ([&](FieldDecl *FD, QualType FDTy) { \ +// return handlers.f(FD, FDTy); \ +// })...) + // Implements the 'for-each-visitor' pattern. template static void VisitAccessorWrapper(CXXRecordDecl *Owner, ParentTy &Parent, @@ -697,14 +732,12 @@ static void VisitAccessorWrapper(CXXRecordDecl *Owner, ParentTy &Parent, Handlers &... handlers); template -static void VisitField(CXXRecordDecl *Owner, RangeTy Item, QualType ItemTy, +static void VisitField(CXXRecordDecl *Owner, RangeTy &&Item, QualType ItemTy, Handlers &... handlers) { if (Util::isSyclAccessorType(ItemTy)) - (void)std::initializer_list{ - (handlers.handleSyclAccessorType(Item, ItemTy), 0)...}; + KF_FOR_EACH(handleSyclAccessorType, Item, ItemTy); if (Util::isSyclStreamType(ItemTy)) - (void)std::initializer_list{ - (handlers.handleSyclStreamType(Item, ItemTy), 0)...}; + KF_FOR_EACH(handleSyclStreamType, Item, ItemTy); if (ItemTy->isStructureOrClassType()) VisitAccessorWrapper(Owner, Item, ItemTy->getAsCXXRecordDecl(), handlers...); @@ -757,40 +790,38 @@ template static void VisitRecordFields(RecordDecl::field_range Fields, Handlers &... handlers) { -#define KF_FOR_EACH(FUNC) handleField(Field, FieldTy, handlers.FUNC()...) - - for (const auto &Field : Fields) { + for (const auto Field : Fields) { (void)std::initializer_list{ (handlers.enterField(nullptr, Field), 0)...}; QualType FieldTy = Field->getType(); if (Util::isSyclAccessorType(FieldTy)) - KF_FOR_EACH(processSyclAccessorType); + KF_FOR_EACH(handleSyclAccessorType, Field, FieldTy); else if (Util::isSyclSamplerType(FieldTy)) - KF_FOR_EACH(processSyclSamplerType); + KF_FOR_EACH(handleSyclSamplerType, Field, FieldTy); else if (Util::isSyclSpecConstantType(FieldTy)) - KF_FOR_EACH(processSyclSpecConstantType); + KF_FOR_EACH(handleSyclSpecConstantType, Field, FieldTy); else if (Util::isSyclStreamType(FieldTy)) { // Stream actually wraps accessors, so do recursion CXXRecordDecl *RD = FieldTy->getAsCXXRecordDecl(); VisitAccessorWrapper(nullptr, Field, RD, handlers...); - KF_FOR_EACH(processSyclStreamType); + KF_FOR_EACH(handleSyclStreamType, Field, FieldTy); } else if (FieldTy->isStructureOrClassType()) { - if (KF_FOR_EACH(processStructType)) { + if (KF_FOR_EACH(handleStructType, Field, FieldTy)) { CXXRecordDecl *RD = FieldTy->getAsCXXRecordDecl(); VisitAccessorWrapper(nullptr, Field, RD, handlers...); } } else if (FieldTy->isReferenceType()) - KF_FOR_EACH(processReferenceType); + KF_FOR_EACH(handleReferenceType, Field, FieldTy); else if (FieldTy->isPointerType()) - KF_FOR_EACH(processPointerType); + KF_FOR_EACH(handlePointerType, Field, FieldTy); else if (FieldTy->isArrayType()) { - if (KF_FOR_EACH(processArrayType)) + if (KF_FOR_EACH(handleArrayType, Field, FieldTy)) VisitArrayElements(Field, FieldTy, handlers...); } else if (FieldTy->isScalarType()) - KF_FOR_EACH(processScalarType); + KF_FOR_EACH(handleScalarType, Field, FieldTy); else - KF_FOR_EACH(processOtherType); + KF_FOR_EACH(handleOtherType, Field, FieldTy); (void)std::initializer_list{ (handlers.leaveField(nullptr, Field), 0)...}; } @@ -804,21 +835,6 @@ template class SyclKernelFieldHandler { Sema &SemaRef; SyclKernelFieldHandler(Sema &S) : SemaRef(S) {} - // The following capture a handler::function pair. - - typedef bool (SyclKernelFieldHandler::*SMemFn)(FieldDecl *, QualType); - using tuple = std::pair; - tuple pmfAccessor{this, &SyclKernelFieldHandler::handleSyclAccessorType}; - tuple pmfSampler{this, &SyclKernelFieldHandler::handleSyclSamplerType}; - tuple pmfConstant{this, &SyclKernelFieldHandler::handleSyclSpecConstantType}; - tuple pmfStream{this, &SyclKernelFieldHandler::handleSyclStreamType}; - tuple pmfStruct{this, &SyclKernelFieldHandler::handleStructType}; - tuple pmfReference{this, &SyclKernelFieldHandler::handleReferenceType}; - tuple pmfPointer{this, &SyclKernelFieldHandler::handlePointerType}; - tuple pmfScalar{this, &SyclKernelFieldHandler::handleScalarType}; - tuple pmfArray{this, &SyclKernelFieldHandler::handleArrayType}; - tuple pmfOther{this, &SyclKernelFieldHandler::handleOtherType}; - public: // Mark these virtual so that we can use override in the implementer classes, // despite virtual dispatch never being used. @@ -863,19 +879,6 @@ template class SyclKernelFieldHandler { virtual void enterArray() {} virtual void nextElement(QualType) {} virtual void leaveArray(QualType, int64_t) {} - - // The following return prebuilt handler::function pairs. - - virtual tuple &processSyclAccessorType() { return pmfAccessor; } - virtual tuple &processSyclSamplerType() { return pmfSampler; } - virtual tuple &processSyclSpecConstantType() { return pmfConstant; } - virtual tuple &processSyclStreamType() { return pmfStream; } - virtual tuple &processStructType() { return pmfStruct; } - virtual tuple &processReferenceType() { return pmfReference; } - virtual tuple &processPointerType() { return pmfPointer; } - virtual tuple &processScalarType() { return pmfScalar; } - virtual tuple &processArrayType() { return pmfArray; } - virtual tuple &processOtherType() { return pmfOther; } }; // A type to check the validity of all of the argument types. From 97ddadb040a5a3a5741a2fc80f2a09ea289de21c Mon Sep 17 00:00:00 2001 From: rdeodhar Date: Thu, 4 Jun 2020 08:51:17 -0700 Subject: [PATCH 4/5] Corrections to returning validity. --- clang/lib/Sema/SemaSYCL.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/clang/lib/Sema/SemaSYCL.cpp b/clang/lib/Sema/SemaSYCL.cpp index cd7bef78ec0f5..b88c489f974f2 100644 --- a/clang/lib/Sema/SemaSYCL.cpp +++ b/clang/lib/Sema/SemaSYCL.cpp @@ -29,6 +29,7 @@ #include #include #include +#include using namespace clang; using namespace std::placeholders; @@ -2277,7 +2278,13 @@ SYCLIntegrationHeader::SYCLIntegrationHeader(DiagnosticsEngine &_Diag, // ----------------------------------------------------------------------------- bool Util::isSyclAccessorType(const QualType &Ty) { - return isSyclType(Ty, "accessor", true /*Tmpl*/); + std::cerr << "isSyclAccessorType:Ty\n"; + Ty->dump(); + bool b = isSyclType(Ty, "accessor", true /*Tmpl*/) || isSyclType(Ty, "accessor_common", true /*Tmpl*/); + std::cerr << (b ? "IS" + : "NOT") + << " an accessor\n\n"; + return b; } bool Util::isSyclSamplerType(const QualType &Ty) { From a16091a8c8af1e2dd1a01fda5dd5cafa7bff0619 Mon Sep 17 00:00:00 2001 From: rdeodhar Date: Thu, 4 Jun 2020 09:05:21 -0700 Subject: [PATCH 5/5] Corrected file upload. --- clang/lib/Sema/SemaSYCL.cpp | 33 +++++++++++---------------------- 1 file changed, 11 insertions(+), 22 deletions(-) diff --git a/clang/lib/Sema/SemaSYCL.cpp b/clang/lib/Sema/SemaSYCL.cpp index b88c489f974f2..03914af524324 100644 --- a/clang/lib/Sema/SemaSYCL.cpp +++ b/clang/lib/Sema/SemaSYCL.cpp @@ -29,7 +29,6 @@ #include #include #include -#include using namespace clang; using namespace std::placeholders; @@ -930,29 +929,25 @@ class SyclKernelFieldChecker bool isValid() { return !IsInvalid; } bool handleReferenceType(FieldDecl *FD, QualType FieldTy) final { - bool bad = Diag.Report(FD->getLocation(), diag::err_bad_kernel_param_type) - << FieldTy; - IsInvalid |= bad; - return !bad; + Diag.Report(FD->getLocation(), diag::err_bad_kernel_param_type) << FieldTy; + IsInvalid = true; + return isValid(); } bool handleStructType(FieldDecl *FD, QualType FieldTy) final { - bool bad = checkNotCopyableToKernel(FD, FieldTy); - IsInvalid |= bad; - return !bad; + IsInvalid |= checkNotCopyableToKernel(FD, FieldTy); + return isValid(); } bool handleArrayType(FieldDecl *FD, QualType FieldTy) final { - bool bad = checkNotCopyableToKernel(FD, FieldTy); - IsInvalid |= bad; - return !bad; + IsInvalid |= checkNotCopyableToKernel(FD, FieldTy); + return isValid(); } bool handleOtherType(FieldDecl *FD, QualType FieldTy) final { - bool bad = Diag.Report(FD->getLocation(), diag::err_bad_kernel_param_type) - << FieldTy; - IsInvalid |= bad; - return !bad; + Diag.Report(FD->getLocation(), diag::err_bad_kernel_param_type) << FieldTy; + IsInvalid = true; + return isValid(); } }; @@ -2278,13 +2273,7 @@ SYCLIntegrationHeader::SYCLIntegrationHeader(DiagnosticsEngine &_Diag, // ----------------------------------------------------------------------------- bool Util::isSyclAccessorType(const QualType &Ty) { - std::cerr << "isSyclAccessorType:Ty\n"; - Ty->dump(); - bool b = isSyclType(Ty, "accessor", true /*Tmpl*/) || isSyclType(Ty, "accessor_common", true /*Tmpl*/); - std::cerr << (b ? "IS" - : "NOT") - << " an accessor\n\n"; - return b; + return isSyclType(Ty, "accessor", true /*Tmpl*/); } bool Util::isSyclSamplerType(const QualType &Ty) {