source: translator/CodeGen/CodeGenerator2.cc @ d11f789

ADTaaron-thesisarm-ehast-experimentalcleanup-dtorsctordeferred_resndemanglerenumforall-pointer-decaygc_noraiijacob/cs343-translationjenkins-sandboxmemorynew-astnew-ast-unique-exprnew-envno_listpersistent-indexerpthread-emulationqualifiedEnumresolv-newstringwith_gc
Last change on this file since d11f789 was 51b7345, checked in by Peter A. Buhr <pabuhr@…>, 10 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.