Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/CodeGen/CodeGenerator.cc

    r76f7fc7 r0b3b2ae  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Thr May  2 10:47:00 2019
    13 // Update Count     : 497
     11// Last Modified By : Peter A. Buhr
     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( CodeGenerator::tabsize ), output( os ), printLabels( *this ), options( pretty, genC, lineMarks, printExprTypes ), endl( *this ) {}
    119         CodeGenerator::CodeGenerator( std::ostream & os, const Options &options ) : indent( 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 ) {
    122121                // GCC builtins should always be printed unmangled
    123                 if ( options.pretty || decl->linkage.is_gcc_builtin ) return decl->name;
     122                if ( pretty || decl->linkage.is_gcc_builtin ) return decl->name;
    124123                if ( decl->mangleName != "" ) {
    125124                        // need to incorporate scope level in order to differentiate names for destructors
     
    165164                previsit( (BaseSyntaxNode *)node );
    166165                GuardAction( [this, node](){
    167                         if ( options.printExprTypes && node->result ) {
    168                                 output << " /* " << genType( node->result, "", options ) << " */ ";
     166                        if ( printExprTypes && node->result ) {
     167                                output << " /* " << genType( node->result, "", pretty, genC ) << " */ ";
    169168                        }
    170169                } );
     
    174173        void CodeGenerator::postvisit( FunctionDecl * functionDecl ) {
    175174                // deleted decls should never be used, so don't print them
    176                 if ( functionDecl->isDeleted && options.genC ) return;
     175                if ( functionDecl->isDeleted && genC ) return;
    177176                extension( functionDecl );
    178177                genAttributes( functionDecl->get_attributes() );
     
    181180                functionDecl->get_funcSpec().print( output );
    182181
    183                 Options subOptions = options;
    184                 subOptions.anonymousUnused = functionDecl->has_body();
    185                 output << genType( functionDecl->get_functionType(), mangleName( functionDecl ), subOptions );
     182                output << genType( functionDecl->get_functionType(), mangleName( functionDecl ), pretty, genC );
    186183
    187184                asmName( functionDecl );
     
    197194        void CodeGenerator::postvisit( ObjectDecl * objectDecl ) {
    198195                // deleted decls should never be used, so don't print them
    199                 if ( objectDecl->isDeleted && options.genC ) return;
    200                 if (objectDecl->get_name().empty() && options.genC ) {
     196                if ( objectDecl->isDeleted && genC ) return;
     197                if (objectDecl->get_name().empty() && genC ) {
    201198                        // only generate an anonymous name when generating C code, otherwise it clutters the output too much
    202199                        static UniqueName name = { "__anonymous_object" };
    203200                        objectDecl->set_name( name.newName() );
    204             // Stops unused parameter warnings.
    205             if ( options.anonymousUnused ) {
    206                 objectDecl->attributes.push_back( new Attribute( "unused" ) );
    207             }
    208201                }
    209202
     
    212205
    213206                handleStorageClass( objectDecl );
    214                 output << genType( objectDecl->get_type(), mangleName( objectDecl ), options.pretty, options.genC );
     207                output << genType( objectDecl->get_type(), mangleName( objectDecl ), pretty, genC );
    215208
    216209                asmName( objectDecl );
     
    231224
    232225        void CodeGenerator::handleAggregate( AggregateDecl * aggDecl, const std::string & kind ) {
    233                 if( ! aggDecl->parameters.empty() && ! options.genC ) {
     226                if( ! aggDecl->parameters.empty() && ! genC ) {
    234227                        // assertf( ! genC, "Aggregate type parameters should not reach code generation." );
    235228                        output << "forall(";
     
    301294
    302295        void CodeGenerator::postvisit( TraitDecl * traitDecl ) {
    303                 assertf( ! options.genC, "TraitDecls should not reach code generation." );
     296                assertf( ! genC, "TraitDecls should not reach code generation." );
    304297                extension( traitDecl );
    305298                handleAggregate( traitDecl, "trait " );
     
    307300
    308301        void CodeGenerator::postvisit( TypedefDecl * typeDecl ) {
    309                 assertf( ! options.genC, "Typedefs are removed and substituted in earlier passes." );
     302                assertf( ! genC, "Typedefs are removed and substituted in earlier passes." );
    310303                output << "typedef ";
    311                 output << genType( typeDecl->get_base(), typeDecl->get_name(), options ) << endl;
     304                output << genType( typeDecl->get_base(), typeDecl->get_name(), pretty, genC ) << endl;
    312305        }
    313306
    314307        void CodeGenerator::postvisit( TypeDecl * typeDecl ) {
    315                 assertf( ! options.genC, "TypeDecls should not reach code generation." );
     308                assertf( ! genC, "TypeDecls should not reach code generation." );
    316309                output << typeDecl->genTypeString() << " " << typeDecl->name;
    317310                if ( typeDecl->sized ) {
     
    378371
    379372        void CodeGenerator::postvisit( ConstructorInit * init ){
    380                 assertf( ! options.genC, "ConstructorInit nodes should not reach code generation." );
     373                assertf( ! genC, "ConstructorInit nodes should not reach code generation." );
    381374                // pseudo-output for constructor/destructor pairs
    382375                output << "<ctorinit>{" << endl << ++indent << "ctor: ";
     
    514507                                        } else {
    515508                                                // no constructors with 0 or more than 2 parameters
    516                                                 assertf( ! options.genC, "UntypedExpr constructor/destructor with 0 or more than 2 parameters." );
     509                                                assertf( ! genC, "UntypedExpr constructor/destructor with 0 or more than 2 parameters." );
    517510                                                output << "(";
    518511                                                (*arg++)->accept( *visitor );
     
    611604                        // an lvalue cast, this has been taken out.
    612605                        output << "(";
    613                         output << genType( castExpr->get_result(), "", options );
     606                        output << genType( castExpr->get_result(), "", pretty, genC );
    614607                        output << ")";
    615608                } // if
     
    619612
    620613        void CodeGenerator::postvisit( KeywordCastExpr * castExpr ) {
    621                 assertf( ! options.genC, "KeywordCast should not reach code generation." );
     614                assertf( ! genC, "KeywordCast should not reach code generation." );
    622615                extension( castExpr );
    623616                output << "((" << castExpr->targetString() << " &)";
     
    627620
    628621        void CodeGenerator::postvisit( VirtualCastExpr * castExpr ) {
    629                 assertf( ! options.genC, "VirtualCastExpr should not reach code generation." );
     622                assertf( ! genC, "VirtualCastExpr should not reach code generation." );
    630623                extension( castExpr );
    631624                output << "(virtual ";
     
    635628
    636629        void CodeGenerator::postvisit( UntypedMemberExpr * memberExpr ) {
    637                 assertf( ! options.genC, "UntypedMemberExpr should not reach code generation." );
     630                assertf( ! genC, "UntypedMemberExpr should not reach code generation." );
    638631                extension( memberExpr );
    639632                memberExpr->get_aggregate()->accept( *visitor );
     
    668661                output << "sizeof(";
    669662                if ( sizeofExpr->get_isType() ) {
    670                         output << genType( sizeofExpr->get_type(), "", options );
     663                        output << genType( sizeofExpr->get_type(), "", pretty, genC );
    671664                } else {
    672665                        sizeofExpr->get_expr()->accept( *visitor );
     
    680673                output << "__alignof__(";
    681674                if ( alignofExpr->get_isType() ) {
    682                         output << genType( alignofExpr->get_type(), "", options );
     675                        output << genType( alignofExpr->get_type(), "", pretty, genC );
    683676                } else {
    684677                        alignofExpr->get_expr()->accept( *visitor );
     
    688681
    689682        void CodeGenerator::postvisit( UntypedOffsetofExpr * offsetofExpr ) {
    690                 assertf( ! options.genC, "UntypedOffsetofExpr should not reach code generation." );
     683                assertf( ! genC, "UntypedOffsetofExpr should not reach code generation." );
    691684                output << "offsetof(";
    692                 output << genType( offsetofExpr->get_type(), "", options );
     685                output << genType( offsetofExpr->get_type(), "", pretty, genC );
    693686                output << ", " << offsetofExpr->get_member();
    694687                output << ")";
     
    698691                // use GCC builtin
    699692                output << "__builtin_offsetof(";
    700                 output << genType( offsetofExpr->get_type(), "", options );
     693                output << genType( offsetofExpr->get_type(), "", pretty, genC );
    701694                output << ", " << mangleName( offsetofExpr->get_member() );
    702695                output << ")";
     
    704697
    705698        void CodeGenerator::postvisit( OffsetPackExpr * offsetPackExpr ) {
    706                 assertf( ! options.genC, "OffsetPackExpr should not reach code generation." );
    707                 output << "__CFA_offsetpack(" << genType( offsetPackExpr->get_type(), "", options ) << ")";
     699                assertf( ! genC, "OffsetPackExpr should not reach code generation." );
     700                output << "__CFA_offsetpack(" << genType( offsetPackExpr->get_type(), "", pretty, genC ) << ")";
    708701        }
    709702
     
    735728                extension( commaExpr );
    736729                output << "(";
    737                 if ( options.genC ) {
     730                if ( genC ) {
    738731                        // arg1 of a CommaExpr is never used, so it can be safely cast to void to reduce gcc warnings.
    739732                        commaExpr->set_arg1( new CastExpr( commaExpr->get_arg1() ) );
     
    746739
    747740        void CodeGenerator::postvisit( TupleAssignExpr * tupleExpr ) {
    748                 assertf( ! options.genC, "TupleAssignExpr should not reach code generation." );
     741                assertf( ! genC, "TupleAssignExpr should not reach code generation." );
    749742                tupleExpr->stmtExpr->accept( *visitor );
    750743        }
    751744
    752745        void CodeGenerator::postvisit( UntypedTupleExpr * tupleExpr ) {
    753                 assertf( ! options.genC, "UntypedTupleExpr should not reach code generation." );
     746                assertf( ! genC, "UntypedTupleExpr should not reach code generation." );
    754747                extension( tupleExpr );
    755748                output << "[";
     
    759752
    760753        void CodeGenerator::postvisit( TupleExpr * tupleExpr ) {
    761                 assertf( ! options.genC, "TupleExpr should not reach code generation." );
     754                assertf( ! genC, "TupleExpr should not reach code generation." );
    762755                extension( tupleExpr );
    763756                output << "[";
     
    767760
    768761        void CodeGenerator::postvisit( TupleIndexExpr * tupleExpr ) {
    769                 assertf( ! options.genC, "TupleIndexExpr should not reach code generation." );
     762                assertf( ! genC, "TupleIndexExpr should not reach code generation." );
    770763                extension( tupleExpr );
    771764                tupleExpr->get_tuple()->accept( *visitor );
     
    774767
    775768        void CodeGenerator::postvisit( TypeExpr * typeExpr ) {
    776                 // if ( options.genC ) std::cerr << "typeexpr still exists: " << typeExpr << std::endl;
    777                 // assertf( ! options.genC, "TypeExpr should not reach code generation." );
    778                 if ( ! options.genC ) {
    779                         output << genType( typeExpr->get_type(), "", options );
     769                // if ( genC ) std::cerr << "typeexpr still exists: " << typeExpr << std::endl;
     770                // assertf( ! genC, "TypeExpr should not reach code generation." );
     771                if ( ! genC ) {
     772                        output<< genType( typeExpr->get_type(), "", pretty, genC );
    780773                }
    781774        }
     
    795788        void CodeGenerator::postvisit( CompoundLiteralExpr *compLitExpr ) {
    796789                assert( compLitExpr->get_result() && dynamic_cast< ListInit * > ( compLitExpr->get_initializer() ) );
    797                 output << "(" << genType( compLitExpr->get_result(), "", options ) << ")";
     790                output << "(" << genType( compLitExpr->get_result(), "", pretty, genC ) << ")";
    798791                compLitExpr->get_initializer()->accept( *visitor );
    799792        }
    800793
    801794        void CodeGenerator::postvisit( UniqueExpr * unqExpr ) {
    802                 assertf( ! options.genC, "Unique expressions should not reach code generation." );
     795                assertf( ! genC, "Unique expressions should not reach code generation." );
    803796                output << "unq<" << unqExpr->get_id() << ">{ ";
    804797                unqExpr->get_expr()->accept( *visitor );
     
    836829
    837830        void CodeGenerator::postvisit( ConstructorExpr * expr ) {
    838                 assertf( ! options.genC, "Unique expressions should not reach code generation." );
     831                assertf( ! genC, "Unique expressions should not reach code generation." );
    839832                expr->callExpr->accept( *visitor );
    840833        }
    841834
    842835        void CodeGenerator::postvisit( DeletedExpr * expr ) {
    843                 assertf( ! options.genC, "Deleted expressions should not reach code generation." );
     836                assertf( ! genC, "Deleted expressions should not reach code generation." );
    844837                expr->expr->accept( *visitor );
    845838        }
    846839
    847840        void CodeGenerator::postvisit( DefaultArgExpr * arg ) {
    848                 assertf( ! options.genC, "Default argument expressions should not reach code generation." );
     841                assertf( ! genC, "Default argument expressions should not reach code generation." );
    849842                arg->expr->accept( *visitor );
    850843        }
    851844
    852845        void CodeGenerator::postvisit( GenericExpr * expr ) {
    853                 assertf( ! options.genC, "C11 _Generic expressions should not reach code generation." );
     846                assertf( ! genC, "C11 _Generic expressions should not reach code generation." );
    854847                output << "_Generic(";
    855848                expr->control->accept( *visitor );
     
    861854                                output << "default: ";
    862855                        } else {
    863                                 output << genType( assoc.type, "", options ) << ": ";
     856                                output << genType( assoc.type, "", pretty, genC ) << ": ";
    864857                        }
    865858                        assoc.expr->accept( *visitor );
     
    896889        void CodeGenerator::postvisit( ExprStmt * exprStmt ) {
    897890                assert( exprStmt );
    898                 if ( options.genC ) {
     891                if ( genC ) {
    899892                        // cast the top-level expression to void to reduce gcc warnings.
    900893                        exprStmt->set_expr( new CastExpr( exprStmt->get_expr() ) );
     
    1006999                  case BranchStmt::FallThrough:
    10071000                  case BranchStmt::FallThroughDefault:
    1008                         assertf( ! options.genC, "fallthru should not reach code generation." );
     1001                        assertf( ! genC, "fallthru should not reach code generation." );
    10091002                  output << "fallthru";
    10101003                        break;
    10111004                } // switch
    10121005                // print branch target for labelled break/continue/fallthru in debug mode
    1013                 if ( ! options.genC && branchStmt->get_type() != BranchStmt::Goto ) {
     1006                if ( ! genC && branchStmt->get_type() != BranchStmt::Goto ) {
    10141007                        if ( ! branchStmt->get_target().empty() ) {
    10151008                                output << " " << branchStmt->get_target();
     
    10281021
    10291022        void CodeGenerator::postvisit( ThrowStmt * throwStmt ) {
    1030                 assertf( ! options.genC, "Throw statements should not reach code generation." );
     1023                assertf( ! genC, "Throw statements should not reach code generation." );
    10311024
    10321025                output << ((throwStmt->get_kind() == ThrowStmt::Terminate) ?
     
    10431036        }
    10441037        void CodeGenerator::postvisit( CatchStmt * stmt ) {
    1045                 assertf( ! options.genC, "Catch statements should not reach code generation." );
     1038                assertf( ! genC, "Catch statements should not reach code generation." );
    10461039
    10471040                output << ((stmt->get_kind() == CatchStmt::Terminate) ?
     
    10601053
    10611054        void CodeGenerator::postvisit( WaitForStmt * stmt ) {
    1062                 assertf( ! options.genC, "Waitfor statements should not reach code generation." );
     1055                assertf( ! genC, "Waitfor statements should not reach code generation." );
    10631056
    10641057                bool first = true;
     
    11061099
    11071100        void CodeGenerator::postvisit( WithStmt * with ) {
    1108                 if ( ! options.genC ) {
     1101                if ( ! genC ) {
    11091102                        output << "with ( ";
    11101103                        genCommaList( with->exprs.begin(), with->exprs.end() );
     
    11721165
    11731166        void CodeGenerator::postvisit( ImplicitCtorDtorStmt * stmt ) {
    1174                 assertf( ! options.genC, "ImplicitCtorDtorStmts should not reach code generation." );
     1167                assertf( ! genC, "ImplicitCtorDtorStmts should not reach code generation." );
    11751168                stmt->callStmt->accept( *visitor );
    11761169        }
Note: See TracChangeset for help on using the changeset viewer.