ioeric added inline comments.

================
Comment at: clangd/index/SymbolCollector.cpp:297
+    // If OrigD is an object of a friend declaration, skip it.
+    if (ASTNode.OrigD->getFriendObjectKind() !=
+        Decl::FriendObjectKind::FOK_None)
----------------
sammccall wrote:
> ioeric wrote:
> > sammccall wrote:
> > > this seems suspect, we're going to treat the third decl in `friend X; X; 
> > > friend X` differently from that in `X; friend X; friend X;`.
> > > 
> > > Why? i.e. why is the inner check necessary and why does it treat the 
> > > original (meaning first, I think) decl specially?
> > > this seems suspect, we're going to treat the third decl in `friend X; X; 
> > > friend X` differently from that in `X; friend X; friend X;`.
> > I'm not very sure if I understand the problem. But I'll try to explain what 
> > would happen for these two examples.
> > - For the first example, the first friend decl will be the canonical decl, 
> > and we would only index the second `X` since its `OrigD` is not in friend 
> > decl. Both the first and third friend decl will not be indexed. 
> > - For the second example, the first non-friend `X` will be the canonical 
> > decl, and all three occurrences will have the same `D` pointing to it. This 
> > probably means that the same X will be processed three times, but it's 
> > probably fine (we might want to optimize it). 
> > 
> > Basically, `D` is always the canonical declaration in AST and `OrigD` is  
> > the declaration that the indexer is currently visiting. I agree it's 
> > confusing...
> > 
> > > Why? i.e. why is the inner check necessary and why does it treat the 
> > > original (meaning first, I think) decl specially?
> > 
> > The inner check handles the following case:
> > ```
> > class X {
> >   friend void foo();
> > }
> > void foo();
> > ```
> > 
> > There will be two occurrences of `foo` in the index:
> > 1. The friend decl, where `D` will be the canonical decl (i.e. friend foo) 
> > and `OrigD` will also be friend foo.
> > 2. The non-friend decl, where `D` will still be the canonical decl (i.e. 
> > friend foo) and `OrigD` is now the non-friend decl.
> > Basically, D is always the canonical declaration in AST and OrigD is the 
> > declaration that the indexer is currently visiting. I agree it's 
> > confusing...
> 
> Whoops, I had this backwards. So I guess I mean the outer check.
> Fundamentally my question is: in an *arbitrary* list of redecls of a symbol, 
> what is special about the canonical declaration (D, which is just the first 
> in the list) that we particularly care whether it's a friend?
> I would expect that either we're ignoring the other redecls, or we're looping 
> over all redecls.
> 
> And here, I think we could just skip all friend decls (that are not 
> definitions), regardless of what `D->getFriendObjectKind()` is. If we have 
> other decls, the symbol was indexed already. If we do not, then we don't want 
> to index it anyway.
> Fundamentally my question is: in an *arbitrary* list of redecls of a symbol, 
> what is special about the canonical declaration (D, which is just the first 
> in the list) that we particularly care whether it's a friend?
It's because we have chosen to use `D` as a symbol's canonical declaration 
(line 332). Here we want to override the canonical declaration `D` when it's a 
friend decl, so that the first non-friend decl would become the canonical 
declaration of the symbol.

> And here, I think we could just skip all friend decls (that are not 
> definitions), regardless of what D->getFriendObjectKind() is. 
OK. I think I understand where the confusion came from now. The override of `D` 
should've been a separate check:
```
if (OrigD is non-definition friend)
  skip;
if (D is friend decl)
  D = OrigD;
```


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D47623



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

Reply via email to