Changeset 8d182b1 for src/CodeGen


Ignore:
Timestamp:
Nov 14, 2023, 12:19:09 PM (2 years ago)
Author:
caparson <caparson@…>
Branches:
master
Children:
1ccae59, 89a8bab
Parents:
df8ba61a (diff), 5625427 (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' of plg.uwaterloo.ca:software/cfa/cfa-cc

Location:
src/CodeGen
Files:
3 deleted
12 edited

Legend:

Unmodified
Added
Removed
  • src/CodeGen/CodeGeneratorNew.cpp

    rdf8ba61a r8d182b1  
    2424namespace CodeGen {
    2525
    26 int CodeGenerator_new::tabsize = 4;
     26int CodeGenerator::tabsize = 4;
    2727
    2828// The kinds of statements that should be followed by whitespace.
     
    3535}
    3636
    37 void CodeGenerator_new::extension( ast::Expr const * expr ) {
     37void CodeGenerator::extension( ast::Expr const * expr ) {
    3838        if ( expr->extension ) output << "__extension__ ";
    3939}
    4040
    41 void CodeGenerator_new::extension( ast::Decl const * decl ) {
     41void CodeGenerator::extension( ast::Decl const * decl ) {
    4242        if ( decl->extension ) output << "__extension__ ";
    4343}
    4444
    45 void CodeGenerator_new::asmName( ast::DeclWithType const * decl ) {
     45void CodeGenerator::asmName( ast::DeclWithType const * decl ) {
    4646        if ( auto asmName = decl->asmName.as<ast::ConstantExpr>() ) {
    4747                output << " asm ( " << asmName->rep << " )";
     
    4949}
    5050
    51 CodeGenerator_new::LabelPrinter & CodeGenerator_new::LabelPrinter::operator()(
     51CodeGenerator::LabelPrinter & CodeGenerator::LabelPrinter::operator()(
    5252                std::vector<ast::Label> const & l ) {
    5353        labels = &l;
     
    5555}
    5656
    57 std::ostream & CodeGenerator_new::LabelPrinter::operator()( std::ostream & output ) const {
     57std::ostream & CodeGenerator::LabelPrinter::operator()( std::ostream & output ) const {
    5858        const std::vector<ast::Label> & labels = *this->labels;
    5959        for ( const ast::Label & label : labels ) {
     
    6666// Using updateLocation at the beginning of a node and endl within a node
    6767// should become the method of formating.
    68 void CodeGenerator_new::updateLocation( CodeLocation const & to ) {
     68void CodeGenerator::updateLocation( CodeLocation const & to ) {
    6969        // Skip if linemarks shouldn't appear or if location is unset.
    7070        if ( !options.lineMarks || to.isUnset() ) return;
     
    8686}
    8787
    88 void CodeGenerator_new::updateLocation( ast::ParseNode const * to ) {
     88void CodeGenerator::updateLocation( ast::ParseNode const * to ) {
    8989        updateLocation( to->location );
    9090}
    9191
    92 std::ostream & CodeGenerator_new::LineEnder::operator()( std::ostream & os ) const {
     92std::ostream & CodeGenerator::LineEnder::operator()( std::ostream & os ) const {
    9393        os << "\n" << std::flush;
    9494        cg.currentLocation.first_line++;
     
    9696}
    9797
    98 CodeGenerator_new::CodeGenerator_new( std::ostream & os, const Options & options ) :
    99                 indent( 0, CodeGenerator_new::tabsize ), output( os ),
     98CodeGenerator::CodeGenerator( std::ostream & os, const Options & options ) :
     99                indent( 0, CodeGenerator::tabsize ), output( os ),
    100100                options( options ), printLabels( *this ), endl( *this )
    101101{}
    102102
    103 std::string CodeGenerator_new::mangleName( ast::DeclWithType const * decl ) {
     103std::string CodeGenerator::mangleName( ast::DeclWithType const * decl ) {
    104104        // GCC builtins should always be printed unmangled.
    105105        if ( options.pretty || decl->linkage.is_gcc_builtin ) {
     
    112112}
    113113
    114 void CodeGenerator_new::genAttributes(
     114void CodeGenerator::genAttributes(
    115115                const std::vector<ast::ptr<ast::Attribute>> & attributes ) {
    116116        if ( attributes.empty() ) return;
     
    129129}
    130130
    131 void CodeGenerator_new::previsit( ast::Node const * ) {
     131void CodeGenerator::previsit( ast::Node const * ) {
    132132        // All traversal is manual.
    133133        // TODO: Which means the ast::Pass is just providing a default no visit?
     
    135135}
    136136
    137 void CodeGenerator_new::previsit( ast::ParseNode const * node ) {
     137void CodeGenerator::previsit( ast::ParseNode const * node ) {
    138138        previsit( (ast::Node const *)node );
    139139        updateLocation( node );
    140140}
    141141
    142 void CodeGenerator_new::postvisit( ast::Node const * node ) {
     142void CodeGenerator::postvisit( ast::Node const * node ) {
    143143        std::stringstream ss;
    144144        ast::print( ss, node );
     
    146146}
    147147
    148 void CodeGenerator_new::previsit( ast::Expr const * expr ) {
     148void CodeGenerator::previsit( ast::Expr const * expr ) {
    149149        previsit( (ast::ParseNode const *)expr );
    150150        GuardAction( [this, expr](){
     
    155155}
    156156
    157 void CodeGenerator_new::postvisit( ast::FunctionDecl const * decl ) {
     157void CodeGenerator::postvisit( ast::FunctionDecl const * decl ) {
    158158        // Deleted decls should never be used, so don't print them in C.
    159159        if ( decl->isDeleted && options.genC ) return;
     
    168168
    169169        std::ostringstream acc;
    170         ast::Pass<CodeGenerator_new> subCG( acc, subOptions );
     170        ast::Pass<CodeGenerator> subCG( acc, subOptions );
    171171        // Add the forall clause.
    172172        // TODO: These probably should be removed by now and the assert used.
     
    213213}
    214214
    215 //void CodeGenerator_new::postvisit( ast::ObjectDecl const * decl_ ) {
    216 ast::ObjectDecl const * CodeGenerator_new::postvisit(
     215ast::ObjectDecl const * CodeGenerator::postvisit(
    217216                ast::ObjectDecl const * decl ) {
    218217        // Deleted decls should never be used, so don't print them in C.
     
    262261}
    263262
    264 void CodeGenerator_new::handleStorageClass( ast::DeclWithType const * decl ) {
     263void CodeGenerator::handleStorageClass( ast::DeclWithType const * decl ) {
    265264        if ( decl->storage.any() ) {
    266265                ast::print( output, decl->storage );
     
    268267}
    269268
    270 void CodeGenerator_new::handleAggregate(
     269void CodeGenerator::handleAggregate(
    271270                ast::AggregateDecl const * decl, std::string const & kind ) {
    272271        if ( !decl->params.empty() && !options.genC ) {
     
    296295}
    297296
    298 void CodeGenerator_new::postvisit( ast::StructDecl const * decl ) {
     297void CodeGenerator::postvisit( ast::StructDecl const * decl ) {
    299298        extension( decl );
    300299        handleAggregate( decl, "struct " );
    301300}
    302301
    303 void CodeGenerator_new::postvisit( ast::UnionDecl const * decl ) {
     302void CodeGenerator::postvisit( ast::UnionDecl const * decl ) {
    304303        extension( decl );
    305304        handleAggregate( decl, "union " );
     
    332331}
    333332
    334 void CodeGenerator_new::postvisit( ast::EnumDecl const * decl ) {
     333void CodeGenerator::postvisit( ast::EnumDecl const * decl ) {
    335334        extension( decl );
    336335        auto members = decl->members;
     
    370369}
    371370
    372 void CodeGenerator_new::postvisit( ast::TraitDecl const * decl ) {
     371void CodeGenerator::postvisit( ast::TraitDecl const * decl ) {
    373372        assertf( !options.genC, "TraitDecls should not reach code generation." );
    374373        extension( decl );
     
    376375}
    377376
    378 void CodeGenerator_new::postvisit( ast::TypedefDecl const * decl ) {
     377void CodeGenerator::postvisit( ast::TypedefDecl const * decl ) {
    379378        assertf( !options.genC, "Typedefs should not reach code generation." );
    380379        output << "typedef " << genType( decl->base, decl->name, options ) << endl;
    381380}
    382381
    383 void CodeGenerator_new::postvisit( ast::TypeDecl const * decl ) {
     382void CodeGenerator::postvisit( ast::TypeDecl const * decl ) {
    384383        assertf( !options.genC, "TypeDecls should not reach code generation." );
    385384        output << decl->genTypeString() << " " << decl->name;
     
    397396}
    398397
    399 void CodeGenerator_new::postvisit( ast::StaticAssertDecl const * decl ) {
     398void CodeGenerator::postvisit( ast::StaticAssertDecl const * decl ) {
    400399        output << "_Static_assert(";
    401400        decl->cond->accept( *visitor );
     
    405404}
    406405
    407 void CodeGenerator_new::postvisit( ast::Designation const * designation ) {
     406void CodeGenerator::postvisit( ast::Designation const * designation ) {
    408407        auto designators = designation->designators;
    409408        if ( 0 == designators.size() ) return;
     
    423422}
    424423
    425 void CodeGenerator_new::postvisit( ast::SingleInit const * init ) {
     424void CodeGenerator::postvisit( ast::SingleInit const * init ) {
    426425        init->value->accept( *visitor );
    427426}
    428427
    429 void CodeGenerator_new::postvisit( ast::ListInit const * init ) {
     428void CodeGenerator::postvisit( ast::ListInit const * init ) {
    430429        auto initBegin = init->initializers.begin();
    431430        auto initEnd = init->initializers.end();
     
    446445}
    447446
    448 void CodeGenerator_new::postvisit( ast::ConstructorInit const * init ) {
     447void CodeGenerator::postvisit( ast::ConstructorInit const * init ) {
    449448        assertf( !options.genC, "ConstructorInit nodes should not reach code generation." );
    450449        // This isn't actual code, but labels the constructor/destructor pairs.
     
    456455}
    457456
    458 void CodeGenerator_new::postvisit( ast::ApplicationExpr const * expr ) {
     457void CodeGenerator::postvisit( ast::ApplicationExpr const * expr ) {
    459458        extension( expr );
    460459        if ( auto var = expr->func.as<ast::VariableExpr>() ) {
     
    550549}
    551550
    552 void CodeGenerator_new::postvisit( ast::UntypedExpr const * expr ) {
     551void CodeGenerator::postvisit( ast::UntypedExpr const * expr ) {
    553552        extension( expr );
    554553        if ( auto name = expr->func.as<ast::NameExpr>() ) {
     
    638637}
    639638
    640 void CodeGenerator_new::postvisit( ast::RangeExpr const * expr ) {
     639void CodeGenerator::postvisit( ast::RangeExpr const * expr ) {
    641640        expr->low->accept( *visitor );
    642641        output << " ... ";
     
    644643}
    645644
    646 void CodeGenerator_new::postvisit( ast::NameExpr const * expr ) {
     645void CodeGenerator::postvisit( ast::NameExpr const * expr ) {
    647646        extension( expr );
    648647        if ( const OperatorInfo * opInfo = operatorLookup( expr->name ) ) {
     
    657656}
    658657
    659 void CodeGenerator_new::postvisit( ast::DimensionExpr const * expr ) {
     658void CodeGenerator::postvisit( ast::DimensionExpr const * expr ) {
    660659        extension( expr );
    661660        output << "/*non-type*/" << expr->name;
    662661}
    663662
    664 void CodeGenerator_new::postvisit( ast::AddressExpr const * expr ) {
     663void CodeGenerator::postvisit( ast::AddressExpr const * expr ) {
    665664        extension( expr );
    666665        output << "(&";
     
    669668}
    670669
    671 void CodeGenerator_new::postvisit( ast::LabelAddressExpr const * expr ) {
     670void CodeGenerator::postvisit( ast::LabelAddressExpr const * expr ) {
    672671        extension( expr );
    673672        output << "(&&" << expr->arg << ")";
    674673}
    675674
    676 void CodeGenerator_new::postvisit( ast::CastExpr const * expr ) {
     675void CodeGenerator::postvisit( ast::CastExpr const * expr ) {
    677676        extension( expr );
    678677        output << "(";
     
    688687}
    689688
    690 void CodeGenerator_new::postvisit( ast::KeywordCastExpr const * expr ) {
     689void CodeGenerator::postvisit( ast::KeywordCastExpr const * expr ) {
    691690        assertf( !options.genC, "KeywordCastExpr should not reach code generation." );
    692691        extension( expr );
     
    696695}
    697696
    698 void CodeGenerator_new::postvisit( ast::VirtualCastExpr const * expr ) {
     697void CodeGenerator::postvisit( ast::VirtualCastExpr const * expr ) {
    699698        assertf( !options.genC, "VirtualCastExpr should not reach code generation." );
    700699        extension( expr );
     
    705704}
    706705
    707 void CodeGenerator_new::postvisit( ast::UntypedMemberExpr const * expr ) {
     706void CodeGenerator::postvisit( ast::UntypedMemberExpr const * expr ) {
    708707        assertf( !options.genC, "UntypedMemberExpr should not reach code generation." );
    709708        extension( expr );
     
    713712}
    714713
    715 void CodeGenerator_new::postvisit( ast::MemberExpr const * expr ) {
     714void CodeGenerator::postvisit( ast::MemberExpr const * expr ) {
    716715        extension( expr );
    717716        expr->aggregate->accept( *visitor );
     
    719718}
    720719
    721 void CodeGenerator_new::postvisit( ast::VariableExpr const * expr ) {
     720void CodeGenerator::postvisit( ast::VariableExpr const * expr ) {
    722721        extension( expr );
    723722        const OperatorInfo * opInfo;
     
    733732}
    734733
    735 void CodeGenerator_new::postvisit( ast::ConstantExpr const * expr ) {
     734void CodeGenerator::postvisit( ast::ConstantExpr const * expr ) {
    736735        extension( expr );
    737736        output << expr->rep;
    738737}
    739738
    740 void CodeGenerator_new::postvisit( ast::SizeofExpr const * expr ) {
     739void CodeGenerator::postvisit( ast::SizeofExpr const * expr ) {
    741740        extension( expr );
    742741        output << "sizeof(";
     
    749748}
    750749
    751 void CodeGenerator_new::postvisit( ast::AlignofExpr const * expr ) {
     750void CodeGenerator::postvisit( ast::AlignofExpr const * expr ) {
    752751        // Using the GCC extension to avoid changing the std to C11.
    753752        extension( expr );
     
    761760}
    762761
    763 void CodeGenerator_new::postvisit( ast::UntypedOffsetofExpr const * expr ) {
     762void CodeGenerator::postvisit( ast::UntypedOffsetofExpr const * expr ) {
    764763        assertf( !options.genC, "UntypedOffsetofExpr should not reach code generation." );
    765764        output << "offsetof(";
     
    769768}
    770769
    771 void CodeGenerator_new::postvisit( ast::OffsetofExpr const * expr ) {
     770void CodeGenerator::postvisit( ast::OffsetofExpr const * expr ) {
    772771        // Use GCC builtin
    773772        output << "__builtin_offsetof(";
     
    777776}
    778777
    779 void CodeGenerator_new::postvisit( ast::OffsetPackExpr const * expr ) {
     778void CodeGenerator::postvisit( ast::OffsetPackExpr const * expr ) {
    780779        assertf( !options.genC, "OffsetPackExpr should not reach code generation." );
    781780        output << "__CFA_offsetpack(" << genType( expr->type, "", options ) << ")";
    782781}
    783782
    784 void CodeGenerator_new::postvisit( ast::LogicalExpr const * expr ) {
     783void CodeGenerator::postvisit( ast::LogicalExpr const * expr ) {
    785784        extension( expr );
    786785        output << "(";
     
    791790}
    792791
    793 void CodeGenerator_new::postvisit( ast::ConditionalExpr const * expr ) {
     792void CodeGenerator::postvisit( ast::ConditionalExpr const * expr ) {
    794793        extension( expr );
    795794        output << "(";
     
    802801}
    803802
    804 void CodeGenerator_new::postvisit( ast::CommaExpr const * expr ) {
     803void CodeGenerator::postvisit( ast::CommaExpr const * expr ) {
    805804        extension( expr );
    806805        output << "(";
     
    818817}
    819818
    820 void CodeGenerator_new::postvisit( ast::TupleAssignExpr const * expr ) {
     819void CodeGenerator::postvisit( ast::TupleAssignExpr const * expr ) {
    821820        assertf( !options.genC, "TupleAssignExpr should not reach code generation." );
    822821        expr->stmtExpr->accept( *visitor );
    823822}
    824823
    825 void CodeGenerator_new::postvisit( ast::UntypedTupleExpr const * expr ) {
     824void CodeGenerator::postvisit( ast::UntypedTupleExpr const * expr ) {
    826825        assertf( !options.genC, "UntypedTupleExpr should not reach code generation." );
    827826        extension( expr );
     
    831830}
    832831
    833 void CodeGenerator_new::postvisit( ast::TupleExpr const * expr ) {
     832void CodeGenerator::postvisit( ast::TupleExpr const * expr ) {
    834833        assertf( !options.genC, "TupleExpr should not reach code generation." );
    835834        extension( expr );
     
    839838}
    840839
    841 void CodeGenerator_new::postvisit( ast::TupleIndexExpr const * expr ) {
     840void CodeGenerator::postvisit( ast::TupleIndexExpr const * expr ) {
    842841        assertf( !options.genC, "TupleIndexExpr should not reach code generation." );
    843842        extension( expr );
     
    846845}
    847846
    848 void CodeGenerator_new::postvisit( ast::TypeExpr const * expr ) {
     847void CodeGenerator::postvisit( ast::TypeExpr const * expr ) {
    849848        // TODO: Should there be an assertion there?
    850849        if ( !options.genC ) {
     
    853852}
    854853
    855 void CodeGenerator_new::postvisit( ast::AsmExpr const * expr ) {
     854void CodeGenerator::postvisit( ast::AsmExpr const * expr ) {
    856855        if ( !expr->inout.empty() ) {
    857856                output << "[ " << expr->inout << " ] ";
     
    863862}
    864863
    865 void CodeGenerator_new::postvisit( ast::CompoundLiteralExpr const * expr ) {
     864void CodeGenerator::postvisit( ast::CompoundLiteralExpr const * expr ) {
    866865        //assert( expr->result && dynamic_cast<ast::ListInit const *>( expr->init ) );
    867866        assert( expr->result && expr->init.as<ast::ListInit>() );
     
    870869}
    871870
    872 void CodeGenerator_new::postvisit( ast::UniqueExpr const * expr ) {
     871void CodeGenerator::postvisit( ast::UniqueExpr const * expr ) {
    873872        assertf( !options.genC, "UniqueExpr should not reach code generation." );
    874873        output << "unq<" << expr->id << ">{ ";
     
    877876}
    878877
    879 void CodeGenerator_new::postvisit( ast::StmtExpr const * expr ) {
     878void CodeGenerator::postvisit( ast::StmtExpr const * expr ) {
    880879        auto stmts = expr->stmts->kids;
    881880        output << "({" << endl;
     
    905904}
    906905
    907 void CodeGenerator_new::postvisit( ast::ConstructorExpr const * expr ) {
     906void CodeGenerator::postvisit( ast::ConstructorExpr const * expr ) {
    908907        assertf( !options.genC, "ConstructorExpr should not reach code generation." );
    909908        expr->callExpr->accept( *visitor );
    910909}
    911910
    912 void CodeGenerator_new::postvisit( ast::DeletedExpr const * expr ) {
     911void CodeGenerator::postvisit( ast::DeletedExpr const * expr ) {
    913912        assertf( !options.genC, "DeletedExpr should not reach code generation." );
    914913        expr->expr->accept( *visitor );
    915914}
    916915
    917 void CodeGenerator_new::postvisit( ast::DefaultArgExpr const * expr ) {
     916void CodeGenerator::postvisit( ast::DefaultArgExpr const * expr ) {
    918917        assertf( !options.genC, "DefaultArgExpr should not reach code generation." );
    919918        expr->expr->accept( *visitor );
    920919}
    921920
    922 void CodeGenerator_new::postvisit( ast::GenericExpr const * expr ) {
     921void CodeGenerator::postvisit( ast::GenericExpr const * expr ) {
    923922        assertf( !options.genC, "GenericExpr should not reach code generation." );
    924923        output << "_Generic(";
     
    940939}
    941940
    942 void CodeGenerator_new::postvisit( ast::CompoundStmt const * stmt ) {
     941void CodeGenerator::postvisit( ast::CompoundStmt const * stmt ) {
    943942        output << "{" << endl;
    944943
     
    955954}
    956955
    957 void CodeGenerator_new::postvisit( ast::ExprStmt const * stmt ) {
     956void CodeGenerator::postvisit( ast::ExprStmt const * stmt ) {
    958957        assert( stmt );
    959958        // Cast the top-level expression to void to reduce gcc warnings.
     
    967966}
    968967
    969 void CodeGenerator_new::postvisit( ast::AsmStmt const * stmt ) {
     968void CodeGenerator::postvisit( ast::AsmStmt const * stmt ) {
    970969        output << "asm ";
    971970        if ( stmt->isVolatile ) output << "volatile ";
     
    991990}
    992991
    993 void CodeGenerator_new::postvisit( ast::AsmDecl const * decl ) {
     992void CodeGenerator::postvisit( ast::AsmDecl const * decl ) {
    994993        output << "asm ";
    995994        ast::AsmStmt const * stmt = decl->stmt;
     
    999998}
    1000999
    1001 void CodeGenerator_new::postvisit( ast::DirectiveDecl const * decl ) {
     1000void CodeGenerator::postvisit( ast::DirectiveDecl const * decl ) {
    10021001        // endl prevents spaces before the directive.
    10031002        output << endl << decl->stmt->directive;
    10041003}
    10051004
    1006 void CodeGenerator_new::postvisit( ast::DirectiveStmt const * stmt ) {
     1005void CodeGenerator::postvisit( ast::DirectiveStmt const * stmt ) {
    10071006        // endl prevents spaces before the directive.
    10081007        output << endl << stmt->directive;
    10091008}
    10101009
    1011 void CodeGenerator_new::postvisit( ast::IfStmt const * stmt ) {
     1010void CodeGenerator::postvisit( ast::IfStmt const * stmt ) {
    10121011        output << "if ( ";
    10131012        stmt->cond->accept( *visitor );
     
    10221021}
    10231022
    1024 void CodeGenerator_new::postvisit( ast::SwitchStmt const * stmt ) {
     1023void CodeGenerator::postvisit( ast::SwitchStmt const * stmt ) {
    10251024        output << "switch ( ";
    10261025        stmt->cond->accept( *visitor );
     
    10361035}
    10371036
    1038 void CodeGenerator_new::postvisit( ast::CaseClause const * clause ) {
     1037void CodeGenerator::postvisit( ast::CaseClause const * clause ) {
    10391038        updateLocation( clause );
    10401039        output << indent;
     
    10561055}
    10571056
    1058 void CodeGenerator_new::postvisit( ast::BranchStmt const * stmt ) {
     1057void CodeGenerator::postvisit( ast::BranchStmt const * stmt ) {
    10591058        switch ( stmt->kind ) {
    10601059        case ast::BranchStmt::Goto:
     
    10911090}
    10921091
    1093 void CodeGenerator_new::postvisit( ast::ReturnStmt const * stmt ) {
     1092void CodeGenerator::postvisit( ast::ReturnStmt const * stmt ) {
    10941093        output << "return ";
    10951094        if ( stmt->expr ) stmt->expr->accept( *visitor );
     
    10971096}
    10981097
    1099 void CodeGenerator_new::postvisit( ast::ThrowStmt const * stmt ) {
     1098void CodeGenerator::postvisit( ast::ThrowStmt const * stmt ) {
    11001099        assertf( !options.genC, "ThrowStmt should not reach code generation." );
    11011100
     
    11121111}
    11131112
    1114 void CodeGenerator_new::postvisit( ast::CatchClause const * stmt ) {
     1113void CodeGenerator::postvisit( ast::CatchClause const * stmt ) {
    11151114        assertf( !options.genC, "CatchClause should not reach code generation." );
    11161115
     
    11261125}
    11271126
    1128 void CodeGenerator_new::postvisit( ast::WaitForStmt const * stmt ) {
     1127void CodeGenerator::postvisit( ast::WaitForStmt const * stmt ) {
    11291128        assertf( !options.genC, "WaitforStmt should not reach code generation." );
    11301129
     
    11721171}
    11731172
    1174 void CodeGenerator_new::postvisit( ast::WithStmt const * stmt ) {
     1173void CodeGenerator::postvisit( ast::WithStmt const * stmt ) {
    11751174        assertf( !options.genC, "WithStmt should not reach code generation." );
    11761175
     
    11811180}
    11821181
    1183 void CodeGenerator_new::postvisit( ast::WhileDoStmt const * stmt ) {
     1182void CodeGenerator::postvisit( ast::WhileDoStmt const * stmt ) {
    11841183        if ( stmt->isDoWhile ) {
    11851184                output << "do";
     
    11911190        output << " ";
    11921191
    1193         output << CodeGenerator_new::printLabels( stmt->body->labels );
     1192        output << CodeGenerator::printLabels( stmt->body->labels );
    11941193        stmt->body->accept( *visitor );
    11951194
     
    12031202}
    12041203
    1205 void CodeGenerator_new::postvisit( ast::ForStmt const * stmt ) {
     1204void CodeGenerator::postvisit( ast::ForStmt const * stmt ) {
    12061205        // Initializer is always hoised so don't generate it.
    12071206        // TODO: Do an assertion check?
     
    12261225}
    12271226
    1228 void CodeGenerator_new::postvisit( ast::NullStmt const * ) {
     1227void CodeGenerator::postvisit( ast::NullStmt const * ) {
    12291228        output << "/* null statement */ ;";
    12301229}
    12311230
    1232 void CodeGenerator_new::postvisit( ast::DeclStmt const * stmt ) {
     1231void CodeGenerator::postvisit( ast::DeclStmt const * stmt ) {
    12331232        stmt->decl->accept( *visitor );
    12341233
     
    12361235}
    12371236
    1238 void CodeGenerator_new::postvisit( ast::ImplicitCtorDtorStmt const * stmt ) {
     1237void CodeGenerator::postvisit( ast::ImplicitCtorDtorStmt const * stmt ) {
    12391238        assertf( !options.genC, "ImplicitCtorCtorStmt should not reach code generation." );
    12401239        stmt->callStmt->accept( *visitor );
    12411240}
    12421241
    1243 void CodeGenerator_new::postvisit( ast::MutexStmt const * stmt ) {
     1242void CodeGenerator::postvisit( ast::MutexStmt const * stmt ) {
    12441243        assertf( !options.genC, "MutexStmt should not reach code generation." );
    12451244        // TODO: But this isn't what a mutex statement looks like.
  • src/CodeGen/CodeGeneratorNew.hpp

    rdf8ba61a r8d182b1  
    2525namespace CodeGen {
    2626
    27 #warning Remove the _new when old version is removed.
    28 struct CodeGenerator_new :
     27struct CodeGenerator final :
    2928                public ast::WithGuards,
    3029                public ast::WithShortCircuiting,
    31                 public ast::WithVisitorRef<CodeGenerator_new> {
    32         CodeGenerator_new( std::ostream & out, Options const & options );
     30                public ast::WithVisitorRef<CodeGenerator> {
     31        CodeGenerator( std::ostream & out, Options const & options );
    3332
    3433        // Turn off visit_children for all nodes.
     
    119118        /// Custom local implementation of endl that updates print location.
    120119        struct LineEnder {
    121                 CodeGenerator_new & cg;
    122                 LineEnder( CodeGenerator_new & cg ) : cg( cg ) {}
     120                CodeGenerator & cg;
     121                LineEnder( CodeGenerator & cg ) : cg( cg ) {}
    123122                std::ostream & operator()( std::ostream & ) const;
    124123        };
     
    129128        /// Wrapper class to help print vectors of Labels.
    130129        struct LabelPrinter {
    131                 LabelPrinter( CodeGenerator_new & cg ) : cg( cg ), labels( nullptr ) {}
     130                LabelPrinter( CodeGenerator & cg ) : cg( cg ), labels( nullptr ) {}
    132131                LabelPrinter & operator()( std::vector<ast::Label> const & l );
    133132                std::ostream & operator()( std::ostream & ) const;
    134                 CodeGenerator_new & cg;
     133                CodeGenerator & cg;
    135134                std::vector<ast::Label> const * labels;
    136135        };
  • src/CodeGen/FixMain.cc

    rdf8ba61a r8d182b1  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // FixMain.cc --
     7// FixMain.cc -- Tools to change a Cforall main into a C main.
    88//
    99// Author           : Thierry Delisle
     
    2525#include "AST/Type.hpp"
    2626#include "AST/Vector.hpp"
    27 #include "Common/PassVisitor.h"
    2827#include "Common/SemanticError.h"  // for SemanticError
    2928#include "CodeGen/GenType.h"       // for GenType
    30 #include "SynTree/Declaration.h"   // for FunctionDecl, operator<<
    31 #include "SynTree/Type.h"          // for FunctionType
    3229#include "SymTab/Mangler.h"
    3330
     
    3633namespace {
    3734
    38 struct FindMainCore {
    39         FunctionDecl * main_signature = nullptr;
    40 
    41         void previsit( FunctionDecl * decl ) {
    42                 if ( FixMain::isMain( decl ) ) {
    43                         if ( main_signature ) {
    44                                 SemanticError( decl, "Multiple definition of main routine\n" );
    45                         }
    46                         main_signature = decl;
    47                 }
    48         }
    49 };
    50 
    51 struct FindMainCore_new {
     35struct FindMainCore final {
    5236        ast::FunctionDecl const * main_declaration = nullptr;
    5337
    5438        void previsit( ast::FunctionDecl const * decl ) {
    55                 if ( FixMain::isMain( decl ) ) {
     39                if ( isMain( decl ) ) {
    5640                        if ( main_declaration ) {
    5741                                SemanticError( decl, "Multiple definition of main routine\n" );
     
    6549        return genType( types[at], "", Options( false, false, false, false ) );
    6650}
    67 
    68 }
    69 
    70         template<typename container>
    71         std::string genTypeAt(const container& p, size_t idx) {
    72                 return genType((*std::next(p.begin(), idx))->get_type(), "");
    73         }
    74 
    75         void FixMain::fix( std::list< Declaration * > & translationUnit,
    76                         std::ostream &os, const char* bootloader_filename ) {
    77                 PassVisitor< FindMainCore > main_finder;
    78                 acceptAll( translationUnit, main_finder );
    79                 FunctionDecl * main_signature = main_finder.pass.main_signature;
    80 
    81                 if( main_signature ) {
    82                         os << "static inline int invoke_main(int argc, char* argv[], char* envp[]) { (void)argc; (void)argv; (void)envp; return ";
    83                         main_signature->mangleName = SymTab::Mangler::mangle(main_signature);
    84 
    85                         os << main_signature->get_scopedMangleName() << "(";
    86                         const auto& params = main_signature->get_functionType()->get_parameters();
    87                         switch(params.size()) {
    88                                 case 3: os << "(" << genTypeAt(params, 0) << ")argc, (" << genTypeAt(params, 1) << ")argv, (" << genTypeAt(params, 2) << ")envp"; break;
    89                                 case 2: os << "(" << genTypeAt(params, 0) << ")argc, (" << genTypeAt(params, 1) << ")argv"; break;
    90                                 case 0: break;
    91                                 default : assert(false);
    92                         }
    93                         os << "); }\n";
    94 
    95                         std::ifstream bootloader(bootloader_filename, std::ios::in);
    96                         assertf( bootloader.is_open(), "cannot open bootloader.c\n" );
    97                         os << bootloader.rdbuf();
    98                 }
    99         }
    100 
    101 namespace {
    10251
    10352ast::ObjectDecl * makeIntObj(){
     
    157106}
    158107
     108struct FixLinkageCore final {
     109        ast::Linkage::Spec const spec;
     110        FixLinkageCore( ast::Linkage::Spec spec ) : spec( spec ) {}
     111
     112        ast::FunctionDecl const * previsit( ast::FunctionDecl const * decl ) {
     113                if ( decl->name != "main" ) return decl;
     114                return ast::mutate_field( decl, &ast::FunctionDecl::linkage, spec );
     115        }
     116};
     117
    159118} // namespace
    160119
    161 bool FixMain::isMain( FunctionDecl * decl ) {
    162         if ( std::string("main") != decl->name ) {
    163                 return false;
    164         }
    165         return is_main( SymTab::Mangler::mangle( decl, true, true ) );
    166 }
    167 
    168 bool FixMain::isMain( const ast::FunctionDecl * decl ) {
     120bool isMain( const ast::FunctionDecl * decl ) {
    169121        if ( std::string("main") != decl->name ) {
    170122                return false;
     
    173125}
    174126
    175 void FixMain::fix( ast::TranslationUnit & translationUnit,
     127void fixMainLinkage( ast::TranslationUnit & translationUnit,
     128                bool replace_main ) {
     129        ast::Linkage::Spec const spec =
     130                ( replace_main ) ? ast::Linkage::Cforall : ast::Linkage::C;
     131        ast::Pass<FixLinkageCore>::run( translationUnit, spec );
     132}
     133
     134void fixMainInvoke( ast::TranslationUnit & translationUnit,
    176135                std::ostream &os, const char * bootloader_filename ) {
    177136
    178         ast::Pass<FindMainCore_new> main_finder;
     137        ast::Pass<FindMainCore> main_finder;
    179138        ast::accept_all( translationUnit, main_finder );
    180139        if ( nullptr == main_finder.core.main_declaration ) return;
  • src/CodeGen/FixMain.h

    rdf8ba61a r8d182b1  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // FixMain.h --
     7// FixMain.h -- Tools to change a Cforall main into a C main.
    88//
    99// Author           : Thierry Delisle
     
    1717
    1818#include <iosfwd>
    19 #include <memory>
    20 #include <list>
    2119
    22 #include "AST/LinkageSpec.hpp"
    23 #include "SynTree/LinkageSpec.h"
    24 
    25 class Declaration;
    26 class FunctionDecl;
    2720namespace ast {
    2821        class FunctionDecl;
     
    3225namespace CodeGen {
    3326
    34 class FixMain {
    35 public :
    36         static inline LinkageSpec::Spec mainLinkage() {
    37                 return replace_main ? LinkageSpec::Cforall : LinkageSpec::C;
    38         }
    39         static inline ast::Linkage::Spec getMainLinkage() {
    40                 return replace_main ? ast::Linkage::Cforall : ast::Linkage::C;
    41         }
     27/// Is this function a program main function?
     28bool isMain( const ast::FunctionDecl * decl );
    4229
    43         static inline void setReplaceMain(bool val) {
    44                 replace_main = val;
    45         }
     30/// Adjust the linkage of main functions.
     31void fixMainLinkage( ast::TranslationUnit & transUnit, bool replaceMain );
    4632
    47         static bool isMain(FunctionDecl* decl);
    48         static bool isMain(const ast::FunctionDecl * decl);
    49 
    50         static void fix( std::list< Declaration * > & decls,
    51                         std::ostream &os, const char* bootloader_filename );
    52         static void fix( ast::TranslationUnit & translationUnit,
    53                         std::ostream &os, const char * bootloader_filename );
    54 
    55 private:
    56         static bool replace_main;
    57 };
     33/// Add a wrapper around to run the Cforall main.
     34void fixMainInvoke( ast::TranslationUnit & transUnit,
     35                std::ostream & os, const char * bootloaderFilename );
    5836
    5937} // namespace CodeGen
  • src/CodeGen/FixNames.cc

    rdf8ba61a r8d182b1  
    2222#include "AST/Expr.hpp"
    2323#include "AST/Pass.hpp"
    24 #include "Common/PassVisitor.h"
    2524#include "Common/SemanticError.h"  // for SemanticError
    2625#include "FixMain.h"               // for FixMain
    2726#include "SymTab/Mangler.h"        // for Mangler
    28 #include "SynTree/LinkageSpec.h"   // for Cforall, isMangled
    29 #include "SynTree/Constant.h"      // for Constant
    30 #include "SynTree/Declaration.h"   // for FunctionDecl, ObjectDecl, Declarat...
    31 #include "SynTree/Expression.h"    // for ConstantExpr
    32 #include "SynTree/Label.h"         // for Label, noLabels
    33 #include "SynTree/Statement.h"     // for ReturnStmt, CompoundStmt
    34 #include "SynTree/Type.h"          // for Type, BasicType, Type::Qualifiers
    35 #include "SynTree/Visitor.h"       // for Visitor, acceptAll
    3627#include "CompilationState.h"
    3728
    3829namespace CodeGen {
    39         class FixNames : public WithGuards {
    40           public:
    41                 void postvisit( ObjectDecl *objectDecl );
    42                 void postvisit( FunctionDecl *functionDecl );
    4330
    44                 void previsit( CompoundStmt *compoundStmt );
    45           private:
    46                 int scopeLevel = 1;
    47 
    48                 void fixDWT( DeclarationWithType *dwt );
    49         };
    50 
    51         void fixNames( std::list< Declaration* > & translationUnit ) {
    52                 PassVisitor<FixNames> fixer;
    53                 acceptAll( translationUnit, fixer );
    54         }
    55 
    56         void FixNames::fixDWT( DeclarationWithType * dwt ) {
    57                 if ( dwt->get_name() != "" ) {
    58                         if ( LinkageSpec::isMangled( dwt->get_linkage() ) ) {
    59                                 if (!useNewAST) {
    60                                         dwt->set_mangleName( SymTab::Mangler::mangle( dwt ) );
    61                                 }
    62                                 dwt->set_scopeLevel( scopeLevel );
    63                         } // if
    64                 } // if
    65         }
    66 
    67         void FixNames::postvisit( ObjectDecl * objectDecl ) {
    68                 fixDWT( objectDecl );
    69         }
    70 
    71         void FixNames::postvisit( FunctionDecl * functionDecl ) {
    72                 fixDWT( functionDecl );
    73 
    74                 if ( FixMain::isMain( functionDecl ) ) {
    75                         int nargs = functionDecl->get_functionType()->get_parameters().size();
    76                         if( !(nargs == 0 || nargs == 2 || nargs == 3) ) {
    77                                 SemanticError(functionDecl, "Main expected to have 0, 2 or 3 arguments\n");
    78                         }
    79                         functionDecl->get_statements()->get_kids().push_back( new ReturnStmt( new ConstantExpr( Constant::from_int( 0 ) ) ) );
    80                 }
    81         }
    82 
    83         void FixNames::previsit( CompoundStmt * ) {
    84                 scopeLevel++;
    85                 GuardAction( [this](){ scopeLevel--; } );
    86         }
     31namespace {
    8732
    8833/// Does work with the main function and scopeLevels.
    89 class FixNames_new final {
     34class FixNames final {
    9035        int scopeLevel = 1;
    9136
     
    10348
    10449        const ast::FunctionDecl *postvisit( const ast::FunctionDecl *functionDecl ) {
    105                 if ( FixMain::isMain( functionDecl ) ) {
     50                if ( isMain( functionDecl ) ) {
    10651                        auto mutDecl = ast::mutate( functionDecl );
    10752
     
    13883};
    13984
     85} // namespace
     86
    14087void fixNames( ast::TranslationUnit & translationUnit ) {
    141         ast::Pass<FixNames_new>::run( translationUnit );
     88        ast::Pass<FixNames>::run( translationUnit );
    14289}
    14390
  • src/CodeGen/FixNames.h

    rdf8ba61a r8d182b1  
    1616#pragma once
    1717
    18 #include <list>  // for list
    19 
    20 class Declaration;
    2118namespace ast {
    2219        class TranslationUnit;
     
    2421
    2522namespace CodeGen {
    26         /// mangles object and function names
    27         void fixNames( std::list< Declaration* > & translationUnit );
     23
    2824/// Sets scope levels and fills in main's default return.
    2925void fixNames( ast::TranslationUnit & translationUnit );
     26
    3027} // namespace CodeGen
    3128
  • src/CodeGen/GenType.cc

    rdf8ba61a r8d182b1  
    2121#include "AST/Print.hpp"          // for print
    2222#include "AST/Vector.hpp"         // for vector
    23 #include "CodeGenerator.h"        // for CodeGenerator
    24 #include "CodeGeneratorNew.hpp"   // for CodeGenerator_new
    25 #include "SynTree/Declaration.h"  // for DeclarationWithType
    26 #include "SynTree/Expression.h"   // for Expression
    27 #include "SynTree/Type.h"         // for PointerType, Type, FunctionType
    28 #include "SynTree/Visitor.h"      // for Visitor
     23#include "CodeGeneratorNew.hpp"   // for CodeGenerator
     24#include "Common/UniqueName.h"    // for UniqueName
    2925
    3026namespace CodeGen {
    31         struct GenType : public WithVisitorRef<GenType>, public WithShortCircuiting {
    32                 std::string typeString;
    33                 GenType( const std::string &typeString, const Options &options );
    34 
    35                 void previsit( BaseSyntaxNode * );
    36                 void postvisit( BaseSyntaxNode * );
    37 
    38                 void postvisit( FunctionType * funcType );
    39                 void postvisit( VoidType * voidType );
    40                 void postvisit( BasicType * basicType );
    41                 void postvisit( PointerType * pointerType );
    42                 void postvisit( ArrayType * arrayType );
    43                 void postvisit( ReferenceType * refType );
    44                 void postvisit( StructInstType * structInst );
    45                 void postvisit( UnionInstType * unionInst );
    46                 void postvisit( EnumInstType * enumInst );
    47                 void postvisit( TypeInstType * typeInst );
    48                 void postvisit( TupleType  * tupleType );
    49                 void postvisit( VarArgsType * varArgsType );
    50                 void postvisit( ZeroType * zeroType );
    51                 void postvisit( OneType * oneType );
    52                 void postvisit( GlobalScopeType * globalType );
    53                 void postvisit( TraitInstType * inst );
    54                 void postvisit( TypeofType * typeof );
    55                 void postvisit( VTableType * vtable );
    56                 void postvisit( QualifiedType * qualType );
    57 
    58           private:
    59                 void handleQualifiers( Type *type );
    60                 std::string handleGeneric( ReferenceToType * refType );
    61                 void genArray( const Type::Qualifiers &qualifiers, Type *base, Expression *dimension, bool isVarLen, bool isStatic );
    62 
    63                 Options options;
    64         };
    65 
    66         std::string genType( Type *type, const std::string &baseString, const Options &options ) {
    67                 PassVisitor<GenType> gt( baseString, options );
    68                 std::ostringstream os;
    69 
    70                 if ( ! type->get_attributes().empty() ) {
    71                         PassVisitor<CodeGenerator> cg( os, options );
    72                         cg.pass.genAttributes( type->get_attributes() );
    73                 } // if
    74 
    75                 type->accept( gt );
    76                 return os.str() + gt.pass.typeString;
    77         }
    78 
    79         std::string genType( Type *type, const std::string &baseString, bool pretty, bool genC , bool lineMarks ) {
    80                 return genType( type, baseString, Options(pretty, genC, lineMarks, false ) );
    81         }
    82 
    83         std::string genPrettyType( Type * type, const std::string & baseString ) {
    84                 return genType( type, baseString, true, false );
    85         }
    86 
    87         GenType::GenType( const std::string &typeString, const Options &options ) : typeString( typeString ), options( options ) {}
    88 
    89         // *** BaseSyntaxNode
    90         void GenType::previsit( BaseSyntaxNode * ) {
    91                 // turn off automatic recursion for all nodes, to allow each visitor to
    92                 // precisely control the order in which its children are visited.
    93                 visit_children = false;
    94         }
    95 
    96         void GenType::postvisit( BaseSyntaxNode * node ) {
    97                 std::stringstream ss;
    98                 node->print( ss );
    99                 assertf( false, "Unhandled node reached in GenType: %s", ss.str().c_str() );
    100         }
    101 
    102         void GenType::postvisit( VoidType * voidType ) {
    103                 typeString = "void " + typeString;
    104                 handleQualifiers( voidType );
    105         }
    106 
    107         void GenType::postvisit( BasicType * basicType ) {
    108                 BasicType::Kind kind = basicType->kind;
    109                 assert( 0 <= kind && kind < BasicType::NUMBER_OF_BASIC_TYPES );
    110                 typeString = std::string( BasicType::typeNames[kind] ) + " " + typeString;
    111                 handleQualifiers( basicType );
    112         }
    113 
    114         void GenType::genArray( const Type::Qualifiers & qualifiers, Type * base, Expression *dimension, bool isVarLen, bool isStatic ) {
    115                 std::ostringstream os;
    116                 if ( typeString != "" ) {
    117                         if ( typeString[ 0 ] == '*' ) {
    118                                 os << "(" << typeString << ")";
    119                         } else {
    120                                 os << typeString;
    121                         } // if
    122                 } // if
    123                 os << "[";
    124 
    125                 if ( isStatic ) {
    126                         os << "static ";
    127                 } // if
    128                 if ( qualifiers.is_const ) {
    129                         os << "const ";
    130                 } // if
    131                 if ( qualifiers.is_volatile ) {
    132                         os << "volatile ";
    133                 } // if
    134                 if ( qualifiers.is_restrict ) {
    135                         os << "__restrict ";
    136                 } // if
    137                 if ( qualifiers.is_atomic ) {
    138                         os << "_Atomic ";
    139                 } // if
    140                 if ( dimension != 0 ) {
    141                         PassVisitor<CodeGenerator> cg( os, options );
    142                         dimension->accept( cg );
    143                 } else if ( isVarLen ) {
    144                         // no dimension expression on a VLA means it came in with the * token
    145                         os << "*";
    146                 } // if
    147                 os << "]";
    148 
    149                 typeString = os.str();
    150 
    151                 base->accept( *visitor );
    152         }
    153 
    154         void GenType::postvisit( PointerType * pointerType ) {
    155                 assert( pointerType->base != 0);
    156                 if ( pointerType->get_isStatic() || pointerType->get_isVarLen() || pointerType->dimension ) {
    157                         genArray( pointerType->get_qualifiers(), pointerType->base, pointerType->dimension, pointerType->get_isVarLen(), pointerType->get_isStatic() );
    158                 } else {
    159                         handleQualifiers( pointerType );
    160                         if ( typeString[ 0 ] == '?' ) {
    161                                 typeString = "* " + typeString;
    162                         } else {
    163                                 typeString = "*" + typeString;
    164                         } // if
    165                         pointerType->base->accept( *visitor );
    166                 } // if
    167         }
    168 
    169         void GenType::postvisit( ArrayType * arrayType ) {
    170                 genArray( arrayType->get_qualifiers(), arrayType->base, arrayType->dimension, arrayType->get_isVarLen(), arrayType->get_isStatic() );
    171         }
    172 
    173         void GenType::postvisit( ReferenceType * refType ) {
    174                 assert( 0 != refType->base );
    175                 assertf( ! options.genC, "Reference types should not reach code generation." );
    176                 handleQualifiers( refType );
    177                 typeString = "&" + typeString;
    178                 refType->base->accept( *visitor );
    179         }
    180 
    181         void GenType::postvisit( FunctionType * funcType ) {
    182                 std::ostringstream os;
    183 
    184                 if ( typeString != "" ) {
    185                         if ( typeString[ 0 ] == '*' ) {
    186                                 os << "(" << typeString << ")";
    187                         } else {
    188                                 os << typeString;
    189                         } // if
    190                 } // if
    191 
    192                 /************* parameters ***************/
    193 
    194                 const std::list<DeclarationWithType *> &pars = funcType->parameters;
    195 
    196                 if ( pars.empty() ) {
    197                         if ( funcType->get_isVarArgs() ) {
    198                                 os << "()";
    199                         } else {
    200                                 os << "(void)";
    201                         } // if
    202                 } else {
    203                         PassVisitor<CodeGenerator> cg( os, options );
    204                         os << "(" ;
    205 
    206                         cg.pass.genCommaList( pars.begin(), pars.end() );
    207 
    208                         if ( funcType->get_isVarArgs() ) {
    209                                 os << ", ...";
    210                         } // if
    211                         os << ")";
    212                 } // if
    213 
    214                 typeString = os.str();
    215 
    216                 if ( funcType->returnVals.size() == 0 ) {
    217                         typeString = "void " + typeString;
    218                 } else {
    219                         funcType->returnVals.front()->get_type()->accept( *visitor );
    220                 } // if
    221 
    222                 // add forall
    223                 if( ! funcType->forall.empty() && ! options.genC ) {
    224                         // assertf( ! genC, "Aggregate type parameters should not reach code generation." );
    225                         std::ostringstream os;
    226                         PassVisitor<CodeGenerator> cg( os, options );
    227                         os << "forall(";
    228                         cg.pass.genCommaList( funcType->forall.begin(), funcType->forall.end() );
    229                         os << ")" << std::endl;
    230                         typeString = os.str() + typeString;
    231                 }
    232         }
    233 
    234         std::string GenType::handleGeneric( ReferenceToType * refType ) {
    235                 if ( ! refType->parameters.empty() ) {
    236                         std::ostringstream os;
    237                         PassVisitor<CodeGenerator> cg( os, options );
    238                         os << "(";
    239                         cg.pass.genCommaList( refType->parameters.begin(), refType->parameters.end() );
    240                         os << ") ";
    241                         return os.str();
    242                 }
    243                 return "";
    244         }
    245 
    246         void GenType::postvisit( StructInstType * structInst )  {
    247                 typeString = structInst->name + handleGeneric( structInst ) + " " + typeString;
    248                 if ( options.genC ) typeString = "struct " + typeString;
    249                 handleQualifiers( structInst );
    250         }
    251 
    252         void GenType::postvisit( UnionInstType * unionInst ) {
    253                 typeString = unionInst->name + handleGeneric( unionInst ) + " " + typeString;
    254                 if ( options.genC ) typeString = "union " + typeString;
    255                 handleQualifiers( unionInst );
    256         }
    257 
    258         void GenType::postvisit( EnumInstType * enumInst ) {
    259                 if ( enumInst->baseEnum && enumInst->baseEnum->base ) {
    260                         typeString = genType(enumInst->baseEnum->base, typeString, options);
    261                 } else {
    262                         typeString = enumInst->name + " " + typeString;
    263                         if ( options.genC ) {
    264                                 typeString = "enum " + typeString;
    265                         }
    266                 }
    267                 handleQualifiers( enumInst );
    268         }
    269 
    270         void GenType::postvisit( TypeInstType * typeInst ) {
    271                 assertf( ! options.genC, "Type instance types should not reach code generation." );
    272                 typeString = typeInst->name + " " + typeString;
    273                 handleQualifiers( typeInst );
    274         }
    275 
    276         void GenType::postvisit( TupleType * tupleType ) {
    277                 assertf( ! options.genC, "Tuple types should not reach code generation." );
    278                 unsigned int i = 0;
    279                 std::ostringstream os;
    280                 os << "[";
    281                 for ( Type * t : *tupleType ) {
    282                         i++;
    283                         os << genType( t, "", options ) << (i == tupleType->size() ? "" : ", ");
    284                 }
    285                 os << "] ";
    286                 typeString = os.str() + typeString;
    287         }
    288 
    289         void GenType::postvisit( VarArgsType * varArgsType ) {
    290                 typeString = "__builtin_va_list " + typeString;
    291                 handleQualifiers( varArgsType );
    292         }
    293 
    294         void GenType::postvisit( ZeroType * zeroType ) {
    295                 // ideally these wouldn't hit codegen at all, but should be safe to make them ints
    296                 typeString = (options.pretty ? "zero_t " : "long int ") + typeString;
    297                 handleQualifiers( zeroType );
    298         }
    299 
    300         void GenType::postvisit( OneType * oneType ) {
    301                 // ideally these wouldn't hit codegen at all, but should be safe to make them ints
    302                 typeString = (options.pretty ? "one_t " : "long int ") + typeString;
    303                 handleQualifiers( oneType );
    304         }
    305 
    306         void GenType::postvisit( GlobalScopeType * globalType ) {
    307                 assertf( ! options.genC, "Global scope type should not reach code generation." );
    308                 handleQualifiers( globalType );
    309         }
    310 
    311         void GenType::postvisit( TraitInstType * inst ) {
    312                 assertf( ! options.genC, "Trait types should not reach code generation." );
    313                 typeString = inst->name + " " + typeString;
    314                 handleQualifiers( inst );
    315         }
    316 
    317         void GenType::postvisit( TypeofType * typeof ) {
    318                 std::ostringstream os;
    319                 PassVisitor<CodeGenerator> cg( os, options );
    320                 os << "typeof(";
    321                 typeof->expr->accept( cg );
    322                 os << ") " << typeString;
    323                 typeString = os.str();
    324                 handleQualifiers( typeof );
    325         }
    326 
    327         void GenType::postvisit( VTableType * vtable ) {
    328                 assertf( ! options.genC, "Virtual table types should not reach code generation." );
    329                 std::ostringstream os;
    330                 os << "vtable(" << genType( vtable->base, "", options ) << ") " << typeString;
    331                 typeString = os.str();
    332                 handleQualifiers( vtable );
    333         }
    334 
    335         void GenType::postvisit( QualifiedType * qualType ) {
    336                 assertf( ! options.genC, "Qualified types should not reach code generation." );
    337                 std::ostringstream os;
    338                 os << genType( qualType->parent, "", options ) << "." << genType( qualType->child, "", options ) << typeString;
    339                 typeString = os.str();
    340                 handleQualifiers( qualType );
    341         }
    342 
    343         void GenType::handleQualifiers( Type * type ) {
    344                 if ( type->get_const() ) {
    345                         typeString = "const " + typeString;
    346                 } // if
    347                 if ( type->get_volatile() ) {
    348                         typeString = "volatile " + typeString;
    349                 } // if
    350                 if ( type->get_restrict() ) {
    351                         typeString = "__restrict " + typeString;
    352                 } // if
    353                 if ( type->get_atomic() ) {
    354                         typeString = "_Atomic " + typeString;
    355                 } // if
    356         }
    35727
    35828namespace {
    35929
    360 #warning Remove the _new when old version is removed.
    361 struct GenType_new :
     30struct GenType final :
    36231                public ast::WithShortCircuiting,
    363                 public ast::WithVisitorRef<GenType_new> {
     32                public ast::WithVisitorRef<GenType> {
    36433        std::string result;
    365         GenType_new( const std::string &typeString, const Options &options );
     34        GenType( const std::string &typeString, const Options &options );
    36635
    36736        void previsit( ast::Node const * );
     
    39766};
    39867
    399 GenType_new::GenType_new( const std::string &typeString, const Options &options ) : result( typeString ), options( options ) {}
    400 
    401 void GenType_new::previsit( ast::Node const * ) {
     68GenType::GenType( const std::string &typeString, const Options &options ) : result( typeString ), options( options ) {}
     69
     70void GenType::previsit( ast::Node const * ) {
    40271        // Turn off automatic recursion for all nodes, to allow each visitor to
    40372        // precisely control the order in which its children are visited.
     
    40574}
    40675
    407 void GenType_new::postvisit( ast::Node const * node ) {
     76void GenType::postvisit( ast::Node const * node ) {
    40877        std::stringstream ss;
    40978        ast::print( ss, node );
     
    41180}
    41281
    413 void GenType_new::postvisit( ast::VoidType const * type ) {
     82void GenType::postvisit( ast::VoidType const * type ) {
    41483        result = "void " + result;
    41584        handleQualifiers( type );
    41685}
    41786
    418 void GenType_new::postvisit( ast::BasicType const * type ) {
     87void GenType::postvisit( ast::BasicType const * type ) {
    41988        ast::BasicType::Kind kind = type->kind;
    42089        assert( 0 <= kind && kind < ast::BasicType::NUMBER_OF_BASIC_TYPES );
     
    42392}
    42493
    425 void GenType_new::genArray( const ast::CV::Qualifiers & qualifiers, ast::Type const * base, ast::Expr const *dimension, bool isVarLen, bool isStatic ) {
     94void GenType::genArray( const ast::CV::Qualifiers & qualifiers, ast::Type const * base, ast::Expr const *dimension, bool isVarLen, bool isStatic ) {
    42695        std::ostringstream os;
    42796        if ( result != "" ) {
     
    449118        }
    450119        if ( dimension != 0 ) {
    451                 ast::Pass<CodeGenerator_new>::read( dimension, os, options );
     120                ast::Pass<CodeGenerator>::read( dimension, os, options );
    452121        } else if ( isVarLen ) {
    453122                // no dimension expression on a VLA means it came in with the * token
     
    461130}
    462131
    463 void GenType_new::postvisit( ast::PointerType const * type ) {
     132void GenType::postvisit( ast::PointerType const * type ) {
    464133        if ( type->isStatic || type->isVarLen || type->dimension ) {
    465134                genArray( type->qualifiers, type->base, type->dimension, type->isVarLen, type->isStatic );
     
    475144}
    476145
    477 void GenType_new::postvisit( ast::ArrayType const * type ) {
     146void GenType::postvisit( ast::ArrayType const * type ) {
    478147        genArray( type->qualifiers, type->base, type->dimension, type->isVarLen, type->isStatic );
    479148}
    480149
    481 void GenType_new::postvisit( ast::ReferenceType const * type ) {
     150void GenType::postvisit( ast::ReferenceType const * type ) {
    482151        assertf( !options.genC, "Reference types should not reach code generation." );
    483152        handleQualifiers( type );
     
    486155}
    487156
    488 void GenType_new::postvisit( ast::FunctionType const * type ) {
     157void GenType::postvisit( ast::FunctionType const * type ) {
    489158        std::ostringstream os;
    490159
     
    526195                //assertf( !options.genC, "FunctionDecl type parameters should not reach code generation." );
    527196                std::ostringstream os;
    528                 ast::Pass<CodeGenerator_new> cg( os, options );
     197                ast::Pass<CodeGenerator> cg( os, options );
    529198                os << "forall(";
    530199                cg.core.genCommaList( type->forall );
     
    534203}
    535204
    536 std::string GenType_new::handleGeneric( ast::BaseInstType const * type ) {
     205std::string GenType::handleGeneric( ast::BaseInstType const * type ) {
    537206        if ( !type->params.empty() ) {
    538207                std::ostringstream os;
    539                 ast::Pass<CodeGenerator_new> cg( os, options );
     208                ast::Pass<CodeGenerator> cg( os, options );
    540209                os << "(";
    541210                cg.core.genCommaList( type->params );
     
    546215}
    547216
    548 void GenType_new::postvisit( ast::StructInstType const * type )  {
     217void GenType::postvisit( ast::StructInstType const * type )  {
    549218        result = type->name + handleGeneric( type ) + " " + result;
    550219        if ( options.genC ) result = "struct " + result;
     
    552221}
    553222
    554 void GenType_new::postvisit( ast::UnionInstType const * type ) {
     223void GenType::postvisit( ast::UnionInstType const * type ) {
    555224        result = type->name + handleGeneric( type ) + " " + result;
    556225        if ( options.genC ) result = "union " + result;
     
    558227}
    559228
    560 void GenType_new::postvisit( ast::EnumInstType const * type ) {
     229void GenType::postvisit( ast::EnumInstType const * type ) {
    561230        if ( type->base && type->base->base ) {
    562231                result = genType( type->base->base, result, options );
     
    570239}
    571240
    572 void GenType_new::postvisit( ast::TypeInstType const * type ) {
     241void GenType::postvisit( ast::TypeInstType const * type ) {
    573242        assertf( !options.genC, "TypeInstType should not reach code generation." );
    574243        result = type->name + " " + result;
     
    576245}
    577246
    578 void GenType_new::postvisit( ast::TupleType const * type ) {
     247void GenType::postvisit( ast::TupleType const * type ) {
    579248        assertf( !options.genC, "TupleType should not reach code generation." );
    580249        unsigned int i = 0;
     
    589258}
    590259
    591 void GenType_new::postvisit( ast::VarArgsType const * type ) {
     260void GenType::postvisit( ast::VarArgsType const * type ) {
    592261        result = "__builtin_va_list " + result;
    593262        handleQualifiers( type );
    594263}
    595264
    596 void GenType_new::postvisit( ast::ZeroType const * type ) {
     265void GenType::postvisit( ast::ZeroType const * type ) {
    597266        // Ideally these wouldn't hit codegen at all, but should be safe to make them ints.
    598267        result = (options.pretty ? "zero_t " : "long int ") + result;
     
    600269}
    601270
    602 void GenType_new::postvisit( ast::OneType const * type ) {
     271void GenType::postvisit( ast::OneType const * type ) {
    603272        // Ideally these wouldn't hit codegen at all, but should be safe to make them ints.
    604273        result = (options.pretty ? "one_t " : "long int ") + result;
     
    606275}
    607276
    608 void GenType_new::postvisit( ast::GlobalScopeType const * type ) {
     277void GenType::postvisit( ast::GlobalScopeType const * type ) {
    609278        assertf( !options.genC, "GlobalScopeType should not reach code generation." );
    610279        handleQualifiers( type );
    611280}
    612281
    613 void GenType_new::postvisit( ast::TraitInstType const * type ) {
     282void GenType::postvisit( ast::TraitInstType const * type ) {
    614283        assertf( !options.genC, "TraitInstType should not reach code generation." );
    615284        result = type->name + " " + result;
     
    617286}
    618287
    619 void GenType_new::postvisit( ast::TypeofType const * type ) {
     288void GenType::postvisit( ast::TypeofType const * type ) {
    620289        std::ostringstream os;
    621290        os << "typeof(";
    622         ast::Pass<CodeGenerator_new>::read( type, os, options );
     291        ast::Pass<CodeGenerator>::read( type, os, options );
    623292        os << ") " << result;
    624293        result = os.str();
     
    626295}
    627296
    628 void GenType_new::postvisit( ast::VTableType const * type ) {
     297void GenType::postvisit( ast::VTableType const * type ) {
    629298        assertf( !options.genC, "Virtual table types should not reach code generation." );
    630299        std::ostringstream os;
     
    634303}
    635304
    636 void GenType_new::postvisit( ast::QualifiedType const * type ) {
     305void GenType::postvisit( ast::QualifiedType const * type ) {
    637306        assertf( !options.genC, "QualifiedType should not reach code generation." );
    638307        std::ostringstream os;
     
    642311}
    643312
    644 void GenType_new::handleQualifiers( ast::Type const * type ) {
     313void GenType::handleQualifiers( ast::Type const * type ) {
    645314        if ( type->is_const() ) {
    646315                result = "const " + result;
     
    657326}
    658327
    659 std::string GenType_new::genParamList( const ast::vector<ast::Type> & range ) {
     328std::string GenType::genParamList( const ast::vector<ast::Type> & range ) {
    660329        auto cur = range.begin();
    661330        auto end = range.end();
    662331        if ( cur == end ) return "";
    663332        std::ostringstream oss;
    664         for ( unsigned int i = 0 ; ; ++i ) {
    665                 oss << genType( *cur++, "__param_" + std::to_string(i), options );
     333        UniqueName param( "__param_" );
     334        while ( true ) {
     335                oss << genType( *cur++, options.genC ? param.newName() : "", options );
    666336                if ( cur == end ) break;
    667337                oss << ", ";
     
    675345        std::ostringstream os;
    676346        if ( !type->attributes.empty() ) {
    677                 ast::Pass<CodeGenerator_new> cg( os, options );
     347                ast::Pass<CodeGenerator> cg( os, options );
    678348                cg.core.genAttributes( type->attributes );
    679349        }
    680350
    681         return os.str() + ast::Pass<GenType_new>::read( type, base, options );
     351        return os.str() + ast::Pass<GenType>::read( type, base, options );
    682352}
    683353
    684354std::string genTypeNoAttr( ast::Type const * type, const std::string & base, const Options & options ) {
    685         return ast::Pass<GenType_new>::read( type, base, options );
     355        return ast::Pass<GenType>::read( type, base, options );
    686356}
    687357
  • src/CodeGen/Generate.cc

    rdf8ba61a r8d182b1  
    1919#include <string>                    // for operator<<
    2020
    21 #include "CodeGeneratorNew.hpp"      // for CodeGenerator_new, doSemicolon, ...
    22 #include "CodeGenerator.h"           // for CodeGenerator, doSemicolon, oper...
     21#include "CodeGeneratorNew.hpp"      // for CodeGenerator, doSemicolon, ...
    2322#include "GenType.h"                 // for genPrettyType
    24 #include "Common/PassVisitor.h"      // for PassVisitor
    25 #include "SynTree/LinkageSpec.h"     // for isBuiltin, isGeneratable
    26 #include "SynTree/BaseSyntaxNode.h"  // for BaseSyntaxNode
    27 #include "SynTree/Declaration.h"     // for Declaration
    28 #include "SynTree/Type.h"            // for Type
    2923
    3024using namespace std;
    3125
    3226namespace CodeGen {
    33         namespace {
    34                 /// Removes misc. nodes that should not exist in CodeGen
    35                 struct TreeCleaner {
    36                         void premutate( CompoundStmt * stmt );
    37                         Statement * postmutate( ImplicitCtorDtorStmt * stmt );
    38 
    39                         static bool shouldClean( Declaration * );
    40                 };
    41 
    42                 void cleanTree( std::list< Declaration * > & translationUnit ) {
    43                         PassVisitor<TreeCleaner> cleaner;
    44                         filter( translationUnit, [](Declaration * decl) { return TreeCleaner::shouldClean(decl); }, false );
    45                         mutateAll( translationUnit, cleaner );
    46                 } // cleanTree
    47         } // namespace
    48 
    49         void generate( std::list< Declaration* > translationUnit, std::ostream &os, bool doIntrinsics, bool pretty, bool generateC, bool lineMarks, bool printExprTypes ) {
    50                 cleanTree( translationUnit );
    51 
    52                 PassVisitor<CodeGenerator> cgv( os, pretty, generateC, lineMarks, printExprTypes );
    53                 for ( auto & dcl : translationUnit ) {
    54                         if ( LinkageSpec::isGeneratable( dcl->get_linkage() ) && (doIntrinsics || ! LinkageSpec::isBuiltin( dcl->get_linkage() ) ) ) {
    55                                 cgv.pass.updateLocation( dcl );
    56                                 dcl->accept(cgv);
    57                                 if ( doSemicolon( dcl ) ) {
    58                                         os << ";";
    59                                 } // if
    60                                 os << cgv.pass.endl;
    61                         } // if
    62                 } // for
    63         }
    64 
    65         void generate( BaseSyntaxNode * node, std::ostream & os ) {
    66                 if ( Type * type = dynamic_cast< Type * >( node ) ) {
    67                         os << genPrettyType( type, "" );
    68                 } else {
    69                         PassVisitor<CodeGenerator> cgv( os, true, false, false, false );
    70                         node->accept( cgv );
    71                 }
    72                 os << std::endl;
    73         }
    74 
    75         namespace {
    76                 void TreeCleaner::premutate( CompoundStmt * cstmt ) {
    77                         filter( cstmt->kids, [](Statement * stmt) {
    78                                 if ( DeclStmt * declStmt = dynamic_cast< DeclStmt * >( stmt ) ) {
    79                                         return shouldClean( declStmt->decl );
    80                                 }
    81                                 return false;
    82                         }, false );
    83                 }
    84 
    85                 Statement * TreeCleaner::postmutate( ImplicitCtorDtorStmt * stmt ) {
    86                         Statement * callStmt = nullptr;
    87                         std::swap( stmt->callStmt, callStmt );
    88                         delete stmt;
    89                         return callStmt;
    90                 }
    91 
    92                 bool TreeCleaner::shouldClean( Declaration * decl ) {
    93                         return dynamic_cast< TraitDecl * >( decl );
    94                 }
    95         } // namespace
    9627
    9728namespace {
     
    10132
    10233        /// Removes various nodes that should not exist in CodeGen.
    103         struct TreeCleaner_new {
     34        struct TreeCleaner final {
    10435                ast::CompoundStmt const * previsit( ast::CompoundStmt const * stmt ) {
    10536                        auto mutStmt = ast::mutate( stmt );
     
    12051                bool pretty, bool generateC, bool lineMarks, bool printExprTypes ) {
    12152        erase_if( translationUnit.decls, shouldClean );
    122         ast::Pass<TreeCleaner_new>::run( translationUnit );
     53        ast::Pass<TreeCleaner>::run( translationUnit );
    12354
    124         ast::Pass<CodeGenerator_new> cgv( os,
     55        ast::Pass<CodeGenerator> cgv( os,
    12556                        Options( pretty, generateC, lineMarks, printExprTypes ) );
    12657        for ( auto & decl : translationUnit.decls ) {
  • src/CodeGen/Generate.h

    rdf8ba61a r8d182b1  
    1717
    1818#include <iostream>  // for ostream
    19 #include <list>      // for list
    20 
    21 class BaseSyntaxNode;
    22 class Declaration;
    2319
    2420namespace ast {
     
    2723
    2824namespace CodeGen {
    29         /// Generates code. doIntrinsics determines if intrinsic functions are printed, pretty formats output nicely (e.g., uses unmangled names, etc.), generateC is true when the output must consist only of C code (allows some assertions, etc.)
    30         void generate( std::list< Declaration* > translationUnit, std::ostream &os, bool doIntrinsics, bool pretty, bool generateC = false , bool lineMarks = false, bool printTypeExpr = false );
    31 
    32         /// Generate code for a single node -- helpful for debugging in gdb
    33         void generate( BaseSyntaxNode * node, std::ostream & os );
    3425
    3526/// Generates all code in transUnit and writing it to the os.
  • src/CodeGen/LinkOnce.cc

    rdf8ba61a r8d182b1  
    2222#include "AST/Expr.hpp"
    2323#include "AST/Pass.hpp"
    24 #include "Common/PassVisitor.h"       // for PassVisitor, WithShortCircuiting
    2524
    2625namespace CodeGen {
    2726
    2827namespace {
    29 
    30 bool is_cfa_linkonce_old( Attribute const * attr ) {
    31         return std::string("cfa_linkonce") == attr->name;
    32 }
    33 
    34 bool is_section_attribute_old( Attribute const * attr ) {
    35         return std::string("section") == attr->name;
    36 }
    37 
    38 class LinkOnceVisitorCore : public WithShortCircuiting {
    39 public:
    40         void previsit( Declaration * ) {
    41                 visit_children = false;
    42         }
    43 
    44         void previsit( DeclarationWithType * decl ) {
    45                 std::list< Attribute * > & attributes = decl->attributes;
    46                 // See if we can find the element:
    47                 auto found = std::find_if(attributes.begin(), attributes.end(), is_cfa_linkonce_old );
    48                 if ( attributes.end() != found ) {
    49                         // Remove any other sections:
    50                         attributes.remove_if( is_section_attribute_old );
    51                         // Iterator to the cfa_linkonce attribute should still be valid.
    52                         Attribute * attribute = *found;
    53                         assert( attribute->parameters.empty() );
    54                         assert( !decl->mangleName.empty() );
    55                         // Overwrite the attribute in place.
    56                         const std::string section_name = ".gnu.linkonce." + decl->mangleName;
    57                         attribute->name = "section";
    58                         attribute->parameters.push_back(
    59                                 new ConstantExpr( Constant::from_string( section_name ) )
    60                         );
    61 
    62                         // Unconditionnaly add "visibility(default)" to anything with gnu.linkonce
    63                         // visibility is a mess otherwise
    64                         attributes.push_back(new Attribute("visibility", {new ConstantExpr( Constant::from_string( "default" ) )}));
    65 
    66                 }
    67                 visit_children = false;
    68         }
    69 };
    7028
    7129bool is_cfa_linkonce( ast::Attribute const * attr ) {
     
    12280} // namespace
    12381
    124 void translateLinkOnce( std::list< Declaration *> & translationUnit ) {
    125         PassVisitor<LinkOnceVisitorCore> translator;
    126         acceptAll( translationUnit, translator );
    127 }
    128 
    12982void translateLinkOnce( ast::TranslationUnit & translationUnit ) {
    13083        ast::Pass<LinkOnceCore>::run( translationUnit );
  • src/CodeGen/LinkOnce.h

    rdf8ba61a r8d182b1  
    2020// for now its almost the only attribute we handle.
    2121
    22 #include <list>  // for list
    2322
    24 class Declaration;
    2523namespace ast {
    2624        class TranslationUnit;
     
    2927namespace CodeGen {
    3028
    31 void translateLinkOnce( std::list< Declaration *> & translationUnit );
    3229void translateLinkOnce( ast::TranslationUnit & translationUnit );
    3330/* Convert the cfa_linkonce attribute on top level declaration into
  • src/CodeGen/module.mk

    rdf8ba61a r8d182b1  
    1616
    1717SRC_CODEGEN = \
    18         CodeGen/FixMain2.cc \
    19         CodeGen/FixMain.h \
     18        CodeGen/CodeGeneratorNew.cpp \
     19        CodeGen/CodeGeneratorNew.hpp \
     20        CodeGen/GenType.cc \
     21        CodeGen/GenType.h \
    2022        CodeGen/OperatorTable.cc \
    2123        CodeGen/OperatorTable.h
    2224
    2325SRC += $(SRC_CODEGEN) \
    24         CodeGen/CodeGenerator.cc \
    25         CodeGen/CodeGenerator.h \
    26         CodeGen/CodeGeneratorNew.cpp \
    27         CodeGen/CodeGeneratorNew.hpp \
    2826        CodeGen/Generate.cc \
    2927        CodeGen/Generate.h \
    3028        CodeGen/FixMain.cc \
     29        CodeGen/FixMain.h \
    3130        CodeGen/FixNames.cc \
    3231        CodeGen/FixNames.h \
    33         CodeGen/GenType.cc \
    34         CodeGen/GenType.h \
    3532        CodeGen/LinkOnce.cc \
    3633        CodeGen/LinkOnce.h \
Note: See TracChangeset for help on using the changeset viewer.