Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/CodeGen/CodeGenerator.cc

    r3ed994e rde8d7fb1  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat May  5 09:08:32 2018
    13 // Update Count     : 494
     12// Last Modified On : Sat Oct 19 19:30:38 2019
     13// Update Count     : 506
    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 ( !lineMarks || to.isUnset() ) return;
     85                if ( !options.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( CodeGenerator::tabsize ), output( os ), printLabels( *this ), pretty( pretty ), genC( genC ), lineMarks( lineMarks ), printExprTypes( printExprTypes ), endl( *this ) {}
     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 ) {}
    119120
    120121        string CodeGenerator::mangleName( DeclarationWithType * decl ) {
    121                 if ( pretty ) return decl->get_name();
    122                 if ( decl->get_mangleName() != "" ) {
     122                // GCC builtins should always be printed unmangled
     123                if ( options.pretty || decl->linkage.is_gcc_builtin ) return decl->name;
     124                if ( decl->mangleName != "" ) {
    123125                        // need to incorporate scope level in order to differentiate names for destructors
    124126                        return decl->get_scopedMangleName();
    125127                } else {
    126                         return decl->get_name();
     128                        return decl->name;
    127129                } // if
    128130        }
     
    132134                output << "__attribute__ ((";
    133135                for ( list< Attribute * >::iterator attr( attributes.begin() );; ) {
    134                         output << (*attr)->get_name();
    135                         if ( ! (*attr)->get_parameters().empty() ) {
     136                        output << (*attr)->name;
     137                        if ( ! (*attr)->parameters.empty() ) {
    136138                                output << "(";
    137                                 genCommaList( (*attr)->get_parameters().begin(), (*attr)->get_parameters().end() );
     139                                genCommaList( (*attr)->parameters.begin(), (*attr)->parameters.end() );
    138140                                output << ")";
    139141                        } // if
     
    163165                previsit( (BaseSyntaxNode *)node );
    164166                GuardAction( [this, node](){
    165                         if ( printExprTypes ) {
    166                                 output << " /* " << genType( node->result, "", pretty, genC ) << " */ ";
     167                        if ( options.printExprTypes && node->result ) {
     168                                output << " /* " << genType( node->result, "", options ) << " */ ";
    167169                        }
    168170                } );
     
    172174        void CodeGenerator::postvisit( FunctionDecl * functionDecl ) {
    173175                // deleted decls should never be used, so don't print them
    174                 if ( functionDecl->isDeleted && genC ) return;
     176                if ( functionDecl->isDeleted && options.genC ) return;
    175177                extension( functionDecl );
    176178                genAttributes( functionDecl->get_attributes() );
     
    179181                functionDecl->get_funcSpec().print( output );
    180182
    181                 output << genType( functionDecl->get_functionType(), mangleName( functionDecl ), pretty, genC );
     183                Options subOptions = options;
     184                subOptions.anonymousUnused = functionDecl->has_body();
     185                output << genType( functionDecl->get_functionType(), mangleName( functionDecl ), subOptions );
    182186
    183187                asmName( functionDecl );
     
    193197        void CodeGenerator::postvisit( ObjectDecl * objectDecl ) {
    194198                // deleted decls should never be used, so don't print them
    195                 if ( objectDecl->isDeleted && genC ) return;
    196                 if (objectDecl->get_name().empty() && genC ) {
     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() ) {
    197205                        // only generate an anonymous name when generating C code, otherwise it clutters the output too much
    198206                        static UniqueName name = { "__anonymous_object" };
    199207                        objectDecl->set_name( name.newName() );
     208                        // Stops unused parameter warnings.
     209                        if ( options.anonymousUnused ) {
     210                                objectDecl->attributes.push_back( new Attribute( "unused" ) );
     211                        }
    200212                }
    201213
     
    204216
    205217                handleStorageClass( objectDecl );
    206                 output << genType( objectDecl->get_type(), mangleName( objectDecl ), pretty, genC );
     218                output << genType( objectDecl->get_type(), mangleName( objectDecl ), options.pretty, options.genC );
    207219
    208220                asmName( objectDecl );
     
    223235
    224236        void CodeGenerator::handleAggregate( AggregateDecl * aggDecl, const std::string & kind ) {
    225                 if( ! aggDecl->get_parameters().empty() && ! genC ) {
     237                if( ! aggDecl->parameters.empty() && ! options.genC ) {
    226238                        // assertf( ! genC, "Aggregate type parameters should not reach code generation." );
    227239                        output << "forall(";
    228                         genCommaList( aggDecl->get_parameters().begin(), aggDecl->get_parameters().end() );
     240                        genCommaList( aggDecl->parameters.begin(), aggDecl->parameters.end() );
    229241                        output << ")" << endl;
    230242                        output << indent;
     
    232244
    233245                output << kind;
    234                 genAttributes( aggDecl->get_attributes() );
    235                 output << aggDecl->get_name();
     246                genAttributes( aggDecl->attributes );
     247                output << aggDecl->name;
    236248
    237249                if ( aggDecl->has_body() ) {
    238                         std::list< Declaration * > & memb = aggDecl->get_members();
     250                        std::list< Declaration * > & memb = aggDecl->members;
    239251                        output << " {" << endl;
    240252
     
    293305
    294306        void CodeGenerator::postvisit( TraitDecl * traitDecl ) {
    295                 assertf( ! genC, "TraitDecls should not reach code generation." );
     307                assertf( ! options.genC, "TraitDecls should not reach code generation." );
    296308                extension( traitDecl );
    297309                handleAggregate( traitDecl, "trait " );
     
    299311
    300312        void CodeGenerator::postvisit( TypedefDecl * typeDecl ) {
    301                 assertf( ! genC, "Typedefs are removed and substituted in earlier passes." );
     313                assertf( ! options.genC, "Typedefs are removed and substituted in earlier passes." );
    302314                output << "typedef ";
    303                 output << genType( typeDecl->get_base(), typeDecl->get_name(), pretty, genC ) << endl;
     315                output << genType( typeDecl->get_base(), typeDecl->get_name(), options ) << endl;
    304316        }
    305317
    306318        void CodeGenerator::postvisit( TypeDecl * typeDecl ) {
    307                 assertf( ! genC, "TypeDecls should not reach code generation." );
     319                assertf( ! options.genC, "TypeDecls should not reach code generation." );
    308320                output << typeDecl->genTypeString() << " " << typeDecl->name;
    309321                if ( typeDecl->sized ) {
     
    370382
    371383        void CodeGenerator::postvisit( ConstructorInit * init ){
    372                 assertf( ! genC, "ConstructorInit nodes should not reach code generation." );
     384                assertf( ! options.genC, "ConstructorInit nodes should not reach code generation." );
    373385                // pseudo-output for constructor/destructor pairs
    374386                output << "<ctorinit>{" << endl << ++indent << "ctor: ";
     
    506518                                        } else {
    507519                                                // no constructors with 0 or more than 2 parameters
    508                                                 assertf( ! genC, "UntypedExpr constructor/destructor with 0 or more than 2 parameters." );
     520                                                assertf( ! options.genC, "UntypedExpr constructor/destructor with 0 or more than 2 parameters." );
    509521                                                output << "(";
    510522                                                (*arg++)->accept( *visitor );
     
    603615                        // an lvalue cast, this has been taken out.
    604616                        output << "(";
    605                         output << genType( castExpr->get_result(), "", pretty, genC );
     617                        output << genType( castExpr->get_result(), "", options );
    606618                        output << ")";
    607619                } // if
     
    611623
    612624        void CodeGenerator::postvisit( KeywordCastExpr * castExpr ) {
    613                 assertf( ! genC, "KeywordCast should not reach code generation." );
     625                assertf( ! options.genC, "KeywordCast should not reach code generation." );
    614626                extension( castExpr );
    615627                output << "((" << castExpr->targetString() << " &)";
     
    619631
    620632        void CodeGenerator::postvisit( VirtualCastExpr * castExpr ) {
    621                 assertf( ! genC, "VirtualCastExpr should not reach code generation." );
     633                assertf( ! options.genC, "VirtualCastExpr should not reach code generation." );
    622634                extension( castExpr );
    623635                output << "(virtual ";
     
    627639
    628640        void CodeGenerator::postvisit( UntypedMemberExpr * memberExpr ) {
    629                 assertf( ! genC, "UntypedMemberExpr should not reach code generation." );
     641                assertf( ! options.genC, "UntypedMemberExpr should not reach code generation." );
    630642                extension( memberExpr );
    631643                memberExpr->get_aggregate()->accept( *visitor );
     
    660672                output << "sizeof(";
    661673                if ( sizeofExpr->get_isType() ) {
    662                         output << genType( sizeofExpr->get_type(), "", pretty, genC );
     674                        output << genType( sizeofExpr->get_type(), "", options );
    663675                } else {
    664676                        sizeofExpr->get_expr()->accept( *visitor );
     
    672684                output << "__alignof__(";
    673685                if ( alignofExpr->get_isType() ) {
    674                         output << genType( alignofExpr->get_type(), "", pretty, genC );
     686                        output << genType( alignofExpr->get_type(), "", options );
    675687                } else {
    676688                        alignofExpr->get_expr()->accept( *visitor );
     
    680692
    681693        void CodeGenerator::postvisit( UntypedOffsetofExpr * offsetofExpr ) {
    682                 assertf( ! genC, "UntypedOffsetofExpr should not reach code generation." );
     694                assertf( ! options.genC, "UntypedOffsetofExpr should not reach code generation." );
    683695                output << "offsetof(";
    684                 output << genType( offsetofExpr->get_type(), "", pretty, genC );
     696                output << genType( offsetofExpr->get_type(), "", options );
    685697                output << ", " << offsetofExpr->get_member();
    686698                output << ")";
     
    690702                // use GCC builtin
    691703                output << "__builtin_offsetof(";
    692                 output << genType( offsetofExpr->get_type(), "", pretty, genC );
     704                output << genType( offsetofExpr->get_type(), "", options );
    693705                output << ", " << mangleName( offsetofExpr->get_member() );
    694706                output << ")";
     
    696708
    697709        void CodeGenerator::postvisit( OffsetPackExpr * offsetPackExpr ) {
    698                 assertf( ! genC, "OffsetPackExpr should not reach code generation." );
    699                 output << "__CFA_offsetpack(" << genType( offsetPackExpr->get_type(), "", pretty, genC ) << ")";
     710                assertf( ! options.genC, "OffsetPackExpr should not reach code generation." );
     711                output << "__CFA_offsetpack(" << genType( offsetPackExpr->get_type(), "", options ) << ")";
    700712        }
    701713
     
    727739                extension( commaExpr );
    728740                output << "(";
    729                 if ( genC ) {
     741                if ( options.genC ) {
    730742                        // arg1 of a CommaExpr is never used, so it can be safely cast to void to reduce gcc warnings.
    731743                        commaExpr->set_arg1( new CastExpr( commaExpr->get_arg1() ) );
     
    738750
    739751        void CodeGenerator::postvisit( TupleAssignExpr * tupleExpr ) {
    740                 assertf( ! genC, "TupleAssignExpr should not reach code generation." );
     752                assertf( ! options.genC, "TupleAssignExpr should not reach code generation." );
    741753                tupleExpr->stmtExpr->accept( *visitor );
    742754        }
    743755
    744756        void CodeGenerator::postvisit( UntypedTupleExpr * tupleExpr ) {
    745                 assertf( ! genC, "UntypedTupleExpr should not reach code generation." );
     757                assertf( ! options.genC, "UntypedTupleExpr should not reach code generation." );
    746758                extension( tupleExpr );
    747759                output << "[";
     
    751763
    752764        void CodeGenerator::postvisit( TupleExpr * tupleExpr ) {
    753                 assertf( ! genC, "TupleExpr should not reach code generation." );
     765                assertf( ! options.genC, "TupleExpr should not reach code generation." );
    754766                extension( tupleExpr );
    755767                output << "[";
     
    759771
    760772        void CodeGenerator::postvisit( TupleIndexExpr * tupleExpr ) {
    761                 assertf( ! genC, "TupleIndexExpr should not reach code generation." );
     773                assertf( ! options.genC, "TupleIndexExpr should not reach code generation." );
    762774                extension( tupleExpr );
    763775                tupleExpr->get_tuple()->accept( *visitor );
     
    766778
    767779        void CodeGenerator::postvisit( TypeExpr * typeExpr ) {
    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 );
     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 );
    772784                }
    773785        }
     
    787799        void CodeGenerator::postvisit( CompoundLiteralExpr *compLitExpr ) {
    788800                assert( compLitExpr->get_result() && dynamic_cast< ListInit * > ( compLitExpr->get_initializer() ) );
    789                 output << "(" << genType( compLitExpr->get_result(), "", pretty, genC ) << ")";
     801                output << "(" << genType( compLitExpr->get_result(), "", options ) << ")";
    790802                compLitExpr->get_initializer()->accept( *visitor );
    791803        }
    792804
    793805        void CodeGenerator::postvisit( UniqueExpr * unqExpr ) {
    794                 assertf( ! genC, "Unique expressions should not reach code generation." );
     806                assertf( ! options.genC, "Unique expressions should not reach code generation." );
    795807                output << "unq<" << unqExpr->get_id() << ">{ ";
    796808                unqExpr->get_expr()->accept( *visitor );
     
    828840
    829841        void CodeGenerator::postvisit( ConstructorExpr * expr ) {
    830                 assertf( ! genC, "Unique expressions should not reach code generation." );
     842                assertf( ! options.genC, "Unique expressions should not reach code generation." );
    831843                expr->callExpr->accept( *visitor );
    832844        }
    833845
    834846        void CodeGenerator::postvisit( DeletedExpr * expr ) {
    835                 assertf( ! genC, "Deleted expressions should not reach code generation." );
     847                assertf( ! options.genC, "Deleted expressions should not reach code generation." );
    836848                expr->expr->accept( *visitor );
    837849        }
    838850
     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
    839856        void CodeGenerator::postvisit( GenericExpr * expr ) {
    840                 assertf( ! genC, "C11 _Generic expressions should not reach code generation." );
     857                assertf( ! options.genC, "C11 _Generic expressions should not reach code generation." );
    841858                output << "_Generic(";
    842859                expr->control->accept( *visitor );
     
    848865                                output << "default: ";
    849866                        } else {
    850                                 output << genType( assoc.type, "", pretty, genC ) << ": ";
     867                                output << genType( assoc.type, "", options ) << ": ";
    851868                        }
    852869                        assoc.expr->accept( *visitor );
     
    883900        void CodeGenerator::postvisit( ExprStmt * exprStmt ) {
    884901                assert( exprStmt );
    885                 if ( genC ) {
     902                if ( options.genC ) {
    886903                        // cast the top-level expression to void to reduce gcc warnings.
    887904                        exprStmt->set_expr( new CastExpr( exprStmt->get_expr() ) );
     
    9931010                  case BranchStmt::FallThrough:
    9941011                  case BranchStmt::FallThroughDefault:
    995                         assertf( ! genC, "fallthru should not reach code generation." );
     1012                        assertf( ! options.genC, "fallthru should not reach code generation." );
    9961013                  output << "fallthru";
    9971014                        break;
    9981015                } // switch
    9991016                // print branch target for labelled break/continue/fallthru in debug mode
    1000                 if ( ! genC && branchStmt->get_type() != BranchStmt::Goto ) {
     1017                if ( ! options.genC && branchStmt->get_type() != BranchStmt::Goto ) {
    10011018                        if ( ! branchStmt->get_target().empty() ) {
    10021019                                output << " " << branchStmt->get_target();
     
    10151032
    10161033        void CodeGenerator::postvisit( ThrowStmt * throwStmt ) {
    1017                 assertf( ! genC, "Throw statements should not reach code generation." );
     1034                assertf( ! options.genC, "Throw statements should not reach code generation." );
    10181035
    10191036                output << ((throwStmt->get_kind() == ThrowStmt::Terminate) ?
     
    10301047        }
    10311048        void CodeGenerator::postvisit( CatchStmt * stmt ) {
    1032                 assertf( ! genC, "Catch statements should not reach code generation." );
     1049                assertf( ! options.genC, "Catch statements should not reach code generation." );
    10331050
    10341051                output << ((stmt->get_kind() == CatchStmt::Terminate) ?
     
    10471064
    10481065        void CodeGenerator::postvisit( WaitForStmt * stmt ) {
    1049                 assertf( ! genC, "Waitfor statements should not reach code generation." );
     1066                assertf( ! options.genC, "Waitfor statements should not reach code generation." );
    10501067
    10511068                bool first = true;
     
    10931110
    10941111        void CodeGenerator::postvisit( WithStmt * with ) {
    1095                 if ( ! genC ) {
     1112                if ( ! options.genC ) {
    10961113                        output << "with ( ";
    10971114                        genCommaList( with->exprs.begin(), with->exprs.end() );
     
    11591176
    11601177        void CodeGenerator::postvisit( ImplicitCtorDtorStmt * stmt ) {
    1161                 assertf( ! genC, "ImplicitCtorDtorStmts should not reach code generation." );
     1178                assertf( ! options.genC, "ImplicitCtorDtorStmts should not reach code generation." );
    11621179                stmt->callStmt->accept( *visitor );
    11631180        }
Note: See TracChangeset for help on using the changeset viewer.