This is an archive of the discontinued LLVM Phabricator instance.

[clang][Index] Fix the incomplete instantiations in libindex.
ClosedPublic

Authored by hokein on Feb 19 2020, 5:49 AM.

Details

Summary

libindex will canonicalize references to template instantiations:

  • 1) reference to an explicit template specialization, report the specializatiion
  • 2) otherwise, report the primary template

but 2) is not true for incomplete instantiations, this patch fixes this.

Fixes https://github.com/clangd/clangd/issues/287

Diff Detail

Event Timeline

hokein created this revision.Feb 19 2020, 5:49 AM
kadircet added inline comments.Feb 20 2020, 12:10 AM
clang/lib/Index/IndexingContext.cpp
175

i believe this might as well be an explicit instantiation, e.g.

template <typename T> struct Foo{};
template <> struct Foo<int>;

void foo(Foo<int>);

could you check what this yield for TKind (and add tests)?

even if this one is also TSK_Undeclared I suppose it is still OK to make use of
TemplatedDecl for indexing purposes, but will likely need some changes in the
function name(ImplicitOrUninstantiated?)/documentation.

175

nit: please use isa instead to emphasize on the fact that we are returning a bool.
also please move it into switch statement.

clang/test/Index/Core/index-source.cpp
324

this looks like a regression, previously when indexing this symbol it was known that first template argument was a SpecializationDecl<Cls> now it is class template instead.

(same for the 2 below)

kadircet added inline comments.Feb 20 2020, 12:11 AM
clang/lib/Index/IndexingContext.cpp
214

maybe return templateddecl iff instantiationpattern is null ?

hokein updated this revision to Diff 245601.Feb 20 2020, 1:20 AM
hokein marked 4 inline comments as done.

address review comments.

clang/lib/Index/IndexingContext.cpp
175

I think explicit instantiation is fine, as it will create a complete specialization, TSK will be TSK_ExplicitInstantiationDeclaration or TSK_ExplicitInstantiationDefinition.

we will get the primary template, no behavior change before/after this patch. Added a test.

clang/test/Index/Core/index-source.cpp
324

yeah, that was my thought previously, but it turns out not -- it is a bug I think, there is no explicit specialization for SpecializationDecl<Cls>, so we should give the primary template.

Take a look on Line 60 of this file, TemplCls<int> gtv(0); it gives the primary class template as well.

kadircet added inline comments.Feb 20 2020, 1:49 AM
clang/lib/Index/IndexingContext.cpp
173

not just instantiation but rather implicit instantiation.

214

nit:

if(const auto *Temp ...)
 return Temp..;
return templateddecl
216

there might be other reasons for not having an instantiation yet (e.g dependent code), maybe just say fallback to class template if no instantiation is available yet?

clang/test/Index/Core/index-instantiated-source.cpp
103

yes this is an explicit instantiation and will have TSKKind set properly.

but i was talking about an explicit specialization in the example above, i.e:

template <> class Foo<float>;

which will still have TSK_Undeclared (I believe, haven't checked).

and let me make myself clear, I am not opposed to the idea of making this also a ref to the primary template instead of the specialization, I just want to make sure we spell it out in the comments and tests explicitly.

104

this is not valid, as you can't define a variable of incomplete type, this needs to be in a function declaration (as I provided in the example) or you can also try making this a pointer as you did below.

i.e.:

void foo(Foo<float>);
clang/test/Index/Core/index-source.cpp
324

yeah makes sense actually, also this is a Ref, not a decl or def so it is not very logical for it to point at some implicit decl.

SGTM

hokein updated this revision to Diff 245608.Feb 20 2020, 2:33 AM
hokein marked 3 inline comments as done.

Add an explicit template declaration (not definition) testcase.

clang/test/Index/Core/index-instantiated-source.cpp
103

Added an explicit specialization declaration (but not definition) case.

In this case, the TSK_Kind is TSK_ExplicitSpecialization, so the result is SpecializationDecl.

104

This is valid code, as this is an explicit instantiation (I thought you meat explicit instantiation).

kadircet accepted this revision.Feb 20 2020, 3:21 AM

LGTM, please fix the formatting warnings though (at least the ones in the implementation)

This revision is now accepted and ready to land.Feb 20 2020, 3:21 AM
hokein updated this revision to Diff 245611.Feb 20 2020, 3:33 AM

Fix the format.

Thanks for the review!

This revision was automatically updated to reflect the committed changes.