Mercurial > projects > ldc
annotate gen/toobj.cpp @ 102:027b8d8b71ec trunk
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
Basically it tries to do the following in order: Resolve types, Declare symbols, Create constant initializers, Apply initializers, Generate functions bodies.
ClassInfo is now has the most useful(biased?) members working.
Probably other stuf...
author | lindquist |
---|---|
date | Sun, 18 Nov 2007 06:52:57 +0100 |
parents | 5071469303d4 |
children | 855adfdb8d38 |
rev | line source |
---|---|
1 | 1 |
2 // Copyright (c) 1999-2004 by Digital Mars | |
3 // All Rights Reserved | |
4 // written by Walter Bright | |
5 // www.digitalmars.com | |
6 // License for redistribution is by either the Artistic License | |
7 // in artistic.txt, or the GNU General Public License in gnu.txt. | |
8 // See the included readme.txt for details. | |
9 | |
10 #include <cstddef> | |
11 #include <iostream> | |
12 #include <fstream> | |
13 | |
40 | 14 #include "gen/llvm.h" |
1 | 15 #include "llvm/Analysis/Verifier.h" |
16 #include "llvm/Bitcode/ReaderWriter.h" | |
17 #include "llvm/Target/TargetMachine.h" | |
18 #include "llvm/Target/TargetMachineRegistry.h" | |
19 | |
20 #include "mars.h" | |
21 #include "module.h" | |
22 #include "mtype.h" | |
23 #include "declaration.h" | |
24 #include "statement.h" | |
25 #include "enum.h" | |
26 #include "aggregate.h" | |
27 #include "init.h" | |
28 #include "attrib.h" | |
29 #include "id.h" | |
30 #include "import.h" | |
31 #include "template.h" | |
18 | 32 #include "scope.h" |
1 | 33 |
4
e116aa1488e6
[svn r8] changed backend includes to always use the gen/<foo>.h prefix
lindquist
parents:
1
diff
changeset
|
34 #include "gen/irstate.h" |
e116aa1488e6
[svn r8] changed backend includes to always use the gen/<foo>.h prefix
lindquist
parents:
1
diff
changeset
|
35 #include "gen/logger.h" |
e116aa1488e6
[svn r8] changed backend includes to always use the gen/<foo>.h prefix
lindquist
parents:
1
diff
changeset
|
36 #include "gen/tollvm.h" |
64
b688ad419f8c
[svn r68] Added support for multi-dimensional static arrays.
lindquist
parents:
63
diff
changeset
|
37 #include "gen/arrays.h" |
88
058d3925950e
[svn r92] Fixed support for statically initialized unions. lots of bugfixes as cleanups too.
lindquist
parents:
86
diff
changeset
|
38 #include "gen/structs.h" |
100 | 39 #include "gen/classes.h" |
40 #include "gen/functions.h" | |
82
d8dd47ef3973
[svn r86] Changed the way arguments are given storage. It is now detected if they will need it during semantic passes.
lindquist
parents:
81
diff
changeset
|
41 #include "gen/todebug.h" |
86
fd32135dca3e
[svn r90] Major updates to the gen directory. Redesigned the 'elem' struct. Much more... !!!
lindquist
parents:
85
diff
changeset
|
42 #include "gen/runtime.h" |
1 | 43 |
44 ////////////////////////////////////////////////////////////////////////////////////////// | |
45 | |
46 void | |
47 Module::genobjfile() | |
48 { | |
49 Logger::cout() << "Generating module: " << (md ? md->toChars() : toChars()) << '\n'; | |
50 LOG_SCOPE; | |
51 | |
6 | 52 // start by deleting the old object file |
1 | 53 deleteObjFile(); |
54 | |
18 | 55 // create a new ir state |
1 | 56 IRState ir; |
57 gIR = &ir; | |
58 ir.dmodule = this; | |
59 | |
6 | 60 // name the module |
1 | 61 std::string mname(toChars()); |
62 if (md != 0) | |
63 mname = md->toChars(); | |
64 ir.module = new llvm::Module(mname); | |
65 | |
6 | 66 // set target stuff |
1 | 67 std::string target_triple(global.params.tt_arch); |
68 target_triple.append(global.params.tt_os); | |
69 ir.module->setTargetTriple(target_triple); | |
70 ir.module->setDataLayout(global.params.data_layout); | |
71 | |
73 | 72 // heavily inspired by tools/llc/llc.cpp:200-230 |
73 const llvm::TargetMachineRegistry::Entry* targetEntry; | |
74 std::string targetError; | |
75 targetEntry = llvm::TargetMachineRegistry::getClosestStaticTargetForModule(*ir.module, targetError); | |
76 assert(targetEntry && "Failed to find a static target for module"); | |
77 std::auto_ptr<llvm::TargetMachine> targetPtr(targetEntry->CtorFn(*ir.module, "")); // TODO: replace "" with features | |
78 assert(targetPtr.get() && "Could not allocate target machine!"); | |
79 llvm::TargetMachine &targetMachine = *targetPtr.get(); | |
80 gTargetData = targetMachine.getTargetData(); | |
1 | 81 |
82
d8dd47ef3973
[svn r86] Changed the way arguments are given storage. It is now detected if they will need it during semantic passes.
lindquist
parents:
81
diff
changeset
|
82 // debug info |
d8dd47ef3973
[svn r86] Changed the way arguments are given storage. It is now detected if they will need it during semantic passes.
lindquist
parents:
81
diff
changeset
|
83 if (global.params.symdebug) { |
d8dd47ef3973
[svn r86] Changed the way arguments are given storage. It is now detected if they will need it during semantic passes.
lindquist
parents:
81
diff
changeset
|
84 RegisterDwarfSymbols(ir.module); |
94
61615fa85940
[svn r98] Added support for std.c.stdlib.alloca via pragma(LLVM_internal, "alloca").
lindquist
parents:
89
diff
changeset
|
85 ir.dmodule->llvmCompileUnit = DtoDwarfCompileUnit(this,true); |
82
d8dd47ef3973
[svn r86] Changed the way arguments are given storage. It is now detected if they will need it during semantic passes.
lindquist
parents:
81
diff
changeset
|
86 } |
d8dd47ef3973
[svn r86] Changed the way arguments are given storage. It is now detected if they will need it during semantic passes.
lindquist
parents:
81
diff
changeset
|
87 |
6 | 88 // process module members |
1 | 89 for (int k=0; k < members->dim; k++) { |
90 Dsymbol* dsym = (Dsymbol*)(members->data[k]); | |
91 assert(dsym); | |
92 dsym->toObjFile(); | |
93 } | |
94 | |
102
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
95 // main driver loop |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
96 for(;;) |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
97 { |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
98 Dsymbol* dsym; |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
99 if (!ir.resolveList.empty()) { |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
100 dsym = ir.resolveList.front(); |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
101 ir.resolveList.pop_front(); |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
102 DtoResolveDsymbol(dsym); |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
103 } |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
104 else if (!ir.declareList.empty()) { |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
105 dsym = ir.declareList.front(); |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
106 ir.declareList.pop_front(); |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
107 DtoDeclareDsymbol(dsym); |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
108 } |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
109 else if (!ir.constInitList.empty()) { |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
110 dsym = ir.constInitList.front(); |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
111 ir.constInitList.pop_front(); |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
112 DtoConstInitDsymbol(dsym); |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
113 } |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
114 else if (!ir.defineList.empty()) { |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
115 dsym = ir.defineList.front(); |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
116 ir.defineList.pop_front(); |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
117 DtoDefineDsymbol(dsym); |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
118 } |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
119 else { |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
120 break; |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
121 } |
98
6789050b5ad1
[svn r102] Further delayed emission of function bodies to avoid problems with circular-forward-references.
lindquist
parents:
96
diff
changeset
|
122 } |
6789050b5ad1
[svn r102] Further delayed emission of function bodies to avoid problems with circular-forward-references.
lindquist
parents:
96
diff
changeset
|
123 |
89 | 124 // generate ModuleInfo |
125 genmoduleinfo(); | |
126 | |
1 | 127 gTargetData = 0; |
128 | |
11
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
10
diff
changeset
|
129 // emit the llvm main function if necessary |
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
10
diff
changeset
|
130 if (ir.emitMain) { |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
77
diff
changeset
|
131 DtoMain(); |
11
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
10
diff
changeset
|
132 } |
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
10
diff
changeset
|
133 |
6 | 134 // verify the llvm |
31
2841234d2aea
[svn r35] * Attributes on struct fields/methods now work
lindquist
parents:
28
diff
changeset
|
135 if (!global.params.novalidate) { |
2841234d2aea
[svn r35] * Attributes on struct fields/methods now work
lindquist
parents:
28
diff
changeset
|
136 std::string verifyErr; |
2841234d2aea
[svn r35] * Attributes on struct fields/methods now work
lindquist
parents:
28
diff
changeset
|
137 Logger::println("Verifying module..."); |
2841234d2aea
[svn r35] * Attributes on struct fields/methods now work
lindquist
parents:
28
diff
changeset
|
138 if (llvm::verifyModule(*ir.module,llvm::ReturnStatusAction,&verifyErr)) |
2841234d2aea
[svn r35] * Attributes on struct fields/methods now work
lindquist
parents:
28
diff
changeset
|
139 { |
2841234d2aea
[svn r35] * Attributes on struct fields/methods now work
lindquist
parents:
28
diff
changeset
|
140 error("%s", verifyErr.c_str()); |
2841234d2aea
[svn r35] * Attributes on struct fields/methods now work
lindquist
parents:
28
diff
changeset
|
141 fatal(); |
2841234d2aea
[svn r35] * Attributes on struct fields/methods now work
lindquist
parents:
28
diff
changeset
|
142 } |
2841234d2aea
[svn r35] * Attributes on struct fields/methods now work
lindquist
parents:
28
diff
changeset
|
143 else { |
2841234d2aea
[svn r35] * Attributes on struct fields/methods now work
lindquist
parents:
28
diff
changeset
|
144 Logger::println("Verification passed!"); |
2841234d2aea
[svn r35] * Attributes on struct fields/methods now work
lindquist
parents:
28
diff
changeset
|
145 } |
1 | 146 } |
147 | |
148 // run passes | |
149 // TODO | |
150 | |
52 | 151 // write bytecode |
152 { | |
153 Logger::println("Writing LLVM bitcode\n"); | |
154 std::ofstream bos(bcfile->name->toChars(), std::ios::binary); | |
155 llvm::WriteBitcodeToFile(ir.module, bos); | |
156 } | |
1 | 157 |
52 | 158 // disassemble ? |
159 if (global.params.disassemble) { | |
160 Logger::println("Writing LLVM asm to: %s\n", llfile->name->toChars()); | |
161 std::ofstream aos(llfile->name->toChars()); | |
162 ir.module->print(aos); | |
163 } | |
1 | 164 |
165 delete ir.module; | |
166 gIR = NULL; | |
167 } | |
168 | |
169 /* ================================================================== */ | |
170 | |
171 // Put out instance of ModuleInfo for this Module | |
172 | |
173 void Module::genmoduleinfo() | |
174 { | |
89 | 175 // The layout is: |
176 // { | |
177 // void **vptr; | |
178 // monitor_t monitor; | |
179 // char[] name; // class name | |
180 // ModuleInfo importedModules[]; | |
181 // ClassInfo localClasses[]; | |
182 // uint flags; // initialization state | |
183 // void *ctor; | |
184 // void *dtor; | |
185 // void *unitTest; | |
186 // } | |
187 | |
188 if (moduleinfo) { | |
189 Logger::println("moduleinfo"); | |
190 } | |
191 if (vmoduleinfo) { | |
192 Logger::println("vmoduleinfo"); | |
193 } | |
194 if (needModuleInfo()) { | |
94
61615fa85940
[svn r98] Added support for std.c.stdlib.alloca via pragma(LLVM_internal, "alloca").
lindquist
parents:
89
diff
changeset
|
195 Logger::attention("module info is needed but skipped"); |
89 | 196 } |
197 | |
198 | |
199 /* | |
200 Symbol *msym = toSymbol(); | |
201 unsigned offset; | |
202 unsigned sizeof_ModuleInfo = 12 * PTRSIZE; | |
203 | |
204 ////////////////////////////////////////////// | |
205 | |
206 csym->Sclass = SCglobal; | |
207 csym->Sfl = FLdata; | |
208 | |
209 // The layout is: | |
210 // { | |
211 // void **vptr; | |
212 // monitor_t monitor; | |
213 // char[] name; // class name | |
214 // ModuleInfo importedModules[]; | |
215 // ClassInfo localClasses[]; | |
216 // uint flags; // initialization state | |
217 // void *ctor; | |
218 // void *dtor; | |
219 // void *unitTest; | |
220 // } | |
221 dt_t *dt = NULL; | |
222 | |
223 if (moduleinfo) | |
224 dtxoff(&dt, moduleinfo->toVtblSymbol(), 0, TYnptr); // vtbl for ModuleInfo | |
225 else | |
226 dtdword(&dt, 0); // BUG: should be an assert() | |
227 dtdword(&dt, 0); // monitor | |
228 | |
229 // name[] | |
230 char *name = toPrettyChars(); | |
231 size_t namelen = strlen(name); | |
232 dtdword(&dt, namelen); | |
233 dtabytes(&dt, TYnptr, 0, namelen + 1, name); | |
234 | |
235 ClassDeclarations aclasses; | |
236 int i; | |
237 | |
238 //printf("members->dim = %d\n", members->dim); | |
239 for (i = 0; i < members->dim; i++) | |
240 { | |
241 Dsymbol *member; | |
242 | |
243 member = (Dsymbol *)members->data[i]; | |
244 //printf("\tmember '%s'\n", member->toChars()); | |
245 member->addLocalClass(&aclasses); | |
246 } | |
247 | |
248 // importedModules[] | |
249 int aimports_dim = aimports.dim; | |
250 for (i = 0; i < aimports.dim; i++) | |
251 { Module *m = (Module *)aimports.data[i]; | |
252 if (!m->needModuleInfo()) | |
253 aimports_dim--; | |
254 } | |
255 dtdword(&dt, aimports_dim); | |
256 if (aimports.dim) | |
257 dtxoff(&dt, csym, sizeof_ModuleInfo, TYnptr); | |
258 else | |
259 dtdword(&dt, 0); | |
260 | |
261 // localClasses[] | |
262 dtdword(&dt, aclasses.dim); | |
263 if (aclasses.dim) | |
264 dtxoff(&dt, csym, sizeof_ModuleInfo + aimports_dim * PTRSIZE, TYnptr); | |
265 else | |
266 dtdword(&dt, 0); | |
267 | |
268 if (needmoduleinfo) | |
269 dtdword(&dt, 0); // flags (4 means MIstandalone) | |
270 else | |
271 dtdword(&dt, 4); // flags (4 means MIstandalone) | |
272 | |
273 if (sctor) | |
274 dtxoff(&dt, sctor, 0, TYnptr); | |
275 else | |
276 dtdword(&dt, 0); | |
277 | |
278 if (sdtor) | |
279 dtxoff(&dt, sdtor, 0, TYnptr); | |
280 else | |
281 dtdword(&dt, 0); | |
282 | |
283 if (stest) | |
284 dtxoff(&dt, stest, 0, TYnptr); | |
285 else | |
286 dtdword(&dt, 0); | |
287 | |
288 ////////////////////////////////////////////// | |
289 | |
290 for (i = 0; i < aimports.dim; i++) | |
291 { | |
292 Module *m; | |
293 | |
294 m = (Module *)aimports.data[i]; | |
295 if (m->needModuleInfo()) | |
296 { Symbol *s = m->toSymbol(); | |
297 s->Sflags |= SFLweak; | |
298 dtxoff(&dt, s, 0, TYnptr); | |
299 } | |
300 } | |
301 | |
302 for (i = 0; i < aclasses.dim; i++) | |
303 { | |
304 ClassDeclaration *cd; | |
305 | |
306 cd = (ClassDeclaration *)aclasses.data[i]; | |
307 dtxoff(&dt, cd->toSymbol(), 0, TYnptr); | |
308 } | |
309 | |
310 csym->Sdt = dt; | |
311 #if ELFOBJ | |
312 // Cannot be CONST because the startup code sets flag bits in it | |
313 csym->Sseg = DATA; | |
314 #endif | |
315 outdata(csym); | |
316 | |
317 ////////////////////////////////////////////// | |
318 | |
319 obj_moduleinfo(msym); | |
320 */ | |
1 | 321 } |
322 | |
323 /* ================================================================== */ | |
324 | |
325 void Dsymbol::toObjFile() | |
326 { | |
38
27b2f40bdb58
[svn r42] Disabled the extensive logging by default. Use the -vv flag to get it back.
lindquist
parents:
31
diff
changeset
|
327 Logger::println("Ignoring Dsymbol::toObjFile for %s", toChars()); |
1 | 328 } |
329 | |
330 /* ================================================================== */ | |
331 | |
332 void Declaration::toObjFile() | |
333 { | |
38
27b2f40bdb58
[svn r42] Disabled the extensive logging by default. Use the -vv flag to get it back.
lindquist
parents:
31
diff
changeset
|
334 Logger::println("Ignoring Declaration::toObjFile for %s", toChars()); |
1 | 335 } |
336 | |
337 /* ================================================================== */ | |
338 | |
339 void InterfaceDeclaration::toObjFile() | |
340 { | |
38
27b2f40bdb58
[svn r42] Disabled the extensive logging by default. Use the -vv flag to get it back.
lindquist
parents:
31
diff
changeset
|
341 Logger::println("Ignoring InterfaceDeclaration::toObjFile for %s", toChars()); |
1 | 342 } |
343 | |
344 /* ================================================================== */ | |
345 | |
346 void StructDeclaration::toObjFile() | |
347 { | |
102
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
348 gIR->resolveList.push_back(this); |
1 | 349 } |
350 | |
351 /* ================================================================== */ | |
352 | |
77
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
74
diff
changeset
|
353 static unsigned LLVM_ClassOffsetToIndex(ClassDeclaration* cd, unsigned os, unsigned& idx) |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
74
diff
changeset
|
354 { |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
74
diff
changeset
|
355 // start at the bottom of the inheritance chain |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
74
diff
changeset
|
356 if (cd->baseClass != 0) { |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
74
diff
changeset
|
357 unsigned o = LLVM_ClassOffsetToIndex(cd->baseClass, os, idx); |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
74
diff
changeset
|
358 if (o != (unsigned)-1) |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
74
diff
changeset
|
359 return o; |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
74
diff
changeset
|
360 } |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
74
diff
changeset
|
361 |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
74
diff
changeset
|
362 // check this class |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
74
diff
changeset
|
363 unsigned i; |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
74
diff
changeset
|
364 for (i=0; i<cd->fields.dim; ++i) { |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
74
diff
changeset
|
365 VarDeclaration* vd = (VarDeclaration*)cd->fields.data[i]; |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
74
diff
changeset
|
366 if (os == vd->offset) |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
74
diff
changeset
|
367 return i+idx; |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
74
diff
changeset
|
368 } |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
74
diff
changeset
|
369 idx += i; |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
74
diff
changeset
|
370 |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
74
diff
changeset
|
371 return (unsigned)-1; |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
74
diff
changeset
|
372 } |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
74
diff
changeset
|
373 |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
74
diff
changeset
|
374 void ClassDeclaration::offsetToIndex(Type* t, unsigned os, std::vector<unsigned>& result) |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
74
diff
changeset
|
375 { |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
74
diff
changeset
|
376 unsigned idx = 0; |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
74
diff
changeset
|
377 unsigned r = LLVM_ClassOffsetToIndex(this, os, idx); |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
74
diff
changeset
|
378 assert(r != (unsigned)-1 && "Offset not found in any aggregate field"); |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
74
diff
changeset
|
379 result.push_back(r+1); // vtable is 0 |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
74
diff
changeset
|
380 } |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
74
diff
changeset
|
381 |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
74
diff
changeset
|
382 /* ================================================================== */ |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
74
diff
changeset
|
383 |
1 | 384 void ClassDeclaration::toObjFile() |
385 { | |
102
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
386 gIR->resolveList.push_back(this); |
1 | 387 } |
388 | |
389 /****************************************** | |
390 * Get offset of base class's vtbl[] initializer from start of csym. | |
391 * Returns ~0 if not this csym. | |
392 */ | |
393 | |
394 unsigned ClassDeclaration::baseVtblOffset(BaseClass *bc) | |
395 { | |
396 return ~0; | |
397 } | |
398 | |
399 /* ================================================================== */ | |
400 | |
401 void VarDeclaration::toObjFile() | |
402 { | |
40 | 403 Logger::print("VarDeclaration::toObjFile(): %s | %s\n", toChars(), type->toChars()); |
1 | 404 LOG_SCOPE; |
405 | |
85
f869c636a113
[svn r89] Fixed a bunch of problems with template instance across multiple modules.
lindquist
parents:
84
diff
changeset
|
406 if (aliassym) |
f869c636a113
[svn r89] Fixed a bunch of problems with template instance across multiple modules.
lindquist
parents:
84
diff
changeset
|
407 { |
88
058d3925950e
[svn r92] Fixed support for statically initialized unions. lots of bugfixes as cleanups too.
lindquist
parents:
86
diff
changeset
|
408 Logger::println("alias sym"); |
85
f869c636a113
[svn r89] Fixed a bunch of problems with template instance across multiple modules.
lindquist
parents:
84
diff
changeset
|
409 toAlias()->toObjFile(); |
f869c636a113
[svn r89] Fixed a bunch of problems with template instance across multiple modules.
lindquist
parents:
84
diff
changeset
|
410 return; |
f869c636a113
[svn r89] Fixed a bunch of problems with template instance across multiple modules.
lindquist
parents:
84
diff
changeset
|
411 } |
f869c636a113
[svn r89] Fixed a bunch of problems with template instance across multiple modules.
lindquist
parents:
84
diff
changeset
|
412 |
1 | 413 // global variable or magic |
85
f869c636a113
[svn r89] Fixed a bunch of problems with template instance across multiple modules.
lindquist
parents:
84
diff
changeset
|
414 if (isDataseg()) |
1 | 415 { |
102
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
416 if (llvmResolved) return; |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
417 llvmResolved = true; |
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
418 llvmDeclared = true; |
40 | 419 |
100 | 420 llvmIRGlobal = new IRGlobal(this); |
421 | |
422 Logger::println("parent: %s (%s)", parent->toChars(), parent->kind()); | |
423 | |
424 bool _isconst = isConst(); | |
425 if (parent && parent->isFuncDeclaration() && init && init->isExpInitializer()) | |
426 _isconst = false; | |
26
99737f94abfb
[svn r30] * Fixed static function-local variables.
lindquist
parents:
24
diff
changeset
|
427 |
99737f94abfb
[svn r30] * Fixed static function-local variables.
lindquist
parents:
24
diff
changeset
|
428 llvm::GlobalValue::LinkageTypes _linkage; |
85
f869c636a113
[svn r89] Fixed a bunch of problems with template instance across multiple modules.
lindquist
parents:
84
diff
changeset
|
429 bool istempl = false; |
100 | 430 bool static_local = false; |
85
f869c636a113
[svn r89] Fixed a bunch of problems with template instance across multiple modules.
lindquist
parents:
84
diff
changeset
|
431 if ((storage_class & STCcomdat) || (parent && DtoIsTemplateInstance(parent))) { |
f869c636a113
[svn r89] Fixed a bunch of problems with template instance across multiple modules.
lindquist
parents:
84
diff
changeset
|
432 _linkage = llvm::GlobalValue::WeakLinkage; |
f869c636a113
[svn r89] Fixed a bunch of problems with template instance across multiple modules.
lindquist
parents:
84
diff
changeset
|
433 istempl = true; |
f869c636a113
[svn r89] Fixed a bunch of problems with template instance across multiple modules.
lindquist
parents:
84
diff
changeset
|
434 } |
100 | 435 else if (parent && parent->isFuncDeclaration()) { |
26
99737f94abfb
[svn r30] * Fixed static function-local variables.
lindquist
parents:
24
diff
changeset
|
436 _linkage = llvm::GlobalValue::InternalLinkage; |
100 | 437 static_local = true; |
438 } | |
26
99737f94abfb
[svn r30] * Fixed static function-local variables.
lindquist
parents:
24
diff
changeset
|
439 else |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
77
diff
changeset
|
440 _linkage = DtoLinkage(protection, storage_class); |
26
99737f94abfb
[svn r30] * Fixed static function-local variables.
lindquist
parents:
24
diff
changeset
|
441 |
100 | 442 const llvm::Type* _type = llvmIRGlobal->type.get(); |
1 | 443 |
21
8d45266bbabe
[svn r25] * Fixed a lot of problems with string literals
lindquist
parents:
18
diff
changeset
|
444 Logger::println("Creating global variable"); |
8d45266bbabe
[svn r25] * Fixed a lot of problems with string literals
lindquist
parents:
18
diff
changeset
|
445 std::string _name(mangle()); |
52 | 446 |
100 | 447 llvm::GlobalVariable* gvar = new llvm::GlobalVariable(_type,_isconst,_linkage,NULL,_name,gIR->module); |
88
058d3925950e
[svn r92] Fixed support for statically initialized unions. lots of bugfixes as cleanups too.
lindquist
parents:
86
diff
changeset
|
448 llvmValue = gvar; |
058d3925950e
[svn r92] Fixed support for statically initialized unions. lots of bugfixes as cleanups too.
lindquist
parents:
86
diff
changeset
|
449 |
100 | 450 if (static_local) |
451 DtoConstInitGlobal(this); | |
452 else | |
102
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
453 gIR->constInitList.push_back(this); |
1 | 454 |
455 //if (storage_class & STCprivate) | |
456 // gvar->setVisibility(llvm::GlobalValue::ProtectedVisibility); | |
457 } | |
458 | |
459 // inside aggregate declaration. declare a field. | |
460 else | |
461 { | |
462 Logger::println("Aggregate var declaration: '%s' offset=%d", toChars(), offset); | |
463 | |
100 | 464 const llvm::Type* _type = DtoType(type); |
73 | 465 |
466 // add the field in the IRStruct | |
100 | 467 gIR->topstruct()->offsets.insert(std::make_pair(offset, IRStruct::Offset(this, _type))); |
1 | 468 } |
469 | |
470 Logger::println("VarDeclaration::toObjFile is done"); | |
471 } | |
472 | |
473 /* ================================================================== */ | |
474 | |
475 void TypedefDeclaration::toObjFile() | |
476 { | |
477 static int tdi = 0; | |
478 Logger::print("TypedefDeclaration::toObjFile(%d): %s\n", tdi++, toChars()); | |
479 LOG_SCOPE; | |
480 | |
52 | 481 // generate typeinfo |
72 | 482 type->getTypeInfo(NULL); |
1 | 483 } |
484 | |
485 /* ================================================================== */ | |
486 | |
487 void EnumDeclaration::toObjFile() | |
488 { | |
38
27b2f40bdb58
[svn r42] Disabled the extensive logging by default. Use the -vv flag to get it back.
lindquist
parents:
31
diff
changeset
|
489 Logger::println("Ignoring EnumDeclaration::toObjFile for %s", toChars()); |
1 | 490 } |
491 | |
492 /* ================================================================== */ | |
493 | |
494 void FuncDeclaration::toObjFile() | |
495 { | |
102
027b8d8b71ec
[svn r106] Turns out the last commit wasn't enough, now the D->LLVM process is even more split up.
lindquist
parents:
100
diff
changeset
|
496 gIR->resolveList.push_back(this); |
1 | 497 } |