Ignore:
Timestamp:
May 9, 2019, 4:48:12 PM (5 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, arm-eh, ast-experimental, cleanup-dtors, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
292d599
Parents:
63364d8 (diff), 02af79b0 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' into ctxswitch

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/CodeGen/CodeGenerator.cc

    r63364d8 rb038fe4  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat May  5 09:08:32 2018
    13 // Update Count     : 494
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Thr May  2 10:47:00 2019
     13// Update Count     : 497
    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( 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 ) {}
    119120
    120121        string CodeGenerator::mangleName( DeclarationWithType * decl ) {
    121122                // GCC builtins should always be printed unmangled
    122                 if ( pretty || decl->linkage.is_gcc_builtin ) return decl->name;
     123                if ( options.pretty || decl->linkage.is_gcc_builtin ) return decl->name;
    123124                if ( decl->mangleName != "" ) {
    124125                        // need to incorporate scope level in order to differentiate names for destructors
     
    164165                previsit( (BaseSyntaxNode *)node );
    165166                GuardAction( [this, node](){
    166                         if ( printExprTypes && node->result ) {
    167                                 output << " /* " << genType( node->result, "", pretty, genC ) << " */ ";
     167                        if ( options.printExprTypes && node->result ) {
     168                                output << " /* " << genType( node->result, "", options ) << " */ ";
    168169                        }
    169170                } );
     
    173174        void CodeGenerator::postvisit( FunctionDecl * functionDecl ) {
    174175                // deleted decls should never be used, so don't print them
    175                 if ( functionDecl->isDeleted && genC ) return;
     176                if ( functionDecl->isDeleted && options.genC ) return;
    176177                extension( functionDecl );
    177178                genAttributes( functionDecl->get_attributes() );
     
    180181                functionDecl->get_funcSpec().print( output );
    181182
    182                 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 );
    183186
    184187                asmName( functionDecl );
     
    194197        void CodeGenerator::postvisit( ObjectDecl * objectDecl ) {
    195198                // deleted decls should never be used, so don't print them
    196                 if ( objectDecl->isDeleted && genC ) return;
    197                 if (objectDecl->get_name().empty() && genC ) {
     199                if ( objectDecl->isDeleted && options.genC ) return;
     200                if (objectDecl->get_name().empty() && options.genC ) {
    198201                        // only generate an anonymous name when generating C code, otherwise it clutters the output too much
    199202                        static UniqueName name = { "__anonymous_object" };
    200203                        objectDecl->set_name( name.newName() );
     204            // Stops unused parameter warnings.
     205            if ( options.anonymousUnused ) {
     206                objectDecl->attributes.push_back( new Attribute( "unused" ) );
     207            }
    201208                }
    202209
     
    205212
    206213                handleStorageClass( objectDecl );
    207                 output << genType( objectDecl->get_type(), mangleName( objectDecl ), pretty, genC );
     214                output << genType( objectDecl->get_type(), mangleName( objectDecl ), options.pretty, options.genC );
    208215
    209216                asmName( objectDecl );
     
    224231
    225232        void CodeGenerator::handleAggregate( AggregateDecl * aggDecl, const std::string & kind ) {
    226                 if( ! aggDecl->parameters.empty() && ! genC ) {
     233                if( ! aggDecl->parameters.empty() && ! options.genC ) {
    227234                        // assertf( ! genC, "Aggregate type parameters should not reach code generation." );
    228235                        output << "forall(";
     
    294301
    295302        void CodeGenerator::postvisit( TraitDecl * traitDecl ) {
    296                 assertf( ! genC, "TraitDecls should not reach code generation." );
     303                assertf( ! options.genC, "TraitDecls should not reach code generation." );
    297304                extension( traitDecl );
    298305                handleAggregate( traitDecl, "trait " );
     
    300307
    301308        void CodeGenerator::postvisit( TypedefDecl * typeDecl ) {
    302                 assertf( ! genC, "Typedefs are removed and substituted in earlier passes." );
     309                assertf( ! options.genC, "Typedefs are removed and substituted in earlier passes." );
    303310                output << "typedef ";
    304                 output << genType( typeDecl->get_base(), typeDecl->get_name(), pretty, genC ) << endl;
     311                output << genType( typeDecl->get_base(), typeDecl->get_name(), options ) << endl;
    305312        }
    306313
    307314        void CodeGenerator::postvisit( TypeDecl * typeDecl ) {
    308                 assertf( ! genC, "TypeDecls should not reach code generation." );
     315                assertf( ! options.genC, "TypeDecls should not reach code generation." );
    309316                output << typeDecl->genTypeString() << " " << typeDecl->name;
    310317                if ( typeDecl->sized ) {
     
    371378
    372379        void CodeGenerator::postvisit( ConstructorInit * init ){
    373                 assertf( ! genC, "ConstructorInit nodes should not reach code generation." );
     380                assertf( ! options.genC, "ConstructorInit nodes should not reach code generation." );
    374381                // pseudo-output for constructor/destructor pairs
    375382                output << "<ctorinit>{" << endl << ++indent << "ctor: ";
     
    507514                                        } else {
    508515                                                // no constructors with 0 or more than 2 parameters
    509                                                 assertf( ! genC, "UntypedExpr constructor/destructor with 0 or more than 2 parameters." );
     516                                                assertf( ! options.genC, "UntypedExpr constructor/destructor with 0 or more than 2 parameters." );
    510517                                                output << "(";
    511518                                                (*arg++)->accept( *visitor );
     
    604611                        // an lvalue cast, this has been taken out.
    605612                        output << "(";
    606                         output << genType( castExpr->get_result(), "", pretty, genC );
     613                        output << genType( castExpr->get_result(), "", options );
    607614                        output << ")";
    608615                } // if
     
    612619
    613620        void CodeGenerator::postvisit( KeywordCastExpr * castExpr ) {
    614                 assertf( ! genC, "KeywordCast should not reach code generation." );
     621                assertf( ! options.genC, "KeywordCast should not reach code generation." );
    615622                extension( castExpr );
    616623                output << "((" << castExpr->targetString() << " &)";
     
    620627
    621628        void CodeGenerator::postvisit( VirtualCastExpr * castExpr ) {
    622                 assertf( ! genC, "VirtualCastExpr should not reach code generation." );
     629                assertf( ! options.genC, "VirtualCastExpr should not reach code generation." );
    623630                extension( castExpr );
    624631                output << "(virtual ";
     
    628635
    629636        void CodeGenerator::postvisit( UntypedMemberExpr * memberExpr ) {
    630                 assertf( ! genC, "UntypedMemberExpr should not reach code generation." );
     637                assertf( ! options.genC, "UntypedMemberExpr should not reach code generation." );
    631638                extension( memberExpr );
    632639                memberExpr->get_aggregate()->accept( *visitor );
     
    661668                output << "sizeof(";
    662669                if ( sizeofExpr->get_isType() ) {
    663                         output << genType( sizeofExpr->get_type(), "", pretty, genC );
     670                        output << genType( sizeofExpr->get_type(), "", options );
    664671                } else {
    665672                        sizeofExpr->get_expr()->accept( *visitor );
     
    673680                output << "__alignof__(";
    674681                if ( alignofExpr->get_isType() ) {
    675                         output << genType( alignofExpr->get_type(), "", pretty, genC );
     682                        output << genType( alignofExpr->get_type(), "", options );
    676683                } else {
    677684                        alignofExpr->get_expr()->accept( *visitor );
     
    681688
    682689        void CodeGenerator::postvisit( UntypedOffsetofExpr * offsetofExpr ) {
    683                 assertf( ! genC, "UntypedOffsetofExpr should not reach code generation." );
     690                assertf( ! options.genC, "UntypedOffsetofExpr should not reach code generation." );
    684691                output << "offsetof(";
    685                 output << genType( offsetofExpr->get_type(), "", pretty, genC );
     692                output << genType( offsetofExpr->get_type(), "", options );
    686693                output << ", " << offsetofExpr->get_member();
    687694                output << ")";
     
    691698                // use GCC builtin
    692699                output << "__builtin_offsetof(";
    693                 output << genType( offsetofExpr->get_type(), "", pretty, genC );
     700                output << genType( offsetofExpr->get_type(), "", options );
    694701                output << ", " << mangleName( offsetofExpr->get_member() );
    695702                output << ")";
     
    697704
    698705        void CodeGenerator::postvisit( OffsetPackExpr * offsetPackExpr ) {
    699                 assertf( ! genC, "OffsetPackExpr should not reach code generation." );
    700                 output << "__CFA_offsetpack(" << genType( offsetPackExpr->get_type(), "", pretty, genC ) << ")";
     706                assertf( ! options.genC, "OffsetPackExpr should not reach code generation." );
     707                output << "__CFA_offsetpack(" << genType( offsetPackExpr->get_type(), "", options ) << ")";
    701708        }
    702709
     
    728735                extension( commaExpr );
    729736                output << "(";
    730                 if ( genC ) {
     737                if ( options.genC ) {
    731738                        // arg1 of a CommaExpr is never used, so it can be safely cast to void to reduce gcc warnings.
    732739                        commaExpr->set_arg1( new CastExpr( commaExpr->get_arg1() ) );
     
    739746
    740747        void CodeGenerator::postvisit( TupleAssignExpr * tupleExpr ) {
    741                 assertf( ! genC, "TupleAssignExpr should not reach code generation." );
     748                assertf( ! options.genC, "TupleAssignExpr should not reach code generation." );
    742749                tupleExpr->stmtExpr->accept( *visitor );
    743750        }
    744751
    745752        void CodeGenerator::postvisit( UntypedTupleExpr * tupleExpr ) {
    746                 assertf( ! genC, "UntypedTupleExpr should not reach code generation." );
     753                assertf( ! options.genC, "UntypedTupleExpr should not reach code generation." );
    747754                extension( tupleExpr );
    748755                output << "[";
     
    752759
    753760        void CodeGenerator::postvisit( TupleExpr * tupleExpr ) {
    754                 assertf( ! genC, "TupleExpr should not reach code generation." );
     761                assertf( ! options.genC, "TupleExpr should not reach code generation." );
    755762                extension( tupleExpr );
    756763                output << "[";
     
    760767
    761768        void CodeGenerator::postvisit( TupleIndexExpr * tupleExpr ) {
    762                 assertf( ! genC, "TupleIndexExpr should not reach code generation." );
     769                assertf( ! options.genC, "TupleIndexExpr should not reach code generation." );
    763770                extension( tupleExpr );
    764771                tupleExpr->get_tuple()->accept( *visitor );
     
    767774
    768775        void CodeGenerator::postvisit( TypeExpr * typeExpr ) {
    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 );
     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 );
    773780                }
    774781        }
     
    788795        void CodeGenerator::postvisit( CompoundLiteralExpr *compLitExpr ) {
    789796                assert( compLitExpr->get_result() && dynamic_cast< ListInit * > ( compLitExpr->get_initializer() ) );
    790                 output << "(" << genType( compLitExpr->get_result(), "", pretty, genC ) << ")";
     797                output << "(" << genType( compLitExpr->get_result(), "", options ) << ")";
    791798                compLitExpr->get_initializer()->accept( *visitor );
    792799        }
    793800
    794801        void CodeGenerator::postvisit( UniqueExpr * unqExpr ) {
    795                 assertf( ! genC, "Unique expressions should not reach code generation." );
     802                assertf( ! options.genC, "Unique expressions should not reach code generation." );
    796803                output << "unq<" << unqExpr->get_id() << ">{ ";
    797804                unqExpr->get_expr()->accept( *visitor );
     
    829836
    830837        void CodeGenerator::postvisit( ConstructorExpr * expr ) {
    831                 assertf( ! genC, "Unique expressions should not reach code generation." );
     838                assertf( ! options.genC, "Unique expressions should not reach code generation." );
    832839                expr->callExpr->accept( *visitor );
    833840        }
    834841
    835842        void CodeGenerator::postvisit( DeletedExpr * expr ) {
    836                 assertf( ! genC, "Deleted expressions should not reach code generation." );
     843                assertf( ! options.genC, "Deleted expressions should not reach code generation." );
    837844                expr->expr->accept( *visitor );
    838845        }
    839846
    840847        void CodeGenerator::postvisit( DefaultArgExpr * arg ) {
    841                 assertf( ! genC, "Default argument expressions should not reach code generation." );
     848                assertf( ! options.genC, "Default argument expressions should not reach code generation." );
    842849                arg->expr->accept( *visitor );
    843850        }
    844851
    845852        void CodeGenerator::postvisit( GenericExpr * expr ) {
    846                 assertf( ! genC, "C11 _Generic expressions should not reach code generation." );
     853                assertf( ! options.genC, "C11 _Generic expressions should not reach code generation." );
    847854                output << "_Generic(";
    848855                expr->control->accept( *visitor );
     
    854861                                output << "default: ";
    855862                        } else {
    856                                 output << genType( assoc.type, "", pretty, genC ) << ": ";
     863                                output << genType( assoc.type, "", options ) << ": ";
    857864                        }
    858865                        assoc.expr->accept( *visitor );
     
    889896        void CodeGenerator::postvisit( ExprStmt * exprStmt ) {
    890897                assert( exprStmt );
    891                 if ( genC ) {
     898                if ( options.genC ) {
    892899                        // cast the top-level expression to void to reduce gcc warnings.
    893900                        exprStmt->set_expr( new CastExpr( exprStmt->get_expr() ) );
     
    9991006                  case BranchStmt::FallThrough:
    10001007                  case BranchStmt::FallThroughDefault:
    1001                         assertf( ! genC, "fallthru should not reach code generation." );
     1008                        assertf( ! options.genC, "fallthru should not reach code generation." );
    10021009                  output << "fallthru";
    10031010                        break;
    10041011                } // switch
    10051012                // print branch target for labelled break/continue/fallthru in debug mode
    1006                 if ( ! genC && branchStmt->get_type() != BranchStmt::Goto ) {
     1013                if ( ! options.genC && branchStmt->get_type() != BranchStmt::Goto ) {
    10071014                        if ( ! branchStmt->get_target().empty() ) {
    10081015                                output << " " << branchStmt->get_target();
     
    10211028
    10221029        void CodeGenerator::postvisit( ThrowStmt * throwStmt ) {
    1023                 assertf( ! genC, "Throw statements should not reach code generation." );
     1030                assertf( ! options.genC, "Throw statements should not reach code generation." );
    10241031
    10251032                output << ((throwStmt->get_kind() == ThrowStmt::Terminate) ?
     
    10361043        }
    10371044        void CodeGenerator::postvisit( CatchStmt * stmt ) {
    1038                 assertf( ! genC, "Catch statements should not reach code generation." );
     1045                assertf( ! options.genC, "Catch statements should not reach code generation." );
    10391046
    10401047                output << ((stmt->get_kind() == CatchStmt::Terminate) ?
     
    10531060
    10541061        void CodeGenerator::postvisit( WaitForStmt * stmt ) {
    1055                 assertf( ! genC, "Waitfor statements should not reach code generation." );
     1062                assertf( ! options.genC, "Waitfor statements should not reach code generation." );
    10561063
    10571064                bool first = true;
     
    10991106
    11001107        void CodeGenerator::postvisit( WithStmt * with ) {
    1101                 if ( ! genC ) {
     1108                if ( ! options.genC ) {
    11021109                        output << "with ( ";
    11031110                        genCommaList( with->exprs.begin(), with->exprs.end() );
     
    11651172
    11661173        void CodeGenerator::postvisit( ImplicitCtorDtorStmt * stmt ) {
    1167                 assertf( ! genC, "ImplicitCtorDtorStmts should not reach code generation." );
     1174                assertf( ! options.genC, "ImplicitCtorDtorStmts should not reach code generation." );
    11681175                stmt->callStmt->accept( *visitor );
    11691176        }
Note: See TracChangeset for help on using the changeset viewer.