@@ -210,19 +210,9 @@ static bool isZeroSizedArray(QualType Ty) {
210210 return false ;
211211}
212212
213- static Sema::DeviceDiagBuilder
214- emitDeferredDiagnosticAndNote (Sema &S, SourceRange Loc, unsigned DiagID,
215- SourceRange UsedAtLoc) {
216- Sema::DeviceDiagBuilder builder =
217- S.SYCLDiagIfDeviceCode (Loc.getBegin (), DiagID);
218- if (UsedAtLoc.isValid ())
219- S.SYCLDiagIfDeviceCode (UsedAtLoc.getBegin (), diag::note_sycl_used_here);
220- return builder;
221- }
222-
223- static void checkSYCLVarType (Sema &S, QualType Ty, SourceRange Loc,
224- llvm::DenseSet<QualType> Visited,
225- SourceRange UsedAtLoc = SourceRange()) {
213+ static void checkSYCLType (Sema &S, QualType Ty, SourceRange Loc,
214+ llvm::DenseSet<QualType> Visited,
215+ SourceRange UsedAtLoc = SourceRange()) {
226216 // Not all variable types are supported inside SYCL kernels,
227217 // for example the quad type __float128 will cause errors in the
228218 // SPIR-V translation phase.
@@ -233,16 +223,21 @@ static void checkSYCLVarType(Sema &S, QualType Ty, SourceRange Loc,
233223 // different location than the variable declaration and we need to
234224 // inform the user of both, e.g. struct member usage vs declaration.
235225
226+ bool Emitting = false ;
227+
236228 // --- check types ---
237229
238230 // zero length arrays
239- if (isZeroSizedArray (Ty))
240- emitDeferredDiagnosticAndNote (S, Loc, diag::err_typecheck_zero_array_size,
241- UsedAtLoc);
231+ if (isZeroSizedArray (Ty)) {
232+ S.SYCLDiagIfDeviceCode (Loc.getBegin (), diag::err_typecheck_zero_array_size);
233+ Emitting = true ;
234+ }
242235
243236 // variable length arrays
244- if (Ty->isVariableArrayType ())
245- emitDeferredDiagnosticAndNote (S, Loc, diag::err_vla_unsupported, UsedAtLoc);
237+ if (Ty->isVariableArrayType ()) {
238+ S.SYCLDiagIfDeviceCode (Loc.getBegin (), diag::err_vla_unsupported);
239+ Emitting = true ;
240+ }
246241
247242 // Sub-reference array or pointer, then proceed with that type.
248243 while (Ty->isAnyPointerType () || Ty->isArrayType ())
@@ -253,9 +248,14 @@ static void checkSYCLVarType(Sema &S, QualType Ty, SourceRange Loc,
253248 Ty->isSpecificBuiltinType (BuiltinType::UInt128) ||
254249 Ty->isSpecificBuiltinType (BuiltinType::LongDouble) ||
255250 (Ty->isSpecificBuiltinType (BuiltinType::Float128) &&
256- !S.Context .getTargetInfo ().hasFloat128Type ()))
257- emitDeferredDiagnosticAndNote (S, Loc, diag::err_type_unsupported, UsedAtLoc )
251+ !S.Context .getTargetInfo ().hasFloat128Type ())) {
252+ S. SYCLDiagIfDeviceCode ( Loc. getBegin () , diag::err_type_unsupported)
258253 << Ty.getUnqualifiedType ().getCanonicalType ();
254+ Emitting = true ;
255+ }
256+
257+ if (Emitting && UsedAtLoc.isValid ())
258+ S.SYCLDiagIfDeviceCode (UsedAtLoc.getBegin (), diag::note_used_here);
259259
260260 // --- now recurse ---
261261 // Pointers complicate recursion. Add this type to Visited.
@@ -264,16 +264,15 @@ static void checkSYCLVarType(Sema &S, QualType Ty, SourceRange Loc,
264264 return ;
265265
266266 if (const auto *ATy = dyn_cast<AttributedType>(Ty))
267- return checkSYCLVarType (S, ATy->getModifiedType (), Loc, Visited);
267+ return checkSYCLType (S, ATy->getModifiedType (), Loc, Visited);
268268
269269 if (const auto *RD = Ty->getAsRecordDecl ()) {
270270 for (const auto &Field : RD->fields ())
271- checkSYCLVarType (S, Field->getType (), Field->getSourceRange (), Visited,
272- Loc);
271+ checkSYCLType (S, Field->getType (), Field->getSourceRange (), Visited, Loc);
273272 } else if (const auto *FPTy = dyn_cast<FunctionProtoType>(Ty)) {
274273 for (const auto &ParamTy : FPTy->param_types ())
275- checkSYCLVarType (S, ParamTy, Loc, Visited);
276- checkSYCLVarType (S, FPTy->getReturnType (), Loc, Visited);
274+ checkSYCLType (S, ParamTy, Loc, Visited);
275+ checkSYCLType (S, FPTy->getReturnType (), Loc, Visited);
277276 }
278277}
279278
@@ -284,7 +283,7 @@ void Sema::checkSYCLDeviceVarDecl(VarDecl *Var) {
284283 SourceRange Loc = Var->getLocation ();
285284 llvm::DenseSet<QualType> Visited;
286285
287- checkSYCLVarType (*this , Ty, Loc, Visited);
286+ checkSYCLType (*this , Ty, Loc, Visited);
288287}
289288
290289class MarkDeviceFunction : public RecursiveASTVisitor <MarkDeviceFunction> {
@@ -805,6 +804,22 @@ class SyclKernelFieldChecker
805804 bool IsInvalid = false ;
806805 DiagnosticsEngine &Diag;
807806
807+ void checkAccessorType (QualType Ty, SourceRange Loc) {
808+ assert (Util::isSyclAccessorType (Ty) &&
809+ " Should only be called on SYCL accessor types." );
810+
811+ const RecordDecl *RecD = Ty->getAsRecordDecl ();
812+ if (const ClassTemplateSpecializationDecl *CTSD =
813+ dyn_cast<ClassTemplateSpecializationDecl>(RecD)) {
814+ const TemplateArgumentList &TAL = CTSD->getTemplateArgs ();
815+ TemplateArgument TA = TAL.get (0 );
816+ const QualType TemplateArgTy = TA.getAsType ();
817+
818+ llvm::DenseSet<QualType> Visited;
819+ checkSYCLType (SemaRef, TemplateArgTy, Loc, Visited);
820+ }
821+ }
822+
808823public:
809824 SyclKernelFieldChecker (Sema &S)
810825 : SyclKernelFieldHandler(S), Diag(S.getASTContext().getDiagnostics()) {}
@@ -836,6 +851,15 @@ class SyclKernelFieldChecker
836851 }
837852 }
838853
854+ void handleSyclAccessorType (const CXXBaseSpecifier &BS,
855+ QualType FieldTy) final {
856+ checkAccessorType (FieldTy, BS.getBeginLoc ());
857+ }
858+
859+ void handleSyclAccessorType (FieldDecl *FD, QualType FieldTy) final {
860+ checkAccessorType (FieldTy, FD->getLocation ());
861+ }
862+
839863 // We should be able to handle this, so we made it part of the visitor, but
840864 // this is 'to be implemented'.
841865 void handleArrayType (FieldDecl *FD, QualType FieldTy) final {
@@ -1543,7 +1567,9 @@ Sema::DeviceDiagBuilder Sema::SYCLDiagIfDeviceCode(SourceLocation Loc,
15431567 " Should only be called during SYCL compilation" );
15441568 FunctionDecl *FD = dyn_cast<FunctionDecl>(getCurLexicalContext ());
15451569 DeviceDiagBuilder::Kind DiagKind = [this , FD] {
1546- if (ConstructingOpenCLKernel || !FD)
1570+ if (ConstructingOpenCLKernel)
1571+ return DeviceDiagBuilder::K_ImmediateWithCallStack;
1572+ if (!FD)
15471573 return DeviceDiagBuilder::K_Nop;
15481574 if (getEmissionStatus (FD) == Sema::FunctionEmissionStatus::Emitted)
15491575 return DeviceDiagBuilder::K_ImmediateWithCallStack;
0 commit comments