source: translator/CodeGen/CodeGenerator2.cc@ c8ffe20b

ADT aaron-thesis arm-eh ast-experimental cleanup-dtors ctor deferred_resn demangler enum forall-pointer-decay gc_noraii jacob/cs343-translation jenkins-sandbox memory new-ast new-ast-unique-expr new-env no_list persistent-indexer pthread-emulation qualifiedEnum resolv-new string with_gc
Last change on this file since c8ffe20b was 51b73452, checked in by Peter A. Buhr <pabuhr@…>, 11 years ago

initial commit

  • Property mode set to 100644
File size: 18.7 KB
Line 
1#include <algorithm>
2#include <iostream>
3#include <cassert>
4#include <list>
5
6#include "SynTree/Type.h"
7#include "SynTree/Declaration.h"
8#include "SynTree/Statement.h"
9#include "SynTree/Expression.h"
10#include "SynTree/Initializer.h"
11
12#include "utility.h"
13#include "UnimplementedError.h"
14
15#include "CodeGenerator2.h"
16#include "OperatorTable.h"
17#include "GenType.h"
18
19using namespace std;
20
21namespace CodeGen {
22
23 int CodeGenerator2::tabsize = 4;
24
25 CodeGenerator2::CodeGenerator2( std::ostream &os ) : cur_indent( 0 ), insideFunction( false ), before(os), after() { }
26
27 CodeGenerator2::CodeGenerator2(std::ostream &os, std::string init, int indent, bool infunp )
28 : cur_indent( indent ), insideFunction( infunp ), before(os), after()
29 {
30 //before << std::string( init );
31 }
32
33 CodeGenerator2::CodeGenerator2(std::ostream &os, char *init, int indent, bool infunp )
34 : cur_indent( indent ), insideFunction( infunp ), before(os), after()
35 {
36 //before << std::string( init );
37 }
38
39 CodeGenerator2::~CodeGenerator2() {
40 after.freeze( false );
41 }
42
43 string
44 mangleName( DeclarationWithType *decl ) {
45 if( decl->get_mangleName() != "" ) {
46 return decl->get_mangleName();
47 } else {
48 return decl->get_name();
49 }
50 }
51
52 //*** Declarations
53 void CodeGenerator2::visit(FunctionDecl *functionDecl){
54
55 handleStorageClass( functionDecl );
56 before << genType( functionDecl->get_functionType(), mangleName( functionDecl ) );
57
58 // how to get this to the Functype?
59 std::list< Declaration * > olds = functionDecl->get_oldDecls();
60 if( ! olds.empty() ) {
61 before << " /* function has old declaration */";
62 }
63
64 // acceptAll( functionDecl->get_oldDecls(), *this );
65 if( functionDecl->get_statements() ) {
66 functionDecl->get_statements()->accept(*this);
67 }
68 }
69
70 void CodeGenerator2::visit(ObjectDecl *objectDecl){
71
72 handleStorageClass( objectDecl );
73 before << genType( objectDecl->get_type(), mangleName( objectDecl ) );
74
75 if( objectDecl->get_init() ) {
76 before << " = ";
77 objectDecl->get_init()->accept( *this );
78 }
79 if( objectDecl->get_bitfieldWidth() ) {
80 before << ":";
81 objectDecl->get_bitfieldWidth()->accept( *this );
82 }
83 }
84
85 void
86 CodeGenerator2::handleAggregate( AggregateDecl *aggDecl )
87 {
88 if ( aggDecl->get_name() != "" )
89 before << aggDecl->get_name();
90
91 std::list< Declaration * > &memb = aggDecl->get_members();
92
93 if( ! memb.empty() ){
94 before << endl << string(cur_indent, ' ') << "{" << endl;
95
96 cur_indent += CodeGenerator2::tabsize;
97 for(std::list< Declaration* >::iterator i = memb.begin(); i != memb.end(); i++){
98 before << string(cur_indent, ' ');
99 (*i)->accept(*this);
100 before << ";" << endl;
101 }
102
103 cur_indent -= CodeGenerator2::tabsize;
104
105 before << string(cur_indent, ' ') << "}";
106 }
107 }
108
109 void CodeGenerator2::visit( StructDecl *structDecl ){
110 before << "struct ";
111 handleAggregate( structDecl );
112 }
113
114 void
115 CodeGenerator2::visit(UnionDecl *aggregateDecl)
116 {
117 before << "union ";
118 handleAggregate( aggregateDecl );
119 }
120
121 void
122 CodeGenerator2::visit(EnumDecl *aggDecl)
123 {
124 before << "enum ";
125
126 if ( aggDecl->get_name() != "" )
127 before << aggDecl->get_name();
128
129 std::list< Declaration* > &memb = aggDecl->get_members();
130
131 if( ! memb.empty() ){
132 before << endl << "{" << endl;
133
134 cur_indent += CodeGenerator2::tabsize;
135 for(std::list< Declaration* >::iterator i = memb.begin(); i != memb.end(); i++){
136 ObjectDecl *obj = dynamic_cast< ObjectDecl* >( *i );
137 assert( obj );
138 before << string(cur_indent, ' ') << mangleName( obj );
139 if( obj->get_init() ) {
140 before << " = ";
141 obj->get_init()->accept(*this);
142 }
143 before << "," << endl;
144 }
145
146 cur_indent -= CodeGenerator2::tabsize;
147
148 before << "}" << endl;
149 }
150 }
151
152 void
153 CodeGenerator2::visit(ContextDecl *aggregateDecl)
154 {
155 }
156
157 void
158 CodeGenerator2::visit(TypedefDecl *typeDecl)
159 {
160 before << "typedef ";
161 before << genType( typeDecl->get_base(), typeDecl->get_name() );
162 }
163
164 void
165 CodeGenerator2::visit(TypeDecl *typeDecl)
166 {
167 // really, we should mutate this into something that isn't a TypeDecl
168 // but that requires large-scale changes, still to be done
169 before << "extern unsigned long " << typeDecl->get_name();
170 if( typeDecl->get_base() ) {
171 before << " = sizeof( " << genType( typeDecl->get_base(), "" ) << " )";
172 }
173 }
174
175 //*** Initializer
176 void
177 CodeGenerator2::visit(SingleInit *init)
178 {
179 init->get_value()->accept( *this );
180 }
181
182 void
183 CodeGenerator2::visit(ListInit *init)
184 {
185 before << "{ ";
186 genCommaList( init->begin_initializers(), init->end_initializers() );
187 before << " }";
188 }
189
190 //*** Constant
191 void CodeGenerator2::visit(Constant *constant) {
192 before << constant->get_value() ;
193 }
194
195 //*** Expressions
196 void
197 CodeGenerator2::visit(ApplicationExpr *applicationExpr)
198 {
199 if( VariableExpr *varExpr = dynamic_cast< VariableExpr* >( applicationExpr->get_function() ) ) {
200 OperatorInfo opInfo;
201 if( varExpr->get_var()->get_linkage() == LinkageSpec::Intrinsic && operatorLookup( varExpr->get_var()->get_name(), opInfo ) ) {
202 std::list< Expression* >::iterator arg = applicationExpr->get_args().begin();
203 switch( opInfo.type ) {
204 case OT_PREFIXASSIGN:
205 case OT_POSTFIXASSIGN:
206 case OT_INFIXASSIGN:
207 {
208 assert( arg != applicationExpr->get_args().end() );
209 if( AddressExpr *addrExpr = dynamic_cast< AddressExpr * >( *arg ) ) {
210
211 *arg = addrExpr->get_arg();
212 } else {
213 UntypedExpr *newExpr = new UntypedExpr( new NameExpr( "*?" ) );
214 newExpr->get_args().push_back( *arg );
215 *arg = newExpr;
216 }
217 break;
218 }
219
220 default:
221 // do nothing
222 ;
223 }
224
225 switch( opInfo.type ) {
226 case OT_INDEX:
227 assert( applicationExpr->get_args().size() == 2 );
228 (*arg++)->accept( *this );
229 before << "[";
230 (*arg)->accept( *this );
231 before << "]";
232 break;
233
234 case OT_CALL:
235 // there are no intrinsic definitions of the function call operator
236 assert( false );
237 break;
238
239 case OT_PREFIX:
240 case OT_PREFIXASSIGN:
241 assert( applicationExpr->get_args().size() == 1 );
242 before << "(";
243 before << opInfo.symbol;
244 (*arg)->accept( *this );
245 before << ")";
246 break;
247
248 case OT_POSTFIX:
249 case OT_POSTFIXASSIGN:
250 assert( applicationExpr->get_args().size() == 1 );
251 (*arg)->accept( *this );
252 before << opInfo.symbol;
253 break;
254
255 case OT_INFIX:
256 case OT_INFIXASSIGN:
257 assert( applicationExpr->get_args().size() == 2 );
258 before << "(";
259 (*arg++)->accept( *this );
260 before << opInfo.symbol;
261 (*arg)->accept( *this );
262 before << ")";
263 break;
264
265 case OT_CONSTANT:
266 // there are no intrinsic definitions of 0 or 1 as functions
267 assert( false );
268 }
269 } else {
270 varExpr->accept( *this );
271 before << "(";
272 genCommaList( applicationExpr->get_args().begin(), applicationExpr->get_args().end() );
273 before << ")";
274 }
275 } else {
276 applicationExpr->get_function()->accept( *this );
277 before << "(";
278 genCommaList( applicationExpr->get_args().begin(), applicationExpr->get_args().end() );
279 before << ")";
280 }
281 }
282
283 void
284 CodeGenerator2::visit(UntypedExpr *untypedExpr)
285 {
286 if( NameExpr *nameExpr = dynamic_cast< NameExpr* >( untypedExpr->get_function() ) ) {
287 OperatorInfo opInfo;
288 if( operatorLookup( nameExpr->get_name(), opInfo ) ) {
289 std::list< Expression* >::iterator arg = untypedExpr->get_args().begin();
290 switch( opInfo.type ) {
291 case OT_INDEX:
292 assert( untypedExpr->get_args().size() == 2 );
293 (*arg++)->accept( *this );
294 before << "[";
295 (*arg)->accept( *this );
296 before << "]";
297 break;
298
299 case OT_CALL:
300 assert( false );
301 break;
302
303 case OT_PREFIX:
304 case OT_PREFIXASSIGN:
305 assert( untypedExpr->get_args().size() == 1 );
306 before << "(";
307 before << opInfo.symbol;
308 (*arg)->accept( *this );
309 before << ")";
310 break;
311
312 case OT_POSTFIX:
313 case OT_POSTFIXASSIGN:
314 assert( untypedExpr->get_args().size() == 1 );
315 (*arg)->accept( *this );
316 before << opInfo.symbol;
317 break;
318
319 case OT_INFIX:
320 case OT_INFIXASSIGN:
321 assert( untypedExpr->get_args().size() == 2 );
322 before << "(";
323 (*arg++)->accept( *this );
324 before << opInfo.symbol;
325 (*arg)->accept( *this );
326 before << ")";
327 break;
328
329 case OT_CONSTANT:
330 // there are no intrinsic definitions of 0 or 1 as functions
331 assert( false );
332 }
333 } else {
334 nameExpr->accept( *this );
335 before << "(";
336 genCommaList( untypedExpr->get_args().begin(), untypedExpr->get_args().end() );
337 before << ")";
338 }
339 } else {
340 untypedExpr->get_function()->accept( *this );
341 before << "(";
342 genCommaList( untypedExpr->get_args().begin(), untypedExpr->get_args().end() );
343 before << ")";
344 }
345 }
346
347 void
348 CodeGenerator2::visit(NameExpr *nameExpr)
349 {
350 OperatorInfo opInfo;
351 if( operatorLookup( nameExpr->get_name(), opInfo ) ) {
352 assert( opInfo.type == OT_CONSTANT );
353 before << opInfo.symbol;
354 } else {
355 before << nameExpr->get_name();
356 }
357 }
358
359 void
360 CodeGenerator2::visit(AddressExpr *addressExpr)
361 {
362 before << "(&";
363 // this hack makes sure that we don't convert "constant_zero" to "0" if we're taking its address
364 if( VariableExpr *variableExpr = dynamic_cast< VariableExpr* >( addressExpr->get_arg() ) ) {
365 before << mangleName( variableExpr->get_var() );
366 } else {
367 addressExpr->get_arg()->accept( *this );
368 }
369 before << ")";
370 }
371
372 void
373 CodeGenerator2::visit(CastExpr *castExpr)
374 {
375 before << "((";
376 if( castExpr->get_results().empty() ) {
377 before << "void" ;
378 } else {
379 before << genType( castExpr->get_results().front(), "" );
380 }
381 before << ")";
382 castExpr->get_arg()->accept( *this );
383 before << ")";
384 }
385
386 void
387 CodeGenerator2::visit(UntypedMemberExpr *memberExpr)
388 {
389 assert( false );
390 }
391
392 void
393 CodeGenerator2::visit(MemberExpr *memberExpr)
394 {
395 memberExpr->get_aggregate()->accept( *this );
396 before << "." << mangleName( memberExpr->get_member() );
397 }
398
399 void
400 CodeGenerator2::visit(VariableExpr *variableExpr)
401 {
402 OperatorInfo opInfo;
403 if( variableExpr->get_var()->get_linkage() == LinkageSpec::Intrinsic && operatorLookup( variableExpr->get_var()->get_name(), opInfo ) && opInfo.type == OT_CONSTANT ) {
404 before << opInfo.symbol;
405 } else {
406 before << mangleName( variableExpr->get_var() );
407 }
408 }
409
410 void
411 CodeGenerator2::visit(ConstantExpr *constantExpr)
412 {
413 assert( constantExpr->get_constant() );
414 constantExpr->get_constant()->accept( *this );
415 }
416
417 void
418 CodeGenerator2::visit(SizeofExpr *sizeofExpr)
419 {
420 before << "sizeof(";
421 if( sizeofExpr->get_isType() ) {
422 before << genType( sizeofExpr->get_type(), "" );
423 } else {
424 sizeofExpr->get_expr()->accept( *this );
425 }
426 before << ")";
427 }
428
429 void
430 CodeGenerator2::visit(LogicalExpr *logicalExpr)
431 {
432 before << "(";
433 logicalExpr->get_arg1()->accept( *this );
434 if( logicalExpr->get_isAnd() ) {
435 before << " && ";
436 } else {
437 before << " || ";
438 }
439 logicalExpr->get_arg2()->accept( *this );
440 before << ")";
441 }
442
443 void
444 CodeGenerator2::visit(ConditionalExpr *conditionalExpr)
445 {
446 before << "(";
447 conditionalExpr->get_arg1()->accept( *this );
448 before << " ? ";
449 conditionalExpr->get_arg2()->accept( *this );
450 before << " : ";
451 conditionalExpr->get_arg3()->accept( *this );
452 before << ")";
453 }
454
455 void
456 CodeGenerator2::visit(CommaExpr *commaExpr)
457 {
458 before << "(";
459 commaExpr->get_arg1()->accept( *this );
460 before << " , ";
461 commaExpr->get_arg2()->accept( *this );
462 before << ")";
463 }
464
465 void
466 CodeGenerator2::visit(TupleExpr *tupleExpr)
467 {
468 }
469
470 void
471 CodeGenerator2::visit(TypeExpr *typeExpr)
472 {
473 }
474
475
476 //*** Statements
477 void CodeGenerator2::visit(CompoundStmt *compoundStmt){
478 std::list<Statement*> ks = compoundStmt->get_kids();
479
480 before << endl << string(cur_indent,' ') << "{" << endl;
481
482 cur_indent += CodeGenerator2::tabsize;
483
484 for(std::list<Statement *>::iterator i = ks.begin(); i != ks.end(); i++){
485 before << string(cur_indent, ' ') << printLabels( (*i)->get_labels() ) ;
486 (*i)->accept(*this);
487 shift_left();
488 before << endl;
489 }
490 cur_indent -= CodeGenerator2::tabsize;
491
492 before << string(cur_indent,' ') << "}" << endl;
493 }
494
495 void CodeGenerator2::visit(ExprStmt *exprStmt){
496 if(exprStmt != 0){
497 exprStmt->get_expr()->accept( *this );
498 shift_left();
499 before << ";" ;
500 }
501 }
502
503 void CodeGenerator2::visit(IfStmt *ifStmt){
504 before << "if (";
505 ifStmt->get_condition()->accept(*this);
506 after << ")" << endl ;
507 shift_left();
508
509 cur_indent += CodeGenerator2::tabsize;
510 before << string(cur_indent, ' ');
511 ifStmt->get_thenPart()->accept(*this);
512 cur_indent -= CodeGenerator2::tabsize;
513 shift_left(); before << endl;
514
515 if(ifStmt->get_elsePart() != 0){
516 before << string(cur_indent, ' ') << " else " << endl ;
517
518 cur_indent += CodeGenerator2::tabsize;
519 ifStmt->get_elsePart()->accept(*this);
520 cur_indent -= CodeGenerator2::tabsize;
521 }
522 }
523
524 void CodeGenerator2::visit(SwitchStmt *switchStmt){
525 //before << /* "\r" << */ string(cur_indent, ' ') << CodeGenerator2::printLabels( switchStmt->get_labels() )
526 before << "switch (" ;
527 switchStmt->get_condition()->accept(*this);
528 after << ")" << std::endl ;
529 shift_left();
530
531 before << string(cur_indent, ' ') << "{" << std::endl;
532 cur_indent += CodeGenerator2::tabsize;
533
534 std::list< Statement * > stmts = switchStmt->get_branches();
535 bool lastBreak = false;
536
537 // horrible, horrible hack
538 if( dynamic_cast<BranchStmt *>(stmts.back()) != 0 ) {
539 lastBreak = true;
540 stmts.pop_back();
541 }
542 acceptAll(stmts, *this );
543 if ( lastBreak ) {
544 Statement *st = switchStmt->get_branches().back();
545 before << CodeGenerator2::printLabels(st->get_labels());
546 st->accept(*this);
547 }
548
549 cur_indent -= CodeGenerator2::tabsize;
550
551 before << /* "\r" << */ string(cur_indent, ' ') << "}" << endl ;
552 }
553
554 void CodeGenerator2::visit(CaseStmt *caseStmt){
555 before << string(cur_indent, ' ');
556 if (caseStmt->isDefault())
557 before << "default " ;
558 else {
559 before << "case " ;
560 caseStmt->get_condition()->accept(*this);
561 }
562 after << ":" << std::endl ;
563 shift_left();
564
565 std::list<Statement *> sts = caseStmt->get_statements();
566
567 cur_indent += CodeGenerator2::tabsize;
568 for(std::list<Statement *>::iterator i = sts.begin(); i != sts.end(); i++){
569 before << /* "\r" << */ string(cur_indent, ' ') << printLabels( (*i)->get_labels() ) ;
570 (*i)->accept(*this);
571 shift_left();
572 before << ";" << endl;
573 }
574 cur_indent -= CodeGenerator2::tabsize;
575 }
576
577 void CodeGenerator2::visit(BranchStmt *branchStmt){
578 switch(branchStmt->get_type()){
579 case BranchStmt::Goto:
580 if( ! branchStmt->get_target().empty() )
581 before << "goto " << branchStmt->get_target();
582 else {
583 if ( branchStmt->get_computedTarget() != 0 ) {
584 before << "goto *";
585 branchStmt->get_computedTarget()->accept(*this);
586 }
587 }
588 break;
589 case BranchStmt::Break:
590 before << "break";
591 break;
592 case BranchStmt::Continue:
593 before << "continue";
594 break;
595 }
596 before << ";";
597 }
598
599
600 void CodeGenerator2::visit(ReturnStmt *returnStmt){
601 before << "return ";
602
603 // xxx -- check for null expression;
604 if ( returnStmt->get_expr() ){
605 returnStmt->get_expr()->accept( *this );
606 }
607 after << ";";
608 }
609
610 void CodeGenerator2::visit(WhileStmt *whileStmt){
611 if( whileStmt->get_isDoWhile() )
612 before << "do" ;
613 else {
614 before << "while(" ;
615 whileStmt->get_condition()->accept(*this);
616 after << ")";
617 }
618 after << "{" << endl ;
619 shift_left();
620
621 whileStmt->get_body()->accept( *this );
622
623 before << /* "\r" << */ string(cur_indent, ' ') << "}" ;
624
625 if( whileStmt->get_isDoWhile() ){
626 before << " while(" ;
627 whileStmt->get_condition()->accept(*this);
628 after << ");";
629 }
630
631 after << endl;
632 }
633
634 void CodeGenerator2::visit(ForStmt *forStmt){
635 before << "for (";
636
637 if( forStmt->get_initialization() != 0 )
638 forStmt->get_initialization()->accept( *this );
639 else
640 before << ";";
641 shift_left();
642
643 if( forStmt->get_condition() != 0 )
644 forStmt->get_condition()->accept( *this );
645 shift_left(); before << ";";
646
647 if( forStmt->get_increment() != 0 )
648 forStmt->get_increment()->accept( *this );
649 shift_left(); before << ")" << endl;
650
651 if( forStmt->get_body() != 0 ){
652 cur_indent += CodeGenerator2::tabsize;
653 before << string(cur_indent, ' ') << CodeGenerator2::printLabels( forStmt->get_body()->get_labels() );
654 forStmt->get_body()->accept( *this );
655 cur_indent -= CodeGenerator2::tabsize;
656 }
657 }
658
659 void CodeGenerator2::visit(NullStmt *nullStmt){
660 //before << /* "\r" << */ string(cur_indent, ' ') << CodeGenerator2::printLabels( nullStmt->get_labels() );
661 before << "/* null statement */ ;";
662 }
663
664 void CodeGenerator2::visit(DeclStmt *declStmt){
665 declStmt->get_decl()->accept( *this );
666
667 if( doSemicolon( declStmt->get_decl() ) ) {
668 after << ";";
669 }
670 shift_left();
671 }
672
673 std::string CodeGenerator2::printLabels ( std::list< Label > &l ) {
674 std::string str("");
675 l.unique();
676
677 for( std::list< Label >::iterator i = l.begin(); i != l.end(); i++)
678 str += *i + ": ";
679
680 return str;
681 }
682
683 void CodeGenerator2::shift_left(){
684 before << string(after.str(), after.pcount());
685
686 after.freeze( false );
687 after.seekp(0);
688 }
689
690 void
691 CodeGenerator2::handleStorageClass( Declaration *decl )
692 {
693 switch( decl->get_storageClass() ) {
694 case Declaration::NoStorageClass:
695 break;
696 case Declaration::Auto:
697 break;
698 case Declaration::Static:
699 before << "static ";
700 break;
701 case Declaration::Extern:
702 before << "extern ";
703 break;
704 case Declaration::Register:
705 before << "register ";
706 break;
707 case Declaration::Fortran:
708 before << "fortran ";
709 break;
710 }
711 }
712
713} // namespace CodeGen
714
715
Note: See TracBrowser for help on using the repository browser.