This is an archive of the discontinued LLVM Phabricator instance.

Allow more lookup of types in dependent base classes
ClosedPublic

Authored by rnk on Jun 20 2014, 5:04 PM.

Details

Summary

MSVC appears to perform name lookup into dependent base classes when the
dependent base class has a known primary template. This allows them to
know whether some unqualified ids are types or not, which allows them to
parse more class templates without typename keywords.

We can do the same thing when type name lookup fails, and if we find a
single type decl in one of our dependent base classes, recover as though
the user wrote 'typename MyClass::TypeFromBase'.

This allows us to parse some COM smart pointer classes in wrl/client.h
from the Windows 8 SDK.

Diff Detail

Repository
rL LLVM

Event Timeline

rnk updated this revision to Diff 10709.Jun 20 2014, 5:04 PM
rnk retitled this revision from to Allow more lookup of types in dependent base classes.
rnk updated this object.
rnk added a reviewer: rsmith.
rnk updated this revision to Diff 10710.Jun 20 2014, 5:16 PM

+cc cfe-commits

rnk added a subscriber: Unknown Object (MLST).Jun 20 2014, 5:17 PM
rnk updated this revision to Diff 10711.Jun 20 2014, 5:17 PM

cfe-commits try 2

rsmith added inline comments.Jun 27 2014, 8:17 AM
lib/Sema/SemaDecl.cpp
139–141 ↗(On Diff #10711)

It'd be nice to also handle deriving from A<T>::B, and so on.

259–268 ↗(On Diff #10711)

I suspect you'll also need to do something like this in ClassifyName.

261–262 ↗(On Diff #10711)

This seems rather specific. I suppose we don't need to worry much about function contexts, because we'll delay-parse most of those, but what about the cases where we don't (auto return type, constexpr functions) and nested classes of class templates? Is it feasible to walk upwards until we see a class template, if we're in a dependent context?

Also, what about a class template within another class template? Should we look in dependent base classes of both?

rnk updated this revision to Diff 10946.Jun 27 2014, 2:40 PM
  • Add recovery to ClassifyName and test template arguments in class scope
lib/Sema/SemaDecl.cpp
139–141 ↗(On Diff #10711)

Thanks for the test! MSVC rejects, though:

template <typename T> struct A { struct B { typedef T InnerType; }; };
template <typename T> struct C : A<T>::B { InnerType m; };

I'll add it as a negative test.

259–268 ↗(On Diff #10711)

Hm, yeah. Looks like that feeds more or less directly into template deduction. I added a bunch of tests for this. It seems that this extra special lookup only applies to types. MSVC doesn't accept unqualified non-type declarations as non-type template arguments, for example.

261–262 ↗(On Diff #10711)

MSVC doesn't support constexpr member functions or auto return types. Eventually, though, they will add support. When they do, they might actually require the use of 'typename Base<T>::', so I'm not inclined to accept code that we think MSVC *might* accept in the future. What do you think?

rsmith accepted this revision.Jul 8 2014, 10:43 AM
rsmith edited edge metadata.

LGTM

test/SemaTemplate/ms-lookup-template-base-classes.cpp
383 ↗(On Diff #10946)

Do you have any tests here for lookup in late-parsed function bodies? (I expect that'll fail too, and probably shouldn't.)

This revision is now accepted and ready to land.Jul 8 2014, 10:43 AM
rnk added a comment.Jul 8 2014, 1:10 PM

thanks!

test/SemaTemplate/ms-lookup-template-base-classes.cpp
383 ↗(On Diff #10946)

Hm, as I add these test cases, I'm starting to think we should generalize the lookup recovery like you suggested. I'll commit this change with more tests and send you a new patch to generalize the check. I'm a more worried because we need to loop over parent DeclContexts to do correct lookup, which I'm less confident about.

rnk closed this revision.Jul 8 2014, 1:14 PM
rnk updated this revision to Diff 11170.

Closed by commit rL212561 (authored by @rnk).