source: translator/CodeGen/CodeGenerator2.cc@ 643a2e1

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 643a2e1 was 6c3744e, checked in by Peter A. Buhr <pabuhr@…>, 11 years ago

add list initializer, formatting changes

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