comparison dmd/PtrExp.d @ 0:10317f0c89a5

Initial commit
author korDen
date Sat, 24 Oct 2009 08:42:06 +0400
parents
children 4ae0d790a452
comparison
equal deleted inserted replaced
-1:000000000000 0:10317f0c89a5
1 module dmd.PtrExp;
2
3 import dmd.Expression;
4 import dmd.Identifier;
5 import dmd.backend.elem;
6 import dmd.UnaExp;
7 import dmd.InterState;
8 import dmd.Type;
9 import dmd.OutBuffer;
10 import dmd.Loc;
11 import dmd.Scope;
12 import dmd.IRState;
13 import dmd.HdrGenState;
14 import dmd.TOK;
15 import dmd.GlobalExpressions;
16 import dmd.SymOffExp;
17 import dmd.AddrExp;
18 import dmd.VarDeclaration;
19 import dmd.StructLiteralExp;
20 import dmd.TypePointer;
21 import dmd.TypeArray;
22 import dmd.ErrorExp;
23 import dmd.TY;
24 import dmd.expression.Ptr;
25 import dmd.expression.Util;
26
27 import dmd.backend.Util;
28 import dmd.backend.TYM;
29 import dmd.backend.mTY;
30 import dmd.backend.OPER;
31
32 class PtrExp : UnaExp
33 {
34 this(Loc loc, Expression e)
35 {
36 super(loc, TOK.TOKstar, PtrExp.sizeof, e);
37 // if (e.type)
38 // type = ((TypePointer *)e.type).next;
39 }
40
41 this(Loc loc, Expression e, Type t)
42 {
43 super(loc, TOKstar, PtrExp.sizeof, e);
44 type = t;
45 }
46
47 Expression semantic(Scope sc)
48 {
49 version (LOGSEMANTIC) {
50 printf("PtrExp::semantic('%s')\n", toChars());
51 }
52 if (!type)
53 {
54 UnaExp.semantic(sc);
55 e1 = resolveProperties(sc, e1);
56 if (!e1.type)
57 writef("PtrExp.semantic('%s')\n", toChars());
58 Expression e = op_overload(sc);
59 if (e)
60 return e;
61 Type tb = e1.type.toBasetype();
62 switch (tb.ty)
63 {
64 case Tpointer:
65 type = (cast(TypePointer)tb).next;
66 break;
67
68 case Tsarray:
69 case Tarray:
70 type = (cast(TypeArray)tb).next;
71 e1 = e1.castTo(sc, type.pointerTo());
72 break;
73
74 default:
75 error("can only * a pointer, not a '%s'", e1.type.toChars());
76 return new ErrorExp();
77 }
78 rvalue();
79 }
80 return this;
81 }
82
83 int isLvalue()
84 {
85 assert(false);
86 }
87
88 Expression toLvalue(Scope sc, Expression e)
89 {
90 static if (false) {
91 tym = tybasic(e1.ET.Tty);
92 if (!(tyscalar(tym) ||
93 tym == TYstruct ||
94 tym == TYarray && e.Eoper == TOKaddr)
95 )
96 synerr(EM_lvalue); // lvalue expected
97 }
98 return this;
99 }
100
101 version (DMDV2) {
102 Expression modifiableLvalue(Scope sc, Expression e)
103 {
104 //printf("PtrExp.modifiableLvalue() %s, type %s\n", toChars(), type.toChars());
105
106 if (e1.op == TOKsymoff)
107 {
108 SymOffExp se = cast(SymOffExp)e1;
109 se.var.checkModify(loc, sc, type);
110 //return toLvalue(sc, e);
111 }
112
113 return Expression.modifiableLvalue(sc, e);
114 }
115 }
116 void toCBuffer(OutBuffer buf, HdrGenState* hgs)
117 {
118 assert(false);
119 }
120
121 elem* toElem(IRState* irs)
122 {
123 elem* e;
124
125 //printf("PtrExp::toElem() %s\n", toChars());
126 e = e1.toElem(irs);
127 e = el_una(OPER.OPind, type.totym(), e);
128
129 if (tybasic(e.Ety) == TYM.TYstruct)
130 {
131 e.Enumbytes = cast(uint)type.size();
132 }
133
134 el_setLoc(e,loc);
135 return e;
136 }
137
138 Expression optimize(int result)
139 {
140 //printf("PtrExp.optimize(result = x%x) %s\n", result, toChars());
141 e1 = e1.optimize(result);
142 // Convert *&ex to ex
143 if (e1.op == TOK.TOKaddress)
144 {
145 Expression e;
146 Expression ex;
147
148 ex = (cast(AddrExp)e1).e1;
149 if (type.equals(ex.type))
150 e = ex;
151 else
152 {
153 e = ex.copy();
154 e.type = type;
155 }
156 return e;
157 }
158 // Constant fold *(&structliteral + offset)
159 if (e1.op == TOK.TOKadd)
160 {
161 Expression e;
162 e = Ptr(type, e1);
163 if (e !is EXP_CANT_INTERPRET)
164 return e;
165 }
166
167 if (e1.op == TOK.TOKsymoff)
168 {
169 SymOffExp se = cast(SymOffExp)e1;
170 VarDeclaration v = se.var.isVarDeclaration();
171 Expression e = expandVar(result, v);
172 if (e && e.op == TOK.TOKstructliteral)
173 {
174 StructLiteralExp sle = cast(StructLiteralExp)e;
175 e = sle.getField(type, se.offset);
176 if (e && e !is EXP_CANT_INTERPRET)
177 return e;
178 }
179 }
180 return this;
181 }
182
183 Expression interpret(InterState* istate)
184 {
185 assert(false);
186 }
187
188 Identifier opId()
189 {
190 assert(false);
191 }
192 }
193