This patch adds new error for misplaced ellipsis in template parameter pack. Fixit is suggested for this error and unexpanded parameter pack error. Is new error here acceptable or should this be a note? This will also impact the wording.
Details
Diff Detail
Event Timeline
include/clang/Basic/DiagnosticParseKinds.td | ||
---|---|---|
716 | My 2 cents about this:
| |
test/FixIt/fixit-parameter-pack.cpp | ||
1 | Can we use an existing test instead of adding a new file? e.g. test/FixIt/fixit-cxx0x.cpp? That file already contains similar diagnostics and FixIts. |
include/clang/Basic/DiagnosticParseKinds.td | ||
---|---|---|
716 | I'll go with '...' instead of ellipsis as it does seem to be clearer and more consistent. I am having some trouble with the exact spelling: '...' must immediately precede declared parameter pack | |
test/FixIt/fixit-parameter-pack.cpp | ||
1 | I think that we can, I'll also add tests that use a struct to make sure we have the same result for template and function parameter packs. |
lib/Parse/ParseTemplate.cpp | ||
---|---|---|
358–366 | This one looks fine, but since you're putting the fix-it on the error itself you have to then recover as if the user wrote the pack correctly. | |
lib/Sema/SemaTemplateVariadic.cpp | ||
253–254 | This I'm not so sure about. The place to put the ... might not be directly after the parameter pack, and pretending it is seems questionable. |
lib/Parse/ParseTemplate.cpp | ||
---|---|---|
358–366 | Thanks, I was thinking about this but I wasn't sure how recovery in this case is done? Do I have to modify the existing Decl? Could you point me to code that does something like this? I have a test for this: template<typename Args...> // this would give misplaced ellipsis error void baz(Args args...); // this should give unexpanded parameter pack error but doesn't as Args is not a parameter pack | |
lib/Sema/SemaTemplateVariadic.cpp | ||
253–254 | Could you be a bit more specific, what do you mean by "might not be directly after"?. I'm looking at [temp.variadic] p5 but the only example there is: template<typename... Args> void g(Args ... args) { f(args); } |
By the way, it's considered good form to add cfe-commits as a CC on all Phabricator reviews. Not everyone uses Phabricator.
lib/Parse/ParseTemplate.cpp | ||
---|---|---|
358–366 | You could modify the existing decl by marking it as a pack (something that currently isn't allowed), but you might have better luck just creating a new decl and replacing the existing one. I'm not quite sure what's the right way to go here. +Richard for comment. | |
lib/Sema/SemaTemplateVariadic.cpp | ||
253–254 | Whatever's before the ... gets duplicated. This, for example, is entirely legal: template<typename T> int f(T arg); template<typename... Args> std::vector<int> g(Args ... args) { return { f(args)... }; } g(1, "2", 3.0); |
include/clang/Basic/DiagnosticParseKinds.td | ||
---|---|---|
716 | Please just reuse err_misplaced_ellipsis_in_declaration. "declared identifier" seems fine here; I don't think we need to be more specific. | |
lib/Parse/ParseTemplate.cpp | ||
358–366 | I'd prefer for the misplaced ellipsis detection/recovery to be done earlier. If you do this in ParseTypeParameter / ParseTemplateTemplateParameter, you should be able to create the parameter with the right variadicness (and also do the right thing if the ellipsis is between the parameter and a default argument). | |
lib/Sema/SemaTemplateVariadic.cpp | ||
253–254 | Right. I don't think we can assume we know where the ellipsis should go here. (Well, we could try all possible places and pick one that works, but that seems like massively overkill.) |
I'm not too happy with DiagnoseMisplacedEllipsis but it's still better than having it in two places. The rest should be good.
lib/Parse/ParseTemplate.cpp | ||
---|---|---|
674 | Please move this check to the callers in ParseDecl.cpp, and change this to an assert. | |
676–679 | I don't really like the interface of this function:
Maybe split it into: DiagnoseMisplacedEllipsis(SourceLocation NewLoc, SourceLocation CorrectLoc, bool AlreadyHasEllipsis); DiagnoseMisplacedEllipsisInDeclarator(SourceLocation NewLoc, SourceLocation CorrectLoc, Declarator *D); ... with the second function calling the first? | |
test/FixIt/fixit-cxx0x.cpp | ||
142 ↗ | (On Diff #10117) | Typo Missplaced |
That's sooo much better. I'm still not checking if ellipsis exist on template parameter and template template paremeter, but I don't expect anyone to write something like
template <typename... T...>
Then again... :)
You might have missed the last part of my comment, I clicked submit too soon and had to edit it. In any case I think you're right, it's not hard to detect redundant ellipsis and provide more accurate recovery. Here it is, with tests for this scenario.
LGTM, thanks.
(Yes, I did miss the last part of your comment and then forgot about the part I had seen...)
My 2 cents about this: