-
Notifications
You must be signed in to change notification settings - Fork 14.9k
Description
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:
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
:
// 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() 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...