Mercurial > projects > ldc
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 /* ================================================================== */ |