Mercurial > projects > ddmd
comparison dmd/Dsymbol.d @ 0:10317f0c89a5
Initial commit
author | korDen |
---|---|
date | Sat, 24 Oct 2009 08:42:06 +0400 |
parents | |
children | 427f8aa74d28 2cc604139636 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:10317f0c89a5 |
---|---|
1 module dmd.Dsymbol; | |
2 | |
3 import dmd.Loc; | |
4 import dmd.STC; | |
5 import dmd.Scope; | |
6 import dmd.Lexer; | |
7 import dmd.Module; | |
8 import dmd.Array; | |
9 import dmd.ScopeDsymbol; | |
10 import dmd.OutBuffer; | |
11 import dmd.Id; | |
12 import dmd.Identifier; | |
13 import dmd.TemplateInstance; | |
14 import dmd.HdrGenState; | |
15 import dmd.AggregateDeclaration; | |
16 import dmd.ClassDeclaration; | |
17 import dmd.LabelDsymbol; | |
18 import dmd.Type; | |
19 import dmd.PROT; | |
20 import dmd.ArrayTypes; | |
21 import dmd.Package; | |
22 import dmd.EnumMember; | |
23 import dmd.TemplateDeclaration; | |
24 import dmd.TemplateMixin; | |
25 import dmd.Declaration; | |
26 import dmd.ThisDeclaration; | |
27 import dmd.TupleDeclaration; | |
28 import dmd.TypedefDeclaration; | |
29 import dmd.AliasDeclaration; | |
30 import dmd.FuncDeclaration; | |
31 import dmd.FuncAliasDeclaration; | |
32 import dmd.FuncLiteralDeclaration; | |
33 import dmd.CtorDeclaration; | |
34 import dmd.PostBlitDeclaration; | |
35 import dmd.DtorDeclaration; | |
36 import dmd.StaticCtorDeclaration; | |
37 import dmd.StaticDtorDeclaration; | |
38 import dmd.InvariantDeclaration; | |
39 import dmd.UnitTestDeclaration; | |
40 import dmd.NewDeclaration; | |
41 import dmd.VarDeclaration; | |
42 import dmd.StructDeclaration; | |
43 import dmd.UnionDeclaration; | |
44 import dmd.InterfaceDeclaration; | |
45 import dmd.WithScopeSymbol; | |
46 import dmd.ArrayScopeSymbol; | |
47 import dmd.Import; | |
48 import dmd.EnumDeclaration; | |
49 import dmd.DeleteDeclaration; | |
50 import dmd.SymbolDeclaration; | |
51 import dmd.AttribDeclaration; | |
52 import dmd.OverloadSet; | |
53 import dmd.DYNCAST; | |
54 import dmd.Global; | |
55 import dmd.Expression; | |
56 import dmd.TOK; | |
57 import dmd.VarExp; | |
58 import dmd.FuncExp; | |
59 | |
60 import dmd.backend.Symbol; | |
61 import dmd.backend.TYPE; | |
62 import dmd.backend.Util; | |
63 import dmd.backend.mTYman; | |
64 import dmd.backend.TYFL; | |
65 import dmd.backend.TYM; | |
66 import dmd.backend.mTY; | |
67 import dmd.backend.SC; | |
68 import dmd.backend.FL; | |
69 import dmd.backend.LIST; | |
70 | |
71 import core.stdc.string : strcmp, memcpy, strlen; | |
72 import core.stdc.stdlib : alloca; | |
73 | |
74 import std.stdio; | |
75 | |
76 // TODO: remove dependencies on these | |
77 Expression isExpression(Object o) | |
78 { | |
79 return cast(Expression)o; | |
80 } | |
81 | |
82 Dsymbol isDsymbol(Object o) | |
83 { | |
84 return cast(Dsymbol)o; | |
85 } | |
86 | |
87 Type isType(Object o) | |
88 { | |
89 return cast(Type)o; | |
90 } | |
91 | |
92 Dsymbol getDsymbol(Object oarg) | |
93 { | |
94 Dsymbol sa; | |
95 Expression ea = isExpression(oarg); | |
96 if (ea) | |
97 { // Try to convert Expression to symbol | |
98 if (ea.op == TOK.TOKvar) | |
99 sa = (cast(VarExp)ea).var; | |
100 else if (ea.op == TOK.TOKfunction) | |
101 sa = (cast(FuncExp)ea).fd; | |
102 else | |
103 sa = null; | |
104 } | |
105 else | |
106 { // Try to convert Type to symbol | |
107 Type ta = isType(oarg); | |
108 if (ta) | |
109 sa = ta.toDsymbol(null); | |
110 else | |
111 sa = isDsymbol(oarg); // if already a symbol | |
112 } | |
113 return sa; | |
114 } | |
115 | |
116 class Dsymbol | |
117 { | |
118 Identifier ident; | |
119 Identifier c_ident; | |
120 Dsymbol parent; | |
121 Symbol* csym; // symbol for code generator | |
122 Symbol* isym; // import version of csym | |
123 ubyte* comment; // documentation comment for this Dsymbol | |
124 Loc loc; // where defined | |
125 Scope scope_; // !=null means context to use for semantic() | |
126 | |
127 this() | |
128 { | |
129 // do nothing | |
130 } | |
131 | |
132 this(Identifier ident) | |
133 { | |
134 this.ident = ident; | |
135 } | |
136 | |
137 string toChars() | |
138 { | |
139 return ident ? ident.toChars() : "__anonymous"; | |
140 } | |
141 | |
142 string locToChars() | |
143 { | |
144 scope OutBuffer buf = new OutBuffer(); | |
145 Module m = getModule(); | |
146 | |
147 if (m && m.srcfile) | |
148 loc.filename = m.srcfile.toChars(); | |
149 | |
150 return loc.toChars(); | |
151 } | |
152 | |
153 int equals(Object o) | |
154 { | |
155 assert(false); | |
156 } | |
157 | |
158 bool isAnonymous() | |
159 { | |
160 return ident ? 0 : 1; | |
161 } | |
162 | |
163 void error(T...)(Loc loc, string format, T t) | |
164 { | |
165 if (!global.gag) | |
166 { | |
167 string p = loc.toChars(); | |
168 if (p.length == 0) | |
169 p = locToChars(); | |
170 | |
171 if (p.length != 0) { | |
172 writef("%s: ", p); | |
173 } | |
174 | |
175 write("Error: "); | |
176 writef("%s %s ", kind(), toPrettyChars()); | |
177 | |
178 writefln(format, t); | |
179 } | |
180 | |
181 global.errors++; | |
182 | |
183 //fatal(); | |
184 } | |
185 | |
186 void error(T...)(string format, T t) | |
187 { | |
188 //printf("Dsymbol.error()\n"); | |
189 if (!global.gag) | |
190 { | |
191 string p = loc.toChars(); | |
192 | |
193 if (p.length != 0) { | |
194 writef("%s: ", p); | |
195 } | |
196 | |
197 write("Error: "); | |
198 if (isAnonymous()) { | |
199 writef("%s ", kind()); | |
200 } else { | |
201 writef("%s %s ", kind(), toPrettyChars()); | |
202 } | |
203 | |
204 writefln(format, t); | |
205 } | |
206 global.errors++; | |
207 | |
208 //fatal(); | |
209 } | |
210 | |
211 void checkDeprecated(Loc loc, Scope sc) | |
212 { | |
213 if (!global.params.useDeprecated && isDeprecated()) | |
214 { | |
215 // Don't complain if we're inside a deprecated symbol's scope | |
216 for (Dsymbol sp = sc.parent; sp; sp = sp.parent) | |
217 { | |
218 if (sp.isDeprecated()) | |
219 return; | |
220 } | |
221 | |
222 for (; sc; sc = sc.enclosing) | |
223 { | |
224 if (sc.scopesym && sc.scopesym.isDeprecated()) | |
225 return; | |
226 | |
227 // If inside a StorageClassDeclaration that is deprecated | |
228 if (sc.stc & STC.STCdeprecated) | |
229 return; | |
230 } | |
231 | |
232 error(loc, "is deprecated"); | |
233 } | |
234 } | |
235 | |
236 Module getModule() | |
237 { | |
238 //printf("Dsymbol.getModule()\n"); | |
239 Dsymbol s = this; | |
240 while (s) | |
241 { | |
242 //printf("\ts = '%s'\n", s.toChars()); | |
243 Module m = s.isModule(); | |
244 if (m) | |
245 return m; | |
246 s = s.parent; | |
247 } | |
248 | |
249 return null; | |
250 } | |
251 | |
252 Dsymbol pastMixin() | |
253 { | |
254 Dsymbol s = this; | |
255 //printf("Dsymbol::pastMixin() %s\n", toChars()); | |
256 while (s && s.isTemplateMixin()) | |
257 s = s.parent; | |
258 return s; | |
259 } | |
260 | |
261 Dsymbol toParent() | |
262 { | |
263 return parent ? parent.pastMixin() : null; | |
264 } | |
265 | |
266 /********************************** | |
267 * Use this instead of toParent() when looking for the | |
268 * 'this' pointer of the enclosing function/class. | |
269 */ | |
270 Dsymbol toParent2() | |
271 { | |
272 Dsymbol s = parent; | |
273 while (s && s.isTemplateInstance()) | |
274 s = s.parent; | |
275 return s; | |
276 } | |
277 | |
278 TemplateInstance inTemplateInstance() | |
279 { | |
280 for (Dsymbol parent = this.parent; parent; parent = parent.parent) | |
281 { | |
282 TemplateInstance ti = parent.isTemplateInstance(); | |
283 if (ti) | |
284 return ti; | |
285 } | |
286 | |
287 return null; | |
288 } | |
289 | |
290 DYNCAST dyncast() { return DYNCAST.DYNCAST_DSYMBOL; } // kludge for template.isSymbol() | |
291 | |
292 /************************************* | |
293 * Do syntax copy of an array of Dsymbol's. | |
294 */ | |
295 static Array arraySyntaxCopy(Array a) | |
296 { | |
297 Array b = null; | |
298 if (a) | |
299 { | |
300 b = a.copy(); | |
301 for (int i = 0; i < b.dim; i++) | |
302 { | |
303 Dsymbol s = cast(Dsymbol)b.data[i]; | |
304 | |
305 s = s.syntaxCopy(null); | |
306 b.data[i] = cast(void*)s; | |
307 } | |
308 } | |
309 return b; | |
310 } | |
311 | |
312 string toPrettyChars() | |
313 { | |
314 //printf("Dsymbol.toPrettyChars() '%s'\n", toChars()); | |
315 if (!parent) { | |
316 return toChars(); | |
317 } | |
318 | |
319 size_t len = 0; | |
320 for (Dsymbol p = this; p; p = p.parent) { | |
321 len += p.toChars().length + 1; | |
322 } | |
323 --len; | |
324 | |
325 char* s = cast(char*)alloca(len); | |
326 char* q = s + len; | |
327 | |
328 for (Dsymbol p = this; p; p = p.parent) | |
329 { | |
330 string t = p.toChars(); | |
331 size_t length = t.length; | |
332 q -= length; | |
333 | |
334 memcpy(q, t.ptr, length); | |
335 if (q is s) | |
336 break; | |
337 | |
338 q--; | |
339 version (TARGET_NET) { | |
340 if (AggregateDeclaration ad = p.isAggregateDeclaration()) | |
341 { | |
342 if (ad.isNested() && p.parent && p.parent.isAggregateDeclaration()) | |
343 { | |
344 *q = '/'; | |
345 continue; | |
346 } | |
347 } | |
348 } | |
349 *q = '.'; | |
350 } | |
351 | |
352 return s[0..len].idup; | |
353 } | |
354 | |
355 string kind() | |
356 { | |
357 assert(false); | |
358 } | |
359 | |
360 /********************************* | |
361 * If this symbol is really an alias for another, | |
362 * return that other. | |
363 */ | |
364 Dsymbol toAlias() // resolve real symbol | |
365 { | |
366 return this; | |
367 } | |
368 | |
369 bool addMember(Scope sc, ScopeDsymbol sd, int memnum) | |
370 { | |
371 //printf("Dsymbol.addMember('%s')\n", toChars()); | |
372 //printf("Dsymbol.addMember(this = %p, '%s' scopesym = '%s')\n", this, toChars(), sd.toChars()); | |
373 assert(sd !is null); | |
374 parent = sd; | |
375 if (!isAnonymous()) // no name, so can't add it to symbol table | |
376 { | |
377 if (!sd.symtab.insert(this)) // if name is already defined | |
378 { | |
379 Dsymbol s2 = sd.symtab.lookup(ident); | |
380 if (!s2.overloadInsert(this)) | |
381 { | |
382 sd.multiplyDefined(Loc(0), this, s2); | |
383 } | |
384 } | |
385 if (sd.isAggregateDeclaration() || sd.isEnumDeclaration()) | |
386 { | |
387 if (ident is Id.__sizeof || ident is Id.alignof_ || ident is Id.mangleof_) | |
388 error(".%s property cannot be redefined", ident.toChars()); | |
389 } | |
390 return true; | |
391 } | |
392 | |
393 return false; | |
394 } | |
395 | |
396 void setScope(Scope sc) | |
397 { | |
398 //printf("Dsymbol.setScope() %p %s\n", this, toChars()); | |
399 if (!sc.nofree) | |
400 sc.setNoFree(); // may need it even after semantic() finishes | |
401 scope_ = sc; | |
402 } | |
403 | |
404 void semantic(Scope sc) | |
405 { | |
406 assert(false); | |
407 } | |
408 | |
409 /************************************* | |
410 * Does semantic analysis on initializers and members of aggregates. | |
411 */ | |
412 void semantic2(Scope sc) | |
413 { | |
414 // Most Dsymbols have no further semantic analysis needed | |
415 } | |
416 | |
417 /************************************* | |
418 * Does semantic analysis on function bodies. | |
419 */ | |
420 void semantic3(Scope sc) | |
421 { | |
422 // Most Dsymbols have no further semantic analysis needed | |
423 } | |
424 | |
425 /************************************* | |
426 * Look for function inlining possibilities. | |
427 */ | |
428 void inlineScan() | |
429 { | |
430 // Most Dsymbols aren't functions | |
431 } | |
432 | |
433 Dsymbol search(Loc loc, Identifier ident, int flags) | |
434 { | |
435 assert(false); | |
436 } | |
437 | |
438 /*************************************** | |
439 * Search for identifier id as a member of 'this'. | |
440 * id may be a template instance. | |
441 * Returns: | |
442 * symbol found, null if not | |
443 */ | |
444 Dsymbol searchX(Loc loc, Scope sc, Identifier id) | |
445 { | |
446 //printf("Dsymbol::searchX(this=%p,%s, ident='%s')\n", this, toChars(), ident.toChars()); | |
447 Dsymbol s = toAlias(); | |
448 Dsymbol sm; | |
449 | |
450 /// HUH???? | |
451 switch (id.dyncast()) | |
452 { | |
453 case DYNCAST.DYNCAST_IDENTIFIER: | |
454 sm = s.search(loc, id, 0); | |
455 break; | |
456 | |
457 case DYNCAST.DYNCAST_DSYMBOL: | |
458 { | |
459 assert(false); /// how can it happen? | |
460 // It's a template instance | |
461 //printf("\ttemplate instance id\n"); | |
462 Dsymbol st = cast(Dsymbol)id; | |
463 TemplateInstance ti = st.isTemplateInstance(); | |
464 id = ti.name; | |
465 sm = s.search(loc, id, 0); | |
466 if (!sm) | |
467 { | |
468 error("template identifier %s is not a member of %s %s", id.toChars(), s.kind(), s.toChars()); | |
469 return null; | |
470 } | |
471 sm = sm.toAlias(); | |
472 TemplateDeclaration td = sm.isTemplateDeclaration(); | |
473 if (!td) | |
474 { | |
475 error("%s is not a template, it is a %s", id.toChars(), sm.kind()); | |
476 return null; | |
477 } | |
478 | |
479 ti.tempdecl = td; | |
480 if (!ti.semanticRun) | |
481 ti.semantic(sc); | |
482 | |
483 sm = ti.toAlias(); | |
484 break; | |
485 } | |
486 | |
487 default: | |
488 assert(0); | |
489 } | |
490 return sm; | |
491 } | |
492 | |
493 bool overloadInsert(Dsymbol s) | |
494 { | |
495 assert(false); | |
496 } | |
497 | |
498 version (_DH) { | |
499 char* toHChars() | |
500 { | |
501 assert(false); | |
502 } | |
503 | |
504 void toHBuffer(OutBuffer buf, HdrGenState* hgs) | |
505 { | |
506 assert(false); | |
507 } | |
508 } | |
509 void toCBuffer(OutBuffer buf, HdrGenState* hgs) | |
510 { | |
511 assert(false); | |
512 } | |
513 | |
514 void toDocBuffer(OutBuffer buf) | |
515 { | |
516 assert(false); | |
517 } | |
518 | |
519 uint size(Loc loc) | |
520 { | |
521 assert(false); | |
522 } | |
523 | |
524 int isforwardRef() | |
525 { | |
526 assert(false); | |
527 } | |
528 | |
529 void defineRef(Dsymbol s) | |
530 { | |
531 assert(false); | |
532 } | |
533 | |
534 AggregateDeclaration isThis() // is a 'this' required to access the member | |
535 { | |
536 assert(false); | |
537 } | |
538 | |
539 ClassDeclaration isClassMember() // are we a member of a class? | |
540 { | |
541 Dsymbol parent = toParent(); | |
542 if (parent && parent.isClassDeclaration()) | |
543 return cast(ClassDeclaration)parent; | |
544 return null; | |
545 } | |
546 | |
547 bool isExport() // is Dsymbol exported? | |
548 { | |
549 return false; | |
550 } | |
551 | |
552 bool isImportedSymbol() // is Dsymbol imported? | |
553 { | |
554 return false; | |
555 } | |
556 | |
557 bool isDeprecated() // is Dsymbol deprecated? | |
558 { | |
559 return false; | |
560 } | |
561 | |
562 version (DMDV2) { | |
563 bool isOverloadable() | |
564 { | |
565 return false; | |
566 } | |
567 } | |
568 | |
569 LabelDsymbol isLabel() // is this a LabelDsymbol? | |
570 { | |
571 return null; | |
572 } | |
573 | |
574 AggregateDeclaration isMember() // is this symbol a member of an AggregateDeclaration? | |
575 { | |
576 //printf("Dsymbol::isMember() %s\n", toChars()); | |
577 Dsymbol parent = toParent(); | |
578 //printf("parent is %s %s\n", parent.kind(), parent.toChars()); | |
579 return parent ? parent.isAggregateDeclaration() : null; | |
580 } | |
581 | |
582 Type getType() // is this a type? | |
583 { | |
584 return null; | |
585 } | |
586 | |
587 string mangle() | |
588 { | |
589 OutBuffer buf = new OutBuffer(); | |
590 string id; | |
591 | |
592 static if (false) { | |
593 printf("Dsymbol::mangle() '%s'", toChars()); | |
594 if (parent) | |
595 printf(" parent = %s %s", parent.kind(), parent.toChars()); | |
596 printf("\n"); | |
597 } | |
598 id = ident ? ident.toChars() : toChars(); | |
599 if (parent) | |
600 { | |
601 string p = parent.mangle(); | |
602 if (p[0] == '_' && p[1] == 'D') | |
603 p = p[2..$]; | |
604 buf.writestring(p); | |
605 } | |
606 ///buf.printf("%zu%s", id.length, id); | |
607 buf.printf("%d%s", id.length, id); | |
608 id = buf.toChars(); | |
609 buf.data = null; | |
610 //printf("Dsymbol::mangle() %s = %s\n", toChars(), id); | |
611 return id; | |
612 } | |
613 | |
614 bool needThis() // need a 'this' pointer? | |
615 { | |
616 return false; | |
617 } | |
618 | |
619 PROT prot() | |
620 { | |
621 assert(false); | |
622 } | |
623 | |
624 Dsymbol syntaxCopy(Dsymbol s) // copy only syntax trees | |
625 { | |
626 assert(false); | |
627 } | |
628 | |
629 /************************************** | |
630 * Determine if this symbol is only one. | |
631 * Returns: | |
632 * false, *ps = null: There are 2 or more symbols | |
633 * true, *ps = null: There are zero symbols | |
634 * true, *ps = symbol: The one and only one symbol | |
635 */ | |
636 bool oneMember(Dsymbol* ps) | |
637 { | |
638 //printf("Dsymbol::oneMember()\n"); | |
639 *ps = this; | |
640 return true; | |
641 } | |
642 | |
643 /***************************************** | |
644 * Same as Dsymbol::oneMember(), but look at an array of Dsymbols. | |
645 */ | |
646 static bool oneMembers(Array members, Dsymbol* ps) | |
647 { | |
648 //printf("Dsymbol::oneMembers() %d\n", members ? members->dim : 0); | |
649 Dsymbol s = null; | |
650 | |
651 if (members) | |
652 { | |
653 for (int i = 0; i < members.dim; i++) | |
654 { | |
655 Dsymbol sx = cast(Dsymbol)members.data[i]; | |
656 | |
657 bool x = sx.oneMember(ps); | |
658 //printf("\t[%d] kind %s = %d, s = %p\n", i, sx->kind(), x, *ps); | |
659 if (!x) | |
660 { | |
661 //printf("\tfalse 1\n"); | |
662 assert(*ps is null); | |
663 return false; | |
664 } | |
665 if (*ps) | |
666 { | |
667 if (s) // more than one symbol | |
668 { | |
669 *ps = null; | |
670 //printf("\tfalse 2\n"); | |
671 return false; | |
672 } | |
673 s = *ps; | |
674 } | |
675 } | |
676 } | |
677 | |
678 *ps = s; // s is the one symbol, null if none | |
679 //printf("\ttrue\n"); | |
680 return true; | |
681 } | |
682 | |
683 /***************************************** | |
684 * Is Dsymbol a variable that contains pointers? | |
685 */ | |
686 bool hasPointers() | |
687 { | |
688 //printf("Dsymbol::hasPointers() %s\n", toChars()); | |
689 return 0; | |
690 } | |
691 | |
692 void addLocalClass(ClassDeclarations) { } | |
693 void checkCtorConstInit() { } | |
694 | |
695 void addComment(ubyte* comment) | |
696 { | |
697 //if (comment) | |
698 //printf("adding comment '%s' to symbol %p '%s'\n", comment, this, toChars()); | |
699 | |
700 if (this.comment is null) { | |
701 this.comment = comment; | |
702 } else { | |
703 static if (true) { | |
704 if (comment !is null && strcmp(cast(char*)comment, cast(char*)this.comment) != 0) | |
705 { // Concatenate the two | |
706 this.comment = Lexer.combineComments(this.comment, comment); | |
707 } | |
708 } | |
709 } | |
710 } | |
711 | |
712 void emitComment(Scope sc) | |
713 { | |
714 assert(false); | |
715 } | |
716 | |
717 void emitDitto(Scope sc) | |
718 { | |
719 assert(false); | |
720 } | |
721 | |
722 // Backend | |
723 | |
724 Symbol* toSymbol() // to backend symbol | |
725 { | |
726 assert(false); | |
727 } | |
728 | |
729 void toObjFile(int multiobj) // compile to .obj file | |
730 { | |
731 //printf("Dsymbol::toObjFile('%s')\n", toChars()); | |
732 // ignore | |
733 } | |
734 | |
735 int cvMember(ubyte* p) // emit cv debug info for member | |
736 { | |
737 assert(false); | |
738 } | |
739 | |
740 /********************************* | |
741 * Generate import symbol from symbol. | |
742 */ | |
743 Symbol* toImport() // to backend import symbol | |
744 { | |
745 if (!isym) | |
746 { | |
747 if (!csym) | |
748 csym = toSymbol(); | |
749 isym = toImport(csym); | |
750 } | |
751 | |
752 return isym; | |
753 } | |
754 | |
755 static Symbol* toImport(Symbol* sym) // to backend import symbol | |
756 { | |
757 char* id; | |
758 char* n; | |
759 Symbol* s; | |
760 type* t; | |
761 | |
762 //printf("Dsymbol::toImport('%s')\n", sym->Sident); | |
763 n = sym.Sident.ptr; | |
764 id = cast(char*) alloca(6 + strlen(n) + 1 + (type_paramsize_i(sym.Stype)).sizeof*3 + 1); | |
765 if (sym.Stype.Tmangle == mTYman_std && tyfunc(sym.Stype.Tty)) | |
766 { | |
767 sprintf(id, "_imp__%s@%lu", n, type_paramsize_i(sym.Stype)); | |
768 } | |
769 else if (sym.Stype.Tmangle == mTYman_d) | |
770 sprintf(id,"_imp_%s",n); | |
771 else | |
772 sprintf(id,"_imp__%s",n); | |
773 t = type_alloc(TYnptr | mTYconst); | |
774 t.Tnext = sym.Stype; | |
775 t.Tnext.Tcount++; | |
776 t.Tmangle = mTYman_c; | |
777 t.Tcount++; | |
778 s = symbol_calloc(id); | |
779 s.Stype = t; | |
780 s.Sclass = SCextern; | |
781 s.Sfl = FLextern; | |
782 slist_add(s); | |
783 | |
784 return s; | |
785 } | |
786 | |
787 Symbol* toSymbolX(string prefix, int sclass, TYPE* t, string suffix) // helper | |
788 { | |
789 Symbol* s; | |
790 char* id; | |
791 string n; | |
792 size_t nlen; | |
793 | |
794 //writef("Dsymbol::toSymbolX('%s', '%s')\n", prefix, this.classinfo.name); | |
795 n = mangle(); | |
796 assert(n.length != 0); | |
797 | |
798 nlen = n.length; | |
799 static if (false) { | |
800 if (nlen > 2 && n[0] == '_' && n[1] == 'D') | |
801 { | |
802 nlen -= 2; | |
803 n += 2; | |
804 } | |
805 } | |
806 id = cast(char*) alloca(2 + nlen + size_t.sizeof * 3 + prefix.length + suffix.length + 1); | |
807 sprintf(id, "_D%.*s%lu%.*s%.*s", n, prefix.length, prefix, suffix); | |
808 | |
809 static if (false) { | |
810 if (global.params.isWindows && (type_mangle(t) == mTYman.mTYman_c || type_mangle(t) == mTYman.mTYman_std)) | |
811 id++; // Windows C mangling will put the '_' back in | |
812 } | |
813 s = symbol_name(id, sclass, t); | |
814 | |
815 //printf("-Dsymbol::toSymbolX() %s\n", id); | |
816 return s; | |
817 } | |
818 | |
819 // Eliminate need for dynamic_cast | |
820 Package isPackage() { return null; } | |
821 Module isModule() { return null; } | |
822 EnumMember isEnumMember() { return null; } | |
823 TemplateDeclaration isTemplateDeclaration() { return null; } | |
824 TemplateInstance isTemplateInstance() { return null; } | |
825 TemplateMixin isTemplateMixin() { return null; } | |
826 Declaration isDeclaration() { return null; } | |
827 ThisDeclaration isThisDeclaration() { return null; } | |
828 TupleDeclaration isTupleDeclaration() { return null; } | |
829 TypedefDeclaration isTypedefDeclaration() { return null; } | |
830 AliasDeclaration isAliasDeclaration() { return null; } | |
831 AggregateDeclaration isAggregateDeclaration() { return null; } | |
832 FuncDeclaration isFuncDeclaration() { return null; } | |
833 FuncAliasDeclaration isFuncAliasDeclaration() { return null; } | |
834 FuncLiteralDeclaration isFuncLiteralDeclaration() { return null; } | |
835 CtorDeclaration isCtorDeclaration() { return null; } | |
836 PostBlitDeclaration isPostBlitDeclaration() { return null; } | |
837 DtorDeclaration isDtorDeclaration() { return null; } | |
838 StaticCtorDeclaration isStaticCtorDeclaration() { return null; } | |
839 StaticDtorDeclaration isStaticDtorDeclaration() { return null; } | |
840 InvariantDeclaration isInvariantDeclaration() { return null; } | |
841 UnitTestDeclaration isUnitTestDeclaration() { return null; } | |
842 NewDeclaration isNewDeclaration() { return null; } | |
843 VarDeclaration isVarDeclaration() { return null; } | |
844 ClassDeclaration isClassDeclaration() { return null; } | |
845 StructDeclaration isStructDeclaration() { return null; } | |
846 UnionDeclaration isUnionDeclaration() { return null; } | |
847 InterfaceDeclaration isInterfaceDeclaration() { return null; } | |
848 ScopeDsymbol isScopeDsymbol() { return null; } | |
849 WithScopeSymbol isWithScopeSymbol() { return null; } | |
850 ArrayScopeSymbol isArrayScopeSymbol() { return null; } | |
851 Import isImport() { return null; } | |
852 EnumDeclaration isEnumDeclaration() { return null; } | |
853 version (_DH) { | |
854 DeleteDeclaration isDeleteDeclaration() { return null; } | |
855 } | |
856 SymbolDeclaration isSymbolDeclaration() { return null; } | |
857 AttribDeclaration isAttribDeclaration() { return null; } | |
858 OverloadSet isOverloadSet() { return null; } | |
859 version (TARGET_NET) { | |
860 PragmaScope isPragmaScope() { return null; } | |
861 } | |
862 } |