Michael137 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?

Yup that was my understanding too. Though last I stepped through clang lookup 
for this case the call back into LLDB to get `Mask` in the `Info` DeclContext 
wasn't being done. It has been a while since I looked at this so I'll double 
check when I get the chance

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