libabigail currently lacks support for pointer-to-member types. These are very simple to model but there may be complexities around building type names and referring to their components (as no standardised naming seems to exist). Useful references: * https://eel.is/c++draft/expr.mptr.oper * https://eel.is/c++draft/dcl.mptr - "there is no 'reference-to-member' type" * https://en.cppreference.com/w/cpp/language/pointer#Pointers_to_members Test case: struct X { void f(int); int a; }; struct Y; int X::* pmi = &X::a; void (X::* pmf)(int) = &X::f; double X::* pmd; char Y::* pmc; typedef struct { int t; } T; auto pmy = &T::t; namespace { struct Z { int z; }; } int Z::* pmz = &Z::z; union U { int u; }; auto pmu = &U::u; typedef const U CU; auto pmcu = &CU::u; Model: * no intrinsic name * containing type (in practice: can be class/struct, union or typedef; after typedef resolution can be qualified or anonymous) * (member) type Naming: $ c++decl declare x as pointer to member of class NAME function returning int int (NAME::*x)() $ c++decl declare x as array 7 of pointer to member of class NAME int int NAME::*x[7] But this doesn't account for the more complex cases for NAME (see the test case above). Component naming (for diff reporting): ¯\_(ツ)_/¯ Concrete representation in XML: ¯\_(ツ)_/¯
$ c++decl declare x as pointer to member of class NAME array 7 of int int (NAME::*x)[7]
Naming of these types appears to follow all the same rules as naming normal pointer types, including when parentheses are needed. pointer to: ... * ... becomes pointer to X member: ... X::* ... Extra complications are: 1. the syntax immediately to the left of the * or X::* may need to be separated by a space int*x; // no space needed before * int X::*x; // space is needed before X int (X::*x)(); // space would look odd inside the bracket 2. this is normally written as just the tag, without struct / class / union but you might want to include the keyword for clarity or for simplicity of coding int struct X::*x;
Indeed, thank you for filing such a detailed enhancement request. Libabigail needs to support this.
Please note that pointer to member happens to be one of the challenging areas in DWARF5, I think it is fine in the underlying type system but if the pointer to member variable is passed as a parameter to a function and is in a register, then I believe that the DWARF to represent that is currently undefined. DWARF6 is supposed to resolve that issue. https://github.com/ccoutant/dwarf-locations/blob/f74b6d8b95ad5cfea80c4493f11e7dae441f02eb/location-description-on-the-dwarf-stack-concept-proposal.txt#L252
I have started to add patches to support the pointer-to-member feature in the branch https://sourceware.org/git/?p=libabigail.git;a=shortlog;h=refs/heads/users/dodji/PR30260. The code can be tested at this point, FWIW.
FWIW, STG diff output looks like this: function symbol 'int struct S::* s2()' {_Z2s2v} was added function symbol 'int s10(int struct S::*)' {_Z3s10M1Si} was added function symbol 'void pmz_fun()' {_Z7pmz_funv} was added variable symbol 'char struct Y::* pmc' was added variable symbol 'int union U::* pmcu' was added variable symbol 'double struct X::* pmd' was added variable symbol 'void(struct X::* pmf)(struct X*, int)' was added variable symbol 'int struct X::* pmi' was added variable symbol 'int union U::* pmu' was added variable symbol 'int struct { int t; }::* pmy' was added variable symbol 'int struct S::* s0' was added variable symbol 'int struct S::** s1' was added variable symbol 'int struct S::*(* s3)()' was added variable symbol 'int struct S::* s4[7]' was added variable symbol 'int* struct S::* s5' was added variable symbol 'int(* struct S::* s6)()' was added variable symbol 'int(struct S::* s7)(struct S*)' was added variable symbol 'int(struct S::* s8)[7]' was added variable symbol 'const int struct S::* volatile s9' was added variable symbol changed from 'char struct A::* diff' to 'int struct B::* diff' type changed from 'char struct A::*' to 'int struct B::*' containing type changed from 'struct A' to 'struct B' type changed from 'char' to 'int' If you have any better ideas than "containing type" and "type", I might steal them. :-) "pointed-to-member type"???
Thanks. The output of abidiff looks like this: Functions changes summary: 0 Removed, 0 Changed, 0 Added function Variables changes summary: 0 Removed, 1 Changed, 0 Added variable 1 Changed variable: [C] 'int S::* pm' was changed to 'char S::* pm' at test-ptr-to-mbr1-v1.cc:6:1: type of variable changed: pointer-to-member type changed from: 'int S::* to: 'char S::*' in data member type 'int' of pointed-to-member type 'int S::*': type name changed from 'int' to 'char' type size changed from 32 to 8 (in bits) in containing type 'struct S' of pointed-to-member type 'int S::*' at test-ptr-to-mbr1-v1.cc:1:1: type size changed from 32 to 8 (in bits) 1 data member change: type of 'int m' changed: type name changed from 'int' to 'char' type size changed from 32 to 8 (in bits) The output of the relevant tests are available at https://sourceware.org/git/?p=libabigail.git;a=tree;f=tests/data/test-abidiff-exit/pointer-to-member;h=61ced53e13335af7b31962b8a3736774be5b68db;hb=HEAD. And one such output is: https://sourceware.org/git/?p=libabigail.git;a=blob;f=tests/data/test-abidiff-exit/pointer-to-member/test-ptr-to-mbr1-output-1.txt;h=a88d96fbec1d301d52e57f5f6a6e233d97de62b1;hb=HEAD
This feature should now be implemented by commit https://sourceware.org/git/?p=libabigail.git;a=commit;h=d4ca1088e4cdc4b3e4c3e67284458911c24a7c59 and should be available in libabigail 2.5. Thank you for filing this enhancement request.