mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-11-10 12:38:28 +00:00
See access_private_parent_member_in_unrelated_class_with_friend.carbon for an example of this fix. The problem with that example, prior to this fix, is that when `Derived::F` is accessed, clang tries to find `F` via `CarbonExternalASTSource::FindExternalVisibleDeclsByName`, but `LookupQualifiedName` doesn't find anything because it (correctly) sees that `F` is a private member of `Base`, so it's not accessible. What it doesn't know is that it will be accessed from the context of `A`, which is a friend of `Base`, and so privacy doesn't matter. `FindExternalVisibleDeclsByName` is really supposed to report visible items, regardless of whether they can be accessed. But changing it to simply ignore access (e.g. by modifying `LookupQualifiedName` to optionally ignore access) doesn't quite work here. This can make a private member of a base class appear within the `DeclContext` of a derived class with access set to private, when it should be set to none. This causes an assert in clang (this case is tested in fail_access_private_parent_member_in_unrelated_fn.carbon). Instead, change `FindExternalVisibleDeclsByName` to call `LookupNameInExactScope` instead of `LookupQualifiedName`. This prevents extended scopes from being searched, so members of a base class are not found when filling in the `DeclContext` of a derived class. Clang will call `FindExternalVisibleDeclsByName` in the context of the base class, and the base class members are added at that time.