1:
2: // Compiler implementation of the D programming language
3: // Copyright (c) 1999-2011 by Digital Mars
4: // All Rights Reserved
5: // written by Walter Bright
6: // http://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 <stdio.h>
12: #include <stddef.h>
13: #include <time.h>
14: static char __file__[] = __FILE__; /* for tassert.h */
15: #include "tassert.h"
16:
17: #if __sun&&__SVR4
18: #include <alloca.h>
19: #endif
20:
21: #include "mars.h"
22: #include "module.h"
23: #include "mtype.h"
24: #include "declaration.h"
25: #include "statement.h"
26: #include "enum.h"
27: #include "aggregate.h"
28: #include "init.h"
29: #include "attrib.h"
30: #include "lexer.h"
31: #include "dsymbol.h"
32: #include "id.h"
33:
34: #include "rmem.h"
35:
36: // Back end
37: #include "cc.h"
38: #include "global.h"
39: #include "oper.h"
40: #include "code.h"
41: #include "type.h"
42: #include "dt.h"
43: #include "cgcv.h"
44: #include "outbuf.h"
45: #include "irstate.h"
46:
47: void slist_add(Symbol *s);
48: void slist_reset();
49:
50: Classsym *fake_classsym(Identifier *id);
51:
52: /********************************* SymbolDeclaration ****************************/
53:
54: SymbolDeclaration::SymbolDeclaration(Loc loc, Symbol *s, StructDeclaration *dsym)
55: : Declaration(new Identifier(s->Sident, TOKidentifier))
56: {
57: this->loc = loc;
58: sym = s;
59: this->dsym = dsym;
60: storage_class |= STCconst;
61: }
62:
63: Symbol *SymbolDeclaration::toSymbol()
64: {
65: return sym;
66: }
67:
68: /*************************************
69: * Helper
70: */
71:
72: Symbol *Dsymbol::toSymbolX(const char *prefix, int sclass, type *t, const char *suffix)
73: {
74: Symbol *s;
75: char *id;
76: const char *n;
77: size_t nlen;
78:
79: //printf("Dsymbol::toSymbolX('%s')\n", prefix);
80: n = mangle();
81: assert(n);
82: nlen = strlen(n);
83: #if 0
84: if (nlen > 2 && n[0] == '_' && n[1] == 'D')
85: {
86: nlen -= 2;
87: n += 2;
88: }
89: #endif
90: id = (char *) alloca(2 + nlen + sizeof(size_t) * 3 + strlen(prefix) + strlen(suffix) + 1);
warning C6255: _alloca indicates failure by raising a stack overflow exception. Consider using _malloca instead
91: sprintf(id,"_D%s%"SIZE_T_FORMAT"u%s%s", n, strlen(prefix), prefix, suffix);
warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\stdio.h(371) : see declaration of 'sprintf'
92: #if 0
93: if (global.params.isWindows &&
94: (type_mangle(t) == mTYman_c || type_mangle(t) == mTYman_std))
95: id++; // Windows C mangling will put the '_' back in
96: #endif
97: s = symbol_name(id, sclass, t);
98: //printf("-Dsymbol::toSymbolX() %s\n", id);
99: return s;
100: }
101:
102: /*************************************
103: */
104:
105: Symbol *Dsymbol::toSymbol()
106: {
107: printf("Dsymbol::toSymbol() '%s', kind = '%s'\n", toChars(), kind());
108: #ifdef DEBUG
109: halt();
110: #endif
111: assert(0); // BUG: implement
112: return NULL;
113: }
114:
115: /*********************************
116: * Generate import symbol from symbol.
117: */
118:
119: Symbol *Dsymbol::toImport()
120: {
121: if (!isym)
122: {
123: if (!csym)
124: csym = toSymbol();
125: isym = toImport(csym);
126: }
127: return isym;
128: }
129:
130: /*************************************
131: */
132:
133: Symbol *Dsymbol::toImport(Symbol *sym)
134: {
135: char *id;
136: char *n;
137: Symbol *s;
138: type *t;
139:
140: //printf("Dsymbol::toImport('%s')\n", sym->Sident);
141: n = sym->Sident;
142: id = (char *) alloca(6 + strlen(n) + 1 + sizeof(type_paramsize(sym->Stype))*3 + 1);
warning C6255: _alloca indicates failure by raising a stack overflow exception. Consider using _malloca instead
143: if (sym->Stype->Tmangle == mTYman_std && tyfunc(sym->Stype->Tty))
144: {
145: sprintf(id,"_imp__%s@%lu",n,(unsigned long)type_paramsize(sym->Stype));
warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\stdio.h(371) : see declaration of 'sprintf'
146: }
147: else if (sym->Stype->Tmangle == mTYman_d)
148: sprintf(id,"_imp_%s",n);
warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\stdio.h(371) : see declaration of 'sprintf'
149: else
150: sprintf(id,"_imp__%s",n);
warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\stdio.h(371) : see declaration of 'sprintf'
151: t = type_alloc(TYnptr | mTYconst);
152: t->Tnext = sym->Stype;
153: t->Tnext->Tcount++;
154: t->Tmangle = mTYman_c;
155: t->Tcount++;
156: s = symbol_calloc(id);
157: s->Stype = t;
158: s->Sclass = SCextern;
159: s->Sfl = FLextern;
160: slist_add(s);
161: return s;
162: }
163:
164: /*************************************
165: */
166:
167: Symbol *VarDeclaration::toSymbol()
168: {
169: //printf("VarDeclaration::toSymbol(%s)\n", toChars());
170: //if (needThis()) *(char*)0=0;
171: assert(!needThis());
172: if (!csym)
173: { Symbol *s;
174: TYPE *t;
175: const char *id;
176:
177: if (isDataseg())
178: id = mangle();
179: else
180: id = ident->toChars();
181: s = symbol_calloc(id);
182:
183: if (storage_class & (STCout | STCref))
184: {
185: if (global.params.symdebug && storage_class & STCparameter)
186: {
187: t = type_alloc(TYnptr); // should be TYref, but problems in back end
188: t->Tnext = type->toCtype();
189: t->Tnext->Tcount++;
190: }
191: else
192: t = type_fake(TYnptr);
193: }
194: else if (storage_class & STClazy)
195: t = type_fake(TYdelegate); // Tdelegate as C type
196: else if (isParameter())
197: t = type->toCParamtype();
198: else
199: t = type->toCtype();
200: t->Tcount++;
201:
202: if (isDataseg())
203: {
204: if (isThreadlocal())
205: { /* Thread local storage
206: */
207: TYPE *ts = t;
208: ts->Tcount++; // make sure a different t is allocated
209: type_setty(&t, t->Tty | mTYthread);
210: ts->Tcount--;
211:
212: if (global.params.vtls)
213: {
214: char *p = loc.toChars();
215: fprintf(stdmsg, "%s: %s is thread local\n", p ? p : "", toChars());
216: if (p)
217: mem.free(p);
218: }
219: }
220: s->Sclass = SCextern;
221: s->Sfl = FLextern;
222: slist_add(s);
223: /* if it's global or static, then it needs to have a qualified but unmangled name.
224: * This gives some explanation of the separation in treating name mangling.
225: * It applies to PDB format, but should apply to CV as PDB derives from CV.
226: * http://msdn.microsoft.com/en-us/library/ff553493(VS.85).aspx
227: */
228: s->prettyIdent = toPrettyChars();
229: }
230: else
231: {
232: s->Sclass = SCauto;
233: s->Sfl = FLauto;
234:
235: if (nestedrefs.dim)
236: {
237: /* Symbol is accessed by a nested function. Make sure
238: * it is not put in a register, and that the optimizer
239: * assumes it is modified across function calls and pointer
240: * dereferences.
241: */
242: //printf("\tnested ref, not register\n");
243: type_setcv(&t, t->Tty | mTYvolatile);
244: }
245: }
246:
247: if (ident == Id::va_argsave)
248: /* __va_argsave is set outside of the realm of the optimizer,
249: * so we tell the optimizer to leave it alone
250: */
251: type_setcv(&t, t->Tty | mTYvolatile);
252:
253: mangle_t m = 0;
254: switch (linkage)
255: {
256: case LINKwindows:
257: m = mTYman_std;
258: break;
259:
260: case LINKpascal:
261: m = mTYman_pas;
262: break;
263:
264: case LINKc:
265: m = mTYman_c;
266: break;
267:
268: case LINKd:
269: m = mTYman_d;
270: break;
271:
272: case LINKcpp:
273: m = mTYman_cpp;
274: break;
275:
276: default:
277: printf("linkage = %d\n", linkage);
278: assert(0);
279: }
280: type_setmangle(&t, m);
281: s->Stype = t;
282:
283: csym = s;
284: }
285: return csym;
286: }
287:
288: /*************************************
289: */
290:
291: Symbol *ClassInfoDeclaration::toSymbol()
292: {
293: return cd->toSymbol();
294: }
295:
296: /*************************************
297: */
298:
299: Symbol *ModuleInfoDeclaration::toSymbol()
300: {
301: return mod->toSymbol();
302: }
303:
304: /*************************************
305: */
306:
307: Symbol *TypeInfoDeclaration::toSymbol()
308: {
309: //printf("TypeInfoDeclaration::toSymbol(%s), linkage = %d\n", toChars(), linkage);
310: return VarDeclaration::toSymbol();
311: }
312:
313: /*************************************
314: */
315:
316: Symbol *TypeInfoClassDeclaration::toSymbol()
317: {
318: //printf("TypeInfoClassDeclaration::toSymbol(%s), linkage = %d\n", toChars(), linkage);
319: assert(tinfo->ty == Tclass);
320: TypeClass *tc = (TypeClass *)tinfo;
321: return tc->sym->toSymbol();
322: }
323:
324: /*************************************
325: */
326:
327: Symbol *FuncAliasDeclaration::toSymbol()
328: {
329: return funcalias->toSymbol();
330: }
331:
332: /*************************************
333: */
334:
335: Symbol *FuncDeclaration::toSymbol()
336: {
337: if (!csym)
338: { Symbol *s;
339: TYPE *t;
340: const char *id;
341:
342: #if 0
343: id = ident->toChars();
344: #else
345: id = mangle();
346: #endif
347: //printf("FuncDeclaration::toSymbol(%s %s)\n", kind(), toChars());
348: //printf("\tid = '%s'\n", id);
349: //printf("\ttype = %s\n", type->toChars());
350: s = symbol_calloc(id);
351: slist_add(s);
352:
353: {
354: s->prettyIdent = toPrettyChars();
355: s->Sclass = SCglobal;
356: symbol_func(s);
357: func_t *f = s->Sfunc;
358: if (isVirtual())
359: f->Fflags |= Fvirtual;
360: else if (isMember2())
361: f->Fflags |= Fstatic;
362: f->Fstartline.Slinnum = loc.linnum;
363: f->Fstartline.Sfilename = (char *)loc.filename;
364: if (endloc.linnum)
365: { f->Fendline.Slinnum = endloc.linnum;
366: f->Fendline.Sfilename = (char *)endloc.filename;
367: }
368: else
369: { f->Fendline.Slinnum = loc.linnum;
370: f->Fendline.Sfilename = (char *)loc.filename;
371: }
372: t = type->toCtype();
373: }
374:
375: mangle_t msave = t->Tmangle;
376: if (isMain())
377: {
378: t->Tty = TYnfunc;
379: t->Tmangle = mTYman_c;
380: }
381: else
382: {
383: switch (linkage)
384: {
385: case LINKwindows:
386: t->Tmangle = mTYman_std;
387: break;
388:
389: case LINKpascal:
390: t->Tty = TYnpfunc;
391: t->Tmangle = mTYman_pas;
392: break;
393:
394: case LINKc:
395: t->Tmangle = mTYman_c;
396: break;
397:
398: case LINKd:
399: t->Tmangle = mTYman_d;
400: break;
401:
402: case LINKcpp:
403: { t->Tmangle = mTYman_cpp;
404: #if TARGET_WINDOS
405: if (isThis())
406: t->Tty = TYmfunc;
407: #endif
408: s->Sflags |= SFLpublic;
409: Dsymbol *parent = toParent();
410: ClassDeclaration *cd = parent->isClassDeclaration();
411: if (cd)
412: {
413: ::type *t = cd->type->toCtype();
warning C6246: Local declaration of 't' hides declaration of the same name in outer scope. For additional information, see previous declaration at line '339' of 'c:\projects\extern\d\dmd\src\tocsym.c': Lines: 339
414: s->Sscope = t->Tnext->Ttag;
415: }
416: break;
417: }
418: default:
419: printf("linkage = %d\n", linkage);
420: assert(0);
421: }
422: }
423: if (msave)
424: assert(msave == t->Tmangle);
425: //printf("Tty = %x, mangle = x%x\n", t->Tty, t->Tmangle);
426: t->Tcount++;
427: s->Stype = t;
428: //s->Sfielddef = this;
429:
430: csym = s;
431: }
432: return csym;
433: }
434:
435: /*************************************
436: */
437:
438: Symbol *FuncDeclaration::toThunkSymbol(int offset)
439: {
440: Symbol *sthunk;
441:
442: toSymbol();
443:
444: #if 0
445: char *id;
446: char *n;
447: type *t;
448:
449: n = sym->Sident;
450: id = (char *) alloca(8 + 5 + strlen(n) + 1);
451: sprintf(id,"_thunk%d__%s", offset, n);
452: s = symbol_calloc(id);
453: slist_add(s);
454: s->Stype = csym->Stype;
455: s->Stype->Tcount++;
456: #endif
457: sthunk = symbol_generate(SCstatic, csym->Stype);
458: sthunk->Sflags |= SFLimplem;
459: cod3_thunk(sthunk, csym, 0, TYnptr, -offset, -1, 0);
460: return sthunk;
461: }
462:
463:
464: /****************************************
465: * Create a static symbol we can hang DT initializers onto.
466: */
467:
468: Symbol *static_sym()
469: {
470: Symbol *s;
471: type *t;
472:
473: t = type_alloc(TYint);
474: t->Tcount++;
475: s = symbol_calloc("internal");
476: s->Sclass = SCstatic;
477: s->Sfl = FLextern;
478: s->Sflags |= SFLnodebug;
479: s->Stype = t;
480: #if ELFOBJ || MACHOBJ
481: s->Sseg = DATA;
482: #endif
483: slist_add(s);
484: return s;
485: }
486:
487: /**************************************
488: * Fake a struct symbol.
489: */
490:
491: Classsym *fake_classsym(Identifier *id)
492: { TYPE *t;
493: Classsym *scc;
494:
495: scc = (Classsym *)symbol_calloc(id->toChars());
496: scc->Sclass = SCstruct;
497: scc->Sstruct = struct_calloc();
498: scc->Sstruct->Sstructalign = 8;
499: //scc->Sstruct->ptrtype = TYnptr;
500: scc->Sstruct->Sflags = STRglobal;
501:
502: t = type_alloc(TYstruct);
503: t->Tflags |= TFsizeunknown | TFforward;
504: t->Ttag = scc; // structure tag name
505: assert(t->Tmangle == 0);
506: t->Tmangle = mTYman_d;
507: t->Tcount++;
508: scc->Stype = t;
509: slist_add(scc);
510: return scc;
511: }
512:
513: /*************************************
514: * Create the "ClassInfo" symbol
515: */
516:
517: static Classsym *scc;
518:
519: Symbol *ClassDeclaration::toSymbol()
520: {
521: if (!csym)
522: {
523: Symbol *s;
524:
525: if (!scc)
526: scc = fake_classsym(Id::ClassInfo);
527:
528: s = toSymbolX("__Class", SCextern, scc->Stype, "Z");
529: s->Sfl = FLextern;
530: s->Sflags |= SFLnodebug;
531: csym = s;
532: slist_add(s);
533: }
534: return csym;
535: }
536:
537: /*************************************
538: * Create the "InterfaceInfo" symbol
539: */
540:
541: Symbol *InterfaceDeclaration::toSymbol()
542: {
543: if (!csym)
544: {
545: Symbol *s;
546:
547: if (!scc)
548: scc = fake_classsym(Id::ClassInfo);
549:
550: s = toSymbolX("__Interface", SCextern, scc->Stype, "Z");
551: s->Sfl = FLextern;
552: s->Sflags |= SFLnodebug;
553: csym = s;
554: slist_add(s);
555: }
556: return csym;
557: }
558:
559: /*************************************
560: * Create the "ModuleInfo" symbol
561: */
562:
563: Symbol *Module::toSymbol()
564: {
565: if (!csym)
566: {
567: Symbol *s;
568: static Classsym *scc;
warning C6244: Local declaration of 'scc' hides previous declaration at line '517' of 'c:\projects\extern\d\dmd\src\tocsym.c'
569:
570: if (!scc)
571: scc = fake_classsym(Id::ClassInfo);
572:
573: s = toSymbolX("__ModuleInfo", SCextern, scc->Stype, "Z");
574: s->Sfl = FLextern;
575: s->Sflags |= SFLnodebug;
576: csym = s;
577: slist_add(s);
578: }
579: return csym;
580: }
581:
582: /*************************************
583: * This is accessible via the ClassData, but since it is frequently
584: * needed directly (like for rtti comparisons), make it directly accessible.
585: */
586:
587: Symbol *ClassDeclaration::toVtblSymbol()
588: {
589: if (!vtblsym)
590: {
591: Symbol *s;
592: TYPE *t;
593:
594: if (!csym)
595: toSymbol();
596:
597: t = type_alloc(TYnptr | mTYconst);
598: t->Tnext = tsvoid;
599: t->Tnext->Tcount++;
600: t->Tmangle = mTYman_d;
601: s = toSymbolX("__vtbl", SCextern, t, "Z");
602: s->Sflags |= SFLnodebug;
603: s->Sfl = FLextern;
604: vtblsym = s;
605: slist_add(s);
606: }
607: return vtblsym;
608: }
609:
610: /**********************************
611: * Create the static initializer for the struct/class.
612: */
613:
614: Symbol *AggregateDeclaration::toInitializer()
615: {
616: Symbol *s;
617: Classsym *stag;
618:
619: if (!sinit)
620: {
621: stag = fake_classsym(Id::ClassInfo);
622: s = toSymbolX("__init", SCextern, stag->Stype, "Z");
623: s->Sfl = FLextern;
624: s->Sflags |= SFLnodebug;
625: slist_add(s);
626: sinit = s;
627: }
628: return sinit;
629: }
630:
631: Symbol *TypedefDeclaration::toInitializer()
632: {
633: Symbol *s;
634: Classsym *stag;
635:
636: if (!sinit)
637: {
638: stag = fake_classsym(Id::ClassInfo);
639: s = toSymbolX("__init", SCextern, stag->Stype, "Z");
640: s->Sfl = FLextern;
641: s->Sflags |= SFLnodebug;
642: slist_add(s);
643: sinit = s;
644: }
645: return sinit;
646: }
647:
648: Symbol *EnumDeclaration::toInitializer()
649: {
650: Symbol *s;
651: Classsym *stag;
652:
653: if (!sinit)
654: {
655: stag = fake_classsym(Id::ClassInfo);
656: Identifier *ident_save = ident;
657: if (!ident)
658: ident = Lexer::uniqueId("__enum");
659: s = toSymbolX("__init", SCextern, stag->Stype, "Z");
660: ident = ident_save;
661: s->Sfl = FLextern;
662: s->Sflags |= SFLnodebug;
663: slist_add(s);
664: sinit = s;
665: }
666: return sinit;
667: }
668:
669:
670: /******************************************
671: */
672:
673: Symbol *Module::toModuleAssert()
674: {
675: if (!massert)
676: {
677: type *t;
678:
679: t = type_alloc(TYjfunc);
680: t->Tflags |= TFprototype | TFfixed;
681: t->Tmangle = mTYman_d;
682: t->Tnext = tsvoid;
683: tsvoid->Tcount++;
684:
685: massert = toSymbolX("__assert", SCextern, t, "FiZv");
686: massert->Sfl = FLextern;
687: massert->Sflags |= SFLnodebug;
688: slist_add(massert);
689: }
690: return massert;
691: }
692:
693: Symbol *Module::toModuleUnittest()
694: {
695: if (!munittest)
696: {
697: type *t;
698:
699: t = type_alloc(TYjfunc);
700: t->Tflags |= TFprototype | TFfixed;
701: t->Tmangle = mTYman_d;
702: t->Tnext = tsvoid;
703: tsvoid->Tcount++;
704:
705: munittest = toSymbolX("__unittest_fail", SCextern, t, "FiZv");
706: munittest->Sfl = FLextern;
707: munittest->Sflags |= SFLnodebug;
708: slist_add(munittest);
709: }
710: return munittest;
711: }
712:
713: /******************************************
714: */
715:
716: Symbol *Module::toModuleArray()
717: {
718: if (!marray)
719: {
720: type *t;
721:
722: t = type_alloc(TYjfunc);
723: t->Tflags |= TFprototype | TFfixed;
724: t->Tmangle = mTYman_d;
725: t->Tnext = tsvoid;
726: tsvoid->Tcount++;
727:
728: marray = toSymbolX("__array", SCextern, t, "Z");
729: marray->Sfl = FLextern;
730: marray->Sflags |= SFLnodebug;
731: slist_add(marray);
732: }
733: return marray;
734: }
735:
736: /********************************************
737: * Determine the right symbol to look up
738: * an associative array element.
739: * Input:
740: * flags 0 don't add value signature
741: * 1 add value signature
742: */
743:
744: Symbol *TypeAArray::aaGetSymbol(const char *func, int flags)
745: #if __DMC__
746: __in
747: {
748: assert(func);
749: assert((flags & ~1) == 0);
750: }
751: __out (result)
752: {
753: assert(result);
754: }
755: __body
756: #endif
757: {
758: int sz;
warning C4101: 'sz' : unreferenced local variable
759: char *id;
760: type *t;
761: Symbol *s;
762: int i;
763:
764: // Dumb linear symbol table - should use associative array!
765: static Symbols *sarray = NULL;
766:
767: //printf("aaGetSymbol(func = '%s', flags = %d, key = %p)\n", func, flags, key);
768: #if 0
769: OutBuffer buf;
770: key->toKeyBuffer(&buf);
771:
772: sz = next->size(); // it's just data, so we only care about the size
773: sz = (sz + 3) & ~3; // reduce proliferation of library routines
774: id = (char *)alloca(3 + strlen(func) + buf.offset + sizeof(sz) * 3 + 1);
775: buf.writeByte(0);
776: if (flags & 1)
777: sprintf(id, "_aa%s%s%d", func, buf.data, sz);
778: else
779: sprintf(id, "_aa%s%s", func, buf.data);
780: #else
781: id = (char *)alloca(3 + strlen(func) + 1);
warning C6255: _alloca indicates failure by raising a stack overflow exception. Consider using _malloca instead
782: sprintf(id, "_aa%s", func);
warning C4996: 'sprintf': This function or variable may be unsafe. Consider using sprintf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\stdio.h(371) : see declaration of 'sprintf'
783: #endif
784: if (!sarray)
785: sarray = new Symbols();
786:
787: // See if symbol is already in sarray
788: for (i = 0; i < sarray->dim; i++)
warning C4018: '<' : signed/unsigned mismatch
789: { s = sarray->tdata()[i];
790: if (strcmp(id, s->Sident) == 0)
791: return s; // use existing Symbol
792: }
793:
794: // Create new Symbol
795:
796: s = symbol_calloc(id);
797: slist_add(s);
798: s->Sclass = SCextern;
799: s->Ssymnum = -1;
800: symbol_func(s);
801:
802: t = type_alloc(TYnfunc);
803: t->Tflags = TFprototype | TFfixed;
804: t->Tmangle = mTYman_c;
805: t->Tparamtypes = NULL;
806: t->Tnext = next->toCtype();
807: t->Tnext->Tcount++;
808: t->Tcount++;
809: s->Stype = t;
810:
811: sarray->push(s); // remember it
812: return s;
813: }
814:
815: