Mercurial > projects > ddmd
annotate dmd/NullExp.d @ 187:b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
author | Abscissa |
---|---|
date | Tue, 07 Jun 2011 23:37:34 -0400 |
parents | e3afd1303184 |
children |
rev | line source |
---|---|
72 | 1 module dmd.NullExp; |
2 | |
114 | 3 import dmd.common; |
72 | 4 import dmd.Expression; |
5 import dmd.backend.elem; | |
6 import dmd.InterState; | |
7 import dmd.MATCH; | |
8 import dmd.Type; | |
9 import dmd.TY; | |
10 import dmd.TypeTypedef; | |
11 import dmd.OutBuffer; | |
12 import dmd.Loc; | |
13 import dmd.Scope; | |
14 import dmd.IRState; | |
15 import dmd.HdrGenState; | |
16 import dmd.TOK; | |
17 import dmd.backend.dt_t; | |
18 import dmd.backend.Util; | |
19 | |
187
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
20 import dmd.DDMDExtensions; |
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
21 |
0 | 22 class NullExp : Expression |
23 { | |
187
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
24 mixin insertMemberExtension!(typeof(this)); |
b0d41ff5e0df
Added expandability scheme outlined in http://www.dsource.org/forums/viewtopic.php?t=5659&sid=6f2150ff5b0bffcd47512a6a7608d218
Abscissa
parents:
178
diff
changeset
|
25 |
0 | 26 ubyte committed; |
27 | |
135 | 28 this(Loc loc, Type type = null) |
72 | 29 { |
178 | 30 register(); |
0 | 31 super(loc, TOK.TOKnull, NullExp.sizeof); |
135 | 32 this.type = type; |
0 | 33 } |
34 | |
72 | 35 override Expression semantic(Scope sc) |
0 | 36 { |
72 | 37 version (LOGSEMANTIC) { |
38 printf("NullExp.semantic('%s')\n", toChars()); | |
39 } | |
40 // null is the same as (void*)0 | |
41 if (!type) | |
42 type = Type.tvoid.pointerTo(); | |
43 | |
0 | 44 return this; |
45 } | |
46 | |
72 | 47 override bool isBool(bool result) |
0 | 48 { |
49 assert(false); | |
50 } | |
51 | |
72 | 52 override int isConst() |
0 | 53 { |
63 | 54 return 0; |
0 | 55 } |
56 | |
72 | 57 override void toCBuffer(OutBuffer buf, HdrGenState* hgs) |
0 | 58 { |
59 buf.writestring("null"); | |
60 } | |
61 | |
72 | 62 override void toMangleBuffer(OutBuffer buf) |
0 | 63 { |
64 | 64 buf.writeByte('n'); |
0 | 65 } |
66 | |
72 | 67 override MATCH implicitConvTo(Type t) |
0 | 68 { |
72 | 69 static if (false) { |
70 printf("NullExp.implicitConvTo(this=%s, type=%s, t=%s, committed = %d)\n", | |
71 toChars(), type.toChars(), t.toChars(), committed); | |
72 } | |
73 if (this.type.equals(t)) | |
74 return MATCH.MATCHexact; | |
75 | |
76 /* Allow implicit conversions from invariant to mutable|const, | |
77 * and mutable to invariant. It works because, after all, a null | |
78 * doesn't actually point to anything. | |
79 */ | |
80 if (t.invariantOf().equals(type.invariantOf())) | |
81 return MATCH.MATCHconst; | |
82 | |
83 // null implicitly converts to any pointer type or dynamic array | |
84 if (type.ty == TY.Tpointer && type.nextOf().ty == TY.Tvoid) | |
85 { | |
86 if (t.ty == TY.Ttypedef) | |
87 t = (cast(TypeTypedef)t).sym.basetype; | |
88 if (t.ty == TY.Tpointer || t.ty == TY.Tarray || | |
89 t.ty == TY.Taarray || t.ty == TY.Tclass || | |
90 t.ty == TY.Tdelegate) | |
91 { | |
92 return committed ? MATCH.MATCHconvert : MATCH.MATCHexact; | |
93 } | |
94 } | |
95 | |
0 | 96 return Expression.implicitConvTo(t); |
97 } | |
98 | |
72 | 99 override Expression castTo(Scope sc, Type t) |
0 | 100 { |
72 | 101 NullExp e; |
102 Type tb; | |
103 | |
104 //printf("NullExp::castTo(t = %p)\n", t); | |
105 if (type is t) | |
106 { | |
107 committed = 1; | |
108 return this; | |
109 } | |
110 | |
111 e = cast(NullExp)copy(); | |
112 e.committed = 1; | |
113 tb = t.toBasetype(); | |
114 e.type = type.toBasetype(); | |
115 | |
116 if (tb !is e.type) | |
117 { | |
118 // null implicitly converts to any pointer type or dynamic array | |
119 if (e.type.ty == TY.Tpointer && e.type.nextOf().ty == TY.Tvoid && | |
120 (tb.ty == TY.Tpointer || tb.ty == TY.Tarray || tb.ty == TY.Taarray || | |
121 tb.ty == TY.Tdelegate)) | |
122 { | |
123 static if (false) { | |
124 if (tb.ty == TY.Tdelegate) | |
125 { | |
126 TypeDelegate td = cast(TypeDelegate)tb; | |
127 TypeFunction tf = cast(TypeFunction)td.nextOf(); | |
128 | |
129 if (!tf.varargs && !(tf.arguments && tf.arguments.dim)) | |
130 { | |
131 return Expression.castTo(sc, t); | |
132 } | |
133 } | |
134 } | |
135 } | |
136 else | |
137 { | |
138 return e.Expression.castTo(sc, t); | |
139 } | |
140 } | |
141 e.type = t; | |
0 | 142 return e; |
143 } | |
144 | |
72 | 145 override Expression interpret(InterState istate) |
0 | 146 { |
123 | 147 return this; |
0 | 148 } |
149 | |
72 | 150 override elem* toElem(IRState* irs) |
0 | 151 { |
152 return el_long(type.totym(), 0); | |
153 } | |
154 | |
72 | 155 override dt_t** toDt(dt_t** pdt) |
0 | 156 { |
72 | 157 assert(type); |
0 | 158 return dtnzeros(pdt, cast(uint)type.size()); |
159 } | |
160 } | |
161 |