Mercurial > projects > ldc
annotate gen/toobj.cpp @ 106:5b5194b25f33 trunk
[svn r110] Fixed typeinfo for classes.
author | lindquist |
---|---|
date | Mon, 19 Nov 2007 06:01:48 +0100 |
parents | 855adfdb8d38 |
children | 27b9f749d9fe |
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 |
103
855adfdb8d38
[svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
lindquist
parents:
102
diff
changeset
|
88 // start out by providing opaque for the built-in class types |
855adfdb8d38
[svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
lindquist
parents:
102
diff
changeset
|
89 if (!ClassDeclaration::object->type->llvmType) |
855adfdb8d38
[svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
lindquist
parents:
102
diff
changeset
|
90 ClassDeclaration::object->type->llvmType = new llvm::PATypeHolder(llvm::OpaqueType::get()); |
855adfdb8d38
[svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
lindquist
parents:
102
diff
changeset
|
91 |
855adfdb8d38
[svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
lindquist
parents:
102
diff
changeset
|
92 if (!Type::typeinfo->type->llvmType) |
855adfdb8d38
[svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
lindquist
parents:
102
diff
changeset
|
93 Type::typeinfo->type->llvmType = new llvm::PATypeHolder(llvm::OpaqueType::get()); |
855adfdb8d38
[svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
lindquist
parents:
102
diff
changeset
|
94 |
855adfdb8d38
[svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
lindquist
parents:
102
diff
changeset
|
95 if (!ClassDeclaration::classinfo->type->llvmType) |
855adfdb8d38
[svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
lindquist
parents:
102
diff
changeset
|
96 ClassDeclaration::classinfo->type->llvmType = new llvm::PATypeHolder(llvm::OpaqueType::get()); |
855adfdb8d38
[svn r107] Getting .classinfo on a class instance now works (classinfo is stored in vtable)
lindquist
parents:
102
diff
changeset
|
97 |
106 | 98 /*if (!Type::typeinfoclass->type->llvmType) |
99 Type::typeinfoclass->type->llvmType = new llvm::PATypeHolder(llvm::OpaqueType::get());*/ | |
100 | |
6 | 101 // process module members |
1 | 102 for (int k=0; k < members->dim; k++) { |
103 Dsymbol* dsym = (Dsymbol*)(members->data[k]); | |
104 assert(dsym); | |
105 dsym->toObjFile(); | |
106 } | |
107 | |
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
|
108 // 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
|
109 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
|
110 { |
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 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
|
112 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
|
113 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
|
114 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
|
115 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
|
116 } |
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 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
|
118 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
|
119 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
|
120 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
|
121 } |
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
|
122 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
|
123 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
|
124 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
|
125 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
|
126 } |
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
|
127 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
|
128 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
|
129 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
|
130 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
|
131 } |
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
|
132 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
|
133 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
|
134 } |
98
6789050b5ad1
[svn r102] Further delayed emission of function bodies to avoid problems with circular-forward-references.
lindquist
parents:
96
diff
changeset
|
135 } |
6789050b5ad1
[svn r102] Further delayed emission of function bodies to avoid problems with circular-forward-references.
lindquist
parents:
96
diff
changeset
|
136 |
89 | 137 // generate ModuleInfo |
138 genmoduleinfo(); | |
139 | |
1 | 140 gTargetData = 0; |
141 | |
11
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
10
diff
changeset
|
142 // 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
|
143 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
|
144 DtoMain(); |
11
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
10
diff
changeset
|
145 } |
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
10
diff
changeset
|
146 |
6 | 147 // verify the llvm |
31
2841234d2aea
[svn r35] * Attributes on struct fields/methods now work
lindquist
parents:
28
diff
changeset
|
148 if (!global.params.novalidate) { |
2841234d2aea
[svn r35] * Attributes on struct fields/methods now work
lindquist
parents:
28
diff
changeset
|
149 std::string verifyErr; |
2841234d2aea
[svn r35] * Attributes on struct fields/methods now work
lindquist
parents:
28
diff
changeset
|
150 Logger::println("Verifying module..."); |
2841234d2aea
[svn r35] * Attributes on struct fields/methods now work
lindquist
parents:
28
diff
changeset
|
151 if (llvm::verifyModule(*ir.module,llvm::ReturnStatusAction,&verifyErr)) |
2841234d2aea
[svn r35] * Attributes on struct fields/methods now work
lindquist
parents:
28
diff
changeset
|
152 { |
2841234d2aea
[svn r35] * Attributes on struct fields/methods now work
lindquist
parents:
28
diff
changeset
|
153 error("%s", verifyErr.c_str()); |
2841234d2aea
[svn r35] * Attributes on struct fields/methods now work
lindquist
parents:
28
diff
changeset
|
154 fatal(); |
2841234d2aea
[svn r35] * Attributes on struct fields/methods now work
lindquist
parents:
28
diff
changeset
|
155 } |
2841234d2aea
[svn r35] * Attributes on struct fields/methods now work
lindquist
parents:
28
diff
changeset
|
156 else { |
2841234d2aea
[svn r35] * Attributes on struct fields/methods now work
lindquist
parents:
28
diff
changeset
|
157 Logger::println("Verification passed!"); |
2841234d2aea
[svn r35] * Attributes on struct fields/methods now work
lindquist
parents:
28
diff
changeset
|
158 } |
1 | 159 } |
160 | |
161 // run passes | |
162 // TODO | |
163 | |
52 | 164 // write bytecode |
165 { | |
166 Logger::println("Writing LLVM bitcode\n"); | |
167 std::ofstream bos(bcfile->name->toChars(), std::ios::binary); | |
168 llvm::WriteBitcodeToFile(ir.module, bos); | |
169 } | |
1 | 170 |
52 | 171 // disassemble ? |
172 if (global.params.disassemble) { | |
173 Logger::println("Writing LLVM asm to: %s\n", llfile->name->toChars()); | |
174 std::ofstream aos(llfile->name->toChars()); | |
175 ir.module->print(aos); | |
176 } | |
1 | 177 |
178 delete ir.module; | |
179 gIR = NULL; | |
180 } | |
181 | |
182 /* ================================================================== */ | |
183 | |
184 // Put out instance of ModuleInfo for this Module | |
185 | |
186 void Module::genmoduleinfo() | |
187 { | |
89 | 188 // The layout is: |
189 // { | |
190 // void **vptr; | |
191 // monitor_t monitor; | |
192 // char[] name; // class name | |
193 // ModuleInfo importedModules[]; | |
194 // ClassInfo localClasses[]; | |
195 // uint flags; // initialization state | |
196 // void *ctor; | |
197 // void *dtor; | |
198 // void *unitTest; | |
199 // } | |
200 | |
201 if (moduleinfo) { | |
202 Logger::println("moduleinfo"); | |
203 } | |
204 if (vmoduleinfo) { | |
205 Logger::println("vmoduleinfo"); | |
206 } | |
207 if (needModuleInfo()) { | |
94
61615fa85940
[svn r98] Added support for std.c.stdlib.alloca via pragma(LLVM_internal, "alloca").
lindquist
parents:
89
diff
changeset
|
208 Logger::attention("module info is needed but skipped"); |
89 | 209 } |
210 | |
211 | |
212 /* | |
213 Symbol *msym = toSymbol(); | |
214 unsigned offset; | |
215 unsigned sizeof_ModuleInfo = 12 * PTRSIZE; | |
216 | |
217 ////////////////////////////////////////////// | |
218 | |
219 csym->Sclass = SCglobal; | |
220 csym->Sfl = FLdata; | |
221 | |
222 // The layout is: | |
223 // { | |
224 // void **vptr; | |
225 // monitor_t monitor; | |
226 // char[] name; // class name | |
227 // ModuleInfo importedModules[]; | |
228 // ClassInfo localClasses[]; | |
229 // uint flags; // initialization state | |
230 // void *ctor; | |
231 // void *dtor; | |
232 // void *unitTest; | |
233 // } | |
234 dt_t *dt = NULL; | |
235 | |
236 if (moduleinfo) | |
237 dtxoff(&dt, moduleinfo->toVtblSymbol(), 0, TYnptr); // vtbl for ModuleInfo | |
238 else | |
239 dtdword(&dt, 0); // BUG: should be an assert() | |
240 dtdword(&dt, 0); // monitor | |
241 | |
242 // name[] | |
243 char *name = toPrettyChars(); | |
244 size_t namelen = strlen(name); | |
245 dtdword(&dt, namelen); | |
246 dtabytes(&dt, TYnptr, 0, namelen + 1, name); | |
247 | |
248 ClassDeclarations aclasses; | |
249 int i; | |
250 | |
251 //printf("members->dim = %d\n", members->dim); | |
252 for (i = 0; i < members->dim; i++) | |
253 { | |
254 Dsymbol *member; | |
255 | |
256 member = (Dsymbol *)members->data[i]; | |
257 //printf("\tmember '%s'\n", member->toChars()); | |
258 member->addLocalClass(&aclasses); | |
259 } | |
260 | |
261 // importedModules[] | |
262 int aimports_dim = aimports.dim; | |
263 for (i = 0; i < aimports.dim; i++) | |
264 { Module *m = (Module *)aimports.data[i]; | |
265 if (!m->needModuleInfo()) | |
266 aimports_dim--; | |
267 } | |
268 dtdword(&dt, aimports_dim); | |
269 if (aimports.dim) | |
270 dtxoff(&dt, csym, sizeof_ModuleInfo, TYnptr); | |
271 else | |
272 dtdword(&dt, 0); | |
273 | |
274 // localClasses[] | |
275 dtdword(&dt, aclasses.dim); | |
276 if (aclasses.dim) | |
277 dtxoff(&dt, csym, sizeof_ModuleInfo + aimports_dim * PTRSIZE, TYnptr); | |
278 else | |
279 dtdword(&dt, 0); | |
280 | |
281 if (needmoduleinfo) | |
282 dtdword(&dt, 0); // flags (4 means MIstandalone) | |
283 else | |
284 dtdword(&dt, 4); // flags (4 means MIstandalone) | |
285 | |
286 if (sctor) | |
287 dtxoff(&dt, sctor, 0, TYnptr); | |
288 else | |
289 dtdword(&dt, 0); | |
290 | |
291 if (sdtor) | |
292 dtxoff(&dt, sdtor, 0, TYnptr); | |
293 else | |
294 dtdword(&dt, 0); | |
295 | |
296 if (stest) | |
297 dtxoff(&dt, stest, 0, TYnptr); | |
298 else | |
299 dtdword(&dt, 0); | |
300 | |
301 ////////////////////////////////////////////// | |
302 | |
303 for (i = 0; i < aimports.dim; i++) | |
304 { | |
305 Module *m; | |
306 | |
307 m = (Module *)aimports.data[i]; | |
308 if (m->needModuleInfo()) | |
309 { Symbol *s = m->toSymbol(); | |
310 s->Sflags |= SFLweak; | |
311 dtxoff(&dt, s, 0, TYnptr); | |
312 } | |
313 } | |
314 | |
315 for (i = 0; i < aclasses.dim; i++) | |
316 { | |
317 ClassDeclaration *cd; | |
318 | |
319 cd = (ClassDeclaration *)aclasses.data[i]; | |
320 dtxoff(&dt, cd->toSymbol(), 0, TYnptr); | |
321 } | |
322 | |
323 csym->Sdt = dt; | |
324 #if ELFOBJ | |
325 // Cannot be CONST because the startup code sets flag bits in it | |
326 csym->Sseg = DATA; | |
327 #endif | |
328 outdata(csym); | |
329 | |
330 ////////////////////////////////////////////// | |
331 | |
332 obj_moduleinfo(msym); | |
333 */ | |
1 | 334 } |
335 | |
336 /* ================================================================== */ | |
337 | |
338 void Dsymbol::toObjFile() | |
339 { | |
38
27b2f40bdb58
[svn r42] Disabled the extensive logging by default. Use the -vv flag to get it back.
lindquist
parents:
31
diff
changeset
|
340 Logger::println("Ignoring Dsymbol::toObjFile for %s", toChars()); |
1 | 341 } |
342 | |
343 /* ================================================================== */ | |
344 | |
345 void Declaration::toObjFile() | |
346 { | |
38
27b2f40bdb58
[svn r42] Disabled the extensive logging by default. Use the -vv flag to get it back.
lindquist
parents:
31
diff
changeset
|
347 Logger::println("Ignoring Declaration::toObjFile for %s", toChars()); |
1 | 348 } |
349 | |
350 /* ================================================================== */ | |
351 | |
352 void InterfaceDeclaration::toObjFile() | |
353 { | |
38
27b2f40bdb58
[svn r42] Disabled the extensive logging by default. Use the -vv flag to get it back.
lindquist
parents:
31
diff
changeset
|
354 Logger::println("Ignoring InterfaceDeclaration::toObjFile for %s", toChars()); |
1 | 355 } |
356 | |
357 /* ================================================================== */ | |
358 | |
359 void StructDeclaration::toObjFile() | |
360 { | |
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
|
361 gIR->resolveList.push_back(this); |
1 | 362 } |
363 | |
364 /* ================================================================== */ | |
365 | |
77
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
74
diff
changeset
|
366 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
|
367 { |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
74
diff
changeset
|
368 // 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
|
369 if (cd->baseClass != 0) { |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
74
diff
changeset
|
370 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
|
371 if (o != (unsigned)-1) |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
74
diff
changeset
|
372 return o; |
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 |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
74
diff
changeset
|
375 // check this class |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
74
diff
changeset
|
376 unsigned i; |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
74
diff
changeset
|
377 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
|
378 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
|
379 if (os == vd->offset) |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
74
diff
changeset
|
380 return i+idx; |
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 idx += i; |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
74
diff
changeset
|
383 |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
74
diff
changeset
|
384 return (unsigned)-1; |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
74
diff
changeset
|
385 } |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
74
diff
changeset
|
386 |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
74
diff
changeset
|
387 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
|
388 { |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
74
diff
changeset
|
389 unsigned idx = 0; |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
74
diff
changeset
|
390 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
|
391 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
|
392 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
|
393 } |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
74
diff
changeset
|
394 |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
74
diff
changeset
|
395 /* ================================================================== */ |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
74
diff
changeset
|
396 |
1 | 397 void ClassDeclaration::toObjFile() |
398 { | |
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
|
399 gIR->resolveList.push_back(this); |
1 | 400 } |
401 | |
402 /****************************************** | |
403 * Get offset of base class's vtbl[] initializer from start of csym. | |
404 * Returns ~0 if not this csym. | |
405 */ | |
406 | |
407 unsigned ClassDeclaration::baseVtblOffset(BaseClass *bc) | |
408 { | |
409 return ~0; | |
410 } | |
411 | |
412 /* ================================================================== */ | |
413 | |
414 void VarDeclaration::toObjFile() | |
415 { | |
40 | 416 Logger::print("VarDeclaration::toObjFile(): %s | %s\n", toChars(), type->toChars()); |
1 | 417 LOG_SCOPE; |
418 | |
85
f869c636a113
[svn r89] Fixed a bunch of problems with template instance across multiple modules.
lindquist
parents:
84
diff
changeset
|
419 if (aliassym) |
f869c636a113
[svn r89] Fixed a bunch of problems with template instance across multiple modules.
lindquist
parents:
84
diff
changeset
|
420 { |
88
058d3925950e
[svn r92] Fixed support for statically initialized unions. lots of bugfixes as cleanups too.
lindquist
parents:
86
diff
changeset
|
421 Logger::println("alias sym"); |
85
f869c636a113
[svn r89] Fixed a bunch of problems with template instance across multiple modules.
lindquist
parents:
84
diff
changeset
|
422 toAlias()->toObjFile(); |
f869c636a113
[svn r89] Fixed a bunch of problems with template instance across multiple modules.
lindquist
parents:
84
diff
changeset
|
423 return; |
f869c636a113
[svn r89] Fixed a bunch of problems with template instance across multiple modules.
lindquist
parents:
84
diff
changeset
|
424 } |
f869c636a113
[svn r89] Fixed a bunch of problems with template instance across multiple modules.
lindquist
parents:
84
diff
changeset
|
425 |
1 | 426 // global variable or magic |
85
f869c636a113
[svn r89] Fixed a bunch of problems with template instance across multiple modules.
lindquist
parents:
84
diff
changeset
|
427 if (isDataseg()) |
1 | 428 { |
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
|
429 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
|
430 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
|
431 llvmDeclared = true; |
40 | 432 |
100 | 433 llvmIRGlobal = new IRGlobal(this); |
434 | |
435 Logger::println("parent: %s (%s)", parent->toChars(), parent->kind()); | |
436 | |
437 bool _isconst = isConst(); | |
438 if (parent && parent->isFuncDeclaration() && init && init->isExpInitializer()) | |
439 _isconst = false; | |
26
99737f94abfb
[svn r30] * Fixed static function-local variables.
lindquist
parents:
24
diff
changeset
|
440 |
99737f94abfb
[svn r30] * Fixed static function-local variables.
lindquist
parents:
24
diff
changeset
|
441 llvm::GlobalValue::LinkageTypes _linkage; |
85
f869c636a113
[svn r89] Fixed a bunch of problems with template instance across multiple modules.
lindquist
parents:
84
diff
changeset
|
442 bool istempl = false; |
100 | 443 bool static_local = false; |
85
f869c636a113
[svn r89] Fixed a bunch of problems with template instance across multiple modules.
lindquist
parents:
84
diff
changeset
|
444 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
|
445 _linkage = llvm::GlobalValue::WeakLinkage; |
f869c636a113
[svn r89] Fixed a bunch of problems with template instance across multiple modules.
lindquist
parents:
84
diff
changeset
|
446 istempl = true; |
f869c636a113
[svn r89] Fixed a bunch of problems with template instance across multiple modules.
lindquist
parents:
84
diff
changeset
|
447 } |
100 | 448 else if (parent && parent->isFuncDeclaration()) { |
26
99737f94abfb
[svn r30] * Fixed static function-local variables.
lindquist
parents:
24
diff
changeset
|
449 _linkage = llvm::GlobalValue::InternalLinkage; |
100 | 450 static_local = true; |
451 } | |
26
99737f94abfb
[svn r30] * Fixed static function-local variables.
lindquist
parents:
24
diff
changeset
|
452 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
|
453 _linkage = DtoLinkage(protection, storage_class); |
26
99737f94abfb
[svn r30] * Fixed static function-local variables.
lindquist
parents:
24
diff
changeset
|
454 |
100 | 455 const llvm::Type* _type = llvmIRGlobal->type.get(); |
1 | 456 |
21
8d45266bbabe
[svn r25] * Fixed a lot of problems with string literals
lindquist
parents:
18
diff
changeset
|
457 Logger::println("Creating global variable"); |
8d45266bbabe
[svn r25] * Fixed a lot of problems with string literals
lindquist
parents:
18
diff
changeset
|
458 std::string _name(mangle()); |
52 | 459 |
100 | 460 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
|
461 llvmValue = gvar; |
058d3925950e
[svn r92] Fixed support for statically initialized unions. lots of bugfixes as cleanups too.
lindquist
parents:
86
diff
changeset
|
462 |
100 | 463 if (static_local) |
464 DtoConstInitGlobal(this); | |
465 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
|
466 gIR->constInitList.push_back(this); |
1 | 467 |
468 //if (storage_class & STCprivate) | |
469 // gvar->setVisibility(llvm::GlobalValue::ProtectedVisibility); | |
470 } | |
471 | |
472 // inside aggregate declaration. declare a field. | |
473 else | |
474 { | |
475 Logger::println("Aggregate var declaration: '%s' offset=%d", toChars(), offset); | |
476 | |
100 | 477 const llvm::Type* _type = DtoType(type); |
73 | 478 |
479 // add the field in the IRStruct | |
100 | 480 gIR->topstruct()->offsets.insert(std::make_pair(offset, IRStruct::Offset(this, _type))); |
1 | 481 } |
482 | |
483 Logger::println("VarDeclaration::toObjFile is done"); | |
484 } | |
485 | |
486 /* ================================================================== */ | |
487 | |
488 void TypedefDeclaration::toObjFile() | |
489 { | |
490 static int tdi = 0; | |
491 Logger::print("TypedefDeclaration::toObjFile(%d): %s\n", tdi++, toChars()); | |
492 LOG_SCOPE; | |
493 | |
52 | 494 // generate typeinfo |
72 | 495 type->getTypeInfo(NULL); |
1 | 496 } |
497 | |
498 /* ================================================================== */ | |
499 | |
500 void EnumDeclaration::toObjFile() | |
501 { | |
38
27b2f40bdb58
[svn r42] Disabled the extensive logging by default. Use the -vv flag to get it back.
lindquist
parents:
31
diff
changeset
|
502 Logger::println("Ignoring EnumDeclaration::toObjFile for %s", toChars()); |
1 | 503 } |
504 | |
505 /* ================================================================== */ | |
506 | |
507 void FuncDeclaration::toObjFile() | |
508 { | |
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
|
509 gIR->resolveList.push_back(this); |
1 | 510 } |