source: translator/CodeGen/CodeGenerator2.cc @ df23c8f

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

add list initializer, formatting changes

  • Property mode set to 100644
File size: 17.8 KB
RevLine 
[51b7345]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 {
[17cd4eb]22    int CodeGenerator2::tabsize = 4;
[51b7345]23
[17cd4eb]24    CodeGenerator2::CodeGenerator2( std::ostream &os ) : cur_indent( 0 ), insideFunction( false ), before( os ), after() { }
[51b7345]25
[17cd4eb]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 );
[51b7345]30    }
31
[17cd4eb]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 );
[51b7345]36    }
37
[17cd4eb]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
[51b7345]61    }
62
[17cd4eb]63    void CodeGenerator2::visit( ObjectDecl *objectDecl ) {
64        handleStorageClass( objectDecl );
65        before << genType( objectDecl->get_type(), mangleName( objectDecl ) );
[51b7345]66   
[17cd4eb]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
[51b7345]75    }
76
[17cd4eb]77    void CodeGenerator2::handleAggregate( AggregateDecl *aggDecl ) {
78        if ( aggDecl->get_name() != "" )
79            before << aggDecl->get_name();
[51b7345]80   
[17cd4eb]81        std::list< Declaration * > &memb = aggDecl->get_members();
[51b7345]82
[17cd4eb]83        if ( ! memb.empty() ) {
84            before << endl << string( cur_indent, ' ' ) << "{" << endl;
[51b7345]85
[17cd4eb]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            }
[51b7345]92
[17cd4eb]93            cur_indent -= CodeGenerator2::tabsize; 
[51b7345]94
[17cd4eb]95            before << string( cur_indent, ' ' ) << "}";
96        } // if
[51b7345]97    }
98
[17cd4eb]99    void CodeGenerator2::visit( StructDecl *structDecl ) {
100        before << "struct ";
101        handleAggregate( structDecl );
102    }
[51b7345]103
[17cd4eb]104    void CodeGenerator2::visit( UnionDecl *aggregateDecl ) {
105        before << "union ";
106        handleAggregate( aggregateDecl );
107    }
[51b7345]108 
[17cd4eb]109    void CodeGenerator2::visit( EnumDecl *aggDecl ) {
110        before << "enum ";
[51b7345]111
[17cd4eb]112        if ( aggDecl->get_name() != "" )
113            before << aggDecl->get_name();
[51b7345]114   
[17cd4eb]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
[51b7345]136    }
137 
[17cd4eb]138    void CodeGenerator2::visit( ContextDecl *aggregateDecl ) {}
[51b7345]139 
[17cd4eb]140    void CodeGenerator2::visit( TypedefDecl *typeDecl ) {
141        before << "typedef ";
142        before << genType( typeDecl->get_base(), typeDecl->get_name() );
143    }
[51b7345]144 
[17cd4eb]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 ) ) {
[51b7345]181           
[17cd4eb]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                    }
[51b7345]190         
[17cd4eb]191                  default:
192                    // do nothing
193                    ;
194                }
[51b7345]195       
[17cd4eb]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;
[51b7345]204         
[17cd4eb]205                  case OT_CALL:
206                    // there are no intrinsic definitions of the function call operator
207                    assert( false );
208                    break;
[51b7345]209         
[17cd4eb]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;
[51b7345]218         
[17cd4eb]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;
[51b7345]235         
[17cd4eb]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    }
[51b7345]253 
[17cd4eb]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;
[51b7345]267         
[17cd4eb]268                  case OT_CALL:
269                    assert( false );
270                    break;
[51b7345]271         
[17cd4eb]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;
[51b7345]280         
[17cd4eb]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;
[51b7345]287 
[17cd4eb]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;
[51b7345]297         
[17cd4eb]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    }
[51b7345]315 
[17cd4eb]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    }
[51b7345]325 
[17cd4eb]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    }
[51b7345]348 
[17cd4eb]349    void CodeGenerator2::visit( UntypedMemberExpr *memberExpr ) {
350        assert( false );
351    }
[51b7345]352 
[17cd4eb]353    void CodeGenerator2::visit( MemberExpr *memberExpr ) {
354        memberExpr->get_aggregate()->accept( *this );
355        before << "." << mangleName( memberExpr->get_member() );
356    }
[51b7345]357 
[17cd4eb]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    }
[51b7345]366 
[17cd4eb]367    void CodeGenerator2::visit( ConstantExpr *constantExpr ) {
368        assert( constantExpr->get_constant() );
369        constantExpr->get_constant()->accept( *this );
370    }
[51b7345]371 
[17cd4eb]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    }
[51b7345]381 
[17cd4eb]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    }
[51b7345]393 
[17cd4eb]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    }
[51b7345]403 
[17cd4eb]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    }
[51b7345]411 
[17cd4eb]412    void CodeGenerator2::visit( TupleExpr *tupleExpr ) {}
[51b7345]413 
[17cd4eb]414    void CodeGenerator2::visit( TypeExpr *typeExpr ) {}
[51b7345]415 
416 
[17cd4eb]417    //*** Statements
418    void CodeGenerator2::visit( CompoundStmt *compoundStmt ) {
419        std::list<Statement*> ks = compoundStmt->get_kids();
[51b7345]420
[17cd4eb]421        before << endl << string( cur_indent, ' ' ) << "{" << endl;
[51b7345]422
[17cd4eb]423        cur_indent += CodeGenerator2::tabsize; 
[51b7345]424
[17cd4eb]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; 
[51b7345]432
[17cd4eb]433        before << string( cur_indent, ' ' ) << "}" << endl;
[51b7345]434    }
435
[17cd4eb]436    void CodeGenerator2::visit( ExprStmt *exprStmt ) {
437        if ( exprStmt != 0 ) {
438            exprStmt->get_expr()->accept( *this );
439            shift_left();
440            before << ";" ;
441        } // if
[51b7345]442    }
443
[17cd4eb]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    }
[51b7345]464
[17cd4eb]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
[6c3744e]479        if ( dynamic_cast<BranchStmt *>( stmts.back() ) != 0 ) {
[17cd4eb]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());
[6c3744e]487            st->accept( *this );
[17cd4eb]488        } // if
489     
490        cur_indent -= CodeGenerator2::tabsize; 
[51b7345]491
[17cd4eb]492        before << /* "\r" << */ string( cur_indent, ' ' ) << "}" << endl ;
[51b7345]493    }
[17cd4eb]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;
[51b7345]516    }
[17cd4eb]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 *";
[6c3744e]526                    branchStmt->get_computedTarget()->accept( *this );
[17cd4eb]527                } // if
528            } // if
529            break;
530          case BranchStmt::Break:
531            before << "break";
532            break;
533          case BranchStmt::Continue:
534            before << "continue";
535            break;
[51b7345]536        }
[17cd4eb]537        before << ";";
[51b7345]538    }
539
540
[17cd4eb]541    void CodeGenerator2::visit( ReturnStmt *returnStmt ) {
542        before << "return ";
[51b7345]543
[17cd4eb]544        // xxx -- check for null expression;
545        if ( returnStmt->get_expr() ) {
546            returnStmt->get_expr()->accept( *this );
547        } // if
548        after += ";";
[51b7345]549    }
550
[17cd4eb]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();
[51b7345]561
[17cd4eb]562        whileStmt->get_body()->accept( *this );
[51b7345]563
[17cd4eb]564        before << /* "\r" << */ string( cur_indent, ' ' ) << "}" ;
[51b7345]565
[17cd4eb]566        if ( whileStmt->get_isDoWhile() ) {
567            before << " while(" ;
568            whileStmt->get_condition()->accept(*this );
569            after += ");";
570        } // if
571
572        after += "\n";
[51b7345]573    }
574
[17cd4eb]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    }
[51b7345]599
[17cd4eb]600    void CodeGenerator2::visit( NullStmt *nullStmt ) {
601        //before << /* "\r" << */ string( cur_indent, ' ' ) << CodeGenerator2::printLabels( nullStmt->get_labels() );
602        before << "/* null statement */ ;";
603    }
[51b7345]604
[17cd4eb]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    }
[51b7345]613
[17cd4eb]614    std::string CodeGenerator2::printLabels( std::list< Label > &l ) {
615        std::string str( "" );
616        l.unique();
[51b7345]617
[17cd4eb]618        for ( std::list< Label >::iterator i = l.begin(); i != l.end(); i++ )
619            str += *i + ": ";
[51b7345]620
[17cd4eb]621        return str;
[51b7345]622    }
623
[17cd4eb]624    void CodeGenerator2::shift_left() {
625        before << after;
626        after = "";
627    }
[51b7345]628
[17cd4eb]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    }
[51b7345]649} // namespace CodeGen
Note: See TracBrowser for help on using the repository browser.