[clang-tidy] Diagnostics for Template Code

I am writing a new checker in clang-tidy. I am matching a FieldDecl in a class that is a template instantiation. When trying to print diagnostics using diag(Fd->getLocation(), ...), the source code location shown is the warning points to the template code rather than the template instantiation code. I give an example at the bottom of this post.

On the other hand, clang prints detailed warnings for template code, i.e. prints the instantiation stack. E.g. for the following code,

template <typename T>
void foo(T t) {
  int x = t;

struct S {};

void bar() {

clang gives the template instantiation stack:

test.cpp:3:7: error: no viable conversion from 'S' to 'int'
  int x = t;
      ^   ~
test.cpp:9:3: note: in instantiation of function template specialization 'foo<S>' requested here
1 error generated.

Is there support for better diagnostics in clang-tidy for template code? If not, is there any ongoing work for adding this support?



template <typename T>
class Test {
    T member;

Test<int> a;

I am matching the int member; FieldDecl from the Test<int> instantiation.

When I try to print the diagnostics using this code:

    FieldDecl *ptr = ....
    diags(ptr->getLocation(), "some warning");

the output I get is:

file.cpp:3:5: warning: some warning [checker-name]
    T member;

while a dump() of the FieldDecl gives the following output.

FieldDecl 0x15a0113f8 <path.cpp:3:> col:5 member 'int':'int'

That is my FieldDecl is the AST node from the int instantiation of the class, while the diagnostic output shows the original template code location.

1 Like

Hi guys,

I will really appreciate if you can give any input on this. Thank you!

@gribozavr @NoQ @AaronBallman @alexfh

Sema::EmitCurrentDiagnostic() does that when the diagnostic triggered is not a note (it’s a warning or error) and the diagnostic is emitted within a template instantiation that is different from the previous time an instantiation stack was printed. Clang-tidy uses the same underlying diagnostics engine as Clang, but it does not call Sema::EmitCurrentDiagnostic() when emitting a diagnostic, it uses its own function which doesn’t do anything fancy: llvm-project/ClangTidyDiagnosticConsumer.cpp at main · llvm/llvm-project · GitHub.

I think it would be reasonable to add this kind of support, but I don’t know of anyone actively working on it at the moment.

1 Like