Mercurial > projects > ddmd
annotate dmd/AssertExp.d @ 174:af724d3510d7
lot os toCBuffer methods implemented
moved shared Type.* stuff into Global
author | korDen |
---|---|
date | Sun, 10 Oct 2010 03:47:23 +0400 |
parents | 25ede4f66bda |
children | e3afd1303184 |
rev | line source |
---|---|
72 | 1 module dmd.AssertExp; |
2 | |
114 | 3 import dmd.common; |
72 | 4 import dmd.Expression; |
5 import dmd.backend.elem; | |
6 import dmd.UnaExp; | |
7 import dmd.InterState; | |
8 import dmd.OutBuffer; | |
9 import dmd.Loc; | |
10 import dmd.Scope; | |
11 import dmd.InlineCostState; | |
12 import dmd.InlineDoState; | |
13 import dmd.IRState; | |
14 import dmd.HdrGenState; | |
0 | 15 import dmd.InlineScanState; |
16 import dmd.Type; | |
17 import dmd.Global; | |
72 | 18 import dmd.InvariantDeclaration; |
0 | 19 import dmd.TOK; |
174 | 20 import dmd.PREC; |
0 | 21 import dmd.TY; |
22 import dmd.TypeClass; | |
23 import dmd.Module; | |
24 import dmd.WANT; | |
25 import dmd.FuncDeclaration; | |
26 import dmd.HaltExp; | |
27 import dmd.TypeStruct; | |
28 import dmd.backend.Util; | |
29 import dmd.codegen.Util; | |
30 import dmd.backend.OPER; | |
31 import dmd.backend.TYM; | |
32 import dmd.backend.RTLSYM; | |
33 import dmd.backend.Symbol; | |
34 import dmd.backend.dt_t; | |
35 import dmd.backend.SC; | |
72 | 36 import dmd.backend.FL; |
0 | 37 |
174 | 38 import dmd.expression.Util; |
39 | |
0 | 40 import core.stdc.string; |
41 import std.string : toStringz; | |
42 | |
165
25ede4f66bda
Temporarily disabled GC (again) because phobos fails to compile with it (looks like some ObjSymbols are being falsely collected, see Library.d:666)
korDen
parents:
114
diff
changeset
|
43 //static __gshared Symbol* assertexp_sfilename = null; |
25ede4f66bda
Temporarily disabled GC (again) because phobos fails to compile with it (looks like some ObjSymbols are being falsely collected, see Library.d:666)
korDen
parents:
114
diff
changeset
|
44 //static __gshared string assertexp_name = null; |
25ede4f66bda
Temporarily disabled GC (again) because phobos fails to compile with it (looks like some ObjSymbols are being falsely collected, see Library.d:666)
korDen
parents:
114
diff
changeset
|
45 //static __gshared Module assertexp_mn = null; |
72 | 46 |
0 | 47 class AssertExp : UnaExp |
48 { | |
49 Expression msg; | |
50 | |
51 this(Loc loc, Expression e, Expression msg = null) | |
52 { | |
53 super(loc, TOK.TOKassert, AssertExp.sizeof, e); | |
54 this.msg = msg; | |
55 } | |
56 | |
72 | 57 override Expression syntaxCopy() |
0 | 58 { |
72 | 59 AssertExp ae = new AssertExp(loc, e1.syntaxCopy(), |
60 msg ? msg.syntaxCopy() : null); | |
53 | 61 return ae; |
0 | 62 } |
63 | |
72 | 64 override Expression semantic(Scope sc) |
0 | 65 { |
66 version (LOGSEMANTIC) { | |
67 printf("AssertExp.semantic('%s')\n", toChars()); | |
68 } | |
69 UnaExp.semantic(sc); | |
70 e1 = resolveProperties(sc, e1); | |
71 // BUG: see if we can do compile time elimination of the Assert | |
72 e1 = e1.optimize(WANTvalue); | |
73 e1 = e1.checkToBoolean(); | |
74 if (msg) | |
75 { | |
76 msg = msg.semantic(sc); | |
77 msg = resolveProperties(sc, msg); | |
78 msg = msg.implicitCastTo(sc, Type.tchar.constOf().arrayOf()); | |
79 msg = msg.optimize(WANTvalue); | |
80 } | |
81 if (e1.isBool(false)) | |
82 { | |
83 FuncDeclaration fd = sc.parent.isFuncDeclaration(); | |
84 fd.hasReturnExp |= 4; | |
85 | |
86 if (!global.params.useAssert) | |
174 | 87 { |
0 | 88 Expression e = new HaltExp(loc); |
89 e = e.semantic(sc); | |
90 return e; | |
91 } | |
92 } | |
93 type = Type.tvoid; | |
94 return this; | |
95 } | |
96 | |
72 | 97 override Expression interpret(InterState istate) |
0 | 98 { |
99 assert(false); | |
100 } | |
101 | |
72 | 102 override bool checkSideEffect(int flag) |
0 | 103 { |
104 return true; | |
105 } | |
106 | |
107 version (DMDV2) { | |
72 | 108 override bool canThrow() |
0 | 109 { |
110 /* assert()s are non-recoverable errors, so functions that | |
111 * use them can be considered "nothrow" | |
112 */ | |
165
25ede4f66bda
Temporarily disabled GC (again) because phobos fails to compile with it (looks like some ObjSymbols are being falsely collected, see Library.d:666)
korDen
parents:
114
diff
changeset
|
113 return false; //(global.params.useAssert != 0); |
0 | 114 } |
115 } | |
72 | 116 override void toCBuffer(OutBuffer buf, HdrGenState* hgs) |
0 | 117 { |
174 | 118 buf.writestring("assert("); |
119 expToCBuffer(buf, hgs, e1, PREC.PREC_assign); | |
120 if (msg) | |
121 { | |
122 buf.writeByte(','); | |
123 expToCBuffer(buf, hgs, msg, PREC_assign); | |
124 } | |
125 buf.writeByte(')'); | |
0 | 126 } |
127 | |
72 | 128 override int inlineCost(InlineCostState* ics) |
0 | 129 { |
130 return 1 + e1.inlineCost(ics) + (msg ? msg.inlineCost(ics) : 0); | |
131 } | |
132 | |
72 | 133 override Expression doInline(InlineDoState ids) |
0 | 134 { |
135 AssertExp ae = cast(AssertExp)copy(); | |
136 | |
137 ae.e1 = e1.doInline(ids); | |
138 if (msg) | |
139 ae.msg = msg.doInline(ids); | |
140 return ae; | |
141 } | |
142 | |
72 | 143 override Expression inlineScan(InlineScanState* iss) |
0 | 144 { |
145 e1 = e1.inlineScan(iss); | |
146 if (msg) | |
147 msg = msg.inlineScan(iss); | |
148 return this; | |
149 } | |
174 | 150 |
0 | 151 static private void* castToVoid(int i) |
152 { | |
153 return cast(void*)i; | |
154 } | |
155 | |
72 | 156 override elem* toElem(IRState* irs) |
0 | 157 { |
158 elem* e; | |
159 elem* ea; | |
160 Type t1 = e1.type.toBasetype(); | |
161 | |
162 //printf("AssertExp.toElem() %s\n", toChars()); | |
163 if (global.params.useAssert) | |
164 { | |
165 e = e1.toElem(irs); | |
166 | |
167 InvariantDeclaration inv = cast(InvariantDeclaration)castToVoid(1); | |
168 | |
169 // If e1 is a class object, call the class invariant on it | |
170 if (global.params.useInvariants && t1.ty == Tclass && | |
171 !(cast(TypeClass)t1).sym.isInterfaceDeclaration()) | |
172 { | |
22
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
0
diff
changeset
|
173 version (POSIX) {///TARGET_LINUX || TARGET_FREEBSD || TARGET_SOLARIS |
0 | 174 e = el_bin(OPcall, TYvoid, el_var(rtlsym[RTLSYM__DINVARIANT]), e); |
175 } else { | |
176 e = el_bin(OPcall, TYvoid, el_var(rtlsym[RTLSYM_DINVARIANT]), e); | |
177 } | |
178 } | |
179 // If e1 is a struct object, call the struct invariant on it | |
180 else if (global.params.useInvariants && | |
181 t1.ty == Tpointer && | |
182 t1.nextOf().ty == Tstruct && | |
183 (inv = (cast(TypeStruct)t1.nextOf()).sym.inv) !is null) | |
184 { | |
185 e = callfunc(loc, irs, 1, inv.type.nextOf(), e, e1.type, inv, inv.type, null, null); | |
186 } | |
187 else | |
188 { | |
189 // Construct: (e1 || ModuleAssert(line)) | |
190 Symbol* sassert; | |
191 Module m = irs.blx.module_; | |
192 string mname = m.srcfile.toChars(); | |
193 | |
194 //printf("filename = '%s'\n", loc.filename); | |
195 //printf("module = '%s'\n", m.srcfile.toChars()); | |
196 | |
197 /* If the source file name has changed, probably due | |
198 * to a #line directive. | |
199 */ | |
200 if (loc.filename && (msg || loc.filename != mname)) | |
174 | 201 { |
0 | 202 elem* efilename; |
203 | |
204 /* Cache values. | |
205 */ | |
165
25ede4f66bda
Temporarily disabled GC (again) because phobos fails to compile with it (looks like some ObjSymbols are being falsely collected, see Library.d:666)
korDen
parents:
114
diff
changeset
|
206 Symbol* assertexp_sfilename = null; |
25ede4f66bda
Temporarily disabled GC (again) because phobos fails to compile with it (looks like some ObjSymbols are being falsely collected, see Library.d:666)
korDen
parents:
114
diff
changeset
|
207 string assertexp_name = null; |
25ede4f66bda
Temporarily disabled GC (again) because phobos fails to compile with it (looks like some ObjSymbols are being falsely collected, see Library.d:666)
korDen
parents:
114
diff
changeset
|
208 Module assertexp_mn = null; |
0 | 209 |
210 if (!assertexp_sfilename || loc.filename != assertexp_name || assertexp_mn != m) | |
211 { | |
212 dt_t* dt = null; | |
213 | |
214 string id = loc.filename; | |
215 int len = id.length; | |
216 dtdword(&dt, len); | |
217 dtabytes(&dt,TYnptr, 0, len + 1, toStringz(id)); | |
218 | |
219 assertexp_sfilename = symbol_generate(SCstatic,type_fake(TYdarray)); | |
220 assertexp_sfilename.Sdt = dt; | |
221 assertexp_sfilename.Sfl = FLdata; | |
222 version (ELFOBJ) { | |
22
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
0
diff
changeset
|
223 assertexp_sfilename.Sseg = Segment.CDATA; |
0 | 224 } |
225 version (MACHOBJ) { | |
22
fd4acc376c45
Implemented object file output and linking on linux.
Robert Clipsham <robert@octarineparrot.com>
parents:
0
diff
changeset
|
226 assertexp_sfilename.Sseg = Segment.DATA; |
0 | 227 } |
228 outdata(assertexp_sfilename); | |
229 | |
230 assertexp_mn = m; | |
231 assertexp_name = id; | |
232 } | |
233 | |
234 efilename = el_var(assertexp_sfilename); | |
235 | |
236 if (msg) | |
174 | 237 { |
0 | 238 elem* emsg = msg.toElem(irs); |
239 ea = el_var(rtlsym[RTLSYM_DASSERT_MSG]); | |
240 ea = el_bin(OPcall, TYvoid, ea, el_params(el_long(TYint, loc.linnum), efilename, emsg, null)); | |
241 } | |
242 else | |
243 { | |
244 ea = el_var(rtlsym[RTLSYM_DASSERT]); | |
245 ea = el_bin(OPcall, TYvoid, ea, el_param(el_long(TYint, loc.linnum), efilename)); | |
246 } | |
247 } | |
248 else | |
249 { | |
250 sassert = m.toModuleAssert(); | |
251 ea = el_bin(OPcall,TYvoid,el_var(sassert), | |
252 el_long(TYint, loc.linnum)); | |
253 } | |
254 e = el_bin(OPoror,TYvoid,e,ea); | |
255 } | |
256 } | |
257 else | |
174 | 258 { |
0 | 259 // BUG: should replace assert(0); with a HLT instruction |
260 e = el_long(TYint, 0); | |
261 } | |
262 el_setLoc(e,loc); | |
263 | |
264 return e; | |
265 } | |
266 } | |
267 |