Changeset b067d9b for src/CodeGen


Ignore:
Timestamp:
Oct 29, 2019, 4:01:24 PM (6 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
773db65, 9421f3d8
Parents:
7951100 (diff), 8364209 (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:
1 added
5 edited

Legend:

Unmodified
Added
Removed
  • src/CodeGen/CodeGenerator.cc

    r7951100 rb067d9b  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat May  5 09:08:32 2018
    13 // Update Count     : 494
     12// Last Modified On : Sat Oct 19 19:30:38 2019
     13// Update Count     : 506
    1414//
    1515#include "CodeGenerator.h"
     
    8383        void CodeGenerator::updateLocation( CodeLocation const & to ) {
    8484                // skip if linemarks shouldn't appear or if codelocation is unset
    85                 if ( !lineMarks || to.isUnset() ) return;
     85                if ( !options.lineMarks || to.isUnset() ) return;
    8686
    8787                if ( currentLocation.followedBy( to, 0 ) ) {
     
    116116        }
    117117
    118         CodeGenerator::CodeGenerator( std::ostream & os, bool pretty, bool genC, bool lineMarks, bool printExprTypes ) : indent( CodeGenerator::tabsize ), output( os ), printLabels( *this ), pretty( pretty ), genC( genC ), lineMarks( lineMarks ), printExprTypes( printExprTypes ), endl( *this ) {}
     118        CodeGenerator::CodeGenerator( std::ostream & os, bool pretty, bool genC, bool lineMarks, bool printExprTypes ) : indent( 0, CodeGenerator::tabsize ), output( os ), printLabels( *this ), options( pretty, genC, lineMarks, printExprTypes ), endl( *this ) {}
     119        CodeGenerator::CodeGenerator( std::ostream & os, const Options &options ) : indent( 0, CodeGenerator::tabsize ), output( os ), printLabels( *this ), options(options), endl( *this ) {}
    119120
    120121        string CodeGenerator::mangleName( DeclarationWithType * decl ) {
    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
     
    133134                output << "__attribute__ ((";
    134135                for ( list< Attribute * >::iterator attr( attributes.begin() );; ) {
    135                         output << (*attr)->get_name();
    136                         if ( ! (*attr)->get_parameters().empty() ) {
     136                        output << (*attr)->name;
     137                        if ( ! (*attr)->parameters.empty() ) {
    137138                                output << "(";
    138                                 genCommaList( (*attr)->get_parameters().begin(), (*attr)->get_parameters().end() );
     139                                genCommaList( (*attr)->parameters.begin(), (*attr)->parameters.end() );
    139140                                output << ")";
    140141                        } // if
     
    164165                previsit( (BaseSyntaxNode *)node );
    165166                GuardAction( [this, node](){
    166                         if ( printExprTypes ) {
    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
     201                // gcc allows an empty declarator (no name) for bit-fields and C states: 6.7.2.1 Structure and union specifiers,
     202                // point 4, page 113: If the (bit field) value is zero, the declaration shall have no declarator.  For anything
     203                // else, the anonymous name refers to the anonymous object for plan9 inheritance.
     204                if ( objectDecl->get_name().empty() && options.genC && ! objectDecl->get_bitfieldWidth() ) {
    198205                        // only generate an anonymous name when generating C code, otherwise it clutters the output too much
    199206                        static UniqueName name = { "__anonymous_object" };
    200207                        objectDecl->set_name( name.newName() );
     208                        // Stops unused parameter warnings.
     209                        if ( options.anonymousUnused ) {
     210                                objectDecl->attributes.push_back( new Attribute( "unused" ) );
     211                        }
    201212                }
    202213
     
    205216
    206217                handleStorageClass( objectDecl );
    207                 output << genType( objectDecl->get_type(), mangleName( objectDecl ), pretty, genC );
     218                output << genType( objectDecl->get_type(), mangleName( objectDecl ), options.pretty, options.genC );
    208219
    209220                asmName( objectDecl );
     
    224235
    225236        void CodeGenerator::handleAggregate( AggregateDecl * aggDecl, const std::string & kind ) {
    226                 if( ! aggDecl->get_parameters().empty() && ! genC ) {
     237                if( ! aggDecl->parameters.empty() && ! options.genC ) {
    227238                        // assertf( ! genC, "Aggregate type parameters should not reach code generation." );
    228239                        output << "forall(";
    229                         genCommaList( aggDecl->get_parameters().begin(), aggDecl->get_parameters().end() );
     240                        genCommaList( aggDecl->parameters.begin(), aggDecl->parameters.end() );
    230241                        output << ")" << endl;
    231242                        output << indent;
     
    233244
    234245                output << kind;
    235                 genAttributes( aggDecl->get_attributes() );
    236                 output << aggDecl->get_name();
     246                genAttributes( aggDecl->attributes );
     247                output << aggDecl->name;
    237248
    238249                if ( aggDecl->has_body() ) {
    239                         std::list< Declaration * > & memb = aggDecl->get_members();
     250                        std::list< Declaration * > & memb = aggDecl->members;
    240251                        output << " {" << endl;
    241252
     
    294305
    295306        void CodeGenerator::postvisit( TraitDecl * traitDecl ) {
    296                 assertf( ! genC, "TraitDecls should not reach code generation." );
     307                assertf( ! options.genC, "TraitDecls should not reach code generation." );
    297308                extension( traitDecl );
    298309                handleAggregate( traitDecl, "trait " );
     
    300311
    301312        void CodeGenerator::postvisit( TypedefDecl * typeDecl ) {
    302                 assertf( ! genC, "Typedefs are removed and substituted in earlier passes." );
     313                assertf( ! options.genC, "Typedefs are removed and substituted in earlier passes." );
    303314                output << "typedef ";
    304                 output << genType( typeDecl->get_base(), typeDecl->get_name(), pretty, genC ) << endl;
     315                output << genType( typeDecl->get_base(), typeDecl->get_name(), options ) << endl;
    305316        }
    306317
    307318        void CodeGenerator::postvisit( TypeDecl * typeDecl ) {
    308                 assertf( ! genC, "TypeDecls should not reach code generation." );
     319                assertf( ! options.genC, "TypeDecls should not reach code generation." );
    309320                output << typeDecl->genTypeString() << " " << typeDecl->name;
    310321                if ( typeDecl->sized ) {
     
    371382
    372383        void CodeGenerator::postvisit( ConstructorInit * init ){
    373                 assertf( ! genC, "ConstructorInit nodes should not reach code generation." );
     384                assertf( ! options.genC, "ConstructorInit nodes should not reach code generation." );
    374385                // pseudo-output for constructor/destructor pairs
    375386                output << "<ctorinit>{" << endl << ++indent << "ctor: ";
     
    507518                                        } else {
    508519                                                // no constructors with 0 or more than 2 parameters
    509                                                 assertf( ! genC, "UntypedExpr constructor/destructor with 0 or more than 2 parameters." );
     520                                                assertf( ! options.genC, "UntypedExpr constructor/destructor with 0 or more than 2 parameters." );
    510521                                                output << "(";
    511522                                                (*arg++)->accept( *visitor );
     
    604615                        // an lvalue cast, this has been taken out.
    605616                        output << "(";
    606                         output << genType( castExpr->get_result(), "", pretty, genC );
     617                        output << genType( castExpr->get_result(), "", options );
    607618                        output << ")";
    608619                } // if
     
    612623
    613624        void CodeGenerator::postvisit( KeywordCastExpr * castExpr ) {
    614                 assertf( ! genC, "KeywordCast should not reach code generation." );
     625                assertf( ! options.genC, "KeywordCast should not reach code generation." );
    615626                extension( castExpr );
    616627                output << "((" << castExpr->targetString() << " &)";
     
    620631
    621632        void CodeGenerator::postvisit( VirtualCastExpr * castExpr ) {
    622                 assertf( ! genC, "VirtualCastExpr should not reach code generation." );
     633                assertf( ! options.genC, "VirtualCastExpr should not reach code generation." );
    623634                extension( castExpr );
    624635                output << "(virtual ";
     
    628639
    629640        void CodeGenerator::postvisit( UntypedMemberExpr * memberExpr ) {
    630                 assertf( ! genC, "UntypedMemberExpr should not reach code generation." );
     641                assertf( ! options.genC, "UntypedMemberExpr should not reach code generation." );
    631642                extension( memberExpr );
    632643                memberExpr->get_aggregate()->accept( *visitor );
     
    661672                output << "sizeof(";
    662673                if ( sizeofExpr->get_isType() ) {
    663                         output << genType( sizeofExpr->get_type(), "", pretty, genC );
     674                        output << genType( sizeofExpr->get_type(), "", options );
    664675                } else {
    665676                        sizeofExpr->get_expr()->accept( *visitor );
     
    673684                output << "__alignof__(";
    674685                if ( alignofExpr->get_isType() ) {
    675                         output << genType( alignofExpr->get_type(), "", pretty, genC );
     686                        output << genType( alignofExpr->get_type(), "", options );
    676687                } else {
    677688                        alignofExpr->get_expr()->accept( *visitor );
     
    681692
    682693        void CodeGenerator::postvisit( UntypedOffsetofExpr * offsetofExpr ) {
    683                 assertf( ! genC, "UntypedOffsetofExpr should not reach code generation." );
     694                assertf( ! options.genC, "UntypedOffsetofExpr should not reach code generation." );
    684695                output << "offsetof(";
    685                 output << genType( offsetofExpr->get_type(), "", pretty, genC );
     696                output << genType( offsetofExpr->get_type(), "", options );
    686697                output << ", " << offsetofExpr->get_member();
    687698                output << ")";
     
    691702                // use GCC builtin
    692703                output << "__builtin_offsetof(";
    693                 output << genType( offsetofExpr->get_type(), "", pretty, genC );
     704                output << genType( offsetofExpr->get_type(), "", options );
    694705                output << ", " << mangleName( offsetofExpr->get_member() );
    695706                output << ")";
     
    697708
    698709        void CodeGenerator::postvisit( OffsetPackExpr * offsetPackExpr ) {
    699                 assertf( ! genC, "OffsetPackExpr should not reach code generation." );
    700                 output << "__CFA_offsetpack(" << genType( offsetPackExpr->get_type(), "", pretty, genC ) << ")";
     710                assertf( ! options.genC, "OffsetPackExpr should not reach code generation." );
     711                output << "__CFA_offsetpack(" << genType( offsetPackExpr->get_type(), "", options ) << ")";
    701712        }
    702713
     
    728739                extension( commaExpr );
    729740                output << "(";
    730                 if ( genC ) {
     741                if ( options.genC ) {
    731742                        // arg1 of a CommaExpr is never used, so it can be safely cast to void to reduce gcc warnings.
    732743                        commaExpr->set_arg1( new CastExpr( commaExpr->get_arg1() ) );
     
    739750
    740751        void CodeGenerator::postvisit( TupleAssignExpr * tupleExpr ) {
    741                 assertf( ! genC, "TupleAssignExpr should not reach code generation." );
     752                assertf( ! options.genC, "TupleAssignExpr should not reach code generation." );
    742753                tupleExpr->stmtExpr->accept( *visitor );
    743754        }
    744755
    745756        void CodeGenerator::postvisit( UntypedTupleExpr * tupleExpr ) {
    746                 assertf( ! genC, "UntypedTupleExpr should not reach code generation." );
     757                assertf( ! options.genC, "UntypedTupleExpr should not reach code generation." );
    747758                extension( tupleExpr );
    748759                output << "[";
     
    752763
    753764        void CodeGenerator::postvisit( TupleExpr * tupleExpr ) {
    754                 assertf( ! genC, "TupleExpr should not reach code generation." );
     765                assertf( ! options.genC, "TupleExpr should not reach code generation." );
    755766                extension( tupleExpr );
    756767                output << "[";
     
    760771
    761772        void CodeGenerator::postvisit( TupleIndexExpr * tupleExpr ) {
    762                 assertf( ! genC, "TupleIndexExpr should not reach code generation." );
     773                assertf( ! options.genC, "TupleIndexExpr should not reach code generation." );
    763774                extension( tupleExpr );
    764775                tupleExpr->get_tuple()->accept( *visitor );
     
    767778
    768779        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 );
     780                // if ( options.genC ) std::cerr << "typeexpr still exists: " << typeExpr << std::endl;
     781                // assertf( ! options.genC, "TypeExpr should not reach code generation." );
     782                if ( ! options.genC ) {
     783                        output << genType( typeExpr->get_type(), "", options );
    773784                }
    774785        }
     
    788799        void CodeGenerator::postvisit( CompoundLiteralExpr *compLitExpr ) {
    789800                assert( compLitExpr->get_result() && dynamic_cast< ListInit * > ( compLitExpr->get_initializer() ) );
    790                 output << "(" << genType( compLitExpr->get_result(), "", pretty, genC ) << ")";
     801                output << "(" << genType( compLitExpr->get_result(), "", options ) << ")";
    791802                compLitExpr->get_initializer()->accept( *visitor );
    792803        }
    793804
    794805        void CodeGenerator::postvisit( UniqueExpr * unqExpr ) {
    795                 assertf( ! genC, "Unique expressions should not reach code generation." );
     806                assertf( ! options.genC, "Unique expressions should not reach code generation." );
    796807                output << "unq<" << unqExpr->get_id() << ">{ ";
    797808                unqExpr->get_expr()->accept( *visitor );
     
    829840
    830841        void CodeGenerator::postvisit( ConstructorExpr * expr ) {
    831                 assertf( ! genC, "Unique expressions should not reach code generation." );
     842                assertf( ! options.genC, "Unique expressions should not reach code generation." );
    832843                expr->callExpr->accept( *visitor );
    833844        }
    834845
    835846        void CodeGenerator::postvisit( DeletedExpr * expr ) {
    836                 assertf( ! genC, "Deleted expressions should not reach code generation." );
     847                assertf( ! options.genC, "Deleted expressions should not reach code generation." );
    837848                expr->expr->accept( *visitor );
    838849        }
    839850
     851        void CodeGenerator::postvisit( DefaultArgExpr * arg ) {
     852                assertf( ! options.genC, "Default argument expressions should not reach code generation." );
     853                arg->expr->accept( *visitor );
     854        }
     855
    840856        void CodeGenerator::postvisit( GenericExpr * expr ) {
    841                 assertf( ! genC, "C11 _Generic expressions should not reach code generation." );
     857                assertf( ! options.genC, "C11 _Generic expressions should not reach code generation." );
    842858                output << "_Generic(";
    843859                expr->control->accept( *visitor );
     
    849865                                output << "default: ";
    850866                        } else {
    851                                 output << genType( assoc.type, "", pretty, genC ) << ": ";
     867                                output << genType( assoc.type, "", options ) << ": ";
    852868                        }
    853869                        assoc.expr->accept( *visitor );
     
    884900        void CodeGenerator::postvisit( ExprStmt * exprStmt ) {
    885901                assert( exprStmt );
    886                 if ( genC ) {
     902                if ( options.genC ) {
    887903                        // cast the top-level expression to void to reduce gcc warnings.
    888904                        exprStmt->set_expr( new CastExpr( exprStmt->get_expr() ) );
     
    9941010                  case BranchStmt::FallThrough:
    9951011                  case BranchStmt::FallThroughDefault:
    996                         assertf( ! genC, "fallthru should not reach code generation." );
     1012                        assertf( ! options.genC, "fallthru should not reach code generation." );
    9971013                  output << "fallthru";
    9981014                        break;
    9991015                } // switch
    10001016                // print branch target for labelled break/continue/fallthru in debug mode
    1001                 if ( ! genC && branchStmt->get_type() != BranchStmt::Goto ) {
     1017                if ( ! options.genC && branchStmt->get_type() != BranchStmt::Goto ) {
    10021018                        if ( ! branchStmt->get_target().empty() ) {
    10031019                                output << " " << branchStmt->get_target();
     
    10161032
    10171033        void CodeGenerator::postvisit( ThrowStmt * throwStmt ) {
    1018                 assertf( ! genC, "Throw statements should not reach code generation." );
     1034                assertf( ! options.genC, "Throw statements should not reach code generation." );
    10191035
    10201036                output << ((throwStmt->get_kind() == ThrowStmt::Terminate) ?
     
    10311047        }
    10321048        void CodeGenerator::postvisit( CatchStmt * stmt ) {
    1033                 assertf( ! genC, "Catch statements should not reach code generation." );
     1049                assertf( ! options.genC, "Catch statements should not reach code generation." );
    10341050
    10351051                output << ((stmt->get_kind() == CatchStmt::Terminate) ?
     
    10481064
    10491065        void CodeGenerator::postvisit( WaitForStmt * stmt ) {
    1050                 assertf( ! genC, "Waitfor statements should not reach code generation." );
     1066                assertf( ! options.genC, "Waitfor statements should not reach code generation." );
    10511067
    10521068                bool first = true;
     
    10941110
    10951111        void CodeGenerator::postvisit( WithStmt * with ) {
    1096                 if ( ! genC ) {
     1112                if ( ! options.genC ) {
    10971113                        output << "with ( ";
    10981114                        genCommaList( with->exprs.begin(), with->exprs.end() );
     
    11601176
    11611177        void CodeGenerator::postvisit( ImplicitCtorDtorStmt * stmt ) {
    1162                 assertf( ! genC, "ImplicitCtorDtorStmts should not reach code generation." );
     1178                assertf( ! options.genC, "ImplicitCtorDtorStmts should not reach code generation." );
    11631179                stmt->callStmt->accept( *visitor );
    11641180        }
  • src/CodeGen/CodeGenerator.h

    r7951100 rb067d9b  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Fri Aug 18 15:40:00 2017
    13 // Update Count     : 56
     12// Last Modified On : Tue Apr 30 12:01:00 2019
     13// Update Count     : 57
    1414//
    1515
     
    2020#include <string>                 // for string
    2121
     22#include "CodeGen/Options.h"      // for Options
    2223#include "Common/Indenter.h"      // for Indenter
    2324#include "Common/PassVisitor.h"   // for PassVisitor
     
    3132
    3233                CodeGenerator( std::ostream &os, bool pretty = false, bool genC = false, bool lineMarks = false, bool printExprTypes = false );
     34                CodeGenerator( std::ostream &os, const Options &options );
    3335
    3436                //*** Turn off visit_children for all nodes
     
    9496                void postvisit( ConstructorExpr * );
    9597                void postvisit( DeletedExpr * );
     98                void postvisit( DefaultArgExpr * );
    9699                void postvisit( GenericExpr * );
    97100
     
    143146                std::ostream & output;
    144147                LabelPrinter printLabels;
    145                 bool pretty = false;  // pretty print
    146                 bool genC = false;    // true if output has to be C code
    147                 bool lineMarks = false;
    148                 bool printExprTypes = false;
     148                Options options;
    149149        public:
    150150                LineEnder endl;
  • src/CodeGen/GenType.cc

    r7951100 rb067d9b  
    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 : Fri Mar 17 09:02:28 2017
    13 // Update Count     : 22
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Wed May  1 15:24:00 2019
     13// Update Count     : 23
    1414//
    1515#include "GenType.h"
     
    2727namespace CodeGen {
    2828        struct GenType : public WithVisitorRef<GenType>, public WithShortCircuiting {
    29                 GenType( const std::string &typeString, bool pretty = false, bool genC = false, bool lineMarks = false );
    30                 std::string get_typeString() const { return typeString; }
    31                 void set_typeString( const std::string &newValue ) { typeString = newValue; }
     29                std::string typeString;
     30                GenType( const std::string &typeString, const Options &options );
    3231
    3332                void previsit( BaseSyntaxNode * );
     
    4847                void postvisit( ZeroType * zeroType );
    4948                void postvisit( OneType * oneType );
     49                void postvisit( GlobalScopeType * globalType );
    5050                void postvisit( TraitInstType * inst );
    5151                void postvisit( TypeofType * typeof );
     52                void postvisit( QualifiedType * qualType );
    5253
    5354          private:
     
    5657                void genArray( const Type::Qualifiers &qualifiers, Type *base, Expression *dimension, bool isVarLen, bool isStatic );
    5758
    58                 std::string typeString;
    59                 bool pretty = false; // pretty print
    60                 bool genC = false;   // generating C code?
    61                 bool lineMarks = false;
     59                Options options;
    6260        };
    6361
     62        std::string genType( Type *type, const std::string &baseString, const Options &options ) {
     63                PassVisitor<GenType> gt( baseString, options );
     64                std::ostringstream os;
     65
     66                if ( ! type->get_attributes().empty() ) {
     67                        PassVisitor<CodeGenerator> cg( os, options );
     68                        cg.pass.genAttributes( type->get_attributes() );
     69                } // if
     70
     71                type->accept( gt );
     72                return os.str() + gt.pass.typeString;
     73        }
     74
    6475        std::string genType( Type *type, const std::string &baseString, bool pretty, bool genC , bool lineMarks ) {
    65                 PassVisitor<GenType> gt( baseString, pretty, genC, lineMarks );
    66                 std::ostringstream os;
    67 
    68                 if ( ! type->get_attributes().empty() ) {
    69                         PassVisitor<CodeGenerator> cg( os, pretty, genC, lineMarks );
    70                         cg.pass.genAttributes( type->get_attributes() );
    71                 } // if
    72 
    73                 type->accept( gt );
    74                 return os.str() + gt.pass.get_typeString();
    75         }
    76 
    77   std::string genPrettyType( Type * type, const std::string & baseString ) {
    78         return genType( type, baseString, true, false );
    79   }
    80 
    81         GenType::GenType( const std::string &typeString, bool pretty, bool genC, bool lineMarks ) : typeString( typeString ), pretty( pretty ), genC( genC ), lineMarks( lineMarks ) {}
     76                return genType( type, baseString, Options(pretty, genC, lineMarks, false ) );
     77        }
     78
     79        std::string genPrettyType( Type * type, const std::string & baseString ) {
     80                return genType( type, baseString, true, false );
     81        }
     82
     83        GenType::GenType( const std::string &typeString, const Options &options ) : typeString( typeString ), options( options ) {}
    8284
    8385        // *** BaseSyntaxNode
     
    133135                } // if
    134136                if ( dimension != 0 ) {
    135                         PassVisitor<CodeGenerator> cg( os, pretty, genC, lineMarks );
     137                        PassVisitor<CodeGenerator> cg( os, options );
    136138                        dimension->accept( cg );
    137139                } else if ( isVarLen ) {
     
    167169        void GenType::postvisit( ReferenceType * refType ) {
    168170                assert( refType->base != 0);
    169                 assertf( ! genC, "Reference types should not reach code generation." );
     171                assertf( ! options.genC, "Reference types should not reach code generation." );
    170172                handleQualifiers( refType );
    171173                typeString = "&" + typeString;
     
    195197                        } // if
    196198                } else {
    197                         PassVisitor<CodeGenerator> cg( os, pretty, genC, lineMarks );
     199                        PassVisitor<CodeGenerator> cg( os, options );
    198200                        os << "(" ;
    199201
     
    215217
    216218                // add forall
    217                 if( ! funcType->forall.empty() && ! genC ) {
     219                if( ! funcType->forall.empty() && ! options.genC ) {
    218220                        // assertf( ! genC, "Aggregate type parameters should not reach code generation." );
    219221                        std::ostringstream os;
    220                         PassVisitor<CodeGenerator> cg( os, pretty, genC, lineMarks );
     222                        PassVisitor<CodeGenerator> cg( os, options );
    221223                        os << "forall(";
    222224                        cg.pass.genCommaList( funcType->forall.begin(), funcType->forall.end() );
     
    229231                if ( ! refType->parameters.empty() ) {
    230232                        std::ostringstream os;
    231                         PassVisitor<CodeGenerator> cg( os, pretty, genC, lineMarks );
     233                        PassVisitor<CodeGenerator> cg( os, options );
    232234                        os << "(";
    233235                        cg.pass.genCommaList( refType->parameters.begin(), refType->parameters.end() );
     
    240242        void GenType::postvisit( StructInstType * structInst )  {
    241243                typeString = structInst->name + handleGeneric( structInst ) + " " + typeString;
    242                 if ( genC ) typeString = "struct " + typeString;
     244                if ( options.genC ) typeString = "struct " + typeString;
    243245                handleQualifiers( structInst );
    244246        }
     
    246248        void GenType::postvisit( UnionInstType * unionInst ) {
    247249                typeString = unionInst->name + handleGeneric( unionInst ) + " " + typeString;
    248                 if ( genC ) typeString = "union " + typeString;
     250                if ( options.genC ) typeString = "union " + typeString;
    249251                handleQualifiers( unionInst );
    250252        }
     
    252254        void GenType::postvisit( EnumInstType * enumInst ) {
    253255                typeString = enumInst->name + " " + typeString;
    254                 if ( genC ) typeString = "enum " + typeString;
     256                if ( options.genC ) typeString = "enum " + typeString;
    255257                handleQualifiers( enumInst );
    256258        }
     
    262264
    263265        void GenType::postvisit( TupleType * tupleType ) {
    264                 assertf( ! genC, "Tuple types should not reach code generation." );
     266                assertf( ! options.genC, "Tuple types should not reach code generation." );
    265267                unsigned int i = 0;
    266268                std::ostringstream os;
     
    268270                for ( Type * t : *tupleType ) {
    269271                        i++;
    270                         os << genType( t, "", pretty, genC, lineMarks ) << (i == tupleType->size() ? "" : ", ");
     272                        os << genType( t, "", options ) << (i == tupleType->size() ? "" : ", ");
    271273                }
    272274                os << "] ";
     
    281283        void GenType::postvisit( ZeroType * zeroType ) {
    282284                // ideally these wouldn't hit codegen at all, but should be safe to make them ints
    283                 typeString = (pretty ? "zero_t " : "long int ") + typeString;
     285                typeString = (options.pretty ? "zero_t " : "long int ") + typeString;
    284286                handleQualifiers( zeroType );
    285287        }
     
    287289        void GenType::postvisit( OneType * oneType ) {
    288290                // ideally these wouldn't hit codegen at all, but should be safe to make them ints
    289                 typeString = (pretty ? "one_t " : "long int ") + typeString;
     291                typeString = (options.pretty ? "one_t " : "long int ") + typeString;
    290292                handleQualifiers( oneType );
    291293        }
    292294
     295        void GenType::postvisit( GlobalScopeType * globalType ) {
     296                assertf( ! options.genC, "Global scope type should not reach code generation." );
     297                handleQualifiers( globalType );
     298        }
     299
    293300        void GenType::postvisit( TraitInstType * inst ) {
    294                 assertf( ! genC, "Trait types should not reach code generation." );
     301                assertf( ! options.genC, "Trait types should not reach code generation." );
    295302                typeString = inst->name + " " + typeString;
    296303                handleQualifiers( inst );
     
    299306        void GenType::postvisit( TypeofType * typeof ) {
    300307                std::ostringstream os;
    301                 PassVisitor<CodeGenerator> cg( os, pretty, genC, lineMarks );
     308                PassVisitor<CodeGenerator> cg( os, options );
    302309                os << "typeof(";
    303310                typeof->expr->accept( cg );
     
    307314        }
    308315
     316        void GenType::postvisit( QualifiedType * qualType ) {
     317                assertf( ! options.genC, "Qualified types should not reach code generation." );
     318                std::ostringstream os;
     319                os << genType( qualType->parent, "", options ) << "." << genType( qualType->child, "", options ) << typeString;
     320                typeString = os.str();
     321                handleQualifiers( qualType );
     322        }
     323
    309324        void GenType::handleQualifiers( Type * type ) {
    310325                if ( type->get_const() ) {
     
    320335                        typeString = "_Atomic " + typeString;
    321336                } // if
    322                 if ( type->get_lvalue() && ! genC ) {
    323                         // when not generating C code, print lvalue for debugging.
    324                         typeString = "lvalue " + typeString;
    325                 }
    326337        }
    327338} // namespace CodeGen
  • src/CodeGen/GenType.h

    r7951100 rb067d9b  
    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 : Fri Jul 21 22:17:23 2017
    13 // Update Count     : 2
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Tue Apr 30 11:47:00 2019
     13// Update Count     : 3
    1414//
    1515
     
    1818#include <string>  // for string
    1919
     20#include "CodeGen/Options.h" // for Options
     21
    2022class Type;
    2123
    2224namespace CodeGen {
     25        std::string genType( Type *type, const std::string &baseString, const Options &options );
    2326        std::string genType( Type *type, const std::string &baseString, bool pretty = false, bool genC = false, bool lineMarks = false );
    2427  std::string genPrettyType( Type * type, const std::string & baseString );
  • src/CodeGen/module.mk

    r7951100 rb067d9b  
    1818#       ArgTweak/Mutate.cc
    1919
    20 SRC +=  CodeGen/Generate.cc \
     20SRC_CODEGEN = \
    2121        CodeGen/CodeGenerator.cc \
     22        CodeGen/FixMain.cc \
    2223        CodeGen/GenType.cc \
    23         CodeGen/FixNames.cc \
    24         CodeGen/FixMain.cc \
    2524        CodeGen/OperatorTable.cc
     25
     26
     27SRC += $(SRC_CODEGEN) CodeGen/Generate.cc CodeGen/FixNames.cc
     28SRCDEMANGLE += $(SRC_CODEGEN)
Note: See TracChangeset for help on using the changeset viewer.