Changeset 933f32f for src


Ignore:
Timestamp:
May 24, 2019, 10:19:41 AM (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:
d908563
Parents:
6a9d4b4 (diff), 292642a (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' into cleanup-dtors

Location:
src
Files:
48 added
1 deleted
89 edited
1 moved

Legend:

Unmodified
Added
Removed
  • src/CodeGen/CodeGenerator.cc

    r6a9d4b4 r933f32f  
    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

    r6a9d4b4 r933f32f  
    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

    r6a9d4b4 r933f32f  
    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

    r6a9d4b4 r933f32f  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Jul 21 22:17:23 2017
    13 // Update Count     : 2
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Tue Apr 30 11:47:00 2019
     13// Update Count     : 3
    1414//
    1515
     
    1818#include <string>  // for string
    1919
     20#include "CodeGen/Options.h" // for Options
     21
    2022class Type;
    2123
    2224namespace CodeGen {
     25        std::string genType( Type *type, const std::string &baseString, const Options &options );
    2326        std::string genType( Type *type, const std::string &baseString, bool pretty = false, bool genC = false, bool lineMarks = false );
    2427  std::string genPrettyType( Type * type, const std::string & baseString );
  • src/CodeGen/module.mk

    r6a9d4b4 r933f32f  
    1818#       ArgTweak/Mutate.cc
    1919
    20 SRC +=  CodeGen/Generate.cc \
     20SRC_CODEGEN = \
    2121        CodeGen/CodeGenerator.cc \
     22        CodeGen/FixMain.cc \
    2223        CodeGen/GenType.cc \
    23         CodeGen/FixNames.cc \
    24         CodeGen/FixMain.cc \
    2524        CodeGen/OperatorTable.cc
     25
     26
     27SRC += $(SRC_CODEGEN) CodeGen/Generate.cc CodeGen/FixNames.cc
     28SRCDEMANGLE += $(SRC_CODEGEN)
  • src/Common/Assert.cc

    r6a9d4b4 r933f32f  
    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

    r6a9d4b4 r933f32f  
    44
    55#include <stack>
    6 
     6#include <type_traits>
     7
     8#include "Common/Stats.h"
    79#include "Common/utility.h"
    810
     
    153155        virtual void visit( ConstructorInit * ctorInit ) override final;
    154156
    155         virtual void visit( Subrange * subrange ) override final;
    156 
    157157        virtual void visit( Constant * constant ) override final;
    158158
     
    255255        virtual Initializer * mutate( ConstructorInit * ctorInit ) override final;
    256256
    257         virtual Subrange * mutate( Subrange * subrange ) override final;
    258 
    259257        virtual Constant * mutate( Constant * constant ) override final;
    260258
     
    300298
    301299
    302         TypeSubstitution **             get_env_ptr    () { return env_impl             ( pass, 0); }
     300        auto                                    get_env_ptr    () -> decltype(env_impl( pass, 0)) { return env_impl( pass, 0); }
    303301        std::list< Statement* > *       get_beforeStmts() { return stmtsToAddBefore_impl( pass, 0); }
    304302        std::list< Statement* > *       get_afterStmts () { return stmtsToAddAfter_impl ( pass, 0); }
     
    347345};
    348346
     347class WithConstTypeSubstitution {
     348protected:
     349        WithConstTypeSubstitution() = default;
     350        ~WithConstTypeSubstitution() = default;
     351
     352public:
     353        const TypeSubstitution * env = nullptr;
     354};
     355
    349356class WithStmtsToAdd {
    350357protected:
     
    426433};
    427434
     435#include "Common/Stats.h"
     436
     437extern struct PassVisitorStats {
     438        size_t depth = 0;
     439        Stats::Counters::MaxCounter<double> * max = nullptr;
     440        Stats::Counters::AverageCounter<double> * avg = nullptr;
     441} pass_visitor_stats;
     442
    428443#include "SynTree/TypeSubstitution.h"
    429444#include "PassVisitor.impl.h"
  • src/Common/PassVisitor.impl.h

    r6a9d4b4 r933f32f  
    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
     
    6769        SemanticErrorException errors;
    6870
     71        pass_visitor_stats.depth++;
     72        pass_visitor_stats.max->push(pass_visitor_stats.depth);
     73        pass_visitor_stats.avg->push(pass_visitor_stats.depth);
    6974        for ( std::list< Declaration* >::iterator i = decls.begin(); ; ++i ) {
     75
     76
    7077                // splice in new declarations after previous decl
    7178                if ( !empty( afterDecls ) ) { decls.splice( i, *afterDecls ); }
     
    8390                if ( !empty( beforeDecls ) ) { decls.splice( i, *beforeDecls ); }
    8491        }
     92        pass_visitor_stats.depth--;
    8593        if ( ! errors.isEmpty() ) {
    8694                throw errors;
     
    94102        SemanticErrorException errors;
    95103
     104        pass_visitor_stats.depth++;
     105        pass_visitor_stats.max->push(pass_visitor_stats.depth);
     106        pass_visitor_stats.avg->push(pass_visitor_stats.depth);
    96107        for ( std::list< Declaration* >::iterator i = decls.begin(); ; ++i ) {
    97108                // splice in new declarations after previous decl
     
    109120                if ( !empty( beforeDecls ) ) { decls.splice( i, *beforeDecls ); }
    110121        }
     122        pass_visitor_stats.depth--;
    111123        if ( ! errors.isEmpty() ) {
    112124                throw errors;
     
    126138        if ( ! visitor.get_visit_children() ) return;
    127139        SemanticErrorException errors;
     140
     141        pass_visitor_stats.depth++;
     142        pass_visitor_stats.max->push(pass_visitor_stats.depth);
     143        pass_visitor_stats.avg->push(pass_visitor_stats.depth);
    128144        for ( typename Container::iterator i = container.begin(); i != container.end(); ++i ) {
    129145                try {
     
    135151                }
    136152        }
     153        pass_visitor_stats.depth--;
    137154        if ( ! errors.isEmpty() ) {
    138155                throw errors;
     
    151168template< typename Container, typename pass_type >
    152169inline void maybeMutate_impl( Container & container, PassVisitor< pass_type > & mutator ) {
     170
    153171        if ( ! mutator.get_visit_children() ) return;
    154172        SemanticErrorException errors;
     173
     174        pass_visitor_stats.depth++;
     175        pass_visitor_stats.max->push(pass_visitor_stats.depth);
     176        pass_visitor_stats.avg->push(pass_visitor_stats.depth);
    155177        for ( typename Container::iterator i = container.begin(); i != container.end(); ++i ) {
    156178                try {
     
    163185                } // try
    164186        } // for
     187        pass_visitor_stats.depth--;
    165188        if ( ! errors.isEmpty() ) {
    166189                throw errors;
     
    185208        DeclList_t* afterDecls  = get_afterDecls();
    186209
     210        pass_visitor_stats.depth++;
     211        pass_visitor_stats.max->push(pass_visitor_stats.depth);
     212        pass_visitor_stats.avg->push(pass_visitor_stats.depth);
    187213        for ( std::list< Statement* >::iterator i = statements.begin(); i != statements.end(); ++i ) {
    188214
     
    192218                try {
    193219                        func( *i );
     220                        assert( *i );
    194221                        assert(( empty( beforeStmts ) && empty( afterStmts ))
    195222                            || ( empty( beforeDecls ) && empty( afterDecls )) );
     
    202229                if ( !empty( beforeStmts ) ) { statements.splice( i, *beforeStmts ); }
    203230        }
     231        pass_visitor_stats.depth--;
    204232
    205233        if ( !empty( afterDecls ) ) { splice( std::back_inserter( statements ), afterDecls); }
     
    229257
    230258        // don't want statements from outer CompoundStmts to be added to this CompoundStmt
    231         ValueGuardPtr< TypeSubstitution * >  oldEnv        ( get_env_ptr    () );
     259        ValueGuardPtr< typename std::remove_pointer<decltype(get_env_ptr())>::type >  oldEnv( get_env_ptr() );
    232260        ValueGuardPtr< DeclList_t >          oldBeforeDecls( get_beforeDecls() );
    233261        ValueGuardPtr< DeclList_t >          oldAfterDecls ( get_afterDecls () );
     
    19651993
    19661994        // don't want statements from outer CompoundStmts to be added to this StmtExpr
    1967         ValueGuardPtr< TypeSubstitution * >      oldEnv        ( get_env_ptr() );
     1995        ValueGuardPtr< typename std::remove_pointer<decltype(get_env_ptr())>::type >  oldEnv( get_env_ptr() );
    19681996        ValueGuardPtr< std::list< Statement* > > oldBeforeStmts( get_beforeStmts() );
    19691997        ValueGuardPtr< std::list< Statement* > > oldAfterStmts ( get_afterStmts () );
     
    19822010
    19832011        // don't want statements from outer CompoundStmts to be added to this StmtExpr
    1984         ValueGuardPtr< TypeSubstitution * >      oldEnv        ( get_env_ptr() );
     2012        ValueGuardPtr< typename std::remove_pointer<decltype(get_env_ptr())>::type >  oldEnv( get_env_ptr() );
    19852013        ValueGuardPtr< std::list< Statement* > > oldBeforeStmts( get_beforeStmts() );
    19862014        ValueGuardPtr< std::list< Statement* > > oldAfterStmts ( get_afterStmts () );
     
    26782706
    26792707//--------------------------------------------------------------------------
    2680 // Subrange
    2681 template< typename pass_type >
    2682 void PassVisitor< pass_type >::visit( Subrange * node ) {
    2683         VISIT_START( node );
    2684 
    2685         VISIT_END( node );
    2686 }
    2687 
    2688 template< typename pass_type >
    2689 Subrange * PassVisitor< pass_type >::mutate( Subrange * node  )  {
    2690         MUTATE_START( node );
    2691 
    2692         MUTATE_END( Subrange, node );
    2693 }
    2694 
    2695 //--------------------------------------------------------------------------
    26962708// Attribute
    26972709template< typename pass_type >
  • src/Common/PassVisitor.proto.h

    r6a9d4b4 r933f32f  
    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
     
    220222INDEXER_FUNC2( addWith   , std::list< Expression * > &, BaseSyntaxNode * );
    221223
     224#undef INDEXER_FUNC1
     225#undef INDEXER_FUNC2
    222226
    223227template<typename pass_type>
  • src/Common/SemanticError.h

    r6a9d4b4 r933f32f  
    1717
    1818#include "ErrorObjects.h"
     19#include "AST/Node.hpp"
    1920#include <cstring>
    2021
  • src/Common/Stats/Heap.h

    r6a9d4b4 r933f32f  
    1616#pragma once
    1717
    18 namespace HeapStats {
    19         void newPass( const char * const name );
    20         void printStats();
     18namespace Stats {
     19        namespace Heap {
     20                void newPass( const char * const name );
     21                void print();
     22        }
    2123}
  • src/Common/module.mk

    r6a9d4b4 r933f32f  
    1515###############################################################################
    1616
    17 SRC += Common/SemanticError.cc \
    18        Common/UniqueName.cc \
    19        Common/DebugMalloc.cc \
    20        Common/Assert.cc \
    21        Common/Heap.cc \
    22        Common/Eval.cc
     17SRC_COMMON = \
     18      Common/Assert.cc \
     19      Common/Eval.cc \
     20      Common/PassVisitor.cc \
     21      Common/SemanticError.cc \
     22      Common/Stats/Counter.cc \
     23      Common/Stats/Heap.cc \
     24      Common/Stats/Stats.cc \
     25      Common/Stats/Time.cc \
     26      Common/UniqueName.cc
     27
     28SRC += $(SRC_COMMON) Common/DebugMalloc.cc
     29SRCDEMANGLE += $(SRC_COMMON)
  • src/Common/utility.h

    r6a9d4b4 r933f32f  
    463463std::pair<long long int, bool> eval(Expression * expr);
    464464
    465 // -----------------------------------------------------------------------------
    466 /// Reorders the input range in-place so that the minimal-value elements according to the
    467 /// comparator are in front;
     465namespace ast {
     466        class Expr;
     467}
     468
     469std::pair<long long int, bool> eval(const ast::Expr * expr);
     470
     471// -----------------------------------------------------------------------------
     472/// Reorders the input range in-place so that the minimal-value elements according to the
     473/// comparator are in front;
    468474/// returns the iterator after the last minimal-value element.
    469475template<typename Iter, typename Compare>
    470476Iter sort_mins( Iter begin, Iter end, Compare& lt ) {
    471477        if ( begin == end ) return end;
    472        
     478
    473479        Iter min_pos = begin;
    474480        for ( Iter i = begin + 1; i != end; ++i ) {
  • src/CompilationState.cc

    r6a9d4b4 r933f32f  
    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

    r6a9d4b4 r933f32f  
    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/Concurrency/Waitfor.cc

    r6a9d4b4 r933f32f  
    1111// Last Modified By :
    1212// Last Modified On :
    13 // Update Count     : 5
     13// Update Count     : 7
    1414//
    1515
  • src/Concurrency/module.mk

    r6a9d4b4 r933f32f  
    1515###############################################################################
    1616
    17 SRC += Concurrency/Keywords.cc \
    18        Concurrency/Waitfor.cc
     17SRC += Concurrency/Keywords.cc Concurrency/Waitfor.cc
     18SRCDEMANGLE += Concurrency/Keywords.cc
    1919
  • src/ControlStruct/ExceptTranslate.cc

    r6a9d4b4 r933f32f  
    99// Author           : Andrew Beach
    1010// Created On       : Wed Jun 14 16:49:00 2017
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Thr Aug 17 17:19:00 2017
    13 // Update Count     : 9
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Wed Feb 13 18:15:29 2019
     13// Update Count     : 11
    1414//
    1515
     
    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/ControlStruct/ForExprMutator.cc

    r6a9d4b4 r933f32f  
    99// Author           : Rodolfo G. Esteves
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Fri Aug 18 10:22:00 2017
    13 // Update Count     : 12
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Mon Mar 11 22:26:52 2019
     13// Update Count     : 14
    1414//
    1515
     
    2121
    2222namespace ControlStruct {
    23         Statement *hoist( Statement *originalStmt, std::list<Statement *> &init ) {
     23        Statement * hoist( Statement * originalStmt, std::list<Statement *> & init ) {
    2424                // If no hoisting is needed, skip:
    2525                if ( 0 == init.size() ) {
     
    2929                // Create compound statement, move initializers outside,
    3030                // the resut of the original stays as is.
    31                 CompoundStmt *block = new CompoundStmt();
    32                 std::list<Statement *> &stmts = block->get_kids();
     31                CompoundStmt * block = new CompoundStmt();
     32                std::list<Statement *> & stmts = block->get_kids();
    3333                stmts.splice( stmts.end(), init );
    3434
     
    3838        }
    3939
    40         Statement *ForExprMutator::postmutate( IfStmt *ifStmt ) {
     40        Statement * ForExprMutator::postmutate( IfStmt * ifStmt ) {
    4141                return hoist( ifStmt, ifStmt->initialization );
    4242        }
    43         Statement *ForExprMutator::postmutate( ForStmt *forStmt ) {
     43        Statement * ForExprMutator::postmutate( ForStmt * forStmt ) {
    4444                // hoist any initializer declarations to make them C89 (rather than C99)
    4545                return hoist( forStmt, forStmt->initialization );
    4646        }
    47         Statement *ForExprMutator::postmutate( WhileStmt *whileStmt ) {
     47        Statement * ForExprMutator::postmutate( WhileStmt * whileStmt ) {
    4848                return hoist( whileStmt, whileStmt->initialization );
    4949        }
  • src/ControlStruct/LabelFixer.cc

    r6a9d4b4 r933f32f  
    99// Author           : Rodolfo G. Esteves
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Rob Schluntz
    12 // Last Modified On : Tue Jul 28 13:32:43 2015
    13 // Update Count     : 156
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Mon Mar 11 22:26:02 2019
     13// Update Count     : 159
    1414//
    1515
     
    3232        }
    3333
    34         LabelFixer::LabelFixer( LabelGenerator *gen ) : generator ( gen ) {
     34        LabelFixer::LabelFixer( LabelGenerator * gen ) : generator ( gen ) {
    3535                if ( generator == 0 )
    3636                        generator = LabelGenerator::getGenerator();
     
    4949
    5050        // prune to at most one label definition for each statement
    51         void LabelFixer::previsit( Statement *stmt ) {
     51        void LabelFixer::previsit( Statement * stmt ) {
    5252                std::list< Label > &labels = stmt->get_labels();
    5353
     
    5858        }
    5959
    60         void LabelFixer::previsit( BranchStmt *branchStmt ) {
     60        void LabelFixer::previsit( BranchStmt * branchStmt ) {
    6161                previsit( ( Statement *)branchStmt );
    6262
     
    7575
    7676
    77         // sets the definition of the labelTable entry to be the provided
    78         // statement for every label in the list parameter. Happens for every kind of statement
    79         Label LabelFixer::setLabelsDef( std::list< Label > &llabel, Statement *definition ) {
     77        // sets the definition of the labelTable entry to be the provided statement for every label in the list
     78        // parameter. Happens for every kind of statement
     79        Label LabelFixer::setLabelsDef( std::list< Label > & llabel, Statement * definition ) {
    8080                assert( definition != 0 );
    8181                assert( llabel.size() > 0 );
     
    100100                } // for
    101101
    102                 // produce one of the labels attached to this statement to be
    103                 // temporarily used as the canonical label
     102                // produce one of the labels attached to this statement to be temporarily used as the canonical label
    104103                return labelTable[ llabel.front() ]->get_label();
    105104        }
     
    117116
    118117        // Builds a table that maps a label to its defining statement.
    119         std::map<Label, Statement * > *LabelFixer::resolveJumps() throw ( SemanticErrorException ) {
     118        std::map<Label, Statement * > * LabelFixer::resolveJumps() throw ( SemanticErrorException ) {
    120119                std::map< Label, Statement * > *ret = new std::map< Label, Statement * >();
    121120                for ( std::map< Label, Entry * >::iterator i = labelTable.begin(); i != labelTable.end(); ++i ) {
  • src/ControlStruct/LabelGenerator.cc

    r6a9d4b4 r933f32f  
    99// Author           : Rodolfo G. Esteves
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Thr Aug 14 14:14:00 2015
    13 // Update Count     : 14
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Mon Mar 11 22:23:20 2019
     13// Update Count     : 15
    1414//
    1515
     
    2424
    2525namespace ControlStruct {
    26         LabelGenerator *LabelGenerator::labelGenerator = 0;
     26        LabelGenerator * LabelGenerator::labelGenerator = 0;
    2727
    28         LabelGenerator *LabelGenerator::getGenerator() {
     28        LabelGenerator * LabelGenerator::getGenerator() {
    2929                if ( LabelGenerator::labelGenerator == 0 )
    3030                        LabelGenerator::labelGenerator = new LabelGenerator();
    31 
    3231                return labelGenerator;
    3332        }
     
    3837                if ( stmt && ! stmt->get_labels().empty() ) {
    3938                        os << "_" << stmt->get_labels().front() << "__";
    40                 }
     39                } // if
    4140                std::string ret = os.str();
    4241                Label l( ret );
  • src/ControlStruct/module.mk

    r6a9d4b4 r933f32f  
    1515###############################################################################
    1616
    17 SRC +=  ControlStruct/LabelGenerator.cc \
     17SRC_CONTROLSTRUCT = \
     18        ControlStruct/ForExprMutator.cc \
    1819        ControlStruct/LabelFixer.cc \
     20        ControlStruct/LabelGenerator.cc \
    1921        ControlStruct/MLEMutator.cc \
    20         ControlStruct/Mutate.cc \
    21         ControlStruct/ForExprMutator.cc \
    22         ControlStruct/ExceptTranslate.cc
     22        ControlStruct/Mutate.cc
     23
     24SRC += $(SRC_CONTROLSTRUCT) ControlStruct/ExceptTranslate.cc
     25SRCDEMANGLE += $(SRC_CONTROLSTRUCT)
     26
  • src/GenPoly/Box.cc

    r6a9d4b4 r933f32f  
    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();
  • src/GenPoly/GenPoly.cc

    r6a9d4b4 r933f32f  
    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

    r6a9d4b4 r933f32f  
    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

    r6a9d4b4 r933f32f  
    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

    r6a9d4b4 r933f32f  
    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/GenPoly/module.mk

    r6a9d4b4 r933f32f  
    2222       GenPoly/FindFunction.cc \
    2323       GenPoly/InstantiateGeneric.cc
     24
     25SRCDEMANGLE += GenPoly/GenPoly.cc GenPoly/Lvalue.cc
     26
  • src/InitTweak/FixInit.cc

    r6a9d4b4 r933f32f  
    1010// Created On       : Wed Jan 13 16:29:30 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Jun 21 17:35:05 2017
    13 // Update Count     : 74
     12// Last Modified On : Wed Feb 13 18:15:56 2019
     13// Update Count     : 76
    1414//
    1515#include "FixInit.h"
     
    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
  • src/InitTweak/InitTweak.cc

    r6a9d4b4 r933f32f  
    55#include <memory>                  // for __shared_ptr
    66
     7#include "AST/Expr.hpp"
     8#include "AST/Stmt.hpp"
     9#include "AST/Type.hpp"
    710#include "Common/PassVisitor.h"
    811#include "Common/SemanticError.h"  // for SemanticError
     
    2629#include "Tuples/Tuples.h"         // for Tuples::isTtype
    2730
    28 class UntypedValofExpr;
    29 
    3031namespace InitTweak {
    3132        namespace {
     
    432433                        assert( false );
    433434                }
     435
     436                // template<typename CallExpr>
     437                // const ast::Expr * callArg( const CallExpr * call, unsigned int pos ) {
     438                //      if( pos >= call->args.size() ) {
     439                //              assertf( false, "getCallArg for argument that doesn't exist: (%u); %s.",
     440                //                      pos, toString( call ).c_str() );
     441                //      }
     442                //      for ( const ast::Expr * arg : call->args ) {
     443                //              if ( pos == 0 ) return arg;
     444                //              --pos;
     445                //      }
     446                //      assert( false );
     447                // }
    434448        }
    435449
     
    451465                        assertf( false, "Unexpected expression type passed to getCallArg: %s", toString( callExpr ).c_str() );
    452466                }
     467        }
     468        const ast::Expr * getCallArg( const ast::Expr * call, unsigned pos ) {
     469                (void)call;
     470                (void)pos;
     471                #warning unimplemented; needs to build AST/Expr.cpp
     472                assertf(false, "unimplemented; needs to build AST/Expr.cpp");
     473                // if ( auto app = dynamic_cast< const ast::ApplicationExpr * >( call ) ) {
     474                //      return callArg( app, pos );
     475                // } else if ( auto untyped = dynamic_cast< const ast::UntypedExpr * >( call ) ) {
     476                //      return callArg( untyped, pos );
     477                // } else if ( auto tupleAssn = dynamic_cast< const ast::TupleAssignExpr * >( call ) ) {
     478                //      const std::list<ast::ptr<ast::Stmt>>& stmts = tupleAssn->stmtExpr->stmts->kids;
     479                //      assertf( ! stmts.empty(), "TupleAssignExpr missing statements." );
     480                //      const ExprStmt * stmt = strict_dynamic_cast< const ast::ExprStmt * >( stmts.back() );
     481                //      const TupleExpr * tuple = strict_dynamic_cast< const ast::TupleExpr * >( stmt->expr );
     482                //      assertf( ! tuple->exprs.empty(), "TupleAssignExpr has empty tuple expr.");
     483                //      return getCallArg( tuple->exprs.front(), pos );
     484                // } else if ( auto ctor = dynamic_cast< const ast::ImplicitCopyCtorExpr * >( call ) ) {
     485                //      return getCallArg( ctor->callExpr, pos );
     486                // } else {
     487                //      assertf( false, "Unexpected expression type passed to getCallArg: %s",
     488                //              toString( call ).c_str() );
     489                // }
    453490        }
    454491
     
    513550                }
    514551        }
     552        const ast::Type* getPointerBase( const ast::Type* t ) {
     553                (void)t;
     554                #warning needs to build Type.cpp before inclusion
     555                assertf(false, "needs to build Type.cpp before inclusion");
     556                // if ( const auto * p = dynamic_cast< const ast::PointerType * >( t ) ) {
     557                //      return p->base;
     558                // } else if ( const auto * a = dynamic_cast< const ast::ArrayType * >( t ) ) {
     559                //      return a->base;
     560                // } else if ( const auto * r = dynamic_cast< const ast::ReferenceType * >( t ) ) {
     561                //      return r->base;
     562                // } else return nullptr;
     563        }
    515564
    516565        Type * isPointerType( Type * type ) {
  • src/InitTweak/InitTweak.h

    r6a9d4b4 r933f32f  
    2020#include <string>             // for string, allocator
    2121
     22#include "AST/Fwd.hpp"        // for AST nodes
    2223#include "SynTree/SynTree.h"  // for Visitor Nodes
    2324
     
    8081        /// returns the argument to a call expression in position N indexed from 0
    8182        Expression *& getCallArg( Expression * callExpr, unsigned int pos );
     83        const ast::Expr * getCallArg( const ast::Expr * call, unsigned pos );
    8284
    8385        /// returns the base type of a PointerType or ArrayType, else returns NULL
    8486        Type * getPointerBase( Type * );
     87        const ast::Type* getPointerBase( const ast::Type* );
    8588
    8689        /// returns the argument if it is a PointerType or ArrayType, else returns NULL
  • src/InitTweak/module.mk

    r6a9d4b4 r933f32f  
    2020        InitTweak/InitTweak.cc
    2121
     22SRCDEMANGLE += InitTweak/GenInit.cc \
     23        InitTweak/InitTweak.cc
     24
  • src/MakeLibCfa.cc

    r6a9d4b4 r933f32f  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sat May 16 10:33:33 2015
    11 // Last Modified By : Rob Schluntz
    12 // Last Modified On : Fri Apr 22 13:54:15 2016
    13 // Update Count     : 40
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Sun Feb 17 21:08:09 2019
     13// Update Count     : 41
    1414//
    1515
     
    146146        } // namespace
    147147} // namespace LibCfa
     148
     149// Local Variables: //
     150// tab-width: 4 //
     151// End: //
  • src/Makefile.am

    r6a9d4b4 r933f32f  
    1010## Author           : Peter A. Buhr
    1111## Created On       : Sun May 31 08:51:46 2015
    12 ## Last Modified By : Andrew Beach
    13 ## Last Modified On : Tus Jul 25 10:34:00 2017
    14 ## Update Count     : 76
     12## Last Modified By : Peter A. Buhr
     13## Last Modified On : Fri Feb 15 09:44:09 2019
     14## Update Count     : 97
    1515###############################################################################
    1616
     
    2020
    2121SRC = main.cc \
    22                         MakeLibCfa.cc \
    23                         CompilationState.cc
     22      MakeLibCfa.cc \
     23      CompilationState.cc
     24
     25SRCDEMANGLE = CompilationState.cc
    2426
    2527MAINTAINERCLEANFILES =
    26 MOSTLYCLEANFILES = Parser/gcc-flags.h
     28MOSTLYCLEANFILES =
    2729
    28 Parser/gcc-flags.h :
    29         ${AM_V_GEN}$(CC) -dM -E - < /dev/null | sed 's/define /define __GCC__/' > $(@)
     30if WITH_LIBPROFILER
     31LIBPROFILER = -lprofiler
     32endif
    3033
    31 Parser/lex.ll : Parser/gcc-flags.h
     34if WITH_LIBTCMALLOC
     35LIBTCMALLOC = -ltcmalloc
     36TCMALLOCFLAG = -DTCMALLOC
     37endif
    3238
    3339include CodeGen/module.mk
     
    4652include Virtual/module.mk
    4753
     54$(addprefix $(srcdir)/, ResolvExpr/ConversionCost.cc ResolvExpr/CommonType.cc SymTab/ManglerCommon.cc) : $(srcdir)/SynTree/Type.h
     55
     56$(srcdir)/SynTree/Type.h : BasicTypes-gen.cc
     57        ${AM_V_GEN}${CXXCOMPILE} $< -o BasicTypes-gen -Wall -Wextra
     58        @./BasicTypes-gen
     59        @rm BasicTypes-gen
     60
    4861# put into lib for now
    4962cfa_cpplibdir = $(CFA_LIBDIR)
    5063cfa_cpplib_PROGRAMS = ../driver/cfa-cpp demangler
    5164___driver_cfa_cpp_SOURCES = $(SRC)
    52 ___driver_cfa_cpp_LDADD = -ldl                  # yywrap
     65___driver_cfa_cpp_LDADD = -ldl $(LIBPROFILER) $(LIBTCMALLOC)
    5366
    54 AM_CXXFLAGS = @HOST_FLAGS@ -Wno-deprecated -Wall -Wextra -DDEBUG_ALL -I./Parser -I$(srcdir)/Parser -I$(srcdir)/include -DYY_NO_INPUT -O2 -g -std=c++14
     67AM_CXXFLAGS = @HOST_FLAGS@ -Wno-deprecated -Wall -Wextra -DDEBUG_ALL -I./Parser -I$(srcdir)/Parser -I$(srcdir)/include -DYY_NO_INPUT -O3 -g -std=c++14 $(TCMALLOCFLAG)
    5568AM_LDFLAGS  = @HOST_FLAGS@ -Xlinker -export-dynamic
    5669ARFLAGS     = cr
     
    5871demangler_SOURCES = SymTab/demangler.cc # test driver for the demangler, also useful as a sanity check that libdemangle.a is complete
    5972
    60 demangler_LDADD = libdemangle.a     # yywrap
     73demangler_LDADD = libdemangle.a -ldl                    # yywrap
    6174
    6275noinst_LIBRARIES = libdemangle.a
    63 libdemangle_a_SOURCES = \
    64         SymTab/Demangle.cc \
    65         SymTab/ManglerCommon.cc \
    66         SynTree/Type.cc \
    67         SynTree/VoidType.cc \
    68         SynTree/BasicType.cc \
    69         SynTree/PointerType.cc \
    70         SynTree/ArrayType.cc \
    71         SynTree/ReferenceType.cc \
    72         SynTree/FunctionType.cc \
    73         SynTree/ReferenceToType.cc \
    74         SynTree/TupleType.cc \
    75         SynTree/TypeofType.cc \
    76         SynTree/AttrType.cc \
    77         SynTree/VarArgsType.cc \
    78         SynTree/ZeroOneType.cc \
    79         SynTree/Constant.cc \
    80         SynTree/Expression.cc \
    81         SynTree/TupleExpr.cc \
    82         SynTree/CommaExpr.cc \
    83         SynTree/TypeExpr.cc \
    84         SynTree/ApplicationExpr.cc \
    85         SynTree/AddressExpr.cc \
    86         SynTree/Statement.cc \
    87         SynTree/CompoundStmt.cc \
    88         SynTree/DeclStmt.cc \
    89         SynTree/Declaration.cc \
    90         SynTree/DeclarationWithType.cc \
    91         SynTree/ObjectDecl.cc \
    92         SynTree/FunctionDecl.cc \
    93         SynTree/AggregateDecl.cc \
    94         SynTree/NamedTypeDecl.cc \
    95         SynTree/TypeDecl.cc \
    96         SynTree/Initializer.cc \
    97         SynTree/TypeSubstitution.cc \
    98         SynTree/Attribute.cc \
    99         SynTree/DeclReplacer.cc \
    100         CompilationState.cc \
    101         CodeGen/CodeGenerator.cc \
    102         CodeGen/FixMain.cc \
    103         CodeGen/Generate.cc \
    104         CodeGen/GenType.cc \
    105         CodeGen/OperatorTable.cc \
    106         Common/Assert.cc \
    107         Common/Eval.cc \
    108         Common/SemanticError.cc \
    109         Common/UniqueName.cc \
    110         Concurrency/Keywords.cc \
    111         ControlStruct/ForExprMutator.cc \
    112         ControlStruct/LabelFixer.cc \
    113         ControlStruct/LabelGenerator.cc \
    114         ControlStruct/MLEMutator.cc \
    115         ControlStruct/Mutate.cc \
    116         GenPoly/GenPoly.cc \
    117         GenPoly/Lvalue.cc \
    118         InitTweak/GenInit.cc \
    119         InitTweak/InitTweak.cc \
    120         Parser/LinkageSpec.cc \
    121         ResolvExpr/AdjustExprType.cc \
    122         ResolvExpr/Alternative.cc \
    123         ResolvExpr/AlternativeFinder.cc \
    124         ResolvExpr/ExplodedActual.cc \
    125         ResolvExpr/CastCost.cc \
    126         ResolvExpr/CommonType.cc \
    127         ResolvExpr/ConversionCost.cc \
    128         ResolvExpr/CurrentObject.cc \
    129         ResolvExpr/FindOpenVars.cc \
    130         ResolvExpr/Occurs.cc \
    131         ResolvExpr/PolyCost.cc \
    132         ResolvExpr/PtrsAssignable.cc \
    133         ResolvExpr/PtrsCastable.cc \
    134         ResolvExpr/RenameVars.cc \
    135         ResolvExpr/ResolveAssertions.cc \
    136         ResolvExpr/Resolver.cc \
    137         ResolvExpr/ResolveTypeof.cc \
    138         ResolvExpr/SpecCost.cc \
    139         ResolvExpr/TypeEnvironment.cc \
    140         ResolvExpr/Unify.cc \
    141         SymTab/Autogen.cc \
    142         SymTab/FixFunction.cc \
    143         SymTab/Indexer.cc \
    144         SymTab/Mangler.cc \
    145         SymTab/Validate.cc \
    146         Tuples/Explode.cc \
    147         Tuples/TupleAssignment.cc \
    148         Tuples/TupleExpansion.cc \
    149         Validate/HandleAttributes.cc \
    150         Validate/FindSpecialDecls.cc
    151 
     76libdemangle_a_SOURCES = $(SRCDEMANGLE)
    15277
    15378MAINTAINERCLEANFILES += ${libdir}/${notdir ${cfa_cpplib_PROGRAMS}}
  • src/Makefile.in

    r6a9d4b4 r933f32f  
    162162libdemangle_a_LIBADD =
    163163am__dirstamp = $(am__leading_dot)dirstamp
    164 am_libdemangle_a_OBJECTS = SymTab/Demangle.$(OBJEXT) \
    165         SymTab/ManglerCommon.$(OBJEXT) SynTree/Type.$(OBJEXT) \
    166         SynTree/VoidType.$(OBJEXT) SynTree/BasicType.$(OBJEXT) \
    167         SynTree/PointerType.$(OBJEXT) SynTree/ArrayType.$(OBJEXT) \
    168         SynTree/ReferenceType.$(OBJEXT) SynTree/FunctionType.$(OBJEXT) \
    169         SynTree/ReferenceToType.$(OBJEXT) SynTree/TupleType.$(OBJEXT) \
    170         SynTree/TypeofType.$(OBJEXT) SynTree/AttrType.$(OBJEXT) \
    171         SynTree/VarArgsType.$(OBJEXT) SynTree/ZeroOneType.$(OBJEXT) \
    172         SynTree/Constant.$(OBJEXT) SynTree/Expression.$(OBJEXT) \
    173         SynTree/TupleExpr.$(OBJEXT) SynTree/CommaExpr.$(OBJEXT) \
    174         SynTree/TypeExpr.$(OBJEXT) SynTree/ApplicationExpr.$(OBJEXT) \
    175         SynTree/AddressExpr.$(OBJEXT) SynTree/Statement.$(OBJEXT) \
    176         SynTree/CompoundStmt.$(OBJEXT) SynTree/DeclStmt.$(OBJEXT) \
    177         SynTree/Declaration.$(OBJEXT) \
    178         SynTree/DeclarationWithType.$(OBJEXT) \
    179         SynTree/ObjectDecl.$(OBJEXT) SynTree/FunctionDecl.$(OBJEXT) \
    180         SynTree/AggregateDecl.$(OBJEXT) \
    181         SynTree/NamedTypeDecl.$(OBJEXT) SynTree/TypeDecl.$(OBJEXT) \
    182         SynTree/Initializer.$(OBJEXT) \
    183         SynTree/TypeSubstitution.$(OBJEXT) SynTree/Attribute.$(OBJEXT) \
    184         SynTree/DeclReplacer.$(OBJEXT) CompilationState.$(OBJEXT) \
    185         CodeGen/CodeGenerator.$(OBJEXT) CodeGen/FixMain.$(OBJEXT) \
    186         CodeGen/Generate.$(OBJEXT) CodeGen/GenType.$(OBJEXT) \
    187         CodeGen/OperatorTable.$(OBJEXT) Common/Assert.$(OBJEXT) \
    188         Common/Eval.$(OBJEXT) Common/SemanticError.$(OBJEXT) \
    189         Common/UniqueName.$(OBJEXT) Concurrency/Keywords.$(OBJEXT) \
    190         ControlStruct/ForExprMutator.$(OBJEXT) \
     164am__objects_1 = CodeGen/CodeGenerator.$(OBJEXT) \
     165        CodeGen/FixMain.$(OBJEXT) CodeGen/GenType.$(OBJEXT) \
     166        CodeGen/OperatorTable.$(OBJEXT)
     167am__objects_2 = Common/Assert.$(OBJEXT) Common/Eval.$(OBJEXT) \
     168        Common/PassVisitor.$(OBJEXT) Common/SemanticError.$(OBJEXT) \
     169        Common/Stats/Counter.$(OBJEXT) Common/Stats/Heap.$(OBJEXT) \
     170        Common/Stats/Stats.$(OBJEXT) Common/Stats/Time.$(OBJEXT) \
     171        Common/UniqueName.$(OBJEXT)
     172am__objects_3 = ControlStruct/ForExprMutator.$(OBJEXT) \
    191173        ControlStruct/LabelFixer.$(OBJEXT) \
    192174        ControlStruct/LabelGenerator.$(OBJEXT) \
    193175        ControlStruct/MLEMutator.$(OBJEXT) \
    194         ControlStruct/Mutate.$(OBJEXT) GenPoly/GenPoly.$(OBJEXT) \
    195         GenPoly/Lvalue.$(OBJEXT) InitTweak/GenInit.$(OBJEXT) \
    196         InitTweak/InitTweak.$(OBJEXT) Parser/LinkageSpec.$(OBJEXT) \
    197         ResolvExpr/AdjustExprType.$(OBJEXT) \
     176        ControlStruct/Mutate.$(OBJEXT)
     177am__objects_4 = ResolvExpr/AdjustExprType.$(OBJEXT) \
    198178        ResolvExpr/Alternative.$(OBJEXT) \
    199179        ResolvExpr/AlternativeFinder.$(OBJEXT) \
    200         ResolvExpr/ExplodedActual.$(OBJEXT) \
    201180        ResolvExpr/CastCost.$(OBJEXT) ResolvExpr/CommonType.$(OBJEXT) \
    202181        ResolvExpr/ConversionCost.$(OBJEXT) \
    203182        ResolvExpr/CurrentObject.$(OBJEXT) \
     183        ResolvExpr/ExplodedActual.$(OBJEXT) \
    204184        ResolvExpr/FindOpenVars.$(OBJEXT) ResolvExpr/Occurs.$(OBJEXT) \
    205185        ResolvExpr/PolyCost.$(OBJEXT) \
     
    212192        ResolvExpr/SpecCost.$(OBJEXT) \
    213193        ResolvExpr/TypeEnvironment.$(OBJEXT) \
    214         ResolvExpr/Unify.$(OBJEXT) SymTab/Autogen.$(OBJEXT) \
    215         SymTab/FixFunction.$(OBJEXT) SymTab/Indexer.$(OBJEXT) \
    216         SymTab/Mangler.$(OBJEXT) SymTab/Validate.$(OBJEXT) \
    217         Tuples/Explode.$(OBJEXT) Tuples/TupleAssignment.$(OBJEXT) \
    218         Tuples/TupleExpansion.$(OBJEXT) \
    219         Validate/HandleAttributes.$(OBJEXT) \
    220         Validate/FindSpecialDecls.$(OBJEXT)
    221 libdemangle_a_OBJECTS = $(am_libdemangle_a_OBJECTS)
    222 am__installdirs = "$(DESTDIR)$(cfa_cpplibdir)"
    223 PROGRAMS = $(cfa_cpplib_PROGRAMS)
    224 am__objects_1 = main.$(OBJEXT) MakeLibCfa.$(OBJEXT) \
    225         CompilationState.$(OBJEXT) CodeGen/Generate.$(OBJEXT) \
    226         CodeGen/CodeGenerator.$(OBJEXT) CodeGen/GenType.$(OBJEXT) \
    227         CodeGen/FixNames.$(OBJEXT) CodeGen/FixMain.$(OBJEXT) \
    228         CodeGen/OperatorTable.$(OBJEXT) CodeTools/DeclStats.$(OBJEXT) \
    229         CodeTools/ResolvProtoDump.$(OBJEXT) \
    230         CodeTools/TrackLoc.$(OBJEXT) Concurrency/Keywords.$(OBJEXT) \
    231         Concurrency/Waitfor.$(OBJEXT) Common/SemanticError.$(OBJEXT) \
    232         Common/UniqueName.$(OBJEXT) Common/DebugMalloc.$(OBJEXT) \
    233         Common/Assert.$(OBJEXT) Common/Heap.$(OBJEXT) \
    234         Common/Eval.$(OBJEXT) ControlStruct/LabelGenerator.$(OBJEXT) \
    235         ControlStruct/LabelFixer.$(OBJEXT) \
    236         ControlStruct/MLEMutator.$(OBJEXT) \
    237         ControlStruct/Mutate.$(OBJEXT) \
    238         ControlStruct/ForExprMutator.$(OBJEXT) \
    239         ControlStruct/ExceptTranslate.$(OBJEXT) GenPoly/Box.$(OBJEXT) \
    240         GenPoly/GenPoly.$(OBJEXT) GenPoly/ScrubTyVars.$(OBJEXT) \
    241         GenPoly/Lvalue.$(OBJEXT) GenPoly/Specialize.$(OBJEXT) \
    242         GenPoly/FindFunction.$(OBJEXT) \
    243         GenPoly/InstantiateGeneric.$(OBJEXT) \
    244         InitTweak/GenInit.$(OBJEXT) InitTweak/FixInit.$(OBJEXT) \
    245         InitTweak/FixGlobalInit.$(OBJEXT) \
    246         InitTweak/InitTweak.$(OBJEXT) Parser/parser.$(OBJEXT) \
    247         Parser/lex.$(OBJEXT) Parser/TypedefTable.$(OBJEXT) \
    248         Parser/ParseNode.$(OBJEXT) Parser/DeclarationNode.$(OBJEXT) \
    249         Parser/ExpressionNode.$(OBJEXT) Parser/StatementNode.$(OBJEXT) \
    250         Parser/InitializerNode.$(OBJEXT) Parser/TypeData.$(OBJEXT) \
    251         Parser/LinkageSpec.$(OBJEXT) Parser/parserutility.$(OBJEXT) \
    252         ResolvExpr/AlternativeFinder.$(OBJEXT) \
    253         ResolvExpr/Alternative.$(OBJEXT) ResolvExpr/Unify.$(OBJEXT) \
    254         ResolvExpr/PtrsAssignable.$(OBJEXT) \
    255         ResolvExpr/CommonType.$(OBJEXT) \
    256         ResolvExpr/ConversionCost.$(OBJEXT) \
    257         ResolvExpr/CastCost.$(OBJEXT) \
    258         ResolvExpr/PtrsCastable.$(OBJEXT) \
    259         ResolvExpr/AdjustExprType.$(OBJEXT) \
    260         ResolvExpr/AlternativePrinter.$(OBJEXT) \
    261         ResolvExpr/Resolver.$(OBJEXT) \
    262         ResolvExpr/ResolveTypeof.$(OBJEXT) \
    263         ResolvExpr/RenameVars.$(OBJEXT) \
    264         ResolvExpr/FindOpenVars.$(OBJEXT) \
    265         ResolvExpr/PolyCost.$(OBJEXT) ResolvExpr/Occurs.$(OBJEXT) \
    266         ResolvExpr/TypeEnvironment.$(OBJEXT) \
    267         ResolvExpr/CurrentObject.$(OBJEXT) \
    268         ResolvExpr/ExplodedActual.$(OBJEXT) \
    269         ResolvExpr/SpecCost.$(OBJEXT) \
    270         ResolvExpr/ResolveAssertions.$(OBJEXT) \
     194        ResolvExpr/Unify.$(OBJEXT)
     195am__objects_5 = SymTab/Autogen.$(OBJEXT) SymTab/FixFunction.$(OBJEXT) \
    271196        SymTab/Indexer.$(OBJEXT) SymTab/Mangler.$(OBJEXT) \
    272         SymTab/ManglerCommon.$(OBJEXT) SymTab/Validate.$(OBJEXT) \
    273         SymTab/FixFunction.$(OBJEXT) SymTab/Autogen.$(OBJEXT) \
    274         SynTree/Type.$(OBJEXT) SynTree/VoidType.$(OBJEXT) \
     197        SymTab/ManglerCommon.$(OBJEXT) SymTab/Validate.$(OBJEXT)
     198am__objects_6 = SynTree/Type.$(OBJEXT) SynTree/VoidType.$(OBJEXT) \
    275199        SynTree/BasicType.$(OBJEXT) SynTree/PointerType.$(OBJEXT) \
    276200        SynTree/ArrayType.$(OBJEXT) SynTree/ReferenceType.$(OBJEXT) \
     
    291215        SynTree/Initializer.$(OBJEXT) \
    292216        SynTree/TypeSubstitution.$(OBJEXT) SynTree/Attribute.$(OBJEXT) \
    293         SynTree/DeclReplacer.$(OBJEXT) \
     217        SynTree/DeclReplacer.$(OBJEXT)
     218am__objects_7 = CompilationState.$(OBJEXT) $(am__objects_1) \
     219        Concurrency/Keywords.$(OBJEXT) $(am__objects_2) \
     220        $(am__objects_3) GenPoly/GenPoly.$(OBJEXT) \
     221        GenPoly/Lvalue.$(OBJEXT) InitTweak/GenInit.$(OBJEXT) \
     222        InitTweak/InitTweak.$(OBJEXT) Parser/LinkageSpec.$(OBJEXT) \
     223        $(am__objects_4) $(am__objects_5) SymTab/Demangle.$(OBJEXT) \
     224        $(am__objects_6) Tuples/TupleAssignment.$(OBJEXT) \
     225        Tuples/TupleExpansion.$(OBJEXT) Tuples/Explode.$(OBJEXT) \
     226        Validate/HandleAttributes.$(OBJEXT) \
     227        Validate/FindSpecialDecls.$(OBJEXT)
     228am_libdemangle_a_OBJECTS = $(am__objects_7)
     229libdemangle_a_OBJECTS = $(am_libdemangle_a_OBJECTS)
     230am__installdirs = "$(DESTDIR)$(cfa_cpplibdir)"
     231PROGRAMS = $(cfa_cpplib_PROGRAMS)
     232am__objects_8 = main.$(OBJEXT) MakeLibCfa.$(OBJEXT) \
     233        CompilationState.$(OBJEXT) $(am__objects_1) \
     234        CodeGen/Generate.$(OBJEXT) CodeGen/FixNames.$(OBJEXT) \
     235        CodeTools/DeclStats.$(OBJEXT) \
     236        CodeTools/ResolvProtoDump.$(OBJEXT) \
     237        CodeTools/TrackLoc.$(OBJEXT) Concurrency/Keywords.$(OBJEXT) \
     238        Concurrency/Waitfor.$(OBJEXT) $(am__objects_2) \
     239        Common/DebugMalloc.$(OBJEXT) $(am__objects_3) \
     240        ControlStruct/ExceptTranslate.$(OBJEXT) GenPoly/Box.$(OBJEXT) \
     241        GenPoly/GenPoly.$(OBJEXT) GenPoly/ScrubTyVars.$(OBJEXT) \
     242        GenPoly/Lvalue.$(OBJEXT) GenPoly/Specialize.$(OBJEXT) \
     243        GenPoly/FindFunction.$(OBJEXT) \
     244        GenPoly/InstantiateGeneric.$(OBJEXT) \
     245        InitTweak/GenInit.$(OBJEXT) InitTweak/FixInit.$(OBJEXT) \
     246        InitTweak/FixGlobalInit.$(OBJEXT) \
     247        InitTweak/InitTweak.$(OBJEXT) Parser/parser.$(OBJEXT) \
     248        Parser/lex.$(OBJEXT) Parser/TypedefTable.$(OBJEXT) \
     249        Parser/ParseNode.$(OBJEXT) Parser/DeclarationNode.$(OBJEXT) \
     250        Parser/ExpressionNode.$(OBJEXT) Parser/StatementNode.$(OBJEXT) \
     251        Parser/InitializerNode.$(OBJEXT) Parser/TypeData.$(OBJEXT) \
     252        Parser/LinkageSpec.$(OBJEXT) Parser/parserutility.$(OBJEXT) \
     253        $(am__objects_4) ResolvExpr/AlternativePrinter.$(OBJEXT) \
     254        $(am__objects_5) $(am__objects_6) \
    294255        Tuples/TupleAssignment.$(OBJEXT) \
    295256        Tuples/TupleExpansion.$(OBJEXT) Tuples/Explode.$(OBJEXT) \
     
    297258        Validate/FindSpecialDecls.$(OBJEXT) \
    298259        Virtual/ExpandCasts.$(OBJEXT)
    299 am____driver_cfa_cpp_OBJECTS = $(am__objects_1)
     260am____driver_cfa_cpp_OBJECTS = $(am__objects_8)
    300261___driver_cfa_cpp_OBJECTS = $(am____driver_cfa_cpp_OBJECTS)
    301 ___driver_cfa_cpp_DEPENDENCIES =
     262am__DEPENDENCIES_1 =
     263___driver_cfa_cpp_DEPENDENCIES = $(am__DEPENDENCIES_1) \
     264        $(am__DEPENDENCIES_1)
    302265AM_V_lt = $(am__v_lt_@AM_V@)
    303266am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
     
    418381DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
    419382ACLOCAL = @ACLOCAL@
    420 ALLOCA = @ALLOCA@
    421383AMTAR = @AMTAR@
    422384AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
     
    566528AUTOMAKE_OPTIONS = foreign subdir-objects
    567529ACLOCAL_AMFLAGS = -I automake
    568 SRC = main.cc MakeLibCfa.cc CompilationState.cc CodeGen/Generate.cc \
    569         CodeGen/CodeGenerator.cc CodeGen/GenType.cc \
    570         CodeGen/FixNames.cc CodeGen/FixMain.cc \
    571         CodeGen/OperatorTable.cc CodeTools/DeclStats.cc \
     530SRC = main.cc MakeLibCfa.cc CompilationState.cc $(SRC_CODEGEN) \
     531        CodeGen/Generate.cc CodeGen/FixNames.cc CodeTools/DeclStats.cc \
    572532        CodeTools/ResolvProtoDump.cc CodeTools/TrackLoc.cc \
    573         Concurrency/Keywords.cc Concurrency/Waitfor.cc \
    574         Common/SemanticError.cc Common/UniqueName.cc \
    575         Common/DebugMalloc.cc Common/Assert.cc Common/Heap.cc \
    576         Common/Eval.cc ControlStruct/LabelGenerator.cc \
    577         ControlStruct/LabelFixer.cc ControlStruct/MLEMutator.cc \
    578         ControlStruct/Mutate.cc ControlStruct/ForExprMutator.cc \
     533        Concurrency/Keywords.cc Concurrency/Waitfor.cc $(SRC_COMMON) \
     534        Common/DebugMalloc.cc $(SRC_CONTROLSTRUCT) \
    579535        ControlStruct/ExceptTranslate.cc GenPoly/Box.cc \
    580536        GenPoly/GenPoly.cc GenPoly/ScrubTyVars.cc GenPoly/Lvalue.cc \
     
    587543        Parser/StatementNode.cc Parser/InitializerNode.cc \
    588544        Parser/TypeData.cc Parser/LinkageSpec.cc \
    589         Parser/parserutility.cc ResolvExpr/AlternativeFinder.cc \
    590         ResolvExpr/Alternative.cc ResolvExpr/Unify.cc \
    591         ResolvExpr/PtrsAssignable.cc ResolvExpr/CommonType.cc \
    592         ResolvExpr/ConversionCost.cc ResolvExpr/CastCost.cc \
    593         ResolvExpr/PtrsCastable.cc ResolvExpr/AdjustExprType.cc \
    594         ResolvExpr/AlternativePrinter.cc ResolvExpr/Resolver.cc \
    595         ResolvExpr/ResolveTypeof.cc ResolvExpr/RenameVars.cc \
    596         ResolvExpr/FindOpenVars.cc ResolvExpr/PolyCost.cc \
    597         ResolvExpr/Occurs.cc ResolvExpr/TypeEnvironment.cc \
    598         ResolvExpr/CurrentObject.cc ResolvExpr/ExplodedActual.cc \
    599         ResolvExpr/SpecCost.cc ResolvExpr/ResolveAssertions.cc \
    600         SymTab/Indexer.cc SymTab/Mangler.cc SymTab/ManglerCommon.cc \
    601         SymTab/Validate.cc SymTab/FixFunction.cc SymTab/Autogen.cc \
    602         SynTree/Type.cc SynTree/VoidType.cc SynTree/BasicType.cc \
    603         SynTree/PointerType.cc SynTree/ArrayType.cc \
    604         SynTree/ReferenceType.cc SynTree/FunctionType.cc \
    605         SynTree/ReferenceToType.cc SynTree/TupleType.cc \
    606         SynTree/TypeofType.cc SynTree/AttrType.cc \
    607         SynTree/VarArgsType.cc SynTree/ZeroOneType.cc \
    608         SynTree/Constant.cc SynTree/Expression.cc SynTree/TupleExpr.cc \
    609         SynTree/CommaExpr.cc SynTree/TypeExpr.cc \
    610         SynTree/ApplicationExpr.cc SynTree/AddressExpr.cc \
    611         SynTree/Statement.cc SynTree/CompoundStmt.cc \
    612         SynTree/DeclStmt.cc SynTree/Declaration.cc \
    613         SynTree/DeclarationWithType.cc SynTree/ObjectDecl.cc \
    614         SynTree/FunctionDecl.cc SynTree/AggregateDecl.cc \
    615         SynTree/NamedTypeDecl.cc SynTree/TypeDecl.cc \
    616         SynTree/Initializer.cc SynTree/TypeSubstitution.cc \
    617         SynTree/Attribute.cc SynTree/DeclReplacer.cc \
     545        Parser/parserutility.cc $(SRC_RESOLVEXPR) \
     546        ResolvExpr/AlternativePrinter.cc $(SRC_SYMTAB) $(SRC_SYNTREE) \
    618547        Tuples/TupleAssignment.cc Tuples/TupleExpansion.cc \
    619548        Tuples/Explode.cc Validate/HandleAttributes.cc \
    620549        Validate/FindSpecialDecls.cc Virtual/ExpandCasts.cc
     550SRCDEMANGLE = CompilationState.cc $(SRC_CODEGEN) \
     551        Concurrency/Keywords.cc $(SRC_COMMON) $(SRC_CONTROLSTRUCT) \
     552        GenPoly/GenPoly.cc GenPoly/Lvalue.cc InitTweak/GenInit.cc \
     553        InitTweak/InitTweak.cc Parser/LinkageSpec.cc $(SRC_RESOLVEXPR) \
     554        $(SRC_SYMTAB) SymTab/Demangle.cc $(SRC_SYNTREE) \
     555        Tuples/TupleAssignment.cc Tuples/TupleExpansion.cc \
     556        Tuples/Explode.cc Validate/HandleAttributes.cc \
     557        Validate/FindSpecialDecls.cc
    621558MAINTAINERCLEANFILES = ${libdir}/${notdir ${cfa_cpplib_PROGRAMS}}
    622 MOSTLYCLEANFILES = Parser/gcc-flags.h Parser/lex.cc Parser/parser.cc \
    623         Parser/parser.hh Parser/parser.output
    624 BUILT_SOURCES = Parser/parser.hh
    625 AM_YFLAGS = -d -t -v
    626 
    627 # put into lib for now
    628 cfa_cpplibdir = $(CFA_LIBDIR)
    629 ___driver_cfa_cpp_SOURCES = $(SRC)
    630 ___driver_cfa_cpp_LDADD = -ldl                  # yywrap
    631 AM_CXXFLAGS = @HOST_FLAGS@ -Wno-deprecated -Wall -Wextra -DDEBUG_ALL -I./Parser -I$(srcdir)/Parser -I$(srcdir)/include -DYY_NO_INPUT -O2 -g -std=c++14
    632 AM_LDFLAGS = @HOST_FLAGS@ -Xlinker -export-dynamic
    633 ARFLAGS = cr
    634 demangler_SOURCES = SymTab/demangler.cc # test driver for the demangler, also useful as a sanity check that libdemangle.a is complete
    635 demangler_LDADD = libdemangle.a     # yywrap
    636 noinst_LIBRARIES = libdemangle.a
    637 libdemangle_a_SOURCES = \
    638         SymTab/Demangle.cc \
    639         SymTab/ManglerCommon.cc \
    640         SynTree/Type.cc \
    641         SynTree/VoidType.cc \
    642         SynTree/BasicType.cc \
    643         SynTree/PointerType.cc \
    644         SynTree/ArrayType.cc \
    645         SynTree/ReferenceType.cc \
    646         SynTree/FunctionType.cc \
    647         SynTree/ReferenceToType.cc \
    648         SynTree/TupleType.cc \
    649         SynTree/TypeofType.cc \
    650         SynTree/AttrType.cc \
    651         SynTree/VarArgsType.cc \
    652         SynTree/ZeroOneType.cc \
    653         SynTree/Constant.cc \
    654         SynTree/Expression.cc \
    655         SynTree/TupleExpr.cc \
    656         SynTree/CommaExpr.cc \
    657         SynTree/TypeExpr.cc \
    658         SynTree/ApplicationExpr.cc \
    659         SynTree/AddressExpr.cc \
    660         SynTree/Statement.cc \
    661         SynTree/CompoundStmt.cc \
    662         SynTree/DeclStmt.cc \
    663         SynTree/Declaration.cc \
    664         SynTree/DeclarationWithType.cc \
    665         SynTree/ObjectDecl.cc \
    666         SynTree/FunctionDecl.cc \
    667         SynTree/AggregateDecl.cc \
    668         SynTree/NamedTypeDecl.cc \
    669         SynTree/TypeDecl.cc \
    670         SynTree/Initializer.cc \
    671         SynTree/TypeSubstitution.cc \
    672         SynTree/Attribute.cc \
    673         SynTree/DeclReplacer.cc \
    674         CompilationState.cc \
     559MOSTLYCLEANFILES = Parser/lex.cc Parser/parser.cc Parser/parser.hh \
     560        Parser/parser.output
     561@WITH_LIBPROFILER_TRUE@LIBPROFILER = -lprofiler
     562@WITH_LIBTCMALLOC_TRUE@LIBTCMALLOC = -ltcmalloc
     563@WITH_LIBTCMALLOC_TRUE@TCMALLOCFLAG = -DTCMALLOC
     564SRC_CODEGEN = \
    675565        CodeGen/CodeGenerator.cc \
    676566        CodeGen/FixMain.cc \
    677         CodeGen/Generate.cc \
    678567        CodeGen/GenType.cc \
    679         CodeGen/OperatorTable.cc \
    680         Common/Assert.cc \
    681         Common/Eval.cc \
    682         Common/SemanticError.cc \
    683         Common/UniqueName.cc \
    684         Concurrency/Keywords.cc \
     568        CodeGen/OperatorTable.cc
     569
     570SRC_COMMON = \
     571      Common/Assert.cc \
     572      Common/Eval.cc \
     573      Common/PassVisitor.cc \
     574      Common/SemanticError.cc \
     575      Common/Stats/Counter.cc \
     576      Common/Stats/Heap.cc \
     577      Common/Stats/Stats.cc \
     578      Common/Stats/Time.cc \
     579      Common/UniqueName.cc
     580
     581SRC_CONTROLSTRUCT = \
    685582        ControlStruct/ForExprMutator.cc \
    686583        ControlStruct/LabelFixer.cc \
    687584        ControlStruct/LabelGenerator.cc \
    688585        ControlStruct/MLEMutator.cc \
    689         ControlStruct/Mutate.cc \
    690         GenPoly/GenPoly.cc \
    691         GenPoly/Lvalue.cc \
    692         InitTweak/GenInit.cc \
    693         InitTweak/InitTweak.cc \
    694         Parser/LinkageSpec.cc \
    695         ResolvExpr/AdjustExprType.cc \
    696         ResolvExpr/Alternative.cc \
    697         ResolvExpr/AlternativeFinder.cc \
    698         ResolvExpr/ExplodedActual.cc \
    699         ResolvExpr/CastCost.cc \
    700         ResolvExpr/CommonType.cc \
    701         ResolvExpr/ConversionCost.cc \
    702         ResolvExpr/CurrentObject.cc \
    703         ResolvExpr/FindOpenVars.cc \
    704         ResolvExpr/Occurs.cc \
    705         ResolvExpr/PolyCost.cc \
    706         ResolvExpr/PtrsAssignable.cc \
    707         ResolvExpr/PtrsCastable.cc \
    708         ResolvExpr/RenameVars.cc \
    709         ResolvExpr/ResolveAssertions.cc \
    710         ResolvExpr/Resolver.cc \
    711         ResolvExpr/ResolveTypeof.cc \
    712         ResolvExpr/SpecCost.cc \
    713         ResolvExpr/TypeEnvironment.cc \
    714         ResolvExpr/Unify.cc \
    715         SymTab/Autogen.cc \
    716         SymTab/FixFunction.cc \
    717         SymTab/Indexer.cc \
    718         SymTab/Mangler.cc \
    719         SymTab/Validate.cc \
    720         Tuples/Explode.cc \
    721         Tuples/TupleAssignment.cc \
    722         Tuples/TupleExpansion.cc \
    723         Validate/HandleAttributes.cc \
    724         Validate/FindSpecialDecls.cc
    725 
     586        ControlStruct/Mutate.cc
     587
     588BUILT_SOURCES = Parser/parser.hh
     589AM_YFLAGS = -d -t -v
     590SRC_RESOLVEXPR = \
     591      ResolvExpr/AdjustExprType.cc \
     592      ResolvExpr/Alternative.cc \
     593      ResolvExpr/AlternativeFinder.cc \
     594      ResolvExpr/CastCost.cc \
     595      ResolvExpr/CommonType.cc \
     596      ResolvExpr/ConversionCost.cc \
     597      ResolvExpr/CurrentObject.cc \
     598      ResolvExpr/ExplodedActual.cc \
     599      ResolvExpr/FindOpenVars.cc \
     600      ResolvExpr/Occurs.cc \
     601      ResolvExpr/PolyCost.cc \
     602      ResolvExpr/PtrsAssignable.cc \
     603      ResolvExpr/PtrsCastable.cc \
     604      ResolvExpr/RenameVars.cc \
     605      ResolvExpr/ResolveAssertions.cc \
     606      ResolvExpr/Resolver.cc \
     607      ResolvExpr/ResolveTypeof.cc \
     608      ResolvExpr/SpecCost.cc \
     609      ResolvExpr/TypeEnvironment.cc \
     610      ResolvExpr/Unify.cc
     611
     612SRC_SYMTAB = \
     613      SymTab/Autogen.cc \
     614      SymTab/FixFunction.cc \
     615      SymTab/Indexer.cc \
     616      SymTab/Mangler.cc \
     617      SymTab/ManglerCommon.cc \
     618      SymTab/Validate.cc
     619
     620SRC_SYNTREE = \
     621      SynTree/Type.cc \
     622      SynTree/VoidType.cc \
     623      SynTree/BasicType.cc \
     624      SynTree/PointerType.cc \
     625      SynTree/ArrayType.cc \
     626      SynTree/ReferenceType.cc \
     627      SynTree/FunctionType.cc \
     628      SynTree/ReferenceToType.cc \
     629      SynTree/TupleType.cc \
     630      SynTree/TypeofType.cc \
     631      SynTree/AttrType.cc \
     632      SynTree/VarArgsType.cc \
     633      SynTree/ZeroOneType.cc \
     634      SynTree/Constant.cc \
     635      SynTree/Expression.cc \
     636      SynTree/TupleExpr.cc \
     637      SynTree/CommaExpr.cc \
     638      SynTree/TypeExpr.cc \
     639      SynTree/ApplicationExpr.cc \
     640      SynTree/AddressExpr.cc \
     641      SynTree/Statement.cc \
     642      SynTree/CompoundStmt.cc \
     643      SynTree/DeclStmt.cc \
     644      SynTree/Declaration.cc \
     645      SynTree/DeclarationWithType.cc \
     646      SynTree/ObjectDecl.cc \
     647      SynTree/FunctionDecl.cc \
     648      SynTree/AggregateDecl.cc \
     649      SynTree/NamedTypeDecl.cc \
     650      SynTree/TypeDecl.cc \
     651      SynTree/Initializer.cc \
     652      SynTree/TypeSubstitution.cc \
     653      SynTree/Attribute.cc \
     654      SynTree/DeclReplacer.cc
     655
     656
     657# put into lib for now
     658cfa_cpplibdir = $(CFA_LIBDIR)
     659___driver_cfa_cpp_SOURCES = $(SRC)
     660___driver_cfa_cpp_LDADD = -ldl $(LIBPROFILER) $(LIBTCMALLOC)
     661AM_CXXFLAGS = @HOST_FLAGS@ -Wno-deprecated -Wall -Wextra -DDEBUG_ALL -I./Parser -I$(srcdir)/Parser -I$(srcdir)/include -DYY_NO_INPUT -O3 -g -std=c++14 $(TCMALLOCFLAG)
     662AM_LDFLAGS = @HOST_FLAGS@ -Xlinker -export-dynamic
     663ARFLAGS = cr
     664demangler_SOURCES = SymTab/demangler.cc # test driver for the demangler, also useful as a sanity check that libdemangle.a is complete
     665demangler_LDADD = libdemangle.a -ldl                    # yywrap
     666noinst_LIBRARIES = libdemangle.a
     667libdemangle_a_SOURCES = $(SRCDEMANGLE)
    726668all: $(BUILT_SOURCES)
    727669        $(MAKE) $(AM_MAKEFLAGS) all-am
     
    762704clean-noinstLIBRARIES:
    763705        -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
    764 SymTab/$(am__dirstamp):
    765         @$(MKDIR_P) SymTab
    766         @: > SymTab/$(am__dirstamp)
    767 SymTab/$(DEPDIR)/$(am__dirstamp):
    768         @$(MKDIR_P) SymTab/$(DEPDIR)
    769         @: > SymTab/$(DEPDIR)/$(am__dirstamp)
    770 SymTab/Demangle.$(OBJEXT): SymTab/$(am__dirstamp) \
    771         SymTab/$(DEPDIR)/$(am__dirstamp)
    772 SymTab/ManglerCommon.$(OBJEXT): SymTab/$(am__dirstamp) \
    773         SymTab/$(DEPDIR)/$(am__dirstamp)
    774 SynTree/$(am__dirstamp):
    775         @$(MKDIR_P) SynTree
    776         @: > SynTree/$(am__dirstamp)
    777 SynTree/$(DEPDIR)/$(am__dirstamp):
    778         @$(MKDIR_P) SynTree/$(DEPDIR)
    779         @: > SynTree/$(DEPDIR)/$(am__dirstamp)
    780 SynTree/Type.$(OBJEXT): SynTree/$(am__dirstamp) \
    781         SynTree/$(DEPDIR)/$(am__dirstamp)
    782 SynTree/VoidType.$(OBJEXT): SynTree/$(am__dirstamp) \
    783         SynTree/$(DEPDIR)/$(am__dirstamp)
    784 SynTree/BasicType.$(OBJEXT): SynTree/$(am__dirstamp) \
    785         SynTree/$(DEPDIR)/$(am__dirstamp)
    786 SynTree/PointerType.$(OBJEXT): SynTree/$(am__dirstamp) \
    787         SynTree/$(DEPDIR)/$(am__dirstamp)
    788 SynTree/ArrayType.$(OBJEXT): SynTree/$(am__dirstamp) \
    789         SynTree/$(DEPDIR)/$(am__dirstamp)
    790 SynTree/ReferenceType.$(OBJEXT): SynTree/$(am__dirstamp) \
    791         SynTree/$(DEPDIR)/$(am__dirstamp)
    792 SynTree/FunctionType.$(OBJEXT): SynTree/$(am__dirstamp) \
    793         SynTree/$(DEPDIR)/$(am__dirstamp)
    794 SynTree/ReferenceToType.$(OBJEXT): SynTree/$(am__dirstamp) \
    795         SynTree/$(DEPDIR)/$(am__dirstamp)
    796 SynTree/TupleType.$(OBJEXT): SynTree/$(am__dirstamp) \
    797         SynTree/$(DEPDIR)/$(am__dirstamp)
    798 SynTree/TypeofType.$(OBJEXT): SynTree/$(am__dirstamp) \
    799         SynTree/$(DEPDIR)/$(am__dirstamp)
    800 SynTree/AttrType.$(OBJEXT): SynTree/$(am__dirstamp) \
    801         SynTree/$(DEPDIR)/$(am__dirstamp)
    802 SynTree/VarArgsType.$(OBJEXT): SynTree/$(am__dirstamp) \
    803         SynTree/$(DEPDIR)/$(am__dirstamp)
    804 SynTree/ZeroOneType.$(OBJEXT): SynTree/$(am__dirstamp) \
    805         SynTree/$(DEPDIR)/$(am__dirstamp)
    806 SynTree/Constant.$(OBJEXT): SynTree/$(am__dirstamp) \
    807         SynTree/$(DEPDIR)/$(am__dirstamp)
    808 SynTree/Expression.$(OBJEXT): SynTree/$(am__dirstamp) \
    809         SynTree/$(DEPDIR)/$(am__dirstamp)
    810 SynTree/TupleExpr.$(OBJEXT): SynTree/$(am__dirstamp) \
    811         SynTree/$(DEPDIR)/$(am__dirstamp)
    812 SynTree/CommaExpr.$(OBJEXT): SynTree/$(am__dirstamp) \
    813         SynTree/$(DEPDIR)/$(am__dirstamp)
    814 SynTree/TypeExpr.$(OBJEXT): SynTree/$(am__dirstamp) \
    815         SynTree/$(DEPDIR)/$(am__dirstamp)
    816 SynTree/ApplicationExpr.$(OBJEXT): SynTree/$(am__dirstamp) \
    817         SynTree/$(DEPDIR)/$(am__dirstamp)
    818 SynTree/AddressExpr.$(OBJEXT): SynTree/$(am__dirstamp) \
    819         SynTree/$(DEPDIR)/$(am__dirstamp)
    820 SynTree/Statement.$(OBJEXT): SynTree/$(am__dirstamp) \
    821         SynTree/$(DEPDIR)/$(am__dirstamp)
    822 SynTree/CompoundStmt.$(OBJEXT): SynTree/$(am__dirstamp) \
    823         SynTree/$(DEPDIR)/$(am__dirstamp)
    824 SynTree/DeclStmt.$(OBJEXT): SynTree/$(am__dirstamp) \
    825         SynTree/$(DEPDIR)/$(am__dirstamp)
    826 SynTree/Declaration.$(OBJEXT): SynTree/$(am__dirstamp) \
    827         SynTree/$(DEPDIR)/$(am__dirstamp)
    828 SynTree/DeclarationWithType.$(OBJEXT): SynTree/$(am__dirstamp) \
    829         SynTree/$(DEPDIR)/$(am__dirstamp)
    830 SynTree/ObjectDecl.$(OBJEXT): SynTree/$(am__dirstamp) \
    831         SynTree/$(DEPDIR)/$(am__dirstamp)
    832 SynTree/FunctionDecl.$(OBJEXT): SynTree/$(am__dirstamp) \
    833         SynTree/$(DEPDIR)/$(am__dirstamp)
    834 SynTree/AggregateDecl.$(OBJEXT): SynTree/$(am__dirstamp) \
    835         SynTree/$(DEPDIR)/$(am__dirstamp)
    836 SynTree/NamedTypeDecl.$(OBJEXT): SynTree/$(am__dirstamp) \
    837         SynTree/$(DEPDIR)/$(am__dirstamp)
    838 SynTree/TypeDecl.$(OBJEXT): SynTree/$(am__dirstamp) \
    839         SynTree/$(DEPDIR)/$(am__dirstamp)
    840 SynTree/Initializer.$(OBJEXT): SynTree/$(am__dirstamp) \
    841         SynTree/$(DEPDIR)/$(am__dirstamp)
    842 SynTree/TypeSubstitution.$(OBJEXT): SynTree/$(am__dirstamp) \
    843         SynTree/$(DEPDIR)/$(am__dirstamp)
    844 SynTree/Attribute.$(OBJEXT): SynTree/$(am__dirstamp) \
    845         SynTree/$(DEPDIR)/$(am__dirstamp)
    846 SynTree/DeclReplacer.$(OBJEXT): SynTree/$(am__dirstamp) \
    847         SynTree/$(DEPDIR)/$(am__dirstamp)
    848706CodeGen/$(am__dirstamp):
    849707        @$(MKDIR_P) CodeGen
     
    856714CodeGen/FixMain.$(OBJEXT): CodeGen/$(am__dirstamp) \
    857715        CodeGen/$(DEPDIR)/$(am__dirstamp)
    858 CodeGen/Generate.$(OBJEXT): CodeGen/$(am__dirstamp) \
    859         CodeGen/$(DEPDIR)/$(am__dirstamp)
    860716CodeGen/GenType.$(OBJEXT): CodeGen/$(am__dirstamp) \
    861717        CodeGen/$(DEPDIR)/$(am__dirstamp)
    862718CodeGen/OperatorTable.$(OBJEXT): CodeGen/$(am__dirstamp) \
    863719        CodeGen/$(DEPDIR)/$(am__dirstamp)
     720Concurrency/$(am__dirstamp):
     721        @$(MKDIR_P) Concurrency
     722        @: > Concurrency/$(am__dirstamp)
     723Concurrency/$(DEPDIR)/$(am__dirstamp):
     724        @$(MKDIR_P) Concurrency/$(DEPDIR)
     725        @: > Concurrency/$(DEPDIR)/$(am__dirstamp)
     726Concurrency/Keywords.$(OBJEXT): Concurrency/$(am__dirstamp) \
     727        Concurrency/$(DEPDIR)/$(am__dirstamp)
    864728Common/$(am__dirstamp):
    865729        @$(MKDIR_P) Common
     
    872736Common/Eval.$(OBJEXT): Common/$(am__dirstamp) \
    873737        Common/$(DEPDIR)/$(am__dirstamp)
     738Common/PassVisitor.$(OBJEXT): Common/$(am__dirstamp) \
     739        Common/$(DEPDIR)/$(am__dirstamp)
    874740Common/SemanticError.$(OBJEXT): Common/$(am__dirstamp) \
    875741        Common/$(DEPDIR)/$(am__dirstamp)
     742Common/Stats/$(am__dirstamp):
     743        @$(MKDIR_P) Common/Stats
     744        @: > Common/Stats/$(am__dirstamp)
     745Common/Stats/$(DEPDIR)/$(am__dirstamp):
     746        @$(MKDIR_P) Common/Stats/$(DEPDIR)
     747        @: > Common/Stats/$(DEPDIR)/$(am__dirstamp)
     748Common/Stats/Counter.$(OBJEXT): Common/Stats/$(am__dirstamp) \
     749        Common/Stats/$(DEPDIR)/$(am__dirstamp)
     750Common/Stats/Heap.$(OBJEXT): Common/Stats/$(am__dirstamp) \
     751        Common/Stats/$(DEPDIR)/$(am__dirstamp)
     752Common/Stats/Stats.$(OBJEXT): Common/Stats/$(am__dirstamp) \
     753        Common/Stats/$(DEPDIR)/$(am__dirstamp)
     754Common/Stats/Time.$(OBJEXT): Common/Stats/$(am__dirstamp) \
     755        Common/Stats/$(DEPDIR)/$(am__dirstamp)
    876756Common/UniqueName.$(OBJEXT): Common/$(am__dirstamp) \
    877757        Common/$(DEPDIR)/$(am__dirstamp)
    878 Concurrency/$(am__dirstamp):
    879         @$(MKDIR_P) Concurrency
    880         @: > Concurrency/$(am__dirstamp)
    881 Concurrency/$(DEPDIR)/$(am__dirstamp):
    882         @$(MKDIR_P) Concurrency/$(DEPDIR)
    883         @: > Concurrency/$(DEPDIR)/$(am__dirstamp)
    884 Concurrency/Keywords.$(OBJEXT): Concurrency/$(am__dirstamp) \
    885         Concurrency/$(DEPDIR)/$(am__dirstamp)
    886758ControlStruct/$(am__dirstamp):
    887759        @$(MKDIR_P) ControlStruct
     
    940812ResolvExpr/AlternativeFinder.$(OBJEXT): ResolvExpr/$(am__dirstamp) \
    941813        ResolvExpr/$(DEPDIR)/$(am__dirstamp)
     814ResolvExpr/CastCost.$(OBJEXT): ResolvExpr/$(am__dirstamp) \
     815        ResolvExpr/$(DEPDIR)/$(am__dirstamp)
     816ResolvExpr/CommonType.$(OBJEXT): ResolvExpr/$(am__dirstamp) \
     817        ResolvExpr/$(DEPDIR)/$(am__dirstamp)
     818ResolvExpr/ConversionCost.$(OBJEXT): ResolvExpr/$(am__dirstamp) \
     819        ResolvExpr/$(DEPDIR)/$(am__dirstamp)
     820ResolvExpr/CurrentObject.$(OBJEXT): ResolvExpr/$(am__dirstamp) \
     821        ResolvExpr/$(DEPDIR)/$(am__dirstamp)
    942822ResolvExpr/ExplodedActual.$(OBJEXT): ResolvExpr/$(am__dirstamp) \
    943823        ResolvExpr/$(DEPDIR)/$(am__dirstamp)
    944 ResolvExpr/CastCost.$(OBJEXT): ResolvExpr/$(am__dirstamp) \
    945         ResolvExpr/$(DEPDIR)/$(am__dirstamp)
    946 ResolvExpr/CommonType.$(OBJEXT): ResolvExpr/$(am__dirstamp) \
    947         ResolvExpr/$(DEPDIR)/$(am__dirstamp)
    948 ResolvExpr/ConversionCost.$(OBJEXT): ResolvExpr/$(am__dirstamp) \
    949         ResolvExpr/$(DEPDIR)/$(am__dirstamp)
    950 ResolvExpr/CurrentObject.$(OBJEXT): ResolvExpr/$(am__dirstamp) \
    951         ResolvExpr/$(DEPDIR)/$(am__dirstamp)
    952824ResolvExpr/FindOpenVars.$(OBJEXT): ResolvExpr/$(am__dirstamp) \
    953825        ResolvExpr/$(DEPDIR)/$(am__dirstamp)
     
    974846ResolvExpr/Unify.$(OBJEXT): ResolvExpr/$(am__dirstamp) \
    975847        ResolvExpr/$(DEPDIR)/$(am__dirstamp)
     848SymTab/$(am__dirstamp):
     849        @$(MKDIR_P) SymTab
     850        @: > SymTab/$(am__dirstamp)
     851SymTab/$(DEPDIR)/$(am__dirstamp):
     852        @$(MKDIR_P) SymTab/$(DEPDIR)
     853        @: > SymTab/$(DEPDIR)/$(am__dirstamp)
    976854SymTab/Autogen.$(OBJEXT): SymTab/$(am__dirstamp) \
    977855        SymTab/$(DEPDIR)/$(am__dirstamp)
     
    982860SymTab/Mangler.$(OBJEXT): SymTab/$(am__dirstamp) \
    983861        SymTab/$(DEPDIR)/$(am__dirstamp)
     862SymTab/ManglerCommon.$(OBJEXT): SymTab/$(am__dirstamp) \
     863        SymTab/$(DEPDIR)/$(am__dirstamp)
    984864SymTab/Validate.$(OBJEXT): SymTab/$(am__dirstamp) \
    985865        SymTab/$(DEPDIR)/$(am__dirstamp)
     866SymTab/Demangle.$(OBJEXT): SymTab/$(am__dirstamp) \
     867        SymTab/$(DEPDIR)/$(am__dirstamp)
     868SynTree/$(am__dirstamp):
     869        @$(MKDIR_P) SynTree
     870        @: > SynTree/$(am__dirstamp)
     871SynTree/$(DEPDIR)/$(am__dirstamp):
     872        @$(MKDIR_P) SynTree/$(DEPDIR)
     873        @: > SynTree/$(DEPDIR)/$(am__dirstamp)
     874SynTree/Type.$(OBJEXT): SynTree/$(am__dirstamp) \
     875        SynTree/$(DEPDIR)/$(am__dirstamp)
     876SynTree/VoidType.$(OBJEXT): SynTree/$(am__dirstamp) \
     877        SynTree/$(DEPDIR)/$(am__dirstamp)
     878SynTree/BasicType.$(OBJEXT): SynTree/$(am__dirstamp) \
     879        SynTree/$(DEPDIR)/$(am__dirstamp)
     880SynTree/PointerType.$(OBJEXT): SynTree/$(am__dirstamp) \
     881        SynTree/$(DEPDIR)/$(am__dirstamp)
     882SynTree/ArrayType.$(OBJEXT): SynTree/$(am__dirstamp) \
     883        SynTree/$(DEPDIR)/$(am__dirstamp)
     884SynTree/ReferenceType.$(OBJEXT): SynTree/$(am__dirstamp) \
     885        SynTree/$(DEPDIR)/$(am__dirstamp)
     886SynTree/FunctionType.$(OBJEXT): SynTree/$(am__dirstamp) \
     887        SynTree/$(DEPDIR)/$(am__dirstamp)
     888SynTree/ReferenceToType.$(OBJEXT): SynTree/$(am__dirstamp) \
     889        SynTree/$(DEPDIR)/$(am__dirstamp)
     890SynTree/TupleType.$(OBJEXT): SynTree/$(am__dirstamp) \
     891        SynTree/$(DEPDIR)/$(am__dirstamp)
     892SynTree/TypeofType.$(OBJEXT): SynTree/$(am__dirstamp) \
     893        SynTree/$(DEPDIR)/$(am__dirstamp)
     894SynTree/AttrType.$(OBJEXT): SynTree/$(am__dirstamp) \
     895        SynTree/$(DEPDIR)/$(am__dirstamp)
     896SynTree/VarArgsType.$(OBJEXT): SynTree/$(am__dirstamp) \
     897        SynTree/$(DEPDIR)/$(am__dirstamp)
     898SynTree/ZeroOneType.$(OBJEXT): SynTree/$(am__dirstamp) \
     899        SynTree/$(DEPDIR)/$(am__dirstamp)
     900SynTree/Constant.$(OBJEXT): SynTree/$(am__dirstamp) \
     901        SynTree/$(DEPDIR)/$(am__dirstamp)
     902SynTree/Expression.$(OBJEXT): SynTree/$(am__dirstamp) \
     903        SynTree/$(DEPDIR)/$(am__dirstamp)
     904SynTree/TupleExpr.$(OBJEXT): SynTree/$(am__dirstamp) \
     905        SynTree/$(DEPDIR)/$(am__dirstamp)
     906SynTree/CommaExpr.$(OBJEXT): SynTree/$(am__dirstamp) \
     907        SynTree/$(DEPDIR)/$(am__dirstamp)
     908SynTree/TypeExpr.$(OBJEXT): SynTree/$(am__dirstamp) \
     909        SynTree/$(DEPDIR)/$(am__dirstamp)
     910SynTree/ApplicationExpr.$(OBJEXT): SynTree/$(am__dirstamp) \
     911        SynTree/$(DEPDIR)/$(am__dirstamp)
     912SynTree/AddressExpr.$(OBJEXT): SynTree/$(am__dirstamp) \
     913        SynTree/$(DEPDIR)/$(am__dirstamp)
     914SynTree/Statement.$(OBJEXT): SynTree/$(am__dirstamp) \
     915        SynTree/$(DEPDIR)/$(am__dirstamp)
     916SynTree/CompoundStmt.$(OBJEXT): SynTree/$(am__dirstamp) \
     917        SynTree/$(DEPDIR)/$(am__dirstamp)
     918SynTree/DeclStmt.$(OBJEXT): SynTree/$(am__dirstamp) \
     919        SynTree/$(DEPDIR)/$(am__dirstamp)
     920SynTree/Declaration.$(OBJEXT): SynTree/$(am__dirstamp) \
     921        SynTree/$(DEPDIR)/$(am__dirstamp)
     922SynTree/DeclarationWithType.$(OBJEXT): SynTree/$(am__dirstamp) \
     923        SynTree/$(DEPDIR)/$(am__dirstamp)
     924SynTree/ObjectDecl.$(OBJEXT): SynTree/$(am__dirstamp) \
     925        SynTree/$(DEPDIR)/$(am__dirstamp)
     926SynTree/FunctionDecl.$(OBJEXT): SynTree/$(am__dirstamp) \
     927        SynTree/$(DEPDIR)/$(am__dirstamp)
     928SynTree/AggregateDecl.$(OBJEXT): SynTree/$(am__dirstamp) \
     929        SynTree/$(DEPDIR)/$(am__dirstamp)
     930SynTree/NamedTypeDecl.$(OBJEXT): SynTree/$(am__dirstamp) \
     931        SynTree/$(DEPDIR)/$(am__dirstamp)
     932SynTree/TypeDecl.$(OBJEXT): SynTree/$(am__dirstamp) \
     933        SynTree/$(DEPDIR)/$(am__dirstamp)
     934SynTree/Initializer.$(OBJEXT): SynTree/$(am__dirstamp) \
     935        SynTree/$(DEPDIR)/$(am__dirstamp)
     936SynTree/TypeSubstitution.$(OBJEXT): SynTree/$(am__dirstamp) \
     937        SynTree/$(DEPDIR)/$(am__dirstamp)
     938SynTree/Attribute.$(OBJEXT): SynTree/$(am__dirstamp) \
     939        SynTree/$(DEPDIR)/$(am__dirstamp)
     940SynTree/DeclReplacer.$(OBJEXT): SynTree/$(am__dirstamp) \
     941        SynTree/$(DEPDIR)/$(am__dirstamp)
    986942Tuples/$(am__dirstamp):
    987943        @$(MKDIR_P) Tuples
     
    990946        @$(MKDIR_P) Tuples/$(DEPDIR)
    991947        @: > Tuples/$(DEPDIR)/$(am__dirstamp)
    992 Tuples/Explode.$(OBJEXT): Tuples/$(am__dirstamp) \
    993         Tuples/$(DEPDIR)/$(am__dirstamp)
    994948Tuples/TupleAssignment.$(OBJEXT): Tuples/$(am__dirstamp) \
    995949        Tuples/$(DEPDIR)/$(am__dirstamp)
    996950Tuples/TupleExpansion.$(OBJEXT): Tuples/$(am__dirstamp) \
     951        Tuples/$(DEPDIR)/$(am__dirstamp)
     952Tuples/Explode.$(OBJEXT): Tuples/$(am__dirstamp) \
    997953        Tuples/$(DEPDIR)/$(am__dirstamp)
    998954Validate/$(am__dirstamp):
     
    10601016        echo " rm -f" $$list; \
    10611017        rm -f $$list
     1018CodeGen/Generate.$(OBJEXT): CodeGen/$(am__dirstamp) \
     1019        CodeGen/$(DEPDIR)/$(am__dirstamp)
    10621020CodeGen/FixNames.$(OBJEXT): CodeGen/$(am__dirstamp) \
    10631021        CodeGen/$(DEPDIR)/$(am__dirstamp)
     
    10771035        Concurrency/$(DEPDIR)/$(am__dirstamp)
    10781036Common/DebugMalloc.$(OBJEXT): Common/$(am__dirstamp) \
    1079         Common/$(DEPDIR)/$(am__dirstamp)
    1080 Common/Heap.$(OBJEXT): Common/$(am__dirstamp) \
    10811037        Common/$(DEPDIR)/$(am__dirstamp)
    10821038ControlStruct/ExceptTranslate.$(OBJEXT):  \
     
    11491105        -rm -f CodeTools/*.$(OBJEXT)
    11501106        -rm -f Common/*.$(OBJEXT)
     1107        -rm -f Common/Stats/*.$(OBJEXT)
    11511108        -rm -f Concurrency/*.$(OBJEXT)
    11521109        -rm -f ControlStruct/*.$(OBJEXT)
     
    11791136@AMDEP_TRUE@@am__include@ @am__quote@Common/$(DEPDIR)/DebugMalloc.Po@am__quote@
    11801137@AMDEP_TRUE@@am__include@ @am__quote@Common/$(DEPDIR)/Eval.Po@am__quote@
    1181 @AMDEP_TRUE@@am__include@ @am__quote@Common/$(DEPDIR)/Heap.Po@am__quote@
     1138@AMDEP_TRUE@@am__include@ @am__quote@Common/$(DEPDIR)/PassVisitor.Po@am__quote@
    11821139@AMDEP_TRUE@@am__include@ @am__quote@Common/$(DEPDIR)/SemanticError.Po@am__quote@
    11831140@AMDEP_TRUE@@am__include@ @am__quote@Common/$(DEPDIR)/UniqueName.Po@am__quote@
     1141@AMDEP_TRUE@@am__include@ @am__quote@Common/Stats/$(DEPDIR)/Counter.Po@am__quote@
     1142@AMDEP_TRUE@@am__include@ @am__quote@Common/Stats/$(DEPDIR)/Heap.Po@am__quote@
     1143@AMDEP_TRUE@@am__include@ @am__quote@Common/Stats/$(DEPDIR)/Stats.Po@am__quote@
     1144@AMDEP_TRUE@@am__include@ @am__quote@Common/Stats/$(DEPDIR)/Time.Po@am__quote@
    11841145@AMDEP_TRUE@@am__include@ @am__quote@Concurrency/$(DEPDIR)/Keywords.Po@am__quote@
    11851146@AMDEP_TRUE@@am__include@ @am__quote@Concurrency/$(DEPDIR)/Waitfor.Po@am__quote@
     
    14441405        -rm -f Common/$(DEPDIR)/$(am__dirstamp)
    14451406        -rm -f Common/$(am__dirstamp)
     1407        -rm -f Common/Stats/$(DEPDIR)/$(am__dirstamp)
     1408        -rm -f Common/Stats/$(am__dirstamp)
    14461409        -rm -f Concurrency/$(DEPDIR)/$(am__dirstamp)
    14471410        -rm -f Concurrency/$(am__dirstamp)
     
    14811444
    14821445distclean: distclean-am
    1483         -rm -rf ./$(DEPDIR) CodeGen/$(DEPDIR) CodeTools/$(DEPDIR) Common/$(DEPDIR) Concurrency/$(DEPDIR) ControlStruct/$(DEPDIR) GenPoly/$(DEPDIR) InitTweak/$(DEPDIR) Parser/$(DEPDIR) ResolvExpr/$(DEPDIR) SymTab/$(DEPDIR) SynTree/$(DEPDIR) Tuples/$(DEPDIR) Validate/$(DEPDIR) Virtual/$(DEPDIR)
     1446        -rm -rf ./$(DEPDIR) CodeGen/$(DEPDIR) CodeTools/$(DEPDIR) Common/$(DEPDIR) Common/Stats/$(DEPDIR) Concurrency/$(DEPDIR) ControlStruct/$(DEPDIR) GenPoly/$(DEPDIR) InitTweak/$(DEPDIR) Parser/$(DEPDIR) ResolvExpr/$(DEPDIR) SymTab/$(DEPDIR) SynTree/$(DEPDIR) Tuples/$(DEPDIR) Validate/$(DEPDIR) Virtual/$(DEPDIR)
    14841447        -rm -f Makefile
    14851448distclean-am: clean-am distclean-compile distclean-generic \
     
    15271490
    15281491maintainer-clean: maintainer-clean-am
    1529         -rm -rf ./$(DEPDIR) CodeGen/$(DEPDIR) CodeTools/$(DEPDIR) Common/$(DEPDIR) Concurrency/$(DEPDIR) ControlStruct/$(DEPDIR) GenPoly/$(DEPDIR) InitTweak/$(DEPDIR) Parser/$(DEPDIR) ResolvExpr/$(DEPDIR) SymTab/$(DEPDIR) SynTree/$(DEPDIR) Tuples/$(DEPDIR) Validate/$(DEPDIR) Virtual/$(DEPDIR)
     1492        -rm -rf ./$(DEPDIR) CodeGen/$(DEPDIR) CodeTools/$(DEPDIR) Common/$(DEPDIR) Common/Stats/$(DEPDIR) Concurrency/$(DEPDIR) ControlStruct/$(DEPDIR) GenPoly/$(DEPDIR) InitTweak/$(DEPDIR) Parser/$(DEPDIR) ResolvExpr/$(DEPDIR) SymTab/$(DEPDIR) SynTree/$(DEPDIR) Tuples/$(DEPDIR) Validate/$(DEPDIR) Virtual/$(DEPDIR)
    15301493        -rm -f Makefile
    15311494maintainer-clean-am: distclean-am maintainer-clean-generic
     
    15671530
    15681531
    1569 Parser/gcc-flags.h :
    1570         ${AM_V_GEN}$(CC) -dM -E - < /dev/null | sed 's/define /define __GCC__/' > $(@)
    1571 
    1572 Parser/lex.ll : Parser/gcc-flags.h
     1532$(addprefix $(srcdir)/, ResolvExpr/ConversionCost.cc ResolvExpr/CommonType.cc SymTab/ManglerCommon.cc) : $(srcdir)/SynTree/Type.h
     1533
     1534$(srcdir)/SynTree/Type.h : BasicTypes-gen.cc
     1535        ${AM_V_GEN}${CXXCOMPILE} $< -o BasicTypes-gen -Wall -Wextra
     1536        @./BasicTypes-gen
     1537        @rm BasicTypes-gen
    15731538
    15741539# Tell versions [3.59,3.63) of GNU make to not export all variables.
  • src/Parser/DeclarationNode.cc

    r6a9d4b4 r933f32f  
    1010// Created On       : Sat May 16 12:34:05 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Nov  1 20:54:26 2018
    13 // Update Count     : 1108
     12// Last Modified On : Fri Feb  1 16:49:17 2019
     13// Update Count     : 1113
    1414//
    1515
     
    4141
    4242// These must harmonize with the corresponding DeclarationNode enumerations.
    43 const char * DeclarationNode::basicTypeNames[] = { "void", "_Bool", "char", "int", "float", "double", "long double", "int128", "float80", "float128", "NoBasicTypeNames" };
    44 const char * DeclarationNode::complexTypeNames[] = { "_Complex", "_Imaginary", "NoComplexTypeNames" };
     43const char * DeclarationNode::basicTypeNames[] = { "void", "_Bool", "char", "int", "int128",
     44                                                                                                   "float", "double", "long double", "float80", "float128",
     45                                                                                                   "_float16", "_float32", "_float32x", "_float64", "_float64x", "_float128", "_float128x", "NoBasicTypeNames" };
     46const char * DeclarationNode::complexTypeNames[] = { "_Complex", "NoComplexTypeNames", "_Imaginary" }; // Imaginary unsupported => parse, but make invisible and print error message
    4547const char * DeclarationNode::signednessNames[] = { "signed", "unsigned", "NoSignednessNames" };
    4648const char * DeclarationNode::lengthNames[] = { "short", "long", "long long", "NoLengthNames" };
  • src/Parser/ExpressionNode.cc

    r6a9d4b4 r933f32f  
    1010// Created On       : Sat May 16 13:17:07 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Jun  4 21:24:45 2018
    13 // Update Count     : 802
     12// Last Modified On : Sun Mar 10 16:10:32 2019
     13// Update Count     : 976
    1414//
    1515
     
    5151extern const Type::Qualifiers noQualifiers;                             // no qualifiers on constants
    5252
    53 static inline bool checkH( char c ) { return c == 'h' || c == 'H'; }
    54 static inline bool checkL( char c ) { return c == 'l' || c == 'L'; }
    55 static inline bool checkZ( char c ) { return c == 'z' || c == 'Z'; }
    56 static inline bool checkU( char c ) { return c == 'u' || c == 'U'; }
     53// static inline bool checkH( char c ) { return c == 'h' || c == 'H'; }
     54// static inline bool checkZ( char c ) { return c == 'z' || c == 'Z'; }
     55// static inline bool checkU( char c ) { return c == 'u' || c == 'U'; }
    5756static inline bool checkF( char c ) { return c == 'f' || c == 'F'; }
    5857static inline bool checkD( char c ) { return c == 'd' || c == 'D'; }
     58static inline bool checkF80( char c ) { return c == 'w' || c == 'W'; }
     59static inline bool checkF128( char c ) { return c == 'q' || c == 'Q'; }
     60static inline bool checkL( char c ) { return c == 'l' || c == 'L'; }
    5961static inline bool checkI( char c ) { return c == 'i' || c == 'I'; }
    6062static inline bool checkB( char c ) { return c == 'b' || c == 'B'; }
    6163static inline bool checkX( char c ) { return c == 'x' || c == 'X'; }
    62 
    63 static const char * lnthsInt[2][6] = {
    64         { "int8_t", "int16_t", "int32_t", "int64_t", "size_t", },
    65         { "uint8_t", "uint16_t", "uint32_t", "uint64_t", "size_t", }
    66 }; // lnthsInt
    67 
    68 static inline void checkLNInt( string & str, int & lnth, int & size ) {
    69         string::size_type posn = str.find_first_of( "lL" ), start = posn;
    70   if ( posn == string::npos ) return;
    71         size = 4;                                                                                       // assume largest size
    72         posn += 1;                                                                                      // advance to size
    73         if ( str[posn] == '8' ) {                                                       // 8
    74                 lnth = 0;
    75         } else if ( str[posn] == '1' ) {
    76                 posn += 1;
    77                 if ( str[posn] == '6' ) {                                               // 16
    78                         lnth = 1;
     64// static inline bool checkN( char c ) { return c == 'n' || c == 'N'; }
     65
     66void lnthSuffix( string & str, int & type, int & ltype ) {
     67        string::size_type posn = str.find_last_of( "lL" );
     68
     69        if ( posn == string::npos ) return;                                     // no suffix
     70        if ( posn == str.length() - 1 ) { type = 3; return; } // no length => long
     71
     72        string::size_type next = posn + 1;                                      // advance to length
     73        if ( str[next] == '3' ) {                                                       // 32
     74                type = ltype = 2;
     75        } else if ( str[next] == '6' ) {                                        // 64
     76                type = ltype = 3;
     77        } else if ( str[next] == '8' ) {                                        // 8
     78                type = ltype = 1;
     79        } else if ( str[next] == '1' ) {
     80                if ( str[next + 1] == '6' ) {                                   // 16
     81                        type = ltype = 0;
    7982                } else {                                                                                // 128
    80                         posn += 1;
    81                         lnth = 5;
    82                 } // if
    83         } else {
    84                 if ( str[posn] == '3' ) {                                               // 32
    85                         lnth = 2;
    86                 } else if ( str[posn] == '6' ) {                                // 64
    87                         lnth = 3;
    88                 } else {
    89                         assertf( false, "internal error, bad integral length %s", str.c_str() );
    90                 } // if
    91                 posn += 1;
    92         } // if
    93         str.erase( start, posn - start + 1 );                           // remove length suffix
    94 } // checkLNInt
     83                        type = 5; ltype = 6;
     84                } // if
     85        } // if
     86        // remove "lL" for these cases because it may not imply long
     87        str.erase( posn );                                                                      // remove length
     88} // lnthSuffix
     89
     90void valueToType( unsigned long long int & v, bool dec, int & type, bool & Unsigned ) {
     91        // use value to determine type
     92        if ( v <= INT_MAX ) {                                                           // signed int
     93                type = 2;
     94        } else if ( v <= UINT_MAX && ! dec ) {                          // unsigned int
     95                type = 2;
     96                Unsigned = true;                                                                // unsigned
     97        } else if ( v <= LONG_MAX ) {                                           // signed long int
     98                type = 3;
     99        } else if ( v <= ULONG_MAX && ( ! dec || LONG_MAX == LLONG_MAX ) ) { // signed long int
     100                type = 3;
     101                Unsigned = true;                                                                // unsigned long int
     102        } else if ( v <= LLONG_MAX ) {                                          // signed long long int
     103                type = 4;
     104        } else {                                                                                        // unsigned long long int
     105                type = 4;
     106                Unsigned = true;                                                                // unsigned long long int
     107        } // if
     108} // valueToType
    95109
    96110Expression * build_constantInteger( string & str ) {
    97         static const BasicType::Kind kind[2][6] = {
    98                 // short (h) must be before char (hh)
     111        static const BasicType::Kind kind[2][7] = {
     112                // short (h) must be before char (hh) because shorter type has the longer suffix
    99113                { BasicType::ShortSignedInt, BasicType::SignedChar, BasicType::SignedInt, BasicType::LongSignedInt, BasicType::LongLongSignedInt, BasicType::SignedInt128, },
    100114                { BasicType::ShortUnsignedInt, BasicType::UnsignedChar, BasicType::UnsignedInt, BasicType::LongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::UnsignedInt128, },
    101115        };
    102116
    103         bool dec = true, Unsigned = false;                                      // decimal, unsigned constant
    104         int size;                                                                                       // 0 => short, 1 => char, 2 => int, 3 => long int, 4 => long long int, 5 => int128
    105         int lnth = -1;                                                                          // literal length
     117        static const char * lnthsInt[2][6] = {
     118                { "int16_t",  "int8_t",  "int32_t",  "int64_t",  "size_t",  "uintptr_t", },
     119                { "uint16_t", "uint8_t", "uint32_t", "uint64_t", "size_t",  "uintptr_t", },
     120        }; // lnthsInt
    106121
    107122        unsigned long long int v;                                                       // converted integral value
    108123        size_t last = str.length() - 1;                                         // last subscript of constant
    109124        Expression * ret;
     125        //string fred( str );
     126
     127        int type = -1;                                                                          // 0 => short, 1 => char, 2 => int, 3 => long int, 4 => long long int, 5 => int128
     128        int ltype = -1;                                                                         // 0 => 16 bits, 1 => 8 bits, 2 => 32 bits, 3 => 64 bits, 4 => size_t, 5 => intptr, 6 => pointer
     129        bool dec = true, Unsigned = false;                                      // decimal, unsigned constant
    110130
    111131        // special constants
     
    119139        } // if
    120140
    121         // Cannot be "0"
     141        // Cannot be just "0"/"1"; sscanf stops at the suffix, if any; value goes over the wall => always generate
    122142
    123143        if ( str[0] == '0' ) {                                                          // radix character ?
     
    127147                        //printf( "%llx %llu\n", v, v );
    128148                } else if ( checkB( str[1] ) ) {                                // binary constant ?
    129                         v = 0;
    130                         for ( unsigned int i = 2;; i += 1 ) {           // compute value
     149                        v = 0;                                                                          // compute value
     150                        for ( unsigned int i = 2;; ) {                          // ignore prefix
    131151                                if ( str[i] == '1' ) v |= 1;
    132                           if ( i == last ) break;
     152                                i += 1;
     153                          if ( i == last - 1 || (str[i] != '0' && str[i] != '1') ) break;
    133154                                v <<= 1;
    134155                        } // for
    135                         //printf( "%llx %llu\n", v, v );
     156                        //printf( "%#llx %llu\n", v, v );
    136157                } else {                                                                                // octal constant
    137158                        sscanf( (char *)str.c_str(), "%llo", &v );
    138                         //printf( "%llo %llu\n", v, v );
     159                        //printf( "%#llo %llu\n", v, v );
    139160                } // if
    140161        } else {                                                                                        // decimal constant ?
    141162                sscanf( (char *)str.c_str(), "%llu", &v );
    142                 //printf( "%llu %llu\n", v, v );
    143         } // if
    144 
    145         if ( v <= INT_MAX ) {                                                           // signed int
    146                 size = 2;
    147         } else if ( v <= UINT_MAX && ! dec ) {                          // unsigned int
    148                 size = 2;
    149                 Unsigned = true;                                                                // unsigned
    150         } else if ( v <= LONG_MAX ) {                                           // signed long int
    151                 size = 3;
    152         } else if ( v <= ULONG_MAX && ( ! dec || LONG_MAX == LLONG_MAX ) ) { // signed long int
    153                 size = 3;
    154                 Unsigned = true;                                                                // unsigned long int
    155         } else if ( v <= LLONG_MAX ) {                                          // signed long long int
    156                 size = 4;
    157         } else {                                                                                        // unsigned long long int
    158                 size = 4;
    159                 Unsigned = true;                                                                // unsigned long long int
    160         } // if
    161 
    162         // At least one digit in integer constant, so safe to backup while looking for suffix.
    163 
    164         if ( checkU( str[last] ) ) {                                            // suffix 'u' ?
    165                 Unsigned = true;
    166                 if ( checkL( str[last - 1] ) ) {                                // suffix 'l' ?
    167                         size = 3;
    168                         if ( checkL( str[last - 2] ) ) {                        // suffix "ll" ?
    169                                 size = 4;
     163                //printf( "%llu\n", v );
     164        } // if
     165
     166        string::size_type posn;
     167
     168        if ( isdigit( str[last] ) ) {                                           // no suffix ?
     169                lnthSuffix( str, type, ltype );                                 // could have length suffix
     170                if ( type == -1 ) {                                                             // no suffix
     171                        valueToType( v, dec, type, Unsigned );
     172                } // if
     173        } else {
     174                // At least one digit in integer constant, so safe to backup while looking for suffix.
     175
     176                posn = str.find_last_of( "pP" );
     177                if ( posn != string::npos ) { valueToType( v, dec, type, Unsigned ); ltype = 5; str.erase( posn, 1 ); goto FINI; }
     178
     179                posn = str.find_last_of( "zZ" );
     180                if ( posn != string::npos ) { Unsigned = true; type = 2; ltype = 4; str.erase( posn, 1 ); goto FINI; }
     181
     182                // 'u' can appear before or after length suffix
     183                if ( str.find_last_of( "uU" ) != string::npos ) Unsigned = true;
     184
     185                posn = str.rfind( "hh" );
     186                if ( posn != string::npos ) { type = 1; str.erase( posn, 2 ); goto FINI; }
     187
     188                posn = str.rfind( "HH" );
     189                if ( posn != string::npos ) { type = 1; str.erase( posn, 2 ); goto FINI; }
     190
     191                posn = str.find_last_of( "hH" );
     192                if ( posn != string::npos ) { type = 0; str.erase( posn, 1 ); goto FINI; }
     193
     194                posn = str.find_last_of( "nN" );
     195                if ( posn != string::npos ) { type = 2; str.erase( posn, 1 ); goto FINI; }
     196
     197                if ( str.rfind( "ll" ) != string::npos || str.rfind( "LL" ) != string::npos ) { type = 4; goto FINI; }
     198
     199                lnthSuffix( str, type, ltype );                                 // must be after check for "ll"
     200                if ( type == -1 ) {                                                             // only 'u' suffix ?
     201                        valueToType( v, dec, type, Unsigned );
     202                } // if
     203          FINI: ;
     204        } // if
     205
     206        //if ( !( 0 <= type && type <= 6 ) ) { printf( "%s %lu %d %s\n", fred.c_str(), fred.length(), type, str.c_str() ); }
     207        assert( 0 <= type && type <= 6 );
     208
     209        // Constant type is correct for overload resolving.
     210        ret = new ConstantExpr( Constant( new BasicType( noQualifiers, kind[Unsigned][type] ), str, v ) );
     211        if ( Unsigned && type < 2 ) {                                           // hh or h, less than int ?
     212                // int i = -1uh => 65535 not -1, so cast is necessary for unsigned, which unfortunately eliminates warnings for large values.
     213                ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[Unsigned][type] ), false );
     214        } else if ( ltype != -1 ) {                                                     // explicit length ?
     215                if ( ltype == 6 ) {                                                             // int128, (int128)constant
     216                        ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[Unsigned][type] ), false );
     217                } else {                                                                                // explicit length, (length_type)constant
     218                        ret = new CastExpr( ret, new TypeInstType( Type::Qualifiers(), lnthsInt[Unsigned][ltype], false ), false );
     219                        if ( ltype == 5 ) {                                                     // pointer, intptr( (uintptr_t)constant )
     220                                ret = build_func( new ExpressionNode( build_varref( new string( "intptr" ) ) ), new ExpressionNode( ret ) );
    170221                        } // if
    171                 } else if ( checkH( str[last - 1] ) ) {                 // suffix 'h' ?
    172                         size = 0;
    173                         if ( checkH( str[last - 2] ) ) {                        // suffix "hh" ?
    174                                 size = 1;
    175                         } // if
    176                         str.erase( last - size - 1, size + 1 );         // remove 'h'/"hh"
    177                 } else {                                                                                // suffix "ln" ?
    178                         checkLNInt( str, lnth, size );
    179                 } // if
    180         } else if ( checkL( str[ last ] ) ) {                           // suffix 'l' ?
    181                 size = 3;
    182                 if ( checkL( str[last - 1] ) ) {                                // suffix 'll' ?
    183                         size = 4;
    184                         if ( checkU( str[last - 2] ) ) {                        // suffix 'u' ?
    185                                 Unsigned = true;
    186                         } // if
    187                 } else if ( checkU( str[last - 1] ) ) {                 // suffix 'u' ?
    188                         Unsigned = true;
    189                 } // if
    190         } else if ( checkH( str[ last ] ) ) {                           // suffix 'h' ?
    191                 size = 0;
    192                 if ( checkH( str[last - 1] ) ) {                                // suffix "hh" ?
    193                         size = 1;
    194                         if ( checkU( str[last - 2] ) ) {                        // suffix 'u' ?
    195                                 Unsigned = true;
    196                         } // if
    197                 } else if ( checkU( str[last - 1] ) ) {                 // suffix 'u' ?
    198                         Unsigned = true;
    199                 } // if
    200                 str.erase( last - size, size + 1 );                             // remove 'h'/"hh"
    201         } else if ( checkZ( str[last] ) ) {                                     // suffix 'z' ?
    202                 lnth = 4;
    203                 str.erase( last, 1 );                                                   // remove 'z'
    204         } else {                                                                                        // suffix "ln" ?
    205                 checkLNInt( str, lnth, size );
    206         } // if
    207 
    208         assert( 0 <= size && size < 6 );
    209         // Constant type is correct for overload resolving.
    210         ret = new ConstantExpr( Constant( new BasicType( noQualifiers, kind[Unsigned][size] ), str, v ) );
    211         if ( Unsigned && size < 2 ) {                                           // hh or h, less than int ?
    212                 // int i = -1uh => 65535 not -1, so cast is necessary for unsigned, which unfortunately eliminates warnings for large values.
    213                 ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[Unsigned][size] ), false );
    214         } else if ( lnth != -1 ) {                                                      // explicit length ?
    215                 if ( lnth == 5 ) {                                                              // int128 ?
    216                         size = 5;
    217                         ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[Unsigned][size] ), false );
    218                 } else {
    219                         ret = new CastExpr( ret, new TypeInstType( Type::Qualifiers(), lnthsInt[Unsigned][lnth], false ), false );
    220                 } // if
    221         } // if
    222   CLEANUP:
    223 
     222                } // if
     223        } // if
     224
     225  CLEANUP: ;
    224226        delete &str;                                                                            // created by lex
    225227        return ret;
     
    227229
    228230
    229 static inline void checkLNFloat( string & str, int & lnth, int & size ) {
    230         string::size_type posn = str.find_first_of( "lL" ), start = posn;
     231static inline void checkFnxFloat( string & str, size_t last, bool & explnth, int & type ) {
     232        string::size_type posn;
     233        // floating-point constant has minimum of 2 characters, 1. or .1, so safe to look ahead
     234        if ( str[1] == 'x' ) {                                                          // hex ?
     235                posn = str.find_last_of( "pP" );                                // back for exponent (must have)
     236                posn = str.find_first_of( "fF", posn + 1 );             // forward for size (fF allowed in hex constant)
     237        } else {
     238                posn = str.find_last_of( "fF" );                                // back for size (fF not allowed)
     239        } // if
    231240  if ( posn == string::npos ) return;
    232         size = 2;                                                                                       // assume largest size
    233         lnth = 0;
     241        explnth = true;
    234242        posn += 1;                                                                                      // advance to size
    235243        if ( str[posn] == '3' ) {                                                       // 32
    236                 size = 0;
     244                if ( str[last] != 'x' ) type = 6;
     245                else type = 7;
    237246        } else if ( str[posn] == '6' ) {                                        // 64
    238                 size = 1;
    239         } else if ( str[posn] == '8' || str[posn] == '1' ) { // 80, 128
    240                 size = 2;
    241                 if ( str[posn] == '1' ) posn += 1;
     247                if ( str[last] != 'x' ) type = 8;
     248                else type = 9;
     249        } else if ( str[posn] == '8' ) {                                        // 80
     250                type = 3;
     251        } else if ( str[posn] == '1' ) {                                        // 16/128
     252                if ( str[posn + 1] == '6' ) {                                   // 16
     253                        type = 5;
     254                } else {                                                                                // 128
     255                        if ( str[last] != 'x' ) type = 10;
     256                        else type = 11;
     257                } // if
    242258        } else {
    243259                assertf( false, "internal error, bad floating point length %s", str.c_str() );
    244260        } // if
    245         posn += 1;
    246         str.erase( start, posn - start + 1 );                           // remove length suffix
    247 } // checkLNFloat
     261} // checkFnxFloat
    248262
    249263
    250264Expression * build_constantFloat( string & str ) {
    251         static const BasicType::Kind kind[2][3] = {
    252                 { BasicType::Float, BasicType::Double, BasicType::LongDouble },
    253                 { BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex },
     265        static const BasicType::Kind kind[2][12] = {
     266                { BasicType::Float, BasicType::Double, BasicType::LongDouble, BasicType::uuFloat80, BasicType::uuFloat128, BasicType::uFloat16, BasicType::uFloat32, BasicType::uFloat32x, BasicType::uFloat64, BasicType::uFloat64x, BasicType::uFloat128, BasicType::uFloat128x },
     267                { BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, (BasicType::Kind)-1, (BasicType::Kind)-1, BasicType::uFloat16Complex, BasicType::uFloat32Complex, BasicType::uFloat32xComplex, BasicType::uFloat64Complex, BasicType::uFloat64xComplex, BasicType::uFloat128Complex, BasicType::uFloat128xComplex },
    254268        };
    255269
    256         bool complx = false;                                                            // real, complex
    257         int size = 1;                                                                           // 0 => float, 1 => double, 2 => long double
    258         int lnth = -1;                                                                          // literal length
    259         // floating-point constant has minimum of 2 characters: 1. or .1
     270        // floating-point constant has minimum of 2 characters 1. or .1
    260271        size_t last = str.length() - 1;
    261272        double v;
     273        int type;                                                                                       // 0 => float, 1 => double, 3 => long double, ...
     274        bool complx = false;                                                            // real, complex
     275        bool explnth = false;                                                           // explicit literal length
    262276
    263277        sscanf( str.c_str(), "%lg", &v );
     
    269283
    270284        if ( checkF( str[last] ) ) {                                            // float ?
    271                 size = 0;
     285                type = 0;
    272286        } else if ( checkD( str[last] ) ) {                                     // double ?
    273                 size = 1;
     287                type = 1;
    274288        } else if ( checkL( str[last] ) ) {                                     // long double ?
    275                 size = 2;
     289                type = 2;
     290        } else if ( checkF80( str[last] ) ) {                           // __float80 ?
     291                type = 3;
     292        } else if ( checkF128( str[last] ) ) {                          // __float128 ?
     293                type = 4;
    276294        } else {
    277                 size = 1;                                                                               // double (default)
    278                 checkLNFloat( str, lnth, size );
    279         } // if
     295                type = 1;                                                                               // double (default if no suffix)
     296                checkFnxFloat( str, last, explnth, type );
     297        } // if
     298
    280299        if ( ! complx && checkI( str[last - 1] ) ) {            // imaginary ?
    281300                complx = true;
    282301        } // if
    283302
    284         assert( 0 <= size && size < 3 );
    285         Expression * ret = new ConstantExpr( Constant( new BasicType( noQualifiers, kind[complx][size] ), str, v ) );
    286         if ( lnth != -1 ) {                                                                     // explicit length ?
    287                 ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[complx][size] ), false );
     303        assert( 0 <= type && type < 12 );
     304        Expression * ret = new ConstantExpr( Constant( new BasicType( noQualifiers, kind[complx][type] ), str, v ) );
     305        if ( explnth ) {                                                                        // explicit length ?
     306                ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[complx][type] ), false );
    288307        } // if
    289308
  • src/Parser/ParseNode.h

    r6a9d4b4 r933f32f  
    1010// Created On       : Sat May 16 13:28:16 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Nov  1 20:54:53 2018
    13 // Update Count     : 854
     12// Last Modified On : Mon Apr 15 14:22:39 2019
     13// Update Count     : 874
    1414//
    1515
     
    132132        void printOneLine( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const {}
    133133
    134         Expression *get_expr() const { return expr.get(); }
    135134        template<typename T>
    136135        bool isExpressionType() const { return nullptr != dynamic_cast<T>(expr.get()); }
    137136
    138137        Expression * build() const { return const_cast<ExpressionNode *>(this)->expr.release(); }
     138
     139        std::unique_ptr<Expression> expr;                                       // public because of lifetime implications
    139140  private:
    140141        bool extension = false;
    141         std::unique_ptr<Expression> expr;
    142142}; // ExpressionNode
    143143
     
    206206class DeclarationNode : public ParseNode {
    207207  public:
    208         // These enumerations must harmonize with their names.
    209         enum BasicType { Void, Bool, Char, Int, Float, Double, LongDouble, Int128, Float80, Float128, NoBasicType };
     208        // These enumerations must harmonize with their names in DeclarationNode.cc.
     209        enum BasicType { Void, Bool, Char, Int, Int128,
     210                                         Float, Double, LongDouble, uuFloat80, uuFloat128,
     211                                         uFloat16, uFloat32, uFloat32x, uFloat64, uFloat64x, uFloat128, uFloat128x, NoBasicType };
    210212        static const char * basicTypeNames[];
    211         enum ComplexType { Complex, Imaginary, NoComplexType };
     213        enum ComplexType { Complex, NoComplexType, Imaginary }; // Imaginary unsupported => parse, but make invisible and print error message
    212214        static const char * complexTypeNames[];
    213215        enum Signedness { Signed, Unsigned, NoSignedness };
  • src/Parser/TypeData.cc

    r6a9d4b4 r933f32f  
    1010// Created On       : Sat May 16 15:12:51 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Nov  2 07:54:26 2018
    13 // Update Count     : 624
     12// Last Modified On : Wed Feb 13 18:16:23 2019
     13// Update Count     : 649
    1414//
    1515
     
    666666
    667667          case DeclarationNode::Float:
    668           case DeclarationNode::Float80:
    669           case DeclarationNode::Float128:
    670668          case DeclarationNode::Double:
    671669          case DeclarationNode::LongDouble:                                     // not set until below
    672                 static BasicType::Kind floattype[3][3] = {
    673                         { BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex },
    674                         { BasicType::FloatImaginary, BasicType::DoubleImaginary, BasicType::LongDoubleImaginary },
    675                         { BasicType::Float, BasicType::Double, BasicType::LongDouble },
     670          case DeclarationNode::uuFloat80:
     671          case DeclarationNode::uuFloat128:
     672          case DeclarationNode::uFloat16:
     673          case DeclarationNode::uFloat32:
     674          case DeclarationNode::uFloat32x:
     675          case DeclarationNode::uFloat64:
     676          case DeclarationNode::uFloat64x:
     677          case DeclarationNode::uFloat128:
     678          case DeclarationNode::uFloat128x:
     679                static BasicType::Kind floattype[2][12] = {
     680                        { BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, (BasicType::Kind)-1, (BasicType::Kind)-1, BasicType::uFloat16Complex, BasicType::uFloat32Complex, BasicType::uFloat32xComplex, BasicType::uFloat64Complex, BasicType::uFloat64xComplex, BasicType::uFloat128Complex, BasicType::uFloat128xComplex, },
     681                        { BasicType::Float, BasicType::Double, BasicType::LongDouble, BasicType::uuFloat80, BasicType::uuFloat128, BasicType::uFloat16, BasicType::uFloat32, BasicType::uFloat32x, BasicType::uFloat64, BasicType::uFloat64x, BasicType::uFloat128, BasicType::uFloat128x, },
    676682                };
    677683
     
    686692                        genTSError( DeclarationNode::lengthNames[ td->length ], td->basictype );
    687693                } // if
     694                if ( td->complextype == DeclarationNode::Imaginary ) {
     695                        genTSError( DeclarationNode::complexTypeNames[ td->complextype ], td->basictype );
     696                } // if
     697                if ( (td->basictype == DeclarationNode::uuFloat80 || td->basictype == DeclarationNode::uuFloat128) && td->complextype == DeclarationNode::Complex ) { // gcc unsupported
     698                        genTSError( DeclarationNode::complexTypeNames[ td->complextype ], td->basictype );
     699                } // if
    688700                if ( td->length == DeclarationNode::Long ) {
    689701                        const_cast<TypeData *>(td)->basictype = DeclarationNode::LongDouble;
    690702                } // if
    691703
    692                 if ( td->basictype == DeclarationNode::Float80 || td->basictype == DeclarationNode::Float128 ) {
    693                         // if ( td->complextype != DeclarationNode::NoComplexType ) {
    694                         //      genTSError( DeclarationNode::complexTypeNames[ td->complextype ], td->basictype );
    695                         // }
    696                         if ( td->basictype == DeclarationNode::Float80 ) ret = BasicType::Float80;
    697                         else ret = BasicType::Float128;
    698                         break;
    699                 }
    700 
    701704                ret = floattype[ td->complextype ][ td->basictype - DeclarationNode::Float ];
     705                //printf( "XXXX %d %d %d %d\n", td->complextype, td->basictype, DeclarationNode::Float, ret );
    702706                break;
    703707
  • src/Parser/TypeData.h

    r6a9d4b4 r933f32f  
    3131        struct Aggregate_t {
    3232                DeclarationNode::Aggregate kind;
    33                 const std::string * name;
    34                 DeclarationNode * params;
    35                 ExpressionNode * actuals;                                               // holds actual parameters later applied to AggInst
    36                 DeclarationNode * fields;
     33                const std::string * name = nullptr;
     34                DeclarationNode * params = nullptr;
     35                ExpressionNode * actuals = nullptr;                                             // holds actual parameters later applied to AggInst
     36                DeclarationNode * fields = nullptr;
    3737                bool body;
    3838                bool anon;
    3939
    4040                bool tagged;
    41                 const std::string * parent;
     41                const std::string * parent = nullptr;
    4242        };
    4343
    4444        struct AggInst_t {
    45                 TypeData * aggregate;
    46                 ExpressionNode * params;
     45                TypeData * aggregate = nullptr;
     46                ExpressionNode * params = nullptr;
    4747                bool hoistType;
    4848        };
    4949
    5050        struct Array_t {
    51                 ExpressionNode * dimension;
     51                ExpressionNode * dimension = nullptr;
    5252                bool isVarLen;
    5353                bool isStatic;
     
    5555
    5656        struct Enumeration_t {
    57                 const std::string * name;
    58                 DeclarationNode * constants;
     57                const std::string * name = nullptr;
     58                DeclarationNode * constants = nullptr;
    5959                bool body;
    6060                bool anon;
     
    6262
    6363        struct Function_t {
    64                 mutable DeclarationNode * params;                               // mutables modified in buildKRFunction
    65                 mutable DeclarationNode * idList;                               // old-style
    66                 mutable DeclarationNode * oldDeclList;
    67                 StatementNode * body;
    68                 ExpressionNode * withExprs;                                             // expressions from function's with_clause
     64                mutable DeclarationNode * params = nullptr;                             // mutables modified in buildKRFunction
     65                mutable DeclarationNode * idList = nullptr;                             // old-style
     66                mutable DeclarationNode * oldDeclList = nullptr;
     67                StatementNode * body = nullptr;
     68                ExpressionNode * withExprs = nullptr;                                           // expressions from function's with_clause
    6969        };
    7070
    7171        struct Symbolic_t {
    72                 const std::string * name;
     72                const std::string * name = nullptr;
    7373                bool isTypedef;                                                                 // false => TYPEGENname, true => TYPEDEFname
    74                 DeclarationNode * params;
    75                 ExpressionNode * actuals;
    76                 DeclarationNode * assertions;
     74                DeclarationNode * params = nullptr;
     75                ExpressionNode * actuals = nullptr;
     76                DeclarationNode * assertions = nullptr;
    7777        };
    7878
    7979        struct Qualified_t {                                                            // qualified type S.T
    80                 TypeData * parent;
    81                 TypeData * child;
     80                TypeData * parent = nullptr;
     81                TypeData * child = nullptr;
    8282        };
    8383
     
    9393
    9494        Type::Qualifiers qualifiers;
    95         DeclarationNode * forall;
     95        DeclarationNode * forall = nullptr;
    9696
    9797        Aggregate_t aggregate;
     
    102102        Symbolic_t symbolic;
    103103        Qualified_t qualified;
    104         DeclarationNode * tuple;
    105         ExpressionNode * typeexpr;
     104        DeclarationNode * tuple = nullptr;
     105        ExpressionNode * typeexpr = nullptr;
    106106
    107107        TypeData( Kind k = Unknown );
  • src/Parser/lex.ll

    r6a9d4b4 r933f32f  
    1010 * Created On       : Sat Sep 22 08:58:10 2001
    1111 * Last Modified By : Peter A. Buhr
    12  * Last Modified On : Thu Nov  1 20:57:35 2018
    13  * Update Count     : 687
     12 * Last Modified On : Wed May 15 21:25:27 2019
     13 * Update Count     : 708
    1414 */
    1515
     
    3939using namespace std;
    4040
     41#include "config.h"                                                                             // configure info
    4142#include "ParseNode.h"
    4243#include "TypedefTable.h"
     
    5960#define IDENTIFIER_RETURN()     RETURN_VAL( typedefTable.isKind( yytext ) )
    6061#define ATTRIBUTE_RETURN()      RETURN_VAL( ATTR_IDENTIFIER )
     62
     63#ifdef HAVE_KEYWORDS_FLOATXX                                                            // GCC >= 7 => keyword, otherwise typedef
     64#define FLOATXX(v) KEYWORD_RETURN(v);
     65#else
     66#define FLOATXX(v) IDENTIFIER_RETURN();
     67#endif // HAVE_KEYWORDS_FLOATXX
    6168
    6269void rm_underscore() {
     
    9299hex_quad {hex}("_"?{hex}){3}
    93100size_opt (8|16|32|64|128)?
    94 length ("ll"|"LL"|[lL]{size_opt})|("hh"|"HH"|[hH])
    95 integer_suffix_opt ("_"?(([uU]({length}?[iI]?)|([iI]{length}))|([iI]({length}?[uU]?)|([uU]{length}))|({length}([iI]?[uU]?)|([uU][iI]))|[zZ]))?
     101                                // CFA: explicit l8/l16/l32/l64/l128, char 'hh', short 'h', int 'n'
     102length ("ll"|"LL"|[lL]{size_opt})|("hh"|"HH"|[hHnN])
     103                                // CFA: size_t 'z', pointer 'p', which define a sign and length
     104integer_suffix_opt ("_"?(([uU]({length}?[iI]?)|([iI]{length}))|([iI]({length}?[uU]?)|([uU]{length}))|({length}([iI]?[uU]?)|([uU][iI]))|[zZ]|[pP]))?
    96105
    97106octal_digits ({octal})|({octal}({octal}|"_")*{octal})
     
    112121                                // GCC: D (double) and iI (imaginary) suffixes, and DL (long double)
    113122exponent "_"?[eE]"_"?[+-]?{decimal_digits}
    114 floating_size 32|64|80|128
    115 floating_length ([fFdDlL]|[lL]{floating_size})
     123floating_size 16|32|32x|64|64x|80|128|128x
     124floating_length ([fFdDlLwWqQ]|[fF]{floating_size})
    116125floating_suffix ({floating_length}?[iI]?)|([iI]{floating_length})
    117126floating_suffix_opt ("_"?({floating_suffix}|"DL"))?
     
    217226char                    { KEYWORD_RETURN(CHAR); }
    218227choose                  { KEYWORD_RETURN(CHOOSE); }                             // CFA
     228coerce                  { KEYWORD_RETURN(COERCE); }                             // CFA
    219229_Complex                { KEYWORD_RETURN(COMPLEX); }                    // C99
    220230__complex               { KEYWORD_RETURN(COMPLEX); }                    // GCC
     
    240250finally                 { KEYWORD_RETURN(FINALLY); }                    // CFA
    241251float                   { KEYWORD_RETURN(FLOAT); }
    242 _Float32                { KEYWORD_RETURN(FLOAT); }                              // GCC
    243 _Float32x               { KEYWORD_RETURN(FLOAT); }                              // GCC
    244 _Float64                { KEYWORD_RETURN(DOUBLE); }                             // GCC
    245 _Float64x               { KEYWORD_RETURN(DOUBLE); }                             // GCC
    246 __float80               { KEYWORD_RETURN(FLOAT80); }                    // GCC
    247 float80                 { KEYWORD_RETURN(FLOAT80); }                    // GCC
    248 _Float128               { KEYWORD_RETURN(FLOAT128); }                   // GCC
    249 _Float128x              { KEYWORD_RETURN(FLOAT128); }                   // GCC
    250 __float128              { KEYWORD_RETURN(FLOAT128); }                   // GCC
    251 float128                { KEYWORD_RETURN(FLOAT128); }                   // GCC
     252__float80               { KEYWORD_RETURN(uuFLOAT80); }                  // GCC
     253float80                 { KEYWORD_RETURN(uuFLOAT80); }                  // GCC
     254__float128              { KEYWORD_RETURN(uuFLOAT128); }                 // GCC
     255float128                { KEYWORD_RETURN(uuFLOAT128); }                 // GCC
     256_Float16                { FLOATXX(uFLOAT16); }                                  // GCC
     257_Float32                { FLOATXX(uFLOAT32); }                                  // GCC
     258_Float32x               { FLOATXX(uFLOAT32X); }                                 // GCC
     259_Float64                { FLOATXX(uFLOAT64); }                                  // GCC
     260_Float64x               { FLOATXX(uFLOAT64X); }                                 // GCC
     261_Float128               { FLOATXX(uFLOAT128); }                                 // GCC
     262_Float128x              { FLOATXX(uFLOAT128); }                                 // GCC
    252263for                             { KEYWORD_RETURN(FOR); }
    253264forall                  { KEYWORD_RETURN(FORALL); }                             // CFA
    254265fortran                 { KEYWORD_RETURN(FORTRAN); }
    255266ftype                   { KEYWORD_RETURN(FTYPE); }                              // CFA
     267generator               { KEYWORD_RETURN(GENERATOR); }                  // CFA
    256268_Generic                { KEYWORD_RETURN(GENERIC); }                    // C11
    257269goto                    { KEYWORD_RETURN(GOTO); }
  • src/Parser/module.mk

    r6a9d4b4 r933f32f  
    3131       Parser/parserutility.cc
    3232
     33SRCDEMANGLE += \
     34        Parser/LinkageSpec.cc
     35
     36
    3337MOSTLYCLEANFILES += Parser/lex.cc Parser/parser.cc Parser/parser.hh Parser/parser.output
  • src/Parser/parser.yy

    r6a9d4b4 r933f32f  
    1010// Created On       : Sat Sep  1 20:22:55 2001
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Nov  8 18:08:23 2018
    13 // Update Count     : 4052
     12// Last Modified On : Wed May 15 21:25:27 2019
     13// Update Count     : 4296
    1414//
    1515
     
    9999        // distribute declaration_specifier across all declared variables, e.g., static, const, __attribute__.
    100100        DeclarationNode * cur = declList, * cl = (new DeclarationNode)->addType( specifier );
    101         //cur->addType( specifier );
    102         for ( cur = dynamic_cast< DeclarationNode * >( cur->get_next() ); cur != nullptr; cur = dynamic_cast< DeclarationNode * >( cur->get_next() ) ) {
     101        for ( cur = dynamic_cast<DeclarationNode *>( cur->get_next() ); cur != nullptr; cur = dynamic_cast<DeclarationNode *>( cur->get_next() ) ) {
    103102                cl->cloneBaseType( cur );
    104103        } // for
    105104        declList->addType( cl );
    106 //      delete cl;
    107105        return declList;
    108106} // distAttr
     
    175173DeclarationNode * fieldDecl( DeclarationNode * typeSpec, DeclarationNode * fieldList ) {
    176174        if ( ! fieldList ) {                                                            // field declarator ?
    177                 if ( ! ( typeSpec->type && typeSpec->type->kind == TypeData::Aggregate ) ) {
     175                if ( ! ( typeSpec->type && (typeSpec->type->kind == TypeData::Aggregate || typeSpec->type->kind == TypeData::Enum) ) ) {
    178176                        stringstream ss;
    179177                        typeSpec->type->print( ss );
     
    187185
    188186ForCtrl * forCtrl( ExpressionNode * type, string * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {
    189         ConstantExpr * constant = dynamic_cast<ConstantExpr *>(type->get_expr());
     187        ConstantExpr * constant = dynamic_cast<ConstantExpr *>(type->expr.get());
    190188        if ( constant && (constant->get_constant()->get_value() == "0" || constant->get_constant()->get_value() == "1") ) {
    191189        type = new ExpressionNode( new CastExpr( maybeMoveBuild< Expression >(type), new BasicType( Type::Qualifiers(), BasicType::SignedInt ) ) );
     
    193191        return new ForCtrl(
    194192                distAttr( DeclarationNode::newTypeof( type, true ), DeclarationNode::newName( index )->addInitializer( new InitializerNode( start ) ) ),
    195                 new ExpressionNode( build_binary_val( compop, new ExpressionNode( build_varref( new string( *index ) ) ), comp ) ),
    196                 new ExpressionNode( build_binary_val( compop == OperKinds::LThan || compop == OperKinds::LEThan ? // choose += or -= for upto/downto
    197                                                                                           OperKinds::PlusAssn : OperKinds::MinusAssn, new ExpressionNode( build_varref( new string( *index ) ) ), inc ) ) );
     193                // NULL comp/inc => leave blank
     194                comp ? new ExpressionNode( build_binary_val( compop, new ExpressionNode( build_varref( new string( *index ) ) ), comp ) ) : 0,
     195                inc ? new ExpressionNode( build_binary_val( compop == OperKinds::LThan || compop == OperKinds::LEThan ? // choose += or -= for upto/downto
     196                                                        OperKinds::PlusAssn : OperKinds::MinusAssn, new ExpressionNode( build_varref( new string( *index ) ) ), inc ) ) : 0 );
    198197} // forCtrl
    199198
    200199ForCtrl * forCtrl( ExpressionNode * type, ExpressionNode * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {
    201         if ( NameExpr * identifier = dynamic_cast<NameExpr *>(index->get_expr()) ) {
     200        if ( NameExpr * identifier = dynamic_cast<NameExpr *>(index->expr.get()) ) {
    202201                return forCtrl( type, new string( identifier->name ), start, compop, comp, inc );
     202        } else if ( CommaExpr * commaExpr = dynamic_cast<CommaExpr *>(index->expr.get()) ) {
     203                if ( NameExpr * identifier = dynamic_cast<NameExpr *>(commaExpr->arg1 ) ) {
     204                        return forCtrl( type, new string( identifier->name ), start, compop, comp, inc );
     205                } else {
     206                        SemanticError( yylloc, "Expression disallowed. Only loop-index name allowed" ); return nullptr;
     207                } // if
    203208        } else {
    204209                SemanticError( yylloc, "Expression disallowed. Only loop-index name allowed" ); return nullptr;
     
    260265%token RESTRICT                                                                                 // C99
    261266%token ATOMIC                                                                                   // C11
    262 %token FORALL MUTEX VIRTUAL                                                             // CFA
     267%token FORALL MUTEX VIRTUAL COERCE                                              // CFA
    263268%token VOID CHAR SHORT INT LONG FLOAT DOUBLE SIGNED UNSIGNED
    264269%token BOOL COMPLEX IMAGINARY                                                   // C99
    265 %token INT128 FLOAT80 FLOAT128                                                  // GCC
     270%token INT128 uuFLOAT80 uuFLOAT128                                              // GCC
     271%token uFLOAT16 uFLOAT32 uFLOAT32X uFLOAT64 uFLOAT64X uFLOAT128 // GCC
    266272%token ZERO_T ONE_T                                                                             // CFA
    267273%token VALIST                                                                                   // GCC
     
    269275%token ENUM STRUCT UNION
    270276%token EXCEPTION                                                                                // CFA
    271 %token COROUTINE MONITOR THREAD                                                 // CFA
     277%token GENERATOR COROUTINE MONITOR THREAD                               // CFA
    272278%token OTYPE FTYPE DTYPE TTYPE TRAIT                                    // CFA
    273279%token SIZEOF OFFSETOF
     
    324330%type<en> argument_expression_list              argument_expression                     default_initialize_opt
    325331%type<ifctl> if_control_expression
    326 %type<fctl> for_control_expression
     332%type<fctl> for_control_expression              for_control_expression_list
    327333%type<compop> inclexcl
    328334%type<en> subrange
    329335%type<decl> asm_name_opt
    330 %type<en> asm_operands_opt asm_operands_list asm_operand
     336%type<en> asm_operands_opt                              asm_operands_list                       asm_operand
    331337%type<label> label_list
    332338%type<en> asm_clobbers_list_opt
    333339%type<flag> asm_volatile_opt
    334340%type<en> handler_predicate_opt
    335 %type<genexpr> generic_association generic_assoc_list
     341%type<genexpr> generic_association              generic_assoc_list
    336342
    337343// statements
     
    671677        // empty
    672678                { $$ = nullptr; }
    673         | '?'                                                                                           // CFA, default parameter
     679        | '@'                                                                                           // CFA, default parameter
    674680                { SemanticError( yylloc, "Default parameter for argument is currently unimplemented." ); $$ = nullptr; }
    675681                // { $$ = new ExpressionNode( build_constantInteger( *new string( "2" ) ) ); }
     
    789795        | '(' type_no_function ')' cast_expression
    790796                { $$ = new ExpressionNode( build_cast( $2, $4 ) ); }
     797                // keyword cast cannot be grouped because of reduction in aggregate_key
     798        | '(' GENERATOR '&' ')' cast_expression                         // CFA
     799                { $$ = new ExpressionNode( build_keyword_cast( KeywordCastExpr::Coroutine, $5 ) ); }
    791800        | '(' COROUTINE '&' ')' cast_expression                         // CFA
    792801                { $$ = new ExpressionNode( build_keyword_cast( KeywordCastExpr::Coroutine, $5 ) ); }
     
    800809        | '(' VIRTUAL type_no_function ')' cast_expression      // CFA
    801810                { $$ = new ExpressionNode( new VirtualCastExpr( maybeMoveBuild< Expression >( $5 ), maybeMoveBuildType( $3 ) ) ); }
     811        | '(' RETURN type_no_function ')' cast_expression       // CFA
     812                { SemanticError( yylloc, "Return cast is currently unimplemented." ); $$ = nullptr; }
     813        | '(' COERCE type_no_function ')' cast_expression       // CFA
     814                { SemanticError( yylloc, "Coerce cast is currently unimplemented." ); $$ = nullptr; }
     815        | '(' qualifier_cast_list ')' cast_expression           // CFA
     816                { SemanticError( yylloc, "Qualifier cast is currently unimplemented." ); $$ = nullptr; }
    802817//      | '(' type_no_function ')' tuple
    803818//              { $$ = new ExpressionNode( build_cast( $2, $4 ) ); }
     819        ;
     820
     821qualifier_cast_list:
     822        cast_modifier type_qualifier_name
     823        | cast_modifier MUTEX
     824        | qualifier_cast_list cast_modifier type_qualifier_name
     825        | qualifier_cast_list cast_modifier MUTEX
     826        ;
     827
     828cast_modifier:
     829        '-'
     830        | '+'
    804831        ;
    805832
     
    9841011                // labels cannot be identifiers 0 or 1 or ATTR_IDENTIFIER
    9851012        identifier_or_type_name ':' attribute_list_opt statement
    986                 {
    987                         $$ = $4->add_label( $1, $3 );
    988                 }
     1013                { $$ = $4->add_label( $1, $3 ); }
    9891014        ;
    9901015
     
    10021027        statement_decl
    10031028        | statement_decl_list statement_decl
    1004                 { if ( $1 != 0 ) { $1->set_last( $2 ); $$ = $1; } }
     1029                { assert( $1 ); $1->set_last( $2 ); $$ = $1; }
    10051030        ;
    10061031
     
    10091034                { $$ = new StatementNode( $1 ); }
    10101035        | EXTENSION declaration                                                         // GCC
    1011                 {
    1012                         distExt( $2 );
    1013                         $$ = new StatementNode( $2 );
    1014                 }
     1036                { distExt( $2 ); $$ = new StatementNode( $2 ); }
    10151037        | function_definition
    10161038                { $$ = new StatementNode( $1 ); }
    10171039        | EXTENSION function_definition                                         // GCC
    1018                 {
    1019                         distExt( $2 );
    1020                         $$ = new StatementNode( $2 );
    1021                 }
     1040                { distExt( $2 ); $$ = new StatementNode( $2 ); }
    10221041        | statement
    10231042        ;
     
    10261045        statement
    10271046        | statement_list_nodecl statement
    1028                 { if ( $1 != 0 ) { $1->set_last( $2 ); $$ = $1; } }
     1047                { assert( $1 ); $1->set_last( $2 ); $$ = $1; }
    10291048        ;
    10301049
     
    11381157        | DO statement WHILE '(' ')' ';'                                        // CFA => do while( 1 )
    11391158                { $$ = new StatementNode( build_do_while( new ExpressionNode( build_constantInteger( *new string( "1" ) ) ), $2 ) ); }
    1140         | FOR '(' push for_control_expression ')' statement pop
     1159        | FOR '(' push for_control_expression_list ')' statement pop
    11411160                { $$ = new StatementNode( build_for( $4, $6 ) ); }
    11421161        | FOR '(' ')' statement                                                         // CFA => for ( ;; )
     
    11441163        ;
    11451164
     1165for_control_expression_list:
     1166        for_control_expression
     1167        | for_control_expression_list ':' for_control_expression
     1168                // ForCtrl + ForCtrl:
     1169                //    init + init => multiple declaration statements that are hoisted
     1170                //    condition + condition => (expression) && (expression)
     1171                //    change + change => (expression), (expression)
     1172                {
     1173                        $1->init->set_last( $3->init );
     1174                        if ( $1->condition ) {
     1175                                if ( $3->condition ) {
     1176                                        $1->condition->expr.reset( new LogicalExpr( $1->condition->expr.release(), $3->condition->expr.release(), true ) );
     1177                                } // if
     1178                        } else $1->condition = $3->condition;
     1179                        if ( $1->change ) {
     1180                                if ( $3->change ) {
     1181                                        $1->change->expr.reset( new CommaExpr( $1->change->expr.release(), $3->change->expr.release() ) );
     1182                                } // if
     1183                        } else $1->change = $3->change;
     1184                        $$ = $1;
     1185                }
     1186        ;
     1187
    11461188for_control_expression:
    1147         comma_expression                                                                        // CFA
     1189        ';' comma_expression_opt ';' comma_expression_opt
     1190                { $$ = new ForCtrl( (ExpressionNode * )nullptr, $2, $4 ); }
     1191        | comma_expression ';' comma_expression_opt ';' comma_expression_opt
     1192                { $$ = new ForCtrl( $1, $3, $5 ); }
     1193        | declaration comma_expression_opt ';' comma_expression_opt // C99, declaration has ';'
     1194                { $$ = new ForCtrl( $1, $2, $4 ); }
     1195
     1196        | comma_expression                                                                      // CFA
    11481197                { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), new ExpressionNode( build_constantInteger( *new string( "0" ) ) ),
    11491198                                                OperKinds::LThan, $1->clone(), new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); }
    1150         | constant_expression inclexcl constant_expression      // CFA
     1199        | comma_expression inclexcl comma_expression            // CFA
    11511200                { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), $1->clone(), $2, $3, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); }
    1152         | constant_expression inclexcl constant_expression '~' constant_expression // CFA
     1201        | comma_expression inclexcl comma_expression '~' comma_expression // CFA
    11531202                { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), $1->clone(), $2, $3, $5 ); }
    11541203        | comma_expression ';' comma_expression                         // CFA
    11551204                { $$ = forCtrl( $3, $1, new ExpressionNode( build_constantInteger( *new string( "0" ) ) ),
    11561205                                                OperKinds::LThan, $3->clone(), new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); }
    1157         | comma_expression ';' constant_expression inclexcl constant_expression // CFA
     1206        | comma_expression ';' comma_expression inclexcl comma_expression // CFA
    11581207                { $$ = forCtrl( $3, $1, $3->clone(), $4, $5, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); }
    1159         | comma_expression ';' constant_expression inclexcl constant_expression '~' constant_expression // CFA
     1208        | comma_expression ';' comma_expression inclexcl comma_expression '~' comma_expression // CFA
    11601209                { $$ = forCtrl( $3, $1, $3->clone(), $4, $5, $7 ); }
    1161         | comma_expression ';' comma_expression_opt ';' comma_expression_opt
    1162                 { $$ = new ForCtrl( $1, $3, $5 ); }
    1163         | ';' comma_expression_opt ';' comma_expression_opt
    1164                 { $$ = new ForCtrl( (ExpressionNode * )nullptr, $2, $4 ); }
    1165         | declaration comma_expression_opt ';' comma_expression_opt // C99, declaration has ';'
    1166                 { $$ = new ForCtrl( $1, $2, $4 ); }
     1210
     1211                // There is a S/R conflicit if ~ and -~ are factored out.
     1212        | comma_expression ';' comma_expression '~' '@'         // CFA
     1213                { $$ = forCtrl( $3, $1, $3->clone(), OperKinds::LThan, nullptr, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); }
     1214        | comma_expression ';' comma_expression ErangeDown '@' // CFA
     1215                { $$ = forCtrl( $3, $1, $3->clone(), OperKinds::GThan, nullptr, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); }
     1216        | comma_expression ';' comma_expression '~' '@' '~' comma_expression // CFA
     1217                { $$ = forCtrl( $3, $1, $3->clone(), OperKinds::LThan, nullptr, $7 ); }
     1218        | comma_expression ';' comma_expression ErangeDown '@' '~' comma_expression // CFA
     1219                { $$ = forCtrl( $3, $1, $3->clone(), OperKinds::GThan, nullptr, $7 ); }
     1220        | comma_expression ';' comma_expression '~' '@' '~' '@' // CFA
     1221                { $$ = forCtrl( $3, $1, $3->clone(), OperKinds::LThan, nullptr, nullptr ); }
    11671222        ;
    11681223
     
    17711826        | FLOAT
    17721827                { $$ = DeclarationNode::newBasicType( DeclarationNode::Float ); }
    1773         | FLOAT80
    1774                 { $$ = DeclarationNode::newBasicType( DeclarationNode::Float80 ); }
    1775         | FLOAT128
    1776                 { $$ = DeclarationNode::newBasicType( DeclarationNode::Float128 ); }
    17771828        | DOUBLE
    17781829                { $$ = DeclarationNode::newBasicType( DeclarationNode::Double ); }
     1830        | uuFLOAT80
     1831                { $$ = DeclarationNode::newBasicType( DeclarationNode::uuFloat80 ); }
     1832        | uuFLOAT128
     1833                { $$ = DeclarationNode::newBasicType( DeclarationNode::uuFloat128 ); }
     1834        | uFLOAT16
     1835                { $$ = DeclarationNode::newBasicType( DeclarationNode::uFloat16 ); }
     1836        | uFLOAT32
     1837                { $$ = DeclarationNode::newBasicType( DeclarationNode::uFloat32 ); }
     1838        | uFLOAT32X
     1839                { $$ = DeclarationNode::newBasicType( DeclarationNode::uFloat32x ); }
     1840        | uFLOAT64
     1841                { $$ = DeclarationNode::newBasicType( DeclarationNode::uFloat64 ); }
     1842        | uFLOAT64X
     1843                { $$ = DeclarationNode::newBasicType( DeclarationNode::uFloat64x ); }
     1844        | uFLOAT128
     1845                { $$ = DeclarationNode::newBasicType( DeclarationNode::uFloat128 ); }
    17791846        | COMPLEX                                                                                       // C99
    17801847                { $$ = DeclarationNode::newComplexType( DeclarationNode::Complex ); }
     
    19962063        | EXCEPTION
    19972064                { yyy = true; $$ = DeclarationNode::Exception; }
     2065        | GENERATOR
     2066                { yyy = true; $$ = DeclarationNode::Coroutine; }
    19982067        | COROUTINE
    19992068                { yyy = true; $$ = DeclarationNode::Coroutine; }
  • src/ResolvExpr/AlternativeFinder.cc

    r6a9d4b4 r933f32f  
    258258                        // - necessary pre-requisite to pruning
    259259                        AltList candidates;
     260                        std::list<std::string> errors;
    260261                        for ( unsigned i = 0; i < alternatives.size(); ++i ) {
    261                                 resolveAssertions( alternatives[i], indexer, candidates );
     262                                resolveAssertions( alternatives[i], indexer, candidates, errors );
    262263                        }
    263264                        // fail early if none such
    264265                        if ( mode.failFast && candidates.empty() ) {
    265266                                std::ostringstream stream;
    266                                 stream << "No resolvable alternatives for expression " << expr << "\n"
    267                                        << "Alternatives with failing assertions are:\n";
    268                                 printAlts( alternatives, stream, 1 );
     267                                stream << "No alternatives with satisfiable assertions for " << expr << "\n";
     268                                //        << "Alternatives with failing assertions are:\n";
     269                                // printAlts( alternatives, stream, 1 );
     270                                for ( const auto& err : errors ) {
     271                                        stream << err;
     272                                }
    269273                                SemanticError( expr->location, stream.str() );
    270274                        }
  • src/ResolvExpr/CommonType.cc

    r6a9d4b4 r933f32f  
    1010// Created On       : Sun May 17 06:59:27 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Sep 25 15:18:17 2017
    13 // Update Count     : 9
     12// Last Modified On : Thu Feb 14 17:10:10 2019
     13// Update Count     : 24
    1414//
    1515
     
    176176        }
    177177
    178         static const BasicType::Kind combinedType[][ BasicType::NUMBER_OF_BASIC_TYPES ] =
    179         {
    180 /*              Bool            Char    SignedChar      UnsignedChar    ShortSignedInt  ShortUnsignedInt        SignedInt       UnsignedInt     LongSignedInt   LongUnsignedInt LongLongSignedInt       LongLongUnsignedInt     Float   Double  LongDouble      FloatComplex    DoubleComplex   LongDoubleComplex       FloatImaginary  DoubleImaginary LongDoubleImaginary   SignedInt128   UnsignedInt128   Float80   Float128 */
    181                 /* Bool */      { BasicType::Bool,              BasicType::Char,        BasicType::SignedChar,  BasicType::UnsignedChar,        BasicType::ShortSignedInt,      BasicType::ShortUnsignedInt,    BasicType::SignedInt,   BasicType::UnsignedInt, BasicType::LongSignedInt,       BasicType::LongUnsignedInt,     BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::SignedInt128,        BasicType::UnsignedInt128, BasicType::Float80, BasicType::Float128 },
    182                 /* Char */      { BasicType::Char,              BasicType::Char,        BasicType::UnsignedChar,        BasicType::UnsignedChar,        BasicType::ShortSignedInt,      BasicType::ShortUnsignedInt,    BasicType::SignedInt,   BasicType::UnsignedInt, BasicType::LongSignedInt,       BasicType::LongUnsignedInt,     BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::SignedInt128,        BasicType::UnsignedInt128, BasicType::Float80, BasicType::Float128 },
    183                 /* SignedChar */        { BasicType::SignedChar,        BasicType::UnsignedChar,        BasicType::SignedChar,  BasicType::UnsignedChar,        BasicType::ShortSignedInt,      BasicType::ShortUnsignedInt,    BasicType::SignedInt,   BasicType::UnsignedInt, BasicType::LongSignedInt,       BasicType::LongUnsignedInt,     BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::SignedInt128,        BasicType::UnsignedInt128, BasicType::Float80, BasicType::Float128 },
    184                 /* UnsignedChar */      { BasicType::UnsignedChar,      BasicType::UnsignedChar,        BasicType::UnsignedChar,        BasicType::UnsignedChar,        BasicType::ShortSignedInt,      BasicType::ShortUnsignedInt,    BasicType::SignedInt,   BasicType::UnsignedInt, BasicType::LongSignedInt,       BasicType::LongUnsignedInt,     BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::SignedInt128,        BasicType::UnsignedInt128, BasicType::Float80, BasicType::Float128 },
    185                 /* ShortSignedInt */    { BasicType::ShortSignedInt,    BasicType::ShortSignedInt,      BasicType::ShortSignedInt,      BasicType::ShortSignedInt,      BasicType::ShortSignedInt,      BasicType::ShortUnsignedInt,    BasicType::SignedInt,   BasicType::UnsignedInt, BasicType::LongSignedInt,       BasicType::LongUnsignedInt,     BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::SignedInt128,        BasicType::UnsignedInt128, BasicType::Float80, BasicType::Float128 },
    186                 /* ShortUnsignedInt */  { BasicType::ShortUnsignedInt,  BasicType::ShortUnsignedInt,    BasicType::ShortUnsignedInt,    BasicType::ShortUnsignedInt,    BasicType::ShortUnsignedInt,    BasicType::ShortUnsignedInt,    BasicType::SignedInt,   BasicType::UnsignedInt, BasicType::LongSignedInt,       BasicType::LongUnsignedInt,     BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::SignedInt128,        BasicType::UnsignedInt128, BasicType::Float80, BasicType::Float128 },
    187                 /* SignedInt */         { BasicType::SignedInt,         BasicType::SignedInt,   BasicType::SignedInt,   BasicType::SignedInt,   BasicType::SignedInt,   BasicType::SignedInt,   BasicType::SignedInt,   BasicType::UnsignedInt, BasicType::LongSignedInt,       BasicType::LongUnsignedInt,     BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::SignedInt128,        BasicType::UnsignedInt128, BasicType::Float80, BasicType::Float128 },
    188                 /* UnsignedInt */       { BasicType::UnsignedInt,               BasicType::UnsignedInt, BasicType::UnsignedInt, BasicType::UnsignedInt, BasicType::UnsignedInt, BasicType::UnsignedInt, BasicType::UnsignedInt, BasicType::UnsignedInt, BasicType::LongUnsignedInt,     BasicType::LongUnsignedInt,     BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::SignedInt128,        BasicType::UnsignedInt128, BasicType::Float80, BasicType::Float128 },
    189                 /* LongSignedInt */     { BasicType::LongSignedInt,             BasicType::LongSignedInt,       BasicType::LongSignedInt,       BasicType::LongSignedInt,       BasicType::LongSignedInt,       BasicType::LongSignedInt,       BasicType::LongSignedInt,       BasicType::LongUnsignedInt,     BasicType::LongSignedInt,       BasicType::LongUnsignedInt,     BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::SignedInt128,        BasicType::UnsignedInt128, BasicType::Float80, BasicType::Float128 },
    190                 /* LongUnsignedInt */   { BasicType::LongUnsignedInt,   BasicType::LongUnsignedInt,     BasicType::LongUnsignedInt,     BasicType::LongUnsignedInt,     BasicType::LongUnsignedInt,     BasicType::LongUnsignedInt,     BasicType::LongUnsignedInt,     BasicType::LongUnsignedInt,     BasicType::LongUnsignedInt,     BasicType::LongUnsignedInt,     BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::SignedInt128,        BasicType::UnsignedInt128, BasicType::Float80, BasicType::Float128 },
    191                 /* LongLongSignedInt */         { BasicType::LongLongSignedInt, BasicType::LongLongSignedInt,   BasicType::LongLongSignedInt,   BasicType::LongLongSignedInt,   BasicType::LongLongSignedInt,   BasicType::LongLongSignedInt,   BasicType::LongLongSignedInt,   BasicType::LongLongSignedInt,   BasicType::LongLongSignedInt,   BasicType::LongLongSignedInt,   BasicType::LongLongSignedInt,   BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::SignedInt128,        BasicType::UnsignedInt128, BasicType::Float80, BasicType::Float128 },
    192                 /* LongLongUnsignedInt */       { BasicType::LongLongUnsignedInt,       BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::SignedInt128,        BasicType::UnsignedInt128, BasicType::Float80, BasicType::Float128 },
    193                 /* Float */     { BasicType::Float,     BasicType::Float,       BasicType::Float,       BasicType::Float,       BasicType::Float,       BasicType::Float,       BasicType::Float,       BasicType::Float,       BasicType::Float,       BasicType::Float,       BasicType::Float,       BasicType::Float,       BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::Float,       BasicType::Float, BasicType::Float80, BasicType::Float128 },
    194                 /* Double */    { BasicType::Double,    BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::Double,      BasicType::LongDouble,  BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::Double,      BasicType::Double, BasicType::Float80, BasicType::Float128 },
    195                 /* LongDouble */        { BasicType::LongDouble,                BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDouble,  BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDouble,  BasicType::LongDouble, BasicType::BasicType::LongDouble, BasicType::Float128 },
    196                 /* FloatComplex */      { BasicType::FloatComplex,      BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::FloatComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, },
    197                 /* DoubleComplex */     { BasicType::DoubleComplex,     BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::DoubleComplex,       BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex },
    198                 /* LongDoubleComplex */         { BasicType::LongDoubleComplex, BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, BasicType::LongDoubleComplex, },
    199                 /* FloatImaginary */    { BasicType::FloatComplex,      BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatImaginary,      BasicType::DoubleImaginary,     BasicType::LongDoubleImaginary, BasicType::FloatImaginary,      BasicType::FloatImaginary, BasicType::LongDoubleImaginary, BasicType::LongDoubleImaginary, },
    200                 /* DoubleImaginary */   { BasicType::DoubleComplex,     BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::DoubleComplex,       BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::DoubleImaginary,     BasicType::DoubleImaginary,     BasicType::LongDoubleImaginary, BasicType::DoubleImaginary,     BasicType::DoubleImaginary, BasicType::LongDoubleImaginary, BasicType::LongDoubleImaginary, },
    201                 /* LongDoubleImaginary */       { BasicType::LongDoubleComplex, BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleImaginary, BasicType::LongDoubleImaginary, BasicType::LongDoubleImaginary, BasicType::LongDoubleImaginary, BasicType::LongDoubleImaginary, },
    202                 /* SignedInt128 */      { BasicType::SignedInt128,      BasicType::SignedInt128,        BasicType::SignedInt128,        BasicType::SignedInt128,        BasicType::SignedInt128,        BasicType::SignedInt128,        BasicType::SignedInt128,        BasicType::SignedInt128,        BasicType::SignedInt128,        BasicType::SignedInt128,        BasicType::SignedInt128,        BasicType::SignedInt128,        BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::SignedInt128,        BasicType::UnsignedInt128, BasicType::Float80, BasicType::Float128, },
    203                 /* UnsignedInt128 */    { BasicType::UnsignedInt128,    BasicType::UnsignedInt128,      BasicType::UnsignedInt128,      BasicType::UnsignedInt128,      BasicType::UnsignedInt128,      BasicType::UnsignedInt128,      BasicType::UnsignedInt128,      BasicType::UnsignedInt128,      BasicType::UnsignedInt128,      BasicType::UnsignedInt128,      BasicType::UnsignedInt128,      BasicType::UnsignedInt128,      BasicType::Float,       BasicType::Double,      BasicType::LongDouble,  BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::FloatComplex,        BasicType::DoubleComplex,       BasicType::LongDoubleComplex,   BasicType::UnsignedInt128,      BasicType::UnsignedInt128, BasicType::Float80, BasicType::Float128, },
    204                 /* Float80 */   { BasicType::Float80,   BasicType::Float80,     BasicType::Float80,     BasicType::Float80,     BasicType::Float80,     BasicType::Float80,     BasicType::Float80,     BasicType::Float80,     BasicType::Float80,     BasicType::Float80,     BasicType::Float80,     BasicType::Float80,     BasicType::Float80,     BasicType::Float80,     BasicType::LongDouble,  BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::Float80,     BasicType::Float80, BasicType::Float80, BasicType::Float128 },
    205                 /* Float128 */  { BasicType::Float128,  BasicType::Float128,    BasicType::Float128,    BasicType::Float128,    BasicType::Float128,    BasicType::Float128,    BasicType::Float128,    BasicType::Float128,    BasicType::Float128,    BasicType::Float128,    BasicType::Float128,    BasicType::Float128,    BasicType::Float128,    BasicType::Float128,    BasicType::Float128,    BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::LongDoubleComplex,   BasicType::Float128,    BasicType::Float128, BasicType::Float128, BasicType::Float128 },
    206         };
     178        // GENERATED START, DO NOT EDIT
     179        // GENERATED BY BasicTypes-gen.cc
     180        #define BT BasicType::
     181        static const BasicType::Kind commonTypes[BasicType::NUMBER_OF_BASIC_TYPES][BasicType::NUMBER_OF_BASIC_TYPES] = { // nearest common ancestor
     182                /*                                      B                       C                      SC                      UC                      SI                     SUI
     183                                                        I                      UI                      LI                     LUI                     LLI                    LLUI
     184                                                       IB                     UIB                     _FH                     _FH                      _F                     _FC
     185                                                        F                      FC                     _FX                    _FXC                      FD                    _FDC
     186                                                        D                      DC                    F80X                   _FDXC                     F80                     _FB
     187                                                    _FLDC                      FB                      LD                     LDC                    _FBX                  _FLDXC
     188                                 */
     189                                  {
     190                /*     B*/                BT Bool,                BT Char,          BT SignedChar,        BT UnsignedChar,      BT ShortSignedInt,    BT ShortUnsignedInt,
     191                                             BT SignedInt,         BT UnsignedInt,       BT LongSignedInt,     BT LongUnsignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
     192                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     193                                                 BT Float,        BT FloatComplex,           BT uFloat32x,    BT uFloat32xComplex,            BT uFloat64,     BT uFloat64Complex,
     194                                                BT Double,       BT DoubleComplex,           BT uFloat64x,    BT uFloat64xComplex,           BT uuFloat80,           BT uFloat128,
     195                                      BT uFloat128Complex,          BT uuFloat128,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
     196                                  },
     197                                  {
     198                /*     C*/                BT Char,                BT Char,          BT SignedChar,        BT UnsignedChar,      BT ShortSignedInt,    BT ShortUnsignedInt,
     199                                             BT SignedInt,         BT UnsignedInt,       BT LongSignedInt,     BT LongUnsignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
     200                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     201                                                 BT Float,        BT FloatComplex,           BT uFloat32x,    BT uFloat32xComplex,            BT uFloat64,     BT uFloat64Complex,
     202                                                BT Double,       BT DoubleComplex,           BT uFloat64x,    BT uFloat64xComplex,           BT uuFloat80,           BT uFloat128,
     203                                      BT uFloat128Complex,          BT uuFloat128,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
     204                                  },
     205                                  {
     206                /*    SC*/          BT SignedChar,          BT SignedChar,          BT SignedChar,        BT UnsignedChar,      BT ShortSignedInt,    BT ShortUnsignedInt,
     207                                             BT SignedInt,         BT UnsignedInt,       BT LongSignedInt,     BT LongUnsignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
     208                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     209                                                 BT Float,        BT FloatComplex,           BT uFloat32x,    BT uFloat32xComplex,            BT uFloat64,     BT uFloat64Complex,
     210                                                BT Double,       BT DoubleComplex,           BT uFloat64x,    BT uFloat64xComplex,           BT uuFloat80,           BT uFloat128,
     211                                      BT uFloat128Complex,          BT uuFloat128,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
     212                                  },
     213                                  {
     214                /*    UC*/        BT UnsignedChar,        BT UnsignedChar,        BT UnsignedChar,        BT UnsignedChar,      BT ShortSignedInt,    BT ShortUnsignedInt,
     215                                             BT SignedInt,         BT UnsignedInt,       BT LongSignedInt,     BT LongUnsignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
     216                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     217                                                 BT Float,        BT FloatComplex,           BT uFloat32x,    BT uFloat32xComplex,            BT uFloat64,     BT uFloat64Complex,
     218                                                BT Double,       BT DoubleComplex,           BT uFloat64x,    BT uFloat64xComplex,           BT uuFloat80,           BT uFloat128,
     219                                      BT uFloat128Complex,          BT uuFloat128,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
     220                                  },
     221                                  {
     222                /*    SI*/      BT ShortSignedInt,      BT ShortSignedInt,      BT ShortSignedInt,      BT ShortSignedInt,      BT ShortSignedInt,    BT ShortUnsignedInt,
     223                                             BT SignedInt,         BT UnsignedInt,       BT LongSignedInt,     BT LongUnsignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
     224                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     225                                                 BT Float,        BT FloatComplex,           BT uFloat32x,    BT uFloat32xComplex,            BT uFloat64,     BT uFloat64Complex,
     226                                                BT Double,       BT DoubleComplex,           BT uFloat64x,    BT uFloat64xComplex,           BT uuFloat80,           BT uFloat128,
     227                                      BT uFloat128Complex,          BT uuFloat128,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
     228                                  },
     229                                  {
     230                /*   SUI*/    BT ShortUnsignedInt,    BT ShortUnsignedInt,    BT ShortUnsignedInt,    BT ShortUnsignedInt,    BT ShortUnsignedInt,    BT ShortUnsignedInt,
     231                                             BT SignedInt,         BT UnsignedInt,       BT LongSignedInt,     BT LongUnsignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
     232                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     233                                                 BT Float,        BT FloatComplex,           BT uFloat32x,    BT uFloat32xComplex,            BT uFloat64,     BT uFloat64Complex,
     234                                                BT Double,       BT DoubleComplex,           BT uFloat64x,    BT uFloat64xComplex,           BT uuFloat80,           BT uFloat128,
     235                                      BT uFloat128Complex,          BT uuFloat128,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
     236                                  },
     237                                  {
     238                /*     I*/           BT SignedInt,           BT SignedInt,           BT SignedInt,           BT SignedInt,           BT SignedInt,           BT SignedInt,
     239                                             BT SignedInt,         BT UnsignedInt,       BT LongSignedInt,     BT LongUnsignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
     240                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     241                                                 BT Float,        BT FloatComplex,           BT uFloat32x,    BT uFloat32xComplex,            BT uFloat64,     BT uFloat64Complex,
     242                                                BT Double,       BT DoubleComplex,           BT uFloat64x,    BT uFloat64xComplex,           BT uuFloat80,           BT uFloat128,
     243                                      BT uFloat128Complex,          BT uuFloat128,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
     244                                  },
     245                                  {
     246                /*    UI*/         BT UnsignedInt,         BT UnsignedInt,         BT UnsignedInt,         BT UnsignedInt,         BT UnsignedInt,         BT UnsignedInt,
     247                                           BT UnsignedInt,         BT UnsignedInt,       BT LongSignedInt,     BT LongUnsignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
     248                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     249                                                 BT Float,        BT FloatComplex,           BT uFloat32x,    BT uFloat32xComplex,            BT uFloat64,     BT uFloat64Complex,
     250                                                BT Double,       BT DoubleComplex,           BT uFloat64x,    BT uFloat64xComplex,           BT uuFloat80,           BT uFloat128,
     251                                      BT uFloat128Complex,          BT uuFloat128,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
     252                                  },
     253                                  {
     254                /*    LI*/       BT LongSignedInt,       BT LongSignedInt,       BT LongSignedInt,       BT LongSignedInt,       BT LongSignedInt,       BT LongSignedInt,
     255                                         BT LongSignedInt,       BT LongSignedInt,       BT LongSignedInt,     BT LongUnsignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
     256                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     257                                                 BT Float,        BT FloatComplex,           BT uFloat32x,    BT uFloat32xComplex,            BT uFloat64,     BT uFloat64Complex,
     258                                                BT Double,       BT DoubleComplex,           BT uFloat64x,    BT uFloat64xComplex,           BT uuFloat80,           BT uFloat128,
     259                                      BT uFloat128Complex,          BT uuFloat128,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
     260                                  },
     261                                  {
     262                /*   LUI*/     BT LongUnsignedInt,     BT LongUnsignedInt,     BT LongUnsignedInt,     BT LongUnsignedInt,     BT LongUnsignedInt,     BT LongUnsignedInt,
     263                                       BT LongUnsignedInt,     BT LongUnsignedInt,     BT LongUnsignedInt,     BT LongUnsignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
     264                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     265                                                 BT Float,        BT FloatComplex,           BT uFloat32x,    BT uFloat32xComplex,            BT uFloat64,     BT uFloat64Complex,
     266                                                BT Double,       BT DoubleComplex,           BT uFloat64x,    BT uFloat64xComplex,           BT uuFloat80,           BT uFloat128,
     267                                      BT uFloat128Complex,          BT uuFloat128,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
     268                                  },
     269                                  {
     270                /*   LLI*/   BT LongLongSignedInt,   BT LongLongSignedInt,   BT LongLongSignedInt,   BT LongLongSignedInt,   BT LongLongSignedInt,   BT LongLongSignedInt,
     271                                     BT LongLongSignedInt,   BT LongLongSignedInt,   BT LongLongSignedInt,   BT LongLongSignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
     272                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     273                                                 BT Float,        BT FloatComplex,           BT uFloat32x,    BT uFloat32xComplex,            BT uFloat64,     BT uFloat64Complex,
     274                                                BT Double,       BT DoubleComplex,           BT uFloat64x,    BT uFloat64xComplex,           BT uuFloat80,           BT uFloat128,
     275                                      BT uFloat128Complex,          BT uuFloat128,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
     276                                  },
     277                                  {
     278                /*  LLUI*/ BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt,
     279                                   BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt,
     280                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     281                                                 BT Float,        BT FloatComplex,           BT uFloat32x,    BT uFloat32xComplex,            BT uFloat64,     BT uFloat64Complex,
     282                                                BT Double,       BT DoubleComplex,           BT uFloat64x,    BT uFloat64xComplex,           BT uuFloat80,           BT uFloat128,
     283                                      BT uFloat128Complex,          BT uuFloat128,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
     284                                  },
     285                                  {
     286                /*    IB*/        BT SignedInt128,        BT SignedInt128,        BT SignedInt128,        BT SignedInt128,        BT SignedInt128,        BT SignedInt128,
     287                                          BT SignedInt128,        BT SignedInt128,        BT SignedInt128,        BT SignedInt128,        BT SignedInt128,        BT SignedInt128,
     288                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     289                                                 BT Float,        BT FloatComplex,           BT uFloat32x,    BT uFloat32xComplex,            BT uFloat64,     BT uFloat64Complex,
     290                                                BT Double,       BT DoubleComplex,           BT uFloat64x,    BT uFloat64xComplex,           BT uuFloat80,           BT uFloat128,
     291                                      BT uFloat128Complex,          BT uuFloat128,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
     292                                  },
     293                                  {
     294                /*   UIB*/      BT UnsignedInt128,      BT UnsignedInt128,      BT UnsignedInt128,      BT UnsignedInt128,      BT UnsignedInt128,      BT UnsignedInt128,
     295                                        BT UnsignedInt128,      BT UnsignedInt128,      BT UnsignedInt128,      BT UnsignedInt128,      BT UnsignedInt128,      BT UnsignedInt128,
     296                                        BT UnsignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     297                                                 BT Float,        BT FloatComplex,           BT uFloat32x,    BT uFloat32xComplex,            BT uFloat64,     BT uFloat64Complex,
     298                                                BT Double,       BT DoubleComplex,           BT uFloat64x,    BT uFloat64xComplex,           BT uuFloat80,           BT uFloat128,
     299                                      BT uFloat128Complex,          BT uuFloat128,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
     300                                  },
     301                                  {
     302                /*   _FH*/            BT uFloat16,            BT uFloat16,            BT uFloat16,            BT uFloat16,            BT uFloat16,            BT uFloat16,
     303                                              BT uFloat16,            BT uFloat16,            BT uFloat16,            BT uFloat16,            BT uFloat16,            BT uFloat16,
     304                                              BT uFloat16,            BT uFloat16,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     305                                                 BT Float,        BT FloatComplex,           BT uFloat32x,    BT uFloat32xComplex,            BT uFloat64,     BT uFloat64Complex,
     306                                                BT Double,       BT DoubleComplex,           BT uFloat64x,    BT uFloat64xComplex,           BT uuFloat80,           BT uFloat128,
     307                                      BT uFloat128Complex,          BT uuFloat128,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
     308                                  },
     309                                  {
     310                /*   _FH*/     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,
     311                                       BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,
     312                                       BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat32Complex,     BT uFloat32Complex,
     313                                          BT FloatComplex,        BT FloatComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,     BT uFloat64Complex,     BT uFloat64Complex,
     314                                         BT DoubleComplex,       BT DoubleComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat128Complex,
     315                                      BT uFloat128Complex,    BT uFloat128Complex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,
     316                                  },
     317                                  {
     318                /*    _F*/            BT uFloat32,            BT uFloat32,            BT uFloat32,            BT uFloat32,            BT uFloat32,            BT uFloat32,
     319                                              BT uFloat32,            BT uFloat32,            BT uFloat32,            BT uFloat32,            BT uFloat32,            BT uFloat32,
     320                                              BT uFloat32,            BT uFloat32,            BT uFloat32,     BT uFloat32Complex,            BT uFloat32,     BT uFloat32Complex,
     321                                                 BT Float,        BT FloatComplex,           BT uFloat32x,    BT uFloat32xComplex,            BT uFloat64,     BT uFloat64Complex,
     322                                                BT Double,       BT DoubleComplex,           BT uFloat64x,    BT uFloat64xComplex,           BT uuFloat80,           BT uFloat128,
     323                                      BT uFloat128Complex,          BT uuFloat128,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
     324                                  },
     325                                  {
     326                /*   _FC*/     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,
     327                                       BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,
     328                                       BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,
     329                                          BT FloatComplex,        BT FloatComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,     BT uFloat64Complex,     BT uFloat64Complex,
     330                                         BT DoubleComplex,       BT DoubleComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat128Complex,
     331                                      BT uFloat128Complex,    BT uFloat128Complex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,
     332                                  },
     333                                  {
     334                /*     F*/               BT Float,               BT Float,               BT Float,               BT Float,               BT Float,               BT Float,
     335                                                 BT Float,               BT Float,               BT Float,               BT Float,               BT Float,               BT Float,
     336                                                 BT Float,               BT Float,               BT Float,        BT FloatComplex,               BT Float,        BT FloatComplex,
     337                                                 BT Float,        BT FloatComplex,           BT uFloat32x,    BT uFloat32xComplex,            BT uFloat64,     BT uFloat64Complex,
     338                                                BT Double,       BT DoubleComplex,           BT uFloat64x,    BT uFloat64xComplex,           BT uuFloat80,           BT uFloat128,
     339                                      BT uFloat128Complex,          BT uuFloat128,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
     340                                  },
     341                                  {
     342                /*    FC*/        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,
     343                                          BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,
     344                                          BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,
     345                                          BT FloatComplex,        BT FloatComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,     BT uFloat64Complex,     BT uFloat64Complex,
     346                                         BT DoubleComplex,       BT DoubleComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat128Complex,
     347                                      BT uFloat128Complex,    BT uFloat128Complex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,
     348                                  },
     349                                  {
     350                /*   _FX*/           BT uFloat32x,           BT uFloat32x,           BT uFloat32x,           BT uFloat32x,           BT uFloat32x,           BT uFloat32x,
     351                                             BT uFloat32x,           BT uFloat32x,           BT uFloat32x,           BT uFloat32x,           BT uFloat32x,           BT uFloat32x,
     352                                             BT uFloat32x,           BT uFloat32x,           BT uFloat32x,    BT uFloat32xComplex,           BT uFloat32x,    BT uFloat32xComplex,
     353                                             BT uFloat32x,    BT uFloat32xComplex,           BT uFloat32x,    BT uFloat32xComplex,            BT uFloat64,     BT uFloat64Complex,
     354                                                BT Double,       BT DoubleComplex,           BT uFloat64x,    BT uFloat64xComplex,           BT uuFloat80,           BT uFloat128,
     355                                      BT uFloat128Complex,          BT uuFloat128,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
     356                                  },
     357                                  {
     358                /*  _FXC*/    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,
     359                                      BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,
     360                                      BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,
     361                                      BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,     BT uFloat64Complex,     BT uFloat64Complex,
     362                                         BT DoubleComplex,       BT DoubleComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat128Complex,
     363                                      BT uFloat128Complex,    BT uFloat128Complex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,
     364                                  },
     365                                  {
     366                /*    FD*/            BT uFloat64,            BT uFloat64,            BT uFloat64,            BT uFloat64,            BT uFloat64,            BT uFloat64,
     367                                              BT uFloat64,            BT uFloat64,            BT uFloat64,            BT uFloat64,            BT uFloat64,            BT uFloat64,
     368                                              BT uFloat64,            BT uFloat64,            BT uFloat64,     BT uFloat64Complex,            BT uFloat64,     BT uFloat64Complex,
     369                                              BT uFloat64,     BT uFloat64Complex,            BT uFloat64,     BT uFloat64Complex,            BT uFloat64,     BT uFloat64Complex,
     370                                                BT Double,       BT DoubleComplex,           BT uFloat64x,    BT uFloat64xComplex,           BT uuFloat80,           BT uFloat128,
     371                                      BT uFloat128Complex,          BT uuFloat128,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
     372                                  },
     373                                  {
     374                /*  _FDC*/     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,
     375                                       BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,
     376                                       BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,
     377                                       BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,
     378                                         BT DoubleComplex,       BT DoubleComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat128Complex,
     379                                      BT uFloat128Complex,    BT uFloat128Complex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,
     380                                  },
     381                                  {
     382                /*     D*/              BT Double,              BT Double,              BT Double,              BT Double,              BT Double,              BT Double,
     383                                                BT Double,              BT Double,              BT Double,              BT Double,              BT Double,              BT Double,
     384                                                BT Double,              BT Double,              BT Double,       BT DoubleComplex,              BT Double,       BT DoubleComplex,
     385                                                BT Double,       BT DoubleComplex,              BT Double,       BT DoubleComplex,              BT Double,       BT DoubleComplex,
     386                                                BT Double,       BT DoubleComplex,           BT uFloat64x,    BT uFloat64xComplex,           BT uuFloat80,           BT uFloat128,
     387                                      BT uFloat128Complex,          BT uuFloat128,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
     388                                  },
     389                                  {
     390                /*    DC*/       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,
     391                                         BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,
     392                                         BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,
     393                                         BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,
     394                                         BT DoubleComplex,       BT DoubleComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat128Complex,
     395                                      BT uFloat128Complex,    BT uFloat128Complex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,
     396                                  },
     397                                  {
     398                /*  F80X*/           BT uFloat64x,           BT uFloat64x,           BT uFloat64x,           BT uFloat64x,           BT uFloat64x,           BT uFloat64x,
     399                                             BT uFloat64x,           BT uFloat64x,           BT uFloat64x,           BT uFloat64x,           BT uFloat64x,           BT uFloat64x,
     400                                             BT uFloat64x,           BT uFloat64x,           BT uFloat64x,    BT uFloat64xComplex,           BT uFloat64x,    BT uFloat64xComplex,
     401                                             BT uFloat64x,    BT uFloat64xComplex,           BT uFloat64x,    BT uFloat64xComplex,           BT uFloat64x,    BT uFloat64xComplex,
     402                                             BT uFloat64x,    BT uFloat64xComplex,           BT uFloat64x,    BT uFloat64xComplex,           BT uuFloat80,           BT uFloat128,
     403                                      BT uFloat128Complex,          BT uuFloat128,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
     404                                  },
     405                                  {
     406                /* _FDXC*/    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,
     407                                      BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,
     408                                      BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,
     409                                      BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,
     410                                      BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat128Complex,
     411                                      BT uFloat128Complex,    BT uFloat128Complex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,
     412                                  },
     413                                  {
     414                /*   F80*/           BT uuFloat80,           BT uuFloat80,           BT uuFloat80,           BT uuFloat80,           BT uuFloat80,           BT uuFloat80,
     415                                             BT uuFloat80,           BT uuFloat80,           BT uuFloat80,           BT uuFloat80,           BT uuFloat80,           BT uuFloat80,
     416                                             BT uuFloat80,           BT uuFloat80,           BT uuFloat80,    BT uFloat64xComplex,           BT uuFloat80,    BT uFloat64xComplex,
     417                                             BT uuFloat80,    BT uFloat64xComplex,           BT uuFloat80,    BT uFloat64xComplex,           BT uuFloat80,    BT uFloat64xComplex,
     418                                             BT uuFloat80,    BT uFloat64xComplex,           BT uuFloat80,    BT uFloat64xComplex,           BT uuFloat80,           BT uFloat128,
     419                                      BT uFloat128Complex,          BT uuFloat128,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
     420                                  },
     421                                  {
     422                /*   _FB*/           BT uFloat128,           BT uFloat128,           BT uFloat128,           BT uFloat128,           BT uFloat128,           BT uFloat128,
     423                                             BT uFloat128,           BT uFloat128,           BT uFloat128,           BT uFloat128,           BT uFloat128,           BT uFloat128,
     424                                             BT uFloat128,           BT uFloat128,           BT uFloat128,    BT uFloat128Complex,           BT uFloat128,    BT uFloat128Complex,
     425                                             BT uFloat128,    BT uFloat128Complex,           BT uFloat128,    BT uFloat128Complex,           BT uFloat128,    BT uFloat128Complex,
     426                                             BT uFloat128,    BT uFloat128Complex,           BT uFloat128,    BT uFloat128Complex,           BT uFloat128,           BT uFloat128,
     427                                      BT uFloat128Complex,          BT uuFloat128,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
     428                                  },
     429                                  {
     430                /* _FLDC*/    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,
     431                                      BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,
     432                                      BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,
     433                                      BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,
     434                                      BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,
     435                                      BT uFloat128Complex,    BT uFloat128Complex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,
     436                                  },
     437                                  {
     438                /*    FB*/          BT uuFloat128,          BT uuFloat128,          BT uuFloat128,          BT uuFloat128,          BT uuFloat128,          BT uuFloat128,
     439                                            BT uuFloat128,          BT uuFloat128,          BT uuFloat128,          BT uuFloat128,          BT uuFloat128,          BT uuFloat128,
     440                                            BT uuFloat128,          BT uuFloat128,          BT uuFloat128,    BT uFloat128Complex,          BT uuFloat128,    BT uFloat128Complex,
     441                                            BT uuFloat128,    BT uFloat128Complex,          BT uuFloat128,    BT uFloat128Complex,          BT uuFloat128,    BT uFloat128Complex,
     442                                            BT uuFloat128,    BT uFloat128Complex,          BT uuFloat128,    BT uFloat128Complex,          BT uuFloat128,          BT uuFloat128,
     443                                      BT uFloat128Complex,          BT uuFloat128,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
     444                                  },
     445                                  {
     446                /*    LD*/          BT LongDouble,          BT LongDouble,          BT LongDouble,          BT LongDouble,          BT LongDouble,          BT LongDouble,
     447                                            BT LongDouble,          BT LongDouble,          BT LongDouble,          BT LongDouble,          BT LongDouble,          BT LongDouble,
     448                                            BT LongDouble,          BT LongDouble,          BT LongDouble,   BT LongDoubleComplex,          BT LongDouble,   BT LongDoubleComplex,
     449                                            BT LongDouble,   BT LongDoubleComplex,          BT LongDouble,   BT LongDoubleComplex,          BT LongDouble,   BT LongDoubleComplex,
     450                                            BT LongDouble,   BT LongDoubleComplex,          BT LongDouble,   BT LongDoubleComplex,          BT LongDouble,          BT LongDouble,
     451                                     BT LongDoubleComplex,          BT LongDouble,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
     452                                  },
     453                                  {
     454                /*   LDC*/   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,
     455                                     BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,
     456                                     BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,
     457                                     BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,
     458                                     BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,
     459                                     BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,
     460                                  },
     461                                  {
     462                /*  _FBX*/          BT uFloat128x,          BT uFloat128x,          BT uFloat128x,          BT uFloat128x,          BT uFloat128x,          BT uFloat128x,
     463                                            BT uFloat128x,          BT uFloat128x,          BT uFloat128x,          BT uFloat128x,          BT uFloat128x,          BT uFloat128x,
     464                                            BT uFloat128x,          BT uFloat128x,          BT uFloat128x,   BT uFloat128xComplex,          BT uFloat128x,   BT uFloat128xComplex,
     465                                            BT uFloat128x,   BT uFloat128xComplex,          BT uFloat128x,   BT uFloat128xComplex,          BT uFloat128x,   BT uFloat128xComplex,
     466                                            BT uFloat128x,   BT uFloat128xComplex,          BT uFloat128x,   BT uFloat128xComplex,          BT uFloat128x,          BT uFloat128x,
     467                                     BT uFloat128xComplex,          BT uFloat128x,          BT uFloat128x,   BT uFloat128xComplex,          BT uFloat128x,   BT uFloat128xComplex,
     468                                  },
     469                                  {
     470                /*_FLDXC*/   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,
     471                                     BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,
     472                                     BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,
     473                                     BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,
     474                                     BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,
     475                                     BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,
     476                                  },
     477        }; // commonTypes
     478        #undef BT
     479        // GENERATED END
    207480        static_assert(
    208                 sizeof(combinedType)/sizeof(combinedType[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES*BasicType::NUMBER_OF_BASIC_TYPES,
     481                sizeof(commonTypes)/sizeof(commonTypes[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES*BasicType::NUMBER_OF_BASIC_TYPES,
    209482                "Each basic type kind should have a corresponding row in the combined type matrix"
    210483        );
     
    218491        void CommonType::postvisit( BasicType *basicType ) {
    219492                if ( BasicType *otherBasic = dynamic_cast< BasicType* >( type2 ) ) {
    220                         BasicType::Kind newType = combinedType[ basicType->get_kind() ][ otherBasic->get_kind() ];
     493                        BasicType::Kind newType = commonTypes[ basicType->get_kind() ][ otherBasic->get_kind() ];
    221494                        if ( ( ( newType == basicType->get_kind() && basicType->get_qualifiers() >= otherBasic->get_qualifiers() ) || widenFirst ) && ( ( newType == otherBasic->get_kind() && basicType->get_qualifiers() <= otherBasic->get_qualifiers() ) || widenSecond ) ) {
    222495                                result = new BasicType( basicType->get_qualifiers() | otherBasic->get_qualifiers(), newType );
     
    224497                } else if ( dynamic_cast< EnumInstType * > ( type2 ) || dynamic_cast< ZeroType* >( type2 ) || dynamic_cast< OneType* >( type2 ) ) {
    225498                        // use signed int in lieu of the enum/zero/one type
    226                         BasicType::Kind newType = combinedType[ basicType->get_kind() ][ BasicType::SignedInt ];
     499                        BasicType::Kind newType = commonTypes[ basicType->get_kind() ][ BasicType::SignedInt ];
    227500                        if ( ( ( newType == basicType->get_kind() && basicType->get_qualifiers() >= type2->get_qualifiers() ) || widenFirst ) && ( ( newType != basicType->get_kind() && basicType->get_qualifiers() <= type2->get_qualifiers() ) || widenSecond ) ) {
    228501                                result = new BasicType( basicType->get_qualifiers() | type2->get_qualifiers(), newType );
  • src/ResolvExpr/ConversionCost.cc

    r6a9d4b4 r933f32f  
    1010// Created On       : Sun May 17 07:06:19 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Sep 25 15:43:34 2017
    13 // Update Count     : 10
     12// Last Modified On : Mon May  6 14:18:22 2019
     13// Update Count     : 25
    1414//
    1515
     
    2828
    2929namespace ResolvExpr {
    30         const Cost Cost::zero =      Cost{  0,  0,  0,  0,  0,  0 };
    31         const Cost Cost::infinity =  Cost{ -1, -1, -1, -1,  1, -1 };
    32         const Cost Cost::unsafe =    Cost{  1,  0,  0,  0,  0,  0 };
    33         const Cost Cost::poly =      Cost{  0,  1,  0,  0,  0,  0 };
    34         const Cost Cost::safe =      Cost{  0,  0,  1,  0,  0,  0 };
    35         const Cost Cost::var =       Cost{  0,  0,  0,  1,  0,  0 };
    36         const Cost Cost::spec =      Cost{  0,  0,  0,  0, -1,  0 };
    37         const Cost Cost::reference = Cost{  0,  0,  0,  0,  0,  1 };
     30#if 0
     31        const Cost Cost::zero =      Cost{  0,  0,  0,  0,  0,  0,  0 };
     32        const Cost Cost::infinity =  Cost{ -1, -1, -1, -1, -1,  1, -1 };
     33        const Cost Cost::unsafe =    Cost{  1,  0,  0,  0,  0,  0,  0 };
     34        const Cost Cost::poly =      Cost{  0,  1,  0,  0,  0,  0,  0 };
     35        const Cost Cost::safe =      Cost{  0,  0,  1,  0,  0,  0,  0 };
     36        const Cost Cost::sign =      Cost{  0,  0,  0,  1,  0,  0,  0 };
     37        const Cost Cost::var =       Cost{  0,  0,  0,  0,  1,  0,  0 };
     38        const Cost Cost::spec =      Cost{  0,  0,  0,  0,  0, -1,  0 };
     39        const Cost Cost::reference = Cost{  0,  0,  0,  0,  0,  0,  1 };
     40#endif
    3841
    3942#if 0
     
    4245#define PRINT(x)
    4346#endif
     47
    4448        Cost conversionCost( Type *src, Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
    4549                if ( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) {
     
    179183        }
    180184
    181 /*
    182             Old
    183             ===
    184            Double
    185              |
    186            Float
    187              |
    188            ULong
    189            /   \
    190         UInt    Long
    191            \   /
    192             Int
    193              |
    194            Ushort
    195              |
    196            Short
    197              |
    198            Uchar
    199            /   \
    200         Schar   Char
    201 
    202                                 New
    203                                 ===
    204                        +-----LongDoubleComplex--+
    205            LongDouble--+          |             +-LongDoubleImag
    206              |         +---DoubleComplex---+         |
    207            Double------+        |          +----DoubleImag
    208              |           +-FloatComplex-+            |
    209            Float---------+              +-------FloatImag
    210              |
    211           ULongLong
    212              |
    213           LongLong
    214              |
    215            ULong
    216            /   \
    217         UInt    Long
    218            \   /
    219             Int
    220              |
    221            Ushort
    222              |
    223            Short
    224              |
    225            Uchar
    226            /   \
    227         Schar   Char
    228            \   /
    229             Bool
    230 */
    231 
    232         static const int costMatrix[][ BasicType::NUMBER_OF_BASIC_TYPES ] = {
    233         /* Src \ Dest:  Bool    Char    SChar   UChar   Short   UShort  Int     UInt    Long    ULong   LLong   ULLong  Float   Double  LDbl    FCplex  DCplex  LDCplex FImag   DImag   LDImag  I128,   U128, F80, F128 */
    234                 /* Bool */      { 0,    1,              1,              2,              3,              4,              5,              6,              6,              7,              8,              9,              12,             13,             14,             12,             13,             14,             -1,             -1,             -1,             10,             11,       14,   15},
    235                 /* Char */      { -1,   0,              -1,             1,              2,              3,              4,              5,              5,              6,              7,              8,              11,             12,             13,             11,             12,             13,             -1,             -1,             -1,             9,              10,       13,   14},
    236                 /* SChar */ { -1,       -1,             0,              1,              2,              3,              4,              5,              5,              6,              7,              8,              11,             12,             13,             11,             12,             13,             -1,             -1,             -1,             9,              10,       13,   14},
    237                 /* UChar */ { -1,       -1,             -1,             0,              1,              2,              3,              4,              4,              5,              6,              7,              10,             11,             12,             10,             11,             12,             -1,             -1,             -1,             8,              9,        12,   13},
    238                 /* Short */ { -1,       -1,             -1,             -1,             0,              1,              2,              3,              3,              4,              5,              6,              9,              10,             11,             9,              10,             11,             -1,             -1,             -1,             7,              8,        11,   12},
    239                 /* UShort */{ -1,       -1,             -1,             -1,             -1,             0,              1,              2,              2,              3,              4,              5,              8,              9,              10,             8,              9,              10,             -1,             -1,             -1,             6,              7,        10,   11},
    240                 /* Int */       { -1,   -1,             -1,             -1,             -1,             -1,             0,              1,              1,              2,              3,              4,              7,              8,              9,              7,              8,              9,              -1,             -1,             -1,             5,              6,        9,    10},
    241                 /* UInt */      { -1,   -1,             -1,             -1,             -1,             -1,             -1,             0,              -1,             1,              2,              3,              6,              7,              8,              6,              7,              8,              -1,             -1,             -1,             4,              5,        8,    9},
    242                 /* Long */      { -1,   -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              1,              2,              3,              6,              7,              8,              6,              7,              8,              -1,             -1,             -1,             4,              5,        8,    9},
    243                 /* ULong */ { -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              1,              2,              5,              6,              7,              5,              6,              7,              -1,             -1,             -1,             3,              4,        7,    8},
    244                 /* LLong */ { -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              1,              4,              5,              6,              4,              5,              6,              -1,             -1,             -1,             2,              3,        6,    7},
    245                 /* ULLong */{ -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              3,              4,              5,              3,              4,              5,              -1,             -1,             -1,             1,              2,        5,    6},
    246 
    247                 /* Float */ { -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              1,              2,              1,              2,              3,              -1,             -1,             -1,             -1,             -1,       2,    3},
    248                 /* Double */{ -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              1,              -1,             1,              2,              -1,             -1,             -1,             -1,             -1,       1,    2},
    249                 /* LDbl */      { -1,   -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              -1,             -1,             1,              -1,             -1,             -1,             -1,             -1,       -1,   1},
    250                 /* FCplex */{ -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              1,              2,              -1,             -1,             -1,             -1,             -1,       -1,   -1},
    251                 /* DCplex */{ -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              1,              -1,             -1,             -1,             -1,             -1,       -1,   -1},
    252                 /* LDCplex */{ -1,      -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             0,              -1,             -1,             -1,             -1,             -1,       -1,   -1},
    253                 /* FImag */ { -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             1,              2,              3,              0,              1,              2,              -1,             -1,       -1,   -1},
    254                 /* DImag */ { -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             1,              2,              -1,             0,              1,              -1,             -1,       -1,   -1},
    255                 /* LDImag */{ -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             1,              -1,             -1,             0,              -1,             -1,       -1,   -1},
    256 
    257                 /* I128 */  { -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             2,              3,              4,              3,              4,              5,              -1,             -1,             -1,             0,              1,        4,    4},
    258                 /* U128 */  { -1,       -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             1,              2,              3,              2,              3,              4,              -1,             -1,             -1,             -1,             0,        3,    3},
    259 
    260                 /* F80 */       { -1,   -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             -1,             1,              -1,             -1,             1,              -1,             -1,             -1,             -1,             -1,       0,    1},
    261                 /* F128 */      { -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},
    262         };
     185        // GENERATED START, DO NOT EDIT
     186        // GENERATED BY BasicTypes-gen.cc
     187        /* EXTENDED INTEGRAL RANK HIERARCHY (root to leaves)
     188                                 _Bool
     189        char                signed char         unsigned char       
     190                  signed short int         unsigned short int       
     191                  signed int               unsigned int             
     192                  signed long int          unsigned long int       
     193                  signed long long int     unsigned long long int   
     194                  __int128                 unsigned __int128       
     195                  _Float16                 _Float16 _Complex       
     196                  _Float32                 _Float32 _Complex       
     197                  float                    float _Complex           
     198                  _Float32x                _Float32x _Complex       
     199                  _Float64                 _Float64 _Complex       
     200                  double                   double _Complex         
     201                  _Float64x                _Float64x _Complex       
     202                             __float80
     203                  _Float128                _Float128 _Complex       
     204                            __float128
     205                  long double              long double _Complex     
     206                  _Float128x               _Float128x _Complex     
     207        */
     208        // GENERATED END
     209
     210        // GENERATED START, DO NOT EDIT
     211        // GENERATED BY BasicTypes-gen.cc
     212        static const int costMatrix[BasicType::NUMBER_OF_BASIC_TYPES][BasicType::NUMBER_OF_BASIC_TYPES] = { // path length from root to node
     213                /*             B    C   SC   UC   SI  SUI    I   UI   LI  LUI  LLI LLUI   IB  UIB  _FH  _FH   _F  _FC    F   FC  _FX _FXC   FD _FDC    D   DC F80X_FDXC  F80  _FB_FLDC   FB   LD  LDC _FBX_FLDXC */
     214                /*     B*/ {   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  12,  13,  13,  14,  14,  15,  15,  16,  17,  16,  18,  17, },
     215                /*     C*/ {  -1,   0,   1,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  12,  13,  13,  14,  14,  15,  16,  15,  17,  16, },
     216                /*    SC*/ {  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  12,  13,  13,  14,  14,  15,  16,  15,  17,  16, },
     217                /*    UC*/ {  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  12,  13,  13,  14,  14,  15,  16,  15,  17,  16, },
     218                /*    SI*/ {  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  12,  13,  13,  14,  15,  14,  16,  15, },
     219                /*   SUI*/ {  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  12,  13,  13,  14,  15,  14,  16,  15, },
     220                /*     I*/ {  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  12,  13,  14,  13,  15,  14, },
     221                /*    UI*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  12,  13,  14,  13,  15,  14, },
     222                /*    LI*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  13,  12,  14,  13, },
     223                /*   LUI*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  11,  12,  13,  12,  14,  13, },
     224                /*   LLI*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  12,  11,  13,  12, },
     225                /*  LLUI*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  10,  11,  12,  11,  13,  12, },
     226                /*    IB*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  11,  10,  12,  11, },
     227                /*   UIB*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,   9,  10,  11,  10,  12,  11, },
     228                /*   _FH*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   8,   9,  10,   9,  11,  10, },
     229                /*   _FH*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   1,  -1,   2,  -1,   3,  -1,   4,  -1,   5,  -1,   6,  -1,  -1,   7,  -1,  -1,   8,  -1,   9, },
     230                /*    _F*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   7,   8,   9,   8,  10,   9, },
     231                /*   _FC*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   1,  -1,   2,  -1,   3,  -1,   4,  -1,   5,  -1,  -1,   6,  -1,  -1,   7,  -1,   8, },
     232                /*     F*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   6,   7,   8,   7,   9,   8, },
     233                /*    FC*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   1,  -1,   2,  -1,   3,  -1,   4,  -1,  -1,   5,  -1,  -1,   6,  -1,   7, },
     234                /*   _FX*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   5,   6,   7,   6,   8,   7, },
     235                /*  _FXC*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   1,  -1,   2,  -1,   3,  -1,  -1,   4,  -1,  -1,   5,  -1,   6, },
     236                /*    FD*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   1,   2,   2,   3,   3,   4,   4,   5,   6,   5,   7,   6, },
     237                /*  _FDC*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   1,  -1,   2,  -1,  -1,   3,  -1,  -1,   4,  -1,   5, },
     238                /*     D*/ {  -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,   1,   1,   2,   2,   3,   3,   4,   5,   4,   6,   5, },
     239                /*    DC*/ {  -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,  -1,   1,  -1,  -1,   2,  -1,  -1,   3,  -1,   4, },
     240                /*  F80X*/ {  -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,   1,   1,   2,   2,   3,   4,   3,   5,   4, },
     241                /* _FDXC*/ {  -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,  -1,  -1,   1,  -1,  -1,   2,  -1,   3, },
     242                /*   F80*/ {  -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,   1,   2,   2,   3,   3,   4,   4, },
     243                /*   _FB*/ {  -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,   1,   1,   2,   2,   3,   3, },
     244                /* _FLDC*/ {  -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,  -1,  -1,   1,  -1,   2, },
     245                /*    FB*/ {  -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,   1,   2,   2,   3, },
     246                /*    LD*/ {  -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,   1,   1,   2, },
     247                /*   LDC*/ {  -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,  -1,   1, },
     248                /*  _FBX*/ {  -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,   1, },
     249                /*_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, },
     250        }; // costMatrix
     251        static const int maxIntCost = 15;
     252        // GENERATED END
    263253        static_assert(
    264254                sizeof(costMatrix)/sizeof(costMatrix[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES*BasicType::NUMBER_OF_BASIC_TYPES,
    265                 "Each basic type kind should have a corresponding row in the cost matrix"
     255                "Missing row in the cost matrix"
    266256        );
    267257
     258        // GENERATED START, DO NOT EDIT
     259        // GENERATED BY BasicTypes-gen.cc
     260        static const int signMatrix[BasicType::NUMBER_OF_BASIC_TYPES][BasicType::NUMBER_OF_BASIC_TYPES] = { // number of sign changes in safe conversion
     261                /*             B    C   SC   UC   SI  SUI    I   UI   LI  LUI  LLI LLUI   IB  UIB  _FH  _FH   _F  _FC    F   FC  _FX _FXC   FD _FDC    D   DC F80X_FDXC  F80  _FB_FLDC   FB   LD  LDC _FBX_FLDXC */
     262                /*     B*/ {   0,   0,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
     263                /*     C*/ {  -1,   0,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
     264                /*    SC*/ {  -1,  -1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
     265                /*    UC*/ {  -1,  -1,  -1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
     266                /*    SI*/ {  -1,  -1,  -1,  -1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
     267                /*   SUI*/ {  -1,  -1,  -1,  -1,  -1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
     268                /*     I*/ {  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
     269                /*    UI*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
     270                /*    LI*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
     271                /*   LUI*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
     272                /*   LLI*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
     273                /*  LLUI*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
     274                /*    IB*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
     275                /*   UIB*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
     276                /*   _FH*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
     277                /*   _FH*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,  -1,   0,  -1,  -1,   0,  -1,   0, },
     278                /*    _F*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
     279                /*   _FC*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,  -1,   0,  -1,  -1,   0,  -1,   0, },
     280                /*     F*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
     281                /*    FC*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,  -1,   0,  -1,  -1,   0,  -1,   0, },
     282                /*   _FX*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
     283                /*  _FXC*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,  -1,   0,  -1,  -1,   0,  -1,   0, },
     284                /*    FD*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
     285                /*  _FDC*/ {  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   0,  -1,   0,  -1,   0,  -1,  -1,   0,  -1,  -1,   0,  -1,   0, },
     286                /*     D*/ {  -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,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
     287                /*    DC*/ {  -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,  -1,   0,  -1,  -1,   0,  -1,  -1,   0,  -1,   0, },
     288                /*  F80X*/ {  -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,   0,   0,   0,   0,   0,   0,   0,   0,   0, },
     289                /* _FDXC*/ {  -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,  -1,  -1,   0,  -1,  -1,   0,  -1,   0, },
     290                /*   F80*/ {  -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,   0,   0,   0,   0,   0,   0,   0,   0, },
     291                /*   _FB*/ {  -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,   0,   0,   0,   0,   0,   0, },
     292                /* _FLDC*/ {  -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,  -1,  -1,   0,  -1,   0, },
     293                /*    FB*/ {  -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,   0,   0,   0,   0,   0, },
     294                /*    LD*/ {  -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,   0,   0,   0, },
     295                /*   LDC*/ {  -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,  -1,   0, },
     296                /*  _FBX*/ {  -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,   0, },
     297                /*_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, },
     298        }; // signMatrix
     299        // GENERATED END
     300        static_assert(
     301                sizeof(signMatrix)/sizeof(signMatrix[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES*BasicType::NUMBER_OF_BASIC_TYPES,
     302                "Missing row in the sign matrix"
     303        );
    268304
    269305        void ConversionCost::postvisit( VoidType * ) {
     
    279315                                cost = Cost::zero;
    280316                                cost.incSafe( tableResult );
     317                                cost.incSign( signMatrix[ basicType->get_kind() ][ destAsBasic->get_kind() ] );
    281318                        } // if
    282319                } else if ( dynamic_cast< EnumInstType *>( dest ) ) {
     
    300337                                        // types are the same, except otherPointer has more qualifiers
    301338                                        cost = Cost::safe;
    302                                 }
     339                                } // if
    303340                        } else {
    304341                                int assignResult = ptrsAssignable( pointerType->base, destAsPtr->base, env );
     
    422459                                cost = Cost::zero;
    423460                                cost.incSafe( tableResult + 1 );
    424                         }
     461                                cost.incSign( signMatrix[ BasicType::SignedInt ][ destAsBasic->get_kind() ] );
     462                        } // if
    425463                } else if ( dynamic_cast< PointerType* >( dest ) ) {
    426                         cost = Cost::safe;
    427                 }
     464                        cost = Cost::zero;
     465                        cost.incSafe( maxIntCost + 2 ); // +1 for zero_t -> int, +1 for disambiguation
     466                } // if
    428467        }
    429468
     
    439478                                cost = Cost::zero;
    440479                                cost.incSafe( tableResult + 1 );
    441                         }
    442                 }
     480                                cost.incSign( signMatrix[ BasicType::SignedInt ][ destAsBasic->get_kind() ] );
     481                        } // if
     482                } // if
    443483        }
    444484} // namespace ResolvExpr
  • src/ResolvExpr/Cost.h

    r6a9d4b4 r933f32f  
    77// Cost.h --
    88//
    9 // Author           : Richard C. Bilson
     9// Author           : Peter Buhr and Aaron Moss
    1010// Created On       : Sun May 17 09:39:50 2015
    11 // Last Modified By : Aaron B. Moss
    12 // Last Modified On : Fri Oct 05 14:32:00 2018
    13 // Update Count     : 7
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Mon Apr 29 18:33:44 2019
     13// Update Count     : 49
    1414//
    1515
     
    1717
    1818#include <iostream>
     19#include <cassert>
     20#include <climits>
    1921
    2022namespace ResolvExpr {
     23#if 0
     24
     25        //*************************** OLD ***************************
     26
    2127        class Cost {
    2228          private:
    23                 Cost( int unsafeCost, int polyCost, int safeCost, int varCost, int specCost,
    24                         int referenceCost );
    25 
     29                Cost( int unsafeCost, int polyCost, int safeCost, int signCost,
     30                          int varCost, int specCost, int referenceCost );
    2631          public:
    2732                Cost & incUnsafe( int inc = 1 );
    2833                Cost & incPoly( int inc = 1 );
    2934                Cost & incSafe( int inc = 1 );
     35                Cost & incSign( int inc = 1 );
    3036                Cost & incVar( int inc = 1 );
    3137                Cost & decSpec( int inc = 1 );
     
    3541                int get_polyCost() const { return polyCost; }
    3642                int get_safeCost() const { return safeCost; }
     43                int get_signCost() const { return signCost; }
    3744                int get_varCost() const { return varCost; }
    3845                int get_specCost() const { return specCost; }
     
    4047
    4148                Cost operator+( const Cost &other ) const;
    42                 Cost operator-( const Cost &other ) const;
    4349                Cost &operator+=( const Cost &other );
    4450                bool operator<( const Cost &other ) const;
     
    5561                static const Cost poly;
    5662                static const Cost safe;
     63                static const Cost sign;
    5764                static const Cost var;
    5865                static const Cost spec;
     
    6370                int polyCost;       ///< Count of parameters and return values bound to some poly type
    6471                int safeCost;       ///< Safe (widening) conversions
     72                int signCost;       ///< Count of safe sign conversions
    6573                int varCost;        ///< Count of polymorphic type variables
    6674                int specCost;       ///< Polymorphic type specializations (type assertions), negative cost
     
    6876        };
    6977
    70         inline Cost::Cost( int unsafeCost, int polyCost, int safeCost, int varCost, int specCost,
    71                         int referenceCost )
    72                 : unsafeCost( unsafeCost ), polyCost( polyCost ), safeCost( safeCost ), varCost( varCost ),
    73                   specCost( specCost ), referenceCost( referenceCost ) {}
     78        inline Cost::Cost( int unsafeCost, int polyCost, int safeCost, int signCost,
     79                                           int varCost, int specCost, int referenceCost )
     80                : unsafeCost( unsafeCost ), polyCost( polyCost ), safeCost( safeCost ), signCost( signCost ),
     81                  varCost( varCost ), specCost( specCost ), referenceCost( referenceCost ) {}
    7482
    7583        inline Cost & Cost::incUnsafe( int inc ) {
     
    8896                if ( *this == infinity ) return *this;
    8997                safeCost += inc;
     98                return *this;
     99        }
     100
     101        inline Cost & Cost::incSign( int inc ) {
     102                if ( *this == infinity ) return *this;
     103                signCost += inc;
    90104                return *this;
    91105        }
     
    111125        inline Cost Cost::operator+( const Cost &other ) const {
    112126                if ( *this == infinity || other == infinity ) return infinity;
    113                 return Cost{
    114                         unsafeCost + other.unsafeCost, polyCost + other.polyCost, safeCost + other.safeCost,
    115                         varCost + other.varCost, specCost + other.specCost,
    116                         referenceCost + other.referenceCost };
    117         }
    118 
    119         inline Cost Cost::operator-( const Cost &other ) const {
    120                 if ( *this == infinity || other == infinity ) return infinity;
    121                 return Cost{
    122                         unsafeCost - other.unsafeCost, polyCost - other.polyCost, safeCost - other.safeCost,
    123                         varCost - other.varCost, specCost - other.specCost,
    124                         referenceCost - other.referenceCost };
     127                return Cost{
     128                        unsafeCost + other.unsafeCost, polyCost + other.polyCost, safeCost + other.safeCost,
     129                                signCost + other.signCost, varCost + other.varCost, specCost + other.specCost,
     130                                referenceCost + other.referenceCost };
    125131        }
    126132
     
    134140                polyCost += other.polyCost;
    135141                safeCost += other.safeCost;
     142                signCost += other.signCost;
    136143                varCost += other.varCost;
    137144                specCost += other.specCost;
     
    156163                } else if ( safeCost < other.safeCost ) {
    157164                        return true;
     165                } else if ( signCost > other.signCost ) {
     166                        return false;
     167                } else if ( signCost < other.signCost ) {
     168                        return true;
    158169                } else if ( varCost > other.varCost ) {
    159170                        return false;
     
    180191                c = polyCost - other.polyCost; if ( c ) return c;
    181192                c = safeCost - other.safeCost; if ( c ) return c;
     193                c = signCost - other.signCost; if ( c ) return c;
    182194                c = varCost - other.varCost; if ( c ) return c;
    183195                c = specCost - other.specCost; if ( c ) return c;
     
    189201                        && polyCost == other.polyCost
    190202                        && safeCost == other.safeCost
     203                        && signCost == other.signCost
    191204                        && varCost == other.varCost
    192205                        && specCost == other.specCost
     
    199212
    200213        inline std::ostream &operator<<( std::ostream &os, const Cost &cost ) {
    201                 return os << "( " << cost.unsafeCost << ", " << cost.polyCost << ", "
    202                           << cost.safeCost << ", " << cost.varCost << ", " << cost.specCost << ", "
     214                return os << "( " << cost.unsafeCost << ", " << cost.polyCost << ", "
     215                          << cost.safeCost << ", " << cost.signCost << ", "
     216                                  << cost.varCost << ", " << cost.specCost << ", "
    203217                          << cost.referenceCost << " )";
    204218        }
     219
     220#else
     221
     222        //*************************** NEW ***************************
     223
     224        // To maximize performance and space, the 7 resolution costs are packed into a single 64-bit word. However, the
     225        // specialization cost is a negative value so a correction is needed is a few places.
     226
     227        class Cost {
     228                union {
     229                        struct {
     230                        #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
     231                                // Little-endian => first value is low priority and last is high priority.
     232                                unsigned char padding;                                  ///< unused
     233                                unsigned char referenceCost;                    ///< reference conversions
     234                                unsigned char specCost;                                 ///< Polymorphic type specializations (type assertions), negative cost
     235                                unsigned char varCost;                                  ///< Count of polymorphic type variables
     236                                unsigned char signCost;                                 ///< Count of safe sign conversions
     237                                unsigned char safeCost;                                 ///< Safe (widening) conversions
     238                                unsigned char polyCost;                                 ///< Count of parameters and return values bound to some poly type
     239                                unsigned char unsafeCost;                               ///< Unsafe (narrowing) conversions
     240                        #else
     241                                #error Cost BIG_ENDIAN unsupported
     242                        #endif
     243                        } v;
     244                        uint64_t all;
     245                };
     246                static const unsigned char correctb = 0xff;             // byte correction for negative spec cost
     247                static const uint64_t correctw = 0x00'00'00'00'00'ff'00'00; //' word correction for negative spec cost
     248          public:
     249                // Compiler adjusts constants for correct endian.
     250                enum : uint64_t {
     251                        zero      = 0x00'00'00'00'00'ff'00'00,
     252                        infinity  = 0xff'ff'ff'ff'ff'00'ff'ff,
     253                        unsafe    = 0x01'00'00'00'00'ff'00'00,
     254                        poly      = 0x00'01'00'00'00'ff'00'00,
     255                        safe      = 0x00'00'01'00'00'ff'00'00,
     256                        sign      = 0x00'00'00'01'00'ff'00'00,
     257                        var       = 0x00'00'00'00'01'ff'00'00,
     258                        spec      = 0x00'00'00'00'00'fe'00'00,
     259                        reference = 0x00'00'00'00'00'ff'01'00,
     260                }; //'
     261
     262                Cost( uint64_t all ) { Cost::all = all; }
     263                Cost( int unsafeCost, int polyCost, int safeCost, int signCost, int varCost, int specCost, int referenceCost ) {
     264                        // Assume little-endian => first value is low priority and last is high priority.
     265                        v = {
     266                        #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
     267                                (unsigned char)0,                                               // padding
     268                                (unsigned char)referenceCost,                   // low priority
     269                                (unsigned char)(specCost + correctb),   // correct for signedness
     270                                (unsigned char)varCost,
     271                                (unsigned char)signCost,
     272                                (unsigned char)safeCost,
     273                                (unsigned char)polyCost,
     274                                (unsigned char)unsafeCost,                              // high priority
     275                        #else
     276                                #error Cost BIG_ENDIAN unsupported
     277                        #endif
     278                        };
     279                }
     280
     281                int get_unsafeCost() const { return v.unsafeCost; }
     282                int get_polyCost() const { return v.polyCost; }
     283                int get_safeCost() const { return v.safeCost; }
     284                int get_signCost() const { return v.signCost; }
     285                int get_varCost() const { return v.varCost; }
     286                int get_specCost() const { return -(correctb - v.specCost); }
     287                int get_referenceCost() const { return v.referenceCost; }
     288
     289                friend bool operator==( const Cost, const Cost );
     290                friend bool operator!=( const Cost lhs, const Cost rhs );
     291                // returns negative for *this < rhs, 0 for *this == rhs, positive for *this > rhs
     292                int compare( const Cost rhs ) const {
     293                        if ( all == infinity ) return 1;
     294                        if ( rhs.all == infinity ) return -1;
     295                        return all > rhs.all ? 1 : all == rhs.all ? 0 : -1;
     296                }
     297                friend bool operator<( const Cost lhs, const Cost rhs );
     298
     299                friend Cost operator+( const Cost lhs, const Cost rhs );
     300 
     301                Cost operator+=( const Cost rhs ) {
     302                        if ( all == infinity ) return *this;
     303                        if ( rhs.all == infinity ) {
     304                                all = infinity;
     305                                return *this;
     306                        }
     307                        all += rhs.all - correctw;                                      // correct for negative spec cost
     308                        return *this;
     309                }
     310
     311                Cost incUnsafe( int inc = 1 ) {
     312                        if ( all != infinity ) { assert( v.unsafeCost + inc <= UCHAR_MAX ); v.unsafeCost += inc; }
     313                        return *this;
     314                }
     315
     316                Cost incPoly( int inc = 1 ) {
     317                        if ( all != infinity ) { assert( v.polyCost + inc <= UCHAR_MAX ); v.polyCost += inc; }
     318                        return *this;
     319                }
     320
     321                Cost incSafe( int inc = 1 ) {
     322                        if ( all != infinity ) { assert( v.safeCost + inc <= UCHAR_MAX ); v.safeCost += inc; }
     323                        return *this;
     324                }
     325
     326                Cost incSign( int inc = 1 ) {
     327                        if ( all != infinity ) { assert( v.signCost + inc <= UCHAR_MAX ); v.signCost += inc; }
     328                        return *this;
     329                }
     330
     331                Cost incVar( int inc = 1 ) {
     332                        if ( all != infinity ) { assert( v.varCost + inc <= UCHAR_MAX ); v.varCost += inc; }
     333                        return *this;
     334                }
     335
     336                Cost decSpec( int dec = 1 ) {
     337                        if ( all != infinity ) { assert( v.specCost - dec >= 0 ); v.specCost -= dec; }
     338                        return *this;
     339                }
     340
     341                Cost incReference( int inc = 1 ) {
     342                        if ( all != infinity ) { assert( v.referenceCost + inc <= UCHAR_MAX ); v.referenceCost += inc; }
     343                        return *this;
     344                }
     345
     346                friend std::ostream & operator<<( std::ostream & os, const Cost cost );
     347        };
     348
     349        inline bool operator==( const Cost lhs, const Cost rhs ) {
     350                return lhs.all == rhs.all;
     351        }
     352
     353        inline bool operator!=( const Cost lhs, const Cost rhs ) {
     354                return !( lhs.all == rhs.all );
     355        }
     356
     357        inline bool operator<( const Cost lhs, const Cost rhs ) {
     358                if ( lhs.all == Cost::infinity ) return false;
     359                if ( rhs.all == Cost::infinity ) return true;
     360                return lhs.all < rhs.all;
     361        }
     362
     363        inline Cost operator+( const Cost lhs, const Cost rhs ) {
     364                if ( lhs.all == Cost::infinity || rhs.all == Cost::infinity ) return Cost{ Cost::infinity };
     365                return Cost{ lhs.all + rhs.all - Cost::correctw }; // correct for negative spec cost
     366        }
     367
     368        inline std::ostream & operator<<( std::ostream & os, const Cost cost ) {
     369                return os << "( " << cost.get_unsafeCost() << ", " << cost.get_polyCost() << ", " << cost.get_safeCost()
     370                                  << ", " << cost.get_signCost() << ", " << cost.get_varCost() << ", " << cost.get_specCost()
     371                                  << ", " << cost.get_referenceCost() << " )";
     372        }
     373#endif // 0
    205374} // namespace ResolvExpr
    206375
  • src/ResolvExpr/RenameVars.cc

    r6a9d4b4 r933f32f  
    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/ResolveAssertions.cc

    r6a9d4b4 r933f32f  
    2020#include <list>                     // for list
    2121#include <memory>                   // for unique_ptr
    22 #include <string>
     22#include <sstream>                  // for ostringstream
     23#include <string>                   // for string
    2324#include <unordered_map>            // for unordered_map, unordered_multimap
    2425#include <utility>                  // for move
     
    2728#include "Alternative.h"            // for Alternative, AssertionItem, AssertionList
    2829#include "Common/FilterCombos.h"    // for filterCombos
     30#include "Common/Indenter.h"        // for Indenter
    2931#include "Common/utility.h"         // for sort_mins
    3032#include "ResolvExpr/RenameVars.h"  // for renameTyVars
     
    3335#include "SynTree/Expression.h"     // for InferredParams
    3436#include "TypeEnvironment.h"        // for TypeEnvironment, etc.
    35 #include "typeops.h"                // for adjustExprType
     37#include "typeops.h"                // for adjustExprType, specCost
    3638#include "Unify.h"                  // for unify
    3739
     
    5658        using CandidateList = std::vector<AssnCandidate>;
    5759
    58         /// Unique identifier for a yet-to-be-resolved assertion
    59         struct AssnId {
    60                 DeclarationWithType* decl;  ///< Declaration of assertion
    61                 AssertionSetValue info;     ///< Information about assertion
    62 
    63                 AssnId(DeclarationWithType* decl, const AssertionSetValue& info) : decl(decl), info(info) {}
    64         };
    65 
    66         /// Cached assertion items
    67         struct AssnCacheItem {
    68                 CandidateList matches;         ///< Possible matches for this assertion
    69                 std::vector<AssnId> deferIds;  ///< Deferred assertions which resolve to this item
    70 
    71                 AssnCacheItem( CandidateList&& m ) : matches(std::move(m)), deferIds() {}
    72         };
    73 
    74         /// Cache of resolved assertions
    75         using AssnCache = std::unordered_map<std::string, AssnCacheItem>;
    76 
    7760        /// Reference to single deferred item
    7861        struct DeferRef {
    79                 const AssnCacheItem& item;
     62                const DeclarationWithType* decl;
     63                const AssertionSetValue& info;
    8064                const AssnCandidate& match;
    8165        };
     
    8468        /// Acts like indexed list of DeferRef
    8569        struct DeferItem {
    86                 const AssnCache* cache;     ///< Cache storing assertion item
    87                 std::string key;            ///< Key into cache
    88                
    89                 DeferItem( const AssnCache& cache, const std::string& key ) : cache(&cache), key(key) {}
    90 
    91                 bool empty() const { return cache->at(key).matches.empty(); }
    92 
    93                 CandidateList::size_type size() const { return cache->at(key).matches.size(); }
    94 
    95                 DeferRef operator[] ( unsigned i ) const {
    96                         const AssnCacheItem& item = cache->at(key);
    97                         return { item, item.matches[i] };
    98                 }
    99 
    100                 // sortable by key
    101                 // TODO look into optimizing combination process with other sort orders (e.g. by number
    102                 // of matches in candidate)
    103                 bool operator< ( const DeferItem& o ) const { return key < o.key; }
    104                 bool operator== ( const DeferItem& o ) const { return key == o.key; }
     70                const DeclarationWithType* decl;
     71                const AssertionSetValue& info;
     72                CandidateList matches;
     73
     74                DeferItem( DeclarationWithType* decl, const AssertionSetValue& info, CandidateList&& matches )
     75                : decl(decl), info(info), matches(std::move(matches)) {}
     76
     77                bool empty() const { return matches.empty(); }
     78
     79                CandidateList::size_type size() const { return matches.size(); }
     80
     81                DeferRef operator[] ( unsigned i ) const { return { decl, info, matches[i] }; }
    10582        };
    10683
     
    177154                                for ( const auto& assn : x.assns ) {
    178155                                        k += computeConversionCost(
    179                                                 assn.match.adjType, assn.item.deferIds[0].decl->get_type(), indexer,
    180                                                 x.env );
     156                                                assn.match.adjType, assn.decl->get_type(), indexer, x.env );
     157                                       
     158                                        // mark vars+specialization cost on function-type assertions
     159                                        PointerType* ptr = dynamic_cast< PointerType* >( assn.decl->get_type() );
     160                                        if ( ! ptr ) continue;
     161                                        FunctionType* func = dynamic_cast< FunctionType* >( ptr->base );
     162                                        if ( ! func ) continue;
     163                                       
     164                                        for ( DeclarationWithType* formal : func->parameters ) {
     165                                                k.decSpec( specCost( formal->get_type() ) );
     166                                        }
     167                                        k.incVar( func->forall.size() );
     168                                        for ( TypeDecl* td : func->forall ) {
     169                                                k.decSpec( td->assertions.size() );
     170                                        }
    181171                                }
    182172                                it = cache.emplace_hint( it, &x, k );
     
    249239
    250240        /// Resolve a single assertion, in context
    251         bool resolveAssertion( AssertionItem& assn, ResnState& resn, AssnCache& cache ) {
     241        bool resolveAssertion( AssertionItem& assn, ResnState& resn ) {
    252242                // skip unused assertions
    253243                if ( ! assn.info.isUsed ) return true;
    254244
    255                 // check cache for this assertion
    256                 std::string assnKey = SymTab::Mangler::mangleAssnKey( assn.decl, resn.alt.env );
    257                 auto it = cache.find( assnKey );
    258 
    259                 // attempt to resolve assertion if this is the first time seen
    260                 if ( it == cache.end() ) {
    261                         // lookup candidates for this assertion
    262                         std::list< SymTab::Indexer::IdData > candidates;
    263                         resn.indexer.lookupId( assn.decl->name, candidates );
    264 
    265                         // find the candidates that unify with the desired type
    266                         CandidateList matches;
    267                         for ( const auto& cdata : candidates ) {
    268                                 DeclarationWithType* candidate = cdata.id;
    269 
    270                                 // build independent unification context for candidate
    271                                 AssertionSet have, newNeed;
    272                                 TypeEnvironment newEnv{ resn.alt.env };
    273                                 OpenVarSet newOpenVars{ resn.alt.openVars };
    274                                 Type* adjType = candidate->get_type()->clone();
    275                                 adjustExprType( adjType, newEnv, resn.indexer );
    276                                 renameTyVars( adjType );
    277 
    278                                 // keep unifying candidates
    279                                 if ( unify( assn.decl->get_type(), adjType, newEnv, newNeed, have, newOpenVars,
    280                                                 resn.indexer ) ) {
    281                                         // set up binding slot for recursive assertions
    282                                         UniqueId crntResnSlot = 0;
    283                                         if ( ! newNeed.empty() ) {
    284                                                 crntResnSlot = ++globalResnSlot;
    285                                                 for ( auto& a : newNeed ) {
    286                                                         a.second.resnSlot = crntResnSlot;
    287                                                 }
    288                                         }
    289 
    290                                         matches.emplace_back( cdata, adjType, std::move(newEnv), std::move(have),
    291                                                 std::move(newNeed), std::move(newOpenVars), crntResnSlot );
    292                                 } else {
    293                                         delete adjType;
    294                                 }
     245                // lookup candidates for this assertion
     246                std::list< SymTab::Indexer::IdData > candidates;
     247                resn.indexer.lookupId( assn.decl->name, candidates );
     248
     249                // find the candidates that unify with the desired type
     250                CandidateList matches;
     251                for ( const auto& cdata : candidates ) {
     252                        DeclarationWithType* candidate = cdata.id;
     253
     254                        // build independent unification context for candidate
     255                        AssertionSet have, newNeed;
     256                        TypeEnvironment newEnv{ resn.alt.env };
     257                        OpenVarSet newOpenVars{ resn.alt.openVars };
     258                        Type* adjType = candidate->get_type()->clone();
     259                        adjustExprType( adjType, newEnv, resn.indexer );
     260                        renameTyVars( adjType );
     261
     262                        // keep unifying candidates
     263                        if ( unify( assn.decl->get_type(), adjType, newEnv, newNeed, have, newOpenVars,
     264                                        resn.indexer ) ) {
     265                                // set up binding slot for recursive assertions
     266                                UniqueId crntResnSlot = 0;
     267                                if ( ! newNeed.empty() ) {
     268                                        crntResnSlot = ++globalResnSlot;
     269                                        for ( auto& a : newNeed ) {
     270                                                a.second.resnSlot = crntResnSlot;
     271                                        }
     272                                }
     273
     274                                matches.emplace_back( cdata, adjType, std::move(newEnv), std::move(have),
     275                                        std::move(newNeed), std::move(newOpenVars), crntResnSlot );
     276                        } else {
     277                                delete adjType;
    295278                        }
    296 
    297                         it = cache.emplace_hint( it, assnKey, AssnCacheItem{ std::move(matches) } );
    298                 }
    299 
    300                 CandidateList& matches = it->second.matches;
     279                }
    301280
    302281                // break if no suitable assertion
     
    305284                // defer if too many suitable assertions
    306285                if ( matches.size() > 1 ) {
    307                         it->second.deferIds.emplace_back( assn.decl, assn.info );
    308                         resn.deferred.emplace_back( cache, assnKey );
     286                        resn.deferred.emplace_back( assn.decl, assn.info, std::move(matches) );
    309287                        return true;
    310288                }
     
    314292                addToIndexer( match.have, resn.indexer );
    315293                resn.newNeed.insert( match.need.begin(), match.need.end() );
    316                 resn.alt.env = match.env;
    317                 resn.alt.openVars = match.openVars;
     294                resn.alt.env = std::move(match.env);
     295                resn.alt.openVars = std::move(match.openVars);
    318296
    319297                bindAssertion( assn.decl, assn.info, resn.alt, match, resn.inferred );
     
    364342        static const int recursionLimit = /* 10 */ 4;
    365343
    366         void resolveAssertions( Alternative& alt, const SymTab::Indexer& indexer, AltList& out ) {
     344        void resolveAssertions( Alternative& alt, const SymTab::Indexer& indexer, AltList& out, std::list<std::string>& errors ) {
    367345                // finish early if no assertions to resolve
    368346                if ( alt.need.empty() ) {
     
    376354                ResnList resns{ ResnState{ alt, root_indexer } };
    377355                ResnList new_resns{};
    378                 AssnCache assnCache;
    379356
    380357                // resolve assertions in breadth-first-order up to a limited number of levels deep
     
    385362                                for ( auto& assn : resn.need ) {
    386363                                        // fail early if any assertion is not resolvable
    387                                         if ( ! resolveAssertion( assn, resn, assnCache ) ) goto nextResn;
     364                                        if ( ! resolveAssertion( assn, resn ) ) {
     365                                                Indenter tabs{ Indenter::tabsize, 3 };
     366                                                std::ostringstream ss;
     367                                                ss << tabs << "Unsatisfiable alternative:\n";
     368                                                resn.alt.print( ss, ++tabs );
     369                                                ss << --tabs << "Could not satisfy assertion:\n";
     370                                                assn.decl->print( ss, ++tabs );
     371                                               
     372                                                errors.emplace_back( ss.str() );
     373                                                goto nextResn;
     374                                        }
    388375                                }
    389376
     
    396383                                        }
    397384                                } else {
    398                                         // only resolve each deferred assertion once
    399                                         std::sort( resn.deferred.begin(), resn.deferred.end() );
    400                                         auto last = std::unique( resn.deferred.begin(), resn.deferred.end() );
    401                                         resn.deferred.erase( last, resn.deferred.end() );
    402385                                        // resolve deferred assertions by mutual compatibility
    403386                                        std::vector<CandidateEnvMerger::OutType> compatible = filterCombos(
    404387                                                resn.deferred,
    405388                                                CandidateEnvMerger{ resn.alt.env, resn.alt.openVars, resn.indexer } );
     389                                        // fail early if no mutually-compatible assertion satisfaction
     390                                        if ( compatible.empty() ) {
     391                                                Indenter tabs{ Indenter::tabsize, 3 };
     392                                                std::ostringstream ss;
     393                                                ss << tabs << "Unsatisfiable alternative:\n";
     394                                                resn.alt.print( ss, ++tabs );
     395                                                ss << --tabs << "No mutually-compatible satisfaction for assertions:\n";
     396                                                ++tabs;
     397                                                for ( const auto& d : resn.deferred ) {
     398                                                        d.decl->print( ss, tabs );
     399                                                }
     400
     401                                                errors.emplace_back( ss.str() );
     402                                                goto nextResn;
     403                                        }
    406404                                        // sort by cost
    407405                                        CandidateCost coster{ resn.indexer };
     
    429427                                                        new_resn.newNeed.insert( match.need.begin(), match.need.end() );
    430428
    431                                                         // for each deferred assertion with the same form
    432                                                         for ( AssnId id : r.item.deferIds ) {
    433                                                                 bindAssertion(
    434                                                                         id.decl, id.info, new_resn.alt, match, new_resn.inferred );
    435                                                         }
     429                                                        bindAssertion( r.decl, r.info, new_resn.alt, match, new_resn.inferred );
    436430                                                }
    437431
  • src/ResolvExpr/ResolveAssertions.h

    r6a9d4b4 r933f32f  
    2424namespace ResolvExpr {
    2525        /// Recursively resolves all assertions provided in an alternative; returns true iff succeeds
    26         void resolveAssertions( Alternative& alt, const SymTab::Indexer& indexer, AltList& out );
     26        void resolveAssertions( Alternative& alt, const SymTab::Indexer& indexer, AltList& out, std::list<std::string>& errors );
    2727} // namespace ResolvExpr
    2828
  • src/ResolvExpr/Resolver.cc

    r6a9d4b4 r933f32f  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 12:17:01 2015
    11 // Last Modified By : Aaron B. Moss
    12 // Last Modified On : Fri Oct 05 09:43:00 2018
    13 // Update Count     : 214
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Tue Feb 19 18:09:56 2019
     13// Update Count     : 240
    1414//
    1515
     
    5454                }
    5555
    56                 void previsit( FunctionDecl *functionDecl );
    57                 void postvisit( FunctionDecl *functionDecl );
    58                 void previsit( ObjectDecl *objectDecll );
     56                void previsit( FunctionDecl * functionDecl );
     57                void postvisit( FunctionDecl * functionDecl );
     58                void previsit( ObjectDecl * objectDecll );
    5959                void previsit( EnumDecl * enumDecl );
    6060                void previsit( StaticAssertDecl * assertDecl );
     
    6363                void previsit( PointerType * at );
    6464
    65                 void previsit( ExprStmt *exprStmt );
    66                 void previsit( AsmExpr *asmExpr );
    67                 void previsit( AsmStmt *asmStmt );
    68                 void previsit( IfStmt *ifStmt );
    69                 void previsit( WhileStmt *whileStmt );
    70                 void previsit( ForStmt *forStmt );
    71                 void previsit( SwitchStmt *switchStmt );
    72                 void previsit( CaseStmt *caseStmt );
    73                 void previsit( BranchStmt *branchStmt );
    74                 void previsit( ReturnStmt *returnStmt );
    75                 void previsit( ThrowStmt *throwStmt );
    76                 void previsit( CatchStmt *catchStmt );
     65                void previsit( ExprStmt * exprStmt );
     66                void previsit( AsmExpr * asmExpr );
     67                void previsit( AsmStmt * asmStmt );
     68                void previsit( IfStmt * ifStmt );
     69                void previsit( WhileStmt * whileStmt );
     70                void previsit( ForStmt * forStmt );
     71                void previsit( SwitchStmt * switchStmt );
     72                void previsit( CaseStmt * caseStmt );
     73                void previsit( BranchStmt * branchStmt );
     74                void previsit( ReturnStmt * returnStmt );
     75                void previsit( ThrowStmt * throwStmt );
     76                void previsit( CatchStmt * catchStmt );
    7777                void previsit( WaitForStmt * stmt );
    7878
    79                 void previsit( SingleInit *singleInit );
    80                 void previsit( ListInit *listInit );
    81                 void previsit( ConstructorInit *ctorInit );
     79                void previsit( SingleInit * singleInit );
     80                void previsit( ListInit * listInit );
     81                void previsit( ConstructorInit * ctorInit );
    8282          private:
    8383                typedef std::list< Initializer * >::iterator InitIterator;
     
    105105        }
    106106
    107         void resolveDecl( Declaration * decl, const SymTab::Indexer &indexer ) {
     107        void resolveDecl( Declaration * decl, const SymTab::Indexer & indexer ) {
    108108                PassVisitor<Resolver> resolver( indexer );
    109109                maybeAccept( decl, resolver );
     
    149149                };
    150150
    151                 void finishExpr( Expression *&expr, const TypeEnvironment &env, TypeSubstitution * oldenv = nullptr ) {
     151                void finishExpr( Expression *& expr, const TypeEnvironment & env, TypeSubstitution * oldenv = nullptr ) {
    152152                        expr->env = oldenv ? oldenv->clone() : new TypeSubstitution;
    153153                        env.makeSubstitution( *expr->env );
     
    280280
    281281        // used in resolveTypeof
    282         Expression * resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer ) {
     282        Expression * resolveInVoidContext( Expression * expr, const SymTab::Indexer & indexer ) {
    283283                TypeEnvironment env;
    284284                return resolveInVoidContext( expr, indexer, env );
    285285        }
    286286
    287         Expression * resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer, TypeEnvironment &env ) {
     287        Expression * resolveInVoidContext( Expression * expr, const SymTab::Indexer & indexer, TypeEnvironment & env ) {
    288288                // it's a property of the language that a cast expression has either 1 or 0 interpretations; if it has 0
    289289                // interpretations, an exception has already been thrown.
    290290                assertf( expr, "expected a non-null expression." );
    291291
    292                 static CastExpr untyped( nullptr ); // cast to void
    293                 untyped.location = expr->location;
     292                CastExpr * untyped = new CastExpr( expr ); // cast to void
     293                untyped->location = expr->location;
    294294
    295295                // set up and resolve expression cast to void
    296                 untyped.arg = expr;
    297296                Alternative choice;
    298                 findUnfinishedKindExpression( &untyped, choice, indexer, "", standardAlternativeFilter, ResolvMode::withAdjustment() );
     297                findUnfinishedKindExpression( untyped, choice, indexer, "", standardAlternativeFilter, ResolvMode::withAdjustment() );
    299298                CastExpr * castExpr = strict_dynamic_cast< CastExpr * >( choice.expr );
     299                assert( castExpr );
    300300                env = std::move( choice.env );
    301301
     
    305305
    306306                // unlink the arg so that it isn't deleted twice at the end of the program
    307                 untyped.arg = nullptr;
     307                untyped->arg = nullptr;
    308308                return ret;
    309309        }
    310310
    311         void findVoidExpression( Expression *& untyped, const SymTab::Indexer &indexer ) {
     311        void findVoidExpression( Expression *& untyped, const SymTab::Indexer & indexer ) {
    312312                resetTyVarRenaming();
    313313                TypeEnvironment env;
     
    318318        }
    319319
    320         void findSingleExpression( Expression *&untyped, const SymTab::Indexer &indexer ) {
     320        void findSingleExpression( Expression *& untyped, const SymTab::Indexer & indexer ) {
    321321                findKindExpression( untyped, indexer, "", standardAlternativeFilter );
    322322        }
     
    337337                        if ( dynamic_cast< EnumInstType * >( type ) ) {
    338338                                return true;
    339                         } else if ( BasicType *bt = dynamic_cast< BasicType * >( type ) ) {
     339                        } else if ( BasicType * bt = dynamic_cast< BasicType * >( type ) ) {
    340340                                return bt->isInteger();
    341341                        } else if ( dynamic_cast< ZeroType* >( type ) != nullptr || dynamic_cast< OneType* >( type ) != nullptr ) {
     
    346346                }
    347347
    348                 void findIntegralExpression( Expression *& untyped, const SymTab::Indexer &indexer ) {
     348                void findIntegralExpression( Expression *& untyped, const SymTab::Indexer & indexer ) {
    349349                        findKindExpression( untyped, indexer, "condition", isIntegralType );
    350350                }
     
    402402        }
    403403
    404         void Resolver::previsit( ObjectDecl *objectDecl ) {
     404        void Resolver::previsit( ObjectDecl * objectDecl ) {
    405405                // To handle initialization of routine pointers, e.g., int (*fp)(int) = foo(), means that
    406406                // class-variable initContext is changed multiple time because the LHS is analysed twice.
     
    432432        }
    433433
    434         void Resolver::previsit( FunctionDecl *functionDecl ) {
     434        void Resolver::previsit( FunctionDecl * functionDecl ) {
    435435#if 0
    436436                std::cerr << "resolver visiting functiondecl ";
     
    442442        }
    443443
    444         void Resolver::postvisit( FunctionDecl *functionDecl ) {
     444        void Resolver::postvisit( FunctionDecl * functionDecl ) {
    445445                // default value expressions have an environment which shouldn't be there and trips up
    446446                // later passes.
     
    467467        }
    468468
    469         void Resolver::previsit( ExprStmt *exprStmt ) {
     469        void Resolver::previsit( ExprStmt * exprStmt ) {
    470470                visit_children = false;
    471471                assertf( exprStmt->expr, "ExprStmt has null Expression in resolver" );
     
    473473        }
    474474
    475         void Resolver::previsit( AsmExpr *asmExpr ) {
     475        void Resolver::previsit( AsmExpr * asmExpr ) {
    476476                visit_children = false;
    477477                findVoidExpression( asmExpr->operand, indexer );
     
    481481        }
    482482
    483         void Resolver::previsit( AsmStmt *asmStmt ) {
     483        void Resolver::previsit( AsmStmt * asmStmt ) {
    484484                visit_children = false;
    485485                acceptAll( asmStmt->get_input(), *visitor );
     
    487487        }
    488488
    489         void Resolver::previsit( IfStmt *ifStmt ) {
     489        void Resolver::previsit( IfStmt * ifStmt ) {
    490490                findIntegralExpression( ifStmt->condition, indexer );
    491491        }
    492492
    493         void Resolver::previsit( WhileStmt *whileStmt ) {
     493        void Resolver::previsit( WhileStmt * whileStmt ) {
    494494                findIntegralExpression( whileStmt->condition, indexer );
    495495        }
    496496
    497         void Resolver::previsit( ForStmt *forStmt ) {
     497        void Resolver::previsit( ForStmt * forStmt ) {
    498498                if ( forStmt->condition ) {
    499499                        findIntegralExpression( forStmt->condition, indexer );
     
    505505        }
    506506
    507         void Resolver::previsit( SwitchStmt *switchStmt ) {
     507        void Resolver::previsit( SwitchStmt * switchStmt ) {
    508508                GuardValue( currentObject );
    509509                findIntegralExpression( switchStmt->condition, indexer );
     
    512512        }
    513513
    514         void Resolver::previsit( CaseStmt *caseStmt ) {
     514        void Resolver::previsit( CaseStmt * caseStmt ) {
    515515                if ( caseStmt->condition ) {
    516516                        std::list< InitAlternative > initAlts = currentObject.getOptions();
     
    531531        }
    532532
    533         void Resolver::previsit( BranchStmt *branchStmt ) {
     533        void Resolver::previsit( BranchStmt * branchStmt ) {
    534534                visit_children = false;
    535535                // must resolve the argument for a computed goto
     
    542542        }
    543543
    544         void Resolver::previsit( ReturnStmt *returnStmt ) {
     544        void Resolver::previsit( ReturnStmt * returnStmt ) {
    545545                visit_children = false;
    546546                if ( returnStmt->expr ) {
     
    549549        }
    550550
    551         void Resolver::previsit( ThrowStmt *throwStmt ) {
     551        void Resolver::previsit( ThrowStmt * throwStmt ) {
    552552                visit_children = false;
    553553                // TODO: Replace *exception type with &exception type.
     
    561561        }
    562562
    563         void Resolver::previsit( CatchStmt *catchStmt ) {
     563        void Resolver::previsit( CatchStmt * catchStmt ) {
    564564                if ( catchStmt->cond ) {
    565565                        findSingleExpression( catchStmt->cond, new BasicType( noQualifiers, BasicType::Bool ), indexer );
     
    725725
    726726                                                }
    727                                                 catch( SemanticErrorException &e ) {
     727                                                catch( SemanticErrorException & e ) {
    728728                                                        errors.append( e );
    729729                                                }
    730730                                        }
    731731                                }
    732                                 catch( SemanticErrorException &e ) {
     732                                catch( SemanticErrorException & e ) {
    733733                                        errors.append( e );
    734734                                }
     
    782782        }
    783783
    784         void Resolver::previsit( SingleInit *singleInit ) {
     784        void Resolver::previsit( SingleInit * singleInit ) {
    785785                visit_children = false;
    786786                // resolve initialization using the possibilities as determined by the currentObject cursor
     
    814814                                if ( PointerType * pt = dynamic_cast< PointerType *>( newExpr->get_result() ) ) {
    815815                                        if ( isCharType( pt->get_base() ) ) {
    816                                                 if ( CastExpr *ce = dynamic_cast< CastExpr * >( newExpr ) ) {
     816                                                if ( CastExpr * ce = dynamic_cast< CastExpr * >( newExpr ) ) {
    817817                                                        // strip cast if we're initializing a char[] with a char *,
    818818                                                        // e.g.  char x[] = "hello";
     
    894894        }
    895895
    896         void Resolver::previsit( ConstructorInit *ctorInit ) {
     896        void Resolver::previsit( ConstructorInit * ctorInit ) {
    897897                visit_children = false;
    898898                // xxx - fallback init has been removed => remove fallbackInit function and remove complexity from FixInit and remove C-init from ConstructorInit
  • src/ResolvExpr/Resolver.h

    r6a9d4b4 r933f32f  
    1010// Created On       : Sun May 17 12:18:34 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Jul 22 09:36:57 2017
    13 // Update Count     : 3
     12// Last Modified On : Mon Feb 18 20:40:38 2019
     13// Update Count     : 4
    1414//
    1515
     
    2929        /// Checks types and binds syntactic constructs to typed representations
    3030        void resolve( std::list< Declaration * > translationUnit );
    31         void resolveDecl( Declaration *, const SymTab::Indexer &indexer );
    32         Expression *resolveInVoidContext( Expression * expr, const SymTab::Indexer &indexer );
    33         void findVoidExpression( Expression *& untyped, const SymTab::Indexer &indexer );
    34         void findSingleExpression( Expression *& untyped, const SymTab::Indexer &indexer );
    35         void findSingleExpression( Expression *& untyped, Type * type, const SymTab::Indexer &indexer );
     31        void resolveDecl( Declaration *, const SymTab::Indexer & indexer );
     32        Expression *resolveInVoidContext( Expression * expr, const SymTab::Indexer & indexer );
     33        void findVoidExpression( Expression *& untyped, const SymTab::Indexer & indexer );
     34        void findSingleExpression( Expression *& untyped, const SymTab::Indexer & indexer );
     35        void findSingleExpression( Expression *& untyped, Type * type, const SymTab::Indexer & indexer );
    3636        void resolveCtorInit( ConstructorInit * ctorInit, const SymTab::Indexer & indexer );
    3737        void resolveStmtExpr( StmtExpr * stmtExpr, const SymTab::Indexer & indexer );
  • src/ResolvExpr/TypeEnvironment.cc

    r6a9d4b4 r933f32f  
    386386        }
    387387
    388         bool TypeEnvironment::bindVarToVar( TypeInstType *var1, TypeInstType *var2, const TypeDecl::Data & data, AssertionSet &need, AssertionSet &have, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer ) {
     388        bool TypeEnvironment::bindVarToVar( TypeInstType *var1, TypeInstType *var2,
     389                        TypeDecl::Data && data, AssertionSet &need, AssertionSet &have,
     390                        const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer ) {
    389391
    390392                auto class1 = internal_lookup( var1->get_name() );
     
    428430                                        class1->set_type( common );
    429431                                }
     432                                class1->data.isComplete |= data.isComplete;
    430433                                env.erase( class2 );
    431434                        } else return false;
     
    435438                                class1->vars.insert( class2->vars.begin(), class2->vars.end() );
    436439                                class1->allowWidening = widen1;
     440                                class1->data.isComplete |= data.isComplete;
    437441                                env.erase( class2 );
    438442                        } else {
    439443                                class2->vars.insert( class1->vars.begin(), class1->vars.end() );
    440444                                class2->allowWidening = widen2;
     445                                class2->data.isComplete |= data.isComplete;
    441446                                env.erase( class1 );
    442447                        } // if
     
    445450                        class1->vars.insert( var2->get_name() );
    446451                        class1->allowWidening = widen1;
     452                        class1->data.isComplete |= data.isComplete;
    447453                } else if ( class2 != env.end() ) {
    448454                        // var1 unbound, add to class2
    449455                        class2->vars.insert( var1->get_name() );
    450456                        class2->allowWidening = widen2;
     457                        class2->data.isComplete |= data.isComplete;
    451458                } else {
    452459                        // neither var bound, create new class
  • src/ResolvExpr/TypeEnvironment.h

    r6a9d4b4 r933f32f  
    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
     
    139140                /// Binds the type classes represented by `var1` and `var2` together; will add
    140141                /// one or both classes if needed. Returns false on failure.
    141                 bool bindVarToVar( TypeInstType *var1, TypeInstType *var2, const TypeDecl::Data & data, AssertionSet &need, AssertionSet &have, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer );
     142                bool bindVarToVar( TypeInstType *var1, TypeInstType *var2, TypeDecl::Data && data, AssertionSet &need, AssertionSet &have, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer );
    142143
    143144                /// Disallows widening for all bindings in the environment
  • src/ResolvExpr/Unify.cc

    r6a9d4b4 r933f32f  
    2121#include <string>                 // for string, operator==, operator!=, bas...
    2222#include <utility>                // for pair, move
    23 
     23#include <vector>
     24
     25#include "AST/Node.hpp"
     26#include "AST/Type.hpp"
    2427#include "Common/PassVisitor.h"   // for PassVisitor
    2528#include "FindOpenVars.h"         // for findOpenVars
     
    172175                bool isopen2 = var2 && ( entry2 != openVars.end() );
    173176
    174                 if ( isopen1 && isopen2 && entry1->second == entry2->second ) {
    175                         result = env.bindVarToVar( var1, var2, entry1->second, needAssertions, haveAssertions, openVars, widenMode, indexer );
     177                if ( isopen1 && isopen2 ) {
     178                        if ( entry1->second.kind != entry2->second.kind ) {
     179                                result = false;
     180                        } else {
     181                                result = env.bindVarToVar(
     182                                        var1, var2, TypeDecl::Data{ entry1->second, entry2->second }, needAssertions,
     183                                        haveAssertions, openVars, widenMode, indexer );
     184                        }
    176185                } else if ( isopen1 ) {
    177186                        result = env.bindVar( var1, type2, entry1->second, needAssertions, haveAssertions, openVars, widenMode, indexer );
     
    624633        }
    625634
    626         // xxx - compute once and store in the FunctionType?
    627635        Type * extractResultType( FunctionType * function ) {
    628636                if ( function->get_returnVals().size() == 0 ) {
     
    638646                }
    639647        }
     648
     649        ast::ptr<ast::Type> extractResultType( const ast::FunctionType * func ) {
     650                assert(!"restore after AST added to build");
     651                // if ( func->returns.empty() ) return new ast::VoidType{};
     652                // if ( func->returns.size() == 1 ) return func->returns[0]->get_type();
     653
     654                // std::vector<ast::ptr<ast::Type>> tys;
     655                // for ( const ast::DeclWithType * decl : func->returns ) {
     656                //      tys.emplace_back( decl->get_type() );
     657                // }
     658                // return new ast::TupleType{ std::move(tys) };
     659        }
    640660} // namespace ResolvExpr
    641661
  • src/ResolvExpr/module.mk

    r6a9d4b4 r933f32f  
    1515###############################################################################
    1616
    17 SRC += ResolvExpr/AlternativeFinder.cc \
    18        ResolvExpr/Alternative.cc \
    19        ResolvExpr/Unify.cc \
    20        ResolvExpr/PtrsAssignable.cc \
    21        ResolvExpr/CommonType.cc \
    22        ResolvExpr/ConversionCost.cc \
    23        ResolvExpr/CastCost.cc \
    24        ResolvExpr/PtrsCastable.cc \
    25        ResolvExpr/AdjustExprType.cc \
    26        ResolvExpr/AlternativePrinter.cc \
    27        ResolvExpr/Resolver.cc \
    28        ResolvExpr/ResolveTypeof.cc \
    29        ResolvExpr/RenameVars.cc \
    30        ResolvExpr/FindOpenVars.cc \
    31        ResolvExpr/PolyCost.cc \
    32        ResolvExpr/Occurs.cc \
    33        ResolvExpr/TypeEnvironment.cc \
    34        ResolvExpr/CurrentObject.cc \
    35        ResolvExpr/ExplodedActual.cc \
    36        ResolvExpr/SpecCost.cc \
    37        ResolvExpr/ResolveAssertions.cc
     17SRC_RESOLVEXPR = \
     18      ResolvExpr/AdjustExprType.cc \
     19      ResolvExpr/Alternative.cc \
     20      ResolvExpr/AlternativeFinder.cc \
     21      ResolvExpr/CastCost.cc \
     22      ResolvExpr/CommonType.cc \
     23      ResolvExpr/ConversionCost.cc \
     24      ResolvExpr/CurrentObject.cc \
     25      ResolvExpr/ExplodedActual.cc \
     26      ResolvExpr/FindOpenVars.cc \
     27      ResolvExpr/Occurs.cc \
     28      ResolvExpr/PolyCost.cc \
     29      ResolvExpr/PtrsAssignable.cc \
     30      ResolvExpr/PtrsCastable.cc \
     31      ResolvExpr/RenameVars.cc \
     32      ResolvExpr/ResolveAssertions.cc \
     33      ResolvExpr/Resolver.cc \
     34      ResolvExpr/ResolveTypeof.cc \
     35      ResolvExpr/SpecCost.cc \
     36      ResolvExpr/TypeEnvironment.cc \
     37      ResolvExpr/Unify.cc
     38
     39SRC += $(SRC_RESOLVEXPR) ResolvExpr/AlternativePrinter.cc
     40SRCDEMANGLE += $(SRC_RESOLVEXPR)
  • src/ResolvExpr/typeops.h

    r6a9d4b4 r933f32f  
    1010// Created On       : Sun May 17 07:28:22 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Jul 22 09:36:18 2017
    13 // Update Count     : 3
     12// Last Modified On : Fri Feb  8 09:30:34 2019
     13// Update Count     : 4
    1414//
    1515
     
    1818#include <vector>
    1919
     20#include "AST/Node.hpp"
     21#include "AST/Type.hpp"
    2022#include "SynTree/SynTree.h"
    2123#include "SynTree/Type.h"
     
    99101        /// creates the type represented by the list of returnVals in a FunctionType. The caller owns the return value.
    100102        Type * extractResultType( FunctionType * functionType );
     103        /// Creates or extracts the type represented by the list of returns in a `FunctionType`.
     104        ast::ptr<ast::Type> extractResultType( const ast::FunctionType * func );
    101105
    102106        // in CommonType.cc
    103         Type *commonType( Type *type1, Type *type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars );
     107        Type * commonType( Type *type1, Type *type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars );
    104108
    105109        // in PolyCost.cc
  • src/SymTab/Indexer.cc

    r6a9d4b4 r933f32f  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 21:37:33 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Aug 17 16:08:40 2017
    13 // Update Count     : 20
     11// Last Modified By : Aaron B. Moss
     12// Last Modified On : Fri Mar  8 13:55:00 2019
     13// Update Count     : 21
    1414//
    1515
     
    1717
    1818#include <cassert>                 // for assert, strict_dynamic_cast
    19 #include <iostream>                // for operator<<, basic_ostream, ostream
    2019#include <string>                  // for string, operator<<, operator!=
     20#include <memory>                  // for shared_ptr, make_shared
    2121#include <unordered_map>           // for operator!=, unordered_map<>::const...
    2222#include <unordered_set>           // for unordered_set
    2323#include <utility>                 // for pair, make_pair, move
     24#include <vector>                  // for vector
    2425
    2526#include "CodeGen/OperatorTable.h" // for isCtorDtor, isCtorDtorAssign
    2627#include "Common/SemanticError.h"  // for SemanticError
    2728#include "Common/utility.h"        // for cloneAll
    28 #include "GenPoly/GenPoly.h"
     29#include "Common/Stats/Counter.h"  // for counters
     30#include "GenPoly/GenPoly.h"       // for getFunctionType
    2931#include "InitTweak/InitTweak.h"   // for isConstructor, isCopyFunction, isC...
    3032#include "Mangler.h"               // for Mangler
     
    3840#include "SynTree/Type.h"          // for Type, StructInstType, UnionInstType
    3941
    40 #define debugPrint(x) if ( doDebug ) { std::cerr << x; }
    41 
    4242namespace SymTab {
    43         std::ostream & operator<<( std::ostream & out, const Indexer::IdData & data ) {
    44                 return out << "(" << data.id << "," << data.baseExpr << ")";
    45         }
    46 
    47         typedef std::unordered_map< std::string, Indexer::IdData > MangleTable;
    48         typedef std::unordered_map< std::string, MangleTable > IdTable;
    49         typedef std::unordered_map< std::string, NamedTypeDecl* > TypeTable;
    50         typedef std::unordered_map< std::string, StructDecl* > StructTable;
    51         typedef std::unordered_map< std::string, EnumDecl* > EnumTable;
    52         typedef std::unordered_map< std::string, UnionDecl* > UnionTable;
    53         typedef std::unordered_map< std::string, TraitDecl* > TraitTable;
    54 
    55         void dump( const IdTable &table, std::ostream &os ) {
    56                 for ( IdTable::const_iterator id = table.begin(); id != table.end(); ++id ) {
    57                         for ( MangleTable::const_iterator mangle = id->second.begin(); mangle != id->second.end(); ++mangle ) {
    58                                 os << mangle->second << std::endl;
    59                         }
    60                 }
    61         }
    62 
    63         template< typename Decl >
    64         void dump( const std::unordered_map< std::string, Decl* > &table, std::ostream &os ) {
    65                 for ( typename std::unordered_map< std::string, Decl* >::const_iterator it = table.begin(); it != table.end(); ++it ) {
    66                         os << it->second << std::endl;
    67                 } // for
    68         }
    69 
    70         struct Indexer::Impl {
    71                 Impl( unsigned long _scope ) : refCount(1), scope( _scope ), size( 0 ), base(),
    72                                 idTable(), typeTable(), structTable(), enumTable(), unionTable(), traitTable() {}
    73                 Impl( unsigned long _scope, Indexer &&_base ) : refCount(1), scope( _scope ), size( 0 ), base( _base ),
    74                                 idTable(), typeTable(), structTable(), enumTable(), unionTable(), traitTable() {}
    75                 unsigned long refCount;   ///< Number of references to these tables
    76                 unsigned long scope;      ///< Scope these tables are associated with
    77                 unsigned long size;       ///< Number of elements stored in this table
    78                 const Indexer base;       ///< Base indexer this extends
    79 
    80                 IdTable idTable;          ///< Identifier namespace
    81                 TypeTable typeTable;      ///< Type namespace
    82                 StructTable structTable;  ///< Struct namespace
    83                 EnumTable enumTable;      ///< Enum namespace
    84                 UnionTable unionTable;    ///< Union namespace
    85                 TraitTable traitTable;    ///< Trait namespace
    86         };
    87 
    88         Indexer::Impl *Indexer::newRef( Indexer::Impl *toClone ) {
    89                 if ( ! toClone ) return 0;
    90 
    91                 // shorten the search chain by skipping empty links
    92                 Indexer::Impl *ret = toClone->size == 0 ? toClone->base.tables : toClone;
    93                 if ( ret ) { ++ret->refCount; }
    94 
    95                 return ret;
    96         }
    97 
    98         void Indexer::deleteRef( Indexer::Impl *toFree ) {
    99                 if ( ! toFree ) return;
    100 
    101                 if ( --toFree->refCount == 0 ) delete toFree;
    102         }
    103 
    104         void Indexer::removeSpecialOverrides( const std::string &id, std::list< IdData > & out ) const {
    105                 // only need to perform this step for constructors, destructors, and assignment functions
    106                 if ( ! CodeGen::isCtorDtorAssign( id ) ) return;
    107 
    108                 // helpful data structure to organize properties for a type
    109                 struct ValueType {
    110                         struct DeclBall { // properties for this particular decl
    111                                 IdData decl;
    112                                 bool isUserDefinedFunc;
    113                                 bool isCopyFunc;
     43
     44        // Statistics block
     45        namespace {
     46                static inline auto stats() {
     47                        using namespace Stats::Counters;
     48                        static auto group   = build<CounterGroup>("Indexers");
     49                        static struct {
     50                                SimpleCounter * count;
     51                                AverageCounter<double> * size;
     52                                SimpleCounter * new_scopes;
     53                                SimpleCounter * lazy_scopes;
     54                                AverageCounter<double> * avg_scope_depth;
     55                                MaxCounter<size_t> * max_scope_depth;
     56                                SimpleCounter * add_calls;
     57                                SimpleCounter * lookup_calls;
     58                                SimpleCounter * map_lookups;
     59                                SimpleCounter * map_mutations;
     60                        } ret = {
     61                                .count   = build<SimpleCounter>("Count", group),
     62                                .size    = build<AverageCounter<double>>("Average Size", group),
     63                                .new_scopes = build<SimpleCounter>("Scopes", group),
     64                                .lazy_scopes = build<SimpleCounter>("Lazy Scopes", group),
     65                                .avg_scope_depth = build<AverageCounter<double>>("Average Scope", group),
     66                                .max_scope_depth = build<MaxCounter<size_t>>("Max Scope", group),
     67                                .add_calls = build<SimpleCounter>("Add Calls", group),
     68                                .lookup_calls = build<SimpleCounter>("Lookup Calls", group),
     69                                .map_lookups = build<SimpleCounter>("Map Lookups", group),
     70                                .map_mutations = build<SimpleCounter>("Map Mutations", group)
    11471                        };
    115                         // properties for this type
    116                         bool existsUserDefinedCopyFunc = false;    // user-defined copy ctor found
    117                         BaseSyntaxNode * deleteStmt = nullptr;     // non-null if a user-defined function is found
    118                         std::list< DeclBall > decls;
    119 
    120                         // another FunctionDecl for the current type was found - determine
    121                         // if it has special properties and update data structure accordingly
    122                         ValueType & operator+=( IdData data ) {
    123                                 DeclarationWithType * function = data.id;
    124                                 bool isUserDefinedFunc = ! LinkageSpec::isOverridable( function->linkage );
    125                                 bool isCopyFunc = InitTweak::isCopyFunction( function, function->name );
    126                                 decls.push_back( DeclBall{ data, isUserDefinedFunc, isCopyFunc } );
    127                                 existsUserDefinedCopyFunc = existsUserDefinedCopyFunc || (isUserDefinedFunc && isCopyFunc);
    128                                 if ( isUserDefinedFunc && ! deleteStmt ) {
    129                                         // any user-defined function can act as an implicit delete statement for generated constructors.
    130                                         // a delete stmt should not act as an implicit delete statement.
    131                                         deleteStmt = data.id;
    132                                 }
    133                                 return *this;
    134                         }
    135                 }; // ValueType
    136 
    137                 std::list< IdData > copy;
    138                 copy.splice( copy.end(), out );
    139 
    140                 // organize discovered declarations by type
    141                 std::unordered_map< std::string, ValueType > funcMap;
    142                 for ( auto decl : copy ) {
    143                         if ( FunctionDecl * function = dynamic_cast< FunctionDecl * >( decl.id ) ) {
    144                                 std::list< DeclarationWithType * > & params = function->type->parameters;
    145                                 assert( ! params.empty() );
    146                                 // use base type of pointer, so that qualifiers on the pointer type aren't considered.
    147                                 Type * base = InitTweak::getPointerBase( params.front()->get_type() );
    148                                 assert( base );
    149                                 funcMap[ Mangler::mangle( base ) ] += decl;
    150                         } else {
    151                                 out.push_back( decl );
    152                         }
    153                 }
    154 
    155                 // if a type contains user defined ctor/dtor/assign, then special rules trigger, which determine
    156                 // the set of ctor/dtor/assign that can be used  by the requester. In particular, if the user defines
    157                 // a default ctor, then the generated default ctor is unavailable, likewise for copy ctor
    158                 // and dtor. If the user defines any ctor/dtor, then no generated field ctors are available.
    159                 // If the user defines any ctor then the generated default ctor is unavailable (intrinsic default
    160                 // ctor must be overridden exactly). If the user defines anything that looks like a copy constructor,
    161                 // then the generated copy constructor is unavailable, and likewise for the assignment operator.
    162                 for ( std::pair< const std::string, ValueType > & pair : funcMap ) {
    163                         ValueType & val = pair.second;
    164                         for ( ValueType::DeclBall ball : val.decls ) {
    165                                 bool isNotUserDefinedFunc = ! ball.isUserDefinedFunc && ball.decl.id->linkage != LinkageSpec::Intrinsic;
    166                                 bool isCopyFunc = ball.isCopyFunc;
    167                                 bool existsUserDefinedCopyFunc = val.existsUserDefinedCopyFunc;
    168 
    169                                 // only implicitly delete non-user defined functions that are not intrinsic, and are
    170                                 // not copy functions (assignment or copy constructor). If a  user-defined copy function exists,
    171                                 // do not pass along the non-user-defined copy functions since signatures do not have to match,
    172                                 // and the generated functions will often be cheaper.
    173                                 if ( isNotUserDefinedFunc ) {
    174                                         if ( isCopyFunc ) {
    175                                                 // Skip over non-user-defined copy functions when there is a user-defined copy function.
    176                                                 // Since their signatures do not have to be exact, deleting them is the wrong choice.
    177                                                 if ( existsUserDefinedCopyFunc ) continue;
    178                                         } else {
    179                                                 // delete non-user-defined non-copy functions if applicable.
    180                                                 // deleteStmt will be non-null only if a user-defined function is found.
    181                                                 ball.decl.deleteStmt = val.deleteStmt;
    182                                         }
    183                                 }
    184                                 out.push_back( ball.decl );
    185                         }
    186                 }
    187         }
    188 
    189         void Indexer::makeWritable() {
    190                 if ( ! tables ) {
    191                         // create indexer if not yet set
    192                         tables = new Indexer::Impl( scope );
    193                 } else if ( tables->refCount > 1 || tables->scope != scope ) {
    194                         // make this indexer the base of a fresh indexer at the current scope
    195                         tables = new Indexer::Impl( scope, std::move( *this ) );
    196                 }
    197         }
    198 
    199         Indexer::Indexer() : tables( 0 ), scope( 0 ) {}
    200 
    201         Indexer::Indexer( const Indexer &that ) : doDebug( that.doDebug ), tables( newRef( that.tables ) ), scope( that.scope ) {}
    202 
    203         Indexer::Indexer( Indexer &&that ) : doDebug( that.doDebug ), tables( that.tables ), scope( that.scope ) {
    204                 that.tables = 0;
    205         }
     72                        return ret;
     73                }
     74        }
     75
     76        Indexer::Indexer()
     77        : idTable(), typeTable(), structTable(), enumTable(), unionTable(), traitTable(),
     78          prevScope(), scope( 0 ), repScope( 0 ) { ++*stats().count; }
    20679
    20780        Indexer::~Indexer() {
    208                 deleteRef( tables );
    209         }
    210 
    211         Indexer& Indexer::operator= ( const Indexer &that ) {
    212                 deleteRef( tables );
    213 
    214                 tables = newRef( that.tables );
    215                 scope = that.scope;
    216                 doDebug = that.doDebug;
    217 
    218                 return *this;
    219         }
    220 
    221         Indexer& Indexer::operator= ( Indexer &&that ) {
    222                 deleteRef( tables );
    223 
    224                 tables = that.tables;
    225                 scope = that.scope;
    226                 doDebug = that.doDebug;
    227 
    228                 that.tables = 0;
    229 
    230                 return *this;
     81                stats().size->push( idTable ? idTable->size() : 0 );
     82        }
     83
     84        void Indexer::lazyInitScope() {
     85                if ( repScope < scope ) {
     86                        ++*stats().lazy_scopes;
     87                        // create rollback
     88                        prevScope = std::make_shared<Indexer>( *this );
     89                        // update repScope
     90                        repScope = scope;
     91                }
     92        }
     93
     94        void Indexer::enterScope() {
     95                ++scope;
     96
     97                ++*stats().new_scopes;
     98                stats().avg_scope_depth->push( scope );
     99                stats().max_scope_depth->push( scope );
     100        }
     101
     102        void Indexer::leaveScope() {
     103                if ( repScope == scope ) {
     104                        Ptr prev = prevScope;           // make sure prevScope stays live
     105                        *this = std::move(*prevScope);  // replace with previous scope
     106                }
     107
     108                --scope;
    231109        }
    232110
    233111        void Indexer::lookupId( const std::string &id, std::list< IdData > &out ) const {
    234                 std::unordered_set< std::string > foundMangleNames;
    235 
    236                 Indexer::Impl *searchTables = tables;
    237                 while ( searchTables ) {
    238 
    239                         IdTable::const_iterator decls = searchTables->idTable.find( id );
    240                         if ( decls != searchTables->idTable.end() ) {
    241                                 const MangleTable &mangleTable = decls->second;
    242                                 for ( MangleTable::const_iterator decl = mangleTable.begin(); decl != mangleTable.end(); ++decl ) {
    243                                         // mark the mangled name as found, skipping this insertion if a declaration for that name has already been found
    244                                         if ( foundMangleNames.insert( decl->first ).second == false ) continue;
    245 
    246                                         out.push_back( decl->second );
    247                                 }
    248                         }
    249 
    250                         // get declarations from base indexers
    251                         searchTables = searchTables->base.tables;
    252                 }
    253 
    254                 // some special functions, e.g. constructors and destructors
    255                 // remove autogenerated functions when they are defined so that
    256                 // they can never be matched
    257                 removeSpecialOverrides( id, out );
     112                ++*stats().lookup_calls;
     113                if ( ! idTable ) return;
     114
     115                ++*stats().map_lookups;
     116                auto decls = idTable->find( id );
     117                if ( decls == idTable->end() ) return;
     118
     119                for ( auto decl : *(decls->second) ) {
     120                        out.push_back( decl.second );
     121                }
    258122        }
    259123
    260124        NamedTypeDecl *Indexer::lookupType( const std::string &id ) const {
    261                 if ( ! tables ) return 0;
    262 
    263                 TypeTable::const_iterator ret = tables->typeTable.find( id );
    264                 return ret != tables->typeTable.end() ? ret->second : tables->base.lookupType( id );
     125                ++*stats().lookup_calls;
     126                if ( ! typeTable ) return nullptr;
     127                ++*stats().map_lookups;
     128                auto it = typeTable->find( id );
     129                return it == typeTable->end() ? nullptr : it->second.decl;
    265130        }
    266131
    267132        StructDecl *Indexer::lookupStruct( const std::string &id ) const {
    268                 if ( ! tables ) return 0;
    269 
    270                 StructTable::const_iterator ret = tables->structTable.find( id );
    271                 return ret != tables->structTable.end() ? ret->second : tables->base.lookupStruct( id );
     133                ++*stats().lookup_calls;
     134                if ( ! structTable ) return nullptr;
     135                ++*stats().map_lookups;
     136                auto it = structTable->find( id );
     137                return it == structTable->end() ? nullptr : it->second.decl;
     138        }
     139
     140        EnumDecl *Indexer::lookupEnum( const std::string &id ) const {
     141                ++*stats().lookup_calls;
     142                if ( ! enumTable ) return nullptr;
     143                ++*stats().map_lookups;
     144                auto it = enumTable->find( id );
     145                return it == enumTable->end() ? nullptr : it->second.decl;
     146        }
     147
     148        UnionDecl *Indexer::lookupUnion( const std::string &id ) const {
     149                ++*stats().lookup_calls;
     150                if ( ! unionTable ) return nullptr;
     151                ++*stats().map_lookups;
     152                auto it = unionTable->find( id );
     153                return it == unionTable->end() ? nullptr : it->second.decl;
     154        }
     155
     156        TraitDecl *Indexer::lookupTrait( const std::string &id ) const {
     157                ++*stats().lookup_calls;
     158                if ( ! traitTable ) return nullptr;
     159                ++*stats().map_lookups;
     160                auto it = traitTable->find( id );
     161                return it == traitTable->end() ? nullptr : it->second.decl;
     162        }
     163
     164        const Indexer* Indexer::atScope( unsigned long target ) const {
     165                // by lazy construction, final indexer in list has repScope 0, cannot be > target
     166                // otherwise, will find first scope representing the target
     167                const Indexer* indexer = this;
     168                while ( indexer->repScope > target ) {
     169                        indexer = indexer->prevScope.get();
     170                }
     171                return indexer;
    272172        }
    273173
    274174        NamedTypeDecl *Indexer::globalLookupType( const std::string &id ) const {
    275                 return lookupTypeAtScope( id, 0 );
     175                return atScope( 0 )->lookupType( id );
    276176        }
    277177
    278178        StructDecl *Indexer::globalLookupStruct( const std::string &id ) const {
    279                 return lookupStructAtScope( id, 0 );
     179                return atScope( 0 )->lookupStruct( id );
    280180        }
    281181
    282182        UnionDecl *Indexer::globalLookupUnion( const std::string &id ) const {
    283                 return lookupUnionAtScope( id, 0 );
     183                return atScope( 0 )->lookupUnion( id );
    284184        }
    285185
    286186        EnumDecl *Indexer::globalLookupEnum( const std::string &id ) const {
    287                 return lookupEnumAtScope( id, 0 );
    288         }
    289 
    290         EnumDecl *Indexer::lookupEnum( const std::string &id ) const {
    291                 if ( ! tables ) return 0;
    292 
    293                 EnumTable::const_iterator ret = tables->enumTable.find( id );
    294                 return ret != tables->enumTable.end() ? ret->second : tables->base.lookupEnum( id );
    295         }
    296 
    297         UnionDecl *Indexer::lookupUnion( const std::string &id ) const {
    298                 if ( ! tables ) return 0;
    299 
    300                 UnionTable::const_iterator ret = tables->unionTable.find( id );
    301                 return ret != tables->unionTable.end() ? ret->second : tables->base.lookupUnion( id );
    302         }
    303 
    304         TraitDecl *Indexer::lookupTrait( const std::string &id ) const {
    305                 if ( ! tables ) return 0;
    306 
    307                 TraitTable::const_iterator ret = tables->traitTable.find( id );
    308                 return ret != tables->traitTable.end() ? ret->second : tables->base.lookupTrait( id );
    309         }
    310 
    311         const Indexer::IdData * Indexer::lookupIdAtScope( const std::string &id, const std::string &mangleName, unsigned long scope ) const {
    312                 if ( ! tables ) return nullptr;
    313                 if ( tables->scope < scope ) return nullptr;
    314 
    315                 IdTable::const_iterator decls = tables->idTable.find( id );
    316                 if ( decls != tables->idTable.end() ) {
    317                         const MangleTable &mangleTable = decls->second;
    318                         MangleTable::const_iterator decl = mangleTable.find( mangleName );
    319                         if ( decl != mangleTable.end() ) return &decl->second;
    320                 }
    321 
    322                 return tables->base.lookupIdAtScope( id, mangleName, scope );
    323         }
    324 
    325         Indexer::IdData * Indexer::lookupIdAtScope( const std::string &id, const std::string &mangleName, unsigned long scope ) {
    326                 return const_cast<IdData *>(const_cast<const Indexer *>(this)->lookupIdAtScope( id, mangleName, scope ));
    327         }
    328 
    329         bool Indexer::hasIncompatibleCDecl( const std::string &id, const std::string &mangleName, unsigned long scope ) const {
    330                 if ( ! tables ) return false;
    331                 if ( tables->scope < scope ) return false;
    332 
    333                 IdTable::const_iterator decls = tables->idTable.find( id );
    334                 if ( decls != tables->idTable.end() ) {
    335                         const MangleTable &mangleTable = decls->second;
    336                         for ( MangleTable::const_iterator decl = mangleTable.begin(); decl != mangleTable.end(); ++decl ) {
    337                                 // check for C decls with the same name, skipping those with a compatible type (by mangleName)
    338                                 if ( ! LinkageSpec::isMangled( decl->second.id->get_linkage() ) && decl->first != mangleName ) return true;
    339                         }
    340                 }
    341 
    342                 return tables->base.hasIncompatibleCDecl( id, mangleName, scope );
    343         }
    344 
    345         bool Indexer::hasCompatibleCDecl( const std::string &id, const std::string &mangleName, unsigned long scope ) const {
    346                 if ( ! tables ) return false;
    347                 if ( tables->scope < scope ) return false;
    348 
    349                 IdTable::const_iterator decls = tables->idTable.find( id );
    350                 if ( decls != tables->idTable.end() ) {
    351                         const MangleTable &mangleTable = decls->second;
    352                         for ( MangleTable::const_iterator decl = mangleTable.begin(); decl != mangleTable.end(); ++decl ) {
    353                                 // check for C decls with the same name, skipping
    354                                 // those with an incompatible type (by mangleName)
    355                                 if ( ! LinkageSpec::isMangled( decl->second.id->get_linkage() ) && decl->first == mangleName ) return true;
    356                         }
    357                 }
    358 
    359                 return tables->base.hasCompatibleCDecl( id, mangleName, scope );
    360         }
    361 
    362         NamedTypeDecl *Indexer::lookupTypeAtScope( const std::string &id, unsigned long scope ) const {
    363                 if ( ! tables ) return 0;
    364                 if ( tables->scope < scope ) return 0;
    365                 if ( tables->scope > scope ) return tables->base.lookupTypeAtScope( id, scope );
    366 
    367                 TypeTable::const_iterator ret = tables->typeTable.find( id );
    368                 return ret != tables->typeTable.end() ? ret->second : tables->base.lookupTypeAtScope( id, scope );
    369         }
    370 
    371         StructDecl *Indexer::lookupStructAtScope( const std::string &id, unsigned long scope ) const {
    372                 if ( ! tables ) return 0;
    373                 if ( tables->scope < scope ) return 0;
    374                 if ( tables->scope > scope ) return tables->base.lookupStructAtScope( id, scope );
    375 
    376                 StructTable::const_iterator ret = tables->structTable.find( id );
    377                 return ret != tables->structTable.end() ? ret->second : tables->base.lookupStructAtScope( id, scope );
    378         }
    379 
    380         EnumDecl *Indexer::lookupEnumAtScope( const std::string &id, unsigned long scope ) const {
    381                 if ( ! tables ) return 0;
    382                 if ( tables->scope < scope ) return 0;
    383                 if ( tables->scope > scope ) return tables->base.lookupEnumAtScope( id, scope );
    384 
    385                 EnumTable::const_iterator ret = tables->enumTable.find( id );
    386                 return ret != tables->enumTable.end() ? ret->second : tables->base.lookupEnumAtScope( id, scope );
    387         }
    388 
    389         UnionDecl *Indexer::lookupUnionAtScope( const std::string &id, unsigned long scope ) const {
    390                 if ( ! tables ) return 0;
    391                 if ( tables->scope < scope ) return 0;
    392                 if ( tables->scope > scope ) return tables->base.lookupUnionAtScope( id, scope );
    393 
    394                 UnionTable::const_iterator ret = tables->unionTable.find( id );
    395                 return ret != tables->unionTable.end() ? ret->second : tables->base.lookupUnionAtScope( id, scope );
    396         }
    397 
    398         TraitDecl *Indexer::lookupTraitAtScope( const std::string &id, unsigned long scope ) const {
    399                 if ( ! tables ) return 0;
    400                 if ( tables->scope < scope ) return 0;
    401                 if ( tables->scope > scope ) return tables->base.lookupTraitAtScope( id, scope );
    402 
    403                 TraitTable::const_iterator ret = tables->traitTable.find( id );
    404                 return ret != tables->traitTable.end() ? ret->second : tables->base.lookupTraitAtScope( id, scope );
     187                return atScope( 0 )->lookupEnum( id );
    405188        }
    406189
     
    424207        }
    425208
    426         bool addedIdConflicts( Indexer::IdData & existing, DeclarationWithType *added, BaseSyntaxNode * deleteStmt, Indexer::ConflictFunction handleConflicts ) {
    427                 // if we're giving the same name mangling to things of different types then there is something wrong
     209       
     210        bool Indexer::addedIdConflicts(
     211                        const Indexer::IdData & existing, DeclarationWithType *added,
     212                        Indexer::OnConflict handleConflicts, BaseSyntaxNode * deleteStmt ) {
     213                // if we're giving the same name mangling to things of different types then there is
     214                // something wrong
    428215                assert( (isObject( added ) && isObject( existing.id ) )
    429216                        || ( isFunction( added ) && isFunction( existing.id ) ) );
    430217
    431                 if ( LinkageSpec::isOverridable( existing.id->get_linkage() ) ) {
     218                if ( LinkageSpec::isOverridable( existing.id->linkage ) ) {
    432219                        // new definition shadows the autogenerated one, even at the same scope
    433220                        return false;
    434                 } else if ( LinkageSpec::isMangled( added->get_linkage() ) || ResolvExpr::typesCompatible( added->get_type(), existing.id->get_type(), Indexer() ) ) {
     221                } else if ( LinkageSpec::isMangled( added->linkage )
     222                                || ResolvExpr::typesCompatible(
     223                                        added->get_type(), existing.id->get_type(), Indexer() ) ) {
    435224
    436225                        // it is a conflict if one declaration is deleted and the other is not
    437226                        if ( deleteStmt && ! existing.deleteStmt ) {
    438                                 return handleConflicts( existing, "deletion of defined identifier " );
     227                                if ( handleConflicts.mode == OnConflict::Error ) {
     228                                        SemanticError( added, "deletion of defined identifier " );
     229                                }
     230                                return true;
    439231                        } else if ( ! deleteStmt && existing.deleteStmt ) {
    440                                 return handleConflicts( existing, "definition of deleted identifier " );
     232                                if ( handleConflicts.mode == OnConflict::Error ) {
     233                                        SemanticError( added, "definition of deleted identifier " );
     234                                }
     235                                return true;
    441236                        }
    442237
    443238                        if ( isDefinition( added ) && isDefinition( existing.id ) ) {
    444                                 if ( isFunction( added ) ) {
    445                                         return handleConflicts( existing, "duplicate function definition for " );
     239                                if ( handleConflicts.mode == OnConflict::Error ) {
     240                                        SemanticError( added,
     241                                                isFunction( added ) ?
     242                                                        "duplicate function definition for " :
     243                                                        "duplicate object definition for " );
     244                                }
     245                                return true;
     246                        } // if
     247                } else {
     248                        if ( handleConflicts.mode == OnConflict::Error ) {
     249                                SemanticError( added, "duplicate definition for " );
     250                        }
     251                        return true;
     252                } // if
     253
     254                return true;
     255        }
     256
     257        bool Indexer::hasCompatibleCDecl( const std::string &id, const std::string &mangleName ) const {
     258                if ( ! idTable ) return false;
     259
     260                ++*stats().map_lookups;
     261                auto decls = idTable->find( id );
     262                if ( decls == idTable->end() ) return false;
     263
     264                for ( auto decl : *(decls->second) ) {
     265                        // skip other scopes (hidden by this decl)
     266                        if ( decl.second.scope != scope ) continue;
     267                        // check for C decl with compatible type (by mangleName)
     268                        if ( ! LinkageSpec::isMangled( decl.second.id->linkage ) && decl.first == mangleName ) {
     269                                return true;
     270                        }
     271                }
     272               
     273                return false;
     274        }
     275
     276        bool Indexer::hasIncompatibleCDecl(
     277                        const std::string &id, const std::string &mangleName ) const {
     278                if ( ! idTable ) return false;
     279
     280                ++*stats().map_lookups;
     281                auto decls = idTable->find( id );
     282                if ( decls == idTable->end() ) return false;
     283
     284                for ( auto decl : *(decls->second) ) {
     285                        // skip other scopes (hidden by this decl)
     286                        if ( decl.second.scope != scope ) continue;
     287                        // check for C decl with incompatible type (by manglename)
     288                        if ( ! LinkageSpec::isMangled( decl.second.id->linkage ) && decl.first != mangleName ) {
     289                                return true;
     290                        }
     291                }
     292
     293                return false;
     294        }
     295
     296        /// gets the base type of the first parameter; decl must be a ctor/dtor/assignment function
     297        std::string getOtypeKey( FunctionDecl* function ) {
     298                auto& params = function->type->parameters;
     299                assert( ! params.empty() );
     300                // use base type of pointer, so that qualifiers on the pointer type aren't considered.
     301                Type* base = InitTweak::getPointerBase( params.front()->get_type() );
     302                assert( base );
     303                return Mangler::mangle( base );
     304        }
     305
     306        /// gets the declaration for the function acting on a type specified by otype key,
     307        /// nullptr if none such
     308        FunctionDecl * getFunctionForOtype( DeclarationWithType * decl, const std::string& otypeKey ) {
     309                FunctionDecl * func = dynamic_cast< FunctionDecl * >( decl );
     310                if ( ! func || otypeKey != getOtypeKey( func ) ) return nullptr;
     311                return func;
     312        }
     313
     314        bool Indexer::removeSpecialOverrides(
     315                        Indexer::IdData& data, Indexer::MangleTable::Ptr& mangleTable ) {
     316                // if a type contains user defined ctor/dtor/assign, then special rules trigger, which
     317                // determinethe set of ctor/dtor/assign that can be used  by the requester. In particular,
     318                // if the user defines a default ctor, then the generated default ctor is unavailable,
     319                // likewise for copy ctor and dtor. If the user defines any ctor/dtor, then no generated
     320                // field ctors are available. If the user defines any ctor then the generated default ctor
     321                // is unavailable (intrinsic default ctor must be overridden exactly). If the user defines
     322                // anything that looks like a copy constructor, then the generated copy constructor is
     323                // unavailable, and likewise for the assignment operator.
     324
     325                // only relevant on function declarations
     326                FunctionDecl * function = dynamic_cast< FunctionDecl * >( data.id );
     327                if ( ! function ) return true;
     328                // only need to perform this check for constructors, destructors, and assignment functions
     329                if ( ! CodeGen::isCtorDtorAssign( data.id->name ) ) return true;
     330
     331                // set up information for this type
     332                bool dataIsUserDefinedFunc = ! LinkageSpec::isOverridable( function->linkage );
     333                bool dataIsCopyFunc = InitTweak::isCopyFunction( function, function->name );
     334                std::string dataOtypeKey = getOtypeKey( function );
     335
     336                if ( dataIsUserDefinedFunc && dataIsCopyFunc ) {
     337                        // this is a user-defined copy function
     338                        // if this is the first such, delete/remove non-user-defined overloads as needed
     339                        std::vector< std::string > removed;
     340                        std::vector< MangleTable::value_type > deleted;
     341                        bool alreadyUserDefinedFunc = false;
     342                       
     343                        for ( const auto& entry : *mangleTable ) {
     344                                // skip decls that aren't functions or are for the wrong type
     345                                FunctionDecl * decl = getFunctionForOtype( entry.second.id, dataOtypeKey );
     346                                if ( ! decl ) continue;
     347
     348                                bool isCopyFunc = InitTweak::isCopyFunction( decl, decl->name );
     349                                if ( ! LinkageSpec::isOverridable( decl->linkage ) ) {
     350                                        // matching user-defined function
     351                                        if ( isCopyFunc ) {
     352                                                // mutation already performed, return early
     353                                                return true;
     354                                        } else {
     355                                                // note that non-copy deletions already performed
     356                                                alreadyUserDefinedFunc = true;
     357                                        }
    446358                                } else {
    447                                         return handleConflicts( existing, "duplicate object definition for " );
    448                                 } // if
    449                         } // if
    450                 } else {
    451                         return handleConflicts( existing, "duplicate definition for " );
    452                 } // if
    453 
     359                                        // non-user-defined function; mark for deletion/removal as appropriate
     360                                        if ( isCopyFunc ) {
     361                                                removed.push_back( entry.first );
     362                                        } else if ( ! alreadyUserDefinedFunc ) {
     363                                                deleted.push_back( entry );
     364                                        }
     365                                }
     366                        }
     367
     368                        // perform removals from mangle table, and deletions if necessary
     369                        for ( const auto& key : removed ) {
     370                                ++*stats().map_mutations;
     371                                mangleTable = mangleTable->erase( key );
     372                        }
     373                        if ( ! alreadyUserDefinedFunc ) for ( const auto& entry : deleted ) {
     374                                ++*stats().map_mutations;
     375                                mangleTable = mangleTable->set( entry.first, IdData{ entry.second, function } );
     376                        }
     377                } else if ( dataIsUserDefinedFunc ) {
     378                        // this is a user-defined non-copy function
     379                        // if this is the first user-defined function, delete non-user-defined overloads
     380                        std::vector< MangleTable::value_type > deleted;
     381                       
     382                        for ( const auto& entry : *mangleTable ) {
     383                                // skip decls that aren't functions or are for the wrong type
     384                                FunctionDecl * decl = getFunctionForOtype( entry.second.id, dataOtypeKey );
     385                                if ( ! decl ) continue;
     386
     387                                // exit early if already a matching user-defined function;
     388                                // earlier function will have mutated table
     389                                if ( ! LinkageSpec::isOverridable( decl->linkage ) ) return true;
     390
     391                                // skip mutating intrinsic functions
     392                                if ( decl->linkage == LinkageSpec::Intrinsic ) continue;
     393
     394                                // user-defined non-copy functions do not override copy functions
     395                                if ( InitTweak::isCopyFunction( decl, decl->name ) ) continue;
     396
     397                                // this function to be deleted after mangleTable iteration is complete
     398                                deleted.push_back( entry );
     399                        }
     400
     401                        // mark deletions to update mangle table
     402                        // this needs to be a separate loop because of iterator invalidation
     403                        for ( const auto& entry : deleted ) {
     404                                ++*stats().map_mutations;
     405                                mangleTable = mangleTable->set( entry.first, IdData{ entry.second, function } );
     406                        }
     407                } else if ( function->linkage != LinkageSpec::Intrinsic ) {
     408                        // this is an overridable generated function
     409                        // if there already exists a matching user-defined function, delete this appropriately
     410                        for ( const auto& entry : *mangleTable ) {
     411                                // skip decls that aren't functions or are for the wrong type
     412                                FunctionDecl * decl = getFunctionForOtype( entry.second.id, dataOtypeKey );
     413                                if ( ! decl ) continue;
     414
     415                                // skip non-user-defined functions
     416                                if ( LinkageSpec::isOverridable( decl->linkage ) ) continue;
     417
     418                                if ( dataIsCopyFunc ) {
     419                                        // remove current function if exists a user-defined copy function
     420                                        // since the signatures for copy functions don't need to match exactly, using
     421                                        // a delete statement is the wrong approach
     422                                        if ( InitTweak::isCopyFunction( decl, decl->name ) ) return false;
     423                                } else {
     424                                        // mark current function deleted by first user-defined function found
     425                                        data.deleteStmt = decl;
     426                                        return true;
     427                                }
     428                        }
     429                }
     430               
     431                // nothing (more) to fix, return true
    454432                return true;
    455433        }
    456434
    457         void Indexer::addId( DeclarationWithType *decl, ConflictFunction handleConflicts, Expression * baseExpr, BaseSyntaxNode * deleteStmt ) {
    458                 if ( decl->name == "" ) return;
    459                 debugPrint( "Adding Id " << decl->name << std::endl );
    460                 makeWritable();
    461 
     435        void Indexer::addId(
     436                        DeclarationWithType *decl, OnConflict handleConflicts, Expression * baseExpr,
     437                        BaseSyntaxNode * deleteStmt ) {
     438                ++*stats().add_calls;
    462439                const std::string &name = decl->name;
     440                if ( name == "" ) return;
     441               
    463442                std::string mangleName;
    464443                if ( LinkageSpec::isOverridable( decl->linkage ) ) {
    465                         // mangle the name without including the appropriate suffix, so overridable routines are placed into the
    466                         // same "bucket" as their user defined versions.
     444                        // mangle the name without including the appropriate suffix, so overridable routines
     445                        // are placed into the same "bucket" as their user defined versions.
    467446                        mangleName = Mangler::mangle( decl, false );
    468447                } else {
     
    470449                } // if
    471450
    472                 // this ensures that no two declarations with the same unmangled name at the same scope both have C linkage
    473                 if ( ! LinkageSpec::isMangled( decl->linkage ) ) {
    474                         // NOTE this is broken in Richard's original code in such a way that it never triggers (it
    475                         // doesn't check decls that have the same manglename, and all C-linkage decls are defined to
    476                         // have their name as their manglename, hence the error can never trigger).
    477                         // The code here is closer to correct, but name mangling would have to be completely
    478                         // isomorphic to C type-compatibility, which it may not be.
    479                         if ( hasIncompatibleCDecl( name, mangleName, scope ) ) {
     451                // this ensures that no two declarations with the same unmangled name at the same scope
     452                // both have C linkage
     453                if ( LinkageSpec::isMangled( decl->linkage ) ) {
     454                        // Check that a Cforall declaration doesn't override any C declaration
     455                        if ( hasCompatibleCDecl( name, mangleName ) ) {
     456                                SemanticError( decl, "Cforall declaration hides C function " );
     457                        }
     458                } else {
     459                        // NOTE: only correct if name mangling is completely isomorphic to C
     460                        // type-compatibility, which it may not be.
     461                        if ( hasIncompatibleCDecl( name, mangleName ) ) {
    480462                                SemanticError( decl, "conflicting overload of C function " );
    481463                        }
    482                 } else {
    483                         // Check that a Cforall declaration doesn't override any C declaration
    484                         if ( hasCompatibleCDecl( name, mangleName, scope ) ) {
    485                                 SemanticError( decl, "Cforall declaration hides C function " );
    486                         }
    487                 }
    488 
    489                 // Skip repeat declarations of the same identifier
    490                 IdData * existing = lookupIdAtScope( name, mangleName, scope );
    491                 if ( existing && existing->id && addedIdConflicts( *existing, decl, deleteStmt, handleConflicts ) ) return;
    492 
    493                 // add to indexer
    494                 tables->idTable[ name ][ mangleName ] = IdData{ decl, baseExpr, deleteStmt };
    495                 ++tables->size;
     464                }
     465
     466                // ensure tables exist and add identifier
     467                MangleTable::Ptr mangleTable;
     468                if ( ! idTable ) {
     469                        idTable = IdTable::new_ptr();
     470                        mangleTable = MangleTable::new_ptr();
     471                } else {
     472                        ++*stats().map_lookups;
     473                        auto decls = idTable->find( name );
     474                        if ( decls == idTable->end() ) {
     475                                mangleTable = MangleTable::new_ptr();
     476                        } else {
     477                                mangleTable = decls->second;
     478                                // skip in-scope repeat declarations of same identifier
     479                                ++*stats().map_lookups;
     480                                auto existing = mangleTable->find( mangleName );
     481                                if ( existing != mangleTable->end()
     482                                                && existing->second.scope == scope
     483                                                && existing->second.id ) {
     484                                        if ( addedIdConflicts( existing->second, decl, handleConflicts, deleteStmt ) ) {
     485                                                if ( handleConflicts.mode == OnConflict::Delete ) {
     486                                                        // set delete expression for conflicting identifier
     487                                                        lazyInitScope();
     488                                                        *stats().map_mutations += 2;
     489                                                        idTable = idTable->set(
     490                                                                name,
     491                                                                mangleTable->set(
     492                                                                        mangleName,
     493                                                                        IdData{ existing->second, handleConflicts.deleteStmt } ) );
     494                                                }
     495                                                return;
     496                                        }
     497                                }
     498                        }
     499                }
     500
     501                // add/overwrite with new identifier
     502                lazyInitScope();
     503                IdData data{ decl, baseExpr, deleteStmt, scope };
     504                // Ensure that auto-generated ctor/dtor/assignment are deleted if necessary
     505                if ( ! removeSpecialOverrides( data, mangleTable ) ) return;
     506                *stats().map_mutations += 2;
     507                idTable = idTable->set( name, mangleTable->set( mangleName, std::move(data) ) );
    496508        }
    497509
    498510        void Indexer::addId( DeclarationWithType * decl, Expression * baseExpr ) {
    499511                // default handling of conflicts is to raise an error
    500                 addId( decl, [decl](IdData &, const std::string & msg) { SemanticError( decl, msg ); return true; }, baseExpr, decl->isDeleted ? decl : nullptr );
     512                addId( decl, OnConflict::error(), baseExpr, decl->isDeleted ? decl : nullptr );
    501513        }
    502514
    503515        void Indexer::addDeletedId( DeclarationWithType * decl, BaseSyntaxNode * deleteStmt ) {
    504516                // default handling of conflicts is to raise an error
    505                 addId( decl, [decl](IdData &, const std::string & msg) { SemanticError( decl, msg ); return true; }, nullptr, deleteStmt );
     517                addId( decl, OnConflict::error(), nullptr, deleteStmt );
    506518        }
    507519
     
    518530                        }
    519531                }
    520                 // does not need to be added to the table if both existing and added have a base that are the same
     532                // does not need to be added to the table if both existing and added have a base that are
     533                // the same
    521534                return true;
    522535        }
    523536
    524537        void Indexer::addType( NamedTypeDecl *decl ) {
    525                 debugPrint( "Adding type " << decl->name << std::endl );
    526                 makeWritable();
    527 
     538                ++*stats().add_calls;
    528539                const std::string &id = decl->name;
    529                 TypeTable::iterator existing = tables->typeTable.find( id );
    530                 if ( existing == tables->typeTable.end() ) {
    531                         NamedTypeDecl *parent = tables->base.lookupTypeAtScope( id, scope );
    532                         if ( ! parent || ! addedTypeConflicts( parent, decl ) ) {
    533                                 tables->typeTable.insert( existing, std::make_pair( id, decl ) );
    534                                 ++tables->size;
    535                         }
    536                 } else {
    537                         if ( ! addedTypeConflicts( existing->second, decl ) ) {
    538                                 existing->second = decl;
    539                         }
    540                 }
     540
     541                if ( ! typeTable ) {
     542                        typeTable = TypeTable::new_ptr();
     543                } else {
     544                        ++*stats().map_lookups;
     545                        auto existing = typeTable->find( id );
     546                        if ( existing != typeTable->end()
     547                                && existing->second.scope == scope
     548                                && addedTypeConflicts( existing->second.decl, decl ) ) return;
     549                }
     550               
     551                lazyInitScope();
     552                ++*stats().map_mutations;
     553                typeTable = typeTable->set( id, Scoped<NamedTypeDecl>{ decl, scope } );
    541554        }
    542555
     
    551564
    552565        void Indexer::addStruct( const std::string &id ) {
    553                 debugPrint( "Adding fwd decl for struct " << id << std::endl );
    554566                addStruct( new StructDecl( id ) );
    555567        }
    556568
    557569        void Indexer::addStruct( StructDecl *decl ) {
    558                 debugPrint( "Adding struct " << decl->name << std::endl );
    559                 makeWritable();
    560 
     570                ++*stats().add_calls;
    561571                const std::string &id = decl->name;
    562                 StructTable::iterator existing = tables->structTable.find( id );
    563                 if ( existing == tables->structTable.end() ) {
    564                         StructDecl *parent = tables->base.lookupStructAtScope( id, scope );
    565                         if ( ! parent || ! addedDeclConflicts( parent, decl ) ) {
    566                                 tables->structTable.insert( existing, std::make_pair( id, decl ) );
    567                                 ++tables->size;
    568                         }
    569                 } else {
    570                         if ( ! addedDeclConflicts( existing->second, decl ) ) {
    571                                 existing->second = decl;
    572                         }
    573                 }
     572
     573                if ( ! structTable ) {
     574                        structTable = StructTable::new_ptr();
     575                } else {
     576                        ++*stats().map_lookups;
     577                        auto existing = structTable->find( id );
     578                        if ( existing != structTable->end() 
     579                                && existing->second.scope == scope
     580                                && addedDeclConflicts( existing->second.decl, decl ) ) return;
     581                }
     582
     583                lazyInitScope();
     584                ++*stats().map_mutations;
     585                structTable = structTable->set( id, Scoped<StructDecl>{ decl, scope } );
    574586        }
    575587
    576588        void Indexer::addEnum( EnumDecl *decl ) {
    577                 debugPrint( "Adding enum " << decl->name << std::endl );
    578                 makeWritable();
    579 
     589                ++*stats().add_calls;
    580590                const std::string &id = decl->name;
    581                 EnumTable::iterator existing = tables->enumTable.find( id );
    582                 if ( existing == tables->enumTable.end() ) {
    583                         EnumDecl *parent = tables->base.lookupEnumAtScope( id, scope );
    584                         if ( ! parent || ! addedDeclConflicts( parent, decl ) ) {
    585                                 tables->enumTable.insert( existing, std::make_pair( id, decl ) );
    586                                 ++tables->size;
    587                         }
    588                 } else {
    589                         if ( ! addedDeclConflicts( existing->second, decl ) ) {
    590                                 existing->second = decl;
    591                         }
    592                 }
     591
     592                if ( ! enumTable ) {
     593                        enumTable = EnumTable::new_ptr();
     594                } else {
     595                        ++*stats().map_lookups;
     596                        auto existing = enumTable->find( id );
     597                        if ( existing != enumTable->end() 
     598                                && existing->second.scope == scope
     599                                && addedDeclConflicts( existing->second.decl, decl ) ) return;
     600                }
     601               
     602                lazyInitScope();
     603                ++*stats().map_mutations;
     604                enumTable = enumTable->set( id, Scoped<EnumDecl>{ decl, scope } );
    593605        }
    594606
    595607        void Indexer::addUnion( const std::string &id ) {
    596                 debugPrint( "Adding fwd decl for union " << id << std::endl );
    597608                addUnion( new UnionDecl( id ) );
    598609        }
    599610
    600611        void Indexer::addUnion( UnionDecl *decl ) {
    601                 debugPrint( "Adding union " << decl->name << std::endl );
    602                 makeWritable();
    603 
     612                ++*stats().add_calls;
    604613                const std::string &id = decl->name;
    605                 UnionTable::iterator existing = tables->unionTable.find( id );
    606                 if ( existing == tables->unionTable.end() ) {
    607                         UnionDecl *parent = tables->base.lookupUnionAtScope( id, scope );
    608                         if ( ! parent || ! addedDeclConflicts( parent, decl ) ) {
    609                                 tables->unionTable.insert( existing, std::make_pair( id, decl ) );
    610                                 ++tables->size;
    611                         }
    612                 } else {
    613                         if ( ! addedDeclConflicts( existing->second, decl ) ) {
    614                                 existing->second = decl;
    615                         }
    616                 }
     614
     615                if ( ! unionTable ) {
     616                        unionTable = UnionTable::new_ptr();
     617                } else {
     618                        ++*stats().map_lookups;
     619                        auto existing = unionTable->find( id );
     620                        if ( existing != unionTable->end()
     621                                && existing->second.scope == scope
     622                                && addedDeclConflicts( existing->second.decl, decl ) ) return;
     623                }
     624
     625                lazyInitScope();
     626                ++*stats().map_mutations;
     627                unionTable = unionTable->set( id, Scoped<UnionDecl>{ decl, scope } );
    617628        }
    618629
    619630        void Indexer::addTrait( TraitDecl *decl ) {
    620                 debugPrint( "Adding trait " << decl->name << std::endl );
    621                 makeWritable();
    622 
     631                ++*stats().add_calls;
    623632                const std::string &id = decl->name;
    624                 TraitTable::iterator existing = tables->traitTable.find( id );
    625                 if ( existing == tables->traitTable.end() ) {
    626                         TraitDecl *parent = tables->base.lookupTraitAtScope( id, scope );
    627                         if ( ! parent || ! addedDeclConflicts( parent, decl ) ) {
    628                                 tables->traitTable.insert( existing, std::make_pair( id, decl ) );
    629                                 ++tables->size;
    630                         }
    631                 } else {
    632                         if ( ! addedDeclConflicts( existing->second, decl ) ) {
    633                                 existing->second = decl;
    634                         }
    635                 }
    636         }
    637 
    638         void Indexer::addMembers( AggregateDecl * aggr, Expression * expr, ConflictFunction handleConflicts ) {
     633
     634                if ( ! traitTable ) {
     635                        traitTable = TraitTable::new_ptr();
     636                } else {
     637                        ++*stats().map_lookups;
     638                        auto existing = traitTable->find( id );
     639                        if ( existing != traitTable->end()
     640                                && existing->second.scope == scope
     641                                && addedDeclConflicts( existing->second.decl, decl ) ) return;
     642                }
     643
     644                lazyInitScope();
     645                ++*stats().map_mutations;
     646                traitTable = traitTable->set( id, Scoped<TraitDecl>{ decl, scope } );
     647        }
     648
     649        void Indexer::addMembers( AggregateDecl * aggr, Expression * expr,
     650                        OnConflict handleConflicts ) {
    639651                for ( Declaration * decl : aggr->members ) {
    640652                        if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType * >( decl ) ) {
     
    642654                                if ( dwt->name == "" ) {
    643655                                        Type * t = dwt->get_type()->stripReferences();
    644                                         if ( dynamic_cast< StructInstType * >( t ) || dynamic_cast< UnionInstType * >( t ) ) {
     656                                        if ( dynamic_cast<StructInstType*>( t ) || dynamic_cast<UnionInstType*>( t ) ) {
    645657                                                Expression * base = expr->clone();
    646658                                                ResolvExpr::Cost cost = ResolvExpr::Cost::zero; // xxx - carry this cost into the indexer as a base cost?
     
    659671                                assertf( aggr, "WithStmt expr has non-aggregate type: %s", toString( expr->result ).c_str() );
    660672
    661                                 addMembers( aggr, expr, [withStmt](IdData & existing, const std::string &) {
    662                                         // on conflict, delete the identifier
    663                                         existing.deleteStmt = withStmt;
    664                                         return true;
    665                                 });
     673                                addMembers( aggr, expr, OnConflict::deleteWith( withStmt ) );
    666674                        }
    667675                }
     
    685693                addIds( ftype->returnVals );
    686694                addIds( ftype->parameters );
    687         }
    688 
    689         void Indexer::enterScope() {
    690                 ++scope;
    691 
    692                 if ( doDebug ) {
    693                         std::cerr << "--- Entering scope " << scope << std::endl;
    694                 }
    695         }
    696 
    697         void Indexer::leaveScope() {
    698                 using std::cerr;
    699 
    700                 assert( scope > 0 && "cannot leave initial scope" );
    701                 if ( doDebug ) {
    702                         cerr << "--- Leaving scope " << scope << " containing" << std::endl;
    703                 }
    704                 --scope;
    705 
    706                 while ( tables && tables->scope > scope ) {
    707                         if ( doDebug ) {
    708                                 dump( tables->idTable, cerr );
    709                                 dump( tables->typeTable, cerr );
    710                                 dump( tables->structTable, cerr );
    711                                 dump( tables->enumTable, cerr );
    712                                 dump( tables->unionTable, cerr );
    713                                 dump( tables->traitTable, cerr );
    714                         }
    715 
    716                         // swap tables for base table until we find one at an appropriate scope
    717                         Indexer::Impl *base = newRef( tables->base.tables );
    718                         deleteRef( tables );
    719                         tables = base;
    720                 }
    721         }
    722 
    723         void Indexer::print( std::ostream &os, int indent ) const {
    724                 using std::cerr;
    725 
    726                 if ( tables ) {
    727                         os << "--- scope " << tables->scope << " ---" << std::endl;
    728 
    729                         os << "===idTable===" << std::endl;
    730                         dump( tables->idTable, os );
    731                         os << "===typeTable===" << std::endl;
    732                         dump( tables->typeTable, os );
    733                         os << "===structTable===" << std::endl;
    734                         dump( tables->structTable, os );
    735                         os << "===enumTable===" << std::endl;
    736                         dump( tables->enumTable, os );
    737                         os << "===unionTable===" << std::endl;
    738                         dump( tables->unionTable, os );
    739                         os << "===contextTable===" << std::endl;
    740                         dump( tables->traitTable, os );
    741 
    742                         tables->base.print( os, indent );
    743                 } else {
    744                         os << "--- end ---" << std::endl;
    745                 }
    746 
    747695        }
    748696
  • src/SymTab/Indexer.h

    r6a9d4b4 r933f32f  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 21:38:55 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Aug 17 16:09:12 2017
    13 // Update Count     : 8
     11// Last Modified By : Aaron B. Moss
     12// Last Modified On : Fri Mar  8 13:55:00 2019
     13// Update Count     : 9
    1414//
    1515
    1616#pragma once
    1717
    18 #include <iosfwd>             // for ostream
    19 #include <list>               // for list
    20 #include <string>             // for string
    21 #include <functional>         // for function
     18#include <functional>              // for function
     19#include <list>                    // for list
     20#include <memory>                  // for shared_ptr, enable_shared_from_this
     21#include <string>                  // for string
    2222
    23 #include "SynTree/Visitor.h"  // for Visitor
    24 #include "SynTree/SynTree.h"  // for AST nodes
     23#include "Common/PersistentMap.h"  // for PersistentMap
     24#include "SynTree/SynTree.h"       // for AST nodes
    2525
    2626namespace ResolvExpr {
    27 class Cost;
     27        class Cost;
    2828}
    2929
    3030namespace SymTab {
    31         class Indexer {
    32           public:
     31        class Indexer : public std::enable_shared_from_this<SymTab::Indexer> {
     32        public:
    3333                explicit Indexer();
     34                virtual ~Indexer();
    3435
    35                 Indexer( const Indexer &that );
    36                 Indexer( Indexer &&that );
    37                 virtual ~Indexer();
    38                 Indexer& operator= ( const Indexer &that );
    39                 Indexer& operator= ( Indexer &&that );
    40 
    41                 // when using an indexer manually (e.g., within a mutator traversal), it is necessary to tell the indexer
    42                 // explicitly when scopes begin and end
     36                // when using an indexer manually (e.g., within a mutator traversal), it is necessary to
     37                // tell the indexer explicitly when scopes begin and end
    4338                void enterScope();
    4439                void leaveScope();
     
    5045                        /// non-null if this declaration is deleted
    5146                        BaseSyntaxNode * deleteStmt = nullptr;
     47                        /// scope of identifier
     48                        unsigned long scope = 0;
    5249
    5350                        // NOTE: shouldn't need either of these constructors, but gcc-4 does not properly support initializer lists with default members.
    5451                        IdData() = default;
    55                         IdData( DeclarationWithType * id, Expression * baseExpr, BaseSyntaxNode * deleteStmt ) : id( id ), baseExpr( baseExpr ), deleteStmt( deleteStmt ) {}
     52                        IdData(
     53                                DeclarationWithType * id, Expression * baseExpr, BaseSyntaxNode * deleteStmt,
     54                                unsigned long scope )
     55                                : id( id ), baseExpr( baseExpr ), deleteStmt( deleteStmt ), scope( scope ) {}
     56                        IdData( const IdData& o, BaseSyntaxNode * deleteStmt )
     57                                : id( o.id ), baseExpr( o.baseExpr ), deleteStmt( deleteStmt ), scope( o.scope ) {}
    5658
    5759                        Expression * combine( ResolvExpr::Cost & cost ) const;
     
    8082                EnumDecl *globalLookupEnum( const std::string &id ) const;
    8183
    82                 void print( std::ostream &os, int indent = 0 ) const;
    83 
    84                 /// looks up a specific mangled ID at the given scope
    85                 IdData * lookupIdAtScope( const std::string &id, const std::string &mangleName, unsigned long scope );
    86                 const IdData * lookupIdAtScope( const std::string &id, const std::string &mangleName, unsigned long scope ) const;
    87                 /// returns true if there exists a declaration with C linkage and the given name with a different mangled name
    88                 bool hasIncompatibleCDecl( const std::string &id, const std::string &mangleName, unsigned long scope ) const;
    89                 /// returns true if there exists a declaration with C linkage and the given name with the same mangled name
    90                 bool hasCompatibleCDecl( const std::string &id, const std::string &mangleName, unsigned long scope ) const;
    91                 // equivalents to lookup functions that only look at tables at scope `scope` (which should be >= tables->scope)
    92                 NamedTypeDecl *lookupTypeAtScope( const std::string &id, unsigned long scope ) const;
    93                 StructDecl *lookupStructAtScope( const std::string &id, unsigned long scope ) const;
    94                 EnumDecl *lookupEnumAtScope( const std::string &id, unsigned long scope ) const;
    95                 UnionDecl *lookupUnionAtScope( const std::string &id, unsigned long scope ) const;
    96                 TraitDecl *lookupTraitAtScope( const std::string &id, unsigned long scope ) const;
    97 
    98                 typedef std::function<bool(IdData &, const std::string &)> ConflictFunction;
    99 
    10084                void addId( DeclarationWithType * decl, Expression * baseExpr = nullptr );
    10185                void addDeletedId( DeclarationWithType * decl, BaseSyntaxNode * deleteStmt );
     
    11296                void addWith( std::list< Expression * > & withExprs, BaseSyntaxNode * withStmt );
    11397
    114                 /// adds all of the members of the Aggregate (addWith helper)
    115                 void addMembers( AggregateDecl * aggr, Expression * expr, ConflictFunction );
    116 
    11798                /// convenience function for adding a list of Ids to the indexer
    11899                void addIds( const std::list< DeclarationWithType * > & decls );
     
    124105                void addFunctionType( FunctionType * ftype );
    125106
    126                 bool doDebug = false; ///< Display debugging trace?
    127107          private:
    128                 struct Impl;
     108                /// Wraps a Decl* with a scope
     109                template<typename Decl>
     110                struct Scoped {
     111                        Decl* decl;           ///< declaration
     112                        unsigned long scope;  ///< scope of this declaration
    129113
    130                 Impl *tables;         ///< Copy-on-write instance of table data structure
    131                 unsigned long scope;  ///< Scope index of this pointer
     114                        Scoped(Decl* d, unsigned long s) : decl(d), scope(s) {}
     115                };
    132116
    133                 /// Takes a new ref to a table (returns null if null)
    134                 static Impl *newRef( Impl *toClone );
    135                 /// Clears a ref to a table (does nothing if null)
    136                 static void deleteRef( Impl *toFree );
     117                using Ptr = std::shared_ptr<const Indexer>;
    137118
    138                 // Removes matching autogenerated constructors and destructors
    139                 // so that they will not be selected
    140                 // void removeSpecialOverrides( FunctionDecl *decl );
    141                 void removeSpecialOverrides( const std::string &id, std::list< IdData > & out ) const;
     119                using MangleTable = PersistentMap< std::string, IdData >;
     120                using IdTable = PersistentMap< std::string, MangleTable::Ptr >;
     121                using TypeTable = PersistentMap< std::string, Scoped<NamedTypeDecl> >;
     122                using StructTable = PersistentMap< std::string, Scoped<StructDecl> >;
     123                using EnumTable = PersistentMap< std::string, Scoped<EnumDecl> >;
     124                using UnionTable = PersistentMap< std::string, Scoped<UnionDecl> >;
     125                using TraitTable = PersistentMap< std::string, Scoped<TraitDecl> >;
    142126
    143                 /// Ensures that tables variable is writable (i.e. allocated, uniquely owned by this Indexer, and at the current scope)
    144                 void makeWritable();
     127                IdTable::Ptr idTable;          ///< identifier namespace
     128                TypeTable::Ptr typeTable;      ///< type namespace
     129                StructTable::Ptr structTable;  ///< struct namespace
     130                EnumTable::Ptr enumTable;      ///< enum namespace
     131                UnionTable::Ptr unionTable;    ///< union namespace
     132                TraitTable::Ptr traitTable;    ///< trait namespace
     133
     134                Ptr prevScope;                 ///< reference to indexer for parent scope
     135                unsigned long scope;           ///< Scope index of this indexer
     136                unsigned long repScope;        ///< Scope index of currently represented scope
     137
     138                /// Ensures that a proper backtracking scope exists before a mutation
     139                void lazyInitScope();
     140
     141                /// Gets the indexer at the given scope
     142                const Indexer* atScope( unsigned long scope ) const;
     143
     144                /// Removes matching autogenerated constructors and destructors so that they will not be
     145                /// selected. If returns false, passed decl should not be added.
     146                bool removeSpecialOverrides( IdData& decl, MangleTable::Ptr& mangleTable );
     147
     148                /// Options for handling identifier conflicts
     149                struct OnConflict {
     150                        enum {
     151                                Error,  ///< Throw a semantic error
     152                                Delete  ///< Delete the earlier version with the delete statement
     153                        } mode;
     154                        BaseSyntaxNode * deleteStmt;  ///< Statement that deletes this expression
     155
     156                private:
     157                        OnConflict() : mode(Error), deleteStmt(nullptr) {}
     158                        OnConflict( BaseSyntaxNode * d ) : mode(Delete), deleteStmt(d) {}
     159                public:
     160                        OnConflict( const OnConflict& ) = default;
     161
     162                        static OnConflict error() { return {}; }
     163                        static OnConflict deleteWith( BaseSyntaxNode * d ) { return { d }; }
     164                };
     165
     166                /// true if the existing identifier conflicts with the added identifier
     167                bool addedIdConflicts(
     168                        const IdData& existing, DeclarationWithType * added, OnConflict handleConflicts,
     169                        BaseSyntaxNode * deleteStmt );
    145170
    146171                /// common code for addId, addDeletedId, etc.
    147                 void addId( DeclarationWithType * decl, ConflictFunction, Expression * baseExpr = nullptr, BaseSyntaxNode * deleteStmt = nullptr );
     172                void addId(
     173                        DeclarationWithType * decl, OnConflict handleConflicts,
     174                        Expression * baseExpr = nullptr, BaseSyntaxNode * deleteStmt = nullptr );
     175
     176                /// adds all of the members of the Aggregate (addWith helper)
     177                void addMembers( AggregateDecl * aggr, Expression * expr, OnConflict handleConflicts );
     178
     179                /// returns true if there exists a declaration with C linkage and the given name with the same mangled name
     180                bool hasCompatibleCDecl( const std::string &id, const std::string &mangleName ) const;
     181                /// returns true if there exists a declaration with C linkage and the given name with a different mangled name
     182                bool hasIncompatibleCDecl( const std::string &id, const std::string &mangleName ) const;
    148183        };
    149184} // namespace SymTab
  • src/SymTab/Mangler.cc

    r6a9d4b4 r933f32f  
    3838                        struct Mangler : public WithShortCircuiting, public WithVisitorRef<Mangler>, public WithGuards {
    3939                                Mangler( bool mangleOverridable, bool typeMode, bool mangleGenericParams );
    40                                 Mangler( const ResolvExpr::TypeEnvironment& env );
    4140                                Mangler( const Mangler & ) = delete;
    4241
     
    6766                          private:
    6867                                std::ostringstream mangleName;  ///< Mangled name being constructed
    69                                 typedef std::map< std::string, std::pair< std::string, int > > VarMapType;
     68                                typedef std::map< std::string, std::pair< int, int > > VarMapType;
    7069                                VarMapType varNums;             ///< Map of type variables to indices
    7170                                int nextVarNum;                 ///< Next type variable index
    72                                 const ResolvExpr::TypeEnvironment* env;  ///< optional environment for substitutions
    7371                                bool isTopLevel;                ///< Is the Mangler at the top level
    7472                                bool mangleOverridable;         ///< Specially mangle overridable built-in methods
     
    8078                          public:
    8179                                Mangler( bool mangleOverridable, bool typeMode, bool mangleGenericParams,
    82                                         int nextVarNum, const ResolvExpr::TypeEnvironment* env,
    83                                         const VarMapType& varNums );
     80                                        int nextVarNum, const VarMapType& varNums );
    8481
    8582                          private:
     
    109106                }
    110107
    111                 std::string mangleAssnKey( DeclarationWithType* decl,
    112                                 const ResolvExpr::TypeEnvironment& env ) {
    113                         PassVisitor<Mangler> mangler( env );
    114                         maybeAccept( decl, mangler );
    115                         return mangler.pass.get_mangleName();
    116                 }
    117 
    118108                namespace {
    119109                        Mangler::Mangler( bool mangleOverridable, bool typeMode, bool mangleGenericParams )
    120                                 : nextVarNum( 0 ), env(nullptr), isTopLevel( true ),
     110                                : nextVarNum( 0 ), isTopLevel( true ),
    121111                                mangleOverridable( mangleOverridable ), typeMode( typeMode ),
    122112                                mangleGenericParams( mangleGenericParams ) {}
    123113                       
    124                         Mangler::Mangler( const ResolvExpr::TypeEnvironment& env )
    125                                 : nextVarNum( 0 ), env( &env ), isTopLevel( true ), mangleOverridable( false ),
    126                                 typeMode( false ), mangleGenericParams( true ) {}
    127                        
    128114                        Mangler::Mangler( bool mangleOverridable, bool typeMode, bool mangleGenericParams,
    129                                 int nextVarNum, const ResolvExpr::TypeEnvironment* env,
    130                                 const VarMapType& varNums )
    131                                 : varNums( varNums ), nextVarNum( nextVarNum ), env( env ), isTopLevel( false ),
     115                                int nextVarNum, const VarMapType& varNums )
     116                                : varNums( varNums ), nextVarNum( nextVarNum ), isTopLevel( false ),
    132117                                mangleOverridable( mangleOverridable ), typeMode( typeMode ),
    133118                                mangleGenericParams( mangleGenericParams ) {}
     
    358343                                                        assert( false );
    359344                                                } // switch
    360                                                 std::string varName;
    361                                                 // replace type with substitution name if environment is available and bound
    362                                                 if ( env ) {
    363                                                         const ResolvExpr::EqvClass* varClass = env->lookup( (*i)->name );
    364                                                         if ( varClass && varClass->type ) {
    365                                                                 PassVisitor<Mangler> sub_mangler(
    366                                                                         mangleOverridable, typeMode, mangleGenericParams, nextVarNum,
    367                                                                         env, varNums );
    368                                                                 varClass->type->accept( sub_mangler );
    369                                                                 varName = std::string{"%"} + sub_mangler.pass.get_mangleName();
    370                                                         }
    371                                                 }
    372                                                 // otherwise just give type numeric name
    373                                                 if ( varName.empty() ) {
    374                                                         varName = std::to_string( nextVarNum++ );
    375                                                 }
    376                                                 varNums[ (*i)->name ] = std::make_pair( varName, (int)(*i)->get_kind() );
     345                                                varNums[ (*i)->name ] = std::make_pair( nextVarNum, (int)(*i)->get_kind() );
    377346                                                for ( std::list< DeclarationWithType* >::iterator assert = (*i)->assertions.begin(); assert != (*i)->assertions.end(); ++assert ) {
    378347                                                        PassVisitor<Mangler> sub_mangler(
    379                                                                 mangleOverridable, typeMode, mangleGenericParams, nextVarNum, env,
    380                                                                 varNums );
     348                                                                mangleOverridable, typeMode, mangleGenericParams, nextVarNum, varNums );
    381349                                                        (*assert)->accept( sub_mangler );
    382350                                                        assertionNames.push_back( sub_mangler.pass.get_mangleName() );
  • src/SymTab/Mangler.h

    r6a9d4b4 r933f32f  
    4444                /// Mangle ignoring generic type parameters
    4545                std::string mangleConcrete( Type* ty );
    46                 /// Mangle for assertion key
    47                 std::string mangleAssnKey( DeclarationWithType* decl,
    48                         const ResolvExpr::TypeEnvironment& env );
    4946
    5047                namespace Encoding {
  • src/SymTab/ManglerCommon.cc

    r6a9d4b4 r933f32f  
    1010// Created On       : Sun May 17 21:44:03 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Jul 22 09:45:30 2017
    13 // Update Count     : 15
     12// Last Modified On : Thu Feb 14 17:06:37 2019
     13// Update Count     : 26
    1414//
    1515
     
    2323                        const std::string manglePrefix = "_X";
    2424
    25                         const std::string basicTypes[] = {
    26                                 "b",  // Bool
    27                                 "c",  // Char
    28                                 "a",  // SignedChar
    29                                 "h",  // UnsignedChar
    30                                 "s",  // ShortSignedInt
    31                                 "t",  // ShortUnsignedInt
    32                                 "i",  // SignedInt
    33                                 "j",  // UnsignedInt
    34                                 "l",  // LongSignedInt
    35                                 "m",  // LongUnsignedInt
    36                                 "x",  // LongLongSignedInt
    37                                 "y",  // LongLongUnsignedInt
    38                                 "f",  // Float
    39                                 "d",  // Double
    40                                 "e",  // LongDouble
    41                                 "Cf", // FloatComplex
    42                                 "Cd", // DoubleComplex
    43                                 "Ce", // LongDoubleComplex
    44                                 // Note: imaginary is not an overloadable type in C++
    45                                 "If", // FloatImaginary
    46                                 "Id", // DoubleImaginary
    47                                 "Ie", // LongDoubleImaginary
    48                                 "n",  // SignedInt128
    49                                 "o",  // UnsignedInt128
    50                                 "Dq",  // Float80 -- TODO: itanium says Float80 and LongDouble both encode to "e", but doing this causes problems with constructing long double, because the cost tables are incorrect
    51                                 "g",  // Float128
    52                                 // "z", // ellipsis
    53                                 // "Dd" // # IEEE 754r decimal floating point (64 bits)
    54                                 // "De" // # IEEE 754r decimal floating point (128 bits)
    55                                 // "Df" // # IEEE 754r decimal floating point (32 bits)
    56                                 // "Dh" // # IEEE 754r half-precision floating point (16 bits)
    57                                 // "DF"N_ // # ISO/IEC TS 18661 binary floating point type _FloatN (N bits)
    58                                 // "Di" // char32_t
    59                                 // "Ds" // char16_t
    60                         };
     25                        // GENERATED START, DO NOT EDIT
     26                        // GENERATED BY BasicTypes-gen.cc
     27                        // NOTES ON MANGLING:
     28                        // * Itanium spec says that Float80 encodes to "e" (like LongDouble), but the distinct lengths cause resolution problems.
     29                        // * Float128 is supposed to encode to "g", but I wanted it to mangle equal to LongDouble.
     30                        // * Mangling for non-standard complex types is by best guess
     31                        // * _FloatN is supposed to encode as "DF"N"_"; modified for same reason as above.
     32                        // * unused mangling identifiers:
     33                        //   - "z" ellipsis
     34                        //   - "Dd" IEEE 754r 64-bit decimal floating point (borrowed for _Float32x)
     35                        //   - "De" IEEE 754r 128-bit decimal floating point
     36                        //   - "Df" IEEE 754r 32-bit decimal floating point
     37                        //   - "Dh" IEEE 754r 16-bit decimal floating point (borrowed for _Float16)
     38                        //   - "DF"N"_" ISO/IEC TS 18661 N-bit binary floating point (_FloatN)
     39                        //   - "Di" char32_t
     40                        //   - "Ds" char16_t
     41                        const std::string basicTypes[BasicType::NUMBER_OF_BASIC_TYPES] = {
     42                                "b",        // _Bool
     43                                "c",        // char
     44                                "a",        // signed char
     45                                "h",        // unsigned char
     46                                "s",        // signed short int
     47                                "t",        // unsigned short int
     48                                "i",        // signed int
     49                                "j",        // unsigned int
     50                                "l",        // signed long int
     51                                "m",        // unsigned long int
     52                                "x",        // signed long long int
     53                                "y",        // unsigned long long int
     54                                "n",        // __int128
     55                                "o",        // unsigned __int128
     56                                "DF16_",    // _Float16
     57                                "CDF16_",   // _Float16 _Complex
     58                                "DF32_",    // _Float32
     59                                "CDF32_",   // _Float32 _Complex
     60                                "f",        // float
     61                                "Cf",       // float _Complex
     62                                "DF32x_",   // _Float32x
     63                                "CDF32x_",  // _Float32x _Complex
     64                                "DF64_",    // _Float64
     65                                "CDF64_",   // _Float64 _Complex
     66                                "d",        // double
     67                                "Cd",       // double _Complex
     68                                "DF64x_",   // _Float64x
     69                                "CDF64x_",  // _Float64x _Complex
     70                                "Dq",       // __float80
     71                                "DF128_",   // _Float128
     72                                "CDF128_",  // _Float128 _Complex
     73                                "g",        // __float128
     74                                "e",        // long double
     75                                "Ce",       // long double _Complex
     76                                "DF128x_",  // _Float128x
     77                                "CDF128x_", // _Float128x _Complex
     78                        }; // basicTypes
     79                        // GENERATED END
    6180                        static_assert(
    6281                                sizeof(basicTypes)/sizeof(basicTypes[0]) == BasicType::NUMBER_OF_BASIC_TYPES,
  • src/SymTab/Validate.cc

    r6a9d4b4 r933f32f  
    4949#include "CodeGen/OperatorTable.h"     // for isCtorDtor, isCtorDtorAssign
    5050#include "ControlStruct/Mutate.h"      // for ForExprMutator
     51#include "Common/Stats.h"              // for Stats::Heap
    5152#include "Common/PassVisitor.h"        // for PassVisitor, WithDeclsToAdd
    5253#include "Common/ScopedMap.h"          // for ScopedMap
     
    298299                PassVisitor<FixQualifiedTypes> fixQual;
    299300
    300                 acceptAll( translationUnit, hoistDecls );
    301                 ReplaceTypedef::replaceTypedef( translationUnit );
    302                 ReturnTypeFixer::fix( translationUnit ); // must happen before autogen
    303                 acceptAll( translationUnit, epc ); // must happen before VerifyCtorDtorAssign, because void return objects should not exist; before LinkReferenceToTypes because it is an indexer and needs correct types for mangling
    304                 acceptAll( translationUnit, lrt ); // must happen before autogen, because sized flag needs to propagate to generated functions
    305                 mutateAll( translationUnit, fixQual ); // must happen after LinkReferenceToTypes, because aggregate members are accessed
    306                 HoistStruct::hoistStruct( translationUnit ); // must happen after EliminateTypedef, so that aggregate typedefs occur in the correct order
    307                 EliminateTypedef::eliminateTypedef( translationUnit ); //
    308                 acceptAll( translationUnit, genericParams );  // check as early as possible - can't happen before LinkReferenceToTypes
    309                 VerifyCtorDtorAssign::verify( translationUnit );  // must happen before autogen, because autogen examines existing ctor/dtors
    310                 ReturnChecker::checkFunctionReturns( translationUnit );
    311                 InitTweak::fixReturnStatements( translationUnit ); // must happen before autogen
    312                 Concurrency::applyKeywords( translationUnit );
    313                 acceptAll( translationUnit, fpd ); // must happen before autogenerateRoutines, after Concurrency::applyKeywords because uniqueIds must be set on declaration before resolution
    314                 ControlStruct::hoistControlDecls( translationUnit );  // hoist initialization out of for statements; must happen before autogenerateRoutines
    315                 autogenerateRoutines( translationUnit ); // moved up, used to be below compoundLiteral - currently needs EnumAndPointerDecay
    316                 Concurrency::implementMutexFuncs( translationUnit );
    317                 Concurrency::implementThreadStarter( translationUnit );
    318                 mutateAll( translationUnit, compoundliteral );
    319                 ResolvExpr::resolveWithExprs( translationUnit ); // must happen before FixObjectType because user-code is resolved and may contain with variables
    320                 FixObjectType::fix( translationUnit );
    321                 ArrayLength::computeLength( translationUnit );
    322                 Validate::findSpecialDecls( translationUnit );
    323                 mutateAll( translationUnit, labelAddrFixer );
    324                 Validate::handleAttributes( translationUnit );
     301                {
     302                        Stats::Heap::newPass("validate-A");
     303                        Stats::Time::BlockGuard guard("validate-A");
     304                        acceptAll( translationUnit, hoistDecls );
     305                        ReplaceTypedef::replaceTypedef( translationUnit );
     306                        ReturnTypeFixer::fix( translationUnit ); // must happen before autogen
     307                        acceptAll( translationUnit, epc ); // must happen before VerifyCtorDtorAssign, because void return objects should not exist; before LinkReferenceToTypes because it is an indexer and needs correct types for mangling
     308                }
     309                {
     310                        Stats::Heap::newPass("validate-B");
     311                        Stats::Time::BlockGuard guard("validate-B");
     312                        Stats::Time::TimeBlock("Link Reference To Types", [&]() {
     313                                acceptAll( translationUnit, lrt ); // must happen before autogen, because sized flag needs to propagate to generated functions
     314                        });
     315                        Stats::Time::TimeBlock("Fix Qualified Types", [&]() {
     316                                mutateAll( translationUnit, fixQual ); // must happen after LinkReferenceToTypes, because aggregate members are accessed
     317                        });
     318                        Stats::Time::TimeBlock("Hoist Structs", [&]() {
     319                                HoistStruct::hoistStruct( translationUnit ); // must happen after EliminateTypedef, so that aggregate typedefs occur in the correct order
     320                        });
     321                        Stats::Time::TimeBlock("Eliminate Typedefs", [&]() {
     322                                EliminateTypedef::eliminateTypedef( translationUnit ); //
     323                        });
     324                }
     325                {
     326                        Stats::Heap::newPass("validate-C");
     327                        Stats::Time::BlockGuard guard("validate-C");
     328                        acceptAll( translationUnit, genericParams );  // check as early as possible - can't happen before LinkReferenceToTypes
     329                        VerifyCtorDtorAssign::verify( translationUnit );  // must happen before autogen, because autogen examines existing ctor/dtors
     330                        ReturnChecker::checkFunctionReturns( translationUnit );
     331                        InitTweak::fixReturnStatements( translationUnit ); // must happen before autogen
     332                }
     333                {
     334                        Stats::Heap::newPass("validate-D");
     335                        Stats::Time::BlockGuard guard("validate-D");
     336                        Stats::Time::TimeBlock("Apply Concurrent Keywords", [&]() {
     337                                Concurrency::applyKeywords( translationUnit );
     338                        });
     339                        Stats::Time::TimeBlock("Forall Pointer Decay", [&]() {
     340                                acceptAll( translationUnit, fpd ); // must happen before autogenerateRoutines, after Concurrency::applyKeywords because uniqueIds must be set on declaration before resolution
     341                        });
     342                        Stats::Time::TimeBlock("Hoist Control Declarations", [&]() {
     343                                ControlStruct::hoistControlDecls( translationUnit );  // hoist initialization out of for statements; must happen before autogenerateRoutines
     344                        });
     345                        Stats::Time::TimeBlock("Generate Autogen routines", [&]() {
     346                                autogenerateRoutines( translationUnit ); // moved up, used to be below compoundLiteral - currently needs EnumAndPointerDecay
     347                        });
     348                }
     349                {
     350                        Stats::Heap::newPass("validate-E");
     351                        Stats::Time::BlockGuard guard("validate-E");
     352                        Stats::Time::TimeBlock("Implement Mutex Func", [&]() {
     353                                Concurrency::implementMutexFuncs( translationUnit );
     354                        });
     355                        Stats::Time::TimeBlock("Implement Thread Start", [&]() {
     356                                Concurrency::implementThreadStarter( translationUnit );
     357                        });
     358                        Stats::Time::TimeBlock("Compound Literal", [&]() {
     359                                mutateAll( translationUnit, compoundliteral );
     360                        });
     361                        Stats::Time::TimeBlock("Resolve With Expressions", [&]() {
     362                                ResolvExpr::resolveWithExprs( translationUnit ); // must happen before FixObjectType because user-code is resolved and may contain with variables
     363                        });
     364                }
     365                {
     366                        Stats::Heap::newPass("validate-F");
     367                        Stats::Time::BlockGuard guard("validate-F");
     368                        Stats::Time::TimeBlock("Fix Object Type", [&]() {
     369                                FixObjectType::fix( translationUnit );
     370                        });
     371                        Stats::Time::TimeBlock("Array Length", [&]() {
     372                                ArrayLength::computeLength( translationUnit );
     373                        });
     374                        Stats::Time::TimeBlock("Find Special Declarations", [&]() {
     375                                Validate::findSpecialDecls( translationUnit );
     376                        });
     377                        Stats::Time::TimeBlock("Fix Label Address", [&]() {
     378                                mutateAll( translationUnit, labelAddrFixer );
     379                        });
     380                        Stats::Time::TimeBlock("Handle Attributes", [&]() {
     381                                Validate::handleAttributes( translationUnit );
     382                        });
     383                }
    325384        }
    326385
  • src/SymTab/module.mk

    r6a9d4b4 r933f32f  
    1515###############################################################################
    1616
    17 SRC += SymTab/Indexer.cc \
    18        SymTab/Mangler.cc \
    19        SymTab/ManglerCommon.cc \
    20        SymTab/Validate.cc \
    21        SymTab/FixFunction.cc \
    22        SymTab/Autogen.cc
     17SRC_SYMTAB = \
     18      SymTab/Autogen.cc \
     19      SymTab/FixFunction.cc \
     20      SymTab/Indexer.cc \
     21      SymTab/Mangler.cc \
     22      SymTab/ManglerCommon.cc \
     23      SymTab/Validate.cc
     24
     25SRC += $(SRC_SYMTAB)
     26SRCDEMANGLE += $(SRC_SYMTAB) SymTab/Demangle.cc
  • src/SynTree/AddressExpr.cc

    r6a9d4b4 r933f32f  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 23:54:44 2015
    11 // Last Modified By : Rob Schluntz
    12 // Last Modified On : Tue Apr 26 12:35:13 2016
    13 // Update Count     : 6
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Thu Feb 28 13:13:38 2019
     13// Update Count     : 10
    1414//
    1515
     
    4747                } else {
    4848                        // taking address of non-lvalue -- must be a reference, loses one layer of reference
    49                         ReferenceType * refType = strict_dynamic_cast< ReferenceType * >( arg->result );
    50                         set_result( addrType( refType->base ) );
     49                        if ( ReferenceType * refType = dynamic_cast< ReferenceType * >( arg->result ) ) {
     50                                set_result( addrType( refType->base ) );
     51                        } else {
     52                                SemanticError( arg->result, "Attempt to take address of non-lvalue expression: " );
     53                        } // if
    5154                }
    5255                // result of & is never an lvalue
  • src/SynTree/Attribute.cc

    r6a9d4b4 r933f32f  
    2121#include "Expression.h"      // for Expression
    2222
    23 Attribute::Attribute( const Attribute &other ) : name( other.name ) {
     23Attribute::Attribute( const Attribute &other ) : BaseSyntaxNode( other ), name( other.name ) {
    2424        cloneAll( other.parameters, parameters );
    2525}
  • src/SynTree/BaseSyntaxNode.h

    r6a9d4b4 r933f32f  
    1818#include "Common/CodeLocation.h"
    1919#include "Common/Indenter.h"
     20#include "Common/Stats.h"
     21
    2022class Visitor;
    2123class Mutator;
     
    2325class BaseSyntaxNode {
    2426  public:
     27  static Stats::Counters::SimpleCounter* new_nodes;
     28
    2529        CodeLocation location;
     30
     31  BaseSyntaxNode() { ++*new_nodes; }
     32  BaseSyntaxNode( const BaseSyntaxNode& o ) : location(o.location) { ++*new_nodes; }
    2633
    2734        virtual ~BaseSyntaxNode() {}
  • src/SynTree/BasicType.cc

    r6a9d4b4 r933f32f  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Sep 25 14:14:03 2017
    13 // Update Count     : 11
     12// Last Modified On : Thu Jan 31 21:37:36 2019
     13// Update Count     : 12
    1414//
    1515
     
    3030
    3131bool BasicType::isInteger() const {
     32        return kind <= UnsignedInt128;
     33#if 0
    3234        switch ( kind ) {
    3335          case Bool:
     
    6365        assert( false );
    6466        return false;
     67#endif
    6568}
    6669
  • src/SynTree/Constant.cc

    r6a9d4b4 r933f32f  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Fri Spt 28 14:49:00 2018
    13 // Update Count     : 30
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Wed Feb 13 18:11:22 2019
     13// Update Count     : 32
    1414//
    1515
     
    2525Constant::Constant( Type * type, std::string rep, double val ) : type( type ), rep( rep ), val( val ) {}
    2626
    27 Constant::Constant( const Constant &other ) : rep( other.rep ), val( other.val ) {
     27Constant::Constant( const Constant &other ) : BaseSyntaxNode( other ), rep( other.rep ), val( other.val ) {
    2828        type = other.type->clone();
    2929}
  • src/SynTree/Declaration.cc

    r6a9d4b4 r933f32f  
    3131
    3232Declaration::Declaration( const std::string &name, Type::StorageClasses scs, LinkageSpec::Spec linkage )
    33                 : name( name ), linkage( linkage ), storageClasses( scs ), uniqueId( 0 ) {
     33                : name( name ), linkage( linkage ), uniqueId( 0 ), storageClasses( scs ) {
    3434}
    3535
    3636Declaration::Declaration( const Declaration &other )
    37         : BaseSyntaxNode( other ), name( other.name ), linkage( other.linkage ), extension( other.extension ), storageClasses( other.storageClasses ), uniqueId( other.uniqueId ) {
     37        : BaseSyntaxNode( other ), name( other.name ), linkage( other.linkage ), extension( other.extension ), uniqueId( other.uniqueId ), storageClasses( other.storageClasses ) {
    3838}
    3939
  • src/SynTree/Declaration.h

    r6a9d4b4 r933f32f  
    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
     
    7071        static Declaration *declFromId( UniqueId id );
    7172
    72   private:
     73        UniqueId uniqueId;
    7374        Type::StorageClasses storageClasses;
    74         UniqueId uniqueId;
     75  private:
    7576};
    7677
     
    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 );
     
    211213                TypeDecl::Kind kind;
    212214                bool isComplete;
     215
    213216                Data() : kind( (TypeDecl::Kind)-1 ), isComplete( false ) {}
    214217                Data( TypeDecl * typeDecl ) : Data( typeDecl->get_kind(), typeDecl->isComplete() ) {}
    215218                Data( Kind kind, bool isComplete ) : kind( kind ), isComplete( isComplete ) {}
     219                Data( const Data& d1, const Data& d2 )
     220                : kind( d1.kind ), isComplete ( d1.isComplete || d2.isComplete ) {}
     221
    216222                bool operator==(const Data & other) const { return kind == other.kind && isComplete == other.isComplete; }
    217223                bool operator!=(const Data & other) const { return !(*this == other);}
     
    239245        virtual void print( std::ostream &os, Indenter indent = {} ) const override;
    240246
    241   private:
    242247        Kind kind;
    243248};
     
    300305        virtual void accept( Visitor &v ) override { v.visit( this ); }
    301306        virtual Declaration *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    302   private:
    303307        DeclarationNode::Aggregate kind;
     308  private:
    304309        virtual std::string typeString() const override;
    305310};
     
    330335        virtual Declaration *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    331336  private:
    332         std::map< std::string, long long int > enumValues;
     337        std::unordered_map< std::string, long long int > enumValues;
    333338        virtual std::string typeString() const override;
    334339};
  • src/SynTree/Expression.cc

    r6a9d4b4 r933f32f  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Jul 25 14:15:47 2017
    13 // Update Count     : 54
     12// Last Modified On : Tue Feb 19 18:10:55 2019
     13// Update Count     : 60
    1414//
    1515
     
    3333#include "GenPoly/Lvalue.h"
    3434
    35 void printInferParams( const InferredParams & inferParams, std::ostream &os, Indenter indent, int level ) {
     35void printInferParams( const InferredParams & inferParams, std::ostream & os, Indenter indent, int level ) {
    3636        if ( ! inferParams.empty() ) {
    3737                os << indent << "with inferred parameters " << level << ":" << std::endl;
     
    4747Expression::Expression() : result( 0 ), env( 0 ) {}
    4848
    49 Expression::Expression( const Expression &other ) : BaseSyntaxNode( other ), result( maybeClone( other.result ) ), env( maybeClone( other.env ) ), extension( other.extension ), inferParams( other.inferParams ), resnSlots( other.resnSlots ) {}
     49Expression::Expression( const Expression & other ) : BaseSyntaxNode( other ), result( maybeClone( other.result ) ), env( maybeClone( other.env ) ), extension( other.extension ), inferParams( other.inferParams ), resnSlots( other.resnSlots ) {}
    5050
    5151void Expression::spliceInferParams( Expression * other ) {
     
    6262}
    6363
    64 void Expression::print( std::ostream &os, Indenter indent ) const {
     64void Expression::print( std::ostream & os, Indenter indent ) const {
    6565        printInferParams( inferParams, os, indent+1, 0 );
    6666
     
    7979}
    8080
    81 ConstantExpr::ConstantExpr( const ConstantExpr &other) : Expression( other ), constant( other.constant ) {
     81ConstantExpr::ConstantExpr( const ConstantExpr & other) : Expression( other ), constant( other.constant ) {
    8282}
    8383
    8484ConstantExpr::~ConstantExpr() {}
    8585
    86 void ConstantExpr::print( std::ostream &os, Indenter indent ) const {
     86void ConstantExpr::print( std::ostream & os, Indenter indent ) const {
    8787        os << "constant expression " ;
    8888        constant.print( os );
     
    124124}
    125125
    126 VariableExpr::VariableExpr( const VariableExpr &other ) : Expression( other ), var( other.var ) {
     126VariableExpr::VariableExpr( const VariableExpr & other ) : Expression( other ), var( other.var ) {
    127127}
    128128
     
    137137}
    138138
    139 void VariableExpr::print( std::ostream &os, Indenter indent ) const {
     139void VariableExpr::print( std::ostream & os, Indenter indent ) const {
    140140        os << "Variable Expression: ";
    141141        var->printShort(os, indent);
     
    143143}
    144144
    145 SizeofExpr::SizeofExpr( Expression *expr_ ) :
     145SizeofExpr::SizeofExpr( Expression * expr_ ) :
    146146                Expression(), expr(expr_), type(0), isType(false) {
    147147        set_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );
    148148}
    149149
    150 SizeofExpr::SizeofExpr( Type *type_ ) :
     150SizeofExpr::SizeofExpr( Type * type_ ) :
    151151                Expression(), expr(0), type(type_), isType(true) {
    152152        set_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );
    153153}
    154154
    155 SizeofExpr::SizeofExpr( const SizeofExpr &other ) :
     155SizeofExpr::SizeofExpr( const SizeofExpr & other ) :
    156156        Expression( other ), expr( maybeClone( other.expr ) ), type( maybeClone( other.type ) ), isType( other.isType ) {
    157157}
     
    162162}
    163163
    164 void SizeofExpr::print( std::ostream &os, Indenter indent) const {
     164void SizeofExpr::print( std::ostream & os, Indenter indent) const {
    165165        os << "Sizeof Expression on: ";
    166166        if (isType) type->print(os, indent+1);
     
    169169}
    170170
    171 AlignofExpr::AlignofExpr( Expression *expr_ ) :
     171AlignofExpr::AlignofExpr( Expression * expr_ ) :
    172172                Expression(), expr(expr_), type(0), isType(false) {
    173173        set_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );
    174174}
    175175
    176 AlignofExpr::AlignofExpr( Type *type_ ) :
     176AlignofExpr::AlignofExpr( Type * type_ ) :
    177177                Expression(), expr(0), type(type_), isType(true) {
    178178        set_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );
    179179}
    180180
    181 AlignofExpr::AlignofExpr( const AlignofExpr &other ) :
     181AlignofExpr::AlignofExpr( const AlignofExpr & other ) :
    182182        Expression( other ), expr( maybeClone( other.expr ) ), type( maybeClone( other.type ) ), isType( other.isType ) {
    183183}
     
    188188}
    189189
    190 void AlignofExpr::print( std::ostream &os, Indenter indent) const {
     190void AlignofExpr::print( std::ostream & os, Indenter indent) const {
    191191        os << "Alignof Expression on: ";
    192192        if (isType) type->print(os, indent+1);
     
    195195}
    196196
    197 UntypedOffsetofExpr::UntypedOffsetofExpr( Type *type, const std::string &member ) :
     197UntypedOffsetofExpr::UntypedOffsetofExpr( Type * type, const std::string & member ) :
    198198                Expression(), type(type), member(member) {
    199199        assert( type );
     
    201201}
    202202
    203 UntypedOffsetofExpr::UntypedOffsetofExpr( const UntypedOffsetofExpr &other ) :
     203UntypedOffsetofExpr::UntypedOffsetofExpr( const UntypedOffsetofExpr & other ) :
    204204        Expression( other ), type( maybeClone( other.type ) ), member( other.member ) {}
    205205
     
    208208}
    209209
    210 void UntypedOffsetofExpr::print( std::ostream &os, Indenter indent) const {
     210void UntypedOffsetofExpr::print( std::ostream & os, Indenter indent) const {
    211211        os << "Untyped Offsetof Expression on member " << member << " of ";
    212212        type->print(os, indent+1);
     
    214214}
    215215
    216 OffsetofExpr::OffsetofExpr( Type *type, DeclarationWithType *member ) :
     216OffsetofExpr::OffsetofExpr( Type * type, DeclarationWithType * member ) :
    217217                Expression(), type(type), member(member) {
    218218        assert( member );
     
    221221}
    222222
    223 OffsetofExpr::OffsetofExpr( const OffsetofExpr &other ) :
     223OffsetofExpr::OffsetofExpr( const OffsetofExpr & other ) :
    224224        Expression( other ), type( maybeClone( other.type ) ), member( other.member ) {}
    225225
     
    228228}
    229229
    230 void OffsetofExpr::print( std::ostream &os, Indenter indent) const {
     230void OffsetofExpr::print( std::ostream & os, Indenter indent) const {
    231231        os << "Offsetof Expression on member " << member->name << " of ";
    232232        type->print(os, indent+1);
     
    234234}
    235235
    236 OffsetPackExpr::OffsetPackExpr( StructInstType *type ) : Expression(), type( type ) {
     236OffsetPackExpr::OffsetPackExpr( StructInstType * type ) : Expression(), type( type ) {
    237237        assert( type );
    238238        set_result( new ArrayType( Type::Qualifiers(), new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), 0, false, false ) );
    239239}
    240240
    241 OffsetPackExpr::OffsetPackExpr( const OffsetPackExpr &other ) : Expression( other ), type( maybeClone( other.type ) ) {}
     241OffsetPackExpr::OffsetPackExpr( const OffsetPackExpr & other ) : Expression( other ), type( maybeClone( other.type ) ) {}
    242242
    243243OffsetPackExpr::~OffsetPackExpr() { delete type; }
    244244
    245 void OffsetPackExpr::print( std::ostream &os, Indenter indent ) const {
     245void OffsetPackExpr::print( std::ostream & os, Indenter indent ) const {
    246246        os << "Offset pack expression on ";
    247247        type->print(os, indent+1);
     
    249249}
    250250
    251 AttrExpr::AttrExpr( Expression *attr, Expression *expr_ ) :
     251AttrExpr::AttrExpr( Expression * attr, Expression * expr_ ) :
    252252                Expression(), attr( attr ), expr(expr_), type(0), isType(false) {
    253253}
    254254
    255 AttrExpr::AttrExpr( Expression *attr, Type *type_ ) :
     255AttrExpr::AttrExpr( Expression * attr, Type * type_ ) :
    256256                Expression(), attr( attr ), expr(0), type(type_), isType(true) {
    257257}
    258258
    259 AttrExpr::AttrExpr( const AttrExpr &other ) :
     259AttrExpr::AttrExpr( const AttrExpr & other ) :
    260260                Expression( other ), attr( maybeClone( other.attr ) ), expr( maybeClone( other.expr ) ), type( maybeClone( other.type ) ), isType( other.isType ) {
    261261}
     
    267267}
    268268
    269 void AttrExpr::print( std::ostream &os, Indenter indent) const {
     269void AttrExpr::print( std::ostream & os, Indenter indent) const {
    270270        os << "Attr ";
    271271        attr->print( os, indent+1);
     
    278278}
    279279
    280 CastExpr::CastExpr( Expression *arg, Type *toType, bool isGenerated ) : Expression(), arg(arg), isGenerated( isGenerated ) {
     280CastExpr::CastExpr( Expression * arg, Type * toType, bool isGenerated ) : arg(arg), isGenerated( isGenerated ) {
    281281        set_result(toType);
    282282}
    283283
    284 CastExpr::CastExpr( Expression *arg, bool isGenerated ) : Expression(), arg(arg), isGenerated( isGenerated ) {
     284CastExpr::CastExpr( Expression * arg, bool isGenerated ) : arg(arg), isGenerated( isGenerated ) {
    285285        set_result( new VoidType( Type::Qualifiers() ) );
    286286}
    287287
    288 CastExpr::CastExpr( const CastExpr &other ) : Expression( other ), arg( maybeClone( other.arg ) ), isGenerated( other.isGenerated ) {
     288CastExpr::CastExpr( const CastExpr & other ) : Expression( other ), arg( maybeClone( other.arg ) ), isGenerated( other.isGenerated ) {
    289289}
    290290
     
    293293}
    294294
    295 void CastExpr::print( std::ostream &os, Indenter indent ) const {
    296         os << "Cast of:" << std::endl << indent+1;
     295void CastExpr::print( std::ostream & os, Indenter indent ) const {
     296        os << (isGenerated ? "Generated " : "Explicit ") << "Cast of:" << std::endl << indent+1;
    297297        arg->print(os, indent+1);
    298298        os << std::endl << indent << "... to:";
     
    306306}
    307307
    308 KeywordCastExpr::KeywordCastExpr( Expression *arg, Target target ) : Expression(), arg(arg), target( target ) {
    309 }
    310 
    311 KeywordCastExpr::KeywordCastExpr( const KeywordCastExpr &other ) : Expression( other ), arg( maybeClone( other.arg ) ), target( other.target ) {
     308KeywordCastExpr::KeywordCastExpr( Expression * arg, Target target ) : Expression(), arg(arg), target( target ) {
     309}
     310
     311KeywordCastExpr::KeywordCastExpr( const KeywordCastExpr & other ) : Expression( other ), arg( maybeClone( other.arg ) ), target( other.target ) {
    312312}
    313313
     
    327327}
    328328
    329 void KeywordCastExpr::print( std::ostream &os, Indenter indent ) const {
     329void KeywordCastExpr::print( std::ostream & os, Indenter indent ) const {
    330330        os << "Keyword Cast of:" << std::endl << indent+1;
    331331        arg->print(os, indent+1);
     
    335335}
    336336
    337 VirtualCastExpr::VirtualCastExpr( Expression *arg_, Type *toType ) : Expression(), arg(arg_) {
     337VirtualCastExpr::VirtualCastExpr( Expression * arg_, Type * toType ) : Expression(), arg(arg_) {
    338338        set_result(toType);
    339339}
    340340
    341 VirtualCastExpr::VirtualCastExpr( const VirtualCastExpr &other ) : Expression( other ), arg( maybeClone( other.arg ) ) {
     341VirtualCastExpr::VirtualCastExpr( const VirtualCastExpr & other ) : Expression( other ), arg( maybeClone( other.arg ) ) {
    342342}
    343343
     
    346346}
    347347
    348 void VirtualCastExpr::print( std::ostream &os, Indenter indent ) const {
     348void VirtualCastExpr::print( std::ostream & os, Indenter indent ) const {
    349349        os << "Virtual Cast of:" << std::endl << indent+1;
    350350        arg->print(os, indent+1);
     
    359359}
    360360
    361 UntypedMemberExpr::UntypedMemberExpr( Expression * member, Expression *aggregate ) :
     361UntypedMemberExpr::UntypedMemberExpr( Expression * member, Expression * aggregate ) :
    362362                Expression(), member(member), aggregate(aggregate) {
    363363        assert( aggregate );
    364364}
    365365
    366 UntypedMemberExpr::UntypedMemberExpr( const UntypedMemberExpr &other ) :
     366UntypedMemberExpr::UntypedMemberExpr( const UntypedMemberExpr & other ) :
    367367                Expression( other ), member( maybeClone( other.member ) ), aggregate( maybeClone( other.aggregate ) ) {
    368368}
     
    373373}
    374374
    375 void UntypedMemberExpr::print( std::ostream &os, Indenter indent ) const {
     375void UntypedMemberExpr::print( std::ostream & os, Indenter indent ) const {
    376376        os << "Untyped Member Expression, with field: " << std::endl << indent+1;
    377377        member->print(os, indent+1 );
     
    381381}
    382382
    383 MemberExpr::MemberExpr( DeclarationWithType *member, Expression *aggregate ) :
     383MemberExpr::MemberExpr( DeclarationWithType * member, Expression * aggregate ) :
    384384                Expression(), member(member), aggregate(aggregate) {
    385385        assert( member );
     
    395395}
    396396
    397 MemberExpr::MemberExpr( const MemberExpr &other ) :
     397MemberExpr::MemberExpr( const MemberExpr & other ) :
    398398                Expression( other ), member( other.member ), aggregate( maybeClone( other.aggregate ) ) {
    399399}
     
    404404}
    405405
    406 void MemberExpr::print( std::ostream &os, Indenter indent ) const {
     406void MemberExpr::print( std::ostream & os, Indenter indent ) const {
    407407        os << "Member Expression, with field:" << std::endl;
    408408        os << indent+1;
     
    413413}
    414414
    415 UntypedExpr::UntypedExpr( Expression *function, const std::list<Expression *> &args ) :
     415UntypedExpr::UntypedExpr( Expression * function, const std::list<Expression *> & args ) :
    416416                Expression(), function(function), args(args) {}
    417417
    418 UntypedExpr::UntypedExpr( const UntypedExpr &other ) :
     418UntypedExpr::UntypedExpr( const UntypedExpr & other ) :
    419419                Expression( other ), function( maybeClone( other.function ) ) {
    420420        cloneAll( other.args, args );
     
    455455
    456456
    457 void UntypedExpr::print( std::ostream &os, Indenter indent ) const {
     457void UntypedExpr::print( std::ostream & os, Indenter indent ) const {
    458458        os << "Applying untyped:" << std::endl;
    459459        os << indent+1;
     
    469469}
    470470
    471 NameExpr::NameExpr( const NameExpr &other ) : Expression( other ), name( other.name ) {
     471NameExpr::NameExpr( const NameExpr & other ) : Expression( other ), name( other.name ) {
    472472}
    473473
    474474NameExpr::~NameExpr() {}
    475475
    476 void NameExpr::print( std::ostream &os, Indenter indent ) const {
     476void NameExpr::print( std::ostream & os, Indenter indent ) const {
    477477        os << "Name: " << get_name();
    478478        Expression::print( os, indent );
    479479}
    480480
    481 LogicalExpr::LogicalExpr( Expression *arg1_, Expression *arg2_, bool andp ) :
     481LogicalExpr::LogicalExpr( Expression * arg1_, Expression * arg2_, bool andp ) :
    482482                Expression(), arg1(arg1_), arg2(arg2_), isAnd(andp) {
    483483        set_result( new BasicType( Type::Qualifiers(), BasicType::SignedInt ) );
    484484}
    485485
    486 LogicalExpr::LogicalExpr( const LogicalExpr &other ) :
     486LogicalExpr::LogicalExpr( const LogicalExpr & other ) :
    487487                Expression( other ), arg1( maybeClone( other.arg1 ) ), arg2( maybeClone( other.arg2 ) ), isAnd( other.isAnd ) {
    488488}
     
    493493}
    494494
    495 void LogicalExpr::print( std::ostream &os, Indenter indent )const {
     495void LogicalExpr::print( std::ostream & os, Indenter indent )const {
    496496        os << "Short-circuited operation (" << (isAnd ? "and" : "or") << ") on: ";
    497497        arg1->print(os);
     
    504504                Expression(), arg1(arg1), arg2(arg2), arg3(arg3) {}
    505505
    506 ConditionalExpr::ConditionalExpr( const ConditionalExpr &other ) :
     506ConditionalExpr::ConditionalExpr( const ConditionalExpr & other ) :
    507507                Expression( other ), arg1( maybeClone( other.arg1 ) ), arg2( maybeClone( other.arg2 ) ), arg3( maybeClone( other.arg3 ) ) {
    508508}
     
    514514}
    515515
    516 void ConditionalExpr::print( std::ostream &os, Indenter indent ) const {
     516void ConditionalExpr::print( std::ostream & os, Indenter indent ) const {
    517517        os << "Conditional expression on: " << std::endl << indent+1;
    518518        arg1->print( os, indent+1 );
     
    527527
    528528
    529 void AsmExpr::print( std::ostream &os, Indenter indent ) const {
     529void AsmExpr::print( std::ostream & os, Indenter indent ) const {
    530530        os << "Asm Expression: " << std::endl;
    531531        if ( inout ) inout->print( os, indent+1 );
     
    549549}
    550550
    551 void ImplicitCopyCtorExpr::print( std::ostream &os, Indenter indent ) const {
     551void ImplicitCopyCtorExpr::print( std::ostream & os, Indenter indent ) const {
    552552        os <<  "Implicit Copy Constructor Expression: " << std::endl << indent+1;
    553553        callExpr->print( os, indent+1 );
     
    570570}
    571571
    572 void ConstructorExpr::print( std::ostream &os, Indenter indent ) const {
     572void ConstructorExpr::print( std::ostream & os, Indenter indent ) const {
    573573        os <<  "Constructor Expression: " << std::endl << indent+1;
    574574        callExpr->print( os, indent + 2 );
     
    583583}
    584584
    585 CompoundLiteralExpr::CompoundLiteralExpr( const CompoundLiteralExpr &other ) : Expression( other ), initializer( other.initializer->clone() ) {}
     585CompoundLiteralExpr::CompoundLiteralExpr( const CompoundLiteralExpr & other ) : Expression( other ), initializer( other.initializer->clone() ) {}
    586586
    587587CompoundLiteralExpr::~CompoundLiteralExpr() {
     
    589589}
    590590
    591 void CompoundLiteralExpr::print( std::ostream &os, Indenter indent ) const {
     591void CompoundLiteralExpr::print( std::ostream & os, Indenter indent ) const {
    592592        os << "Compound Literal Expression: " << std::endl << indent+1;
    593593        result->print( os, indent+1 );
     
    597597}
    598598
    599 RangeExpr::RangeExpr( Expression *low, Expression *high ) : low( low ), high( high ) {}
    600 RangeExpr::RangeExpr( const RangeExpr &other ) : Expression( other ), low( other.low->clone() ), high( other.high->clone() ) {}
    601 void RangeExpr::print( std::ostream &os, Indenter indent ) const {
     599RangeExpr::RangeExpr( Expression * low, Expression * high ) : low( low ), high( high ) {}
     600RangeExpr::RangeExpr( const RangeExpr & other ) : Expression( other ), low( other.low->clone() ), high( other.high->clone() ) {}
     601void RangeExpr::print( std::ostream & os, Indenter indent ) const {
    602602        os << "Range Expression: ";
    603603        low->print( os, indent );
     
    607607}
    608608
    609 StmtExpr::StmtExpr( CompoundStmt *statements ) : statements( statements ) {
     609StmtExpr::StmtExpr( CompoundStmt * statements ) : statements( statements ) {
    610610        computeResult();
    611611}
    612 StmtExpr::StmtExpr( const StmtExpr &other ) : Expression( other ), statements( other.statements->clone() ) {
     612StmtExpr::StmtExpr( const StmtExpr & other ) : Expression( other ), statements( other.statements->clone() ) {
    613613        cloneAll( other.returnDecls, returnDecls );
    614614        cloneAll( other.dtors, dtors );
     
    639639        }
    640640}
    641 void StmtExpr::print( std::ostream &os, Indenter indent ) const {
     641void StmtExpr::print( std::ostream & os, Indenter indent ) const {
    642642        os << "Statement Expression: " << std::endl << indent+1;
    643643        statements->print( os, indent+1 );
     
    655655
    656656long long UniqueExpr::count = 0;
    657 UniqueExpr::UniqueExpr( Expression *expr, long long idVal ) : expr( expr ), object( nullptr ), var( nullptr ), id( idVal ) {
     657UniqueExpr::UniqueExpr( Expression * expr, long long idVal ) : expr( expr ), object( nullptr ), var( nullptr ), id( idVal ) {
    658658        assert( expr );
    659659        assert( count != -1 );
     
    663663        }
    664664}
    665 UniqueExpr::UniqueExpr( const UniqueExpr &other ) : Expression( other ), expr( maybeClone( other.expr ) ), object( maybeClone( other.object ) ), var( maybeClone( other.var ) ), id( other.id ) {
     665UniqueExpr::UniqueExpr( const UniqueExpr & other ) : Expression( other ), expr( maybeClone( other.expr ) ), object( maybeClone( other.object ) ), var( maybeClone( other.var ) ), id( other.id ) {
    666666}
    667667UniqueExpr::~UniqueExpr() {
     
    670670        delete var;
    671671}
    672 void UniqueExpr::print( std::ostream &os, Indenter indent ) const {
     672void UniqueExpr::print( std::ostream & os, Indenter indent ) const {
    673673        os << "Unique Expression with id:" << id << std::endl << indent+1;
    674674        expr->print( os, indent+1 );
  • src/SynTree/Expression.h

    r6a9d4b4 r933f32f  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Sep  3 19:23:46 2017
    13 // Update Count     : 48
     12// Last Modified On : Mon Feb 18 18:29:51 2019
     13// Update Count     : 49
    1414//
    1515
     
    195195  public:
    196196        Expression * arg;
    197         bool isGenerated = true; // whether this cast appeared in the source program
     197        bool isGenerated = true; // cast generated implicitly by code generation or explicit in program
    198198
    199199        CastExpr( Expression * arg, bool isGenerated = true );
  • src/SynTree/Label.h

    r6a9d4b4 r933f32f  
    3535        operator std::string() const { return name; }
    3636        bool empty() { return name.empty(); }
    37   private:
     37
    3838        std::string name;
    3939        Statement * labelled;
  • src/SynTree/Mutator.h

    r6a9d4b4 r933f32f  
    121121        virtual Initializer * mutate( ConstructorInit * ctorInit ) = 0 ;
    122122
    123         virtual Subrange * mutate( Subrange * subrange ) = 0;
    124 
    125123        virtual Constant * mutate( Constant * constant ) = 0;
    126124
  • src/SynTree/Statement.h

    r6a9d4b4 r933f32f  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Mar  8 14:53:02 2018
    13 // Update Count     : 78
     12// Last Modified On : Tue Mar 12 09:01:53 2019
     13// Update Count     : 83
    1414//
    1515
     
    1919#include <list>                    // for list
    2020#include <memory>                  // for allocator
    21 #include <vector>                        // for vector
     21#include <vector>                                  // for vector
    2222
    2323#include "BaseSyntaxNode.h"        // for BaseSyntaxNode
     
    4343        const std::list<Label> & get_labels() const { return labels; }
    4444
    45         virtual Statement *clone() const override = 0;
    46         virtual void accept( Visitor &v ) override = 0;
    47         virtual Statement *acceptMutator( Mutator &m ) override = 0;
    48         virtual void print( std::ostream &os, Indenter indent = {} ) const override;
     45        virtual Statement * clone() const override = 0;
     46        virtual void accept( Visitor & v ) override = 0;
     47        virtual Statement * acceptMutator( Mutator & m ) override = 0;
     48        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    4949};
    5050
     
    5555        CompoundStmt();
    5656        CompoundStmt( std::list<Statement *> stmts );
    57         CompoundStmt( const CompoundStmt &other );
     57        CompoundStmt( const CompoundStmt & other );
    5858        virtual ~CompoundStmt();
    5959
     
    6262        void push_front( Statement * stmt ) { kids.push_front( stmt ); }
    6363
    64         virtual CompoundStmt *clone() const override { return new CompoundStmt( *this ); }
    65         virtual void accept( Visitor &v ) override { v.visit( this ); }
    66         virtual CompoundStmt *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    67         virtual void print( std::ostream &os, Indenter indent = {} ) const override;
     64        virtual CompoundStmt * clone() const override { return new CompoundStmt( *this ); }
     65        virtual void accept( Visitor & v ) override { v.visit( this ); }
     66        virtual CompoundStmt * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
     67        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    6868};
    6969
     
    7272        NullStmt( const std::list<Label> & labels = {} );
    7373
    74         virtual NullStmt *clone() const override { return new NullStmt( *this ); }
    75         virtual void accept( Visitor &v ) override { v.visit( this ); }
    76         virtual NullStmt *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    77         virtual void print( std::ostream &os, Indenter indent = {} ) const override;
     74        virtual NullStmt * clone() const override { return new NullStmt( *this ); }
     75        virtual void accept( Visitor & v ) override { v.visit( this ); }
     76        virtual NullStmt * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
     77        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    7878};
    7979
    8080class ExprStmt : public Statement {
    8181  public:
    82         Expression *expr;
    83 
    84         ExprStmt( Expression *expr );
    85         ExprStmt( const ExprStmt &other );
     82        Expression * expr;
     83
     84        ExprStmt( Expression * expr );
     85        ExprStmt( const ExprStmt & other );
    8686        virtual ~ExprStmt();
    8787
    88         Expression *get_expr() { return expr; }
    89         void set_expr( Expression *newValue ) { expr = newValue; }
    90 
    91         virtual ExprStmt *clone() const override { return new ExprStmt( *this ); }
    92         virtual void accept( Visitor &v ) override { v.visit( this ); }
    93         virtual Statement *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    94         virtual void print( std::ostream &os, Indenter indent = {} ) const override;
     88        Expression * get_expr() { return expr; }
     89        void set_expr( Expression * newValue ) { expr = newValue; }
     90
     91        virtual ExprStmt * clone() const override { return new ExprStmt( *this ); }
     92        virtual void accept( Visitor & v ) override { v.visit( this ); }
     93        virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
     94        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    9595};
    9696
     
    9898  public:
    9999        bool voltile;
    100         Expression *instruction;
     100        Expression * instruction;
    101101        std::list<Expression *> output, input;
    102102        std::list<ConstantExpr *> clobber;
    103103        std::list<Label> gotolabels;
    104104
    105         AsmStmt( bool voltile, Expression *instruction, std::list<Expression *> output, std::list<Expression *> input, std::list<ConstantExpr *> clobber, std::list<Label> gotolabels );
    106         AsmStmt( const AsmStmt &other );
     105        AsmStmt( bool voltile, Expression * instruction, std::list<Expression *> output, std::list<Expression *> input, std::list<ConstantExpr *> clobber, std::list<Label> gotolabels );
     106        AsmStmt( const AsmStmt & other );
    107107        virtual ~AsmStmt();
    108108
     
    114114        void set_output( const std::list<Expression *> & newValue ) { output = newValue; }
    115115        std::list<Expression *> & get_input() { return input; }
    116         void set_input( const std::list<Expression *> &newValue ) { input = newValue; }
     116        void set_input( const std::list<Expression *> & newValue ) { input = newValue; }
    117117        std::list<ConstantExpr *> & get_clobber() { return clobber; }
    118         void set_clobber( const std::list<ConstantExpr *> &newValue ) { clobber = newValue; }
     118        void set_clobber( const std::list<ConstantExpr *> & newValue ) { clobber = newValue; }
    119119        std::list<Label> & get_gotolabels() { return gotolabels; }
    120         void set_gotolabels( const std::list<Label> &newValue ) { gotolabels = newValue; }
     120        void set_gotolabels( const std::list<Label> & newValue ) { gotolabels = newValue; }
    121121
    122122        virtual AsmStmt * clone() const { return new AsmStmt( *this ); }
     
    141141class IfStmt : public Statement {
    142142  public:
    143         Expression *condition;
    144         Statement *thenPart;
    145         Statement *elsePart;
     143        Expression * condition;
     144        Statement * thenPart;
     145        Statement * elsePart;
    146146        std::list<Statement *> initialization;
    147147
    148         IfStmt( Expression *condition, Statement *thenPart, Statement *elsePart,
     148        IfStmt( Expression * condition, Statement * thenPart, Statement * elsePart,
    149149                        std::list<Statement *> initialization = std::list<Statement *>() );
    150         IfStmt( const IfStmt &other );
     150        IfStmt( const IfStmt & other );
    151151        virtual ~IfStmt();
    152152
    153         std::list<Statement *> &get_initialization() { return initialization; }
    154         Expression *get_condition() { return condition; }
    155         void set_condition( Expression *newValue ) { condition = newValue; }
    156         Statement *get_thenPart() { return thenPart; }
    157         void set_thenPart( Statement *newValue ) { thenPart = newValue; }
    158         Statement *get_elsePart() { return elsePart; }
    159         void set_elsePart( Statement *newValue ) { elsePart = newValue; }
    160 
    161         virtual IfStmt *clone() const override { return new IfStmt( *this ); }
    162         virtual void accept( Visitor &v ) override { v.visit( this ); }
    163         virtual Statement *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    164         virtual void print( std::ostream &os, Indenter indent = {} ) const override;
     153        std::list<Statement *> & get_initialization() { return initialization; }
     154        Expression * get_condition() { return condition; }
     155        void set_condition( Expression * newValue ) { condition = newValue; }
     156        Statement * get_thenPart() { return thenPart; }
     157        void set_thenPart( Statement * newValue ) { thenPart = newValue; }
     158        Statement * get_elsePart() { return elsePart; }
     159        void set_elsePart( Statement * newValue ) { elsePart = newValue; }
     160
     161        virtual IfStmt * clone() const override { return new IfStmt( *this ); }
     162        virtual void accept( Visitor & v ) override { v.visit( this ); }
     163        virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
     164        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    165165};
    166166
     
    170170        std::list<Statement *> statements;
    171171
    172         SwitchStmt( Expression *condition, const std::list<Statement *> &statements );
    173         SwitchStmt( const SwitchStmt &other );
     172        SwitchStmt( Expression * condition, const std::list<Statement *> & statements );
     173        SwitchStmt( const SwitchStmt & other );
    174174        virtual ~SwitchStmt();
    175175
    176         Expression *get_condition() { return condition; }
    177         void set_condition( Expression *newValue ) { condition = newValue; }
     176        Expression * get_condition() { return condition; }
     177        void set_condition( Expression * newValue ) { condition = newValue; }
    178178
    179179        std::list<Statement *> & get_statements() { return statements; }
    180180
    181         virtual void accept( Visitor &v ) override { v.visit( this ); }
    182         virtual Statement *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    183 
    184         virtual SwitchStmt *clone() const override { return new SwitchStmt( *this ); }
    185         virtual void print( std::ostream &os, Indenter indent = {} ) const override;
     181        virtual void accept( Visitor & v ) override { v.visit( this ); }
     182        virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
     183
     184        virtual SwitchStmt * clone() const override { return new SwitchStmt( *this ); }
     185        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    186186
    187187};
     
    192192        std::list<Statement *> stmts;
    193193
    194         CaseStmt( Expression *conditions, const std::list<Statement *> &stmts, bool isdef = false ) throw (SemanticErrorException);
    195         CaseStmt( const CaseStmt &other );
     194        CaseStmt( Expression * conditions, const std::list<Statement *> & stmts, bool isdef = false ) throw (SemanticErrorException);
     195        CaseStmt( const CaseStmt & other );
    196196        virtual ~CaseStmt();
    197197
     
    201201        void set_default(bool b) { _isDefault = b; }
    202202
    203         Expression * &get_condition() { return condition; }
    204         void set_condition( Expression *newValue ) { condition = newValue; }
    205 
    206         std::list<Statement *> &get_statements() { return stmts; }
    207         void set_statements( std::list<Statement *> &newValue ) { stmts = newValue; }
    208 
    209         virtual void accept( Visitor &v ) override { v.visit( this ); }
    210         virtual Statement *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    211 
    212         virtual CaseStmt *clone() const override { return new CaseStmt( *this ); }
    213         virtual void print( std::ostream &os, Indenter indent = {} ) const override;
     203        Expression * & get_condition() { return condition; }
     204        void set_condition( Expression * newValue ) { condition = newValue; }
     205
     206        std::list<Statement *> & get_statements() { return stmts; }
     207        void set_statements( std::list<Statement *> & newValue ) { stmts = newValue; }
     208
     209        virtual void accept( Visitor & v ) override { v.visit( this ); }
     210        virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
     211
     212        virtual CaseStmt * clone() const override { return new CaseStmt( *this ); }
     213        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    214214  private:
    215215        bool _isDefault;
     
    218218class WhileStmt : public Statement {
    219219  public:
    220         Expression *condition;
    221         Statement *body;
     220        Expression * condition;
     221        Statement * body;
    222222        std::list<Statement *> initialization;
    223223        bool isDoWhile;
    224224
    225         WhileStmt( Expression *condition,
    226                Statement *body, std::list<Statement *> & initialization, bool isDoWhile = false );
    227         WhileStmt( const WhileStmt &other );
     225        WhileStmt( Expression * condition, Statement * body, std::list<Statement *> & initialization, bool isDoWhile = false );
     226        WhileStmt( const WhileStmt & other );
    228227        virtual ~WhileStmt();
    229228
    230         Expression *get_condition() { return condition; }
    231         void set_condition( Expression *newValue ) { condition = newValue; }
    232         Statement *get_body() { return body; }
    233         void set_body( Statement *newValue ) { body = newValue; }
     229        Expression * get_condition() { return condition; }
     230        void set_condition( Expression * newValue ) { condition = newValue; }
     231        Statement * get_body() { return body; }
     232        void set_body( Statement * newValue ) { body = newValue; }
    234233        bool get_isDoWhile() { return isDoWhile; }
    235234        void set_isDoWhile( bool newValue ) { isDoWhile = newValue; }
    236235
    237         virtual WhileStmt *clone() const override { return new WhileStmt( *this ); }
    238         virtual void accept( Visitor &v ) override { v.visit( this ); }
    239         virtual Statement *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    240         virtual void print( std::ostream &os, Indenter indent = {} ) const override;
     236        virtual WhileStmt * clone() const override { return new WhileStmt( *this ); }
     237        virtual void accept( Visitor & v ) override { v.visit( this ); }
     238        virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
     239        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    241240};
    242241
     
    244243  public:
    245244        std::list<Statement *> initialization;
    246         Expression *condition;
    247         Expression *increment;
    248         Statement *body;
    249 
    250         ForStmt( std::list<Statement *> initialization,
    251              Expression *condition = 0, Expression *increment = 0, Statement *body = 0 );
    252         ForStmt( const ForStmt &other );
     245        Expression * condition;
     246        Expression * increment;
     247        Statement * body;
     248
     249        ForStmt( std::list<Statement *> initialization, Expression * condition = 0, Expression * increment = 0, Statement * body = 0 );
     250        ForStmt( const ForStmt & other );
    253251        virtual ~ForStmt();
    254252
    255         std::list<Statement *> &get_initialization() { return initialization; }
    256         Expression *get_condition() { return condition; }
    257         void set_condition( Expression *newValue ) { condition = newValue; }
    258         Expression *get_increment() { return increment; }
    259         void set_increment( Expression *newValue ) { increment = newValue; }
    260         Statement *get_body() { return body; }
    261         void set_body( Statement *newValue ) { body = newValue; }
    262 
    263         virtual ForStmt *clone() const override { return new ForStmt( *this ); }
    264         virtual void accept( Visitor &v ) override { v.visit( this ); }
    265         virtual Statement *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    266         virtual void print( std::ostream &os, Indenter indent = {} ) const override;
     253        std::list<Statement *> & get_initialization() { return initialization; }
     254        Expression * get_condition() { return condition; }
     255        void set_condition( Expression * newValue ) { condition = newValue; }
     256        Expression * get_increment() { return increment; }
     257        void set_increment( Expression * newValue ) { increment = newValue; }
     258        Statement * get_body() { return body; }
     259        void set_body( Statement * newValue ) { body = newValue; }
     260
     261        virtual ForStmt * clone() const override { return new ForStmt( *this ); }
     262        virtual void accept( Visitor & v ) override { v.visit( this ); }
     263        virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
     264        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    267265};
    268266
     
    274272        const Label originalTarget;
    275273        Label target;
    276         Expression *computedTarget;
     274        Expression * computedTarget;
    277275        Type type;
    278276
    279277        BranchStmt( Label target, Type ) throw (SemanticErrorException);
    280         BranchStmt( Expression *computedTarget, Type ) throw (SemanticErrorException);
     278        BranchStmt( Expression * computedTarget, Type ) throw (SemanticErrorException);
    281279
    282280        Label get_originalTarget() { return originalTarget; }
     
    284282        void set_target( Label newValue ) { target = newValue; }
    285283
    286         Expression *get_computedTarget() { return computedTarget; }
     284        Expression * get_computedTarget() { return computedTarget; }
    287285        void set_target( Expression * newValue ) { computedTarget = newValue; }
    288286
    289287        Type get_type() { return type; }
    290         const char *get_typename() { return brType[ type ]; }
    291 
    292         virtual BranchStmt *clone() const override { return new BranchStmt( *this ); }
    293         virtual void accept( Visitor &v ) override { v.visit( this ); }
    294         virtual Statement *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    295         virtual void print( std::ostream &os, Indenter indent = {} ) const override;
     288        const char * get_typename() { return brType[ type ]; }
     289
     290        virtual BranchStmt * clone() const override { return new BranchStmt( *this ); }
     291        virtual void accept( Visitor & v ) override { v.visit( this ); }
     292        virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
     293        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    296294  private:
    297         static const char *brType[];
     295        static const char * brType[];
    298296};
    299297
    300298class ReturnStmt : public Statement {
    301299  public:
    302         Expression *expr;
    303 
    304         ReturnStmt( Expression *expr );
    305         ReturnStmt( const ReturnStmt &other );
     300        Expression * expr;
     301
     302        ReturnStmt( Expression * expr );
     303        ReturnStmt( const ReturnStmt & other );
    306304        virtual ~ReturnStmt();
    307305
    308         Expression *get_expr() { return expr; }
    309         void set_expr( Expression *newValue ) { expr = newValue; }
    310 
    311         virtual ReturnStmt *clone() const override { return new ReturnStmt( *this ); }
    312         virtual void accept( Visitor &v ) override { v.visit( this ); }
    313         virtual Statement *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    314         virtual void print( std::ostream &os, Indenter indent = {} ) const override;
     306        Expression * get_expr() { return expr; }
     307        void set_expr( Expression * newValue ) { expr = newValue; }
     308
     309        virtual ReturnStmt * clone() const override { return new ReturnStmt( *this ); }
     310        virtual void accept( Visitor & v ) override { v.visit( this ); }
     311        virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
     312        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    315313};
    316314
     
    324322
    325323        ThrowStmt( Kind kind, Expression * expr, Expression * target = nullptr );
    326         ThrowStmt( const ThrowStmt &other );
     324        ThrowStmt( const ThrowStmt & other );
    327325        virtual ~ThrowStmt();
    328326
     
    333331        void set_target( Expression * newTarget ) { target = newTarget; }
    334332
    335         virtual ThrowStmt *clone() const override { return new ThrowStmt( *this ); }
    336         virtual void accept( Visitor &v ) override { v.visit( this ); }
    337         virtual Statement *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    338         virtual void print( std::ostream &os, Indenter indent = {} ) const override;
     333        virtual ThrowStmt * clone() const override { return new ThrowStmt( *this ); }
     334        virtual void accept( Visitor & v ) override { v.visit( this ); }
     335        virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
     336        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    339337};
    340338
     
    345343        FinallyStmt * finallyBlock;
    346344
    347         TryStmt( CompoundStmt *tryBlock, std::list<CatchStmt *> &handlers, FinallyStmt *finallyBlock = 0 );
    348         TryStmt( const TryStmt &other );
     345        TryStmt( CompoundStmt * tryBlock, std::list<CatchStmt *> & handlers, FinallyStmt * finallyBlock = 0 );
     346        TryStmt( const TryStmt & other );
    349347        virtual ~TryStmt();
    350348
    351         CompoundStmt *get_block() const { return block; }
    352         void set_block( CompoundStmt *newValue ) { block = newValue; }
     349        CompoundStmt * get_block() const { return block; }
     350        void set_block( CompoundStmt * newValue ) { block = newValue; }
    353351        std::list<CatchStmt *>& get_catchers() { return handlers; }
    354352
    355         FinallyStmt *get_finally() const { return finallyBlock; }
    356         void set_finally( FinallyStmt *newValue ) { finallyBlock = newValue; }
    357 
    358         virtual TryStmt *clone() const override { return new TryStmt( *this ); }
    359         virtual void accept( Visitor &v ) override { v.visit( this ); }
    360         virtual Statement *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    361         virtual void print( std::ostream &os, Indenter indent = {} ) const override;
     353        FinallyStmt * get_finally() const { return finallyBlock; }
     354        void set_finally( FinallyStmt * newValue ) { finallyBlock = newValue; }
     355
     356        virtual TryStmt * clone() const override { return new TryStmt( *this ); }
     357        virtual void accept( Visitor & v ) override { v.visit( this ); }
     358        virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
     359        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    362360};
    363361
     
    367365
    368366        const Kind kind;
    369         Declaration *decl;
    370         Expression *cond;
    371         Statement *body;
    372 
    373         CatchStmt( Kind kind, Declaration *decl,
    374                    Expression *cond, Statement *body );
    375         CatchStmt( const CatchStmt &other );
     367        Declaration * decl;
     368        Expression * cond;
     369        Statement * body;
     370
     371        CatchStmt( Kind kind, Declaration * decl,
     372                   Expression * cond, Statement * body );
     373        CatchStmt( const CatchStmt & other );
    376374        virtual ~CatchStmt();
    377375
    378376        Kind get_kind() { return kind; }
    379         Declaration *get_decl() { return decl; }
    380         void set_decl( Declaration *newValue ) { decl = newValue; }
    381         Expression *get_cond() { return cond; }
    382         void set_cond( Expression *newCond ) { cond = newCond; }
    383         Statement *get_body() { return body; }
    384         void set_body( Statement *newValue ) { body = newValue; }
    385 
    386         virtual CatchStmt *clone() const override { return new CatchStmt( *this ); }
    387         virtual void accept( Visitor &v ) override { v.visit( this ); }
    388         virtual Statement *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    389         virtual void print( std::ostream &os, Indenter indent = {} ) const override;
     377        Declaration * get_decl() { return decl; }
     378        void set_decl( Declaration * newValue ) { decl = newValue; }
     379        Expression * get_cond() { return cond; }
     380        void set_cond( Expression * newCond ) { cond = newCond; }
     381        Statement * get_body() { return body; }
     382        void set_body( Statement * newValue ) { body = newValue; }
     383
     384        virtual CatchStmt * clone() const override { return new CatchStmt( *this ); }
     385        virtual void accept( Visitor & v ) override { v.visit( this ); }
     386        virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
     387        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    390388};
    391389
    392390class FinallyStmt : public Statement {
    393391  public:
    394         CompoundStmt *block;
    395 
    396         FinallyStmt( CompoundStmt *block );
    397         FinallyStmt( const FinallyStmt &other );
     392        CompoundStmt * block;
     393
     394        FinallyStmt( CompoundStmt * block );
     395        FinallyStmt( const FinallyStmt & other );
    398396        virtual ~FinallyStmt();
    399397
    400         CompoundStmt *get_block() const { return block; }
    401         void set_block( CompoundStmt *newValue ) { block = newValue; }
    402 
    403         virtual FinallyStmt *clone() const override { return new FinallyStmt( *this ); }
    404         virtual void accept( Visitor &v ) override { v.visit( this ); }
    405         virtual Statement *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    406         virtual void print( std::ostream &os, Indenter indent = {} ) const override;
     398        CompoundStmt * get_block() const { return block; }
     399        void set_block( CompoundStmt * newValue ) { block = newValue; }
     400
     401        virtual FinallyStmt * clone() const override { return new FinallyStmt( *this ); }
     402        virtual void accept( Visitor & v ) override { v.visit( this ); }
     403        virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
     404        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    407405};
    408406
     
    438436        } orelse;
    439437
    440         virtual WaitForStmt *clone() const override { return new WaitForStmt( *this ); }
    441         virtual void accept( Visitor &v ) override { v.visit( this ); }
    442         virtual Statement *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    443         virtual void print( std::ostream &os, Indenter indent = {} ) const override;
     438        virtual WaitForStmt * clone() const override { return new WaitForStmt( *this ); }
     439        virtual void accept( Visitor & v ) override { v.visit( this ); }
     440        virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
     441        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    444442
    445443};
     
    464462class DeclStmt : public Statement {
    465463  public:
    466         Declaration *decl;
    467 
    468         DeclStmt( Declaration *decl );
    469         DeclStmt( const DeclStmt &other );
     464        Declaration * decl;
     465
     466        DeclStmt( Declaration * decl );
     467        DeclStmt( const DeclStmt & other );
    470468        virtual ~DeclStmt();
    471469
    472         Declaration *get_decl() const { return decl; }
    473         void set_decl( Declaration *newValue ) { decl = newValue; }
    474 
    475         virtual DeclStmt *clone() const override { return new DeclStmt( *this ); }
    476         virtual void accept( Visitor &v ) override { v.visit( this ); }
    477         virtual Statement *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    478         virtual void print( std::ostream &os, Indenter indent = {} ) const override;
    479 };
    480 
    481 
    482 /// represents an implicit application of a constructor or destructor. Qualifiers are replaced
    483 /// immediately before and after the call so that qualified objects can be constructed
    484 /// with the same functions as unqualified objects.
     470        Declaration * get_decl() const { return decl; }
     471        void set_decl( Declaration * newValue ) { decl = newValue; }
     472
     473        virtual DeclStmt * clone() const override { return new DeclStmt( *this ); }
     474        virtual void accept( Visitor & v ) override { v.visit( this ); }
     475        virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
     476        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     477};
     478
     479
     480/// represents an implicit application of a constructor or destructor. Qualifiers are replaced immediately before and
     481/// after the call so that qualified objects can be constructed with the same functions as unqualified objects.
    485482class ImplicitCtorDtorStmt : public Statement {
    486483  public:
     
    492489        virtual ~ImplicitCtorDtorStmt();
    493490
    494         Statement *get_callStmt() const { return callStmt; }
     491        Statement * get_callStmt() const { return callStmt; }
    495492        void set_callStmt( Statement * newValue ) { callStmt = newValue; }
    496493
    497         virtual ImplicitCtorDtorStmt *clone() const override { return new ImplicitCtorDtorStmt( *this ); }
    498         virtual void accept( Visitor &v ) override { v.visit( this ); }
    499         virtual Statement *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    500         virtual void print( std::ostream &os, Indenter indent = {} ) const override;
     494        virtual ImplicitCtorDtorStmt * clone() const override { return new ImplicitCtorDtorStmt( *this ); }
     495        virtual void accept( Visitor & v ) override { v.visit( this ); }
     496        virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
     497        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    501498};
    502499
  • src/SynTree/SynTree.h

    r6a9d4b4 r933f32f  
    3434class NamedTypeDecl;
    3535class TypeDecl;
    36 class FtypeDecl;
    37 class DtypeDecl;
    3836class TypedefDecl;
    3937class AsmDecl;
     
    9088class ConstructorExpr;
    9189class CompoundLiteralExpr;
    92 class UntypedValofExpr;
    9390class RangeExpr;
    9491class UntypedTupleExpr;
     
    132129class ConstructorInit;
    133130
    134 class Subrange;
    135 
    136131//template <class T>    // emulate a union with templates?
    137132class Constant;
  • src/SynTree/Type.cc

    r6a9d4b4 r933f32f  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Jun 22 10:17:19 2018
    13 // Update Count     : 39
     12// Last Modified On : Thu Jan 31 21:54:16 2019
     13// Update Count     : 43
    1414//
    1515#include "Type.h"
     
    2525
    2626const char *BasicType::typeNames[] = {
     27#if 0
    2728        "_Bool",
    2829        "char",
     
    4950        "unsigned __int128",
    5051        "__float80",
    51         "__float128"
     52        "__float128",
     53        "_Float16",
     54        "_Float32",
     55        "_Float32x",
     56        "_Float64",
     57        "_Float64x",
     58        "_Float128",
     59        "_Float128x",
     60        "_Float16 _Complex",
     61        "_Float32 _Complex",
     62        "_Float32x _Complex",
     63        "_Float64 _Complex",
     64        "_Float64x _Complex",
     65        "_Float128 _Complex",
     66        "_Float128x _Complex",
     67#endif
     68        "_Bool",
     69        "char",
     70        "signed char",
     71        "unsigned char",
     72        "signed short int",
     73        "unsigned short int",
     74        "signed int",
     75        "unsigned int",
     76        "signed long int",
     77        "unsigned long int",
     78        "signed long long int",
     79        "unsigned long long int",
     80        "__int128",
     81        "unsigned __int128",
     82        "_Float16",
     83        "_Float16 _Complex",
     84        "_Float32",
     85        "_Float32 _Complex",
     86        "float",
     87        "float _Complex",
     88        //"float _Imaginary",
     89        "_Float32x",
     90        "_Float32x _Complex",
     91        "_Float64",
     92        "_Float64 _Complex",
     93        "double",
     94        "double _Complex",
     95        //"double _Imaginary",
     96        "_Float64x",
     97        "_Float64x _Complex",
     98        "__float80",
     99        "_Float128",
     100        "_Float128 _Complex",
     101        "__float128",
     102        "long double",
     103        "long double _Complex",
     104        //"long double _Imaginary",
     105        "_Float128x",
     106        "_Float128x _Complex",
    52107};
    53108static_assert(
  • src/SynTree/Type.h

    r6a9d4b4 r933f32f  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Sep 25 14:14:01 2017
    13 // Update Count     : 154
     12// Last Modified On : Thu Feb 14 17:11:24 2019
     13// Update Count     : 169
    1414//
    1515
     
    207207class BasicType : public Type {
    208208  public:
     209        // GENERATED START, DO NOT EDIT
     210        // GENERATED BY BasicTypes-gen.cc
    209211        enum Kind {
    210212                Bool,
     
    220222                LongLongSignedInt,
    221223                LongLongUnsignedInt,
    222                 Float,
    223                 Double,
    224                 LongDouble,
    225                 FloatComplex,
    226                 DoubleComplex,
    227                 LongDoubleComplex,
    228                 FloatImaginary,
    229                 DoubleImaginary,
    230                 LongDoubleImaginary,
    231224                SignedInt128,
    232225                UnsignedInt128,
    233                 Float80,
    234                 Float128,
     226                uFloat16,
     227                uFloat16Complex,
     228                uFloat32,
     229                uFloat32Complex,
     230                Float,
     231                FloatComplex,
     232                uFloat32x,
     233                uFloat32xComplex,
     234                uFloat64,
     235                uFloat64Complex,
     236                Double,
     237                DoubleComplex,
     238                uFloat64x,
     239                uFloat64xComplex,
     240                uuFloat80,
     241                uFloat128,
     242                uFloat128Complex,
     243                uuFloat128,
     244                LongDouble,
     245                LongDoubleComplex,
     246                uFloat128x,
     247                uFloat128xComplex,
    235248                NUMBER_OF_BASIC_TYPES
    236249        } kind;
     250        // GENERATED END
    237251
    238252        static const char *typeNames[];                                         // string names for basic types, MUST MATCH with Kind
  • src/SynTree/TypeSubstitution.cc

    r6a9d4b4 r933f32f  
    6464}
    6565
     66void TypeSubstitution::addVar( std::string formalExpr, Expression *actualExpr ) {
     67        varEnv[ formalExpr ] = actualExpr;
     68}
     69
    6670void TypeSubstitution::remove( std::string formalType ) {
    6771        TypeEnvType::iterator i = typeEnv.find( formalType );
     
    108112namespace {
    109113        struct EnvTrimmer {
    110                 TypeSubstitution * env, * newEnv;
    111                 EnvTrimmer( TypeSubstitution * env, TypeSubstitution * newEnv ) : env( env ), newEnv( newEnv ){}
     114                const TypeSubstitution * env;
     115                TypeSubstitution * newEnv;
     116                EnvTrimmer( const TypeSubstitution * env, TypeSubstitution * newEnv ) : env( env ), newEnv( newEnv ){}
    112117                void previsit( TypeDecl * tyDecl ) {
    113118                        // transfer known bindings for seen type variables
     
    120125
    121126/// reduce environment to just the parts that are referenced in a given expression
    122 TypeSubstitution * TypeSubstitution::newFromExpr( Expression * expr, TypeSubstitution * env ) {
     127TypeSubstitution * TypeSubstitution::newFromExpr( Expression * expr, const TypeSubstitution * env ) {
    123128        if ( env ) {
    124129                TypeSubstitution * newEnv = new TypeSubstitution();
  • src/SynTree/TypeSubstitution.h

    r6a9d4b4 r933f32f  
    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 );
     
    4848        bool empty() const;
    4949
     50        void addVar( std::string formalExpr, Expression *actualExpr );
     51
    5052        template< typename FormalIterator, typename ActualIterator >
    5153        void add( FormalIterator formalBegin, FormalIterator formalEnd, ActualIterator actualBegin );
     
    5658
    5759        /// create a new TypeSubstitution using bindings from env containing all of the type variables in expr
    58         static TypeSubstitution * newFromExpr( Expression * expr, TypeSubstitution * env );
     60        static TypeSubstitution * newFromExpr( Expression * expr, const TypeSubstitution * env );
    5961
    6062        void normalize();
     
    7880        friend class PassVisitor;
    7981
    80         typedef std::map< std::string, Type* > TypeEnvType;
    81         typedef std::map< std::string, Expression* > VarEnvType;
     82        typedef std::unordered_map< std::string, Type * > TypeEnvType;
     83        typedef std::unordered_map< std::string, Expression * > VarEnvType;
    8284        TypeEnvType typeEnv;
    8385        VarEnvType varEnv;
     
    8991        auto begin() const -> decltype( typeEnv.begin() ) { return typeEnv.begin(); }
    9092        auto   end() const -> decltype( typeEnv.  end() ) { return typeEnv.  end(); }
     93
     94        auto beginVar()       -> decltype( varEnv.begin() ) { return varEnv.begin(); }
     95        auto   endVar()       -> decltype( varEnv.  end() ) { return varEnv.  end(); }
     96        auto beginVar() const -> decltype( varEnv.begin() ) { return varEnv.begin(); }
     97        auto   endVar() const -> decltype( varEnv.  end() ) { return varEnv.  end(); }
    9198};
    9299
     
    98105        ActualIterator actualIt = actualBegin;
    99106        for ( ; formalIt != formalEnd; ++formalIt, ++actualIt ) {
    100                 if ( TypeDecl *formal = dynamic_cast< TypeDecl* >( *formalIt ) ) {
    101                         if ( TypeExpr *actual = dynamic_cast< TypeExpr* >( *actualIt ) ) {
     107                if ( TypeDecl *formal = dynamic_cast< TypeDecl * >( *formalIt ) ) {
     108                        if ( TypeExpr *actual = dynamic_cast< TypeExpr * >( *actualIt ) ) {
    102109                                if ( formal->get_name() != "" ) {
    103110                                        TypeEnvType::iterator i = typeEnv.find( formal->get_name() );
     
    130137// definitition must happen after PassVisitor is included so that WithGuards can be used
    131138struct TypeSubstitution::Substituter : public WithGuards, public WithVisitorRef<Substituter> {
    132                 Substituter( TypeSubstitution & sub, bool freeOnly ) : sub( sub ), freeOnly( freeOnly ) {}
     139                Substituter( const TypeSubstitution & sub, bool freeOnly ) : sub( sub ), freeOnly( freeOnly ) {}
    133140
    134141                Type * postmutate( TypeInstType * aggregateUseType );
     
    143150                void premutate( UnionInstType * aggregateUseType );
    144151
    145                 TypeSubstitution & sub;
     152                const TypeSubstitution & sub;
    146153                int subCount = 0;
    147154                bool freeOnly;
    148                 typedef std::set< std::string > BoundVarsType;
     155                typedef std::unordered_set< std::string > BoundVarsType;
    149156                BoundVarsType boundVars;
    150157};
    151158
    152159template< typename SynTreeClass >
    153 int TypeSubstitution::apply( SynTreeClass *&input ) {
     160int TypeSubstitution::apply( SynTreeClass *&input ) const {
    154161        assert( input );
    155162        PassVisitor<Substituter> sub( *this, false );
     
    163170
    164171template< typename SynTreeClass >
    165 int TypeSubstitution::applyFree( SynTreeClass *&input ) {
     172int TypeSubstitution::applyFree( SynTreeClass *&input ) const {
    166173        assert( input );
    167174        PassVisitor<Substituter> sub( *this, true );
  • src/SynTree/Visitor.h

    r6a9d4b4 r933f32f  
    123123        virtual void visit( ConstructorInit * ctorInit ) = 0;
    124124
    125         virtual void visit( Subrange * subrange ) = 0;
    126 
    127125        virtual void visit( Constant * constant ) = 0;
    128126
  • src/SynTree/module.mk

    r6a9d4b4 r933f32f  
    1515###############################################################################
    1616
    17 SRC += SynTree/Type.cc \
    18        SynTree/VoidType.cc \
    19        SynTree/BasicType.cc \
    20        SynTree/PointerType.cc \
    21        SynTree/ArrayType.cc \
    22        SynTree/ReferenceType.cc \
    23        SynTree/FunctionType.cc \
    24        SynTree/ReferenceToType.cc \
    25        SynTree/TupleType.cc \
    26        SynTree/TypeofType.cc \
    27        SynTree/AttrType.cc \
    28        SynTree/VarArgsType.cc \
    29        SynTree/ZeroOneType.cc \
    30        SynTree/Constant.cc \
    31        SynTree/Expression.cc \
    32        SynTree/TupleExpr.cc \
    33        SynTree/CommaExpr.cc \
    34        SynTree/TypeExpr.cc \
    35        SynTree/ApplicationExpr.cc \
    36        SynTree/AddressExpr.cc \
    37        SynTree/Statement.cc \
    38        SynTree/CompoundStmt.cc \
    39        SynTree/DeclStmt.cc \
    40        SynTree/Declaration.cc \
    41        SynTree/DeclarationWithType.cc \
    42        SynTree/ObjectDecl.cc \
    43        SynTree/FunctionDecl.cc \
    44        SynTree/AggregateDecl.cc \
    45        SynTree/NamedTypeDecl.cc \
    46        SynTree/TypeDecl.cc \
    47        SynTree/Initializer.cc \
    48        SynTree/TypeSubstitution.cc \
    49        SynTree/Attribute.cc \
    50        SynTree/DeclReplacer.cc
     17SRC_SYNTREE = \
     18      SynTree/Type.cc \
     19      SynTree/VoidType.cc \
     20      SynTree/BasicType.cc \
     21      SynTree/PointerType.cc \
     22      SynTree/ArrayType.cc \
     23      SynTree/ReferenceType.cc \
     24      SynTree/FunctionType.cc \
     25      SynTree/ReferenceToType.cc \
     26      SynTree/TupleType.cc \
     27      SynTree/TypeofType.cc \
     28      SynTree/AttrType.cc \
     29      SynTree/VarArgsType.cc \
     30      SynTree/ZeroOneType.cc \
     31      SynTree/Constant.cc \
     32      SynTree/Expression.cc \
     33      SynTree/TupleExpr.cc \
     34      SynTree/CommaExpr.cc \
     35      SynTree/TypeExpr.cc \
     36      SynTree/ApplicationExpr.cc \
     37      SynTree/AddressExpr.cc \
     38      SynTree/Statement.cc \
     39      SynTree/CompoundStmt.cc \
     40      SynTree/DeclStmt.cc \
     41      SynTree/Declaration.cc \
     42      SynTree/DeclarationWithType.cc \
     43      SynTree/ObjectDecl.cc \
     44      SynTree/FunctionDecl.cc \
     45      SynTree/AggregateDecl.cc \
     46      SynTree/NamedTypeDecl.cc \
     47      SynTree/TypeDecl.cc \
     48      SynTree/Initializer.cc \
     49      SynTree/TypeSubstitution.cc \
     50      SynTree/Attribute.cc \
     51      SynTree/DeclReplacer.cc
    5152
     53SRC += $(SRC_SYNTREE)
     54SRCDEMANGLE += $(SRC_SYNTREE)
  • src/Tuples/TupleExpansion.cc

    r6a9d4b4 r933f32f  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Jun 21 17:35:04 2017
    13 // Update Count     : 19
     12// Last Modified On : Wed Feb 13 18:14:12 2019
     13// Update Count     : 21
    1414//
    1515
     
    1717#include <cassert>                // for assert
    1818#include <list>                   // for list
    19 
     19#include <vector>
     20
     21#include "AST/CVQualifiers.hpp"
     22#include "AST/Expr.hpp"
     23#include "AST/Node.hpp"
     24#include "AST/Type.hpp"
    2025#include "Common/PassVisitor.h"   // for PassVisitor, WithDeclsToAdd, WithGu...
    2126#include "Common/ScopedMap.h"     // for ScopedMap
     
    5863                };
    5964
    60                 struct TupleTypeReplacer : public WithDeclsToAdd, public WithGuards, public WithTypeSubstitution {
     65                struct TupleTypeReplacer : public WithDeclsToAdd, public WithGuards, public WithConstTypeSubstitution {
    6166                        Type * postmutate( TupleType * tupleType );
    6267
     
    314319                return new TupleType( qualifiers, types );
    315320        }
     321        const ast::Type * makeTupleType( const std::vector<ast::ptr<ast::Expr>> & exprs ) {
     322                (void) exprs;
     323                #warning Not implemented; needs Type.cpp in build
     324                assertf(false, "Not implemented; needs Type.cpp in build");
     325                // // produce the TupleType which aggregates the types of the exprs
     326                // std::vector<ast::ptr<ast::Type>> types;
     327                // ast::CV::Qualifiers quals{
     328                //      ast::CV::Const | ast::CV::Volatile | ast::CV::Restrict | ast::CV::Lvalue |
     329                //      ast::CV::Atomic | ast::CV::Mutex };
     330
     331                // for ( const ast::Expr * expr : exprs ) {
     332                //      assert( expr->result );
     333                //      // if the type of any expr is void, the type of the entire tuple is void
     334                //      if ( expr->result->isVoid() ) return new ast::VoidType{};
     335
     336                //      // qualifiers on the tuple type are the qualifiers that exist on all components
     337                //      quals &= expr->result->qualifiers;
     338
     339                //      types.emplace_back( expr->result );
     340                // }
     341
     342                // if ( exprs.empty() ) { quals = ast::CV::Qualifiers{}; }
     343                // return new ast::TupleType{ std::move(types), quals };
     344        }
    316345
    317346        TypeInstType * isTtype( Type * type ) {
  • src/Tuples/Tuples.h

    r6a9d4b4 r933f32f  
    1919#include <vector>
    2020
     21#include "AST/Fwd.hpp"
     22#include "AST/Node.hpp"
    2123#include "SynTree/Expression.h"
    2224#include "SynTree/Declaration.h"
     
    2729namespace Tuples {
    2830        // TupleAssignment.cc
    29         void handleTupleAssignment( ResolvExpr::AlternativeFinder & currentFinder, UntypedExpr * assign, 
     31        void handleTupleAssignment( ResolvExpr::AlternativeFinder & currentFinder, UntypedExpr * assign,
    3032                std::vector< ResolvExpr::AlternativeFinder >& args );
    31        
     33
    3234        // TupleExpansion.cc
    3335        /// expands z.[a, b.[x, y], c] into [z.a, z.b.x, z.b.y, z.c], inserting UniqueExprs as appropriate
     
    4244        /// returns VoidType if any of the expressions have Voidtype, otherwise TupleType of the Expression result types
    4345        Type * makeTupleType( const std::list< Expression * > & exprs );
     46        const ast::Type * makeTupleType( const std::vector<ast::ptr<ast::Expr>> & exprs );
    4447
    4548        /// returns a TypeInstType if `type` is a ttype, nullptr otherwise
    4649        TypeInstType * isTtype( Type * type );
     50        const ast::TypeInstType * isTtype( const ast::Type * type );
    4751
    4852        /// returns true if the expression may contain side-effects.
  • src/Tuples/module.mk

    r6a9d4b4 r933f32f  
    1515###############################################################################
    1616
    17 SRC +=  Tuples/TupleAssignment.cc \
    18         Tuples/TupleExpansion.cc \
    19         Tuples/Explode.cc
     17SRC += Tuples/TupleAssignment.cc Tuples/TupleExpansion.cc Tuples/Explode.cc
     18SRCDEMANGLE += Tuples/TupleAssignment.cc Tuples/TupleExpansion.cc Tuples/Explode.cc
  • src/Validate/module.mk

    r6a9d4b4 r933f32f  
    1515###############################################################################
    1616
    17 SRC += Validate/HandleAttributes.cc \
    18         Validate/FindSpecialDecls.cc
     17SRC += Validate/HandleAttributes.cc Validate/FindSpecialDecls.cc
     18SRCDEMANGLE += Validate/HandleAttributes.cc Validate/FindSpecialDecls.cc
  • src/config.h.in

    r6a9d4b4 r933f32f  
    5252#undef CFA_VERSION_SHORT
    5353
    54 /* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
    55    systems. This function is required for `alloca.c' support on those systems.
    56    */
    57 #undef CRAY_STACKSEG_END
    58 
    59 /* Define to 1 if using `alloca.c'. */
    60 #undef C_ALLOCA
    61 
    62 /* Define to 1 if you have `alloca', as a function or macro. */
    63 #undef HAVE_ALLOCA
    64 
    65 /* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
    66    */
    67 #undef HAVE_ALLOCA_H
     54/* Have compiler warning cast-function-type. */
     55#undef HAVE_CAST_FUNCTION_TYPE
    6856
    6957/* Define to 1 if you have the <dlfcn.h> header file. */
    7058#undef HAVE_DLFCN_H
    7159
    72 /* Define to 1 if you have the <fenv.h> header file. */
    73 #undef HAVE_FENV_H
    74 
    75 /* Define to 1 if you have the <float.h> header file. */
    76 #undef HAVE_FLOAT_H
    77 
    7860/* Define to 1 if you have the <inttypes.h> header file. */
    7961#undef HAVE_INTTYPES_H
    8062
     63/* Have keywords _FloatXX. */
     64#undef HAVE_KEYWORDS_FLOATXX
     65
    8166/* Define to 1 if you have the <libintl.h> header file. */
    8267#undef HAVE_LIBINTL_H
    83 
    84 /* Define to 1 if you have the <limits.h> header file. */
    85 #undef HAVE_LIMITS_H
    8668
    8769/* Define to 1 if you have the <malloc.h> header file. */
     
    9173#undef HAVE_MEMORY_H
    9274
    93 /* Define to 1 if you have the `memset' function. */
    94 #undef HAVE_MEMSET
    95 
    96 /* Define to 1 if you have the `putenv' function. */
    97 #undef HAVE_PUTENV
    98 
    99 /* Define to 1 if stdbool.h conforms to C99. */
    100 #undef HAVE_STDBOOL_H
    101 
    102 /* Define to 1 if you have the <stddef.h> header file. */
    103 #undef HAVE_STDDEF_H
    104 
    10575/* Define to 1 if you have the <stdint.h> header file. */
    10676#undef HAVE_STDINT_H
     
    10979#undef HAVE_STDLIB_H
    11080
    111 /* Define to 1 if you have the `strchr' function. */
    112 #undef HAVE_STRCHR
    113 
    11481/* Define to 1 if you have the <strings.h> header file. */
    11582#undef HAVE_STRINGS_H
     
    11784/* Define to 1 if you have the <string.h> header file. */
    11885#undef HAVE_STRING_H
    119 
    120 /* Define to 1 if you have the `strtol' function. */
    121 #undef HAVE_STRTOL
    12286
    12387/* Define to 1 if you have the <sys/stat.h> header file. */
     
    13094#undef HAVE_UNISTD_H
    13195
    132 /* Define to 1 if the system has the type `_Bool'. */
    133 #undef HAVE__BOOL
     96/* Define to 1 if the system has the type `_Float32'. */
     97#undef HAVE__FLOAT32
    13498
    13599/* Define to the sub-directory where libtool stores uninstalled libraries. */
     
    157121#undef PACKAGE_VERSION
    158122
    159 /* If using the C implementation of alloca, define if you know the
    160    direction of stack growth for your system; otherwise it will be
    161    automatically deduced at runtime.
    162         STACK_DIRECTION > 0 => grows toward higher addresses
    163         STACK_DIRECTION < 0 => grows toward lower addresses
    164         STACK_DIRECTION = 0 => direction of growth unknown */
    165 #undef STACK_DIRECTION
    166 
    167123/* Define to 1 if you have the ANSI C header files. */
    168124#undef STDC_HEADERS
     
    180136   `char[]'. */
    181137#undef YYTEXT_POINTER
    182 
    183 /* Define for Solaris 2.5.1 so the uint32_t typedef from <sys/synch.h>,
    184    <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
    185    #define below would cause a syntax error. */
    186 #undef _UINT32_T
    187 
    188 /* Define for Solaris 2.5.1 so the uint8_t typedef from <sys/synch.h>,
    189    <pthread.h>, or <semaphore.h> is not used. If the typedef were allowed, the
    190    #define below would cause a syntax error. */
    191 #undef _UINT8_T
    192 
    193 /* Define to `__inline__' or `__inline' if that's what the C compiler
    194    calls it, or to nothing if 'inline' is not supported under any name.  */
    195 #ifndef __cplusplus
    196 #undef inline
    197 #endif
    198 
    199 /* Define to the type of a signed integer type of width exactly 16 bits if
    200    such a type exists and the standard includes do not define it. */
    201 #undef int16_t
    202 
    203 /* Define to the type of a signed integer type of width exactly 32 bits if
    204    such a type exists and the standard includes do not define it. */
    205 #undef int32_t
    206 
    207 /* Define to the type of a signed integer type of width exactly 8 bits if such
    208    a type exists and the standard includes do not define it. */
    209 #undef int8_t
    210 
    211 /* Define to the equivalent of the C99 'restrict' keyword, or to
    212    nothing if this is not supported.  Do not define if restrict is
    213    supported directly.  */
    214 #undef restrict
    215 /* Work around a bug in Sun C++: it does not support _Restrict or
    216    __restrict__, even though the corresponding Sun C compiler ends up with
    217    "#define restrict _Restrict" or "#define restrict __restrict__" in the
    218    previous line.  Perhaps some future version of Sun C++ will work with
    219    restrict; if so, hopefully it defines __RESTRICT like Sun C does.  */
    220 #if defined __SUNPRO_CC && !defined __RESTRICT
    221 # define _Restrict
    222 # define __restrict__
    223 #endif
    224 
    225 /* Define to `unsigned int' if <sys/types.h> does not define. */
    226 #undef size_t
    227 
    228 /* Define to the type of an unsigned integer type of width exactly 16 bits if
    229    such a type exists and the standard includes do not define it. */
    230 #undef uint16_t
    231 
    232 /* Define to the type of an unsigned integer type of width exactly 32 bits if
    233    such a type exists and the standard includes do not define it. */
    234 #undef uint32_t
    235 
    236 /* Define to the type of an unsigned integer type of width exactly 8 bits if
    237    such a type exists and the standard includes do not define it. */
    238 #undef uint8_t
  • src/include/cassert

    r6a9d4b4 r933f32f  
    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

    r6a9d4b4 r933f32f  
    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 : Wed Dec 26 08:11:19 2018
    13 // Update Count     : 499
     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
     
    3738#include "CodeTools/TrackLoc.h"             // for fillLocations
    3839#include "Common/CompilerError.h"           // for CompilerError
    39 #include "Common/Heap.h"
     40#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 #define PASS(name, pass)                   \
     69static void NewPass( const char * const name ) {
     70        Stats::Heap::newPass( name );
     71        using namespace Stats::Counters;
     72        {
     73                static auto group = build<CounterGroup>( "Pass Visitor" );
     74                auto pass = build<CounterGroup>( name, group );
     75                pass_visitor_stats.depth = 0;
     76                pass_visitor_stats.avg = build<AverageCounter<double>>( "Average Depth", pass );
     77                pass_visitor_stats.max = build<MaxCounter<double>>( "Max Depth", pass );
     78        }
     79        {
     80                static auto group = build<CounterGroup>( "Syntax Node" );
     81                auto pass = build<CounterGroup>( name, group );
     82                BaseSyntaxNode::new_nodes = build<SimpleCounter>( "Allocs", pass );
     83        }
     84}
     85
     86#define PASS( name, pass )                  \
    6887        if ( errorp ) { cerr << name << endl; } \
    69         HeapStats::newPass(name);               \
    70         pass;
     88        NewPass(name);                          \
     89        Stats::Time::StartBlock(name);          \
     90        pass;                                   \
     91        Stats::Time::StopBlock();
    7192
    7293LinkageSpec::Spec linkage = LinkageSpec::Cforall;
     
    7495DeclarationNode * parseTree = nullptr;                                  // program parse tree
    7596
    76 std::string PreludeDirector = "";
     97static std::string PreludeDirector = "";
    7798
    7899static void parse_cmdline( int argc, char *argv[], const char *& filename );
     
    130151} // backtrace
    131152
    132 void sigSegvBusHandler( int sig_num ) {
     153static void sigSegvBusHandler( int sig_num ) {
    133154        cerr << "*CFA runtime error* program cfa-cpp terminated with "
    134155                 <<     (sig_num == SIGSEGV ? "segment fault" : "bus error")
     
    136157        backtrace( 2 );                                                                         // skip first 2 stack frames
    137158        //_exit( EXIT_FAILURE );
    138         abort();
     159        abort();                                                                                        // cause core dump for debugging
    139160} // sigSegvBusHandler
    140161
    141 void sigAbortHandler( __attribute__((unused)) int sig_num ) {
     162static void sigAbortHandler( __attribute__((unused)) int sig_num ) {
    142163        backtrace( 6 );                                                                         // skip first 6 stack frames
    143164        signal( SIGABRT, SIG_DFL);                                                      // reset default signal handler
    144     raise( SIGABRT );                                                                   // reraise SIGABRT
     165                raise( SIGABRT );                                                                       // reraise SIGABRT
    145166} // sigAbortHandler
    146167
     
    148169int main( int argc, char * argv[] ) {
    149170        FILE * input;                                                                           // use FILE rather than istream because yyin is FILE
    150         ostream *output = & cout;
    151         const char *filename = nullptr;
     171        ostream * output = & cout;
     172        const char * filename = nullptr;
    152173        list< Declaration * > translationUnit;
    153174
     
    181202                } // if
    182203
     204                Stats::Time::StartGlobal();
     205                NewPass("Parse");
     206                Stats::Time::StartBlock("Parse");
     207
    183208                // read in the builtins, extras, and the prelude
    184209                if ( ! nopreludep ) {                                                   // include gcc builtins
     
    215240                        parseTree->printList( cout );
    216241                        delete parseTree;
    217                         return 0;
     242                        return EXIT_SUCCESS;
    218243                } // if
    219244
     
    224249                if ( astp ) {
    225250                        dump( translationUnit );
    226                         return 0;
     251                        return EXIT_SUCCESS;
    227252                } // if
    228253
     
    231256                // works okay for now.
    232257                CodeTools::fillLocations( translationUnit );
     258                Stats::Time::StopBlock();
    233259
    234260                // add the assignment statement after the initialization of a type parameter
    235                 PASS( "validate", SymTab::validate( translationUnit, symtabp ) );
     261                PASS( "Validate", SymTab::validate( translationUnit, symtabp ) );
    236262                if ( symtabp ) {
    237263                        deleteAll( translationUnit );
    238                         return 0;
     264                        return EXIT_SUCCESS;
    239265                } // if
    240266
     
    242268                        PassVisitor<ResolvExpr::AlternativePrinter> printer( cout );
    243269                        acceptAll( translationUnit, printer );
    244                         return 0;
     270                        return EXIT_SUCCESS;
    245271                } // if
    246272
    247273                if ( validp ) {
    248274                        dump( translationUnit );
    249                         return 0;
    250                 } // if
    251 
    252                 PASS( "fixLabels", ControlStruct::fixLabels( translationUnit ) );
    253                 PASS( "fixNames", CodeGen::fixNames( translationUnit ) );
    254                 PASS( "genInit", InitTweak::genInit( translationUnit ) );
    255                 PASS( "expandMemberTuples" , Tuples::expandMemberTuples( translationUnit ) );
     275                        return EXIT_SUCCESS;
     276                } // if
     277
     278                PASS( "Fix Labels", ControlStruct::fixLabels( translationUnit ) );
     279                PASS( "Fix Names", CodeGen::fixNames( translationUnit ) );
     280                PASS( "Gen Init", InitTweak::genInit( translationUnit ) );
     281                PASS( "Expand Member Tuples" , Tuples::expandMemberTuples( translationUnit ) );
    256282                if ( libcfap ) {
    257283                        // generate the bodies of cfa library functions
     
    262288                        CodeTools::printDeclStats( translationUnit );
    263289                        deleteAll( translationUnit );
    264                         return 0;
    265                 }
     290                        return EXIT_SUCCESS;
     291                } // if
    266292
    267293                if ( bresolvep ) {
    268294                        dump( translationUnit );
    269                         return 0;
     295                        return EXIT_SUCCESS;
    270296                } // if
    271297
     
    274300                if ( resolvprotop ) {
    275301                        CodeTools::dumpAsResolvProto( translationUnit );
    276                         return 0;
    277                 }
    278 
    279                 PASS( "resolve", ResolvExpr::resolve( translationUnit ) );
     302                        return EXIT_SUCCESS;
     303                } // if
     304
     305                PASS( "Resolve", ResolvExpr::resolve( translationUnit ) );
    280306                if ( exprp ) {
    281307                        dump( translationUnit );
    282                         return 0;
     308                        return EXIT_SUCCESS;
    283309                } // if
    284310
    285311                // fix ObjectDecl - replaces ConstructorInit nodes
    286                 PASS( "fixInit", InitTweak::fix( translationUnit, buildingLibrary() ) );
     312                PASS( "Fix Init", InitTweak::fix( translationUnit, buildingLibrary() ) );
    287313                if ( ctorinitp ) {
    288314                        dump ( translationUnit );
    289                         return 0;
    290                 } // if
    291 
    292                 PASS( "expandUniqueExpr", Tuples::expandUniqueExpr( translationUnit ) ); // xxx - is this the right place for this? want to expand ASAP so tha, sequent passes don't need to worry about double-visiting a unique expr - needs to go after InitTweak::fix so that copy constructed return declarations are reused
    293 
    294                 PASS( "translateEHM" , ControlStruct::translateEHM( translationUnit ) );
    295 
    296                 PASS( "generateWaitfor" , Concurrency::generateWaitFor( translationUnit ) );
    297 
    298                 PASS( "convertSpecializations",  GenPoly::convertSpecializations( translationUnit ) ); // needs to happen before tuple types are expanded
    299 
    300                 PASS( "expandTuples", Tuples::expandTuples( translationUnit ) ); // xxx - is this the right place for this?
     315                        return EXIT_SUCCESS;
     316                } // if
     317
     318                PASS( "Expand Unique Expr", Tuples::expandUniqueExpr( translationUnit ) ); // xxx - is this the right place for this? want to expand ASAP so tha, sequent passes don't need to worry about double-visiting a unique expr - needs to go after InitTweak::fix so that copy constructed return declarations are reused
     319
     320                PASS( "Translate EHM" , ControlStruct::translateEHM( translationUnit ) );
     321
     322                PASS( "Gen Waitfor" , Concurrency::generateWaitFor( translationUnit ) );
     323
     324                PASS( "Convert Specializations",  GenPoly::convertSpecializations( translationUnit ) ); // needs to happen before tuple types are expanded
     325
     326                PASS( "Expand Tuples", Tuples::expandTuples( translationUnit ) ); // xxx - is this the right place for this?
    301327
    302328                if ( tuplep ) {
    303329                        dump( translationUnit );
    304                         return 0;
    305                 }
    306 
    307                 PASS( "virtual expandCasts", Virtual::expandCasts( translationUnit ) ); // Must come after translateEHM
    308 
    309                 PASS( "instantiateGenerics", GenPoly::instantiateGeneric( translationUnit ) );
     330                        return EXIT_SUCCESS;
     331                } // if
     332
     333                PASS( "Virtual Expand Casts", Virtual::expandCasts( translationUnit ) ); // Must come after translateEHM
     334
     335                PASS( "Instantiate Generics", GenPoly::instantiateGeneric( translationUnit ) );
    310336                if ( genericsp ) {
    311337                        dump( translationUnit );
    312                         return 0;
    313                 }
    314                 PASS( "convertLvalue", GenPoly::convertLvalue( translationUnit ) );
     338                        return EXIT_SUCCESS;
     339                } // if
     340                PASS( "Convert L-Value", GenPoly::convertLvalue( translationUnit ) );
    315341
    316342
    317343                if ( bboxp ) {
    318344                        dump( translationUnit );
    319                         return 0;
    320                 } // if
    321                 PASS( "box", GenPoly::box( translationUnit ) );
     345                        return EXIT_SUCCESS;
     346                } // if
     347                PASS( "Box", GenPoly::box( translationUnit ) );
    322348
    323349                if ( bcodegenp ) {
    324350                        dump( translationUnit );
    325                         return 0;
    326                 }
     351                        return EXIT_SUCCESS;
     352                } // if
    327353
    328354                if ( optind < argc ) {                                                  // any commands after the flags and input file ? => output file name
     
    331357
    332358                CodeTools::fillLocations( translationUnit );
    333                 PASS( "codegen", CodeGen::generate( translationUnit, *output, ! noprotop, prettycodegenp, true, linemarks ) );
     359                PASS( "Code Gen", CodeGen::generate( translationUnit, *output, ! genproto, prettycodegenp, true, linemarks ) );
    334360
    335361                CodeGen::FixMain::fix( *output, (PreludeDirector + "/bootloader.c").c_str() );
     
    347373                        delete output;
    348374                } // if
    349                 return 1;
     375                return EXIT_FAILURE;
    350376        } catch ( UnimplementedError &e ) {
    351377                cout << "Sorry, " << e.get_what() << " is not currently implemented" << endl;
     
    353379                        delete output;
    354380                } // if
    355                 return 1;
     381                return EXIT_FAILURE;
    356382        } catch ( CompilerError &e ) {
    357383                cerr << "Compiler Error: " << e.get_what() << endl;
     
    360386                        delete output;
    361387                } // if
    362                 return 1;
    363         } catch(...) {
     388                return EXIT_FAILURE;
     389        } catch ( ... ) {
    364390                std::exception_ptr eptr = std::current_exception();
    365391                try {
    366392                        if (eptr) {
    367393                                std::rethrow_exception(eptr);
    368                         }
    369                         else {
    370                                 std::cerr << "Exception Uncaught and Unkown" << std::endl;
    371                         }
     394                        } else {
     395                                std::cerr << "Exception Uncaught and Unknown" << std::endl;
     396                        } // if
    372397                } catch(const std::exception& e) {
    373398                        std::cerr << "Uncaught Exception \"" << e.what() << "\"\n";
    374                 }
    375                 return 1;
    376         }// try
     399                } // try
     400                return EXIT_FAILURE;
     401        } // try
    377402
    378403        deleteAll( translationUnit );
    379         if(!libcfap && !treep) HeapStats::printStats();
    380         return 0;
     404        Stats::print();
     405        return EXIT_SUCCESS;
    381406} // main
    382407
    383 void parse_cmdline( int argc, char * argv[], const char *& filename ) {
    384         enum { Ast, Bbox, Bresolver, CtorInitFix, DeclStats, Expr, ExprAlt, Grammar, LibCFA, Linemarks, Nolinemarks, Nopreamble, Parse, PreludeDir, Prototypes, Resolver, ResolvProto, Symbol, Tree, TupleExpansion, Validate, };
    385 
    386         static struct option long_opts[] = {
    387                 { "ast", no_argument, 0, Ast },
    388                 { "before-box", no_argument, 0, Bbox },
    389                 { "before-resolver", no_argument, 0, Bresolver },
    390                 { "ctorinitfix", no_argument, 0, CtorInitFix },
    391                 { "decl-stats", no_argument, 0, DeclStats },
    392                 { "expr", no_argument, 0, Expr },
    393                 { "expralt", no_argument, 0, ExprAlt },
    394                 { "grammar", no_argument, 0, Grammar },
    395                 { "libcfa", no_argument, 0, LibCFA },
    396                 { "line-marks", no_argument, 0, Linemarks },
    397                 { "no-line-marks", no_argument, 0, Nolinemarks },
    398                 { "no-preamble", no_argument, 0, Nopreamble },
    399                 { "parse", no_argument, 0, Parse },
    400                 { "prelude-dir", required_argument, 0, PreludeDir },
    401                 { "no-prototypes", no_argument, 0, Prototypes },
    402                 { "resolver", no_argument, 0, Resolver },
    403                 { "resolv-proto", no_argument, 0, ResolvProto },
    404                 { "symbol", no_argument, 0, Symbol },
    405                 { "tree", no_argument, 0, Tree },
    406                 { "tuple-expansion", no_argument, 0, TupleExpansion },
    407                 { "validate", no_argument, 0, Validate },
    408                 { 0, 0, 0, 0 }
    409         }; // long_opts
    410         int long_index;
    411 
     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 ) {
    412507        opterr = 0;                                                                                     // (global) prevent getopt from printing error messages
    413508
    414509        bool Wsuppress = false, Werror = false;
    415510        int c;
    416         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 ) {
    417512                switch ( c ) {
    418                   case Ast:
    419                   case 'a':                                                                             // dump AST
    420                         astp = true;
    421                         break;
    422                   case Bresolver:
    423                   case 'b':                                                                             // print before resolver steps
    424                         bresolvep = true;
    425                         break;
    426                   case 'B':                                                                             // print before box steps
    427                         bboxp = true;
    428                         break;
    429                   case CtorInitFix:
    430                   case 'c':                                                                             // print after constructors and destructors are replaced
    431                         ctorinitp = true;
    432                         break;
    433                   case 'C':                                                                             // print before code generation
    434                         bcodegenp = true;
    435                         break;
    436                   case DeclStats:
    437                   case 'd':
    438                     declstatsp = true;
    439                         break;
    440                   case Expr:
    441                   case 'e':                                                                             // dump AST after expression analysis
    442                         exprp = true;
    443                         break;
    444                   case ExprAlt:
    445                   case 'f':                                                                             // print alternatives for expressions
    446                         expraltp = true;
    447                         break;
    448                   case Grammar:
    449                   case 'g':                                                                             // bison debugging info (grammar rules)
    450                         yydebug = true;
    451                         break;
    452                   case 'G':                                                                             // dump AST after instantiate generics
    453                         genericsp = true;
    454                         break;
    455                   case LibCFA:
     513                  case 'h':                                                                             // help message
     514                        usage( argv );                                                          // no return
     515                        break;
    456516                  case 'l':                                                                             // generate libcfa.c
    457517                        libcfap = true;
    458518                        break;
    459                   case Linemarks:
    460                   case 'L':                                                                             // print lines marks
     519                  case 'L':                                                                             // generate line marks
    461520                        linemarks = true;
    462521                        break;
    463                   case Nopreamble:
    464                   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
    465529                        nopreludep = true;
    466530                        break;
    467                   case Nolinemarks:
    468                   case 'N':                                                                             // suppress line marks
    469                         linemarks = false;
    470                         break;
    471                   case Prototypes:
    472                   case 'p':                                                                             // generate prototypes for preamble functions
    473                         noprotop = true;
    474                         break;
    475                   case PreludeDir:
    476                         PreludeDirector = optarg;
    477                         break;
    478                   case 'm':                                                                             // don't replace the main
    479                         nomainp = true;
    480                         break;
    481                   case Parse:
    482                   case 'q':                                                                             // dump parse tree
    483                         parsep = true;
    484                         break;
    485                   case Resolver:
    486                   case 'r':                                                                             // print resolver steps
    487                         resolvep = true;
    488                         break;
    489                   case 'R':                                                                             // dump resolv-proto instance
    490                         resolvprotop = true;
    491                         break;
    492                   case Symbol:
    493                   case 's':                                                                             // print symbol table events
    494                         symtabp = true;
    495                         break;
    496                   case 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;
    497552                  case 't':                                                                             // build in tree
    498553                        treep = true;
    499554                        break;
    500                   case TupleExpansion:
    501                   case 'T':                                                                             // print after tuple expansion
    502                         tuplep = true;
    503                         break;
    504                   case 'v':                                                                             // dump AST after decl validation pass
    505                         validp = true;
    506                         break;
    507                   case 'w':
     555                  case 'w':                                                                             // suppress all warnings, hidden
    508556                        Wsuppress = true;
    509557                        break;
    510                   case 'W':
     558                  case 'W':                                                                             // coordinate gcc -W with CFA, hidden
    511559                        if ( strcmp( optarg, "all" ) == 0 ) {
    512560                                SemanticWarning_EnableAll();
     
    525573                        } // if
    526574                        break;
    527                   case 'y':                                                                             // dump AST on error
    528                         errorp = true;
    529                         break;
    530                   case 'z':                                                                             // dump as codegen rather than AST
    531                         codegenp = true;
    532                         break;
    533                         case 'Z':                                                                       // prettyprint during codegen (i.e. print unmangled names, etc.)
    534                         prettycodegenp = true;
    535                         break;
    536                   case 'D':                                                                             // ignore -Dxxx
    537                         break;
    538                   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
    539578                        filename = optarg;
    540579                        break;
    541                   case '?':
     580                  case '?':                                                                             // unknown option
    542581                        if ( optopt ) {                                                         // short option ?
    543                                 assertf( false, "Unknown option: -%c\n", (char)optopt );
     582                                cout << "Unknown option -" << (char)optopt << endl;
    544583                        } else {
    545                                 assertf( false, "Unknown option: %s\n", argv[optind - 1] );
    546                         } // if
    547                         #if defined(__GNUC__) && __GNUC__ >= 7
    548                                 __attribute__((fallthrough));
    549                         #endif
     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:
    550595                  default:
    551                         abort();
     596                        usage( argv );                                                          // no return
    552597                } // switch
    553598        } // while
     
    587632        list< Declaration * > decls;
    588633
    589         if ( noprotop ) {
     634        if ( genproto ) {
    590635                filter( translationUnit.begin(), translationUnit.end(), back_inserter( decls ), notPrelude );
    591636        } else {
     
    595640        // depending on commandline options, either generate code or dump the AST
    596641        if ( codegenp ) {
    597                 CodeGen::generate( decls, out, ! noprotop, prettycodegenp );
     642                CodeGen::generate( decls, out, ! genproto, prettycodegenp );
    598643        } else {
    599644                printAll( decls, out );
    600         }
     645        } // if
    601646        deleteAll( translationUnit );
    602647} // dump
Note: See TracChangeset for help on using the changeset viewer.