nridge marked an inline comment as done.
nridge added inline comments.

================
Comment at: clang-tools-extra/clangd/XRefs.cpp:885
+static Optional<TypeHierarchyItem>
+getTypeHierarchy(const CXXRecordDecl &CXXRD, ASTContext &ASTCtx, int Levels,
+                 TypeHierarchyDirection Direction) {
----------------
nridge wrote:
> sammccall wrote:
> > kadircet wrote:
> > > nridge wrote:
> > > > sammccall wrote:
> > > > > The scope and complexity of this function seems unneccesarily large:
> > > > >  - it's (in future?) capable of resolving in both directions
> > > > >  - it calls itself recursively, modifying TypeHierarchyDirection to 
> > > > > control the search
> > > > >  - it handles levels, even though this optimization is only important 
> > > > > for derived types
> > > > > 
> > > > > Can we restrict this to retrieving (all) recursive base types?
> > > > > i.e. `Optional<TypeHierarchyItem> getTypeAncestors(const 
> > > > > CXXRecordDecl &CXXRD, ASTContext &Ctx)`
> > > > > Then later, subtype resolution can be the job of another function: 
> > > > > `resolveTypeDescendants(TypeHierarchyItem& Item, int depth)`
> > > > > 
> > > > > That way the recursion of getTypeAncestors is simpler to understand, 
> > > > > as it has much smaller scope. And code sharing between the two LSP 
> > > > > calls is clearer: fetching type hierarchy is a call to 
> > > > > `getTypeAncestors` and a call to `resolveTypeDescendants` (if 
> > > > > direction is children or both, and resolve is > 0), and resolving a 
> > > > > hierarchy is a call to `resolveTypeDescendants`.
> > > > If we remove "levels" here, should we introduce some kind of guard for 
> > > > infinite recursion, in case the user writes something like:
> > > > 
> > > > ```
> > > > template <int N>
> > > > struct S : S<N + 1> {};
> > > > 
> > > > S<0> s;
> > > > ```
> > > clang should be limiting recursive template instantiations. Also since we 
> > > are just traversing the AST produced by clang, it should never be 
> > > infinite, but still a nice test case can you add one?
> > I think there is a point here...
> > 
> > Consider our `S` template with the direction reversed and a base case 
> > specialized:
> > ```
> > template <int N>
> > struct S : S<N - 1> {};
> > template<>
> > struct S<0>{};
> > 
> > S<2> instance;
> > ```
> > 
> > Now the hierarchy of `S<2>` is well defined and finite: `S<2> : S<1> : 
> > S<0>`.
> > However IIUC the `CXXRecordDecl` for `S<2>` is the instantiation of the 
> > primary template, whose base is `S<N - 1>`, which is dependent[1], so the 
> > base's `CXXRecordDecl` is the primary template, whose base is `S<N - 1>`... 
> > and we never reach the base case.
> > 
> > Actually I'm not sure whether this happens if the base is dependent merely 
> > where it's spelled, or still dependent after instantiation? Even in the 
> > latter case one can construct examples where we'll infloop:
> > ```template <int N>
> > struct Foo {
> >   S<N> instance;
> > }```
> > Trying to get the hierarchy on `S<N>` could infloop. (I agree these should 
> > both be test cases)
> > 
> > What's the Right Thing?
> >  - not sure about a recursion limit, as showing 10 `S<N-1>`s in the 
> > hierarchy is silly.
> >  - not sure about bailing out on dependent types either, as knowing that 
> > e.g. my `SmallSet<T>` inherits from `SmallMap<T, bool>` is meaningful or 
> > useful.
> >  - maybe we should bail out once we see instantiations of the same template 
> > decl twice in a parent chain. I.e. keep the seen non-null 
> > `CXXRecordDecl->getTemplateInstantiationPattern()`s in a set and stop 
> > recursing if insertion fails.
> > 
> > However for this patch I'd suggest just bailing out on dependent types with 
> > a TODO as the simplest, this is an edge case that can be fixed later.
> > 
> The current patch does actually recurse infinitely on this test case, likely 
> for the reasons Sam outlined (our handling of dependent types), and 
> eventually runs into the segfault.
> 
> I will update the patch to address this.
I meant to say "eventually runs into a stack overflow".


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D56370/new/

https://reviews.llvm.org/D56370



_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to