nridge added inline comments.

================
Comment at: clang-tools-extra/clangd/SemanticHighlighting.cpp:177
       return;
+    if (TP->isPointerType() || TP->isLValueReferenceType())
+      // When highlighting dependant template types the type can be a pointer 
or
----------------
ilya-biryukov wrote:
> jvikstrom wrote:
> > ilya-biryukov wrote:
> > > ilya-biryukov wrote:
> > > > jvikstrom wrote:
> > > > > ilya-biryukov wrote:
> > > > > > jvikstrom wrote:
> > > > > > > ilya-biryukov wrote:
> > > > > > > > jvikstrom wrote:
> > > > > > > > > ilya-biryukov wrote:
> > > > > > > > > > `RecursiveASTVisitor` also traverses the pointer and 
> > > > > > > > > > reference types, why does it not reach the inner 
> > > > > > > > > > `TemplateTypeParmType` in the cases you describe?
> > > > > > > > > The D in `using D = ...` `typedef ... D` does not have a 
> > > > > > > > > TypeLoc (at least not one that is visited). Therefore we use 
> > > > > > > > > the VisitTypedefNameDecl (line 121) to get the location of 
> > > > > > > > > `D` to be able to highlight it. And we just send the typeLocs 
> > > > > > > > > typeptr to addType (which is a Pointer for `using D = T*;`)...
> > > > > > > > > 
> > > > > > > > > But maybe we should get the underlying type before we call 
> > > > > > > > > addType with TypePtr? Just a while loop on line 123 basically 
> > > > > > > > > (can we have multiple PointerTypes nested in each other 
> > > > > > > > > actually?)
> > > > > > > > > 
> > > > > > > > > Even if we keep it in addType the comment is actually wrong, 
> > > > > > > > > because it obviously works when for the actual "type 
> > > > > > > > > occurrences" for `D` (so will fix that no matter what). This 
> > > > > > > > > recursion will just make us add more duplicate tokens...
> > > > > > > > Could we investigate why `RecursiveASTVisitor` does not visit 
> > > > > > > > the `TypeLoc` of a corresponding decl?
> > > > > > > > Here's the code from `RecursiveASTVisitor.h` that should do the 
> > > > > > > > trick:
> > > > > > > > ```
> > > > > > > > DEF_TRAVERSE_DECL(TypeAliasDecl, {
> > > > > > > >   TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
> > > > > > > >   // We shouldn't traverse D->getTypeForDecl(); it's a result of
> > > > > > > >   // declaring the type alias, not something that was written 
> > > > > > > > in the
> > > > > > > >   // source.
> > > > > > > > })
> > > > > > > > ```
> > > > > > > > 
> > > > > > > > If it doesn't, we are probably holding it wrong.
> > > > > > > There just doesn't seem to be a TypeLoc for the typedef'ed Decl.  
> > > > > > > We can get the `T*` TypeLoc (with 
> > > > > > > `D->getTypeSourceInfo()->getTypeLoc()`). But there isn't one for 
> > > > > > > `D`. Even the `D->getTypeForDecl` returns null.
> > > > > > > 
> > > > > > > And I have no idea where I'd even start debugging that. Or if 
> > > > > > > it's even a bug
> > > > > > > 
> > > > > > I may have misinterpreted the patch. Are we trying to add 
> > > > > > highlightings for the names of using aliases here? E.g. for the 
> > > > > > following range:
> > > > > > ```
> > > > > > template <class T>
> > > > > > struct Foo {
> > > > > >   using [[D]] = T**;
> > > > > > };
> > > > > > ```
> > > > > > 
> > > > > > Why isn't this handled in `VisitNamedDecl`?
> > > > > > We don't seem to call this function for `TypedefNameDecl` at all 
> > > > > > and it actually weird. Is this because we attempt to highlight 
> > > > > > typedefs as their underlying types?
> > > > > So currently using aliases and typedefs are highlighted the same as 
> > > > > the underlying type (in most cases). One case where they aren't is 
> > > > > when the underlying type is a template parameter (which is what this 
> > > > > patch is trying to solve).
> > > > > 
> > > > > 
> > > > > > Why isn't this handled in VisitNamedDecl?
> > > > > 
> > > > > The Decl is actually visited in `VisitNamedDecl`, however as it is a 
> > > > > `TypeAliasDecl` which we do not have a check for in the addToken 
> > > > > function it will not get highlighted in that visit.
> > > > > 
> > > > > Actually, could add a check for `TypeAliasDecl` in `addToken` (should 
> > > > > probably be a check for `TypedefNameDecl` to cover both `using ...` 
> > > > > and `typedef ...`) and move the code from the `VisitTypedefNameDecl` 
> > > > > to the `addToken` function inside that check instead.
> > > > > 
> > > > > 
> > > > > 
> > > > > > We don't seem to call this function for TypedefNameDecl at all and 
> > > > > > it actually weird. Is this because we attempt to highlight typedefs 
> > > > > > as their underlying types?
> > > > > 
> > > > > 
> > > > > Don't understand what you mean. What function? 
> > > > > So currently using aliases and typedefs are highlighted the same as 
> > > > > the underlying type (in most cases). 
> > > > Thanks for clarifying this. This is where my confusion is coming from.
> > > > A few question to try understanding the approach taken (sorry if that's 
> > > > too detailed, I am probably missing the context here)
> > > > - What do we fallback to? From my reading of the code, we do not 
> > > > highlight them at all if the underlying type is not one of the 
> > > > predefined cases.
> > > > - Why are pointers and **l-value** references special? What about 
> > > > arrays, r-value references, function types, pack expansions, etc.?
> > > > 
> > > > > Don't understand what you mean. What function?
> > > > We don't call `VisitNamedDecl` from `VisitTypedefNameDecl`. I guess 
> > > > that's intentional if we try to highlight them as underlying types.
> > > Summarizing the offline discussion:
> > > - we chose to highlight typedefs same as their underlying type (e.g. if 
> > > it's a class we highlight the typedef as class too)
> > > - we need to ensure all typdefs are highlighted in **some** color. That 
> > > means we need to handle all composite types in this function and recurse 
> > > into those. That involves handling at least functions, arrays, all 
> > > reference types (not just l-value references).
> > > - we should add tests for this.
> > > 
> > > @jvikstrom, please let me know if I missed something.
> > > we chose to highlight typedefs same as their underlying type (e.g. if 
> > > it's a class we highlight the typedef as class too)
> > 
> > So this version should do that. For the typedef part.
> > 
> > When there are references with typedefs 
> > `SomeTypedefTypeThatIsNotBuiltinAndHasNoTagDecl R = ...` this will not 
> > highlight the `SomeTypedefTypeThatIsNotBuiltinAndHasNoTagDecl` because 
> > RecursiveASTVisitor does not traverse into typedeftypelocs, so we'd need to 
> > add the getUnderlyingType thing in VisitTypeLoc as well.
> > Also need to do this for auto.
> > 
> > And, does it make sense to highlight function typedefs as their return type?
> > 
> > 
> > But I'm a bit worried this current approach might not be really sensible.
> > The 'short circuit'  when we find a TagDecl is because otherwise we get 
> > weird results at times. (for example TemplateInstantiations, if 
> > instantiated with a builtin we'd highlight that as a Primitive while it 
> > should be a class because of traversal order)
> > 
> > I guess it would be possible to create a TypeVisitor kind of like how you 
> > get deduced types from a typeptr, but that would be a lot of boilerplate.
> > 
> > Maybe what we could do instead of stopping the traversal early when finding 
> > a TagDecl is add one field for each Leaf type in UnderlyingTypeVisitor. 
> > When returning we'd then return the Record if there is one or Enum if there 
> > is one, ... , or a Builtin if none of the others exist.
> > 
> > Is there maybe some other way of finding the "correct" type for a type 
> > hierarchy or maybe doing the very basic ranking would be enough? (Record > 
> > Enum > TemplateTypeParm > ObjC stuff > Builtin)
> > 
> > And, does it make sense to highlight function typedefs as their return type?
> I also think it's confusing. But we need to fallback to something if we see a 
> function type (or some other unhandled type) and I believe we 
> currently just don't highlight those typedefs at all, which seems bad.
> 
> I would just have a separate highlighting kind for typedefs (regardless of 
> what the underlying type is).
> This would allow to avoid both technical problems (simplifying the 
> implementation) and logical questions (e.g. 'should we highlight typedefs to 
> functions as their return type?)
> I would just have a separate highlighting kind for typedefs (regardless of 
> what the underlying type is).

FWIW, this is what Eclipse CDT does.

(Although clangd's current choice to highlight typedefs based on their target 
type is certainly an interesting one. From a user's point of view I can see 
arguments in either direction. On the one hand, revealing information about the 
target type is useful. On the other hand, knowing that a type //is// an alias 
for something else can also be useful.)


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D66516



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

Reply via email to