[PATCH] D42170: Fixit for 'typedef' instead of 'typename' typo

Volodymyr Sapsai via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Tue Jan 23 11:31:43 PST 2018


vsapsai added inline comments.


================
Comment at: Parse/ParseTemplate.cpp:492
+  // Is there just a typo in the input code? ('typedef' instead of 'typename')
+  if (Tok.is(tok::kw_typedef)) {
+    Diag(Tok.getLocation(), diag::err_expected_template_parameter);
----------------
jkorous-apple wrote:
> vsapsai wrote:
> > How does it work when you have `typedef` for the first template parameter?
> It works all right but I am puzzled by your question now :-)
> 
> 
> ```
> /Users/jankorous/src/oss/llvm/llvm/tools/clang/test/Parser/typedef-instead-of-typename-typo.hpp:3:11: error: expected template parameter
> template <typedef A, typename B> struct Foo {
>           ^
> /Users/jankorous/src/oss/llvm/llvm/tools/clang/test/Parser/typedef-instead-of-typename-typo.hpp:3:11: note: Did you mean to use 'typename'?
> template <typedef A, typename B> struct Foo {
>           ^~~~~~~
>           typename
> fix-it:"/Users/jankorous/src/oss/llvm/llvm/tools/clang/test/Parser/typedef-instead-of-typename-typo.hpp":{3:11-3:18}:"typename"
> /Users/jankorous/src/oss/llvm/llvm/tools/clang/test/Parser/typedef-instead-of-typename-typo.hpp:4:3: error: unknown type name 'a'
>   a
>   ^
> 
> ```
> 
> I am probably not following you here. Do you have any specific reason on your mind? Anything I should think about or check in the source code?
I was suspicious that
```lang=c++
  if (isStartOfTemplateTypeParameter())
    return ParseTypeParameter(Depth, Position);
```
earlier in the function won't let your code run for the first template parameter. But `isStartOfTemplateTypeParameter` has
```lang=c++
  if (Tok.isNot(tok::kw_typename))
    return false;
```
so everything works fine.


================
Comment at: Parser/typedef-instead-of-typename-typo.hpp:5
+  a
+}; // CHECK: expected-error{{expected template parameter}} \
+// CHECK: expected-note{{Did you mean to use 'typename'?}} \
----------------
jkorous-apple wrote:
> vsapsai wrote:
> > It is a little bit confusing to what lines the messages would be attributed to. Need to check locally because not sure I interpret all those backslashes the same way lit does.
> > 
> > Also idea for the test. To check that the fix-it was applied properly you can add a member like `B b;` and it shouldn't trigger any errors.
> I am totally open to suggestions how to write better tests using FileCheck. As far as I understand it I have to keep the expected-* macro on the same line as the code. Or is there any better way?
> 
> Do I understand it right that you suggest to create another test in which to try applying fixit and check that compilation was successful? Do you mean to create compile_commands.json temporarily and use clang-check -fixit?
> 
> 
To answer your question. You can keep the expected-* macro on the same line and attach subsequent expectations with backslash. Another option is doing something like `expected-note at -1 {{...}}`. That `-1` is a relative line number.

Back to the test case. I believe you need to separate expected-* checks from fixit output check. The former uses `-verify` and the latter `| FileCheck %s`. I think test/FixIt/fixit-vexing-parse.cpp is a good example. And remember that you can split long lines, `template <typename A, typedef B> struct Foo` doesn't have to be on the same line.

For suggested test I didn't mean anything fancy. Just something like adding a line `B b;` Because currently for
```lang=c++
template <typename A, typedef B> 
struct Foo {
    B b;
};
```
the output is
```
recovery.cc:1:31: error: unknown type name 'B'
template <typename A, typedef B>
                              ^
recovery.cc:3:5: error: unknown type name 'B'
    B b;
    ^
2 errors generated.
```
And with your change we won't have the second error.


https://reviews.llvm.org/D42170





More information about the cfe-commits mailing list