clayborg wrote:

> > I didn't see much explanation as to why this is needed in the bug report.
> 
> The motivating example is something like:
> 
> ```
> struct Info {
>   enum Mask : uintptr_t {
>     Enum
>   };
> }
> ```
> 
> `expr Info::Mask::Enum`.
> 
> > Is there a reason we need to complete nested types within a type? Seems 
> > like we can put that off until later. Right now if you parse a member 
> > function, any types it needs will be parsed lazily and only if needed, 
> > which is ok. If we start completing all types within types without ever 
> > needing to actually use then, it will make debugging slower and cause our 
> > memory usage to grow.
> 
> LLDB will first resolve the `Info` structure (and all its member fields, but 
> not nested types). When clang looks for `Mask`, it wants to find it in a 
> direct lookup into the `Info` DeclContext. But that lookup will fail because 
> we never created the decls for the nested type. There is no fallback to the 
> external source in such a case unfortunately so LLDB never has the chance to 
> correct this. There was no obvious point to which we could defer completing 
> the nested type when completing the outer. Maybe adding that external source 
> fallback? But I might've missed something obvious. A potential option would 
> be to limit the completion performed in this patch to enums, though a general 
> solution would be nice.

What we do for classes is we create forward declarations for them at first. As 
soon as someone wants to know more, we complete the type via the external 
source interface. This works for expressions since this is what precomiled 
headers do, it also works with our CompilerType as we can ask for the forward 
type, the layout type, or the complete type. I wonder if we can make this work 
for enums as well. 

I am worried about a class that contains many types. Usually when we need to 
know something about a type, like in your example above, we will get a callback 
to the ClangExternalASTSourceCallbacks methods:
```
  void FindExternalLexicalDecls(
      const clang::DeclContext *DC,
      llvm::function_ref<bool(clang::Decl::Kind)> IsKindWeWant,
      llvm::SmallVectorImpl<clang::Decl *> &Result) override;

  bool FindExternalVisibleDeclsByName(const clang::DeclContext *DC,
                                      clang::DeclarationName Name) override;
```
So if you typed Info::Mask::Enum, the expression parser will first ask about 
"Info" with no containing decl context (or maybe it specifies the translation 
unit decl context to indicate it is a root type) and we will return the "struct 
Info". Then it would call FindExternalVisibleDeclsByName() with the DeclContext 
set to "struct Info" and we will find "Mask" inside of this type, then it will 
ask about "Enum" within the "Info::Mask" type and it should be in the type 
definition. Maybe some isn't working correctly for enums in this lookup 
mechanism?



https://github.com/llvm/llvm-project/pull/66879
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to