<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/155082>155082</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
USRGenerator doesn't handle MemberPointerType arguments in functions and template specializations
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
bkryza
</td>
</tr>
</table>
<pre>
Current implementation of `USRGenerator` generates ambiguous USR values for declarations, which contain pointers to members or pointers to methods. I created a `c-index-test` compatible test case, which illustrates the issue. The test case as is passes to show what USR is generated for these declarations, but note that in particular the last 6 declarations, which are different, have the exact same USR.
The following test case can placed in `clang/test/Index/USR/` and ran on latest LLVM repository build as:
```bash
build/bin/c-index-test core -print-source-symbols -- clang/test/Index/USR/member-pointer-types-as-arguments.cpp | build/bin/FileCheck clang/test/Index/USR/member-pointer-types-as-arguments.cpp
```
`member-pointer-types-as-arguments.cpp`:
```cpp
// RUN: c-index-test core -print-source-symbols -- %s | FileCheck %s
template <typename T> struct A;
// CHECK: {{[0-9]+}}:30 | struct(Gen)/C++ | A | c:@ST>1#T@A |
// OK
template <typename R, typename Arg>
struct A<R (*)(Arg)> {};
// CHECK: {{[0-9]+}}:8 | struct(Gen,TPS)/C++ | A | c:@SP>2#T#T@A>#*Ft0.0(#t0.1) |
// OK
template<typename K, typename V> struct B;
template<typename M, typename C>
struct A<B<M,C>> {
};
// CHECK: {{[0-9]+}}:8 | struct(Gen,TPS)/C++ | A | c:@SP>2#T#T@A>#>@ST>2#T#T@B2t0.0t0.1 |
// OK
struct R {
int *p;
};
void f(int*, int* R::* mp);
// CHECK: {{[0-9]+}}:6 | function/C | f | c:@F@f#*I# # |
// BAD - second argument is encoded as empty space
template<typename M, typename C>
struct A<M C::*> {
};
// CHECK: {{[0-9]+}}:8 | struct(Gen,TPS)/C++ | A | c:@SP>2#T#T@A># |
// BAD - template specialization argument is not encoded in USR
// also note the additional empty space at the and of USR
template <typename M, typename C>
struct A<M (C::*)()> {
};
// CHECK: {{[0-9]+}}:8 | struct(Gen,TPS)/C++ | A | c:@SP>2#T#T@A># |
// BAD - template specialization argument is not encoded in USR
template <typename M, typename C, typename Arg>
struct A<M (C::*)(Arg)> {
};
// CHECK: {{[0-9]+}}:8 | struct(Gen,TPS)/C++ | A | c:@SP>3#T#T#T@A># |
// BAD - template specialization argument is not encoded in USR
template <typename M, typename C, typename Arg>
struct A<M (C::*)(Arg) const> {
};
// CHECK: {{[0-9]+}}:8 | struct(Gen,TPS)/C++ | A | c:@SP>3#T#T#T@A># |
// BAD - template specialization argument is not encoded in USR
template <typename M, typename C, typename Arg>
struct A<M (C::*)(Arg,Arg,Arg)> {
};
// CHECK: {{[0-9]+}}:8 | struct(Gen,TPS)/C++ | A | c:@SP>3#T#T#T@A># |
// BAD - template specialization argument is not encoded in USR
template <typename M, typename C, typename Arg>
struct A<M (C::*)(Arg) &> {
};
// CHECK: {{[0-9]+}}:8 | struct(Gen,TPS)/C++ | A | c:@SP>3#T#T#T@A># |
// BAD - template specialization argument is not encoded in USR
template <typename M, typename C, typename Arg>
struct A<M (C::*)(Arg) &&> {
};
// CHECK: {{[0-9]+}}:8 | struct(Gen,TPS)/C++ | A | c:@SP>3#T#T#T@A># |
// BAD - template specialization argument is not encoded in USR
template <typename M, typename C, typename Arg>
struct A<M (C::*)(Arg) const &> {
};
// CHECK: {{[0-9]+}}:8 | struct(Gen,TPS)/C++ | A | c:@SP>3#T#T#T@A># |
// BAD - template specialization argument is not encoded in USR
template <typename M, typename C, typename Arg>
struct A<M (C::*)(Arg) const &&> {
};
// CHECK: {{[0-9]+}}:8 | struct(Gen,TPS)/C++ | A | c:@SP>3#T#T#T@A># |
// BAD - template specialization argument is not encoded in USR
```
The question is, whether this behaviour is by design or is it an ommision in the [USRGenerator::VisitType()](https://github.com/llvm/llvm-project/blob/91cdd35008e9ab32dffb7e401cdd7313b3461892/clang/lib/Index/USRGeneration.cpp#L869-L977) implementation?
If it's the latter I'd be happy to contribute a fix for this. My use case is that I'd like to use USR for unique identification of declarations and types across multiple translation units, however at the momement it's not possible to this limitation...
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJzsWF1zmzgU_TXyyx17sBTb8OAH7IRupslux0n6LuDaaCskKomk7q_fkcAO3qYf2WZ2ujvJEBsk7tU9R8dCHG6t2CnEJZmtyOx8xFtXabPMP5j9Zz7KdblfrltjUDkQdSOxRuW4E1qB3gKZR3c3mzeo0HCnDZlHsOsu0AKvc7FrdWvh7mYD91y2aGGrDZRYSG5CEkvoGh4qUVRQaOW4UNBooRwaC05DjXXuT7X5W7OrdGkncAmFQe6wBO5rKcZClfhp7NA6X0uh64Y7kUsE3wQFt_g4oJCyta6r1VUIwtoWJ3BbDe4GbkFYaLi1GIa2lX6Ah4q7AErYI94yQHMVWvwCYN46UNohOB_oMXLjRNFKHiJAcutg_hVeuEEoxXaLfg58c8XvMYThJ144sLxGX8wESJSSKPX1b7WU-kGo3QBJwRU0khdY-go8W5KrHaFZYItml546QrO7mw2hmaePqxIMV6AVSB4SXV29vwaDjbbCabOHvBWyBG4JS7vByTzqjpzbikRpuIHQLBeK0Gw4P1BogzBujFBubHVrChzbfZ1raWE8hm8W18li3Eti7PYN2jG3Y252rdennRRNA2SxhtPxMyFxXWHx4QXSD8H22EPLjwXPo56yQ4o-I80IzWBz9zthKTyDLkJnNgB-hOibuqoc1o2fQCBs7etRXjG3hF2AdaYtHKSErR5HX_92sX7rxyeLlT9mq2ickNk5oSuyOPcHS1kURuviCY3foCI0ITRb-7voKvSm4bPwSM-iGz_glFB2S86i0PM44h9vv1Hoxmv-eJWaHWEXJEofS19vgNCY0DRUEPs7aOLRhfrPn40tfgLa-vbdzfcAviPsggaAPUhfKGWEppmLJlGokbloMiU0-Tb-Ify3J_DfD2Zt1SN7Ou76JG79BWkrwtb-ntDTkxWlvwJf7OIgl2HvinoSPX1Pc9dD2_RAAACEckBo2vSIjtCi9F6LEraExsIvqamnqjuDjS-Opf60boKOnsnGPGDctqrw67gnoGsYQs_IWbTtpHFJKIPwPwS1Ss9hDBYLrUo4rBz-aYOq0KV_3FnAunF7sA0v8J-r4Nq39YB_KRXAU4Qc1wfbYCG4FJ-7nciQIaXdkSWh_IPxMUv3x6XVh8cxAi9L4ZNwOWQUuOt6Ven3OX2Wr6xQ3yeZ0HjAc1imBmvUr0H4i_L9g0x9b2V_krnTBf7fJ48dyftPE-g33Na90vhzNK4Hn6-a_GlNEjp_JfElSHzl8YUWyFdJviyV_3s2T02B2wrhY4s2BIve1kFXoQFXCQs5Vvxe6Nb4hPkeSrRip0CHa-GAK9B1LWwIV2FPSmarE9MtEP5eWOFu9w32W0tPWlw51wRvJiDbCVe1-aTQNaGZlPeHr3Fj9J_o2cxyqXNCs2RalCWbRVGMCc8ZLbfbfIFnkW9esCnL2dl8GieU0OxgpEiRn_oofX1Cq2B4UHYVz5PxVbJYeD2cWomEZR1bl1sQjtCF7W0x59DAJaGLEnKEijfNHpwOVqEReesQOGzFp956E3YC13tog9ll0TMYDLcugRQf0Af77rubTYhplfjYIogSlRNbURyNzaEVF14Cgo8DvDDaWqhb6UQjEZzhysouqlXChfmt9APeozm8QtS6xk4xHTKvmkZb29mSupOBFLXouJhMJqNyycqEJXyEy-liNktYMk3iUbVMWDlPttOCFtMZY8k851G5WFCMk3ibU5aPxJJGdBbFlEXxjE3jSR4toiiPFgmLGZ3GBTmLsOZCTvzET7TZjYLruZzOfNRI8hylDVYwpQofOk-UUEpm5yOzDGrJ250lZ5EU1tnHNE44icuhLqHUaBWhCwcVV6VEuA7W2LvOGfNaPf6arNf24Z25J_zpH6AdtUYuny3sgMMSmvVA75f0rwAAAP__9GCmKg">