@@ -392,85 +392,82 @@ void SemaSYCL::CheckSYCLEntryPointFunctionDecl(FunctionDecl *FD) {
392392
393393ExprResult SemaSYCL::BuildSYCLKernelLaunchIdExpr (FunctionDecl *FD,
394394 QualType KNT) {
395+ // The current context must be the function definition context to ensure
396+ // that name lookup is performed within the correct scope.
397+ assert (SemaRef.CurContext == FD);
395398
396- ASTContext &Ctx = SemaRef.getASTContext ();
397- // Some routines need a valid source location to work correctly.
398- SourceLocation BodyLoc =
399- FD->getEndLoc ().isValid () ? FD->getEndLoc () : FD->getLocation ();
399+ // An appropriate source location is required to emit diagnostics if
400+ // lookup fails to produce an overload set. The desired location is the
401+ // start of the function body, but that is not yet available since the
402+ // body of the function has not yet been set when this function is called.
403+ // The general location of the function is used instead.
404+ SourceLocation Loc = FD->getLocation ();
400405
401- IdentifierInfo &LaunchFooName =
406+ ASTContext &Ctx = SemaRef.getASTContext ();
407+ IdentifierInfo &SYCLKernelLaunchID =
402408 Ctx.Idents .get (" sycl_kernel_launch" , tok::TokenKind::identifier);
403409
404- // Perform overload resolution for a call to an accessible (member) function
405- // template named 'sycl_kernel_launch' "from within the definition of
406- // FD where":
407- // - The kernel name type is passed as the first template argument.
408- // - Any remaining template parameters are deduced from the function
409- // arguments or assigned by default template arguments.
410- // - 'this' is passed as the implicit function argument if 'FD' is a
411- // non-static member function.
412- // - The name of the kernel, expressed as a string literal, is passed as the
413- // first function argument.
414- // - The parameters of FD are forwarded as-if by 'std::forward()' as the
415- // remaining explicit function arguments.
416- // - Any remaining function arguments are initialized by default arguments.
417- LookupResult Result (SemaRef, &LaunchFooName, BodyLoc,
410+ // Perform ordinary name lookup for a function or variable template that
411+ // accepts a single type template argument.
412+ LookupResult Result (SemaRef, &SYCLKernelLaunchID, Loc,
418413 Sema::LookupOrdinaryName);
419- CXXScopeSpec SS;
420- SemaRef.LookupTemplateName (Result, SemaRef.getCurScope (), SS,
421- /* ObjectType=*/ QualType (),
422- /* EnteringContext=*/ false , BodyLoc);
414+ CXXScopeSpec EmptySS;
415+ SemaRef.LookupTemplateName (Result, SemaRef.getCurScope (), EmptySS,
416+ /* ObjectType*/ QualType (),
417+ /* EnteringContext*/ false ,
418+ Sema::TemplateNameIsRequired);
423419
424420 if (Result.empty () || Result.isAmbiguous ()) {
425- SemaRef.Diag (BodyLoc , SemaRef.getLangOpts ().SYCLIsHost
426- ? diag::err_sycl_host_no_launch_function
427- : diag::warn_sycl_device_no_host_launch_function);
428- SemaRef.Diag (BodyLoc , diag::note_sycl_host_launch_function);
421+ SemaRef.Diag (Loc , SemaRef.getLangOpts ().SYCLIsHost
422+ ? diag::err_sycl_host_no_launch_function
423+ : diag::warn_sycl_device_no_host_launch_function);
424+ SemaRef.Diag (Loc , diag::note_sycl_host_launch_function);
429425
430426 return ExprError ();
431427 }
432428
433- TemplateArgumentListInfo TALI{BodyLoc, BodyLoc };
429+ TemplateArgumentListInfo TALI{Loc, Loc };
434430 TemplateArgument KNTA = TemplateArgument (KNT);
435431 TemplateArgumentLoc TAL =
436- SemaRef.getTrivialTemplateArgumentLoc (KNTA, QualType (), BodyLoc );
432+ SemaRef.getTrivialTemplateArgumentLoc (KNTA, QualType (), Loc );
437433 TALI.addArgument (TAL);
438434 ExprResult IdExpr;
439- if (SemaRef.isPotentialImplicitMemberAccess (SS, Result,
440- /* IsAddressOfOperand=*/ false ))
441- // BuildPossibleImplicitMemberExpr creates UnresolvedMemberExpr. Using it
442- // allows to pass implicit/explicit this argument automatically.
443- IdExpr = SemaRef.BuildPossibleImplicitMemberExpr (SS, BodyLoc, Result, &TALI,
435+ if (SemaRef.isPotentialImplicitMemberAccess (EmptySS, Result,
436+ /* IsAddressOfOperand*/ false ))
437+ // The lookup result allows for a possible implicit member access that
438+ // would require an implicit or explicit 'this' argument.
439+ IdExpr = SemaRef.BuildPossibleImplicitMemberExpr (EmptySS, SourceLocation (),
440+ Result, &TALI,
444441 SemaRef.getCurScope ());
445442 else
446- IdExpr = SemaRef.BuildTemplateIdExpr (SS, BodyLoc , Result,
447- /* RequiresADL= */ true , &TALI);
443+ IdExpr = SemaRef.BuildTemplateIdExpr (EmptySS, SourceLocation () , Result,
444+ /* RequiresADL*/ true , &TALI);
448445
449- // Can happen if SKEP attributed function is a static member, but the launcher
450- // is a regular member. Perhaps emit a note saying that we're in host code
451- // synthesis.
446+ // The resulting expression may be invalid if, for example, 'FD' is a
447+ // non-static member function and sycl_kernel_launch lookup selects a
448+ // member function (which would require a 'this' argument which is
449+ // not available).
452450 if (IdExpr.isInvalid ())
453451 return ExprError ();
454452
455453 return IdExpr;
456454}
457455
458- StmtResult SemaSYCL::BuildUnresolvedSYCLKernelCallStmt (CompoundStmt *CS,
459- Expr *IdExpr) {
460- return UnresolvedSYCLKernelCallStmt::Create (SemaRef.getASTContext (), CS,
461- IdExpr);
462- }
463-
464456namespace {
465457
466- void PrepareKernelArgumentsForKernelLaunch (SmallVectorImpl<Expr *> &Args,
467- const SYCLKernelInfo *SKI,
468- Sema &SemaRef,
469- SourceLocation Loc) {
470- assert (SKI && " Need a kernel!" );
471- ASTContext &Ctx = SemaRef.getASTContext ();
458+ // Constructs the arguments to be passed for the SYCL kernel launch call.
459+ // The first argument is a string literal that contains the SYCL kernel
460+ // name. The remaining arguments are the parameters of 'FD'.
461+ void BuildSYCLKernelLaunchCallArgs (Sema &SemaRef, FunctionDecl *FD,
462+ const SYCLKernelInfo *SKI,
463+ SmallVectorImpl<Expr *> &Args,
464+ SourceLocation Loc) {
465+ // The current context must be the function definition context to ensure
466+ // that parameter references occur within the correct scope.
467+ assert (SemaRef.CurContext == FD);
472468
473469 // Prepare a string literal that contains the kernel name.
470+ ASTContext &Ctx = SemaRef.getASTContext ();
474471 const std::string KernelName = SKI->GetKernelName ();
475472 QualType KernelNameCharTy = Ctx.CharTy .withConst ();
476473 llvm::APInt KernelNameSize (Ctx.getTypeSize (Ctx.getSizeType ()),
@@ -482,30 +479,23 @@ void PrepareKernelArgumentsForKernelLaunch(SmallVectorImpl<Expr *> &Args,
482479 /* Pascal*/ false , KernelNameArrayTy, Loc);
483480 Args.push_back (KernelNameExpr);
484481
485- // Right now we simply forward the arguments of the skep-attributed function.
486- // With decomposition present there can be another logic.
487- // Make sure to use CurContext to avoid diagnostics that we're using a
488- // variable coming from another context. The function should be the same as in
489- // the kernel info though.
490- auto *FD = cast<FunctionDecl>(SemaRef.CurContext );
491- assert (declaresSameEntity (FD, SKI->getKernelEntryPointDecl ()));
492482 for (ParmVarDecl *PVD : FD->parameters ()) {
493483 QualType ParamType = PVD->getOriginalType ().getNonReferenceType ();
494484 Expr *DRE = SemaRef.BuildDeclRefExpr (PVD, ParamType, VK_LValue, Loc);
495- assert (DRE);
496485 Args.push_back (DRE);
497486 }
498487}
499488
500- StmtResult BuildSYCLKernelLaunchStmt (Sema &SemaRef,
501- const SYCLKernelInfo *SKI,
502- Expr *IdExpr, SourceLocation Loc) {
489+ // Constructs the SYCL kernel launch call.
490+ StmtResult BuildSYCLKernelLaunchCallStmt (Sema &SemaRef, FunctionDecl *FD,
491+ const SYCLKernelInfo *SKI,
492+ Expr *IdExpr, SourceLocation Loc) {
503493 SmallVector<Stmt *> Stmts;
504- assert (SKI && " Need a Kernel!" );
505494
495+ // IdExpr may be null if name lookup failed.
506496 if (IdExpr) {
507497 llvm::SmallVector<Expr *, 12 > Args;
508- PrepareKernelArgumentsForKernelLaunch (Args, SKI, SemaRef , Loc);
498+ BuildSYCLKernelLaunchCallArgs (SemaRef, FD, SKI, Args , Loc);
509499 ExprResult LaunchResult =
510500 SemaRef.BuildCallExpr (SemaRef.getCurScope (), IdExpr, Loc, Args, Loc);
511501 if (LaunchResult.isInvalid ())
@@ -630,14 +620,20 @@ StmtResult SemaSYCL::BuildSYCLKernelCallStmt(FunctionDecl *FD,
630620 BuildSYCLKernelEntryPointOutline (SemaRef, FD, Body);
631621 assert (OFD);
632622
633- // Build host kernel launch stmt.
634- SourceLocation BodyLoc =
635- FD-> getEndLoc (). isValid () ? FD-> getEndLoc () : FD-> getLocation ();
636- StmtResult LaunchRes =
637- BuildSYCLKernelLaunchStmt (SemaRef, &SKI, LaunchIdExpr, BodyLoc );
623+ // Build the host kernel launch statement. An appropriate source location
624+ // is required to emit diagnostics.
625+ SourceLocation Loc = Body-> getLBracLoc ();
626+ StmtResult LaunchResult =
627+ BuildSYCLKernelLaunchCallStmt (SemaRef, FD, &SKI, LaunchIdExpr, Loc );
638628
639629 Stmt *NewBody =
640- new (getASTContext ()) SYCLKernelCallStmt (Body, LaunchRes .get (), OFD);
630+ new (getASTContext ()) SYCLKernelCallStmt (Body, LaunchResult .get (), OFD);
641631
642632 return NewBody;
643633}
634+
635+ StmtResult SemaSYCL::BuildUnresolvedSYCLKernelCallStmt (CompoundStmt *Body,
636+ Expr *LaunchIdExpr) {
637+ return UnresolvedSYCLKernelCallStmt::Create (SemaRef.getASTContext (), Body,
638+ LaunchIdExpr);
639+ }
0 commit comments