GabrielDosReis/ipr

Does IPR need a method type?

Opened this issue · 2 comments

IPR distinguishes between non-static data members (Fields) and static data members (Var).
Thus taking an address of a Field, will result in an expression of Ptr_to_member type and taking an address of a Var, will result in an expression of Pointer type.

For Fundecl, IPR makes no distinction whether they are members or non-members. We need to resort to examining the specifiers() of the Fundecl and decide based on the presence of DeclSpecifiers::Static bit to see if it is a member function (Method) or static member function.

We had a brief discussion on 8/4/2021 and this item is a reminder of this discussion to decide whether anything need to change in IPR or stay as it is.

In the early design days of the IPR, we decided that we wanted to unify the notions of both non-static member functions and static member functions and that such unification should involve types (remember: types are the backbone of semantics in IPR). So, we didn't have "method types" (as you would find in the first versions of the MSVC's IFC format). Furthermore, we also had a strong desire to have the necessary infrastructure in place to support multi-methods; that required disentangling the whole non-static member function and overloading puzzle. Those issues are largely immaterial for nonstatic data members (fields) and ordinary variables and static data members. We never got to be doing that disentanglement as we all got busy.

Note that the unification concern is now renewed with urgency with the proposed [Deducing this]. That paper has a good summary of the mess that needs to be addressed. The syntax is debatable; but the semantics model in IPR need to be regular. My current thinking is to have some notion of member type so that we can retire Ptr_to_member.

In a recent discussion when this subject was touched. One of the ideas to explore was to add a Member(C,T) type where C is a class and T is a type.

In the following example:

struct S { int f(double(); int d; };

The type of S::f would be Member(S, int(double)).
The type of S::d would be Member(S, int).
The type of &S::d, i.e. int S::* would be Pointer(Member(S, int)).

Possible interplay with deducing-this,

struct Z { int g(this Z, double); };

Have a unary type constructor Method(C), so that the type of Z::g would be
int(Member(X), double).