Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/CodeGen/CodeGenerator.cc

    rde8d7fb1 r3ed994e  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Oct 19 19:30:38 2019
    13 // Update Count     : 506
     12// Last Modified On : Sat May  5 09:08:32 2018
     13// Update Count     : 494
    1414//
    1515#include "CodeGenerator.h"
     
    8383        void CodeGenerator::updateLocation( CodeLocation const & to ) {
    8484                // skip if linemarks shouldn't appear or if codelocation is unset
    85                 if ( !options.lineMarks || to.isUnset() ) return;
     85                if ( !lineMarks || to.isUnset() ) return;
    8686
    8787                if ( currentLocation.followedBy( to, 0 ) ) {
     
    116116        }
    117117
    118         CodeGenerator::CodeGenerator( std::ostream & os, bool pretty, bool genC, bool lineMarks, bool printExprTypes ) : indent( 0, CodeGenerator::tabsize ), output( os ), printLabels( *this ), options( pretty, genC, lineMarks, printExprTypes ), endl( *this ) {}
    119         CodeGenerator::CodeGenerator( std::ostream & os, const Options &options ) : indent( 0, CodeGenerator::tabsize ), output( os ), printLabels( *this ), options(options), endl( *this ) {}
     118        CodeGenerator::CodeGenerator( std::ostream & os, bool pretty, bool genC, bool lineMarks, bool printExprTypes ) : indent( CodeGenerator::tabsize ), output( os ), printLabels( *this ), pretty( pretty ), genC( genC ), lineMarks( lineMarks ), printExprTypes( printExprTypes ), endl( *this ) {}
    120119
    121120        string CodeGenerator::mangleName( DeclarationWithType * decl ) {
    122                 // GCC builtins should always be printed unmangled
    123                 if ( options.pretty || decl->linkage.is_gcc_builtin ) return decl->name;
    124                 if ( decl->mangleName != "" ) {
     121                if ( pretty ) return decl->get_name();
     122                if ( decl->get_mangleName() != "" ) {
    125123                        // need to incorporate scope level in order to differentiate names for destructors
    126124                        return decl->get_scopedMangleName();
    127125                } else {
    128                         return decl->name;
     126                        return decl->get_name();
    129127                } // if
    130128        }
     
    134132                output << "__attribute__ ((";
    135133                for ( list< Attribute * >::iterator attr( attributes.begin() );; ) {
    136                         output << (*attr)->name;
    137                         if ( ! (*attr)->parameters.empty() ) {
     134                        output << (*attr)->get_name();
     135                        if ( ! (*attr)->get_parameters().empty() ) {
    138136                                output << "(";
    139                                 genCommaList( (*attr)->parameters.begin(), (*attr)->parameters.end() );
     137                                genCommaList( (*attr)->get_parameters().begin(), (*attr)->get_parameters().end() );
    140138                                output << ")";
    141139                        } // if
     
    165163                previsit( (BaseSyntaxNode *)node );
    166164                GuardAction( [this, node](){
    167                         if ( options.printExprTypes && node->result ) {
    168                                 output << " /* " << genType( node->result, "", options ) << " */ ";
     165                        if ( printExprTypes ) {
     166                                output << " /* " << genType( node->result, "", pretty, genC ) << " */ ";
    169167                        }
    170168                } );
     
    174172        void CodeGenerator::postvisit( FunctionDecl * functionDecl ) {
    175173                // deleted decls should never be used, so don't print them
    176                 if ( functionDecl->isDeleted && options.genC ) return;
     174                if ( functionDecl->isDeleted && genC ) return;
    177175                extension( functionDecl );
    178176                genAttributes( functionDecl->get_attributes() );
     
    181179                functionDecl->get_funcSpec().print( output );
    182180
    183                 Options subOptions = options;
    184                 subOptions.anonymousUnused = functionDecl->has_body();
    185                 output << genType( functionDecl->get_functionType(), mangleName( functionDecl ), subOptions );
     181                output << genType( functionDecl->get_functionType(), mangleName( functionDecl ), pretty, genC );
    186182
    187183                asmName( functionDecl );
     
    197193        void CodeGenerator::postvisit( ObjectDecl * objectDecl ) {
    198194                // deleted decls should never be used, so don't print them
    199                 if ( objectDecl->isDeleted && options.genC ) return;
    200 
    201                 // gcc allows an empty declarator (no name) for bit-fields and C states: 6.7.2.1 Structure and union specifiers,
    202                 // point 4, page 113: If the (bit field) value is zero, the declaration shall have no declarator.  For anything
    203                 // else, the anonymous name refers to the anonymous object for plan9 inheritance.
    204                 if ( objectDecl->get_name().empty() && options.genC && ! objectDecl->get_bitfieldWidth() ) {
     195                if ( objectDecl->isDeleted && genC ) return;
     196                if (objectDecl->get_name().empty() && genC ) {
    205197                        // only generate an anonymous name when generating C code, otherwise it clutters the output too much
    206198                        static UniqueName name = { "__anonymous_object" };
    207199                        objectDecl->set_name( name.newName() );
    208                         // Stops unused parameter warnings.
    209                         if ( options.anonymousUnused ) {
    210                                 objectDecl->attributes.push_back( new Attribute( "unused" ) );
    211                         }
    212200                }
    213201
     
    216204
    217205                handleStorageClass( objectDecl );
    218                 output << genType( objectDecl->get_type(), mangleName( objectDecl ), options.pretty, options.genC );
     206                output << genType( objectDecl->get_type(), mangleName( objectDecl ), pretty, genC );
    219207
    220208                asmName( objectDecl );
     
    235223
    236224        void CodeGenerator::handleAggregate( AggregateDecl * aggDecl, const std::string & kind ) {
    237                 if( ! aggDecl->parameters.empty() && ! options.genC ) {
     225                if( ! aggDecl->get_parameters().empty() && ! genC ) {
    238226                        // assertf( ! genC, "Aggregate type parameters should not reach code generation." );
    239227                        output << "forall(";
    240                         genCommaList( aggDecl->parameters.begin(), aggDecl->parameters.end() );
     228                        genCommaList( aggDecl->get_parameters().begin(), aggDecl->get_parameters().end() );
    241229                        output << ")" << endl;
    242230                        output << indent;
     
    244232
    245233                output << kind;
    246                 genAttributes( aggDecl->attributes );
    247                 output << aggDecl->name;
     234                genAttributes( aggDecl->get_attributes() );
     235                output << aggDecl->get_name();
    248236
    249237                if ( aggDecl->has_body() ) {
    250                         std::list< Declaration * > & memb = aggDecl->members;
     238                        std::list< Declaration * > & memb = aggDecl->get_members();
    251239                        output << " {" << endl;
    252240
     
    305293
    306294        void CodeGenerator::postvisit( TraitDecl * traitDecl ) {
    307                 assertf( ! options.genC, "TraitDecls should not reach code generation." );
     295                assertf( ! genC, "TraitDecls should not reach code generation." );
    308296                extension( traitDecl );
    309297                handleAggregate( traitDecl, "trait " );
     
    311299
    312300        void CodeGenerator::postvisit( TypedefDecl * typeDecl ) {
    313                 assertf( ! options.genC, "Typedefs are removed and substituted in earlier passes." );
     301                assertf( ! genC, "Typedefs are removed and substituted in earlier passes." );
    314302                output << "typedef ";
    315                 output << genType( typeDecl->get_base(), typeDecl->get_name(), options ) << endl;
     303                output << genType( typeDecl->get_base(), typeDecl->get_name(), pretty, genC ) << endl;
    316304        }
    317305
    318306        void CodeGenerator::postvisit( TypeDecl * typeDecl ) {
    319                 assertf( ! options.genC, "TypeDecls should not reach code generation." );
     307                assertf( ! genC, "TypeDecls should not reach code generation." );
    320308                output << typeDecl->genTypeString() << " " << typeDecl->name;
    321309                if ( typeDecl->sized ) {
     
    382370
    383371        void CodeGenerator::postvisit( ConstructorInit * init ){
    384                 assertf( ! options.genC, "ConstructorInit nodes should not reach code generation." );
     372                assertf( ! genC, "ConstructorInit nodes should not reach code generation." );
    385373                // pseudo-output for constructor/destructor pairs
    386374                output << "<ctorinit>{" << endl << ++indent << "ctor: ";
     
    518506                                        } else {
    519507                                                // no constructors with 0 or more than 2 parameters
    520                                                 assertf( ! options.genC, "UntypedExpr constructor/destructor with 0 or more than 2 parameters." );
     508                                                assertf( ! genC, "UntypedExpr constructor/destructor with 0 or more than 2 parameters." );
    521509                                                output << "(";
    522510                                                (*arg++)->accept( *visitor );
     
    615603                        // an lvalue cast, this has been taken out.
    616604                        output << "(";
    617                         output << genType( castExpr->get_result(), "", options );
     605                        output << genType( castExpr->get_result(), "", pretty, genC );
    618606                        output << ")";
    619607                } // if
     
    623611
    624612        void CodeGenerator::postvisit( KeywordCastExpr * castExpr ) {
    625                 assertf( ! options.genC, "KeywordCast should not reach code generation." );
     613                assertf( ! genC, "KeywordCast should not reach code generation." );
    626614                extension( castExpr );
    627615                output << "((" << castExpr->targetString() << " &)";
     
    631619
    632620        void CodeGenerator::postvisit( VirtualCastExpr * castExpr ) {
    633                 assertf( ! options.genC, "VirtualCastExpr should not reach code generation." );
     621                assertf( ! genC, "VirtualCastExpr should not reach code generation." );
    634622                extension( castExpr );
    635623                output << "(virtual ";
     
    639627
    640628        void CodeGenerator::postvisit( UntypedMemberExpr * memberExpr ) {
    641                 assertf( ! options.genC, "UntypedMemberExpr should not reach code generation." );
     629                assertf( ! genC, "UntypedMemberExpr should not reach code generation." );
    642630                extension( memberExpr );
    643631                memberExpr->get_aggregate()->accept( *visitor );
     
    672660                output << "sizeof(";
    673661                if ( sizeofExpr->get_isType() ) {
    674                         output << genType( sizeofExpr->get_type(), "", options );
     662                        output << genType( sizeofExpr->get_type(), "", pretty, genC );
    675663                } else {
    676664                        sizeofExpr->get_expr()->accept( *visitor );
     
    684672                output << "__alignof__(";
    685673                if ( alignofExpr->get_isType() ) {
    686                         output << genType( alignofExpr->get_type(), "", options );
     674                        output << genType( alignofExpr->get_type(), "", pretty, genC );
    687675                } else {
    688676                        alignofExpr->get_expr()->accept( *visitor );
     
    692680
    693681        void CodeGenerator::postvisit( UntypedOffsetofExpr * offsetofExpr ) {
    694                 assertf( ! options.genC, "UntypedOffsetofExpr should not reach code generation." );
     682                assertf( ! genC, "UntypedOffsetofExpr should not reach code generation." );
    695683                output << "offsetof(";
    696                 output << genType( offsetofExpr->get_type(), "", options );
     684                output << genType( offsetofExpr->get_type(), "", pretty, genC );
    697685                output << ", " << offsetofExpr->get_member();
    698686                output << ")";
     
    702690                // use GCC builtin
    703691                output << "__builtin_offsetof(";
    704                 output << genType( offsetofExpr->get_type(), "", options );
     692                output << genType( offsetofExpr->get_type(), "", pretty, genC );
    705693                output << ", " << mangleName( offsetofExpr->get_member() );
    706694                output << ")";
     
    708696
    709697        void CodeGenerator::postvisit( OffsetPackExpr * offsetPackExpr ) {
    710                 assertf( ! options.genC, "OffsetPackExpr should not reach code generation." );
    711                 output << "__CFA_offsetpack(" << genType( offsetPackExpr->get_type(), "", options ) << ")";
     698                assertf( ! genC, "OffsetPackExpr should not reach code generation." );
     699                output << "__CFA_offsetpack(" << genType( offsetPackExpr->get_type(), "", pretty, genC ) << ")";
    712700        }
    713701
     
    739727                extension( commaExpr );
    740728                output << "(";
    741                 if ( options.genC ) {
     729                if ( genC ) {
    742730                        // arg1 of a CommaExpr is never used, so it can be safely cast to void to reduce gcc warnings.
    743731                        commaExpr->set_arg1( new CastExpr( commaExpr->get_arg1() ) );
     
    750738
    751739        void CodeGenerator::postvisit( TupleAssignExpr * tupleExpr ) {
    752                 assertf( ! options.genC, "TupleAssignExpr should not reach code generation." );
     740                assertf( ! genC, "TupleAssignExpr should not reach code generation." );
    753741                tupleExpr->stmtExpr->accept( *visitor );
    754742        }
    755743
    756744        void CodeGenerator::postvisit( UntypedTupleExpr * tupleExpr ) {
    757                 assertf( ! options.genC, "UntypedTupleExpr should not reach code generation." );
     745                assertf( ! genC, "UntypedTupleExpr should not reach code generation." );
    758746                extension( tupleExpr );
    759747                output << "[";
     
    763751
    764752        void CodeGenerator::postvisit( TupleExpr * tupleExpr ) {
    765                 assertf( ! options.genC, "TupleExpr should not reach code generation." );
     753                assertf( ! genC, "TupleExpr should not reach code generation." );
    766754                extension( tupleExpr );
    767755                output << "[";
     
    771759
    772760        void CodeGenerator::postvisit( TupleIndexExpr * tupleExpr ) {
    773                 assertf( ! options.genC, "TupleIndexExpr should not reach code generation." );
     761                assertf( ! genC, "TupleIndexExpr should not reach code generation." );
    774762                extension( tupleExpr );
    775763                tupleExpr->get_tuple()->accept( *visitor );
     
    778766
    779767        void CodeGenerator::postvisit( TypeExpr * typeExpr ) {
    780                 // if ( options.genC ) std::cerr << "typeexpr still exists: " << typeExpr << std::endl;
    781                 // assertf( ! options.genC, "TypeExpr should not reach code generation." );
    782                 if ( ! options.genC ) {
    783                         output << genType( typeExpr->get_type(), "", options );
     768                // if ( genC ) std::cerr << "typeexpr still exists: " << typeExpr << std::endl;
     769                // assertf( ! genC, "TypeExpr should not reach code generation." );
     770                if ( ! genC ) {
     771                        output<< genType( typeExpr->get_type(), "", pretty, genC );
    784772                }
    785773        }
     
    799787        void CodeGenerator::postvisit( CompoundLiteralExpr *compLitExpr ) {
    800788                assert( compLitExpr->get_result() && dynamic_cast< ListInit * > ( compLitExpr->get_initializer() ) );
    801                 output << "(" << genType( compLitExpr->get_result(), "", options ) << ")";
     789                output << "(" << genType( compLitExpr->get_result(), "", pretty, genC ) << ")";
    802790                compLitExpr->get_initializer()->accept( *visitor );
    803791        }
    804792
    805793        void CodeGenerator::postvisit( UniqueExpr * unqExpr ) {
    806                 assertf( ! options.genC, "Unique expressions should not reach code generation." );
     794                assertf( ! genC, "Unique expressions should not reach code generation." );
    807795                output << "unq<" << unqExpr->get_id() << ">{ ";
    808796                unqExpr->get_expr()->accept( *visitor );
     
    840828
    841829        void CodeGenerator::postvisit( ConstructorExpr * expr ) {
    842                 assertf( ! options.genC, "Unique expressions should not reach code generation." );
     830                assertf( ! genC, "Unique expressions should not reach code generation." );
    843831                expr->callExpr->accept( *visitor );
    844832        }
    845833
    846834        void CodeGenerator::postvisit( DeletedExpr * expr ) {
    847                 assertf( ! options.genC, "Deleted expressions should not reach code generation." );
     835                assertf( ! genC, "Deleted expressions should not reach code generation." );
    848836                expr->expr->accept( *visitor );
    849837        }
    850838
    851         void CodeGenerator::postvisit( DefaultArgExpr * arg ) {
    852                 assertf( ! options.genC, "Default argument expressions should not reach code generation." );
    853                 arg->expr->accept( *visitor );
    854         }
    855 
    856839        void CodeGenerator::postvisit( GenericExpr * expr ) {
    857                 assertf( ! options.genC, "C11 _Generic expressions should not reach code generation." );
     840                assertf( ! genC, "C11 _Generic expressions should not reach code generation." );
    858841                output << "_Generic(";
    859842                expr->control->accept( *visitor );
     
    865848                                output << "default: ";
    866849                        } else {
    867                                 output << genType( assoc.type, "", options ) << ": ";
     850                                output << genType( assoc.type, "", pretty, genC ) << ": ";
    868851                        }
    869852                        assoc.expr->accept( *visitor );
     
    900883        void CodeGenerator::postvisit( ExprStmt * exprStmt ) {
    901884                assert( exprStmt );
    902                 if ( options.genC ) {
     885                if ( genC ) {
    903886                        // cast the top-level expression to void to reduce gcc warnings.
    904887                        exprStmt->set_expr( new CastExpr( exprStmt->get_expr() ) );
     
    1010993                  case BranchStmt::FallThrough:
    1011994                  case BranchStmt::FallThroughDefault:
    1012                         assertf( ! options.genC, "fallthru should not reach code generation." );
     995                        assertf( ! genC, "fallthru should not reach code generation." );
    1013996                  output << "fallthru";
    1014997                        break;
    1015998                } // switch
    1016999                // print branch target for labelled break/continue/fallthru in debug mode
    1017                 if ( ! options.genC && branchStmt->get_type() != BranchStmt::Goto ) {
     1000                if ( ! genC && branchStmt->get_type() != BranchStmt::Goto ) {
    10181001                        if ( ! branchStmt->get_target().empty() ) {
    10191002                                output << " " << branchStmt->get_target();
     
    10321015
    10331016        void CodeGenerator::postvisit( ThrowStmt * throwStmt ) {
    1034                 assertf( ! options.genC, "Throw statements should not reach code generation." );
     1017                assertf( ! genC, "Throw statements should not reach code generation." );
    10351018
    10361019                output << ((throwStmt->get_kind() == ThrowStmt::Terminate) ?
     
    10471030        }
    10481031        void CodeGenerator::postvisit( CatchStmt * stmt ) {
    1049                 assertf( ! options.genC, "Catch statements should not reach code generation." );
     1032                assertf( ! genC, "Catch statements should not reach code generation." );
    10501033
    10511034                output << ((stmt->get_kind() == CatchStmt::Terminate) ?
     
    10641047
    10651048        void CodeGenerator::postvisit( WaitForStmt * stmt ) {
    1066                 assertf( ! options.genC, "Waitfor statements should not reach code generation." );
     1049                assertf( ! genC, "Waitfor statements should not reach code generation." );
    10671050
    10681051                bool first = true;
     
    11101093
    11111094        void CodeGenerator::postvisit( WithStmt * with ) {
    1112                 if ( ! options.genC ) {
     1095                if ( ! genC ) {
    11131096                        output << "with ( ";
    11141097                        genCommaList( with->exprs.begin(), with->exprs.end() );
     
    11761159
    11771160        void CodeGenerator::postvisit( ImplicitCtorDtorStmt * stmt ) {
    1178                 assertf( ! options.genC, "ImplicitCtorDtorStmts should not reach code generation." );
     1161                assertf( ! genC, "ImplicitCtorDtorStmts should not reach code generation." );
    11791162                stmt->callStmt->accept( *visitor );
    11801163        }
Note: See TracChangeset for help on using the changeset viewer.