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