Mercurial > projects > ldc
annotate gen/typinf.c @ 54:28e99b04a132 trunk
[svn r58] Fixed cond expression resulting in a non-basic type.
Fixed identity expression for dynamic arrays.
Revamped the system to keep track of lvalues and rvalues and their relations.
Typedef declaration now generate the custom typeinfo.
Other bugfixes.
author | lindquist |
---|---|
date | Wed, 24 Oct 2007 01:37:34 +0200 |
parents | 0c77619e803b |
children | a9d29e9f1fed |
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 | |
226 Expression *createTypeInfoArray(Scope *sc, Expression *args[], int dim) | |
227 { | |
228 assert(0); | |
229 return 0; | |
230 } | |
231 | |
52 | 232 /* ========================================================================= */ |
233 | |
234 ////////////////////////////////////////////////////////////////////////////// | |
235 // MAGIC PLACE | |
236 ////////////////////////////////////////////////////////////////////////////// | |
237 | |
238 void TypeInfoDeclaration::toObjFile() | |
239 { | |
240 Logger::println("TypeInfoDeclaration::toObjFile()"); | |
241 LOG_SCOPE; | |
242 Logger::println("type = '%s'", tinfo->toChars()); | |
243 | |
244 if (llvmTouched) return; | |
245 else llvmTouched = true; | |
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 |