Changeset 02af79b0 for src


Ignore:
Timestamp:
May 9, 2019, 4:47:53 PM (6 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, arm-eh, ast-experimental, cleanup-dtors, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
b038fe4
Parents:
ec28948 (diff), db27767 (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
Files:
21 added
27 edited

Legend:

Unmodified
Added
Removed
  • src/BasicTypes-gen.cc

    rec28948 r02af79b0  
     1#include <algorithm>
    12#include <queue>
    23#include <iostream>
     
    340341        } // for
    341342        code << "\t}; // costMatrix" << endl;
     343
     344        // maximum conversion cost from int
     345        code << "\tstatic const int maxIntCost = " << *max_element(costMatrix[SignedInt], costMatrix[SignedInt] + NUMBER_OF_BASIC_TYPES) << ";" << endl;
    342346        code << "\t";                                                                           // indentation for end marker
    343 
     347       
    344348        if ( (start = str.find( ENDMK, start + 1 )) == string::npos ) Abort( "end", ConversionCost );
    345349        if ( (end = str.find( STARTMK, start + 1 )) == string::npos ) Abort( "start", ConversionCost );
  • src/CodeGen/CodeGenerator.cc

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

    rec28948 r02af79b0  
    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
     
    144146                std::ostream & output;
    145147                LabelPrinter printLabels;
    146                 bool pretty = false;  // pretty print
    147                 bool genC = false;    // true if output has to be C code
    148                 bool lineMarks = false;
    149                 bool printExprTypes = false;
     148                Options options;
    150149        public:
    151150                LineEnder endl;
  • src/CodeGen/GenType.cc

    rec28948 r02af79b0  
    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"
     
    2828        struct GenType : public WithVisitorRef<GenType>, public WithShortCircuiting {
    2929                std::string typeString;
    30                 GenType( const std::string &typeString, bool pretty, bool genC, bool lineMarks );
     30                GenType( const std::string &typeString, const Options &options );
    3131
    3232                void previsit( BaseSyntaxNode * );
     
    5757                void genArray( const Type::Qualifiers &qualifiers, Type *base, Expression *dimension, bool isVarLen, bool isStatic );
    5858
    59                 bool pretty = false;    // pretty print
    60                 bool genC = false;      // generating C code?
    61                 bool lineMarks = false; // lineMarks on for CodeGenerator?
     59                Options options;
    6260        };
    6361
    64         std::string genType( Type *type, const std::string &baseString, bool pretty, bool genC , bool lineMarks ) {
    65                 PassVisitor<GenType> gt( baseString, pretty, genC, lineMarks );
     62        std::string genType( Type *type, const std::string &baseString, const Options &options ) {
     63                PassVisitor<GenType> gt( baseString, options );
    6664                std::ostringstream os;
    6765
    6866                if ( ! type->get_attributes().empty() ) {
    69                         PassVisitor<CodeGenerator> cg( os, pretty, genC, lineMarks );
     67                        PassVisitor<CodeGenerator> cg( os, options );
    7068                        cg.pass.genAttributes( type->get_attributes() );
    7169                } // if
     
    7573        }
    7674
    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 ) {}
     75        std::string genType( Type *type, const std::string &baseString, bool pretty, bool genC , bool 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
    293295        void GenType::postvisit( GlobalScopeType * globalType ) {
    294                 assertf( ! genC, "Global scope type should not reach code generation." );
     296                assertf( ! options.genC, "Global scope type should not reach code generation." );
    295297                handleQualifiers( globalType );
    296298        }
    297299
    298300        void GenType::postvisit( TraitInstType * inst ) {
    299                 assertf( ! genC, "Trait types should not reach code generation." );
     301                assertf( ! options.genC, "Trait types should not reach code generation." );
    300302                typeString = inst->name + " " + typeString;
    301303                handleQualifiers( inst );
     
    304306        void GenType::postvisit( TypeofType * typeof ) {
    305307                std::ostringstream os;
    306                 PassVisitor<CodeGenerator> cg( os, pretty, genC, lineMarks );
     308                PassVisitor<CodeGenerator> cg( os, options );
    307309                os << "typeof(";
    308310                typeof->expr->accept( cg );
     
    313315
    314316        void GenType::postvisit( QualifiedType * qualType ) {
    315                 assertf( ! genC, "Qualified types should not reach code generation." );
    316                 std::ostringstream os;
    317                 os << genType( qualType->parent, "", pretty, genC, lineMarks ) << "." << genType( qualType->child, "", pretty, genC, lineMarks ) << typeString;
     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;
    318320                typeString = os.str();
    319321                handleQualifiers( qualType );
     
    333335                        typeString = "_Atomic " + typeString;
    334336                } // if
    335                 if ( type->get_lvalue() && ! genC ) {
     337                if ( type->get_lvalue() && ! options.genC ) {
    336338                        // when not generating C code, print lvalue for debugging.
    337339                        typeString = "lvalue " + typeString;
  • src/CodeGen/GenType.h

    rec28948 r02af79b0  
    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/Common/Assert.cc

    rec28948 r02af79b0  
    3939}
    4040
     41void abort(const char *fmt, ... ) noexcept __attribute__((noreturn, format(printf, 1, 2)));
     42void abort(const char *fmt, ... ) noexcept {
     43        va_list args;
     44        va_start( args, fmt );
     45        vfprintf( stderr, fmt, args );
     46        va_end( args );
     47        fprintf( stderr, "\n" );
     48        abort();
     49}
     50
    4151// Local Variables: //
    4252// tab-width: 4 //
  • src/Common/PassVisitor.h

    rec28948 r02af79b0  
    44
    55#include <stack>
     6#include <type_traits>
    67
    78#include "Common/Stats.h"
     
    301302
    302303
    303         TypeSubstitution **             get_env_ptr    () { return env_impl             ( pass, 0); }
     304        auto                                    get_env_ptr    () -> decltype(env_impl( pass, 0)) { return env_impl( pass, 0); }
    304305        std::list< Statement* > *       get_beforeStmts() { return stmtsToAddBefore_impl( pass, 0); }
    305306        std::list< Statement* > *       get_afterStmts () { return stmtsToAddAfter_impl ( pass, 0); }
     
    348349};
    349350
     351class WithConstTypeSubstitution {
     352protected:
     353        WithConstTypeSubstitution() = default;
     354        ~WithConstTypeSubstitution() = default;
     355
     356public:
     357        const TypeSubstitution * env = nullptr;
     358};
     359
    350360class WithStmtsToAdd {
    351361protected:
  • src/Common/PassVisitor.impl.h

    rec28948 r02af79b0  
    2020
    2121#define MUTATE_END( type, node )                \
    22         return call_postmutate< type * >( node ); \
     22        auto __return = call_postmutate< type * >( node ); \
     23        assert( __return ); \
     24        return __return;
    2325
    2426
     
    253255
    254256        // don't want statements from outer CompoundStmts to be added to this CompoundStmt
    255         ValueGuardPtr< TypeSubstitution * >  oldEnv        ( get_env_ptr    () );
     257        ValueGuardPtr< typename std::remove_pointer<decltype(get_env_ptr())>::type >  oldEnv( get_env_ptr() );
    256258        ValueGuardPtr< DeclList_t >          oldBeforeDecls( get_beforeDecls() );
    257259        ValueGuardPtr< DeclList_t >          oldAfterDecls ( get_afterDecls () );
     
    19951997
    19961998        // don't want statements from outer CompoundStmts to be added to this StmtExpr
    1997         ValueGuardPtr< TypeSubstitution * >      oldEnv        ( get_env_ptr() );
     1999        ValueGuardPtr< typename std::remove_pointer<decltype(get_env_ptr())>::type >  oldEnv( get_env_ptr() );
    19982000        ValueGuardPtr< std::list< Statement* > > oldBeforeStmts( get_beforeStmts() );
    19992001        ValueGuardPtr< std::list< Statement* > > oldAfterStmts ( get_afterStmts () );
     
    20122014
    20132015        // don't want statements from outer CompoundStmts to be added to this StmtExpr
    2014         ValueGuardPtr< TypeSubstitution * >      oldEnv        ( get_env_ptr() );
     2016        ValueGuardPtr< typename std::remove_pointer<decltype(get_env_ptr())>::type >  oldEnv( get_env_ptr() );
    20152017        ValueGuardPtr< std::list< Statement* > > oldBeforeStmts( get_beforeStmts() );
    20162018        ValueGuardPtr< std::list< Statement* > > oldAfterStmts ( get_afterStmts () );
  • src/Common/PassVisitor.proto.h

    rec28948 r02af79b0  
    165165static inline type * name##_impl( __attribute__((unused)) pass_type& pass, __attribute__((unused)) long unused ) { return nullptr;}    \
    166166
    167 FIELD_PTR( TypeSubstitution *, env )
     167FIELD_PTR( const TypeSubstitution *, env )
    168168FIELD_PTR( std::list< Statement* >, stmtsToAddBefore )
    169169FIELD_PTR( std::list< Statement* >, stmtsToAddAfter  )
     
    174174FIELD_PTR( PassVisitor<pass_type> * const, visitor )
    175175
     176#undef FIELD_PTR
     177
    176178//---------------------------------------------------------
    177179// Indexer
  • src/CompilationState.cc

    rec28948 r02af79b0  
    99// Author           : Rob Schluntz
    1010// Created On       : Mon Ju1 30 10:47:01 2018
    11 // Last Modified By : Rob Schluntz
    12 // Last Modified On : Mon Ju1 30 10:46:25 2018
    13 // Update Count     : 2
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Fri May  3 13:45:23 2019
     13// Update Count     : 4
    1414//
    1515
    16 bool
     16int
    1717        astp = false,
    1818        bresolvep = false,
     
    2626        libcfap = false,
    2727        nopreludep = false,
    28         noprotop = false,
     28        genproto = false,
    2929        nomainp = false,
    3030        parsep = false,
  • src/CompilationState.h

    rec28948 r02af79b0  
    99// Author           : Rob Schluntz
    1010// Created On       : Mon Ju1 30 10:47:01 2018
    11 // Last Modified By : Rob Schluntz
    12 // Last Modified On : Mon Ju1 30 10:46:25 2018
    13 // Update Count     : 2
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Fri May  3 13:43:21 2019
     13// Update Count     : 4
    1414//
    1515
    1616extern int yydebug;                   // set for -g flag (Grammar)
    17 extern bool
     17extern int
    1818        astp,
    1919        bresolvep,
     
    2727        libcfap,
    2828        nopreludep,
    29         noprotop,
     29        genproto,
    3030        nomainp,
    3131        parsep,
  • src/ControlStruct/ExceptTranslate.cc

    rec28948 r02af79b0  
    617617                                return create_terminate_rethrow( throwStmt );
    618618                        } else {
    619                                 assertf(false, "Invalid throw in %s at %i\n",
     619                                abort("Invalid throw in %s at %i\n",
    620620                                        throwStmt->location.filename.c_str(),
    621621                                        throwStmt->location.first_line);
    622                                 return nullptr;
    623622                        }
    624623                } else {
     
    628627                                return create_resume_rethrow( throwStmt );
    629628                        } else {
    630                                 assertf(false, "Invalid throwResume in %s at %i\n",
     629                                abort("Invalid throwResume in %s at %i\n",
    631630                                        throwStmt->location.filename.c_str(),
    632631                                        throwStmt->location.first_line);
    633                                 return nullptr;
    634632                        }
    635633                }
  • src/GenPoly/Box.cc

    rec28948 r02af79b0  
    7676
    7777                /// Replaces polymorphic return types with out-parameters, replaces calls to polymorphic functions with adapter calls as needed, and adds appropriate type variables to the function call
    78                 class Pass1 final : public BoxPass, public WithTypeSubstitution, public WithStmtsToAdd, public WithGuards, public WithVisitorRef<Pass1>, public WithShortCircuiting {
     78                class Pass1 final : public BoxPass, public WithConstTypeSubstitution, public WithStmtsToAdd, public WithGuards, public WithVisitorRef<Pass1>, public WithShortCircuiting {
    7979                  public:
    8080                        Pass1();
     
    150150                /// * Calculates polymorphic offsetof expressions from offset array
    151151                /// * Inserts dynamic calculation of polymorphic type layouts where needed
    152                 class PolyGenericCalculator final : public BoxPass, public WithGuards, public WithVisitorRef<PolyGenericCalculator>, public WithStmtsToAdd, public WithDeclsToAdd, public WithTypeSubstitution {
     152                class PolyGenericCalculator final : public BoxPass, public WithGuards, public WithVisitorRef<PolyGenericCalculator>, public WithStmtsToAdd, public WithDeclsToAdd, public WithConstTypeSubstitution {
    153153                public:
    154154                        PolyGenericCalculator();
     
    17641764
    17651765                Expression *PolyGenericCalculator::postmutate( SizeofExpr *sizeofExpr ) {
    1766                         Type *ty = sizeofExpr->get_isType() ? 
     1766                        Type *ty = sizeofExpr->get_isType() ?
    17671767                                sizeofExpr->get_type() : sizeofExpr->get_expr()->get_result();
    1768                        
     1768
    17691769                        Expression * gen = genSizeof( ty );
    17701770                        if ( gen ) {
  • src/GenPoly/GenPoly.cc

    rec28948 r02af79b0  
    440440        }
    441441
    442         bool needsBoxing( Type * param, Type * arg, const TyVarMap &exprTyVars, TypeSubstitution * env ) {
     442        bool needsBoxing( Type * param, Type * arg, const TyVarMap &exprTyVars, const TypeSubstitution * env ) {
    443443                // is parameter is not polymorphic, don't need to box
    444444                if ( ! isPolyType( param, exprTyVars ) ) return false;
     
    450450        }
    451451
    452         bool needsBoxing( Type * param, Type * arg, ApplicationExpr * appExpr, TypeSubstitution * env ) {
     452        bool needsBoxing( Type * param, Type * arg, ApplicationExpr * appExpr, const TypeSubstitution * env ) {
    453453                FunctionType * function = getFunctionType( appExpr->function->result );
    454454                assertf( function, "ApplicationExpr has non-function type: %s", toString( appExpr->function->result ).c_str() );
  • src/GenPoly/GenPoly.h

    rec28948 r02af79b0  
    8181
    8282        /// true if arg requires boxing given exprTyVars
    83         bool needsBoxing( Type * param, Type * arg, const TyVarMap &exprTyVars, TypeSubstitution * env );
     83        bool needsBoxing( Type * param, Type * arg, const TyVarMap &exprTyVars, const TypeSubstitution * env );
    8484
    8585        /// true if arg requires boxing in the call to appExpr
    86         bool needsBoxing( Type * param, Type * arg, ApplicationExpr * appExpr, TypeSubstitution * env );
     86        bool needsBoxing( Type * param, Type * arg, ApplicationExpr * appExpr, const TypeSubstitution * env );
    8787
    8888        /// Adds the type variable `tyVar` to `tyVarMap`
  • src/GenPoly/InstantiateGeneric.cc

    rec28948 r02af79b0  
    168168
    169169        /// Mutator pass that replaces concrete instantiations of generic types with actual struct declarations, scoped appropriately
    170         struct GenericInstantiator final : public WithTypeSubstitution, public WithDeclsToAdd, public WithVisitorRef<GenericInstantiator>, public WithGuards {
     170        struct GenericInstantiator final : public WithConstTypeSubstitution, public WithDeclsToAdd, public WithVisitorRef<GenericInstantiator>, public WithGuards {
    171171                /// Map of (generic type, parameter list) pairs to concrete type instantiations
    172172                InstantiationMap< AggregateDecl, AggregateDecl > instantiations;
  • src/GenPoly/Specialize.cc

    rec28948 r02af79b0  
    4242
    4343namespace GenPoly {
    44         struct Specialize final : public WithTypeSubstitution, public WithStmtsToAdd, public WithVisitorRef<Specialize> {
     44        struct Specialize final : public WithConstTypeSubstitution, public WithStmtsToAdd, public WithVisitorRef<Specialize> {
    4545                Expression * postmutate( ApplicationExpr *applicationExpr );
    4646                Expression * postmutate( CastExpr *castExpr );
     
    5454
    5555        /// Looks up open variables in actual type, returning true if any of them are bound in the environment or formal type.
    56         bool needsPolySpecialization( Type *formalType, Type *actualType, TypeSubstitution *env ) {
     56        bool needsPolySpecialization( Type *formalType, Type *actualType, const TypeSubstitution *env ) {
    5757                if ( env ) {
    5858                        using namespace ResolvExpr;
     
    145145        }
    146146
    147         bool needsSpecialization( Type *formalType, Type *actualType, TypeSubstitution *env ) {
     147        bool needsSpecialization( Type *formalType, Type *actualType, const TypeSubstitution *env ) {
    148148                return needsPolySpecialization( formalType, actualType, env ) || needsTupleSpecialization( formalType, actualType );
    149149        }
  • src/InitTweak/FixInit.cc

    rec28948 r02af79b0  
    7272                };
    7373
    74                 struct InsertImplicitCalls : public WithTypeSubstitution {
     74                struct InsertImplicitCalls : public WithConstTypeSubstitution {
    7575                        /// wrap function application expressions as ImplicitCopyCtorExpr nodes so that it is easy to identify which
    7676                        /// function calls need their parameters to be copy constructed
     
    187187                };
    188188
    189                 class FixCopyCtors final : public WithStmtsToAdd, public WithShortCircuiting, public WithVisitorRef<FixCopyCtors>, public WithTypeSubstitution {
     189                class FixCopyCtors final : public WithStmtsToAdd, public WithShortCircuiting, public WithVisitorRef<FixCopyCtors>, public WithConstTypeSubstitution {
    190190                  public:
    191191                        FixCopyCtors( UnqCount & unqCount ) : unqCount( unqCount ){}
  • src/ResolvExpr/ConversionCost.cc

    rec28948 r02af79b0  
    1010// Created On       : Sun May 17 07:06:19 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Apr 26 16:33:04 2019
    13 // Update Count     : 24
     12// Last Modified On : Mon May  6 14:18:22 2019
     13// Update Count     : 25
    1414//
    1515
     
    249249                /*_FLDXC*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0, },
    250250        }; // costMatrix
     251        static const int maxIntCost = 15;
    251252        // GENERATED END
    252253        static_assert(
     
    461462                        } // if
    462463                } else if ( dynamic_cast< PointerType* >( dest ) ) {
    463                         cost = Cost::safe;
     464                        cost = Cost::zero;
     465                        cost.incSafe( maxIntCost + 2 ); // +1 for zero_t -> int, +1 for disambiguation
    464466                } // if
    465467        }
  • src/ResolvExpr/RenameVars.cc

    rec28948 r02af79b0  
    1010// Created On       : Sun May 17 12:05:18 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Mar  2 17:36:32 2016
    13 // Update Count     : 5
     12// Last Modified On : Tue Apr 30 17:07:57 2019
     13// Update Count     : 7
    1414//
    1515
     
    3939                  private:
    4040                        int level, resetCount;
    41                         std::list< std::map< std::string, std::string > > mapStack;
     41                        std::list< std::unordered_map< std::string, std::string > > mapStack;
    4242                };
    4343
     
    5555        namespace {
    5656                RenameVars::RenameVars() : level( 0 ), resetCount( 0 ) {
    57                         mapStack.push_front( std::map< std::string, std::string >() );
     57                        mapStack.push_front( std::unordered_map< std::string, std::string >() );
    5858                }
    5959
     
    6565                void RenameVars::previsit( TypeInstType * instType ) {
    6666                        previsit( (Type *)instType );
    67                         std::map< std::string, std::string >::const_iterator i = mapStack.front().find( instType->name );
     67                        std::unordered_map< std::string, std::string >::const_iterator i = mapStack.front().find( instType->name );
    6868                        if ( i != mapStack.front().end() ) {
    6969                                instType->name = i->second;
  • src/ResolvExpr/TypeEnvironment.h

    rec28948 r02af79b0  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 12:24:58 2015
    11 // Last Modified By : Aaron B. Moss
    12 // Last Modified On : Mon Jun 18 11:58:00 2018
    13 // Update Count     : 4
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Tue Apr 30 23:04:10 2019
     13// Update Count     : 9
    1414//
    1515
     
    1818#include <iostream>                    // for ostream
    1919#include <list>                        // for list, list<>::iterator, list<>...
    20 #include <map>                         // for map, map<>::value_compare
    21 #include <set>                         // for set
     20#include <map>                                             // for map, map<>::value_compare
     21#include <unordered_map>
     22#include <set>                                             // for set
    2223#include <string>                      // for string
    2324#include <utility>                     // for move, swap
     
    6465                AssertionSetValue() : isUsed(false), resnSlot(0) {}
    6566        };
    66         typedef std::map< DeclarationWithType*, AssertionSetValue, AssertCompare > AssertionSet;
    67         typedef std::map< std::string, TypeDecl::Data > OpenVarSet;
     67        typedef std::map< DeclarationWithType *, AssertionSetValue, AssertCompare > AssertionSet;
     68        typedef std::unordered_map< std::string, TypeDecl::Data > OpenVarSet;
    6869
    6970        /// merges one set of open vars into another
  • src/SynTree/Declaration.h

    rec28948 r02af79b0  
    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 : Sun Sep  3 19:24:06 2017
    13 // Update Count     : 131
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Thr May  2 10:47:00 2019
     13// Update Count     : 135
    1414//
    1515
     
    1919#include <iosfwd>                // for ostream
    2020#include <list>                  // for list
     21#include <unordered_map>         // for unordered_map
    2122#include <string>                // for string, operator+, allocator, to_string
    2223
     
    166167        CompoundStmt *get_statements() const { return statements; }
    167168        void set_statements( CompoundStmt *newValue ) { statements = newValue; }
     169        bool has_body() const { return NULL != statements; }
    168170
    169171        static FunctionDecl * newFunction( const std::string & name, FunctionType * type, CompoundStmt * statements );
     
    334336        virtual Declaration *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    335337  private:
    336         std::map< std::string, long long int > enumValues;
     338        std::unordered_map< std::string, long long int > enumValues;
    337339        virtual std::string typeString() const override;
    338340};
  • src/SynTree/TypeSubstitution.cc

    rec28948 r02af79b0  
    108108namespace {
    109109        struct EnvTrimmer {
    110                 TypeSubstitution * env, * newEnv;
    111                 EnvTrimmer( TypeSubstitution * env, TypeSubstitution * newEnv ) : env( env ), newEnv( newEnv ){}
     110                const TypeSubstitution * env;
     111                TypeSubstitution * newEnv;
     112                EnvTrimmer( const TypeSubstitution * env, TypeSubstitution * newEnv ) : env( env ), newEnv( newEnv ){}
    112113                void previsit( TypeDecl * tyDecl ) {
    113114                        // transfer known bindings for seen type variables
     
    120121
    121122/// reduce environment to just the parts that are referenced in a given expression
    122 TypeSubstitution * TypeSubstitution::newFromExpr( Expression * expr, TypeSubstitution * env ) {
     123TypeSubstitution * TypeSubstitution::newFromExpr( Expression * expr, const TypeSubstitution * env ) {
    123124        if ( env ) {
    124125                TypeSubstitution * newEnv = new TypeSubstitution();
  • src/SynTree/TypeSubstitution.h

    rec28948 r02af79b0  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Jul 22 09:52:24 2017
    13 // Update Count     : 3
     12// Last Modified On : Tue Apr 30 22:52:47 2019
     13// Update Count     : 9
    1414//
    1515
     
    1919#include <iosfwd>                  // for ostream
    2020#include <list>                    // for list<>::iterator, _List_iterator
    21 #include <map>                     // for _Rb_tree_iterator, map, map<>::val...
    22 #include <set>                     // for set
     21#include <unordered_map>
     22#include <unordered_set>
    2323#include <string>                  // for string, operator!=
    2424#include <utility>                 // for pair
     
    3939        TypeSubstitution &operator=( const TypeSubstitution &other );
    4040
    41         template< typename SynTreeClass > int apply( SynTreeClass *&input );
    42         template< typename SynTreeClass > int applyFree( SynTreeClass *&input );
     41        template< typename SynTreeClass > int apply( SynTreeClass *&input ) const;
     42        template< typename SynTreeClass > int applyFree( SynTreeClass *&input ) const;
    4343
    4444        void add( std::string formalType, Type *actualType );
     
    5656
    5757        /// create a new TypeSubstitution using bindings from env containing all of the type variables in expr
    58         static TypeSubstitution * newFromExpr( Expression * expr, TypeSubstitution * env );
     58        static TypeSubstitution * newFromExpr( Expression * expr, const TypeSubstitution * env );
    5959
    6060        void normalize();
     
    7878        friend class PassVisitor;
    7979
    80         typedef std::map< std::string, Type* > TypeEnvType;
    81         typedef std::map< std::string, Expression* > VarEnvType;
     80        typedef std::unordered_map< std::string, Type * > TypeEnvType;
     81        typedef std::unordered_map< std::string, Expression * > VarEnvType;
    8282        TypeEnvType typeEnv;
    8383        VarEnvType varEnv;
     
    9898        ActualIterator actualIt = actualBegin;
    9999        for ( ; formalIt != formalEnd; ++formalIt, ++actualIt ) {
    100                 if ( TypeDecl *formal = dynamic_cast< TypeDecl* >( *formalIt ) ) {
    101                         if ( TypeExpr *actual = dynamic_cast< TypeExpr* >( *actualIt ) ) {
     100                if ( TypeDecl *formal = dynamic_cast< TypeDecl * >( *formalIt ) ) {
     101                        if ( TypeExpr *actual = dynamic_cast< TypeExpr * >( *actualIt ) ) {
    102102                                if ( formal->get_name() != "" ) {
    103103                                        TypeEnvType::iterator i = typeEnv.find( formal->get_name() );
     
    130130// definitition must happen after PassVisitor is included so that WithGuards can be used
    131131struct TypeSubstitution::Substituter : public WithGuards, public WithVisitorRef<Substituter> {
    132                 Substituter( TypeSubstitution & sub, bool freeOnly ) : sub( sub ), freeOnly( freeOnly ) {}
     132                Substituter( const TypeSubstitution & sub, bool freeOnly ) : sub( sub ), freeOnly( freeOnly ) {}
    133133
    134134                Type * postmutate( TypeInstType * aggregateUseType );
     
    143143                void premutate( UnionInstType * aggregateUseType );
    144144
    145                 TypeSubstitution & sub;
     145                const TypeSubstitution & sub;
    146146                int subCount = 0;
    147147                bool freeOnly;
    148                 typedef std::set< std::string > BoundVarsType;
     148                typedef std::unordered_set< std::string > BoundVarsType;
    149149                BoundVarsType boundVars;
    150150};
    151151
    152152template< typename SynTreeClass >
    153 int TypeSubstitution::apply( SynTreeClass *&input ) {
     153int TypeSubstitution::apply( SynTreeClass *&input ) const {
    154154        assert( input );
    155155        PassVisitor<Substituter> sub( *this, false );
     
    163163
    164164template< typename SynTreeClass >
    165 int TypeSubstitution::applyFree( SynTreeClass *&input ) {
     165int TypeSubstitution::applyFree( SynTreeClass *&input ) const {
    166166        assert( input );
    167167        PassVisitor<Substituter> sub( *this, true );
  • src/Tuples/TupleExpansion.cc

    rec28948 r02af79b0  
    5858                };
    5959
    60                 struct TupleTypeReplacer : public WithDeclsToAdd, public WithGuards, public WithTypeSubstitution {
     60                struct TupleTypeReplacer : public WithDeclsToAdd, public WithGuards, public WithConstTypeSubstitution {
    6161                        Type * postmutate( TupleType * tupleType );
    6262
  • src/include/cassert

    rec28948 r02af79b0  
    4545}
    4646
     47extern void abort(const char *fmt, ...  ) noexcept __attribute__((noreturn, format(printf, 1, 2)));
    4748// Local Variables: //
    4849// tab-width: 4 //
  • src/main.cc

    rec28948 r02af79b0  
    77// main.cc --
    88//
    9 // Author           : Richard C. Bilson
     9// Author           : Peter Buhr and Rob Schluntz
    1010// Created On       : Fri May 15 23:12:02 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Feb 16 09:14:04 2019
    13 // Update Count     : 500
     12// Last Modified On : Fri May  3 16:10:52 2019
     13// Update Count     : 599
    1414//
    1515
     
    2424#include <fstream>                          // for ofstream
    2525#include <iostream>                         // for operator<<, basic_ostream
     26#include <iomanip>
    2627#include <iterator>                         // for back_inserter
    2728#include <list>                             // for list
     
    3940#include "Common/Stats.h"
    4041#include "Common/PassVisitor.h"
     42// #include "AST/Pass.hpp"
    4143#include "Common/SemanticError.h"           // for SemanticError
    4244#include "Common/UnimplementedError.h"      // for UnimplementedError
     
    6567using namespace std;
    6668
    67 void NewPass(const char * const name) {
    68         Stats::Heap::newPass(name);
     69static void NewPass( const char * const name ) {
     70        Stats::Heap::newPass( name );
    6971        using namespace Stats::Counters;
    70        
    7172        {
    72                 static auto group = build<CounterGroup>("Pass Visitor");
    73                 auto pass = build<CounterGroup>(name, group);
     73                static auto group = build<CounterGroup>( "Pass Visitor" );
     74                auto pass = build<CounterGroup>( name, group );
    7475                pass_visitor_stats.depth = 0;
    75                 pass_visitor_stats.avg = build<AverageCounter<double>>("Average Depth", pass);
    76                 pass_visitor_stats.max = build<MaxCounter<double>>("Max Depth", pass);
     76                pass_visitor_stats.avg = build<AverageCounter<double>>( "Average Depth", pass );
     77                pass_visitor_stats.max = build<MaxCounter<double>>( "Max Depth", pass );
    7778        }
    78 
    7979        {
    80                 static auto group = build<CounterGroup>("Syntax Node");
    81                 auto pass = build<CounterGroup>(name, group);
    82                 BaseSyntaxNode::new_nodes = build<SimpleCounter>("Allocs", pass);
     80                static auto group = build<CounterGroup>( "Syntax Node" );
     81                auto pass = build<CounterGroup>( name, group );
     82                BaseSyntaxNode::new_nodes = build<SimpleCounter>( "Allocs", pass );
    8383        }
    8484}
    8585
    86 #define PASS(name, pass)                  \
     86#define PASS( name, pass )                  \
    8787        if ( errorp ) { cerr << name << endl; } \
    8888        NewPass(name);                          \
     
    9595DeclarationNode * parseTree = nullptr;                                  // program parse tree
    9696
    97 std::string PreludeDirector = "";
     97static std::string PreludeDirector = "";
    9898
    9999static void parse_cmdline( int argc, char *argv[], const char *& filename );
     
    151151} // backtrace
    152152
    153 void sigSegvBusHandler( int sig_num ) {
     153static void sigSegvBusHandler( int sig_num ) {
    154154        cerr << "*CFA runtime error* program cfa-cpp terminated with "
    155155                 <<     (sig_num == SIGSEGV ? "segment fault" : "bus error")
     
    157157        backtrace( 2 );                                                                         // skip first 2 stack frames
    158158        //_exit( EXIT_FAILURE );
    159         abort();
     159        abort();                                                                                        // cause core dump for debugging
    160160} // sigSegvBusHandler
    161161
    162 void sigAbortHandler( __attribute__((unused)) int sig_num ) {
     162static void sigAbortHandler( __attribute__((unused)) int sig_num ) {
    163163        backtrace( 6 );                                                                         // skip first 6 stack frames
    164164        signal( SIGABRT, SIG_DFL);                                                      // reset default signal handler
     
    240240                        parseTree->printList( cout );
    241241                        delete parseTree;
    242                         return 0;
     242                        return EXIT_SUCCESS;
    243243                } // if
    244244
     
    249249                if ( astp ) {
    250250                        dump( translationUnit );
    251                         return 0;
     251                        return EXIT_SUCCESS;
    252252                } // if
    253253
     
    262262                if ( symtabp ) {
    263263                        deleteAll( translationUnit );
    264                         return 0;
     264                        return EXIT_SUCCESS;
    265265                } // if
    266266
     
    268268                        PassVisitor<ResolvExpr::AlternativePrinter> printer( cout );
    269269                        acceptAll( translationUnit, printer );
    270                         return 0;
     270                        return EXIT_SUCCESS;
    271271                } // if
    272272
    273273                if ( validp ) {
    274274                        dump( translationUnit );
    275                         return 0;
     275                        return EXIT_SUCCESS;
    276276                } // if
    277277
     
    288288                        CodeTools::printDeclStats( translationUnit );
    289289                        deleteAll( translationUnit );
    290                         return 0;
    291                 }
     290                        return EXIT_SUCCESS;
     291                } // if
    292292
    293293                if ( bresolvep ) {
    294294                        dump( translationUnit );
    295                         return 0;
     295                        return EXIT_SUCCESS;
    296296                } // if
    297297
     
    300300                if ( resolvprotop ) {
    301301                        CodeTools::dumpAsResolvProto( translationUnit );
    302                         return 0;
    303                 }
     302                        return EXIT_SUCCESS;
     303                } // if
    304304
    305305                PASS( "Resolve", ResolvExpr::resolve( translationUnit ) );
    306306                if ( exprp ) {
    307307                        dump( translationUnit );
    308                         return 0;
     308                        return EXIT_SUCCESS;
    309309                } // if
    310310
     
    313313                if ( ctorinitp ) {
    314314                        dump ( translationUnit );
    315                         return 0;
     315                        return EXIT_SUCCESS;
    316316                } // if
    317317
     
    328328                if ( tuplep ) {
    329329                        dump( translationUnit );
    330                         return 0;
    331                 }
     330                        return EXIT_SUCCESS;
     331                } // if
    332332
    333333                PASS( "Virtual Expand Casts", Virtual::expandCasts( translationUnit ) ); // Must come after translateEHM
     
    336336                if ( genericsp ) {
    337337                        dump( translationUnit );
    338                         return 0;
    339                 }
     338                        return EXIT_SUCCESS;
     339                } // if
    340340                PASS( "Convert L-Value", GenPoly::convertLvalue( translationUnit ) );
    341341
     
    343343                if ( bboxp ) {
    344344                        dump( translationUnit );
    345                         return 0;
     345                        return EXIT_SUCCESS;
    346346                } // if
    347347                PASS( "Box", GenPoly::box( translationUnit ) );
     
    349349                if ( bcodegenp ) {
    350350                        dump( translationUnit );
    351                         return 0;
    352                 }
     351                        return EXIT_SUCCESS;
     352                } // if
    353353
    354354                if ( optind < argc ) {                                                  // any commands after the flags and input file ? => output file name
     
    357357
    358358                CodeTools::fillLocations( translationUnit );
    359                 PASS( "Code Gen", CodeGen::generate( translationUnit, *output, ! noprotop, prettycodegenp, true, linemarks ) );
     359                PASS( "Code Gen", CodeGen::generate( translationUnit, *output, ! genproto, prettycodegenp, true, linemarks ) );
    360360
    361361                CodeGen::FixMain::fix( *output, (PreludeDirector + "/bootloader.c").c_str() );
     
    373373                        delete output;
    374374                } // if
    375                 return 1;
     375                return EXIT_FAILURE;
    376376        } catch ( UnimplementedError &e ) {
    377377                cout << "Sorry, " << e.get_what() << " is not currently implemented" << endl;
     
    379379                        delete output;
    380380                } // if
    381                 return 1;
     381                return EXIT_FAILURE;
    382382        } catch ( CompilerError &e ) {
    383383                cerr << "Compiler Error: " << e.get_what() << endl;
     
    386386                        delete output;
    387387                } // if
    388                 return 1;
    389         } catch(...) {
     388                return EXIT_FAILURE;
     389        } catch ( ... ) {
    390390                std::exception_ptr eptr = std::current_exception();
    391391                try {
    392392                        if (eptr) {
    393393                                std::rethrow_exception(eptr);
    394                         }
    395                         else {
    396                                 std::cerr << "Exception Uncaught and Unkown" << std::endl;
    397                         }
     394                        } else {
     395                                std::cerr << "Exception Uncaught and Unknown" << std::endl;
     396                        } // if
    398397                } catch(const std::exception& e) {
    399398                        std::cerr << "Uncaught Exception \"" << e.what() << "\"\n";
    400                 }
    401                 return 1;
    402         }// try
     399                } // try
     400                return EXIT_FAILURE;
     401        } // try
    403402
    404403        deleteAll( translationUnit );
    405404        Stats::print();
    406 
    407         return 0;
     405        return EXIT_SUCCESS;
    408406} // main
    409407
    410 void parse_cmdline( int argc, char * argv[], const char *& filename ) {
    411         enum { Ast, Bbox, Bresolver, CtorInitFix, DeclStats, Expr, ExprAlt, Grammar, LibCFA, Linemarks, Nolinemarks, Nopreamble, Parse, PreludeDir, Prototypes, Resolver, ResolvProto, Stats, Symbol, Tree, TupleExpansion, Validate};
    412 
    413         static struct option long_opts[] = {
    414                 { "ast", no_argument, 0, Ast },
    415                 { "before-box", no_argument, 0, Bbox },
    416                 { "before-resolver", no_argument, 0, Bresolver },
    417                 { "ctorinitfix", no_argument, 0, CtorInitFix },
    418                 { "decl-stats", no_argument, 0, DeclStats },
    419                 { "expr", no_argument, 0, Expr },
    420                 { "expralt", no_argument, 0, ExprAlt },
    421                 { "grammar", no_argument, 0, Grammar },
    422                 { "libcfa", no_argument, 0, LibCFA },
    423                 { "line-marks", no_argument, 0, Linemarks },
    424                 { "no-line-marks", no_argument, 0, Nolinemarks },
    425                 { "no-preamble", no_argument, 0, Nopreamble },
    426                 { "parse", no_argument, 0, Parse },
    427                 { "prelude-dir", required_argument, 0, PreludeDir },
    428                 { "no-prototypes", no_argument, 0, Prototypes },
    429                 { "resolver", no_argument, 0, Resolver },
    430                 { "resolv-proto", no_argument, 0, ResolvProto },
    431                 { "stats", required_argument, 0, Stats },
    432                 { "symbol", no_argument, 0, Symbol },
    433                 { "tree", no_argument, 0, Tree },
    434                 { "tuple-expansion", no_argument, 0, TupleExpansion },
    435                 { "validate", no_argument, 0, Validate },
    436                 { 0, 0, 0, 0 }
    437         }; // long_opts
    438         int long_index;
    439 
     408
     409static const char optstring[] = ":hlLmNn:pP:S:twW:D:F:";
     410
     411enum { PreludeDir = 128 };
     412static struct option long_opts[] = {
     413        { "help", no_argument, nullptr, 'h' },
     414        { "libcfa", no_argument, nullptr, 'l' },
     415        { "linemarks", no_argument, nullptr, 'L' },
     416        { "no-main", no_argument, 0, 'm' },
     417        { "no-linemarks", no_argument, nullptr, 'N' },
     418        { "no-prelude", no_argument, nullptr, 'n' },
     419        { "prototypes", no_argument, nullptr, 'p' },
     420        { "print", required_argument, nullptr, 'P' },
     421        { "prelude-dir", required_argument, nullptr, PreludeDir },
     422        { "statistics", required_argument, nullptr, 'S' },
     423        { "tree", no_argument, nullptr, 't' },
     424        { "", no_argument, nullptr, 0 },                                        // -w
     425        { "", no_argument, nullptr, 0 },                                        // -W
     426        { "", no_argument, nullptr, 0 },                                        // -D
     427        { "", no_argument, nullptr, 0 },                                        // -F
     428        { nullptr, 0, nullptr, 0 }
     429}; // long_opts
     430
     431static const char * description[] = {
     432        "print help message",                                                           // -h
     433        "generate libcfa.c",                                                            // -l
     434        "generate line marks",                                                          // -L
     435        "do not replace main",                                                          // -m
     436        "do not generate line marks",                                           // -N
     437        "do not read prelude",                                                          // -n
     438        "generate prototypes for prelude functions",            // -p
     439        "print",                                                                                        // -P
     440        "<directory> prelude directory for debug/nodebug",      // no flag
     441        "<option-list> enable profiling information:\n          counters,heap,time,all,none", // -S
     442        "build in tree",                                                                        // -t
     443        "",                                                                                                     // -w
     444        "",                                                                                                     // -W
     445        "",                                                                                                     // -D
     446        "",                                                                                                     // -F
     447}; // description
     448
     449static_assert( sizeof( long_opts ) / sizeof( long_opts[0] ) - 1 == sizeof( description ) / sizeof( description[0] ), "Long opts and description must match" );
     450
     451static struct Printopts {
     452        const char * name;
     453        int & flag;
     454        int val;
     455        const char * descript;
     456} printopts[] = {
     457        { "altexpr", expraltp, true, "alternatives for expressions" },
     458        { "ascodegen", codegenp, true, "as codegen rather than AST" },
     459        { "ast", astp, true, "AST after parsing" },
     460        { "astdecl", validp, true, "AST after declaration validation pass" },
     461        { "asterr", errorp, true, "AST on error" },
     462        { "astexpr", exprp, true, "AST after expression analysis" },
     463        { "astgen", genericsp, true, "AST after instantiate generics" },
     464        { "box", bboxp, true, "before box step" },
     465        { "ctordtor", ctorinitp, true, "after ctor/dtor are replaced" },
     466        { "codegen", bcodegenp, true, "before code generation" },
     467        { "declstats", declstatsp, true, "code property statistics" },
     468        { "parse", yydebug, true, "yacc (parsing) debug information" },
     469        { "pretty", prettycodegenp, true, "prettyprint for ascodegen flag" },
     470        { "resolver", bresolvep, true, "before resolver step" },
     471        { "rproto", resolvprotop, true, "resolver-proto instance" },
     472        { "rsteps", resolvep, true, "resolver steps" },
     473        { "symevt", symtabp, true, "symbol table events" },
     474        { "tree", parsep, true, "parse tree" },
     475        { "tuple", tuplep, true, "after tuple expansion" },
     476};
     477enum { printoptsSize = sizeof( printopts ) / sizeof( printopts[0] ) };
     478
     479static void usage( char *argv[] ) {
     480    cout << "Usage: " << argv[0] << " options are:" << endl;
     481        int i = 0, j = 1;                                                                       // j skips starting colon
     482        for ( ; long_opts[i].name != 0 && optstring[j] != '\0'; i += 1, j += 1 ) {
     483                if ( long_opts[i].name[0] != '\0' ) {                   // hidden option, internal usage only
     484                        if ( strcmp( long_opts[i].name, "prelude-dir" ) != 0 ) { // flag
     485                                cout << "  -" << optstring[j] << ",";
     486                        } else {                                                                        // no flag
     487                                j -= 1;                                                                 // compensate
     488                                cout << "     ";
     489                        } // if
     490                        cout << " --" << left << setw(12) << long_opts[i].name << "  ";
     491                        if ( strcmp( long_opts[i].name, "print" ) == 0 ) {
     492                                cout << "one of: " << endl;
     493                                for ( int i = 0; i < printoptsSize; i += 1 ) {
     494                                        cout << setw(10) << " " << left << setw(10) << printopts[i].name << "  " << printopts[i].descript << endl;
     495                                } // for
     496                        } else {
     497                                cout << description[i] << endl;
     498                        } // if
     499                } // if
     500                if ( optstring[j + 1] == ':' ) j += 1;
     501        } // for
     502        if ( long_opts[i].name != 0 || optstring[j] != '\0' ) assertf( false, "internal error, mismatch of option flags and names\n" );
     503    exit( EXIT_FAILURE );
     504} // usage
     505
     506static void parse_cmdline( int argc, char * argv[], const char *& filename ) {
    440507        opterr = 0;                                                                                     // (global) prevent getopt from printing error messages
    441508
    442509        bool Wsuppress = false, Werror = false;
    443510        int c;
    444         while ( (c = getopt_long( argc, argv, "abBcCdefgGlLmnNpqrRstTvwW:yzZD:F:", long_opts, &long_index )) != -1 ) {
     511        while ( (c = getopt_long( argc, argv, optstring, long_opts, nullptr )) != -1 ) {
    445512                switch ( c ) {
    446                         case Ast:
    447                         case 'a':                                                                               // dump AST
    448                         astp = true;
    449                         break;
    450                         case Bresolver:
    451                         case 'b':                                                                               // print before resolver steps
    452                         bresolvep = true;
    453                         break;
    454                         case 'B':                                                                               // print before box steps
    455                         bboxp = true;
    456                         break;
    457                         case CtorInitFix:
    458                         case 'c':                                                                               // print after constructors and destructors are replaced
    459                         ctorinitp = true;
    460                         break;
    461                         case 'C':                                                                               // print before code generation
    462                         bcodegenp = true;
    463                         break;
    464                         case DeclStats:
    465                         case 'd':
    466                                 declstatsp = true;
    467                         break;
    468                         case Expr:
    469                         case 'e':                                                                               // dump AST after expression analysis
    470                         exprp = true;
    471                         break;
    472                         case ExprAlt:
    473                         case 'f':                                                                               // print alternatives for expressions
    474                         expraltp = true;
    475                         break;
    476                         case Grammar:
    477                         case 'g':                                                                               // bison debugging info (grammar rules)
    478                         yydebug = true;
    479                         break;
    480                         case 'G':                                                                               // dump AST after instantiate generics
    481                         genericsp = true;
    482                         break;
    483                         case LibCFA:
    484                         case 'l':                                                                               // generate libcfa.c
     513                  case 'h':                                                                             // help message
     514                        usage( argv );                                                          // no return
     515                        break;
     516                  case 'l':                                                                             // generate libcfa.c
    485517                        libcfap = true;
    486518                        break;
    487                         case Linemarks:
    488                         case 'L':                                                                               // print lines marks
     519                  case 'L':                                                                             // generate line marks
    489520                        linemarks = true;
    490521                        break;
    491                         case Nopreamble:
    492                         case 'n':                                                                               // do not read preamble
     522                  case 'm':                                                                             // do not replace main
     523                        nomainp = true;
     524                        break;
     525                  case 'N':                                                                             // do not generate line marks
     526                        linemarks = false;
     527                        break;
     528                  case 'n':                                                                             // do not read prelude
    493529                        nopreludep = true;
    494530                        break;
    495                         case Nolinemarks:
    496                         case 'N':                                                                               // suppress line marks
    497                         linemarks = false;
    498                         break;
    499                         case Prototypes:
    500                         case 'p':                                                                               // generate prototypes for preamble functions
    501                         noprotop = true;
    502                         break;
    503                         case PreludeDir:
    504                                 PreludeDirector = optarg;
    505                         break;
    506                         case 'm':                                                                               // don't replace the main
    507                                 nomainp = true;
    508                         break;
    509                         case Parse:
    510                         case 'q':                                                                               // dump parse tree
    511                         parsep = true;
    512                         break;
    513                         case Resolver:
    514                         case 'r':                                                                               // print resolver steps
    515                         resolvep = true;
    516                         break;
    517                         case 'R':                                                                               // dump resolv-proto instance
    518                         resolvprotop = true;
    519                         break;
    520                         case Stats:
    521                                 Stats::parse_params(optarg);
    522                         break;
    523                         case Symbol:
    524                         case 's':                                                                               // print symbol table events
    525                         symtabp = true;
    526                         break;
    527                         case Tree:
    528                         case 't':                                                                               // build in tree
     531                  case 'p':                                                                             // generate prototypes for prelude functions
     532                        genproto = true;
     533                        break;
     534                  case 'P':                                                                             // print options
     535                        for ( int i = 0;; i += 1 ) {
     536                                if ( i == printoptsSize ) {
     537                                        cout << "Unknown --print option " << optarg << endl;
     538                                        goto Default;
     539                                } // if
     540                                if ( strcmp( optarg, printopts[i].name ) == 0 ) {
     541                                        printopts[i].flag = printopts[i].val;
     542                                        break;
     543                                } // if
     544                        } // for
     545                        break;
     546                  case PreludeDir:                                                              // prelude directory for debug/nodebug, hidden
     547                        PreludeDirector = optarg;
     548                        break;
     549                  case 'S':                                                                             // enable profiling information, argument comma separated list of names
     550                        Stats::parse_params( optarg );
     551                        break;
     552                  case 't':                                                                             // build in tree
    529553                        treep = true;
    530554                        break;
    531                         case TupleExpansion:
    532                         case 'T':                                                                               // print after tuple expansion
    533                         tuplep = true;
    534                         break;
    535                         case 'v':                                                                               // dump AST after decl validation pass
    536                         validp = true;
    537                         break;
    538                         case 'w':
     555                  case 'w':                                                                             // suppress all warnings, hidden
    539556                        Wsuppress = true;
    540557                        break;
    541                         case 'W':
     558                  case 'W':                                                                             // coordinate gcc -W with CFA, hidden
    542559                        if ( strcmp( optarg, "all" ) == 0 ) {
    543560                                SemanticWarning_EnableAll();
     
    556573                        } // if
    557574                        break;
    558                         case 'y':                                                                               // dump AST on error
    559                         errorp = true;
    560                         break;
    561                         case 'z':                                                                               // dump as codegen rather than AST
    562                         codegenp = true;
    563                         break;
    564                         case 'Z':                                                                       // prettyprint during codegen (i.e. print unmangled names, etc.)
    565                         prettycodegenp = true;
    566                         break;
    567                         case 'D':                                                                               // ignore -Dxxx
    568                         break;
    569                         case 'F':                                                                               // source file-name without suffix
     575                  case 'D':                                                                             // ignore -Dxxx, forwarded by cpp, hidden
     576                        break;
     577                  case 'F':                                                                             // source file-name without suffix, hidden
    570578                        filename = optarg;
    571579                        break;
    572                         case '?':
     580                  case '?':                                                                             // unknown option
    573581                        if ( optopt ) {                                                         // short option ?
    574                                 assertf( false, "Unknown option: -%c\n", (char)optopt );
     582                                cout << "Unknown option -" << (char)optopt << endl;
    575583                        } else {
    576                                 assertf( false, "Unknown option: %s\n", argv[optind - 1] );
    577                         } // if
    578                         #if defined(__GNUC__) && __GNUC__ >= 7
    579                                 __attribute__((fallthrough));
    580                         #endif
    581                         default:
    582                         abort();
     584                                cout << "Unknown option " << argv[optind - 1] << endl;
     585                        } // if
     586                        goto Default;
     587                  case ':':                                                                             // missing option
     588                        if ( optopt ) {                                                         // short option ?
     589                                cout << "Missing option for -" << (char)optopt << endl;
     590                        } else {
     591                                cout << "Missing option for " << argv[optind - 1] << endl;
     592                        } // if
     593                        goto Default;
     594                  Default:
     595                  default:
     596                        usage( argv );                                                          // no return
    583597                } // switch
    584598        } // while
     
    618632        list< Declaration * > decls;
    619633
    620         if ( noprotop ) {
     634        if ( genproto ) {
    621635                filter( translationUnit.begin(), translationUnit.end(), back_inserter( decls ), notPrelude );
    622636        } else {
     
    626640        // depending on commandline options, either generate code or dump the AST
    627641        if ( codegenp ) {
    628                 CodeGen::generate( decls, out, ! noprotop, prettycodegenp );
     642                CodeGen::generate( decls, out, ! genproto, prettycodegenp );
    629643        } else {
    630644                printAll( decls, out );
    631         }
     645        } // if
    632646        deleteAll( translationUnit );
    633647} // dump
Note: See TracChangeset for help on using the changeset viewer.