-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[SYCL] Basic diagnostics for the sycl_kernel_entry_point attribute. #120327
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
6ed96d3
0b7f6bf
0e89f39
5eeff88
97f58f4
da651f6
c0044ab
1a0898f
977f4fa
b30dd84
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -52,6 +52,7 @@ | |
| #include "clang/Sema/SemaOpenMP.h" | ||
| #include "clang/Sema/SemaPPC.h" | ||
| #include "clang/Sema/SemaRISCV.h" | ||
| #include "clang/Sema/SemaSYCL.h" | ||
| #include "clang/Sema/SemaSwift.h" | ||
| #include "clang/Sema/SemaWasm.h" | ||
| #include "clang/Sema/Template.h" | ||
|
|
@@ -3018,6 +3019,15 @@ static void checkNewAttributesAfterDef(Sema &S, Decl *New, const Decl *Old) { | |
| // declarations after definitions. | ||
| ++I; | ||
| continue; | ||
| } else if (isa<SYCLKernelEntryPointAttr>(NewAttribute)) { | ||
| // Elevate latent uses of the sycl_kernel_entry_point attribute to an | ||
| // error since the definition will have already been created without | ||
| // the semantic effects of the attribute having been applied. | ||
| S.Diag(NewAttribute->getLocation(), | ||
| diag::err_sycl_entry_point_after_definition); | ||
| S.Diag(Def->getLocation(), diag::note_previous_definition); | ||
| ++I; | ||
| continue; | ||
| } | ||
|
|
||
| S.Diag(NewAttribute->getLocation(), | ||
|
|
@@ -12146,7 +12156,7 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, | |
| OpenMP().ActOnFinishedFunctionDefinitionInOpenMPAssumeScope(NewFD); | ||
|
|
||
| if (LangOpts.isSYCL() && NewFD->hasAttr<SYCLKernelEntryPointAttr>()) | ||
| getASTContext().registerSYCLEntryPointFunction(NewFD); | ||
| SYCL().CheckSYCLEntryPointFunctionDecl(NewFD); | ||
|
|
||
| // Semantic checking for this function declaration (in isolation). | ||
|
|
||
|
|
@@ -15978,6 +15988,24 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, | |
| CheckCoroutineWrapper(FD); | ||
| } | ||
|
|
||
| // Diagnose invalid SYCL kernel entry point function declarations. | ||
| if (FD && !FD->isInvalidDecl() && !FD->isTemplated() && | ||
erichkeane marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| FD->hasAttr<SYCLKernelEntryPointAttr>()) { | ||
| if (FD->isDeleted()) { | ||
| Diag(FD->getAttr<SYCLKernelEntryPointAttr>()->getLocation(), | ||
| diag::err_sycl_entry_point_invalid) | ||
| << /*deleted function*/ 2; | ||
| } else if (FD->isDefaulted()) { | ||
| Diag(FD->getAttr<SYCLKernelEntryPointAttr>()->getLocation(), | ||
| diag::err_sycl_entry_point_invalid) | ||
| << /*defaulted function*/ 3; | ||
| } else if (FSI->isCoroutine()) { | ||
| Diag(FD->getAttr<SYCLKernelEntryPointAttr>()->getLocation(), | ||
| diag::err_sycl_entry_point_invalid) | ||
| << /*coroutine*/ 7; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When these get this high, an enum typically makes sense instead of comments (which get lost/etc).
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you point me to an example? I haven't been able to find one. It doesn't look like there is a way to declare an enum with the diagnostic definition. Without the ability to do so, I don't see how adding an intermediate enum somewhere else improves the situation.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, there isn't a convenient way of doing so in the diagnostics engine unfortunately. I'd love for us to have that! But typically we just define it elsewhere. For large lists like this it can make it significantly more readable, and much less likely to not be updated because of a copy/paste error (which happens OFTEN). See
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for pointing me to those examples. For both For simple diagnostics, where the
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I still disagree strongly. Any time where there are more than 2-3 options, and are used in more than 1 or 2 places, it vastly improves readability and prevents bugs of printing the wrong thing. We can have a second opinion from Aaron, but this is something pretty important to me as code-owner.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's a judgement call either way, IMO. Personally, I dislike using one-shot enumerations because they're overkill for what they're used for. The in-line comment saying "this value corresponds to that selection" is plenty to keep the code readable. However, I do like using enumerations when the enum is used for selecting the diagnostic and some other purpose. e.g., In this specific case, I lean towards not needing the enumeration because then we have to figure out where that lives (Are we making That said, coming up with some tablegen syntax that allows someone to associate enumerations with the diagnostic definition itself would be a pretty interesting idea to explore because then we'd get something that could be consistently applied and doesn't require as much maintenance and review effort. e.g., that code then be used like: (Though I think we may want to find some better place for the enum to live so that uses in calls to
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks, @AaronBallman. I like the suggested tablegen approach and would be happy to use that if someone (other than me) implemented it! I share your perspective on one-shot enumerations. I'll leave the code as is for now. @erichkeane, as a compromise, I would be happy to split this diagnostic into eight distinct ones to avoid the situation all together. I don't think we gain much by using a single diagnostic in the first place. Let me know if you would prefer that.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd prefer we don't split into separate diagnostics; that increases overhead and maintenance burden for very little gain IMO. We generally prefer using |
||
| } | ||
| } | ||
|
|
||
| { | ||
| // Do not call PopExpressionEvaluationContext() if it is a lambda because | ||
| // one is already popped when finishing the lambda in BuildLambdaExpr(). | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1550,6 +1550,8 @@ NamedDecl *Sema::ActOnNonTypeTemplateParameter(Scope *S, Declarator &D, | |
| IdResolver.AddDecl(Param); | ||
| } | ||
|
|
||
| ProcessDeclAttributes(S, Param, D); | ||
|
||
|
|
||
| // C++0x [temp.param]p9: | ||
| // A default template-argument may be specified for any kind of | ||
| // template-parameter that is not a template parameter pack. | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.