3 #define YYLTYPE Location
9 bool memoryGuard = false;
10 public void SetMemoryGuard(bool b) { memoryGuard = b; } public bool GetMemoryGuard() { return memoryGuard; }
12 static void OutputIdentifier(Identifier id, File f)
17 TODO: Name Space Fix ups
18 if(id.nameSpace && id.nameSpace->name)
20 f.Puts(id.nameSpace->name);
24 if(id._class.type == templateTypeSpecifier)
26 if(id._class.templateParameter && id._class.templateParameter.identifier && id._class.templateParameter.identifier.string)
27 f.Puts(id._class.templateParameter.identifier.string);
33 if(!strcmp(id._class.name, "class"))
34 f.Puts("typed_object");
36 f.Puts(id._class.name);
42 f.Puts((id && id.string) ? id.string : "(null identifier)");
45 static void OutputOperator(int op, File f)
49 case INC_OP: f.Puts("++"); break;
50 case DEC_OP: f.Puts("--");break;
51 case SIZEOF: f.Puts("sizeof "); break;
52 case LEFT_OP: f.Puts("<<"); break;
53 case RIGHT_OP: f.Puts(">>"); break;
54 case LE_OP: f.Puts("<="); break;
55 case GE_OP: f.Puts(">="); break;
56 case EQ_OP: f.Puts("=="); break;
57 case NE_OP: f.Puts("!="); break;
58 case AND_OP: f.Puts("&&"); break;
59 case OR_OP: f.Puts("||"); break;
60 case MUL_ASSIGN: f.Puts("*="); break;
61 case DIV_ASSIGN: f.Puts("/="); break;
62 case MOD_ASSIGN: f.Puts("%="); break;
63 case ADD_ASSIGN: f.Puts("+="); break;
64 case SUB_ASSIGN: f.Puts("-="); break;
65 case LEFT_ASSIGN: f.Puts("<<="); break;
66 case RIGHT_ASSIGN: f.Puts(">>="); break;
67 case AND_ASSIGN: f.Puts("&="); break;
68 case XOR_ASSIGN: f.Puts("^="); break;
69 case OR_ASSIGN: f.Puts("|="); break;
70 case '&': case '*': case '+': case '-': case '~': case '!': case '/': case '%':
71 case '<': case '>': case '|': case '^': case '=':
74 case DELETE: f.Puts("delete "); break;
78 public void OutputTypeName(TypeName type, File f)
80 /*if(type.typedObject)
82 //f.Puts("Class * class, void *");
85 else */if(type.qualifiers)
88 for(spec = type.qualifiers->first; spec; spec = spec.next)
90 OutputSpecifier(spec, f);
91 if(spec.next) f.Puts(" ");
97 OutputDeclarator(type.declarator, f);
100 if(/*!type.typedObject && */!type.qualifiers && !type.declarator)
105 public void OutputExpression(Expression exp, File f)
111 if(exp._classExp.specifiers)
114 for(spec = exp._classExp.specifiers->first; spec; spec = spec.next)
116 OutputSpecifier(spec, f);
117 if(spec.next) f.Puts(" ");
119 if(exp._classExp.decl)
122 OutputDeclarator(exp._classExp.decl, f);
127 case extensionCompoundExp:
128 f.Puts("__extension__ (");
129 OutputStatement(exp.compound, f);
135 OutputTypeName(exp._renew.typeName, f);
137 OutputExpression(exp._renew.size, f);
143 OutputTypeName(exp._renew.typeName, f);
145 OutputExpression(exp._renew.size, f);
150 OutputExpression(exp._renew.exp, f);
152 OutputTypeName(exp._renew.typeName, f);
154 OutputExpression(exp._renew.size, f);
159 OutputExpression(exp._renew.exp, f);
161 OutputTypeName(exp._renew.typeName, f);
163 OutputExpression(exp._renew.size, f);
168 OutputIdentifier(exp.identifier, f);
172 OutputInstance(exp.instance, f);
176 f.Puts(exp.constant);
187 OutputExpression(exp.op.exp1, f);
191 OutputOperator(exp.op.op, f);
194 if(exp.op.exp1 || (exp.op.exp2.type == opExp && !exp.op.exp2.op.exp1 && exp.op.exp2.op.op == exp.op.op))
196 OutputExpression(exp.op.exp2, f);
199 case extensionExpressionExp:
202 Expression expression;
203 if(exp.type == extensionExpressionExp)
204 f.Puts("__extension__ (");
208 for(expression = exp.list->first; expression; expression = expression.next)
210 OutputExpression(expression, f);
211 if(expression.next) f.Puts(", ");
219 Expression expression;
221 OutputExpression(exp.index.exp, f);
224 for(expression = exp.index.index->first; expression; expression = expression.next)
226 OutputExpression(expression, f);
227 if(expression.next) f.Puts(", ");
234 OutputExpression(exp.call.exp, f);
236 if(exp.call.arguments)
238 Expression expression;
239 for(expression = exp.call.arguments->first; expression; expression = expression.next)
241 OutputExpression(expression, f);
242 if(expression.next) f.Puts(", ");
250 OutputExpression(exp.member.exp, f);
252 if(exp.member.member)
253 OutputIdentifier(exp.member.member, f);
256 OutputExpression(exp.member.exp, f);
258 OutputIdentifier(exp.member.member, f);
262 OutputTypeName(exp.typeName, f);
265 case extensionInitializerExp:
266 f.Puts("__extension__ (");
267 if(exp.initializer.typeName)
268 OutputTypeName(exp.initializer.typeName, f);
270 if(exp.initializer.initializer)
271 OutputInitializer(exp.initializer.initializer, f);
275 OutputTypeName(exp.cast.typeName, f);
278 OutputExpression(exp.cast.exp, f);
281 OutputExpression(exp.cond.cond, f);
284 Expression expression;
285 for(expression = exp.cond.exp->first; expression; expression = expression.next)
287 OutputExpression(expression, f);
288 if(expression.next) f.Puts(", ");
292 OutputExpression(exp.cond.elseExp, f);
295 f.Puts("__builtin_va_arg(");
296 OutputExpression(exp.vaArg.exp, f);
298 OutputTypeName(exp.vaArg.typeName, f);
305 Expression expression;
306 for(expression = exp.list->first; expression; expression = expression.next)
308 OutputExpression(expression, f);
309 if(expression.next) f.Puts(", ");
317 static void OutputAsmField(AsmField field, File f)
319 f.Puts(field.command);
323 OutputExpression(field.expression, f);
328 static void OutputStatement(Statement stmt, File f)
330 char name[MAX_FILENAME] = "";
331 char origName[MAX_FILENAME] = "";
335 eString_GetLastDirectory(sourceFile, name);
340 if(yylloc.start.included)
342 //GetWorkingDir(name, sizeof(name));
343 PathCat(name, GetIncludeFileFromID(yylloc.start.included));
347 //GetWorkingDir(name, sizeof(name));
348 PathCat(name, sourceFile);
350 ChangeCh(name, '\\', '/');
352 //GetWorkingDir(origName, sizeof(origName));
353 PathCat(origName, outputFile);
354 ChangeCh(origName, '\\', '/');
358 if(inCompiler && outputLineNumbers && stmt.loc.start.line)
360 /*if(stmt.loc.start.line == 1)
362 f.Printf("\n#line %d \"%s\"\n", stmt.loc.start.line, name);
369 OutputIdentifier(stmt.labeled.id, f);
372 OutputStatement(stmt.labeled.stmt, f);
375 if(stmt.caseStmt.exp)
378 OutputExpression(stmt.caseStmt.exp, f);
384 f.Puts("default:\n");
387 if(stmt.caseStmt.stmt)
388 OutputStatement(stmt.caseStmt.stmt, f);
394 if(stmt.compound.declarations)
397 for(decl = stmt.compound.declarations->first; decl; decl = decl.next)
399 OutputDeclaration(decl, f);
403 if(stmt.compound.statements)
406 if(stmt.compound.declarations)
411 for(statement = stmt.compound.statements->first; statement; statement = statement.next)
413 OutputStatement(statement, f);
418 if(inCompiler && outputLineNumbers && stmt.loc.end.line)
420 /*if(stmt.loc.end.line == 1)
423 f.Printf("\n#line %d \"%s\"\n", stmt.loc.end.line, name);
435 for(exp = stmt.expressions->first; exp; exp = exp.next)
437 OutputExpression(exp, f);
438 if(exp.next) f.Puts(", ");
448 for(exp = stmt.ifStmt.exp->first; exp; exp = exp.next)
450 OutputExpression(exp, f);
451 if(exp.next) f.Puts(", ");
456 OutputStatement(stmt.ifStmt.stmt, f);
457 if(stmt.ifStmt.elseStmt)
462 if(stmt.ifStmt.elseStmt.type != ifStmt)
469 OutputStatement(stmt.ifStmt.elseStmt, f);
477 for(exp = stmt.switchStmt.exp->first; exp; exp = exp.next)
479 OutputExpression(exp, f);
480 if(exp.next) f.Puts(", ");
484 OutputStatement(stmt.switchStmt.stmt, f);
491 for(exp = stmt.switchStmt.exp->first; exp; exp = exp.next)
493 OutputExpression(exp, f);
494 if(exp.next) f.Puts(", ");
498 OutputStatement(stmt.whileStmt.stmt, f);
506 OutputStatement(stmt.whileStmt.stmt, f);
508 for(exp = stmt.switchStmt.exp->first; exp; exp = exp.next)
510 OutputExpression(exp, f);
511 if(exp.next) f.Puts(", ");
520 OutputStatement(stmt.forStmt.init, f);
522 OutputStatement(stmt.forStmt.check, f);
524 if(stmt.forStmt.increment)
526 // TESTING THIS HERE FOR FOR INCREMENT
527 if(inCompiler && outputLineNumbers && stmt.loc.end.line)
529 /*if(stmt.loc.end.line == 1)
532 f.Printf("\n#line %d \"%s\"\n", stmt.loc.end.line, name);
536 for(exp = stmt.forStmt.increment->first; exp; exp = exp.next)
538 OutputExpression(exp, f);
539 if(exp.next) f.Puts(", ");
544 OutputStatement(stmt.forStmt.stmt, f);
550 OutputIdentifier(stmt.gotoStmt.id, f);
564 if(inCompiler && memoryGuard)
566 Expression exp = stmt.expressions ? stmt.expressions->last : null;
568 if(exp && exp.expType)
571 char string[1024] = "";
572 OldList * specs = MkList();
575 if(exp.expType.kind == templateType)
577 if(exp.expType.templateParameter.dataTypeString)
578 decl = SpecDeclFromString(exp.expType.templateParameter.dataTypeString, specs,
579 MkDeclaratorIdentifier(MkIdentifier("__ecereReturnVal")));
580 else if(exp.expType.templateParameter.dataType)
583 specs = CopyList(exp.expType.templateParameter.dataType.specifiers, CopySpecifier);
584 decl = PlugDeclarator(/*CopyDeclarator(*/exp.expType.templateParameter.dataType.decl/*)*/,
585 MkDeclaratorIdentifier(MkIdentifier("__ecereReturnVal")));
589 ListAdd(specs, MkSpecifierName("uint64"));
590 decl = MkDeclaratorIdentifier(MkIdentifier("__ecereReturnVal"));
595 PrintType(exp.expType, string, true, true);
596 decl = SpecDeclFromString(string, specs, MkDeclaratorIdentifier(MkIdentifier("__ecereReturnVal")));
599 typeName = MkTypeName(specs, decl);
600 InstDeclPassTypeName(typeName, false);
601 OutputTypeName(typeName, f);
603 FreeTypeName(typeName);
610 Expression exp = stmt.expressions ? stmt.expressions->last : null;
611 if(exp && exp.expType)
612 f.Printf("__ecereReturnVal = ");
617 for(exp = stmt.expressions->first; exp; exp = exp.next)
619 OutputExpression(exp, f);
620 if(exp.next) f.Puts(", ");
625 if(inCompiler && memoryGuard)
627 Expression exp = stmt.expressions ? (Expression)stmt.expressions->last : null;
628 f.Printf(" __ecereNameSpace__ecere__com__MemoryGuard_PopLoc();");
629 if(exp && exp.expType)
630 f.Printf("return __ecereReturnVal;");
643 if(stmt.asmStmt.spec)
644 OutputSpecifier(stmt.asmStmt.spec, f);
646 f.Puts(stmt.asmStmt.statements);
648 if(stmt.asmStmt.inputFields || stmt.asmStmt.outputFields || stmt.asmStmt.clobberedFields)
651 if(stmt.asmStmt.inputFields)
653 for(field = stmt.asmStmt.inputFields->first; field; field = field.next)
655 if(field.prev) f.Puts(",");
656 OutputAsmField(field, f);
660 if(stmt.asmStmt.outputFields || stmt.asmStmt.clobberedFields)
663 if(stmt.asmStmt.outputFields)
665 for(field = stmt.asmStmt.outputFields->first; field; field = field.next)
667 if(field.prev) f.Puts(",");
668 OutputAsmField(field, f);
672 if(stmt.asmStmt.clobberedFields)
675 for(field = stmt.asmStmt.clobberedFields->first; field; field = field.next)
677 if(field.prev) f.Puts(",");
678 OutputAsmField(field, f);
686 if(inCompiler && outputLineNumbers && stmt.loc.start.line)
688 f.Printf("\n#line %d \"%s\"\n", outputLine+2, origName);
693 static void OutputPointer(Pointer ptr, File f)
700 for(spec = ptr.qualifiers->first; spec; spec = spec.next)
702 OutputSpecifier(spec, f);
703 if(spec.next) f.Puts(" ");
708 OutputPointer(ptr.pointer, f);
712 static void OutputDeclarator(Declarator decl, File f)
716 case structDeclarator:
719 OutputDeclarator(decl.declarator, f);
721 if(decl.structDecl.exp)
724 OutputExpression(decl.structDecl.exp, f);
726 if(decl.structDecl.posExp)
729 OutputExpression(decl.structDecl.posExp, f);
731 if(decl.structDecl.attrib)
734 f.Puts(decl.structDecl.attrib);
737 case identifierDeclarator:
738 OutputIdentifier(decl.identifier, f);
740 case bracketsDeclarator:
742 OutputDeclarator(decl.declarator, f);
745 case extendedDeclarator:
746 f.Puts(decl.extended.extended);
748 OutputDeclarator(decl.declarator, f);
750 case extendedDeclaratorEnd:
751 OutputDeclarator(decl.declarator, f);
753 f.Puts(decl.extended.extended);
755 case arrayDeclarator:
758 OutputDeclarator(decl.declarator, f);
764 ProcessExpressionType(decl.array.exp);
765 ComputeExpression(decl.array.exp);
767 OutputExpression(decl.array.exp, f);
769 else if(decl.array.enumClass)
771 Symbol _class = decl.array.enumClass.symbol; // FindClass(decl.array.enumClass.name);
772 if(_class && _class.registered)
774 f.Printf("%d", eClass_GetProperty(_class.registered, "enumSize"));
779 case functionDeclarator:
784 OutputDeclarator(decl.declarator, f);
786 if(decl.function.parameters && decl.function.parameters->first)
788 for(param = decl.function.parameters->first; param; param = param.next)
790 OutputTypeName(param, f);
798 case pointerDeclarator:
799 if(decl.pointer.pointer) OutputPointer(decl.pointer.pointer, f);
803 OutputDeclarator(decl.declarator, f);
809 static void OutputEnumerator(Enumerator enumerator, File f)
811 OutputIdentifier(enumerator.id, f);
815 OutputExpression(enumerator.exp, f);
819 static void OutputSpecifier(Specifier spec, File f)
824 switch(spec.specifier)
865 f.Puts("unsigned int");
873 f.Puts("__builtin_va_list");
891 f.Puts("typed_object");
894 f.Puts("any_object");
904 case extendedSpecifier:
906 //case classSpecifier:
907 if(spec.name && !strcmp(spec.name, "class"))
909 f.Puts("typed_object");
913 Symbol symbol = spec.symbol; // FindClass(spec.name);
914 // WILL HAVE TO VERIFY THESE ELSEWHERE...
915 if(!symbol && spec.name)
916 symbol = FindClass(spec.name);
919 f.Puts(symbol.string ? symbol.string : "(null)");
931 OutputIdentifier(spec.id, f);
935 Enumerator enumerator;
938 for(enumerator = spec.list->first; enumerator; enumerator = enumerator.next)
940 OutputEnumerator(enumerator, f);
941 if(enumerator.next) f.Puts(", ");
948 case structSpecifier:
951 f.Puts((spec.type == structSpecifier) ? "struct" : "union");
955 OutputIdentifier(spec.id, f);
962 for(def = spec.definitions->first; def; def = def.next)
964 //OutputDeclaration(decl, f);
965 OutputClassDef(def, f);
971 case typeOfSpecifier:
973 OutputExpression(spec.expression, f);
976 case subClassSpecifier:
978 OutputSpecifier(spec._class, f);
981 case templateTypeSpecifier:
982 OutputIdentifier(spec.templateParameter.identifier, f);
987 static void OutputInitializer(Initializer initializer, File f)
989 char name[MAX_FILENAME] = "";
990 char origName[MAX_FILENAME] = "";
994 eString_GetLastDirectory(sourceFile, name);
999 if(yylloc.start.included)
1001 //GetWorkingDir(name, sizeof(name));
1002 PathCat(name, GetIncludeFileFromID(yylloc.start.included));
1006 //GetWorkingDir(name, sizeof(name));
1007 PathCat(name, sourceFile);
1009 ChangeCh(name, '\\', '/');
1011 //GetWorkingDir(origName, sizeof(origName));
1012 PathCat(origName, outputFile);
1013 ChangeCh(origName, '\\', '/');
1016 switch(initializer.type)
1018 case listInitializer:
1024 if(inCompiler && outputLineNumbers && initializer.loc.start.line)
1026 /*if(initializer.loc.start.line == 1)
1029 f.Printf("\n#line %d \"%s\"\n", initializer.loc.start.line, name);
1033 for(init = initializer.list->first; init; init = init.next)
1035 OutputInitializer(init, f);
1036 if(init.next) f.Puts(", ");
1040 if(inCompiler && outputLineNumbers && initializer.loc.start.line)
1042 /*if(initializer.loc.start.line == 1)
1045 f.Printf("\n#line %d \"%s\"\n", initializer.loc.start.line, name);
1052 case expInitializer:
1054 OutputExpression(initializer.exp, f);
1059 static void OutputInitDeclarator(InitDeclarator decl, File f)
1061 OutputDeclarator(decl.declarator, f);
1062 if(decl.initializer)
1065 OutputInitializer(decl.initializer, f);
1069 static void OutputDeclaration(Declaration decl, File f)
1072 char origName[MAX_FILENAME] = "";
1076 case initDeclaration:
1080 //GetWorkingDir(origName, sizeof(origName));
1083 PathCat(origName, outputFile);
1084 ChangeCh(origName, '\\', '/');
1087 if(decl.declarators && decl.declarators->first)
1089 for(d = decl.declarators->first; d; d = d.next)
1092 char name[MAX_FILENAME] = "";
1095 GetLastDirectory(sourceFile, name);
1098 if(yylloc.start.included)
1100 //GetWorkingDir(name, sizeof(name));
1101 PathCat(name, GetIncludeFileFromID(yylloc.start.included));
1105 //GetWorkingDir(name, sizeof(name));
1106 PathCat(name, sourceFile);
1108 ChangeCh(name, '\\', '/');
1110 if(inCompiler && outputLineNumbers && decl.loc.start.line)
1112 /*if(decl.loc.start.line == 1)
1115 f.Printf("\n#line %d \"%s\"\n", decl.loc.start.line, name);
1124 for(spec = decl.specifiers->first; spec; spec = spec.next)
1126 OutputSpecifier(spec, f);
1127 if(spec.next) f.Puts(" ");
1130 if(decl.declarators && decl.declarators->first)
1134 for(d = decl.declarators->first; d; d = d.next)
1136 OutputInitDeclarator(d, f);
1137 if(d.next) f.Puts(", ");
1142 case structDeclaration:
1146 for(spec = decl.specifiers->first; spec; spec = spec.next)
1148 OutputSpecifier(spec, f);
1149 if(spec.next) f.Puts(" ");
1152 if(decl.declarators)
1157 for(d = decl.declarators->first; d; d = d.next)
1159 OutputDeclarator(d, f);
1160 if(d.next) f.Puts(", ");
1166 OutputSpecifier(decl.extStorage, f);
1170 case instDeclaration:
1173 OutputInstance(decl.inst, f);
1176 case defineDeclaration:
1177 return; // Skip semicolon
1181 if(inCompiler && outputLineNumbers && decl.loc.start.line && decl.type == initDeclaration)
1183 f.Printf("\n#line %d \"%s\"\n", outputLine+2, origName);
1188 static FunctionDefinition curFunction;
1190 static void OutputFunction(FunctionDefinition func, File f)
1192 FunctionDefinition oldFunc = curFunction;
1197 for(spec = func.specifiers->first; spec; spec = spec.next)
1199 OutputSpecifier(spec, f);
1200 if(spec.next) f.Puts(" ");
1204 if(func.declarator) OutputDeclarator(func.declarator, f);
1207 if(func.declarations)
1210 for(decl = func.declarations->first; decl; decl = decl.next)
1212 OutputDeclaration(decl, f);
1219 if(inCompiler && memoryGuard)
1221 char name[1024] = "";
1222 Identifier id = GetDeclId(func.declarator);
1224 if(yylloc.start.included)
1226 //GetWorkingDir(name, sizeof(name));
1227 PathCat(name, GetIncludeFileFromID(yylloc.start.included));
1231 //GetWorkingDir(name, sizeof(name));
1232 PathCat(name, sourceFile);
1234 ChangeCh(name, '\\', '/');
1237 f.Printf(" __ecereNameSpace__ecere__com__MemoryGuard_PushLoc(\"%s:%s\");\n", name, id.string);
1240 OutputStatement(func.body, f);
1241 if(inCompiler && memoryGuard)
1243 f.Printf(" __ecereNameSpace__ecere__com__MemoryGuard_PopLoc();\n");
1250 curFunction = oldFunc;
1253 static void OutputMemberInit(MemberInit init, File f)
1255 if(init.identifiers)
1257 if(init.identifiers->count > 1)
1261 for(id = init.identifiers->first; id; id = id.next)
1263 OutputIdentifier(id, f);
1269 else if(init.identifiers->first)
1270 OutputIdentifier(init.identifiers->first, f);
1273 if(init.initializer)
1274 OutputInitializer(init.initializer, f);
1277 static void OutputMembersInit(MembersInit init, File f)
1281 case dataMembersInit:
1284 if(init.dataMembers)
1286 for(member = init.dataMembers->first; member; member = member.next)
1288 OutputMemberInit(member, f);
1289 if(member.next) f.Puts(", ");
1294 case methodMembersInit:
1295 OutputClassFunction(init.function, f);
1300 static void OutputInstance(Instantiation inst, File f)
1303 OutputSpecifier(inst._class, f);
1307 OutputExpression(inst.exp, f);
1309 if(inst.members && inst.members->count > 1)
1314 else if(inst.members)
1321 for(init = inst.members->first; init; init = init.next)
1323 OutputMembersInit(init, f);
1324 if(init.type == dataMembersInit && init.next)
1337 static void OutputClassFunction(ClassFunction func, File f)
1342 for(spec = func.specifiers->first; spec; spec = spec.next)
1344 OutputSpecifier(spec, f);
1345 if(spec.next) f.Puts(" ");
1351 //if(func.class != (void *)-1)
1353 OutputSpecifier(func.class, f);
1356 if(func.declarator) OutputDeclarator(func.declarator, f);
1359 if(func.declarations)
1362 for(decl = func.declarations->first; decl; decl = decl.next)
1364 OutputDeclaration(decl, f);
1371 OutputStatement(func.body, f);
1379 static void OutputClassDef(ClassDef def, File f)
1383 case declarationClassDef:
1386 OutputDeclaration(def.decl, f);
1387 if(def.next && def.next.type != declarationClassDef)
1394 case defaultPropertiesClassDef:
1397 for(init = def.defProperties->first; init; init = init.next)
1399 OutputMemberInit(init, f);
1400 if(init.next) f.Puts(", ");
1406 case functionClassDef:
1407 OutputClassFunction(def.function, f);
1414 static void OutputClass(ClassDefinition _class, File f)
1417 OutputSpecifier(_class._class, f);
1418 if(_class.baseSpecs)
1423 for(spec = _class.baseSpecs->first; spec; spec = spec.next)
1425 OutputSpecifier(spec, f);
1428 if(_class.definitions)
1433 for(def = _class.definitions->first; def; def = def.next)
1435 OutputClassDef(def, f);
1444 public void OutputTree(OldList ast, File f)
1450 for(external = ast.first; external; external = external.next)
1452 switch(external.type)
1454 case functionExternal:
1455 OutputFunction(external.function, f);
1459 case declarationExternal:
1460 OutputDeclaration(external.declaration, f);
1465 OutputClass(external._class, f);
1473 public char * StringFromSpecDecl(OldList specs, Declarator decl)
1476 TypeName typeName { };
1477 File f = TempFile { };
1480 typeName.qualifiers = specs;
1481 typeName.declarator = decl;
1483 OutputTypeName(typeName, f);
1488 string = new char[size + 1];
1490 f.Read(string, 1, size);
1491 string[size] = '\0';
1492 TrimRSpaces(string, string);