When we have a DeclContext from a module (i.e., the isFromASTFile flag is set on the respective Decl),
Clang expects ExternalASTSource:: FindExternalVisibleDeclsByName to build the lookup in and set
ExternalVisibleStorage as described by the comment in DeclContext::buildLookupImpl:
// If it's from an AST file, don't add it now. It'll get handled by // FindExternalVisibleDeclsByName if needed. [...]
We already mostly implemented FindExternalVisibleDeclsByName in LLDB and we already set ExternalVisibleStorage
when building the AST for our symbol file. However, when we import a Decl from one AST to another and
copy over the Decl, we only set the IsFromASTFile bit but didn't enable ExternalVisibleStorage if the
Decl is also a DeclContext.
This patch sets ExternalVisibleStorage for all DeclContexts that are from a module (which seems to be expected
by Clang). I also expanded the implementation of FindExternalVisibleDeclsByName to cover all Decl kinds
and not just Objective-C methods.
I also removed that when we "Complete" a type that we unset the ExternalVisibleStorage flag. The reason for that
is that even when we have all Decls loaded in a DeclContext and we consider the type "Complete" from LLDB's
perspective, we still might need to build the lookup for some declarations from the ExternalASTSource.
One strange situation that I found while debugging this is that we set the 'owning module' in LLDB after we imported
a declaration. However we have some situations where between the Import and the Imported callback some part of Clang
decides to inspect a Declaration we just added. In that case we build the lookup as if the Decl is not from a module.
So the lookup failure we were seeing only appear if Clang doesn't decide to do a build the lookup before LLDB actually
marks an imported Decl as being owned by a module/coming from an AST file.
The change to module-ownership.mm is that I removed that we allow the <undeserialized declarations> in the test.
It seems the idea was to make the test pass even when there are no <undeserialized declarations> in that struct,
but because of the extra space after {{.*}} the test fails when we don't have <undeserialized declarations> in the
output. In any case, given that the struct has only one member, there shouldn't be any <undeserialized declarations>
when we dump it and see that one member, so the previous test was anyway too permissive. I'm not sure why that
case didn't work before, but given that it apparently fixes this test, I didn't investigate this yet.
That makes sense, thanks!