comparison gen/declarations.cpp @ 1147:dbe4af57b240

Changed use of toObjFile to a new codegen method. More versioning of DMD specific codegen code.
author Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
date Fri, 27 Mar 2009 17:54:27 +0100
parents
children 3d1b16dabd25
comparison
equal deleted inserted replaced
1146:1860414bf3b7 1147:dbe4af57b240
1 #include "gen/llvm.h"
2
3 #include "aggregate.h"
4 #include "declaration.h"
5 #include "enum.h"
6 #include "id.h"
7 #include "mem.h"
8 #include "template.h"
9
10 #include "gen/irstate.h"
11 #include "gen/tollvm.h"
12 #include "gen/llvmhelpers.h"
13 #include "gen/logger.h"
14
15 #include "ir/ir.h"
16 #include "ir/irvar.h"
17
18 /* ================================================================== */
19
20 void Dsymbol::codegen(Ir*)
21 {
22 Logger::println("Ignoring Dsymbol::toObjFile for %s", toChars());
23 }
24
25 /* ================================================================== */
26
27 void Declaration::codegen(Ir*)
28 {
29 Logger::println("Ignoring Declaration::toObjFile for %s", toChars());
30 }
31
32 /* ================================================================== */
33
34 void InterfaceDeclaration::codegen(Ir*)
35 {
36 //Logger::println("Ignoring InterfaceDeclaration::toObjFile for %s", toChars());
37 DtoResolveDsymbol(this);
38 }
39
40 /* ================================================================== */
41
42 void StructDeclaration::codegen(Ir*)
43 {
44 DtoResolveDsymbol(this);
45 }
46
47 /* ================================================================== */
48
49 void ClassDeclaration::codegen(Ir*)
50 {
51 DtoResolveDsymbol(this);
52 }
53
54 /* ================================================================== */
55
56 void TupleDeclaration::codegen(Ir* p)
57 {
58 Logger::println("TupleDeclaration::toObjFile(): %s", toChars());
59
60 assert(isexp);
61 assert(objects);
62
63 int n = objects->dim;
64
65 for (int i=0; i < n; ++i)
66 {
67 DsymbolExp* exp = (DsymbolExp*)objects->data[i];
68 assert(exp->op == TOKdsymbol);
69 exp->s->codegen(p);
70 }
71 }
72
73 /* ================================================================== */
74
75 void VarDeclaration::codegen(Ir* p)
76 {
77 Logger::print("VarDeclaration::toObjFile(): %s | %s\n", toChars(), type->toChars());
78 LOG_SCOPE;
79
80 if (aliassym)
81 {
82 Logger::println("alias sym");
83 toAlias()->codegen(p);
84 return;
85 }
86
87 // global variable or magic
88 #if DMDV2
89 // taken from dmd2/structs
90 if (isDataseg() || (storage_class & (STCconst | STCinvariant) && init))
91 #else
92 if (isDataseg())
93 #endif
94 {
95 Logger::println("data segment");
96
97 #if DMDV2
98 if (storage_class & STCmanifest)
99 {
100 assert(0 && "manifest constant being codegened!!!");
101 }
102 #endif
103
104 // don't duplicate work
105 if (this->ir.resolved) return;
106 this->ir.resolved = true;
107 this->ir.declared = true;
108
109 this->ir.irGlobal = new IrGlobal(this);
110
111 Logger::println("parent: %s (%s)", parent->toChars(), parent->kind());
112
113 #if DMDV2
114 // not sure why this is only needed for d2
115 bool _isconst = isConst() && init;
116 #else
117 bool _isconst = isConst();
118 #endif
119
120
121 Logger::println("Creating global variable");
122
123 const LLType* _type = this->ir.irGlobal->type.get();
124 llvm::GlobalValue::LinkageTypes _linkage = DtoLinkage(this);
125 std::string _name(mangle());
126
127 llvm::GlobalVariable* gvar = new llvm::GlobalVariable(_type,_isconst,_linkage,NULL,_name,gIR->module);
128 this->ir.irGlobal->value = gvar;
129
130 if (Logger::enabled())
131 Logger::cout() << *gvar << '\n';
132
133 // if this global is used from a nested function, this is necessary or
134 // optimization could potentially remove the global (if it's the only use)
135 if (nakedUse)
136 gIR->usedArray.push_back(DtoBitCast(gvar, getVoidPtrType()));
137
138 gIR->constInitList.push_back(this);
139 }
140 else
141 {
142 // might already have its irField, as classes derive each other without getting copies of the VarDeclaration
143 if (!ir.irField)
144 {
145 assert(!ir.isSet());
146 ir.irField = new IrField(this);
147 }
148 IrStruct* irstruct = gIR->topstruct();
149 irstruct->addVar(this);
150
151 Logger::println("added offset %u", offset);
152 }
153 }
154
155 /* ================================================================== */
156
157 void TypedefDeclaration::codegen(Ir*)
158 {
159 static int tdi = 0;
160 Logger::print("TypedefDeclaration::toObjFile(%d): %s\n", tdi++, toChars());
161 LOG_SCOPE;
162
163 // generate typeinfo
164 DtoTypeInfoOf(type, false);
165 }
166
167 /* ================================================================== */
168
169 void EnumDeclaration::codegen(Ir*)
170 {
171 Logger::println("Ignoring EnumDeclaration::toObjFile for %s", toChars());
172 }
173
174 /* ================================================================== */
175
176 void FuncDeclaration::codegen(Ir*)
177 {
178 DtoResolveDsymbol(this);
179 }
180
181 /* ================================================================== */
182
183 void AnonDeclaration::codegen(Ir* p)
184 {
185 Array *d = include(NULL, NULL);
186
187 if (d)
188 {
189 // get real aggregate parent
190 IrStruct* irstruct = gIR->topstruct();
191
192 // push a block on the stack
193 irstruct->pushAnon(isunion);
194
195 // go over children
196 for (unsigned i = 0; i < d->dim; i++)
197 { Dsymbol *s = (Dsymbol *)d->data[i];
198 s->codegen(p);
199 }
200
201 // finish
202 irstruct->popAnon();
203 }
204 }
205
206 /* ================================================================== */
207
208 void TemplateInstance::codegen(Ir* p)
209 {
210 #if LOG
211 printf("TemplateInstance::toObjFile('%s', this = %p)\n", toChars(), this);
212 #endif
213 if (!errors && members)
214 {
215 for (int i = 0; i < members->dim; i++)
216 {
217 Dsymbol *s = (Dsymbol *)members->data[i];
218 s->codegen(p);
219 }
220 }
221 }
222
223 /* ================================================================== */
224
225 void TemplateMixin::codegen(Ir* p)
226 {
227 TemplateInstance::codegen(p);
228 }
229
230 /* ================================================================== */
231
232 void AttribDeclaration::codegen(Ir* p)
233 {
234 Array *d = include(NULL, NULL);
235
236 if (d)
237 {
238 for (unsigned i = 0; i < d->dim; i++)
239 { Dsymbol *s = (Dsymbol *)d->data[i];
240 s->codegen(p);
241 }
242 }
243 }
244
245 /* ================================================================== */
246
247 void obj_includelib(const char* lib);
248
249 void PragmaDeclaration::codegen(Ir* p)
250 {
251 if (ident == Id::lib)
252 {
253 assert(args && args->dim == 1);
254
255 Expression *e = (Expression *)args->data[0];
256
257 assert(e->op == TOKstring);
258
259 StringExp *se = (StringExp *)e;
260 char *name = (char *)mem.malloc(se->len + 1);
261 memcpy(name, se->string, se->len);
262 name[se->len] = 0;
263 obj_includelib(name);
264 }
265 AttribDeclaration::codegen(p);
266 }
267
268 /* ================================================================== */