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