Develop and Download Open Source Software

Browse Subversion Repository

Contents of /bl/trunk/bl1.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 5 - (show annotations) (download) (as text)
Sun Sep 30 15:46:36 2007 UTC (16 years, 6 months ago) by aloha
File MIME type: text/x-csrc
File size: 24267 byte(s)
support / (div),% (mod),! (not) operator

1 /*
2 * Buggy Language (BL) GCC toy Frontend.
3 *
4 * Copyright (C) 2007 - WAKATSUKI toshihiro <alohakun _AT_ gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21 /* Some code and ideas were taken from a hello-world gcc frontend
22 * http://svn.gna.org/viewcvs/gsc/branches/hello-world/
23 * and gcc/treelang sample frontend.
24 * */
25
26 #include "config.h"
27 #include "system.h"
28 #include "coretypes.h"
29 #include "tm.h"
30 #include "toplev.h"
31 #include "ggc.h"
32 #include "cgraph.h"
33 #include "tree-gimple.h"
34 #include "langhooks-def.h"
35 #include "langhooks.h"
36
37 static GTY(()) tree signed_and_unsigned_types[MAX_BITS_PER_WORD + 1][2];
38
39 static tree bl_type_for_size(unsigned precision, int unsignedp) {
40 tree t;
41 if(precision <= MAX_BITS_PER_WORD
42 && signed_and_unsigned_types[precision][unsignedp] != 0)
43 return signed_and_unsigned_types[precision][unsignedp];
44 if(unsignedp)
45 t = signed_and_unsigned_types[precision][1] = make_unsigned_type(precision);
46 else
47 t = signed_and_unsigned_types[precision][0] = make_signed_type(precision);
48 return t;
49 }
50
51 static tree bl_type_for_mode(enum machine_mode mode, int unsignedp) {
52 if(SCALAR_INT_MODE_P(mode))
53 return bl_type_for_size(GET_MODE_BITSIZE(mode), unsignedp);
54 else
55 return NULL_TREE;
56 }
57
58 struct binding_level {
59 tree names;
60 tree blocks;
61 tree stmts;
62 struct binding_level *level_chain;
63 };
64
65 static struct binding_level *current_binding_level = NULL;
66 static struct binding_level *global_binding_level = NULL;
67 static struct binding_level clear_binding_level = {NULL, NULL, NULL, NULL };
68
69 static tree* getstmtlist(void) {
70 return &current_binding_level->stmts;
71 }
72
73 /* need for expanding BIND_EXPR */
74 static void insert_block(tree block ATTRIBUTE_UNUSED) {
75 puts("enter insert_block()");
76 gcc_unreachable();
77 }
78
79 static int global_bindings_p(void) {
80 return current_binding_level == global_binding_level ? true : false;
81 }
82
83 static void push_level(void) {
84 struct binding_level *newlevel = xmalloc(sizeof(struct binding_level));
85 *newlevel = clear_binding_level;
86 newlevel->level_chain = current_binding_level;
87 current_binding_level = newlevel;
88 current_binding_level->stmts = alloc_stmt_list ();
89 }
90
91 static tree pushdecl(tree decl) {
92 /* when auto (stack allocated) variable */
93 if(TREE_CODE(decl) == VAR_DECL
94 && !DECL_EXTERNAL(decl)
95 && !TREE_STATIC(decl)
96 && !TREE_PUBLIC(decl)) {
97 TREE_CHAIN(decl) = BLOCK_VARS(current_binding_level->blocks);
98 BLOCK_VARS(current_binding_level->blocks) = decl;
99 tree code = build1(DECL_EXPR, void_type_node, decl);
100 TREE_USED(code) = true;
101 TREE_SIDE_EFFECTS(code) = true;
102 append_to_statement_list(code, getstmtlist());
103 } else
104 append_to_statement_list(decl, getstmtlist());
105 return decl;
106 }
107
108 static tree getdecls(void) {
109 return current_binding_level->names;
110 }
111
112 #define MAX_LINE_SIZE 1024
113 static char current_line[MAX_LINE_SIZE];
114 static unsigned int current_lineno = 1;
115
116 static FILE *bl_input_file;
117
118 static bool bl_init(void) {
119 build_common_tree_nodes(false, false);
120 build_common_tree_nodes_2(false);
121
122 if(!main_input_filename ||
123 main_input_filename[0] == ' ' ||
124 !main_input_filename[0]) {
125 return false;
126 }
127
128 bl_input_file = fopen(main_input_filename, "r");
129
130 if(!bl_input_file) {
131 fprintf (stderr, "Unable to open input file %s\n", main_input_filename);
132 exit (1);
133 }
134
135 if(!fgets(current_line, MAX_LINE_SIZE, bl_input_file)) {
136 fprintf (stderr, "Input file %s is empty\n", main_input_filename);
137 exit (1);
138 }
139
140 /* create toplevel */
141 push_level();
142 global_binding_level = current_binding_level;
143 current_binding_level->level_chain = NULL;
144
145 current_function_decl = NULL_TREE;
146 return true;
147 }
148
149 static void bl_finish(void) {
150 fclose(bl_input_file);
151 }
152
153 #include <ctype.h>
154
155 static tree parse_integer_value(char* string, unsigned int length) {
156
157 long long int val = 0;
158 unsigned int i = 0;
159 unsigned int signed_p = 0;
160 int negative = 1;
161 switch(string[0]) {
162 case (unsigned char)'-':
163 negative = -1;
164 signed_p = i = 1;
165 break;
166
167 case (unsigned char)'+':
168 signed_p = i = 1;
169 break;
170
171 default:
172 break;
173 }
174 for (; i < length; i++)
175 val = val * 10 + string[i] - (unsigned char)'0';
176 val = val * negative;
177 return build_int_cst_wide (signed_p == 1 ?
178 integer_type_node : unsigned_type_node,
179 val & 0xffffffff, (val >> 32) & 0xffffffff);
180 }
181
182 #define BUFSIZE 256
183
184 static tree next_tok(char **string) {
185 static char buf[BUFSIZE];
186 char c;
187 int i = 0;
188
189 while((c = **string) == ' ' || c == '\t' || c == '\r')
190 (*string)++;
191
192 if((c = **string) == '\n' || c == '\0')
193 return NULL_TREE;
194
195 if(**string == '(') {
196 (*string)++;
197 printf("[(] : id\n");
198 return get_identifier("(");
199 }
200
201 if(**string == ')') {
202 (*string)++;
203 printf("[)] : id\n");
204 return get_identifier(")");
205 }
206
207 if(**string == ',') {
208 (*string)++;
209 printf("[,] : id\n");
210 return get_identifier(",");
211 }
212
213 if(**string == '"') {
214 (*string)++;
215 while(**string != '"') {
216 buf[i++] = **string;
217 (*string)++;
218 }
219 (*string)++;
220 buf[i] = '\0';
221 printf("\"%s\"\n", buf);
222 return build_string_literal(strlen(buf) + 1, buf);
223 } else {
224 while((c = **string) != ' '
225 && c != '\n'
226 && c != '\t'
227 && c != '\r'
228 && c != '\0'
229 && c != ','
230 && c != '('
231 && c != ')') {
232 buf[i++] = **string;
233 (*string)++;
234 }
235 }
236 gcc_assert(i < BUFSIZE);
237 buf[i] = '\0';
238 printf("[%s]", buf);
239 if((((c = buf[0]) == '+' || c == '-') && isdigit(buf[1]))
240 || isdigit(c)) {
241 printf(" : integer\n");
242 return parse_integer_value(buf, strlen(buf));
243 } else {
244 printf(" : id\n");
245 return get_identifier(buf);
246 }
247 }
248
249 #undef BUFSIZE
250
251 static tree tok = NULL_TREE;
252 static tree prev_tok = NULL_TREE;
253
254 static tree next(void) {
255 static char *last = current_line;
256
257 if(prev_tok) {
258 tok = prev_tok;
259 prev_tok = NULL;
260 return tok;
261 }
262
263 tok = next_tok(&last);
264
265 if(!tok) {
266 while(fgets(current_line, MAX_LINE_SIZE, bl_input_file)) {
267 current_lineno++;
268 if(current_line[0] == '\n')
269 continue;
270 last = current_line;
271 printf("[EOL] (NULL_TREE)\n");
272 return NULL_TREE;
273 }
274 printf("[EOF] (id_EOF)\n");
275 return get_identifier("EOF");
276 }
277 return tok;
278 }
279
280 static void pushback(void) {
281 prev_tok = tok;
282 }
283
284 static int check(const char *id) {
285 tree t = next();
286 pushback();
287 if(get_identifier(id) == t)
288 return true;
289 else
290 return false;
291 }
292
293 static int next_p(void) {
294 tree t = next();
295 pushback();
296 if(!t || t == get_identifier("EOF"))
297 return false;
298 return true;
299 }
300
301 static void expect(const char *tokname) {
302 tree t = next();
303 if(get_identifier(tokname) != t) {
304 if(TREE_CODE(t) == IDENTIFIER_NODE) {
305 fprintf(stderr, "error : expected %s, but %s\n", tokname,
306 IDENTIFIER_POINTER(t));
307 } else
308 fprintf(stderr, "error : expected %s, but invalid token\n", tokname);
309 exit(1);
310 }
311 }
312
313 static tree lookup_variable(tree name) {
314 struct binding_level* cl = current_binding_level;
315 do {
316 tree names = cl->names;
317 while(names) {
318 if(name == DECL_NAME(names))
319 return names;
320 names = TREE_CHAIN(names);
321 }
322 } while((cl = cl->level_chain));
323 fprintf(stderr, "warning : variable %s can't find in this scope.\n",
324 IDENTIFIER_POINTER(name));
325 return NULL_TREE;
326 }
327
328 static tree eval_value(tree t) {
329 if(TREE_CODE(t) == IDENTIFIER_NODE)
330 return lookup_variable(t);
331 return t;
332 }
333
334 static enum tree_code get_operator(tree t) {
335 if(get_identifier("+") == t)
336 return PLUS_EXPR;
337 else if(get_identifier("-") == t)
338 return MINUS_EXPR;
339 else if(get_identifier("*") == t)
340 return MULT_EXPR;
341 else if(get_identifier("/") == t)
342 return TRUNC_DIV_EXPR;
343 else if(get_identifier("%") == t)
344 return TRUNC_MOD_EXPR;
345 else {
346 fprintf(stderr, "Invalid operator : %s\n", IDENTIFIER_POINTER(t));
347 gcc_unreachable();
348 }
349 }
350
351 static void bl_finalize_function(tree fn_decl) {
352 struct cgraph_node *cgn = cgraph_node(fn_decl);
353 cgraph_finalize_function(fn_decl, false);
354 if(cgn) {
355 // finalize all nested functions recursively
356 for(cgn = cgn->nested; cgn ; cgn = cgn->next_nested) {
357 bl_finalize_function(cgn->decl);
358 }
359 }
360 }
361
362 /*
363 * Program ::= Def*
364 *
365 * // global definition
366 * Def ::= id = Expr ('\n' | EOF) // variable definition
367 * | id = fun (argtype id)* -> rettype '\n' // function definition
368 * Stmt*
369 * nuf ('\n' | EOF)
370 * | id :: argtype* -> rettype '\n' // function prototype
371 *
372 * Stmt ::= return Expr '\n' // return statement
373 * | id <- Expr '\n' // assignment statement
374 * | Def // local definition
375 * | if Expr '\n' // if statement
376 * Stmt*
377 * else
378 * Stmt*
379 * if '\n'
380 *
381 * Expr ::= Term + Term
382 * | Term - Term
383 * | Term
384 *
385 * Term ::= Fact * Fact
386 * | Fact / Fact
387 * | Fact % Fact
388 * | Fact
389 *
390 * Fact ::= id '(' {Expr} (,Expr)* ')' // function call
391 * | '(' Expr ')'
392 * | id // variable
393 * | integer
394 * | ! Fact // not
395 */
396
397 static tree parse_expr(void);
398
399 static tree parse_fact(void) {
400 tree T1 = next();
401
402 // function call : id '(' {Expr} (, Expr)* ')'
403 if(TREE_CODE(T1) == IDENTIFIER_NODE &&
404 T1 != get_identifier("!") &&
405 check("(")) {
406 tree fn_decl = lookup_variable(T1);
407 if(TREE_CODE(fn_decl) != FUNCTION_DECL) {
408 fprintf(stderr, "error : %s is not function type node.\n",
409 IDENTIFIER_POINTER(T1));
410 exit(1);
411 }
412 tree args = NULL_TREE;
413 next();
414 if(!check(")")) {
415 args = tree_cons(NULL_TREE, parse_expr(), NULL_TREE);
416 while(check(",")) {
417 next();
418 args = tree_cons(NULL_TREE, parse_expr(), args);
419 }
420 expect(")");
421 }
422 args = nreverse(args);
423 return build_function_call_expr(fn_decl, args);
424 }
425
426 if(T1 == get_identifier("!")) {
427 tree exp = parse_fact();
428 return build1(BIT_NOT_EXPR,TREE_TYPE(exp),exp);
429 }
430
431 if(T1 == get_identifier("(")) {
432 tree t = parse_expr();
433 expect(")");
434 return t;
435 }
436
437 return eval_value(T1);
438 }
439
440 static tree parse_term(void) {
441 tree T1 = parse_fact();
442
443 while(next_p()) {
444 if(!check("*")
445 && !check("/")
446 && !check("%")) {
447 break;
448 }
449 tree op = next();
450 tree T2 = parse_fact();
451 T1 = fold_build2(get_operator(op), integer_type_node, T1,T2);
452 }
453 return T1;
454 }
455
456 static tree parse_expr(void) {
457 tree T1 = parse_term();
458
459 while(next_p()) {
460 if(!check("+")
461 && !check("-")) {
462 break;
463 }
464 tree op = next();
465 tree T2 = parse_term();
466 T1 = fold_build2(get_operator(op), integer_type_node, T1,T2);
467 }
468 return T1;
469 }
470
471 static tree parse_stmt(void) {
472 tree T1 = next();
473 if(!T1
474 || T1 == get_identifier("nuf")
475 || T1 == get_identifier("else")
476 || T1 == get_identifier("fi")
477 || T1 == get_identifier("EOF"))
478 return NULL_TREE;
479
480 if(get_identifier("if") == T1) {
481 fprintf(stderr, "enter if statement\n");
482 tree exp = parse_expr();
483 tree cond_exp = fold_build2(NE_EXPR, boolean_type_node, exp,
484 fold_build1(CONVERT_EXPR, TREE_TYPE(exp),
485 integer_zero_node));
486
487 // allocate new binding level and stmtlist for then stmts
488 push_level();
489 while(parse_stmt())
490 ;
491 next(); // discard EOL
492 tree then_stmts = *getstmtlist();
493 current_binding_level = current_binding_level->level_chain;
494
495 // allocate new binding level and stmtlist for else stmts
496 push_level();
497 while(parse_stmt())
498 ;
499 next(); // discard EOL
500 tree else_stmts = *getstmtlist();
501 current_binding_level = current_binding_level->level_chain;
502
503 tree cond = build3(COND_EXPR, void_type_node, cond_exp,
504 then_stmts, else_stmts);
505
506 append_to_statement_list(cond, getstmtlist());
507
508 fprintf(stderr, "leave if statement\n");
509
510 TREE_CHAIN(cond) = current_binding_level->names;
511 current_binding_level->names = cond;
512 return cond;
513 }
514
515 if(get_identifier("return") == T1) {
516 fprintf(stderr, "enter return\n");
517 tree value = parse_expr();
518 tree setret = fold_build2(MODIFY_EXPR, integer_type_node,
519 DECL_RESULT(current_function_decl),
520 fold_build1(CONVERT_EXPR, integer_type_node, value));
521 TREE_SIDE_EFFECTS(setret) = true;
522 TREE_USED(setret) = true;
523 tree ret = fold_build1(RETURN_EXPR, integer_type_node, setret);
524 pushdecl(ret);
525 fprintf(stderr, "leave return\n");
526 return ret;
527 }
528 // DEFINITION EXPR
529 if(TREE_CODE(T1) == IDENTIFIER_NODE && check("::")) {
530 next();
531 tree id_TYPE = next();
532 tree parm_types = NULL_TREE;
533 tree result_type = NULL_TREE;
534
535 fprintf(stderr, "enter parse fun protorype\n");
536 while(id_TYPE != get_identifier("->")) {
537 tree parm_type = NULL_TREE;
538 if(id_TYPE == get_identifier("Int")) {
539 parm_type = integer_type_node;
540 }
541 if(id_TYPE == get_identifier("String")) {
542 parm_type = build_pointer_type(char_type_node);
543 }
544 parm_types = tree_cons(NULL_TREE, parm_type, parm_types);
545
546 id_TYPE = next();
547 fprintf(stderr, "type : %s\n", IDENTIFIER_POINTER(id_TYPE));
548 }
549 tree id_RES = next();
550 if(id_RES == get_identifier("Int")) {
551 result_type = integer_type_node;
552 }
553 if(id_RES == get_identifier("Void")) {
554 result_type = void_type_node;
555 }
556 next();
557 tree fn_decl = build_fn_decl(IDENTIFIER_POINTER(T1),
558 build_function_type(result_type, parm_types));
559 DECL_EXTERNAL(fn_decl) = true;
560 TREE_CHAIN(fn_decl) = current_binding_level->names;
561 current_binding_level->names = fn_decl;
562 fprintf(stderr, "leave parse fun protorype\n");
563
564 rest_of_decl_compilation(fn_decl, /* TOPLEVEL */true, /* AT END */false);
565 return fn_decl;
566 }
567
568 if(TREE_CODE(T1) == IDENTIFIER_NODE && check("=")) {
569 next();
570
571 // TYPED VARIABLE DEFINITION BY INITIALIZER (e.g. x = 123)
572 if(!check("fun")) {
573 fprintf(stderr, "enter init\n");
574 tree value = parse_expr();
575 tree var_decl = build_decl(VAR_DECL, T1, TREE_TYPE(value));
576 DECL_EXTERNAL(var_decl) = false;
577 if(global_bindings_p()) {
578 TREE_STATIC(var_decl) = true;
579 TREE_PUBLIC(var_decl) = true;
580 } else {
581 TREE_STATIC(var_decl) = false;
582 TREE_PUBLIC(var_decl) = false;
583 }
584 TREE_USED(var_decl) = true;
585 DECL_INITIAL(var_decl) = value;
586 DECL_CONTEXT(var_decl) = current_function_decl;
587 TREE_CHAIN(var_decl) = current_binding_level->names;
588 current_binding_level->names = var_decl;
589 if(global_bindings_p())
590 rest_of_decl_compilation(var_decl, /* TOP LEVEL */true,
591 /* AT END OF COMPILATION */false);
592 else
593 pushdecl(var_decl);
594 fprintf(stderr, "leave init\n");
595 return var_decl;
596 }
597
598 // FUNCTION DEFINITION
599 if(check("fun")) {
600 next();
601 fprintf(stderr, "enter fun def\n");
602 tree fn_decl = build_fn_decl(IDENTIFIER_POINTER(T1), NULL_TREE);
603 tree arg_types = NULL_TREE;
604 tree result_type = NULL_TREE;
605 tree parms = NULL_TREE;
606 tree id_TYPE = next();
607 tree id_PARM = next();
608 tree id_RES = NULL_TREE;
609 tree block = build_block(NULL_TREE, // variables
610 NULL_TREE, // subblocks
611 NULL_TREE, // supercontext
612 NULL_TREE); // next same level block
613
614 DECL_EXTERNAL(fn_decl) = false;
615 DECL_ARTIFICIAL(fn_decl) = false;
616 DECL_CONTEXT(fn_decl) = current_function_decl;
617 TREE_STATIC(fn_decl) = true;
618 TREE_PUBLIC(fn_decl) = true;
619 if(current_function_decl) {
620 fprintf(stderr, "enter nested function def\n");
621 TREE_STATIC(fn_decl) = false;
622 TREE_PUBLIC(fn_decl) = false;
623 BLOCK_SUPERCONTEXT(block) = current_function_decl;
624 BLOCK_SUBBLOCKS(current_binding_level->blocks) = block;
625 }
626 DECL_INITIAL(fn_decl) = block;
627
628 TREE_CHAIN(fn_decl) = current_binding_level->names;
629 current_binding_level->names = fn_decl;
630
631 // enter new scope (in function)
632 push_level();
633 tree prev_fn_decl = current_function_decl;
634 current_function_decl = fn_decl;
635 current_binding_level->blocks = block;
636
637 while(id_TYPE != get_identifier("->")) {
638 fprintf(stderr, "enter parse fun arg\n");
639 tree parm_type = NULL_TREE;
640 if(id_TYPE == get_identifier("Int")) {
641 parm_type = integer_type_node;
642 }
643 tree parm = build_decl(PARM_DECL, id_PARM, parm_type);
644 DECL_ARG_TYPE(parm) = parm_type;
645 TREE_CHAIN(parm) = parms;
646 parms = parm;
647 DECL_CONTEXT(parm) = fn_decl;
648 TREE_CHAIN(parm) = current_binding_level->names;
649 current_binding_level->names = parm;
650 arg_types = tree_cons(NULL_TREE, parm_type, arg_types);
651
652 id_TYPE = next();
653 id_PARM = next();
654
655 fprintf(stderr, "type : %s, parm : %s\n", IDENTIFIER_POINTER(id_TYPE),
656 IDENTIFIER_POINTER(id_PARM));
657 }
658 gcc_assert(!next());
659 id_RES = id_PARM;
660 if(id_RES == get_identifier("Int")) {
661 result_type = integer_type_node;
662 fprintf(stderr, "parse result : %s\n",
663 IDENTIFIER_POINTER(id_RES));
664 }
665 tree result_decl = build_decl(RESULT_DECL, NULL_TREE, result_type);
666 DECL_CONTEXT(result_decl) = fn_decl;
667 DECL_RESULT(fn_decl) = result_decl;
668
669 DECL_ARGUMENTS(fn_decl) = parms;
670 TREE_TYPE(fn_decl) = build_function_type(result_type, arg_types);
671
672 //debug_tree(fn_decl);
673
674 // parse stmts in fun ... nuf
675 fprintf(stderr, "enter stmts in %s()\n", IDENTIFIER_POINTER(T1));
676 while(parse_stmt())
677 ;
678 next(); // discard EOL or EOF
679 fprintf(stderr, "leave stmts in %s()\n", IDENTIFIER_POINTER(T1));
680
681 DECL_SAVED_TREE(fn_decl) = build3(BIND_EXPR, void_type_node,
682 BLOCK_VARS(block), *(getstmtlist()), block);
683 allocate_struct_function(fn_decl);
684 gimplify_function_tree(fn_decl);
685
686 if(!prev_fn_decl) {
687 fprintf(stderr, "enter finalize %s()\n", IDENTIFIER_POINTER(T1));
688 bl_finalize_function(fn_decl);
689 fprintf(stderr, "leave finalize %s()\n", IDENTIFIER_POINTER(T1));
690 } else
691 fprintf(stderr, "leave nested function def\n");
692 // pop fnction decl
693 current_function_decl = prev_fn_decl;
694 current_binding_level = current_binding_level->level_chain;
695
696 fprintf(stderr, "leave fun def\n");
697 return fn_decl;
698 }
699 }
700 // ASSIGNMENT (e.g. x <- 123)
701 if(TREE_CODE(T1) == IDENTIFIER_NODE &&
702 check("<-")) {
703 next();
704 fprintf(stderr, "enter assign\n");
705 tree value = parse_expr();
706 tree assign = fold_build2(MODIFY_EXPR, integer_type_node, eval_value(T1),
707 fold_build1(CONVERT_EXPR, integer_type_node, value));
708 TREE_SIDE_EFFECTS(assign) = true;
709 TREE_USED(assign) = true;
710 pushdecl(assign);
711 fprintf(stderr, "leave assign\n");
712 return assign;
713 }
714
715 debug_tree(T1);
716 gcc_unreachable();
717 }
718
719 static void bl_parse_file(int debug ATTRIBUTE_UNUSED) {
720
721 while(parse_stmt())
722 ;
723
724 cgraph_finalize_compilation_unit();
725 cgraph_optimize();
726 }
727
728 /************************* from treelang **********************************/
729
730 struct lang_identifier GTY(()) {
731 struct tree_identifier common;
732 };
733
734 union lang_tree_node GTY(( desc("0") )){};
735 struct lang_type GTY(()){};
736 struct lang_decl GTY(()){};
737 struct language_function GTY(()){};
738
739 static tree builtin_function(const char *name, tree type,
740 int function_code, enum built_in_class class,
741 const char *library_name, tree attrs) {
742 tree decl = build_decl(FUNCTION_DECL, get_identifier(name), type);
743 DECL_EXTERNAL(decl) = true;
744 TREE_PUBLIC(decl) = true;
745 if(library_name)
746 SET_DECL_ASSEMBLER_NAME(decl, get_identifier(library_name));
747 pushdecl(decl);
748 DECL_BUILT_IN_CLASS(decl) = class;
749 DECL_FUNCTION_CODE(decl) = function_code;
750 if (attrs)
751 decl_attributes(&decl, attrs, ATTR_FLAG_BUILT_IN);
752 else
753 decl_attributes(&decl, NULL_TREE, 0);
754 return decl;
755 }
756
757 static tree bl_signed_type(tree type_node ATTRIBUTE_UNUSED) {
758 puts("enter bl_signed_type()");
759 gcc_unreachable();
760 }
761
762 static unsigned int bl_init_options (unsigned int argc ATTRIBUTE_UNUSED,
763 const char **argv ATTRIBUTE_UNUSED) {
764 return CL_bl;
765 }
766
767 static int bl_handle_option(size_t scode,
768 const char *arg ATTRIBUTE_UNUSED,
769 int value ATTRIBUTE_UNUSED) {
770 enum opt_code code = (enum opt_code) scode;
771
772 if(code == OPT_bye) {
773 return 1;
774 }
775 return 0;
776 }
777
778 tree convert(tree type ATTRIBUTE_UNUSED, tree expr ATTRIBUTE_UNUSED) {
779 puts("enter convert()");
780 gcc_unreachable();
781 }
782
783 static bool bl_mark_addressable(tree exp) {
784 switch (TREE_CODE(exp)){
785 case STRING_CST:
786 break;
787 case FUNCTION_DECL:
788 TREE_ADDRESSABLE(exp) = true;
789 break;
790 case ARRAY_REF:
791 return bl_mark_addressable(TREE_OPERAND(exp, 0));
792 break;
793 default:
794 puts("enter bl_marK_adressable()");
795 gcc_unreachable();
796 break;
797 }
798 return true;
799 }
800
801 static tree bl_unsigned_type(tree type_node ATTRIBUTE_UNUSED) {
802 puts("enter bl_unsigned_type()");
803 gcc_unreachable();
804 }
805
806 static tree bl_signed_or_unsigned_type(int unsignedp ATTRIBUTE_UNUSED,
807 tree type ATTRIBUTE_UNUSED) {
808 puts("enter bl_signed_or_unsigned_type()");
809 gcc_unreachable();
810 }
811
812 /*****************************************************************************/
813
814 #undef LANG_HOOKS_NAME
815 #define LANG_HOOKS_NAME "bl"
816
817 #undef LANG_HOOKS_INIT
818 #define LANG_HOOKS_INIT bl_init
819
820 #undef LANG_HOOKS_INIT_OPTIONS
821 #define LANG_HOOKS_INIT_OPTIONS bl_init_options
822
823 #undef LANG_HOOKS_FINISH
824 #define LANG_HOOKS_FINISH bl_finish
825
826 #undef LANG_HOOKS_HANDLE_OPTION
827 #define LANG_HOOKS_HANDLE_OPTION bl_handle_option
828
829 #undef LANG_HOOKS_PARSE_FILE
830 #define LANG_HOOKS_PARSE_FILE bl_parse_file
831
832 #undef LANG_HOOKS_MARK_ADDRESSABLE
833 #define LANG_HOOKS_MARK_ADDRESSABLE bl_mark_addressable
834
835 #undef LANG_HOOKS_TYPE_FOR_MODE
836 #define LANG_HOOKS_TYPE_FOR_MODE bl_type_for_mode
837
838 #undef LANG_HOOKS_TYPE_FOR_SIZE
839 #define LANG_HOOKS_TYPE_FOR_SIZE bl_type_for_size
840
841 #undef LANG_HOOKS_UNSIGNED_TYPE
842 #define LANG_HOOKS_UNSIGNED_TYPE bl_unsigned_type
843
844 #undef LANG_HOOKS_SIGNED_TYPE
845 #define LANG_HOOKS_SIGNED_TYPE bl_signed_type
846
847 #undef LANG_HOOKS_SIGNED_OR_UNSIGNED_TYPE
848 #define LANG_HOOKS_SIGNED_OR_UNSIGNED_TYPE bl_signed_or_unsigned_type
849
850 #undef LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION
851 #define LANG_HOOKS_CALLGRAPH_EXPAND_FUNCTION tree_rest_of_compilation
852
853 const struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
854
855 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE,
856 const enum tree_code_class tree_code_type[] = {
857 #include "tree.def"
858 tcc_exceptional
859 };
860 #undef DEFTREECODE
861
862 #define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH,
863 const unsigned char tree_code_length[] = {
864 #include "tree.def"
865 0
866 };
867 #undef DEFTREECODE
868
869 #define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME,
870 const char *const tree_code_name[] = {
871 #include "tree.def"
872 "@@dummy"
873 };
874 #undef DEFTREECODE
875
876 #include "gt-bl-bl1.h"
877 #include "gtype-bl.h"

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26