source: doc/proposals/Upcast_EumCast.md

Last change on this file was c819d90, checked in by JiadaL <j82liang@…>, 8 weeks ago

A upcast proposal for enums

  • Property mode set to 100644
File size: 3.5 KB
Line 
1# Changes:
2## 0. Introduce a new type of cast: Upcast or Enum Cast.
3The naming of the cast is not determined.
4## 1. Updates on CastExpr::CastKind
5```
6        enum CastKind {
7                Default, // C
8                Coerce, // reinterpret cast
9                Return,  // overload selection
10                Up // <------ NEW; Cast to a super type
11        };
12```
13Scope: All enumerations, including C enumeration, and CFA enumeration (typed and opague). 
14Example Usage: 
15```
16    enum A { a };
17    enum B { b };
18    enum AB { inline A, inline B, ab };
19
20    // Explicit (user called) up cast
21    (AB) A.a;
22    // Implicit (generated) up cast
23    void foo(AB);
24    foo(A.a);
25```
26
27Aside: Expressions "(AB) a" or "foo(a)" don't introduce a upcast. Because enum AB is an enum type with elements AB.a, AB.b, and AB.ab. The expression "(AB) a" results in AB.a since it has a lower cost than "(AB) A.a". (no conversion/cast cost)
28## 2. Why needs a new cast type
29The up cast is a special kind of a cast that requires "offset operations".
30```
31    (AB) b.b; // is equivalent to
32    (AB) ((unsigned int)b.b + OFFSET) // (AB)(0 + 1)
33```
34OFFSET is an constanct value: The OFFSET from B to AB is 1. It is the number of enumerators declared before the declaration "inline B". The statement "inline B" is after "inline A", where "inline A" introduces one enumerator.
35
36Similarilty:
37```
38    enum E {
39        e;
40    };
41    enum ABCDE {
42        inline AB,
43        C, D,
44        inline E
45    };
46```
47The OFFSET from type E to type ABCDE is "# of element from AB" + 1 (C) + 1 (D), 4. 
48But we don't want to introduce the OFFSET_OPERATION + 4 on every cast from type E to type ABCDE. Sometime, the compiler introduce a generated cast (AB) E.e to maniputate expression type. It actually happens when after we have an upcast, we need to cast the expression (E.e + 4) to type ABCED, without "upcast it agains". It is a widening cast with no upcast effect.
49
50## 3. Implication
51A new pass "Upcast Pass" where happens before the resolver to identify Upcast. A cast (T) y for variable y with type Y is an upcast only if there is a "Upcast Path" from type T to type Y.
52For example,
53```
54    enum T {
55        ..., inline A, ...
56    };
57    enum A {
58        ..., inline B, ...
59    };
60    enum B {
61        ..., inline Y, ...
62    };
63    enum Y { ... };
64```
65There is a upcast Path from Y to T: Y -(upcast)-> B -(upcast)-> A -(upcast)-> T. The pass runs an algorithm to determine if there is such path exist from Y to T.   
66Aisde: The cast is "bottom-up": (T)((A)((B) y)), casting from the smaller type to the bigger type. But the algorithm is search "top-down", from T to Y. Because inline information is stored in the super type. T knows it inlines A, A knows it inline B, but not vise versa. 
67The CastKind will replaced by "CastKind::Up"
68
69The unifier in the resolver identify a function calls "foo(A.a)" performs an upcast, by running the algorithmn from AB to A, and introduce the implicit upcast in the Application Expression "foo((AB) A.B)".
70
71For all Upcast, the resolver replace them with 1. a offset operation (a functiion call ?+?(expr, OFFSET)), 2 and a Coerce cast from the lower type to the supper type. (There are some cast between enum type to integral type in between to satisfy the function ?+?(). We can ignore them for now.)
72
73Upcast should only exisit in the AST between the "Upcast Pass" and the "Resolver". They are essentially labels saying: this node needs an offset operation.
74
75"Upcast Pass" is a subpass of resolver. It does not need to be a standalone pass. It can be a special step when the compiler visits a CastExpr nocde.
76
77
Note: See TracBrowser for help on using the repository browser.