Mercurial > projects > ldc
annotate gen/typinf.c @ 57:a9d29e9f1fed trunk
[svn r61] Added support for D-style variadic functions :)
author | lindquist |
---|---|
date | Thu, 25 Oct 2007 02:39:53 +0200 |
parents | 28e99b04a132 |
children | 2c3cd3596187 |
rev | line source |
---|---|
1 | 1 |
2 | |
3 // Copyright (c) 1999-2004 by Digital Mars | |
4 // All Rights Reserved | |
5 // written by Walter Bright | |
6 // www.digitalmars.com | |
7 // License for redistribution is by either the Artistic License | |
8 // in artistic.txt, or the GNU General Public License in gnu.txt. | |
9 // See the included readme.txt for details. | |
10 | |
11 #include <cstdio> | |
12 #include <cassert> | |
13 | |
52 | 14 #include "gen/llvm.h" |
15 | |
1 | 16 #include "mars.h" |
17 #include "module.h" | |
18 #include "mtype.h" | |
19 #include "scope.h" | |
20 #include "init.h" | |
21 #include "expression.h" | |
22 #include "attrib.h" | |
23 #include "declaration.h" | |
24 #include "template.h" | |
25 #include "id.h" | |
26 #include "enum.h" | |
27 #include "import.h" | |
28 #include "aggregate.h" | |
29 | |
52 | 30 #include "gen/irstate.h" |
4
e116aa1488e6
[svn r8] changed backend includes to always use the gen/<foo>.h prefix
lindquist
parents:
1
diff
changeset
|
31 #include "gen/logger.h" |
52 | 32 #include "gen/runtime.h" |
54
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
33 #include "gen/tollvm.h" |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
34 #include "gen/arrays.h" |
1 | 35 |
36 /******************************************* | |
37 * Get a canonicalized form of the TypeInfo for use with the internal | |
38 * runtime library routines. Canonicalized in that static arrays are | |
39 * represented as dynamic arrays, enums are represented by their | |
40 * underlying type, etc. This reduces the number of TypeInfo's needed, | |
41 * so we can use the custom internal ones more. | |
42 */ | |
43 | |
44 Expression *Type::getInternalTypeInfo(Scope *sc) | |
45 { TypeInfoDeclaration *tid; | |
46 Expression *e; | |
47 Type *t; | |
48 static TypeInfoDeclaration *internalTI[TMAX]; | |
49 | |
50 //printf("Type::getInternalTypeInfo() %s\n", toChars()); | |
51 t = toBasetype(); | |
52 switch (t->ty) | |
53 { | |
54 case Tsarray: | |
55 t = t->next->arrayOf(); // convert to corresponding dynamic array type | |
56 break; | |
57 | |
58 case Tclass: | |
59 if (((TypeClass *)t)->sym->isInterfaceDeclaration()) | |
60 break; | |
61 goto Linternal; | |
62 | |
63 case Tarray: | |
64 if (t->next->ty != Tclass) | |
65 break; | |
66 goto Linternal; | |
67 | |
68 case Tfunction: | |
69 case Tdelegate: | |
70 case Tpointer: | |
71 Linternal: | |
72 tid = internalTI[t->ty]; | |
73 if (!tid) | |
74 { tid = new TypeInfoDeclaration(t, 1); | |
75 internalTI[t->ty] = tid; | |
76 } | |
77 e = new VarExp(0, tid); | |
52 | 78 //e = e->addressOf(sc); |
1 | 79 e->type = tid->type; // do this so we don't get redundant dereference |
80 return e; | |
81 | |
82 default: | |
83 break; | |
84 } | |
85 //printf("\tcalling getTypeInfo() %s\n", t->toChars()); | |
86 return t->getTypeInfo(sc); | |
87 } | |
88 | |
89 | |
90 /**************************************************** | |
91 * Get the exact TypeInfo. | |
92 */ | |
93 | |
94 Expression *Type::getTypeInfo(Scope *sc) | |
95 { | |
96 Expression *e; | |
97 Type *t; | |
98 | |
99 //printf("Type::getTypeInfo() %p, %s\n", this, toChars()); | |
100 t = merge(); // do this since not all Type's are merge'd | |
101 if (!t->vtinfo) | |
102 { t->vtinfo = t->getTypeInfoDeclaration(); | |
103 assert(t->vtinfo); | |
104 | |
105 /* If this has a custom implementation in std/typeinfo, then | |
106 * do not generate a COMDAT for it. | |
107 */ | |
108 if (!t->builtinTypeInfo()) | |
109 { // Generate COMDAT | |
110 if (sc) // if in semantic() pass | |
111 { // Find module that will go all the way to an object file | |
112 Module *m = sc->module->importedFrom; | |
113 m->members->push(t->vtinfo); | |
114 } | |
115 else // if in obj generation pass | |
116 { | |
117 t->vtinfo->toObjFile(); | |
118 } | |
119 } | |
120 } | |
121 e = new VarExp(0, t->vtinfo); | |
122 //e = e->addressOf(sc); | |
123 e->type = t->vtinfo->type; // do this so we don't get redundant dereference | |
124 return e; | |
125 } | |
126 | |
52 | 127 enum RET TypeFunction::retStyle() |
128 { | |
129 return RETstack; | |
130 } | |
1 | 131 |
132 TypeInfoDeclaration *Type::getTypeInfoDeclaration() | |
133 { | |
134 //printf("Type::getTypeInfoDeclaration() %s\n", toChars()); | |
135 return new TypeInfoDeclaration(this, 0); | |
136 } | |
137 | |
52 | 138 TypeInfoDeclaration *TypeTypedef::getTypeInfoDeclaration() |
1 | 139 { |
52 | 140 return new TypeInfoTypedefDeclaration(this); |
1 | 141 } |
142 | |
52 | 143 TypeInfoDeclaration *TypePointer::getTypeInfoDeclaration() |
144 { | |
145 return new TypeInfoPointerDeclaration(this); | |
146 } | |
1 | 147 |
148 TypeInfoDeclaration *TypeDArray::getTypeInfoDeclaration() | |
149 { | |
150 return new TypeInfoArrayDeclaration(this); | |
151 } | |
152 | |
153 TypeInfoDeclaration *TypeSArray::getTypeInfoDeclaration() | |
154 { | |
155 return new TypeInfoStaticArrayDeclaration(this); | |
156 } | |
157 | |
158 TypeInfoDeclaration *TypeAArray::getTypeInfoDeclaration() | |
159 { | |
160 return new TypeInfoAssociativeArrayDeclaration(this); | |
161 } | |
162 | |
52 | 163 TypeInfoDeclaration *TypeStruct::getTypeInfoDeclaration() |
164 { | |
165 return new TypeInfoStructDeclaration(this); | |
166 } | |
1 | 167 |
168 TypeInfoDeclaration *TypeClass::getTypeInfoDeclaration() | |
169 { | |
170 if (sym->isInterfaceDeclaration()) | |
171 return new TypeInfoInterfaceDeclaration(this); | |
172 else | |
173 return new TypeInfoClassDeclaration(this); | |
174 } | |
175 | |
176 TypeInfoDeclaration *TypeEnum::getTypeInfoDeclaration() | |
177 { | |
178 return new TypeInfoEnumDeclaration(this); | |
179 } | |
180 | |
181 TypeInfoDeclaration *TypeFunction::getTypeInfoDeclaration() | |
182 { | |
183 return new TypeInfoFunctionDeclaration(this); | |
184 } | |
185 | |
186 TypeInfoDeclaration *TypeDelegate::getTypeInfoDeclaration() | |
187 { | |
188 return new TypeInfoDelegateDeclaration(this); | |
189 } | |
190 | |
191 TypeInfoDeclaration *TypeTuple::getTypeInfoDeclaration() | |
192 { | |
193 return new TypeInfoTupleDeclaration(this); | |
194 } | |
195 | |
196 | |
197 /* ========================================================================= */ | |
198 | |
199 /* These decide if there's an instance for them already in std.typeinfo, | |
200 * because then the compiler doesn't need to build one. | |
201 */ | |
202 | |
203 int Type::builtinTypeInfo() | |
204 { | |
205 return 0; | |
206 } | |
207 | |
208 int TypeBasic::builtinTypeInfo() | |
209 { | |
210 return 1; | |
211 } | |
212 | |
213 int TypeDArray::builtinTypeInfo() | |
214 { | |
52 | 215 return next->isTypeBasic() != NULL; |
1 | 216 } |
217 | |
218 /* ========================================================================= */ | |
219 | |
220 /*************************************** | |
221 * Create a static array of TypeInfo references | |
222 * corresponding to an array of Expression's. | |
223 * Used to supply hidden _arguments[] value for variadic D functions. | |
224 */ | |
225 | |
57
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
54
diff
changeset
|
226 Expression *createTypeInfoArray(Scope *sc, Expression *exps[], int dim) |
1 | 227 { |
228 assert(0); | |
57
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
54
diff
changeset
|
229 return NULL; |
1 | 230 } |
231 | |
52 | 232 /* ========================================================================= */ |
233 | |
234 ////////////////////////////////////////////////////////////////////////////// | |
235 // MAGIC PLACE | |
236 ////////////////////////////////////////////////////////////////////////////// | |
237 | |
238 void TypeInfoDeclaration::toObjFile() | |
239 { | |
57
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
54
diff
changeset
|
240 if (llvmTouched) return; |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
54
diff
changeset
|
241 else llvmTouched = true; |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
54
diff
changeset
|
242 |
52 | 243 Logger::println("TypeInfoDeclaration::toObjFile()"); |
244 LOG_SCOPE; | |
245 Logger::println("type = '%s'", tinfo->toChars()); | |
246 | |
54
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
247 Logger::println("typeinfo mangle: %s", mangle()); |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
248 |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
249 if (tinfo->builtinTypeInfo()) { |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
250 // this is a declaration of a builtin __initZ var |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
251 llvmValue = LLVM_D_GetRuntimeGlobal(gIR->module, mangle()); |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
252 assert(llvmValue); |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
253 Logger::cout() << "Got typeinfo var:" << '\n' << *llvmValue << '\n'; |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
254 } |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
255 else { |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
256 toDt(NULL); |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
257 // this is a specialized typeinfo |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
258 //std::vector<const llvm::Type*> stypes; |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
259 //stypes.push_back( |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
260 } |
52 | 261 } |
262 | |
263 /* ========================================================================= */ | |
264 | |
265 void TypeInfoDeclaration::toDt(dt_t **pdt) | |
266 { | |
267 assert(0 && "TypeInfoDeclaration"); | |
268 } | |
269 | |
270 void TypeInfoTypedefDeclaration::toDt(dt_t **pdt) | |
271 { | |
54
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
272 Logger::println("TypeInfoTypedefDeclaration::toDt() %s", toChars()); |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
273 LOG_SCOPE; |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
274 |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
275 ClassDeclaration* base = Type::typeinfotypedef; |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
276 base->toObjFile(); |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
277 |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
278 llvm::Constant* initZ = base->llvmInitZ; |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
279 assert(initZ); |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
280 const llvm::StructType* stype = llvm::cast<llvm::StructType>(initZ->getType()); |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
281 |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
282 std::vector<llvm::Constant*> sinits; |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
283 sinits.push_back(initZ->getOperand(0)); |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
284 |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
285 assert(tinfo->ty == Ttypedef); |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
286 TypeTypedef *tc = (TypeTypedef *)tinfo; |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
287 TypedefDeclaration *sd = tc->sym; |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
288 |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
289 // TypeInfo base |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
290 //const llvm::PointerType* basept = llvm::cast<llvm::PointerType>(initZ->getOperand(1)->getType()); |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
291 //sinits.push_back(llvm::ConstantPointerNull::get(basept)); |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
292 Logger::println("generating base typeinfo"); |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
293 //sd->basetype = sd->basetype->merge(); |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
294 sd->basetype->getTypeInfo(NULL); // generate vtinfo |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
295 assert(sd->basetype->vtinfo); |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
296 if (!sd->basetype->vtinfo->llvmValue) |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
297 sd->basetype->vtinfo->toObjFile(); |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
298 assert(llvm::isa<llvm::Constant>(sd->basetype->vtinfo->llvmValue)); |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
299 llvm::Constant* castbase = llvm::cast<llvm::Constant>(sd->basetype->vtinfo->llvmValue); |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
300 castbase = llvm::ConstantExpr::getBitCast(castbase, initZ->getOperand(1)->getType()); |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
301 sinits.push_back(castbase); |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
302 |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
303 // char[] name |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
304 char *name = sd->toPrettyChars(); |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
305 sinits.push_back(LLVM_DtoConstString(name)); |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
306 assert(sinits.back()->getType() == initZ->getOperand(2)->getType()); |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
307 |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
308 // void[] init |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
309 //const llvm::PointerType* initpt = llvm::PointerType::get(llvm::Type::Int8Ty); |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
310 //sinits.push_back(LLVM_DtoConstantSlice(LLVM_DtoConstSize_t(0), llvm::ConstantPointerNull::get(initpt))); |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
311 sinits.push_back(initZ->getOperand(3)); |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
312 |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
313 // create the symbol |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
314 llvm::Constant* tiInit = llvm::ConstantStruct::get(stype, sinits); |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
315 llvm::GlobalVariable* gvar = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::InternalLinkage,tiInit,toChars(),gIR->module); |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
316 |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
317 llvmValue = gvar; |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
318 |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
319 /* |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
320 dtxoff(pdt, Type::typeinfotypedef->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Typedef |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
321 dtdword(pdt, 0); // monitor |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
322 |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
323 assert(tinfo->ty == Ttypedef); |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
324 |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
325 TypeTypedef *tc = (TypeTypedef *)tinfo; |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
326 TypedefDeclaration *sd = tc->sym; |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
327 //printf("basetype = %s\n", sd->basetype->toChars()); |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
328 |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
329 // Put out: |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
330 // TypeInfo base; |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
331 // char[] name; |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
332 // void[] m_init; |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
333 |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
334 sd->basetype = sd->basetype->merge(); |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
335 sd->basetype->getTypeInfo(NULL); // generate vtinfo |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
336 assert(sd->basetype->vtinfo); |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
337 dtxoff(pdt, sd->basetype->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for basetype |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
338 |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
339 char *name = sd->toPrettyChars(); |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
340 size_t namelen = strlen(name); |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
341 dtdword(pdt, namelen); |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
342 dtabytes(pdt, TYnptr, 0, namelen + 1, name); |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
343 |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
344 // void[] init; |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
345 if (tinfo->isZeroInit() || !sd->init) |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
346 { // 0 initializer, or the same as the base type |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
347 dtdword(pdt, 0); // init.length |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
348 dtdword(pdt, 0); // init.ptr |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
349 } |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
350 else |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
351 { |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
352 dtdword(pdt, sd->type->size()); // init.length |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
353 dtxoff(pdt, sd->toInitializer(), 0, TYnptr); // init.ptr |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
52
diff
changeset
|
354 */ |
52 | 355 } |
356 | |
357 void TypeInfoEnumDeclaration::toDt(dt_t **pdt) | |
358 { | |
359 assert(0 && "TypeInfoEnumDeclaration"); | |
360 } | |
361 | |
362 void TypeInfoPointerDeclaration::toDt(dt_t **pdt) | |
363 { | |
364 assert(0 && "TypeInfoPointerDeclaration"); | |
365 } | |
366 | |
367 void TypeInfoArrayDeclaration::toDt(dt_t **pdt) | |
368 { | |
369 assert(0 && "TypeInfoArrayDeclaration"); | |
370 } | |
371 | |
372 void TypeInfoStaticArrayDeclaration::toDt(dt_t **pdt) | |
373 { | |
374 assert(0 && "TypeInfoStaticArrayDeclaration"); | |
375 } | |
376 | |
377 void TypeInfoAssociativeArrayDeclaration::toDt(dt_t **pdt) | |
378 { | |
379 assert(0 && "TypeInfoAssociativeArrayDeclaration"); | |
380 } | |
381 | |
382 void TypeInfoFunctionDeclaration::toDt(dt_t **pdt) | |
383 { | |
384 assert(0 && "TypeInfoFunctionDeclaration"); | |
385 } | |
386 | |
387 void TypeInfoDelegateDeclaration::toDt(dt_t **pdt) | |
388 { | |
389 assert(0 && "TypeInfoDelegateDeclaration"); | |
390 } | |
391 | |
392 void TypeInfoStructDeclaration::toDt(dt_t **pdt) | |
393 { | |
394 assert(0 && "TypeInfoStructDeclaration"); | |
395 } | |
396 | |
397 void TypeInfoClassDeclaration::toDt(dt_t **pdt) | |
398 { | |
399 assert(0 && "TypeInfoClassDeclaration"); | |
400 } | |
401 | |
402 void TypeInfoInterfaceDeclaration::toDt(dt_t **pdt) | |
403 { | |
404 assert(0 && "TypeInfoInterfaceDeclaration"); | |
405 } | |
406 | |
407 void TypeInfoTupleDeclaration::toDt(dt_t **pdt) | |
408 { | |
409 assert(0 && "TypeInfoTupleDeclaration"); | |
410 } | |
411 | |
412 // original dmdfe toDt code for reference | |
413 | |
414 #if 0 | |
415 | |
416 void TypeInfoDeclaration::toDt(dt_t **pdt) | |
417 { | |
418 //printf("TypeInfoDeclaration::toDt() %s\n", toChars()); | |
419 dtxoff(pdt, Type::typeinfo->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo | |
420 dtdword(pdt, 0); // monitor | |
421 } | |
422 | |
423 void TypeInfoTypedefDeclaration::toDt(dt_t **pdt) | |
424 { | |
425 //printf("TypeInfoTypedefDeclaration::toDt() %s\n", toChars()); | |
426 | |
427 dtxoff(pdt, Type::typeinfotypedef->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Typedef | |
428 dtdword(pdt, 0); // monitor | |
429 | |
430 assert(tinfo->ty == Ttypedef); | |
431 | |
432 TypeTypedef *tc = (TypeTypedef *)tinfo; | |
433 TypedefDeclaration *sd = tc->sym; | |
434 //printf("basetype = %s\n", sd->basetype->toChars()); | |
435 | |
436 /* Put out: | |
437 * TypeInfo base; | |
438 * char[] name; | |
439 * void[] m_init; | |
440 */ | |
441 | |
442 sd->basetype = sd->basetype->merge(); | |
443 sd->basetype->getTypeInfo(NULL); // generate vtinfo | |
444 assert(sd->basetype->vtinfo); | |
445 dtxoff(pdt, sd->basetype->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for basetype | |
446 | |
447 char *name = sd->toPrettyChars(); | |
448 size_t namelen = strlen(name); | |
449 dtdword(pdt, namelen); | |
450 dtabytes(pdt, TYnptr, 0, namelen + 1, name); | |
451 | |
452 // void[] init; | |
453 if (tinfo->isZeroInit() || !sd->init) | |
454 { // 0 initializer, or the same as the base type | |
455 dtdword(pdt, 0); // init.length | |
456 dtdword(pdt, 0); // init.ptr | |
457 } | |
458 else | |
459 { | |
460 dtdword(pdt, sd->type->size()); // init.length | |
461 dtxoff(pdt, sd->toInitializer(), 0, TYnptr); // init.ptr | |
462 } | |
463 } | |
464 | |
465 void TypeInfoEnumDeclaration::toDt(dt_t **pdt) | |
466 { | |
467 //printf("TypeInfoEnumDeclaration::toDt()\n"); | |
468 dtxoff(pdt, Type::typeinfoenum->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Enum | |
469 dtdword(pdt, 0); // monitor | |
470 | |
471 assert(tinfo->ty == Tenum); | |
472 | |
473 TypeEnum *tc = (TypeEnum *)tinfo; | |
474 EnumDeclaration *sd = tc->sym; | |
475 | |
476 /* Put out: | |
477 * TypeInfo base; | |
478 * char[] name; | |
479 * void[] m_init; | |
480 */ | |
481 | |
482 sd->memtype->getTypeInfo(NULL); | |
483 dtxoff(pdt, sd->memtype->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for enum members | |
484 | |
485 char *name = sd->toPrettyChars(); | |
486 size_t namelen = strlen(name); | |
487 dtdword(pdt, namelen); | |
488 dtabytes(pdt, TYnptr, 0, namelen + 1, name); | |
489 | |
490 // void[] init; | |
491 if (tinfo->isZeroInit() || !sd->defaultval) | |
492 { // 0 initializer, or the same as the base type | |
493 dtdword(pdt, 0); // init.length | |
494 dtdword(pdt, 0); // init.ptr | |
495 } | |
496 else | |
497 { | |
498 dtdword(pdt, sd->type->size()); // init.length | |
499 dtxoff(pdt, sd->toInitializer(), 0, TYnptr); // init.ptr | |
500 } | |
501 } | |
502 | |
503 void TypeInfoPointerDeclaration::toDt(dt_t **pdt) | |
504 { | |
505 //printf("TypeInfoPointerDeclaration::toDt()\n"); | |
506 dtxoff(pdt, Type::typeinfopointer->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Pointer | |
507 dtdword(pdt, 0); // monitor | |
508 | |
509 assert(tinfo->ty == Tpointer); | |
510 | |
511 TypePointer *tc = (TypePointer *)tinfo; | |
512 | |
513 tc->next->getTypeInfo(NULL); | |
514 dtxoff(pdt, tc->next->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for type being pointed to | |
515 } | |
516 | |
517 void TypeInfoArrayDeclaration::toDt(dt_t **pdt) | |
518 { | |
519 //printf("TypeInfoArrayDeclaration::toDt()\n"); | |
520 dtxoff(pdt, Type::typeinfoarray->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Array | |
521 dtdword(pdt, 0); // monitor | |
522 | |
523 assert(tinfo->ty == Tarray); | |
524 | |
525 TypeDArray *tc = (TypeDArray *)tinfo; | |
526 | |
527 tc->next->getTypeInfo(NULL); | |
528 dtxoff(pdt, tc->next->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for array of type | |
529 } | |
530 | |
531 void TypeInfoStaticArrayDeclaration::toDt(dt_t **pdt) | |
532 { | |
533 //printf("TypeInfoStaticArrayDeclaration::toDt()\n"); | |
534 dtxoff(pdt, Type::typeinfostaticarray->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_StaticArray | |
535 dtdword(pdt, 0); // monitor | |
536 | |
537 assert(tinfo->ty == Tsarray); | |
538 | |
539 TypeSArray *tc = (TypeSArray *)tinfo; | |
540 | |
541 tc->next->getTypeInfo(NULL); | |
542 dtxoff(pdt, tc->next->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for array of type | |
543 | |
544 dtdword(pdt, tc->dim->toInteger()); // length | |
545 } | |
546 | |
547 void TypeInfoAssociativeArrayDeclaration::toDt(dt_t **pdt) | |
548 { | |
549 //printf("TypeInfoAssociativeArrayDeclaration::toDt()\n"); | |
550 dtxoff(pdt, Type::typeinfoassociativearray->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_AssociativeArray | |
551 dtdword(pdt, 0); // monitor | |
552 | |
553 assert(tinfo->ty == Taarray); | |
554 | |
555 TypeAArray *tc = (TypeAArray *)tinfo; | |
556 | |
557 tc->next->getTypeInfo(NULL); | |
558 dtxoff(pdt, tc->next->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for array of type | |
559 | |
560 tc->index->getTypeInfo(NULL); | |
561 dtxoff(pdt, tc->index->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for array of type | |
562 } | |
563 | |
564 void TypeInfoFunctionDeclaration::toDt(dt_t **pdt) | |
565 { | |
566 //printf("TypeInfoFunctionDeclaration::toDt()\n"); | |
567 dtxoff(pdt, Type::typeinfofunction->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Function | |
568 dtdword(pdt, 0); // monitor | |
569 | |
570 assert(tinfo->ty == Tfunction); | |
571 | |
572 TypeFunction *tc = (TypeFunction *)tinfo; | |
573 | |
574 tc->next->getTypeInfo(NULL); | |
575 dtxoff(pdt, tc->next->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for function return value | |
576 } | |
577 | |
578 void TypeInfoDelegateDeclaration::toDt(dt_t **pdt) | |
579 { | |
580 //printf("TypeInfoDelegateDeclaration::toDt()\n"); | |
581 dtxoff(pdt, Type::typeinfodelegate->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Delegate | |
582 dtdword(pdt, 0); // monitor | |
583 | |
584 assert(tinfo->ty == Tdelegate); | |
585 | |
586 TypeDelegate *tc = (TypeDelegate *)tinfo; | |
587 | |
588 tc->next->next->getTypeInfo(NULL); | |
589 dtxoff(pdt, tc->next->next->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for delegate return value | |
590 } | |
591 | |
592 void TypeInfoStructDeclaration::toDt(dt_t **pdt) | |
593 { | |
594 //printf("TypeInfoStructDeclaration::toDt() '%s'\n", toChars()); | |
595 | |
596 unsigned offset = Type::typeinfostruct->structsize; | |
597 | |
598 dtxoff(pdt, Type::typeinfostruct->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Struct | |
599 dtdword(pdt, 0); // monitor | |
600 | |
601 assert(tinfo->ty == Tstruct); | |
602 | |
603 TypeStruct *tc = (TypeStruct *)tinfo; | |
604 StructDeclaration *sd = tc->sym; | |
605 | |
606 /* Put out: | |
607 * char[] name; | |
608 * void[] init; | |
609 * hash_t function(void*) xtoHash; | |
610 * int function(void*,void*) xopEquals; | |
611 * int function(void*,void*) xopCmp; | |
612 * char[] function(void*) xtoString; | |
613 * uint m_flags; | |
614 * | |
615 * name[] | |
616 */ | |
617 | |
618 char *name = sd->toPrettyChars(); | |
619 size_t namelen = strlen(name); | |
620 dtdword(pdt, namelen); | |
621 //dtabytes(pdt, TYnptr, 0, namelen + 1, name); | |
622 dtxoff(pdt, toSymbol(), offset, TYnptr); | |
623 offset += namelen + 1; | |
624 | |
625 // void[] init; | |
626 dtdword(pdt, sd->structsize); // init.length | |
627 if (sd->zeroInit) | |
628 dtdword(pdt, 0); // NULL for 0 initialization | |
629 else | |
630 dtxoff(pdt, sd->toInitializer(), 0, TYnptr); // init.ptr | |
631 | |
632 FuncDeclaration *fd; | |
633 FuncDeclaration *fdx; | |
634 TypeFunction *tf; | |
635 Type *ta; | |
636 Dsymbol *s; | |
637 | |
638 static TypeFunction *tftohash; | |
639 static TypeFunction *tftostring; | |
640 | |
641 if (!tftohash) | |
642 { | |
643 Scope sc; | |
644 | |
645 tftohash = new TypeFunction(NULL, Type::thash_t, 0, LINKd); | |
646 tftohash = (TypeFunction *)tftohash->semantic(0, &sc); | |
647 | |
648 tftostring = new TypeFunction(NULL, Type::tchar->arrayOf(), 0, LINKd); | |
649 tftostring = (TypeFunction *)tftostring->semantic(0, &sc); | |
650 } | |
651 | |
652 TypeFunction *tfeqptr; | |
653 { | |
654 Scope sc; | |
655 Arguments *arguments = new Arguments; | |
656 Argument *arg = new Argument(STCin, tc->pointerTo(), NULL, NULL); | |
657 | |
658 arguments->push(arg); | |
659 tfeqptr = new TypeFunction(arguments, Type::tint32, 0, LINKd); | |
660 tfeqptr = (TypeFunction *)tfeqptr->semantic(0, &sc); | |
661 } | |
662 | |
663 #if 0 | |
664 TypeFunction *tfeq; | |
665 { | |
666 Scope sc; | |
667 Array *arguments = new Array; | |
668 Argument *arg = new Argument(In, tc, NULL, NULL); | |
669 | |
670 arguments->push(arg); | |
671 tfeq = new TypeFunction(arguments, Type::tint32, 0, LINKd); | |
672 tfeq = (TypeFunction *)tfeq->semantic(0, &sc); | |
673 } | |
674 #endif | |
675 | |
676 s = search_function(sd, Id::tohash); | |
677 fdx = s ? s->isFuncDeclaration() : NULL; | |
678 if (fdx) | |
679 { fd = fdx->overloadExactMatch(tftohash); | |
680 if (fd) | |
681 dtxoff(pdt, fd->toSymbol(), 0, TYnptr); | |
682 else | |
683 //fdx->error("must be declared as extern (D) uint toHash()"); | |
684 dtdword(pdt, 0); | |
685 } | |
686 else | |
687 dtdword(pdt, 0); | |
688 | |
689 s = search_function(sd, Id::eq); | |
690 fdx = s ? s->isFuncDeclaration() : NULL; | |
691 for (int i = 0; i < 2; i++) | |
692 { | |
693 if (fdx) | |
694 { fd = fdx->overloadExactMatch(tfeqptr); | |
695 if (fd) | |
696 dtxoff(pdt, fd->toSymbol(), 0, TYnptr); | |
697 else | |
698 //fdx->error("must be declared as extern (D) int %s(%s*)", fdx->toChars(), sd->toChars()); | |
699 dtdword(pdt, 0); | |
700 } | |
701 else | |
702 dtdword(pdt, 0); | |
703 | |
704 s = search_function(sd, Id::cmp); | |
705 fdx = s ? s->isFuncDeclaration() : NULL; | |
706 } | |
707 | |
708 s = search_function(sd, Id::tostring); | |
709 fdx = s ? s->isFuncDeclaration() : NULL; | |
710 if (fdx) | |
711 { fd = fdx->overloadExactMatch(tftostring); | |
712 if (fd) | |
713 dtxoff(pdt, fd->toSymbol(), 0, TYnptr); | |
714 else | |
715 //fdx->error("must be declared as extern (D) char[] toString()"); | |
716 dtdword(pdt, 0); | |
717 } | |
718 else | |
719 dtdword(pdt, 0); | |
720 | |
721 // uint m_flags; | |
722 dtdword(pdt, tc->hasPointers()); | |
723 | |
724 // name[] | |
725 dtnbytes(pdt, namelen + 1, name); | |
726 } | |
727 | |
728 void TypeInfoClassDeclaration::toDt(dt_t **pdt) | |
729 { | |
730 //printf("TypeInfoClassDeclaration::toDt() %s\n", tinfo->toChars()); | |
731 dtxoff(pdt, Type::typeinfoclass->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfoClass | |
732 dtdword(pdt, 0); // monitor | |
733 | |
734 assert(tinfo->ty == Tclass); | |
735 | |
736 TypeClass *tc = (TypeClass *)tinfo; | |
737 Symbol *s; | |
738 | |
739 if (!tc->sym->vclassinfo) | |
740 tc->sym->vclassinfo = new ClassInfoDeclaration(tc->sym); | |
741 s = tc->sym->vclassinfo->toSymbol(); | |
742 dtxoff(pdt, s, 0, TYnptr); // ClassInfo for tinfo | |
743 } | |
744 | |
745 void TypeInfoInterfaceDeclaration::toDt(dt_t **pdt) | |
746 { | |
747 //printf("TypeInfoInterfaceDeclaration::toDt() %s\n", tinfo->toChars()); | |
748 dtxoff(pdt, Type::typeinfointerface->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfoInterface | |
749 dtdword(pdt, 0); // monitor | |
750 | |
751 assert(tinfo->ty == Tclass); | |
752 | |
753 TypeClass *tc = (TypeClass *)tinfo; | |
754 Symbol *s; | |
755 | |
756 if (!tc->sym->vclassinfo) | |
757 tc->sym->vclassinfo = new ClassInfoDeclaration(tc->sym); | |
758 s = tc->sym->vclassinfo->toSymbol(); | |
759 dtxoff(pdt, s, 0, TYnptr); // ClassInfo for tinfo | |
760 } | |
761 | |
762 void TypeInfoTupleDeclaration::toDt(dt_t **pdt) | |
763 { | |
764 //printf("TypeInfoTupleDeclaration::toDt() %s\n", tinfo->toChars()); | |
765 dtxoff(pdt, Type::typeinfotypelist->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfoInterface | |
766 dtdword(pdt, 0); // monitor | |
767 | |
768 assert(tinfo->ty == Ttuple); | |
769 | |
770 TypeTuple *tu = (TypeTuple *)tinfo; | |
771 | |
772 size_t dim = tu->arguments->dim; | |
773 dtdword(pdt, dim); // elements.length | |
774 | |
775 dt_t *d = NULL; | |
776 for (size_t i = 0; i < dim; i++) | |
777 { Argument *arg = (Argument *)tu->arguments->data[i]; | |
778 Expression *e = arg->type->getTypeInfo(NULL); | |
779 e = e->optimize(WANTvalue); | |
780 e->toDt(&d); | |
781 } | |
782 | |
783 Symbol *s; | |
784 s = static_sym(); | |
785 s->Sdt = d; | |
786 outdata(s); | |
787 | |
788 dtxoff(pdt, s, 0, TYnptr); // elements.ptr | |
789 } | |
790 | |
791 void TypeInfoDeclaration::toObjFile() | |
792 { | |
793 Symbol *s; | |
794 unsigned sz; | |
795 Dsymbol *parent; | |
796 | |
797 //printf("TypeInfoDeclaration::toObjFile(%p '%s') protection %d\n", this, toChars(), protection); | |
798 | |
799 s = toSymbol(); | |
800 sz = type->size(); | |
801 | |
802 parent = this->toParent(); | |
803 s->Sclass = SCcomdat; | |
804 s->Sfl = FLdata; | |
805 | |
806 toDt(&s->Sdt); | |
807 | |
808 dt_optimize(s->Sdt); | |
809 | |
810 // See if we can convert a comdat to a comdef, | |
811 // which saves on exe file space. | |
812 if (s->Sclass == SCcomdat && | |
813 s->Sdt->dt == DT_azeros && | |
814 s->Sdt->DTnext == NULL) | |
815 { | |
816 s->Sclass = SCglobal; | |
817 s->Sdt->dt = DT_common; | |
818 } | |
819 | |
820 #if ELFOBJ // Burton | |
821 if (s->Sdt && s->Sdt->dt == DT_azeros && s->Sdt->DTnext == NULL) | |
822 s->Sseg = UDATA; | |
823 else | |
824 s->Sseg = DATA; | |
825 #endif /* ELFOBJ */ | |
826 outdata(s); | |
827 if (isExport()) | |
828 obj_export(s,0); | |
829 } | |
830 | |
831 #endif |