Changeset b067d9b for src


Ignore:
Timestamp:
Oct 29, 2019, 4:01:24 PM (6 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
773db65, 9421f3d8
Parents:
7951100 (diff), 8364209 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

Location:
src
Files:
91 added
102 deleted
147 edited
1 moved

Legend:

Unmodified
Added
Removed
  • src/CodeGen/CodeGenerator.cc

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

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

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

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

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

    r7951100 rb067d9b  
    1616
    1717SRC += CodeTools/DeclStats.cc \
     18        CodeTools/ResolvProtoDump.cc \
    1819        CodeTools/TrackLoc.cc
  • src/Common/Assert.cc

    r7951100 rb067d9b  
    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/Debug.h

    r7951100 rb067d9b  
    2828namespace Debug {
    2929        /// debug codegen a translation unit
    30         static inline void codeGen( __attribute__((unused)) const std::list< Declaration * > & translationUnit, __attribute__((unused)) const std::string & label, __attribute__((unused)) LinkageSpec::Spec linkageFilter = LinkageSpec::Compiler ) {
     30        static inline void codeGen( __attribute__((unused)) const std::list< Declaration * > & translationUnit, __attribute__((unused)) const std::string & label, __attribute__((unused)) LinkageSpec::Spec linkageFilter = LinkageSpec::Builtin ) {
    3131        #ifdef DEBUG
    3232                std::list< Declaration * > decls;
  • src/Common/Indenter.h

    r7951100 rb067d9b  
    1818
    1919struct Indenter {
    20         static unsigned tabsize;
     20        static unsigned tabsize;  ///< default number of spaces in one level of indentation
    2121
    22         Indenter( unsigned int amt = tabsize, unsigned int indent = 0 ) : amt( amt ), indent( indent ) {}
    23         unsigned int amt;  // amount 1 level increases indent by (i.e. how much to increase by in operator++)
    24         unsigned int indent;
     22        unsigned int indent;      ///< number of spaces to indent
     23        unsigned int amt;         ///< spaces in one level of indentation
    2524
    26         Indenter & operator+=(int nlevels) { indent += amt*nlevels; return *this; }
    27         Indenter & operator-=(int nlevels) { indent -= amt*nlevels; return *this; }
     25        Indenter( unsigned int indent = 0, unsigned int amt = tabsize )
     26        : indent( indent ), amt( amt ) {}
     27
     28        Indenter & operator+=(int nlevels) { indent += nlevels; return *this; }
     29        Indenter & operator-=(int nlevels) { indent -= nlevels; return *this; }
    2830        Indenter operator+(int nlevels) { Indenter indenter = *this; return indenter += nlevels; }
    2931        Indenter operator-(int nlevels) { Indenter indenter = *this; return indenter -= nlevels; }
     
    3335
    3436inline std::ostream & operator<<( std::ostream & out, const Indenter & indent ) {
    35         return out << std::string(indent.indent, ' ');
     37        return out << std::string(indent.indent * indent.amt, ' ');
    3638}
    3739
  • src/Common/PassVisitor.h

    r7951100 rb067d9b  
    44
    55#include <stack>
    6 
     6#include <type_traits>
     7
     8#include "Common/Stats.h"
    79#include "Common/utility.h"
    810
     
    5860
    5961        virtual void visit( ObjectDecl * objectDecl ) override final;
     62        virtual void visit( const ObjectDecl * objectDecl ) override final;
    6063        virtual void visit( FunctionDecl * functionDecl ) override final;
     64        virtual void visit( const FunctionDecl * functionDecl ) override final;
    6165        virtual void visit( StructDecl * aggregateDecl ) override final;
     66        virtual void visit( const StructDecl * aggregateDecl ) override final;
    6267        virtual void visit( UnionDecl * aggregateDecl ) override final;
     68        virtual void visit( const UnionDecl * aggregateDecl ) override final;
    6369        virtual void visit( EnumDecl * aggregateDecl ) override final;
     70        virtual void visit( const EnumDecl * aggregateDecl ) override final;
    6471        virtual void visit( TraitDecl * aggregateDecl ) override final;
     72        virtual void visit( const TraitDecl * aggregateDecl ) override final;
    6573        virtual void visit( TypeDecl * typeDecl ) override final;
     74        virtual void visit( const TypeDecl * typeDecl ) override final;
    6675        virtual void visit( TypedefDecl * typeDecl ) override final;
     76        virtual void visit( const TypedefDecl * typeDecl ) override final;
    6777        virtual void visit( AsmDecl * asmDecl ) override final;
     78        virtual void visit( const AsmDecl * asmDecl ) override final;
    6879        virtual void visit( StaticAssertDecl * assertDecl ) override final;
     80        virtual void visit( const StaticAssertDecl * assertDecl ) override final;
    6981
    7082        virtual void visit( CompoundStmt * compoundStmt ) override final;
     83        virtual void visit( const CompoundStmt * compoundStmt ) override final;
    7184        virtual void visit( ExprStmt * exprStmt ) override final;
     85        virtual void visit( const ExprStmt * exprStmt ) override final;
    7286        virtual void visit( AsmStmt * asmStmt ) override final;
     87        virtual void visit( const AsmStmt * asmStmt ) override final;
    7388        virtual void visit( DirectiveStmt * dirStmt ) override final;
     89        virtual void visit( const DirectiveStmt * dirStmt ) override final;
    7490        virtual void visit( IfStmt * ifStmt ) override final;
     91        virtual void visit( const IfStmt * ifStmt ) override final;
    7592        virtual void visit( WhileStmt * whileStmt ) override final;
     93        virtual void visit( const WhileStmt * whileStmt ) override final;
    7694        virtual void visit( ForStmt * forStmt ) override final;
     95        virtual void visit( const ForStmt * forStmt ) override final;
    7796        virtual void visit( SwitchStmt * switchStmt ) override final;
     97        virtual void visit( const SwitchStmt * switchStmt ) override final;
    7898        virtual void visit( CaseStmt * caseStmt ) override final;
     99        virtual void visit( const CaseStmt * caseStmt ) override final;
    79100        virtual void visit( BranchStmt * branchStmt ) override final;
     101        virtual void visit( const BranchStmt * branchStmt ) override final;
    80102        virtual void visit( ReturnStmt * returnStmt ) override final;
     103        virtual void visit( const ReturnStmt * returnStmt ) override final;
    81104        virtual void visit( ThrowStmt * throwStmt ) override final;
     105        virtual void visit( const ThrowStmt * throwStmt ) override final;
    82106        virtual void visit( TryStmt * tryStmt ) override final;
     107        virtual void visit( const TryStmt * tryStmt ) override final;
    83108        virtual void visit( CatchStmt * catchStmt ) override final;
     109        virtual void visit( const CatchStmt * catchStmt ) override final;
    84110        virtual void visit( FinallyStmt * finallyStmt ) override final;
     111        virtual void visit( const FinallyStmt * finallyStmt ) override final;
    85112        virtual void visit( WaitForStmt * waitforStmt ) override final;
     113        virtual void visit( const WaitForStmt * waitforStmt ) override final;
    86114        virtual void visit( WithStmt * withStmt ) override final;
     115        virtual void visit( const WithStmt * withStmt ) override final;
    87116        virtual void visit( NullStmt * nullStmt ) override final;
     117        virtual void visit( const NullStmt * nullStmt ) override final;
    88118        virtual void visit( DeclStmt * declStmt ) override final;
     119        virtual void visit( const DeclStmt * declStmt ) override final;
    89120        virtual void visit( ImplicitCtorDtorStmt * impCtorDtorStmt ) override final;
     121        virtual void visit( const ImplicitCtorDtorStmt * impCtorDtorStmt ) override final;
    90122
    91123        virtual void visit( ApplicationExpr * applicationExpr ) override final;
     124        virtual void visit( const ApplicationExpr * applicationExpr ) override final;
    92125        virtual void visit( UntypedExpr * untypedExpr ) override final;
     126        virtual void visit( const UntypedExpr * untypedExpr ) override final;
    93127        virtual void visit( NameExpr * nameExpr ) override final;
     128        virtual void visit( const NameExpr * nameExpr ) override final;
    94129        virtual void visit( CastExpr * castExpr ) override final;
     130        virtual void visit( const CastExpr * castExpr ) override final;
    95131        virtual void visit( KeywordCastExpr * castExpr ) override final;
     132        virtual void visit( const KeywordCastExpr * castExpr ) override final;
    96133        virtual void visit( VirtualCastExpr * castExpr ) override final;
     134        virtual void visit( const VirtualCastExpr * castExpr ) override final;
    97135        virtual void visit( AddressExpr * addressExpr ) override final;
     136        virtual void visit( const AddressExpr * addressExpr ) override final;
    98137        virtual void visit( LabelAddressExpr * labAddressExpr ) override final;
     138        virtual void visit( const LabelAddressExpr * labAddressExpr ) override final;
    99139        virtual void visit( UntypedMemberExpr * memberExpr ) override final;
     140        virtual void visit( const UntypedMemberExpr * memberExpr ) override final;
    100141        virtual void visit( MemberExpr * memberExpr ) override final;
     142        virtual void visit( const MemberExpr * memberExpr ) override final;
    101143        virtual void visit( VariableExpr * variableExpr ) override final;
     144        virtual void visit( const VariableExpr * variableExpr ) override final;
    102145        virtual void visit( ConstantExpr * constantExpr ) override final;
     146        virtual void visit( const ConstantExpr * constantExpr ) override final;
    103147        virtual void visit( SizeofExpr * sizeofExpr ) override final;
     148        virtual void visit( const SizeofExpr * sizeofExpr ) override final;
    104149        virtual void visit( AlignofExpr * alignofExpr ) override final;
     150        virtual void visit( const AlignofExpr * alignofExpr ) override final;
    105151        virtual void visit( UntypedOffsetofExpr * offsetofExpr ) override final;
     152        virtual void visit( const UntypedOffsetofExpr * offsetofExpr ) override final;
    106153        virtual void visit( OffsetofExpr * offsetofExpr ) override final;
     154        virtual void visit( const OffsetofExpr * offsetofExpr ) override final;
    107155        virtual void visit( OffsetPackExpr * offsetPackExpr ) override final;
    108         virtual void visit( AttrExpr * attrExpr ) override final;
     156        virtual void visit( const OffsetPackExpr * offsetPackExpr ) override final;
    109157        virtual void visit( LogicalExpr * logicalExpr ) override final;
     158        virtual void visit( const LogicalExpr * logicalExpr ) override final;
    110159        virtual void visit( ConditionalExpr * conditionalExpr ) override final;
     160        virtual void visit( const ConditionalExpr * conditionalExpr ) override final;
    111161        virtual void visit( CommaExpr * commaExpr ) override final;
     162        virtual void visit( const CommaExpr * commaExpr ) override final;
    112163        virtual void visit( TypeExpr * typeExpr ) override final;
     164        virtual void visit( const TypeExpr * typeExpr ) override final;
    113165        virtual void visit( AsmExpr * asmExpr ) override final;
     166        virtual void visit( const AsmExpr * asmExpr ) override final;
    114167        virtual void visit( ImplicitCopyCtorExpr * impCpCtorExpr ) override final;
     168        virtual void visit( const ImplicitCopyCtorExpr * impCpCtorExpr ) override final;
    115169        virtual void visit( ConstructorExpr *  ctorExpr ) override final;
     170        virtual void visit( const ConstructorExpr *  ctorExpr ) override final;
    116171        virtual void visit( CompoundLiteralExpr * compLitExpr ) override final;
     172        virtual void visit( const CompoundLiteralExpr * compLitExpr ) override final;
    117173        virtual void visit( RangeExpr * rangeExpr ) override final;
     174        virtual void visit( const RangeExpr * rangeExpr ) override final;
    118175        virtual void visit( UntypedTupleExpr * tupleExpr ) override final;
     176        virtual void visit( const UntypedTupleExpr * tupleExpr ) override final;
    119177        virtual void visit( TupleExpr * tupleExpr ) override final;
     178        virtual void visit( const TupleExpr * tupleExpr ) override final;
    120179        virtual void visit( TupleIndexExpr * tupleExpr ) override final;
     180        virtual void visit( const TupleIndexExpr * tupleExpr ) override final;
    121181        virtual void visit( TupleAssignExpr * assignExpr ) override final;
     182        virtual void visit( const TupleAssignExpr * assignExpr ) override final;
    122183        virtual void visit( StmtExpr *  stmtExpr ) override final;
     184        virtual void visit( const StmtExpr *  stmtExpr ) override final;
    123185        virtual void visit( UniqueExpr *  uniqueExpr ) override final;
     186        virtual void visit( const UniqueExpr *  uniqueExpr ) override final;
    124187        virtual void visit( UntypedInitExpr *  initExpr ) override final;
     188        virtual void visit( const UntypedInitExpr *  initExpr ) override final;
    125189        virtual void visit( InitExpr *  initExpr ) override final;
     190        virtual void visit( const InitExpr *  initExpr ) override final;
    126191        virtual void visit( DeletedExpr *  delExpr ) override final;
     192        virtual void visit( const DeletedExpr *  delExpr ) override final;
     193        virtual void visit( DefaultArgExpr * argExpr ) override final;
     194        virtual void visit( const DefaultArgExpr * argExpr ) override final;
    127195        virtual void visit( GenericExpr * genExpr ) override final;
     196        virtual void visit( const GenericExpr * genExpr ) override final;
    128197
    129198        virtual void visit( VoidType * basicType ) override final;
     199        virtual void visit( const VoidType * basicType ) override final;
    130200        virtual void visit( BasicType * basicType ) override final;
     201        virtual void visit( const BasicType * basicType ) override final;
    131202        virtual void visit( PointerType * pointerType ) override final;
     203        virtual void visit( const PointerType * pointerType ) override final;
    132204        virtual void visit( ArrayType * arrayType ) override final;
     205        virtual void visit( const ArrayType * arrayType ) override final;
    133206        virtual void visit( ReferenceType * referenceType ) override final;
     207        virtual void visit( const ReferenceType * referenceType ) override final;
     208        virtual void visit( QualifiedType * qualType ) override final;
     209        virtual void visit( const QualifiedType * qualType ) override final;
    134210        virtual void visit( FunctionType * functionType ) override final;
     211        virtual void visit( const FunctionType * functionType ) override final;
    135212        virtual void visit( StructInstType * aggregateUseType ) override final;
     213        virtual void visit( const StructInstType * aggregateUseType ) override final;
    136214        virtual void visit( UnionInstType * aggregateUseType ) override final;
     215        virtual void visit( const UnionInstType * aggregateUseType ) override final;
    137216        virtual void visit( EnumInstType * aggregateUseType ) override final;
     217        virtual void visit( const EnumInstType * aggregateUseType ) override final;
    138218        virtual void visit( TraitInstType * aggregateUseType ) override final;
     219        virtual void visit( const TraitInstType * aggregateUseType ) override final;
    139220        virtual void visit( TypeInstType * aggregateUseType ) override final;
     221        virtual void visit( const TypeInstType * aggregateUseType ) override final;
    140222        virtual void visit( TupleType * tupleType ) override final;
     223        virtual void visit( const TupleType * tupleType ) override final;
    141224        virtual void visit( TypeofType * typeofType ) override final;
     225        virtual void visit( const TypeofType * typeofType ) override final;
    142226        virtual void visit( AttrType * attrType ) override final;
     227        virtual void visit( const AttrType * attrType ) override final;
    143228        virtual void visit( VarArgsType * varArgsType ) override final;
     229        virtual void visit( const VarArgsType * varArgsType ) override final;
    144230        virtual void visit( ZeroType * zeroType ) override final;
     231        virtual void visit( const ZeroType * zeroType ) override final;
    145232        virtual void visit( OneType * oneType ) override final;
     233        virtual void visit( const OneType * oneType ) override final;
     234        virtual void visit( GlobalScopeType * globalType ) override final;
     235        virtual void visit( const GlobalScopeType * globalType ) override final;
    146236
    147237        virtual void visit( Designation * designation ) override final;
     238        virtual void visit( const Designation * designation ) override final;
    148239        virtual void visit( SingleInit * singleInit ) override final;
     240        virtual void visit( const SingleInit * singleInit ) override final;
    149241        virtual void visit( ListInit * listInit ) override final;
     242        virtual void visit( const ListInit * listInit ) override final;
    150243        virtual void visit( ConstructorInit * ctorInit ) override final;
    151 
    152         virtual void visit( Subrange * subrange ) override final;
     244        virtual void visit( const ConstructorInit * ctorInit ) override final;
    153245
    154246        virtual void visit( Constant * constant ) override final;
     247        virtual void visit( const Constant * constant ) override final;
    155248
    156249        virtual void visit( Attribute * attribute ) override final;
     250        virtual void visit( const Attribute * attribute ) override final;
    157251
    158252        virtual DeclarationWithType * mutate( ObjectDecl * objectDecl ) override final;
     
    183277        virtual Statement * mutate( FinallyStmt * finallyStmt ) override final;
    184278        virtual Statement * mutate( WaitForStmt * waitforStmt ) override final;
    185         virtual Statement * mutate( WithStmt * withStmt ) override final;
     279        virtual Declaration * mutate( WithStmt * withStmt ) override final;
    186280        virtual NullStmt * mutate( NullStmt * nullStmt ) override final;
    187281        virtual Statement * mutate( DeclStmt * declStmt ) override final;
     
    205299        virtual Expression * mutate( OffsetofExpr * offsetofExpr ) override final;
    206300        virtual Expression * mutate( OffsetPackExpr * offsetPackExpr ) override final;
    207         virtual Expression * mutate( AttrExpr * attrExpr ) override final;
    208301        virtual Expression * mutate( LogicalExpr * logicalExpr ) override final;
    209302        virtual Expression * mutate( ConditionalExpr * conditionalExpr ) override final;
     
    224317        virtual Expression * mutate( InitExpr *  initExpr ) override final;
    225318        virtual Expression * mutate( DeletedExpr *  delExpr ) override final;
     319        virtual Expression * mutate( DefaultArgExpr * argExpr ) override final;
    226320        virtual Expression * mutate( GenericExpr * genExpr ) override final;
    227321
     
    231325        virtual Type * mutate( ArrayType * arrayType ) override final;
    232326        virtual Type * mutate( ReferenceType * referenceType ) override final;
     327        virtual Type * mutate( QualifiedType * qualType ) override final;
    233328        virtual Type * mutate( FunctionType * functionType ) override final;
    234329        virtual Type * mutate( StructInstType * aggregateUseType ) override final;
     
    243338        virtual Type * mutate( ZeroType * zeroType ) override final;
    244339        virtual Type * mutate( OneType * oneType ) override final;
     340        virtual Type * mutate( GlobalScopeType * globalType ) override final;
    245341
    246342        virtual Designation * mutate( Designation * designation ) override final;
     
    249345        virtual Initializer * mutate( ConstructorInit * ctorInit ) override final;
    250346
    251         virtual Subrange * mutate( Subrange * subrange ) override final;
    252 
    253347        virtual Constant * mutate( Constant * constant ) override final;
    254348
     
    258352
    259353private:
     354        bool inFunction = false;
     355
    260356        template<typename pass_t> friend void acceptAll( std::list< Declaration* > &decls, PassVisitor< pass_t >& visitor );
     357        template<typename pass_t> friend void acceptAll( const std::list< const Declaration * > &decls, PassVisitor< pass_t >& visitor );
    261358        template<typename pass_t> friend void mutateAll( std::list< Declaration* > &decls, PassVisitor< pass_t >& visitor );
    262359        template< typename TreeType, typename pass_t > friend void maybeAccept_impl( TreeType * tree, PassVisitor< pass_t > & visitor );
     360        template< typename TreeType, typename pass_t > friend void maybeAccept_impl( const TreeType * tree, PassVisitor< pass_t > & visitor );
    263361        template< typename TreeType, typename pass_t > friend void maybeMutate_impl( TreeType *& tree, PassVisitor< pass_t > & mutator );
    264362        template< typename Container, typename pass_t > friend void maybeAccept_impl( Container & container, PassVisitor< pass_t > & visitor );
     363        template< typename Container, typename pass_t > friend void maybeAccept_impl( const Container & container, PassVisitor< pass_t > & visitor );
    265364        template< typename Container, typename pass_t > friend void maybeMutate_impl( Container & container, PassVisitor< pass_t > & mutator );
    266365
    267366        template<typename node_type> void call_previsit ( node_type * node ) { previsit_impl ( pass, node, 0 ); }
     367        template<typename node_type> void call_previsit ( const node_type * node ) { previsit_impl ( pass, node, 0 ); }
    268368        template<typename node_type> void call_postvisit( node_type * node ) { postvisit_impl( pass, node, 0 ); }
     369        template<typename node_type> void call_postvisit( const node_type * node ) { postvisit_impl( pass, node, 0 ); }
    269370
    270371        template<typename node_type> void call_premutate ( node_type * node ) { premutate_impl( pass, node, 0 ); }
     
    280381        void visitStatementList ( std::list< Statement* > &statements );
    281382        void mutateStatementList( std::list< Statement* > &statements );
     383        void visitStatementList ( const std::list< Statement * > & statements );
    282384
    283385        template< typename func_t >
     
    285387        Statement * visitStatement ( Statement * stmt );
    286388        Statement * mutateStatement( Statement * stmt );
     389        void visitStatement ( const Statement * stmt );
    287390
    288391        template< typename func_t >
     
    290393        Expression * visitExpression ( Expression * expr );
    291394        Expression * mutateExpression( Expression * expr );
    292 
    293 
    294         TypeSubstitution **             get_env_ptr    () { return env_impl             ( pass, 0); }
     395        void visitExpression ( const Expression * expr );
     396
     397
     398        auto                                    get_env_ptr    () -> decltype(env_impl( pass, 0)) { return env_impl( pass, 0); }
    295399        std::list< Statement* > *       get_beforeStmts() { return stmtsToAddBefore_impl( pass, 0); }
    296400        std::list< Statement* > *       get_afterStmts () { return stmtsToAddAfter_impl ( pass, 0); }
     
    303407        void indexerScopeEnter  ()                                    { indexer_impl_enterScope  ( pass, 0       ); }
    304408        void indexerScopeLeave  ()                                    { indexer_impl_leaveScope  ( pass, 0       ); }
    305         void indexerAddId       ( DeclarationWithType      * node  ) { indexer_impl_addId       ( pass, 0, node ); }
    306         void indexerAddType     ( NamedTypeDecl             * node  ) { indexer_impl_addType     ( pass, 0, node ); }
     409        void indexerAddId       ( const DeclarationWithType * node  ) { indexer_impl_addId       ( pass, 0, node ); }
     410        void indexerAddType     ( const NamedTypeDecl       * node  ) { indexer_impl_addType     ( pass, 0, node ); }
    307411        void indexerAddStruct   ( const std::string         & id    ) { indexer_impl_addStruct   ( pass, 0, id   ); }
    308         void indexerAddStruct   ( StructDecl                * node  ) { indexer_impl_addStruct   ( pass, 0, node ); }
    309         void indexerAddStructFwd( StructDecl                * node  ) { indexer_impl_addStructFwd( pass, 0, node ); }
    310         void indexerAddEnum     ( EnumDecl                  * node  ) { indexer_impl_addEnum     ( pass, 0, node ); }
     412        void indexerAddStruct   ( const StructDecl          * node  ) { indexer_impl_addStruct   ( pass, 0, node ); }
     413        void indexerAddStructFwd( const StructDecl          * node  ) { indexer_impl_addStructFwd( pass, 0, node ); }
     414        void indexerAddEnum     ( const EnumDecl            * node  ) { indexer_impl_addEnum     ( pass, 0, node ); }
    311415        void indexerAddUnion    ( const std::string         & id    ) { indexer_impl_addUnion    ( pass, 0, id   ); }
    312         void indexerAddUnion    ( UnionDecl                 * node  ) { indexer_impl_addUnion    ( pass, 0, node ); }
    313         void indexerAddUnionFwd ( UnionDecl                 * node  ) { indexer_impl_addUnionFwd ( pass, 0, node ); }
    314         void indexerAddTrait    ( TraitDecl                 * node  ) { indexer_impl_addTrait    ( pass, 0, node ); }
    315         void indexerAddWith     ( std::list< Expression * > & exprs, BaseSyntaxNode * withStmt ) { indexer_impl_addWith( pass, 0, exprs, withStmt ); }
     416        void indexerAddUnion    ( const UnionDecl           * node  ) { indexer_impl_addUnion    ( pass, 0, node ); }
     417        void indexerAddUnionFwd ( const UnionDecl           * node  ) { indexer_impl_addUnionFwd ( pass, 0, node ); }
     418        void indexerAddTrait    ( const TraitDecl           * node  ) { indexer_impl_addTrait    ( pass, 0, node ); }
     419        void indexerAddWith     ( const std::list< Expression * > & exprs, const Declaration * withStmt ) { indexer_impl_addWith( pass, 0, exprs, withStmt ); }
    316420
    317421
    318422        template< typename TreeType, typename VisitorType >
    319         friend inline void indexerScopedAccept( TreeType * tree, VisitorType &visitor );
     423        friend inline void indexerScopedAccept( TreeType * tree, VisitorType & visitor );
    320424
    321425        template< typename TreeType, typename VisitorType >
    322         friend inline void indexerScopedMutate( TreeType *& tree, VisitorType &visitor );
     426        friend inline void indexerScopedAccept( const TreeType * tree, VisitorType & visitor );
     427
     428        template< typename TreeType, typename VisitorType >
     429        friend inline void indexerScopedMutate( TreeType *& tree, VisitorType & visitor );
    323430};
    324431
     
    337444public:
    338445        TypeSubstitution * env = nullptr;
     446};
     447
     448class WithConstTypeSubstitution {
     449protected:
     450        WithConstTypeSubstitution() = default;
     451        ~WithConstTypeSubstitution() = default;
     452
     453public:
     454        const TypeSubstitution * env = nullptr;
    339455};
    340456
     
    418534};
    419535
     536#include "Common/Stats.h"
     537
     538extern struct PassVisitorStats {
     539        size_t depth = 0;
     540        Stats::Counters::MaxCounter<double> * max = nullptr;
     541        Stats::Counters::AverageCounter<double> * avg = nullptr;
     542} pass_visitor_stats;
     543
    420544#include "SynTree/TypeSubstitution.h"
    421545#include "PassVisitor.impl.h"
  • src/Common/PassVisitor.impl.h

    r7951100 rb067d9b  
    2020
    2121#define MUTATE_END( type, node )                \
    22         return call_postmutate< type * >( node ); \
    23 
    24 
    25 #define VISIT_BODY( node )          \
    26         VISIT_START( node );          \
    27         if( children_guard ) {        \
    28                 Visitor::visit( node ); \
    29         }                             \
    30         VISIT_END( node );            \
    31 
    32 
    33 #define MUTATE_BODY( type, node )    \
    34         MUTATE_START( node );          \
    35         if( children_guard ) {         \
    36                 Mutator::mutate( node ); \
    37         }                              \
    38         MUTATE_END( type, node );      \
    39 
     22        auto __return = call_postmutate< type * >( node ); \
     23        assert( __return ); \
     24        return __return;
    4025
    4126
     
    6752        SemanticErrorException errors;
    6853
     54        pass_visitor_stats.depth++;
     55        pass_visitor_stats.max->push(pass_visitor_stats.depth);
     56        pass_visitor_stats.avg->push(pass_visitor_stats.depth);
    6957        for ( std::list< Declaration* >::iterator i = decls.begin(); ; ++i ) {
     58
     59
    7060                // splice in new declarations after previous decl
    7161                if ( !empty( afterDecls ) ) { decls.splice( i, *afterDecls ); }
     
    8373                if ( !empty( beforeDecls ) ) { decls.splice( i, *beforeDecls ); }
    8474        }
     75        pass_visitor_stats.depth--;
     76        if ( ! errors.isEmpty() ) {
     77                throw errors;
     78        }
     79}
     80
     81template< typename pass_type >
     82inline void acceptAll( const std::list< const Declaration * > & decls, PassVisitor< pass_type >& visitor ) {
     83        SemanticErrorException errors;
     84
     85        pass_visitor_stats.depth++;
     86        pass_visitor_stats.max->push(pass_visitor_stats.depth);
     87        pass_visitor_stats.avg->push(pass_visitor_stats.depth);
     88        for ( const Declaration * decl : decls ) {
     89                try {
     90                        // run visitor on declaration
     91                        maybeAccept_impl( decl, visitor );
     92                }
     93                catch( SemanticErrorException &e ) {
     94                        errors.append( e );
     95                }
     96        }
     97        pass_visitor_stats.depth--;
    8598        if ( ! errors.isEmpty() ) {
    8699                throw errors;
     
    94107        SemanticErrorException errors;
    95108
     109        pass_visitor_stats.depth++;
     110        pass_visitor_stats.max->push(pass_visitor_stats.depth);
     111        pass_visitor_stats.avg->push(pass_visitor_stats.depth);
    96112        for ( std::list< Declaration* >::iterator i = decls.begin(); ; ++i ) {
    97113                // splice in new declarations after previous decl
     
    109125                if ( !empty( beforeDecls ) ) { decls.splice( i, *beforeDecls ); }
    110126        }
     127        pass_visitor_stats.depth--;
    111128        if ( ! errors.isEmpty() ) {
    112129                throw errors;
     
    122139}
    123140
     141template< typename TreeType, typename pass_type >
     142inline void maybeAccept_impl( const TreeType * tree, PassVisitor< pass_type > & visitor ) {
     143        if ( ! visitor.get_visit_children() ) return;
     144        if ( tree ) {
     145                tree->accept( visitor );
     146        }
     147}
     148
    124149template< typename Container, typename pass_type >
    125150inline void maybeAccept_impl( Container & container, PassVisitor< pass_type > & visitor ) {
    126151        if ( ! visitor.get_visit_children() ) return;
    127152        SemanticErrorException errors;
     153
     154        pass_visitor_stats.depth++;
     155        pass_visitor_stats.max->push(pass_visitor_stats.depth);
     156        pass_visitor_stats.avg->push(pass_visitor_stats.depth);
    128157        for ( typename Container::iterator i = container.begin(); i != container.end(); ++i ) {
    129158                try {
     
    135164                }
    136165        }
     166        pass_visitor_stats.depth--;
     167        if ( ! errors.isEmpty() ) {
     168                throw errors;
     169        }
     170}
     171
     172template< typename Container, typename pass_type >
     173inline void maybeAccept_impl( const Container & container, PassVisitor< pass_type > & visitor ) {
     174        if ( ! visitor.get_visit_children() ) return;
     175        SemanticErrorException errors;
     176
     177        pass_visitor_stats.depth++;
     178        pass_visitor_stats.max->push(pass_visitor_stats.depth);
     179        pass_visitor_stats.avg->push(pass_visitor_stats.depth);
     180        for ( const auto & i : container ) {
     181                try {
     182                        if ( i ) {
     183                                i->accept( visitor );
     184                        }
     185                } catch( SemanticErrorException &e ) {
     186                        errors.append( e );
     187                }
     188        }
     189        pass_visitor_stats.depth--;
    137190        if ( ! errors.isEmpty() ) {
    138191                throw errors;
     
    151204template< typename Container, typename pass_type >
    152205inline void maybeMutate_impl( Container & container, PassVisitor< pass_type > & mutator ) {
     206
    153207        if ( ! mutator.get_visit_children() ) return;
    154208        SemanticErrorException errors;
     209
     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);
    155213        for ( typename Container::iterator i = container.begin(); i != container.end(); ++i ) {
    156214                try {
     
    163221                } // try
    164222        } // for
     223        pass_visitor_stats.depth--;
    165224        if ( ! errors.isEmpty() ) {
    166225                throw errors;
     
    185244        DeclList_t* afterDecls  = get_afterDecls();
    186245
     246        pass_visitor_stats.depth++;
     247        pass_visitor_stats.max->push(pass_visitor_stats.depth);
     248        pass_visitor_stats.avg->push(pass_visitor_stats.depth);
    187249        for ( std::list< Statement* >::iterator i = statements.begin(); i != statements.end(); ++i ) {
    188250
     
    192254                try {
    193255                        func( *i );
     256                        assert( *i );
    194257                        assert(( empty( beforeStmts ) && empty( afterStmts ))
    195258                            || ( empty( beforeDecls ) && empty( afterDecls )) );
     
    202265                if ( !empty( beforeStmts ) ) { statements.splice( i, *beforeStmts ); }
    203266        }
     267        pass_visitor_stats.depth--;
    204268
    205269        if ( !empty( afterDecls ) ) { splice( std::back_inserter( statements ), afterDecls); }
     
    216280
    217281template< typename pass_type >
     282void PassVisitor< pass_type >::visitStatementList( const std::list< Statement * > & statements ) {
     283        if ( ! get_visit_children() ) return;
     284        SemanticErrorException errors;
     285
     286        pass_visitor_stats.depth++;
     287        pass_visitor_stats.max->push(pass_visitor_stats.depth);
     288        pass_visitor_stats.avg->push(pass_visitor_stats.depth);
     289        for ( const Statement * i : statements ) {
     290                try {
     291                        maybeAccept_impl( i, *this );
     292                } catch ( SemanticErrorException &e ) {
     293                        errors.append( e );
     294                }
     295        }
     296        pass_visitor_stats.depth--;
     297        if ( !errors.isEmpty() ) { throw errors; }
     298}
     299
     300template< typename pass_type >
    218301void PassVisitor< pass_type >::mutateStatementList( std::list< Statement * > & statements ) {
    219302        handleStatementList( statements, [this]( Statement *& stmt) {
     
    229312
    230313        // don't want statements from outer CompoundStmts to be added to this CompoundStmt
    231         ValueGuardPtr< TypeSubstitution * >  oldEnv        ( get_env_ptr    () );
     314        ValueGuardPtr< typename std::remove_pointer<decltype(get_env_ptr())>::type >  oldEnv( get_env_ptr() );
    232315        ValueGuardPtr< DeclList_t >          oldBeforeDecls( get_beforeDecls() );
    233316        ValueGuardPtr< DeclList_t >          oldAfterDecls ( get_afterDecls () );
     
    264347
    265348template< typename pass_type >
     349void PassVisitor< pass_type >::visitStatement( const Statement * stmt ) {
     350        if ( ! get_visit_children() ) return;
     351
     352        // don't want statements from outer CompoundStmts to be added to this CompoundStmt
     353        ValueGuardPtr< typename std::remove_pointer<decltype(get_env_ptr())>::type >  oldEnv( get_env_ptr() );
     354
     355        maybeAccept_impl( stmt, *this );
     356}
     357
     358template< typename pass_type >
    266359Statement * PassVisitor< pass_type >::mutateStatement( Statement * stmt ) {
    267360        return handleStatement( stmt, [this]( Statement * stmt ) {
     
    295388
    296389template< typename pass_type >
     390void PassVisitor< pass_type >::visitExpression( const Expression * expr ) {
     391        if ( ! get_visit_children() ) return;
     392        if( !expr ) return;
     393
     394        auto env_ptr = get_env_ptr();
     395        if ( env_ptr && expr->get_env() ) {
     396                *env_ptr = expr->get_env();
     397        }
     398
     399        maybeAccept_impl( expr, *this );
     400}
     401
     402template< typename pass_type >
    297403Expression * PassVisitor< pass_type >::mutateExpression( Expression * expr ) {
    298404        return handleExpression(expr, [this]( Expression * expr ) {
     
    304410template< typename TreeType, typename VisitorType >
    305411inline void indexerScopedAccept( TreeType * tree, VisitorType & visitor ) {
     412        if ( ! visitor.get_visit_children() ) return;
     413        auto guard = makeFuncGuard(
     414                [&visitor]() { visitor.indexerScopeEnter(); },
     415                [&visitor]() { visitor.indexerScopeLeave(); }
     416        );
     417        maybeAccept_impl( tree, visitor );
     418}
     419
     420template< typename TreeType, typename VisitorType >
     421inline void indexerScopedAccept( const TreeType * tree, VisitorType & visitor ) {
    306422        if ( ! visitor.get_visit_children() ) return;
    307423        auto guard = makeFuncGuard(
     
    366482
    367483template< typename pass_type >
     484void PassVisitor< pass_type >::visit( const ObjectDecl * node ) {
     485        VISIT_START( node );
     486
     487        maybeAccept_impl( node->type         , *this );
     488        maybeAccept_impl( node->init         , *this );
     489        maybeAccept_impl( node->bitfieldWidth, *this );
     490        maybeAccept_impl( node->attributes   , *this );
     491
     492        VISIT_END( node );
     493}
     494
     495template< typename pass_type >
    368496DeclarationWithType * PassVisitor< pass_type >::mutate( ObjectDecl * node ) {
    369497        MUTATE_START( node );
     
    404532                        indexerAddId( &func );
    405533                        maybeAccept_impl( node->type, *this );
     534                        // function body needs to have the same scope as parameters - CompoundStmt will not enter
     535                        // a new scope if inFunction is true
     536                        ValueGuard< bool > oldInFunction( inFunction );
     537                        inFunction = true;
     538                        maybeAccept_impl( node->statements, *this );
     539                        maybeAccept_impl( node->attributes, *this );
     540                }
     541        }
     542
     543        VISIT_END( node );
     544}
     545
     546template< typename pass_type >
     547void PassVisitor< pass_type >::visit( const FunctionDecl * node ) {
     548        VISIT_START( node );
     549
     550        indexerAddId( node );
     551
     552        maybeAccept_impl( node->withExprs, *this );
     553        {
     554                // with clause introduces a level of scope (for the with expression members).
     555                // with clause exprs are added to the indexer before parameters so that parameters
     556                // shadow with exprs and not the other way around.
     557                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
     558                indexerAddWith( node->withExprs, node );
     559                {
     560                        auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
     561                        // implicit add __func__ identifier as specified in the C manual 6.4.2.2
     562                        static ObjectDecl func(
     563                                "__func__", noStorageClasses, LinkageSpec::C, nullptr,
     564                                new ArrayType( Type::Qualifiers(), new BasicType( Type::Qualifiers( Type::Const ), BasicType::Char ), nullptr, true, false ),
     565                                nullptr
     566                        );
     567                        indexerAddId( &func );
     568                        maybeAccept_impl( node->type, *this );
     569                        // function body needs to have the same scope as parameters - CompoundStmt will not enter
     570                        // a new scope if inFunction is true
     571                        ValueGuard< bool > oldInFunction( inFunction );
     572                        inFunction = true;
    406573                        maybeAccept_impl( node->statements, *this );
    407574                        maybeAccept_impl( node->attributes, *this );
     
    434601                        indexerAddId( &func );
    435602                        maybeMutate_impl( node->type, *this );
     603                        // function body needs to have the same scope as parameters - CompoundStmt will not enter
     604                        // a new scope if inFunction is true
     605                        ValueGuard< bool > oldInFunction( inFunction );
     606                        inFunction = true;
    436607                        maybeMutate_impl( node->statements, *this );
    437608                        maybeMutate_impl( node->attributes, *this );
     
    465636
    466637template< typename pass_type >
    467 Declaration * PassVisitor< pass_type >::mutate( StructDecl * node ) {
    468         MUTATE_START( node );
     638void PassVisitor< pass_type >::visit( const StructDecl * node ) {
     639        VISIT_START( node );
    469640
    470641        // make up a forward declaration and add it before processing the members
     
    474645        {
    475646                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
     647                maybeAccept_impl( node->parameters, *this );
     648                maybeAccept_impl( node->members   , *this );
     649        }
     650
     651        // this addition replaces the forward declaration
     652        indexerAddStruct( node );
     653
     654        VISIT_END( node );
     655}
     656
     657template< typename pass_type >
     658Declaration * PassVisitor< pass_type >::mutate( StructDecl * node ) {
     659        MUTATE_START( node );
     660
     661        // make up a forward declaration and add it before processing the members
     662        // needs to be on the heap because addStruct saves the pointer
     663        indexerAddStructFwd( node );
     664
     665        {
     666                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
    476667                maybeMutate_impl( node->parameters, *this );
    477668                maybeMutate_impl( node->members   , *this );
     
    503694        VISIT_END( node );
    504695}
     696template< typename pass_type >
     697void PassVisitor< pass_type >::visit( const UnionDecl * node ) {
     698        VISIT_START( node );
     699
     700        // make up a forward declaration and add it before processing the members
     701        indexerAddUnionFwd( node );
     702
     703        {
     704                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
     705                maybeAccept_impl( node->parameters, *this );
     706                maybeAccept_impl( node->members   , *this );
     707        }
     708
     709        indexerAddUnion( node );
     710
     711        VISIT_END( node );
     712}
    505713
    506714template< typename pass_type >
     
    538746
    539747template< typename pass_type >
     748void PassVisitor< pass_type >::visit( const EnumDecl * node ) {
     749        VISIT_START( node );
     750
     751        indexerAddEnum( node );
     752
     753        // unlike structs, traits, and unions, enums inject their members into the global scope
     754        maybeAccept_impl( node->parameters, *this );
     755        maybeAccept_impl( node->members   , *this );
     756
     757        VISIT_END( node );
     758}
     759
     760template< typename pass_type >
    540761Declaration * PassVisitor< pass_type >::mutate( EnumDecl * node ) {
    541762        MUTATE_START( node );
     
    554775template< typename pass_type >
    555776void PassVisitor< pass_type >::visit( TraitDecl * node ) {
     777        VISIT_START( node );
     778
     779        {
     780                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
     781                maybeAccept_impl( node->parameters, *this );
     782                maybeAccept_impl( node->members   , *this );
     783        }
     784
     785        indexerAddTrait( node );
     786
     787        VISIT_END( node );
     788}
     789
     790template< typename pass_type >
     791void PassVisitor< pass_type >::visit( const TraitDecl * node ) {
    556792        VISIT_START( node );
    557793
     
    606842}
    607843
    608 template< typename pass_type >
    609 Declaration * PassVisitor< pass_type >::mutate( TypeDecl * node ) {
    610         MUTATE_START( node );
     844
     845template< typename pass_type >
     846void PassVisitor< pass_type >::visit( const TypeDecl * node ) {
     847        VISIT_START( node );
    611848
    612849        {
    613850                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
    614                 maybeMutate_impl( node->parameters, *this );
    615                 maybeMutate_impl( node->base      , *this );
     851                maybeAccept_impl( node->parameters, *this );
     852                maybeAccept_impl( node->base      , *this );
    616853        }
    617854
     
    621858        indexerAddType( node );
    622859
     860        maybeAccept_impl( node->assertions, *this );
     861
     862        indexerScopedAccept( node->init, *this );
     863
     864        VISIT_END( node );
     865}
     866
     867template< typename pass_type >
     868Declaration * PassVisitor< pass_type >::mutate( TypeDecl * node ) {
     869        MUTATE_START( node );
     870
     871        {
     872                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
     873                maybeMutate_impl( node->parameters, *this );
     874                maybeMutate_impl( node->base      , *this );
     875        }
     876
     877        // see A NOTE ON THE ORDER OF TRAVERSAL, above
     878        // note that assertions come after the type is added to the symtab, since they are not part of the type proper
     879        // and may depend on the type itself
     880        indexerAddType( node );
     881
    623882        maybeMutate_impl( node->assertions, *this );
    624883
     
    648907
    649908template< typename pass_type >
     909void PassVisitor< pass_type >::visit( const TypedefDecl * node ) {
     910        VISIT_START( node );
     911
     912        {
     913                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
     914                maybeAccept_impl( node->parameters, *this );
     915                maybeAccept_impl( node->base      , *this );
     916        }
     917
     918        indexerAddType( node );
     919
     920        maybeAccept_impl( node->assertions, *this );
     921
     922        VISIT_END( node );
     923}
     924
     925template< typename pass_type >
    650926Declaration * PassVisitor< pass_type >::mutate( TypedefDecl * node ) {
    651927        MUTATE_START( node );
     
    676952
    677953template< typename pass_type >
     954void PassVisitor< pass_type >::visit( const AsmDecl * node ) {
     955        VISIT_START( node );
     956
     957        maybeAccept_impl( node->stmt, *this );
     958
     959        VISIT_END( node );
     960}
     961
     962template< typename pass_type >
    678963AsmDecl * PassVisitor< pass_type >::mutate( AsmDecl * node ) {
    679964        MUTATE_START( node );
     
    697982
    698983template< typename pass_type >
     984void PassVisitor< pass_type >::visit( const StaticAssertDecl * node ) {
     985        VISIT_START( node );
     986
     987        visitExpression( node->condition );
     988        maybeAccept_impl( node->message, *this );
     989
     990        VISIT_END( node );
     991}
     992
     993template< typename pass_type >
    699994StaticAssertDecl * PassVisitor< pass_type >::mutate( StaticAssertDecl * node ) {
    700995        MUTATE_START( node );
     
    7121007        VISIT_START( node );
    7131008        {
    714                 auto guard1 = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
     1009                // do not enter a new scope if inFunction is true - needs to check old state before the assignment
     1010                ValueGuard< bool > oldInFunction( inFunction );
     1011                auto guard1 = makeFuncGuard( [this, &oldInFunction]() { if ( ! oldInFunction.old ) indexerScopeEnter(); }, [this, &oldInFunction]() { if ( ! oldInFunction.old ) indexerScopeLeave(); } );
    7151012                auto guard2 = makeFuncGuard( [this]() { call_beginScope();   }, [this]() { call_endScope();     } );
     1013                inFunction = false;
    7161014                visitStatementList( node->kids );
    7171015        }
     
    7201018
    7211019template< typename pass_type >
     1020void PassVisitor< pass_type >::visit( const CompoundStmt * node ) {
     1021        VISIT_START( node );
     1022        {
     1023                // do not enter a new scope if inFunction is true - needs to check old state before the assignment
     1024                ValueGuard< bool > oldInFunction( inFunction );
     1025                auto guard1 = makeFuncGuard( [this, &oldInFunction]() { if ( ! oldInFunction.old ) indexerScopeEnter(); }, [this, &oldInFunction]() { if ( ! oldInFunction.old ) indexerScopeLeave(); } );
     1026                auto guard2 = makeFuncGuard( [this]() { call_beginScope();   }, [this]() { call_endScope();     } );
     1027                inFunction = false;
     1028                visitStatementList( node->kids );
     1029        }
     1030        VISIT_END( node );
     1031}
     1032
     1033template< typename pass_type >
    7221034CompoundStmt * PassVisitor< pass_type >::mutate( CompoundStmt * node ) {
    7231035        MUTATE_START( node );
    7241036        {
    725                 auto guard1 = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
     1037                // do not enter a new scope if inFunction is true - needs to check old state before the assignment
     1038                ValueGuard< bool > oldInFunction( inFunction );
     1039                auto guard1 = makeFuncGuard( [this, &oldInFunction]() { if ( ! oldInFunction.old ) indexerScopeEnter(); }, [this, &oldInFunction]() { if ( ! oldInFunction.old ) indexerScopeLeave(); } );
    7261040                auto guard2 = makeFuncGuard( [this]() { call_beginScope();   }, [this]() { call_endScope();     } );
     1041                inFunction = false;
    7271042                mutateStatementList( node->kids );
    7281043        }
     
    7341049template< typename pass_type >
    7351050void PassVisitor< pass_type >::visit( ExprStmt * node ) {
     1051        VISIT_START( node );
     1052
     1053        visitExpression( node->expr );
     1054
     1055        VISIT_END( node );
     1056}
     1057
     1058template< typename pass_type >
     1059void PassVisitor< pass_type >::visit( const ExprStmt * node ) {
    7361060        VISIT_START( node );
    7371061
     
    7651089
    7661090template< typename pass_type >
     1091void PassVisitor< pass_type >::visit( const AsmStmt * node ) {
     1092        VISIT_START( node )
     1093
     1094        maybeAccept_impl( node->instruction, *this );
     1095        maybeAccept_impl( node->output, *this );
     1096        maybeAccept_impl( node->input, *this );
     1097        maybeAccept_impl( node->clobber, *this );
     1098
     1099        VISIT_END( node );
     1100}
     1101
     1102template< typename pass_type >
    7671103Statement * PassVisitor< pass_type >::mutate( AsmStmt * node ) {
    7681104        MUTATE_START( node );
     
    7861122
    7871123template< typename pass_type >
     1124void PassVisitor< pass_type >::visit( const DirectiveStmt * node ) {
     1125        VISIT_START( node )
     1126
     1127        VISIT_END( node );
     1128}
     1129
     1130template< typename pass_type >
    7881131Statement * PassVisitor< pass_type >::mutate( DirectiveStmt * node ) {
    7891132        MUTATE_START( node );
     
    8001143                // if statements introduce a level of scope (for the initialization)
    8011144                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
    802                 maybeAccept_impl( node->get_initialization(), *this );
     1145                maybeAccept_impl( node->initialization, *this );
    8031146                visitExpression ( node->condition );
    8041147                node->thenPart = visitStatement( node->thenPart );
     
    8091152
    8101153template< typename pass_type >
    811 Statement * PassVisitor< pass_type >::mutate( IfStmt * node ) {
    812         MUTATE_START( node );
     1154void PassVisitor< pass_type >::visit( const IfStmt * node ) {
     1155        VISIT_START( node );
    8131156        {
    8141157                // if statements introduce a level of scope (for the initialization)
    8151158                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
    816                 maybeMutate_impl( node->get_initialization(), *this );
     1159                maybeAccept_impl( node->initialization, *this );
     1160                visitExpression ( node->condition );
     1161                visitStatement  ( node->thenPart );
     1162                visitStatement  ( node->elsePart );
     1163        }
     1164        VISIT_END( node );
     1165}
     1166
     1167template< typename pass_type >
     1168Statement * PassVisitor< pass_type >::mutate( IfStmt * node ) {
     1169        MUTATE_START( node );
     1170        {
     1171                // if statements introduce a level of scope (for the initialization)
     1172                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
     1173                maybeMutate_impl( node->initialization, *this );
    8171174                node->condition = mutateExpression( node->condition );
    8181175                node->thenPart  = mutateStatement ( node->thenPart  );
     
    8341191                visitExpression ( node->condition );
    8351192                node->body = visitStatement( node->body );
     1193        }
     1194
     1195        VISIT_END( node );
     1196}
     1197
     1198template< typename pass_type >
     1199void PassVisitor< pass_type >::visit( const WhileStmt * node ) {
     1200        VISIT_START( node );
     1201
     1202        {
     1203                // while statements introduce a level of scope (for the initialization)
     1204                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
     1205                maybeAccept_impl( node->initialization, *this );
     1206                visitExpression ( node->condition );
     1207                visitStatement  ( node->body );
    8361208        }
    8371209
     
    8721244
    8731245template< typename pass_type >
     1246void PassVisitor< pass_type >::visit( const ForStmt * node ) {
     1247        VISIT_START( node );
     1248        {
     1249                // for statements introduce a level of scope (for the initialization)
     1250                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
     1251                maybeAccept_impl( node->initialization, *this );
     1252                visitExpression( node->condition );
     1253                visitExpression( node->increment );
     1254                visitStatement ( node->body );
     1255        }
     1256        VISIT_END( node );
     1257}
     1258
     1259template< typename pass_type >
    8741260Statement * PassVisitor< pass_type >::mutate( ForStmt * node ) {
    8751261        MUTATE_START( node );
     
    8981284
    8991285template< typename pass_type >
     1286void PassVisitor< pass_type >::visit( const SwitchStmt * node ) {
     1287        VISIT_START( node );
     1288
     1289        visitExpression   ( node->condition  );
     1290        visitStatementList( node->statements );
     1291
     1292        VISIT_END( node );
     1293}
     1294
     1295template< typename pass_type >
    9001296Statement * PassVisitor< pass_type >::mutate( SwitchStmt * node ) {
    9011297        MUTATE_START( node );
     
    9201316
    9211317template< typename pass_type >
     1318void PassVisitor< pass_type >::visit( const CaseStmt * node ) {
     1319        VISIT_START( node );
     1320
     1321        visitExpression   ( node->condition );
     1322        visitStatementList( node->stmts     );
     1323
     1324        VISIT_END( node );
     1325}
     1326
     1327template< typename pass_type >
    9221328Statement * PassVisitor< pass_type >::mutate( CaseStmt * node ) {
    9231329        MUTATE_START( node );
     
    9381344
    9391345template< typename pass_type >
     1346void PassVisitor< pass_type >::visit( const BranchStmt * node ) {
     1347        VISIT_START( node );
     1348        VISIT_END( node );
     1349}
     1350
     1351template< typename pass_type >
    9401352Statement * PassVisitor< pass_type >::mutate( BranchStmt * node ) {
    9411353        MUTATE_START( node );
     
    9551367
    9561368template< typename pass_type >
     1369void PassVisitor< pass_type >::visit( const ReturnStmt * node ) {
     1370        VISIT_START( node );
     1371
     1372        visitExpression( node->expr );
     1373
     1374        VISIT_END( node );
     1375}
     1376
     1377template< typename pass_type >
    9571378Statement * PassVisitor< pass_type >::mutate( ReturnStmt * node ) {
    9581379        MUTATE_START( node );
     
    9651386//--------------------------------------------------------------------------
    9661387// ThrowStmt
    967 
    9681388template< typename pass_type >
    9691389void PassVisitor< pass_type >::visit( ThrowStmt * node ) {
     
    9771397
    9781398template< typename pass_type >
     1399void PassVisitor< pass_type >::visit( const ThrowStmt * node ) {
     1400        VISIT_START( node );
     1401
     1402        maybeAccept_impl( node->expr, *this );
     1403        maybeAccept_impl( node->target, *this );
     1404
     1405        VISIT_END( node );
     1406}
     1407
     1408template< typename pass_type >
    9791409Statement * PassVisitor< pass_type >::mutate( ThrowStmt * node ) {
    9801410        MUTATE_START( node );
     
    9901420template< typename pass_type >
    9911421void PassVisitor< pass_type >::visit( TryStmt * node ) {
     1422        VISIT_START( node );
     1423
     1424        maybeAccept_impl( node->block       , *this );
     1425        maybeAccept_impl( node->handlers    , *this );
     1426        maybeAccept_impl( node->finallyBlock, *this );
     1427
     1428        VISIT_END( node );
     1429}
     1430
     1431template< typename pass_type >
     1432void PassVisitor< pass_type >::visit( const TryStmt * node ) {
    9921433        VISIT_START( node );
    9931434
     
    10261467
    10271468template< typename pass_type >
     1469void PassVisitor< pass_type >::visit( const CatchStmt * node ) {
     1470        VISIT_START( node );
     1471        {
     1472                // catch statements introduce a level of scope (for the caught exception)
     1473                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
     1474                maybeAccept_impl( node->decl, *this );
     1475                visitExpression ( node->cond );
     1476                visitStatement  ( node->body );
     1477        }
     1478        VISIT_END( node );
     1479}
     1480
     1481template< typename pass_type >
    10281482Statement * PassVisitor< pass_type >::mutate( CatchStmt * node ) {
    10291483        MUTATE_START( node );
     
    10501504
    10511505template< typename pass_type >
     1506void PassVisitor< pass_type >::visit( const FinallyStmt * node ) {
     1507        VISIT_START( node );
     1508
     1509        maybeAccept_impl( node->block, *this );
     1510
     1511        VISIT_END( node );
     1512}
     1513
     1514template< typename pass_type >
    10521515Statement * PassVisitor< pass_type >::mutate( FinallyStmt * node ) {
    10531516        MUTATE_START( node );
     
    10821545
    10831546template< typename pass_type >
     1547void PassVisitor< pass_type >::visit( const WaitForStmt * node ) {
     1548        VISIT_START( node );
     1549
     1550        for( auto & clause : node->clauses ) {
     1551                maybeAccept_impl( clause.target.function, *this );
     1552                maybeAccept_impl( clause.target.arguments, *this );
     1553
     1554                maybeAccept_impl( clause.statement, *this );
     1555                maybeAccept_impl( clause.condition, *this );
     1556        }
     1557
     1558        maybeAccept_impl( node->timeout.time, *this );
     1559        maybeAccept_impl( node->timeout.statement, *this );
     1560        maybeAccept_impl( node->timeout.condition, *this );
     1561        maybeAccept_impl( node->orelse.statement, *this );
     1562        maybeAccept_impl( node->orelse.condition, *this );
     1563
     1564        VISIT_END( node );
     1565}
     1566
     1567template< typename pass_type >
    10841568Statement * PassVisitor< pass_type >::mutate( WaitForStmt * node ) {
    10851569        MUTATE_START( node );
     
    11051589
    11061590//--------------------------------------------------------------------------
    1107 // NullStmt
     1591// WithStmt
    11081592template< typename pass_type >
    11091593void PassVisitor< pass_type >::visit( WithStmt * node ) {
     
    11201604
    11211605template< typename pass_type >
    1122 Statement * PassVisitor< pass_type >::mutate( WithStmt * node ) {
     1606void PassVisitor< pass_type >::visit( const WithStmt * node ) {
     1607        VISIT_START( node );
     1608        maybeAccept_impl( node->exprs, *this );
     1609        {
     1610                // catch statements introduce a level of scope (for the caught exception)
     1611                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
     1612                indexerAddWith( node->exprs, node );
     1613                maybeAccept_impl( node->stmt, *this );
     1614        }
     1615        VISIT_END( node );
     1616}
     1617
     1618template< typename pass_type >
     1619Declaration * PassVisitor< pass_type >::mutate( WithStmt * node ) {
    11231620        MUTATE_START( node );
    11241621        maybeMutate_impl( node->exprs, *this );
     
    11291626                maybeMutate_impl( node->stmt, *this );
    11301627        }
     1628        MUTATE_END( Declaration, node );
     1629}
     1630
     1631//--------------------------------------------------------------------------
     1632// NullStmt
     1633template< typename pass_type >
     1634void PassVisitor< pass_type >::visit( NullStmt * node ) {
     1635        VISIT_START( node );
     1636        VISIT_END( node );
     1637}
     1638
     1639template< typename pass_type >
     1640void PassVisitor< pass_type >::visit( const NullStmt * node ) {
     1641        VISIT_START( node );
     1642        VISIT_END( node );
     1643}
     1644
     1645template< typename pass_type >
     1646NullStmt * PassVisitor< pass_type >::mutate( NullStmt * node ) {
     1647        MUTATE_START( node );
     1648        MUTATE_END( NullStmt, node );
     1649}
     1650
     1651//--------------------------------------------------------------------------
     1652// DeclStmt
     1653template< typename pass_type >
     1654void PassVisitor< pass_type >::visit( DeclStmt * node ) {
     1655        VISIT_START( node );
     1656
     1657        maybeAccept_impl( node->decl, *this );
     1658
     1659        VISIT_END( node );
     1660}
     1661
     1662template< typename pass_type >
     1663void PassVisitor< pass_type >::visit( const DeclStmt * node ) {
     1664        VISIT_START( node );
     1665
     1666        maybeAccept_impl( node->decl, *this );
     1667
     1668        VISIT_END( node );
     1669}
     1670
     1671template< typename pass_type >
     1672Statement * PassVisitor< pass_type >::mutate( DeclStmt * node ) {
     1673        MUTATE_START( node );
     1674
     1675        maybeMutate_impl( node->decl, *this );
     1676
    11311677        MUTATE_END( Statement, node );
    11321678}
    11331679
    11341680//--------------------------------------------------------------------------
    1135 // NullStmt
    1136 template< typename pass_type >
    1137 void PassVisitor< pass_type >::visit( NullStmt * node ) {
    1138         VISIT_START( node );
    1139         VISIT_END( node );
    1140 }
    1141 
    1142 template< typename pass_type >
    1143 NullStmt * PassVisitor< pass_type >::mutate( NullStmt * node ) {
    1144         MUTATE_START( node );
    1145         MUTATE_END( NullStmt, node );
    1146 }
    1147 
    1148 //--------------------------------------------------------------------------
    1149 // DeclStmt
    1150 template< typename pass_type >
    1151 void PassVisitor< pass_type >::visit( DeclStmt * node ) {
    1152         VISIT_START( node );
    1153 
    1154         maybeAccept_impl( node->decl, *this );
    1155 
    1156         VISIT_END( node );
    1157 }
    1158 
    1159 template< typename pass_type >
    1160 Statement * PassVisitor< pass_type >::mutate( DeclStmt * node ) {
    1161         MUTATE_START( node );
    1162 
    1163         maybeMutate_impl( node->decl, *this );
     1681// ImplicitCtorDtorStmt
     1682template< typename pass_type >
     1683void PassVisitor< pass_type >::visit( ImplicitCtorDtorStmt * node ) {
     1684        VISIT_START( node );
     1685
     1686        maybeAccept_impl( node->callStmt, *this );
     1687
     1688        VISIT_END( node );
     1689}
     1690
     1691template< typename pass_type >
     1692void PassVisitor< pass_type >::visit( const ImplicitCtorDtorStmt * node ) {
     1693        VISIT_START( node );
     1694
     1695        maybeAccept_impl( node->callStmt, *this );
     1696
     1697        VISIT_END( node );
     1698}
     1699
     1700template< typename pass_type >
     1701Statement * PassVisitor< pass_type >::mutate( ImplicitCtorDtorStmt * node ) {
     1702        MUTATE_START( node );
     1703
     1704        maybeMutate_impl( node->callStmt, *this );
    11641705
    11651706        MUTATE_END( Statement, node );
     
    11671708
    11681709//--------------------------------------------------------------------------
    1169 // ImplicitCtorDtorStmt
    1170 template< typename pass_type >
    1171 void PassVisitor< pass_type >::visit( ImplicitCtorDtorStmt * node ) {
    1172         VISIT_START( node );
    1173 
    1174         maybeAccept_impl( node->callStmt, *this );
    1175 
    1176         VISIT_END( node );
    1177 }
    1178 
    1179 template< typename pass_type >
    1180 Statement * PassVisitor< pass_type >::mutate( ImplicitCtorDtorStmt * node ) {
    1181         MUTATE_START( node );
    1182 
    1183         maybeMutate_impl( node->callStmt, *this );
    1184 
    1185         MUTATE_END( Statement, node );
    1186 }
    1187 
    1188 //--------------------------------------------------------------------------
    11891710// ApplicationExpr
    11901711template< typename pass_type >
     
    11931714
    11941715        indexerScopedAccept( node->result  , *this );
    1195         maybeAccept_impl        ( node->function, *this );
    1196         maybeAccept_impl        ( node->args    , *this );
     1716        maybeAccept_impl   ( node->function, *this );
     1717        maybeAccept_impl   ( node->args    , *this );
     1718
     1719        VISIT_END( node );
     1720}
     1721
     1722template< typename pass_type >
     1723void PassVisitor< pass_type >::visit( const ApplicationExpr * node ) {
     1724        VISIT_START( node );
     1725
     1726        indexerScopedAccept( node->result  , *this );
     1727        maybeAccept_impl   ( node->function, *this );
     1728        maybeAccept_impl   ( node->args    , *this );
    11971729
    11981730        VISIT_END( node );
     
    12281760
    12291761template< typename pass_type >
     1762void PassVisitor< pass_type >::visit( const UntypedExpr * node ) {
     1763        VISIT_START( node );
     1764
     1765        indexerScopedAccept( node->result, *this );
     1766
     1767        for ( auto expr : node->args ) {
     1768                visitExpression( expr );
     1769        }
     1770
     1771        VISIT_END( node );
     1772}
     1773
     1774template< typename pass_type >
    12301775Expression * PassVisitor< pass_type >::mutate( UntypedExpr * node ) {
    12311776        MUTATE_START( node );
     
    12531798
    12541799template< typename pass_type >
     1800void PassVisitor< pass_type >::visit( const NameExpr * node ) {
     1801        VISIT_START( node );
     1802
     1803        indexerScopedAccept( node->result, *this );
     1804
     1805        VISIT_END( node );
     1806}
     1807
     1808template< typename pass_type >
    12551809Expression * PassVisitor< pass_type >::mutate( NameExpr * node ) {
    12561810        MUTATE_START( node );
     
    12691823
    12701824        indexerScopedAccept( node->result, *this );
    1271         maybeAccept_impl        ( node->arg   , *this );
     1825        maybeAccept_impl   ( node->arg   , *this );
     1826
     1827        VISIT_END( node );
     1828}
     1829
     1830template< typename pass_type >
     1831void PassVisitor< pass_type >::visit( const CastExpr * node ) {
     1832        VISIT_START( node );
     1833
     1834        indexerScopedAccept( node->result, *this );
     1835        maybeAccept_impl   ( node->arg   , *this );
    12721836
    12731837        VISIT_END( node );
     
    12981862
    12991863template< typename pass_type >
     1864void PassVisitor< pass_type >::visit( const KeywordCastExpr * node ) {
     1865        VISIT_START( node );
     1866
     1867        indexerScopedAccept( node->result, *this );
     1868        maybeAccept_impl   ( node->arg   , *this );
     1869
     1870        VISIT_END( node );
     1871}
     1872
     1873template< typename pass_type >
    13001874Expression * PassVisitor< pass_type >::mutate( KeywordCastExpr * node ) {
    13011875        MUTATE_START( node );
     
    13151889
    13161890        indexerScopedAccept( node->result, *this );
    1317         maybeAccept_impl( node->arg, *this );
     1891        maybeAccept_impl   ( node->arg, *this );
     1892
     1893        VISIT_END( node );
     1894}
     1895
     1896template< typename pass_type >
     1897void PassVisitor< pass_type >::visit( const VirtualCastExpr * node ) {
     1898        VISIT_START( node );
     1899
     1900        indexerScopedAccept( node->result, *this );
     1901        maybeAccept_impl   ( node->arg, *this );
    13181902
    13191903        VISIT_END( node );
     
    13441928
    13451929template< typename pass_type >
     1930void PassVisitor< pass_type >::visit( const AddressExpr * node ) {
     1931        VISIT_START( node );
     1932
     1933        indexerScopedAccept( node->result, *this );
     1934        maybeAccept_impl   ( node->arg   , *this );
     1935
     1936        VISIT_END( node );
     1937}
     1938
     1939template< typename pass_type >
    13461940Expression * PassVisitor< pass_type >::mutate( AddressExpr * node ) {
    13471941        MUTATE_START( node );
     
    13661960
    13671961template< typename pass_type >
     1962void PassVisitor< pass_type >::visit( const LabelAddressExpr * node ) {
     1963        VISIT_START( node );
     1964
     1965        indexerScopedAccept( node->result, *this );
     1966
     1967        VISIT_END( node );
     1968}
     1969
     1970template< typename pass_type >
    13681971Expression * PassVisitor< pass_type >::mutate( LabelAddressExpr * node ) {
    13691972        MUTATE_START( node );
     
    13791982template< typename pass_type >
    13801983void PassVisitor< pass_type >::visit( UntypedMemberExpr * node ) {
     1984        VISIT_START( node );
     1985
     1986        indexerScopedAccept( node->result   , *this );
     1987        maybeAccept_impl   ( node->aggregate, *this );
     1988        maybeAccept_impl   ( node->member   , *this );
     1989
     1990        VISIT_END( node );
     1991}
     1992
     1993template< typename pass_type >
     1994void PassVisitor< pass_type >::visit( const UntypedMemberExpr * node ) {
    13811995        VISIT_START( node );
    13821996
     
    14132027
    14142028template< typename pass_type >
     2029void PassVisitor< pass_type >::visit( const MemberExpr * node ) {
     2030        VISIT_START( node );
     2031
     2032        indexerScopedAccept( node->result   , *this );
     2033        maybeAccept_impl   ( node->aggregate, *this );
     2034
     2035        VISIT_END( node );
     2036}
     2037
     2038template< typename pass_type >
    14152039Expression * PassVisitor< pass_type >::mutate( MemberExpr * node ) {
    14162040        MUTATE_START( node );
     
    14352059
    14362060template< typename pass_type >
     2061void PassVisitor< pass_type >::visit( const VariableExpr * node ) {
     2062        VISIT_START( node );
     2063
     2064        indexerScopedAccept( node->result, *this );
     2065
     2066        VISIT_END( node );
     2067}
     2068
     2069template< typename pass_type >
    14372070Expression * PassVisitor< pass_type >::mutate( VariableExpr * node ) {
    14382071        MUTATE_START( node );
     
    14482081template< typename pass_type >
    14492082void PassVisitor< pass_type >::visit( ConstantExpr * node ) {
     2083        VISIT_START( node );
     2084
     2085        indexerScopedAccept( node->result   , *this );
     2086        maybeAccept_impl   ( &node->constant, *this );
     2087
     2088        VISIT_END( node );
     2089}
     2090
     2091template< typename pass_type >
     2092void PassVisitor< pass_type >::visit( const ConstantExpr * node ) {
    14502093        VISIT_START( node );
    14512094
     
    14732116template< typename pass_type >
    14742117void PassVisitor< pass_type >::visit( SizeofExpr * node ) {
     2118        VISIT_START( node );
     2119
     2120        indexerScopedAccept( node->result, *this );
     2121        if ( node->get_isType() ) {
     2122                maybeAccept_impl( node->type, *this );
     2123        } else {
     2124                maybeAccept_impl( node->expr, *this );
     2125        }
     2126
     2127        VISIT_END( node );
     2128}
     2129
     2130template< typename pass_type >
     2131void PassVisitor< pass_type >::visit( const SizeofExpr * node ) {
    14752132        VISIT_START( node );
    14762133
     
    15172174
    15182175template< typename pass_type >
     2176void PassVisitor< pass_type >::visit( const AlignofExpr * node ) {
     2177        VISIT_START( node );
     2178
     2179        indexerScopedAccept( node->result, *this );
     2180        if ( node->get_isType() ) {
     2181                maybeAccept_impl( node->type, *this );
     2182        } else {
     2183                maybeAccept_impl( node->expr, *this );
     2184        }
     2185
     2186        VISIT_END( node );
     2187}
     2188
     2189template< typename pass_type >
    15192190Expression * PassVisitor< pass_type >::mutate( AlignofExpr * node ) {
    15202191        MUTATE_START( node );
     
    15442215
    15452216template< typename pass_type >
     2217void PassVisitor< pass_type >::visit( const UntypedOffsetofExpr * node ) {
     2218        VISIT_START( node );
     2219
     2220        indexerScopedAccept( node->result, *this );
     2221        maybeAccept_impl   ( node->type  , *this );
     2222
     2223        VISIT_END( node );
     2224}
     2225
     2226template< typename pass_type >
    15462227Expression * PassVisitor< pass_type >::mutate( UntypedOffsetofExpr * node ) {
    15472228        MUTATE_START( node );
     
    15672248
    15682249template< typename pass_type >
     2250void PassVisitor< pass_type >::visit( const OffsetofExpr * node ) {
     2251        VISIT_START( node );
     2252
     2253        indexerScopedAccept( node->result, *this );
     2254        maybeAccept_impl   ( node->type  , *this );
     2255
     2256        VISIT_END( node );
     2257}
     2258
     2259template< typename pass_type >
    15692260Expression * PassVisitor< pass_type >::mutate( OffsetofExpr * node ) {
    15702261        MUTATE_START( node );
     
    15902281
    15912282template< typename pass_type >
     2283void PassVisitor< pass_type >::visit( const OffsetPackExpr * node ) {
     2284        VISIT_START( node );
     2285
     2286        indexerScopedAccept( node->result, *this );
     2287        maybeAccept_impl   ( node->type  , *this );
     2288
     2289        VISIT_END( node );
     2290}
     2291
     2292template< typename pass_type >
    15922293Expression * PassVisitor< pass_type >::mutate( OffsetPackExpr * node ) {
    15932294        MUTATE_START( node );
     
    16012302
    16022303//--------------------------------------------------------------------------
    1603 // AttrExpr
    1604 template< typename pass_type >
    1605 void PassVisitor< pass_type >::visit( AttrExpr * node ) {
    1606         VISIT_START( node );
    1607 
    1608         indexerScopedAccept( node->result, *this );
    1609         if ( node->get_isType() ) {
    1610                 maybeAccept_impl( node->type, *this );
    1611         } else {
    1612                 maybeAccept_impl( node->expr, *this );
    1613         }
    1614 
    1615         VISIT_END( node );
    1616 }
    1617 
    1618 template< typename pass_type >
    1619 Expression * PassVisitor< pass_type >::mutate( AttrExpr * node ) {
    1620         MUTATE_START( node );
    1621 
    1622         indexerScopedMutate( node->env   , *this );
    1623         indexerScopedMutate( node->result, *this );
    1624         if ( node->get_isType() ) {
    1625                 maybeMutate_impl( node->type, *this );
    1626         } else {
    1627                 maybeMutate_impl( node->expr, *this );
    1628         }
    1629 
    1630         MUTATE_END( Expression, node );
    1631 }
    1632 
    1633 //--------------------------------------------------------------------------
    16342304// LogicalExpr
    16352305template< typename pass_type >
    16362306void PassVisitor< pass_type >::visit( LogicalExpr * node ) {
     2307        VISIT_START( node );
     2308
     2309        indexerScopedAccept( node->result, *this );
     2310        maybeAccept_impl   ( node->arg1  , *this );
     2311        maybeAccept_impl   ( node->arg2  , *this );
     2312
     2313        VISIT_END( node );
     2314}
     2315
     2316template< typename pass_type >
     2317void PassVisitor< pass_type >::visit( const LogicalExpr * node ) {
    16372318        VISIT_START( node );
    16382319
     
    16662347        maybeAccept_impl        ( node->arg2  , *this );
    16672348        maybeAccept_impl        ( node->arg3  , *this );
     2349
     2350        VISIT_END( node );
     2351}
     2352
     2353template< typename pass_type >
     2354void PassVisitor< pass_type >::visit( const ConditionalExpr * node ) {
     2355        VISIT_START( node );
     2356
     2357        indexerScopedAccept( node->result, *this );
     2358        maybeAccept_impl   ( node->arg1  , *this );
     2359        maybeAccept_impl   ( node->arg2  , *this );
     2360        maybeAccept_impl   ( node->arg3  , *this );
    16682361
    16692362        VISIT_END( node );
     
    16972390
    16982391template< typename pass_type >
     2392void PassVisitor< pass_type >::visit( const CommaExpr * node ) {
     2393        VISIT_START( node );
     2394
     2395        indexerScopedAccept( node->result, *this );
     2396        maybeAccept_impl   ( node->arg1  , *this );
     2397        maybeAccept_impl   ( node->arg2  , *this );
     2398
     2399        VISIT_END( node );
     2400}
     2401
     2402template< typename pass_type >
    16992403Expression * PassVisitor< pass_type >::mutate( CommaExpr * node ) {
    17002404        MUTATE_START( node );
     
    17212425
    17222426template< typename pass_type >
     2427void PassVisitor< pass_type >::visit( const TypeExpr * node ) {
     2428        VISIT_START( node );
     2429
     2430        indexerScopedAccept( node->result, *this );
     2431        maybeAccept_impl   ( node->type, *this );
     2432
     2433        VISIT_END( node );
     2434}
     2435
     2436template< typename pass_type >
    17232437Expression * PassVisitor< pass_type >::mutate( TypeExpr * node ) {
    17242438        MUTATE_START( node );
     
    17352449template< typename pass_type >
    17362450void PassVisitor< pass_type >::visit( AsmExpr * node ) {
     2451        VISIT_START( node );
     2452
     2453        indexerScopedAccept( node->result    , *this );
     2454        maybeAccept_impl   ( node->inout     , *this );
     2455        maybeAccept_impl   ( node->constraint, *this );
     2456        maybeAccept_impl   ( node->operand   , *this );
     2457
     2458        VISIT_END( node );
     2459}
     2460
     2461template< typename pass_type >
     2462void PassVisitor< pass_type >::visit( const AsmExpr * node ) {
    17372463        VISIT_START( node );
    17382464
     
    17642490        VISIT_START( node );
    17652491
    1766         indexerScopedAccept( node->result     , *this );
    1767         maybeAccept_impl   ( node->callExpr   , *this );
    1768         maybeAccept_impl   ( node->tempDecls  , *this );
    1769         maybeAccept_impl   ( node->returnDecls, *this );
    1770         maybeAccept_impl   ( node->dtors      , *this );
     2492        indexerScopedAccept( node->result    , *this );
     2493        maybeAccept_impl   ( node->callExpr  , *this );
     2494
     2495        VISIT_END( node );
     2496}
     2497
     2498template< typename pass_type >
     2499void PassVisitor< pass_type >::visit( const ImplicitCopyCtorExpr * node ) {
     2500        VISIT_START( node );
     2501
     2502        indexerScopedAccept( node->result    , *this );
     2503        maybeAccept_impl   ( node->callExpr  , *this );
    17712504
    17722505        VISIT_END( node );
     
    17772510        MUTATE_START( node );
    17782511
    1779         indexerScopedMutate( node->env        , *this );
    1780         indexerScopedMutate( node->result     , *this );
    1781         maybeMutate_impl   ( node->callExpr   , *this );
    1782         maybeMutate_impl   ( node->tempDecls  , *this );
    1783         maybeMutate_impl   ( node->returnDecls, *this );
    1784         maybeMutate_impl   ( node->dtors      , *this );
     2512        indexerScopedMutate( node->env       , *this );
     2513        indexerScopedMutate( node->result    , *this );
     2514        maybeMutate_impl   ( node->callExpr  , *this );
    17852515
    17862516        MUTATE_END( Expression, node );
     
    17912521template< typename pass_type >
    17922522void PassVisitor< pass_type >::visit( ConstructorExpr * node ) {
     2523        VISIT_START( node );
     2524
     2525        indexerScopedAccept( node->result  , *this );
     2526        maybeAccept_impl   ( node->callExpr, *this );
     2527
     2528        VISIT_END( node );
     2529}
     2530
     2531template< typename pass_type >
     2532void PassVisitor< pass_type >::visit( const ConstructorExpr * node ) {
    17932533        VISIT_START( node );
    17942534
     
    18232563
    18242564template< typename pass_type >
     2565void PassVisitor< pass_type >::visit( const CompoundLiteralExpr * node ) {
     2566        VISIT_START( node );
     2567
     2568        indexerScopedAccept( node->result     , *this );
     2569        maybeAccept_impl   ( node->initializer, *this );
     2570
     2571        VISIT_END( node );
     2572}
     2573
     2574template< typename pass_type >
    18252575Expression * PassVisitor< pass_type >::mutate( CompoundLiteralExpr * node ) {
    18262576        MUTATE_START( node );
     
    18372587template< typename pass_type >
    18382588void PassVisitor< pass_type >::visit( RangeExpr * node ) {
     2589        VISIT_START( node );
     2590
     2591        indexerScopedAccept( node->result, *this );
     2592        maybeAccept_impl   ( node->low   , *this );
     2593        maybeAccept_impl   ( node->high  , *this );
     2594
     2595        VISIT_END( node );
     2596}
     2597
     2598template< typename pass_type >
     2599void PassVisitor< pass_type >::visit( const RangeExpr * node ) {
    18392600        VISIT_START( node );
    18402601
     
    18712632
    18722633template< typename pass_type >
     2634void PassVisitor< pass_type >::visit( const UntypedTupleExpr * node ) {
     2635        VISIT_START( node );
     2636
     2637        indexerScopedAccept( node->result, *this );
     2638        maybeAccept_impl   ( node->exprs , *this );
     2639
     2640        VISIT_END( node );
     2641}
     2642
     2643template< typename pass_type >
    18732644Expression * PassVisitor< pass_type >::mutate( UntypedTupleExpr * node ) {
    18742645        MUTATE_START( node );
     
    18942665
    18952666template< typename pass_type >
     2667void PassVisitor< pass_type >::visit( const TupleExpr * node ) {
     2668        VISIT_START( node );
     2669
     2670        indexerScopedAccept( node->result, *this );
     2671        maybeAccept_impl   ( node->exprs , *this );
     2672
     2673        VISIT_END( node );
     2674}
     2675
     2676template< typename pass_type >
    18962677Expression * PassVisitor< pass_type >::mutate( TupleExpr * node ) {
    18972678        MUTATE_START( node );
     
    19172698
    19182699template< typename pass_type >
     2700void PassVisitor< pass_type >::visit( const TupleIndexExpr * node ) {
     2701        VISIT_START( node );
     2702
     2703        indexerScopedAccept( node->result, *this );
     2704        maybeAccept_impl   ( node->tuple , *this );
     2705
     2706        VISIT_END( node );
     2707}
     2708
     2709template< typename pass_type >
    19192710Expression * PassVisitor< pass_type >::mutate( TupleIndexExpr * node ) {
    19202711        MUTATE_START( node );
     
    19402731
    19412732template< typename pass_type >
     2733void PassVisitor< pass_type >::visit( const TupleAssignExpr * node ) {
     2734        VISIT_START( node );
     2735
     2736        indexerScopedAccept( node->result  , *this );
     2737        maybeAccept_impl( node->stmtExpr, *this );
     2738
     2739        VISIT_END( node );
     2740}
     2741
     2742template< typename pass_type >
    19422743Expression * PassVisitor< pass_type >::mutate( TupleAssignExpr * node ) {
    19432744        MUTATE_START( node );
     
    19572758
    19582759        // don't want statements from outer CompoundStmts to be added to this StmtExpr
    1959         ValueGuardPtr< TypeSubstitution * >      oldEnv        ( get_env_ptr() );
     2760        ValueGuardPtr< typename std::remove_pointer<decltype(get_env_ptr())>::type >  oldEnv( get_env_ptr() );
    19602761        ValueGuardPtr< std::list< Statement* > > oldBeforeStmts( get_beforeStmts() );
    19612762        ValueGuardPtr< std::list< Statement* > > oldAfterStmts ( get_afterStmts () );
     
    19702771
    19712772template< typename pass_type >
     2773void PassVisitor< pass_type >::visit( const StmtExpr * node ) {
     2774        VISIT_START( node );
     2775
     2776        // don't want statements from outer CompoundStmts to be added to this StmtExpr
     2777        ValueGuardPtr< typename std::remove_pointer<decltype(get_env_ptr())>::type >  oldEnv( get_env_ptr() );
     2778        ValueGuardPtr< std::list< Statement* > > oldBeforeStmts( get_beforeStmts() );
     2779        ValueGuardPtr< std::list< Statement* > > oldAfterStmts ( get_afterStmts () );
     2780
     2781        indexerScopedAccept( node->result     , *this );
     2782        maybeAccept_impl   ( node->statements , *this );
     2783        maybeAccept_impl   ( node->returnDecls, *this );
     2784        maybeAccept_impl   ( node->dtors      , *this );
     2785
     2786        VISIT_END( node );
     2787}
     2788
     2789template< typename pass_type >
    19722790Expression * PassVisitor< pass_type >::mutate( StmtExpr * node ) {
    19732791        MUTATE_START( node );
    19742792
    19752793        // don't want statements from outer CompoundStmts to be added to this StmtExpr
    1976         ValueGuardPtr< TypeSubstitution * >      oldEnv        ( get_env_ptr() );
     2794        ValueGuardPtr< typename std::remove_pointer<decltype(get_env_ptr())>::type >  oldEnv( get_env_ptr() );
    19772795        ValueGuardPtr< std::list< Statement* > > oldBeforeStmts( get_beforeStmts() );
    19782796        ValueGuardPtr< std::list< Statement* > > oldAfterStmts ( get_afterStmts () );
     
    19992817
    20002818template< typename pass_type >
     2819void PassVisitor< pass_type >::visit( const UniqueExpr * node ) {
     2820        VISIT_START( node );
     2821
     2822        indexerScopedAccept( node->result, *this );
     2823        maybeAccept_impl   ( node->expr  , *this );
     2824
     2825        VISIT_END( node );
     2826}
     2827
     2828template< typename pass_type >
    20012829Expression * PassVisitor< pass_type >::mutate( UniqueExpr * node ) {
    20022830        MUTATE_START( node );
     
    20132841template< typename pass_type >
    20142842void PassVisitor< pass_type >::visit( UntypedInitExpr * node ) {
     2843        VISIT_START( node );
     2844
     2845        indexerScopedAccept( node->result, *this );
     2846        maybeAccept_impl   ( node->expr  , *this );
     2847        // not currently visiting initAlts, but this doesn't matter since this node is only used in the resolver.
     2848
     2849        VISIT_END( node );
     2850}
     2851
     2852template< typename pass_type >
     2853void PassVisitor< pass_type >::visit( const UntypedInitExpr * node ) {
    20152854        VISIT_START( node );
    20162855
     
    20482887
    20492888template< typename pass_type >
     2889void PassVisitor< pass_type >::visit( const InitExpr * node ) {
     2890        VISIT_START( node );
     2891
     2892        indexerScopedAccept( node->result, *this );
     2893        maybeAccept_impl   ( node->expr  , *this );
     2894        maybeAccept_impl   ( node->designation, *this );
     2895
     2896        VISIT_END( node );
     2897}
     2898
     2899template< typename pass_type >
    20502900Expression * PassVisitor< pass_type >::mutate( InitExpr * node ) {
    20512901        MUTATE_START( node );
     
    20662916
    20672917        indexerScopedAccept( node->result, *this );
    2068         maybeAccept_impl( node->expr, *this );
     2918        maybeAccept_impl   ( node->expr, *this );
     2919        // don't visit deleteStmt, because it is a pointer to somewhere else in the tree.
     2920
     2921        VISIT_END( node );
     2922}
     2923
     2924template< typename pass_type >
     2925void PassVisitor< pass_type >::visit( const DeletedExpr * node ) {
     2926        VISIT_START( node );
     2927
     2928        indexerScopedAccept( node->result, *this );
     2929        maybeAccept_impl   ( node->expr, *this );
    20692930        // don't visit deleteStmt, because it is a pointer to somewhere else in the tree.
    20702931
     
    20842945
    20852946//--------------------------------------------------------------------------
     2947// DefaultArgExpr
     2948template< typename pass_type >
     2949void PassVisitor< pass_type >::visit( DefaultArgExpr * node ) {
     2950        VISIT_START( node );
     2951
     2952        indexerScopedAccept( node->result, *this );
     2953        maybeAccept_impl   ( node->expr, *this );
     2954
     2955        VISIT_END( node );
     2956}
     2957
     2958template< typename pass_type >
     2959void PassVisitor< pass_type >::visit( const DefaultArgExpr * node ) {
     2960        VISIT_START( node );
     2961
     2962        indexerScopedAccept( node->result, *this );
     2963        maybeAccept_impl   ( node->expr, *this );
     2964
     2965        VISIT_END( node );
     2966}
     2967
     2968template< typename pass_type >
     2969Expression * PassVisitor< pass_type >::mutate( DefaultArgExpr * node ) {
     2970        MUTATE_START( node );
     2971
     2972        indexerScopedMutate( node->env, *this );
     2973        indexerScopedMutate( node->result, *this );
     2974        maybeMutate_impl( node->expr, *this );
     2975
     2976        MUTATE_END( Expression, node );
     2977}
     2978
     2979//--------------------------------------------------------------------------
    20862980// GenericExpr
    20872981template< typename pass_type >
     
    20922986        maybeAccept_impl( node->control, *this );
    20932987        for ( GenericExpr::Association & assoc : node->associations ) {
     2988                indexerScopedAccept( assoc.type, *this );
     2989                maybeAccept_impl( assoc.expr, *this );
     2990        }
     2991
     2992        VISIT_END( node );
     2993}
     2994
     2995template< typename pass_type >
     2996void PassVisitor< pass_type >::visit( const GenericExpr * node ) {
     2997        VISIT_START( node );
     2998
     2999        indexerScopedAccept( node->result, *this );
     3000        maybeAccept_impl( node->control, *this );
     3001        for ( const GenericExpr::Association & assoc : node->associations ) {
    20943002                indexerScopedAccept( assoc.type, *this );
    20953003                maybeAccept_impl( assoc.expr, *this );
     
    21263034
    21273035template< typename pass_type >
     3036void PassVisitor< pass_type >::visit( const VoidType * node ) {
     3037        VISIT_START( node );
     3038
     3039        maybeAccept_impl( node->forall, *this );
     3040
     3041        VISIT_END( node );
     3042}
     3043
     3044template< typename pass_type >
    21283045Type * PassVisitor< pass_type >::mutate( VoidType * node ) {
    21293046        MUTATE_START( node );
     
    21383055template< typename pass_type >
    21393056void PassVisitor< pass_type >::visit( BasicType * node ) {
     3057        VISIT_START( node );
     3058
     3059        maybeAccept_impl( node->forall, *this );
     3060
     3061        VISIT_END( node );
     3062}
     3063
     3064template< typename pass_type >
     3065void PassVisitor< pass_type >::visit( const BasicType * node ) {
    21403066        VISIT_START( node );
    21413067
     
    21683094
    21693095template< typename pass_type >
     3096void PassVisitor< pass_type >::visit( const PointerType * node ) {
     3097        VISIT_START( node );
     3098
     3099        maybeAccept_impl( node->forall, *this );
     3100        // xxx - should PointerType visit/mutate dimension?
     3101        maybeAccept_impl( node->base, *this );
     3102
     3103        VISIT_END( node );
     3104}
     3105
     3106template< typename pass_type >
    21703107Type * PassVisitor< pass_type >::mutate( PointerType * node ) {
    21713108        MUTATE_START( node );
     
    21923129
    21933130template< typename pass_type >
     3131void PassVisitor< pass_type >::visit( const ArrayType * node ) {
     3132        VISIT_START( node );
     3133
     3134        maybeAccept_impl( node->forall, *this );
     3135        maybeAccept_impl( node->dimension, *this );
     3136        maybeAccept_impl( node->base, *this );
     3137
     3138        VISIT_END( node );
     3139}
     3140
     3141template< typename pass_type >
    21943142Type * PassVisitor< pass_type >::mutate( ArrayType * node ) {
    21953143        MUTATE_START( node );
     
    22153163
    22163164template< typename pass_type >
     3165void PassVisitor< pass_type >::visit( const ReferenceType * node ) {
     3166        VISIT_START( node );
     3167
     3168        maybeAccept_impl( node->forall, *this );
     3169        maybeAccept_impl( node->base, *this );
     3170
     3171        VISIT_END( node );
     3172}
     3173
     3174template< typename pass_type >
    22173175Type * PassVisitor< pass_type >::mutate( ReferenceType * node ) {
    22183176        MUTATE_START( node );
     
    22203178        maybeMutate_impl( node->forall, *this );
    22213179        maybeMutate_impl( node->base, *this );
     3180
     3181        MUTATE_END( Type, node );
     3182}
     3183
     3184//--------------------------------------------------------------------------
     3185// QualifiedType
     3186template< typename pass_type >
     3187void PassVisitor< pass_type >::visit( QualifiedType * node ) {
     3188        VISIT_START( node );
     3189
     3190        maybeAccept_impl( node->forall, *this );
     3191        maybeAccept_impl( node->parent, *this );
     3192        maybeAccept_impl( node->child, *this );
     3193
     3194        VISIT_END( node );
     3195}
     3196
     3197template< typename pass_type >
     3198void PassVisitor< pass_type >::visit( const QualifiedType * node ) {
     3199        VISIT_START( node );
     3200
     3201        maybeAccept_impl( node->forall, *this );
     3202        maybeAccept_impl( node->parent, *this );
     3203        maybeAccept_impl( node->child, *this );
     3204
     3205        VISIT_END( node );
     3206}
     3207
     3208template< typename pass_type >
     3209Type * PassVisitor< pass_type >::mutate( QualifiedType * node ) {
     3210        MUTATE_START( node );
     3211
     3212        maybeMutate_impl( node->forall, *this );
     3213        maybeMutate_impl( node->parent, *this );
     3214        maybeMutate_impl( node->child, *this );
    22223215
    22233216        MUTATE_END( Type, node );
     
    22383231
    22393232template< typename pass_type >
     3233void PassVisitor< pass_type >::visit( const FunctionType * node ) {
     3234        VISIT_START( node );
     3235
     3236        maybeAccept_impl( node->forall, *this );
     3237        maybeAccept_impl( node->returnVals, *this );
     3238        maybeAccept_impl( node->parameters, *this );
     3239
     3240        VISIT_END( node );
     3241}
     3242
     3243template< typename pass_type >
    22403244Type * PassVisitor< pass_type >::mutate( FunctionType * node ) {
    22413245        MUTATE_START( node );
     
    22663270
    22673271template< typename pass_type >
     3272void PassVisitor< pass_type >::visit( const StructInstType * node ) {
     3273        VISIT_START( node );
     3274
     3275        indexerAddStruct( node->name );
     3276
     3277        {
     3278                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
     3279                maybeAccept_impl( node->forall    , *this );
     3280                maybeAccept_impl( node->parameters, *this );
     3281        }
     3282
     3283        VISIT_END( node );
     3284}
     3285
     3286template< typename pass_type >
    22683287Type * PassVisitor< pass_type >::mutate( StructInstType * node ) {
    22693288        MUTATE_START( node );
     
    22983317
    22993318template< typename pass_type >
     3319void PassVisitor< pass_type >::visit( const UnionInstType * node ) {
     3320        VISIT_START( node );
     3321
     3322        indexerAddStruct( node->name );
     3323
     3324        {
     3325                auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } );
     3326                maybeAccept_impl( node->forall    , *this );
     3327                maybeAccept_impl( node->parameters, *this );
     3328        }
     3329
     3330        VISIT_END( node );
     3331}
     3332
     3333template< typename pass_type >
    23003334Type * PassVisitor< pass_type >::mutate( UnionInstType * node ) {
    23013335        MUTATE_START( node );
     
    23253359
    23263360template< typename pass_type >
     3361void PassVisitor< pass_type >::visit( const EnumInstType * node ) {
     3362        VISIT_START( node );
     3363
     3364        maybeAccept_impl( node->forall, *this );
     3365        maybeAccept_impl( node->parameters, *this );
     3366
     3367        VISIT_END( node );
     3368}
     3369
     3370template< typename pass_type >
    23273371Type * PassVisitor< pass_type >::mutate( EnumInstType * node ) {
    23283372        MUTATE_START( node );
     
    23473391
    23483392template< typename pass_type >
     3393void PassVisitor< pass_type >::visit( const TraitInstType * node ) {
     3394        VISIT_START( node );
     3395
     3396        maybeAccept_impl( node->forall    , *this );
     3397        maybeAccept_impl( node->parameters, *this );
     3398
     3399        VISIT_END( node );
     3400}
     3401
     3402template< typename pass_type >
    23493403Type * PassVisitor< pass_type >::mutate( TraitInstType * node ) {
    23503404        MUTATE_START( node );
     
    23603414template< typename pass_type >
    23613415void PassVisitor< pass_type >::visit( TypeInstType * node ) {
     3416        VISIT_START( node );
     3417
     3418        maybeAccept_impl( node->forall    , *this );
     3419        maybeAccept_impl( node->parameters, *this );
     3420
     3421        VISIT_END( node );
     3422}
     3423
     3424template< typename pass_type >
     3425void PassVisitor< pass_type >::visit( const TypeInstType * node ) {
    23623426        VISIT_START( node );
    23633427
     
    23923456
    23933457template< typename pass_type >
     3458void PassVisitor< pass_type >::visit( const TupleType * node ) {
     3459        VISIT_START( node );
     3460
     3461        maybeAccept_impl( node->forall, *this );
     3462        maybeAccept_impl( node->types, *this );
     3463        maybeAccept_impl( node->members, *this );
     3464
     3465        VISIT_END( node );
     3466}
     3467
     3468template< typename pass_type >
    23943469Type * PassVisitor< pass_type >::mutate( TupleType * node ) {
    23953470        MUTATE_START( node );
     
    24063481template< typename pass_type >
    24073482void PassVisitor< pass_type >::visit( TypeofType * node ) {
     3483        VISIT_START( node );
     3484
     3485        assert( node->expr );
     3486        maybeAccept_impl( node->expr, *this );
     3487
     3488        VISIT_END( node );
     3489}
     3490
     3491template< typename pass_type >
     3492void PassVisitor< pass_type >::visit( const TypeofType * node ) {
    24083493        VISIT_START( node );
    24093494
     
    24423527
    24433528template< typename pass_type >
     3529void PassVisitor< pass_type >::visit( const AttrType * node ) {
     3530        VISIT_START( node );
     3531
     3532        if ( node->isType ) {
     3533                assert( node->type );
     3534                maybeAccept_impl( node->type, *this );
     3535        } else {
     3536                assert( node->expr );
     3537                maybeAccept_impl( node->expr, *this );
     3538        } // if
     3539
     3540        VISIT_END( node );
     3541}
     3542
     3543template< typename pass_type >
    24443544Type * PassVisitor< pass_type >::mutate( AttrType * node ) {
    24453545        MUTATE_START( node );
     
    24683568
    24693569template< typename pass_type >
     3570void PassVisitor< pass_type >::visit( const VarArgsType * node ) {
     3571        VISIT_START( node );
     3572
     3573        maybeAccept_impl( node->forall, *this );
     3574
     3575        VISIT_END( node );
     3576}
     3577
     3578template< typename pass_type >
    24703579Type * PassVisitor< pass_type >::mutate( VarArgsType * node ) {
    24713580        MUTATE_START( node );
     
    24883597
    24893598template< typename pass_type >
     3599void PassVisitor< pass_type >::visit( const ZeroType * node ) {
     3600        VISIT_START( node );
     3601
     3602        maybeAccept_impl( node->forall, *this );
     3603
     3604        VISIT_END( node );
     3605}
     3606
     3607template< typename pass_type >
    24903608Type * PassVisitor< pass_type >::mutate( ZeroType * node ) {
    24913609        MUTATE_START( node );
     
    25083626
    25093627template< typename pass_type >
     3628void PassVisitor< pass_type >::visit( const OneType * node ) {
     3629        VISIT_START( node );
     3630
     3631        maybeAccept_impl( node->forall, *this );
     3632
     3633        VISIT_END( node );
     3634}
     3635
     3636template< typename pass_type >
    25103637Type * PassVisitor< pass_type >::mutate( OneType * node ) {
    25113638        MUTATE_START( node );
     
    25173644
    25183645//--------------------------------------------------------------------------
     3646// GlobalScopeType
     3647template< typename pass_type >
     3648void PassVisitor< pass_type >::visit( GlobalScopeType * node ) {
     3649        VISIT_START( node );
     3650
     3651        maybeAccept_impl( node->forall, *this );
     3652
     3653        VISIT_END( node );
     3654}
     3655
     3656template< typename pass_type >
     3657void PassVisitor< pass_type >::visit( const GlobalScopeType * node ) {
     3658        VISIT_START( node );
     3659
     3660        maybeAccept_impl( node->forall, *this );
     3661
     3662        VISIT_END( node );
     3663}
     3664
     3665template< typename pass_type >
     3666Type * PassVisitor< pass_type >::mutate( GlobalScopeType * node ) {
     3667        MUTATE_START( node );
     3668
     3669        maybeMutate_impl( node->forall, *this );
     3670
     3671        MUTATE_END( Type, node );
     3672}
     3673
     3674//--------------------------------------------------------------------------
    25193675// Designation
    25203676template< typename pass_type >
     
    25283684
    25293685template< typename pass_type >
     3686void PassVisitor< pass_type >::visit( const Designation * node ) {
     3687        VISIT_START( node );
     3688
     3689        maybeAccept_impl( node->designators, *this );
     3690
     3691        VISIT_END( node );
     3692}
     3693
     3694template< typename pass_type >
    25303695Designation * PassVisitor< pass_type >::mutate( Designation * node ) {
    25313696        MUTATE_START( node );
     
    25483713
    25493714template< typename pass_type >
     3715void PassVisitor< pass_type >::visit( const SingleInit * node ) {
     3716        VISIT_START( node );
     3717
     3718        visitExpression( node->value );
     3719
     3720        VISIT_END( node );
     3721}
     3722
     3723template< typename pass_type >
    25503724Initializer * PassVisitor< pass_type >::mutate( SingleInit * node ) {
    25513725        MUTATE_START( node );
     
    25603734template< typename pass_type >
    25613735void PassVisitor< pass_type >::visit( ListInit * node ) {
     3736        VISIT_START( node );
     3737
     3738        maybeAccept_impl( node->designations, *this );
     3739        maybeAccept_impl( node->initializers, *this );
     3740
     3741        VISIT_END( node );
     3742}
     3743
     3744template< typename pass_type >
     3745void PassVisitor< pass_type >::visit( const ListInit * node ) {
    25623746        VISIT_START( node );
    25633747
     
    25923776
    25933777template< typename pass_type >
     3778void PassVisitor< pass_type >::visit( const ConstructorInit * node ) {
     3779        VISIT_START( node );
     3780
     3781        maybeAccept_impl( node->ctor, *this );
     3782        maybeAccept_impl( node->dtor, *this );
     3783        maybeAccept_impl( node->init, *this );
     3784
     3785        VISIT_END( node );
     3786}
     3787
     3788template< typename pass_type >
    25943789Initializer * PassVisitor< pass_type >::mutate( ConstructorInit * node ) {
    25953790        MUTATE_START( node );
     
    26033798
    26043799//--------------------------------------------------------------------------
    2605 // Subrange
    2606 template< typename pass_type >
    2607 void PassVisitor< pass_type >::visit( Subrange * node ) {
    2608         VISIT_START( node );
    2609 
    2610         VISIT_END( node );
    2611 }
    2612 
    2613 template< typename pass_type >
    2614 Subrange * PassVisitor< pass_type >::mutate( Subrange * node  )  {
    2615         MUTATE_START( node );
    2616 
    2617         MUTATE_END( Subrange, node );
    2618 }
    2619 
    2620 //--------------------------------------------------------------------------
    26213800// Attribute
    26223801template< typename pass_type >
     
    26283807
    26293808template< typename pass_type >
     3809void PassVisitor< pass_type >::visit( const Constant * node ) {
     3810        VISIT_START( node );
     3811
     3812        VISIT_END( node );
     3813}
     3814
     3815template< typename pass_type >
    26303816Constant * PassVisitor< pass_type >::mutate( Constant * node  )  {
    26313817        MUTATE_START( node );
     
    26383824template< typename pass_type >
    26393825void PassVisitor< pass_type >::visit( Attribute * node ) {
     3826        VISIT_START( node );
     3827
     3828        maybeAccept_impl( node->parameters, *this );
     3829
     3830        VISIT_END( node );
     3831}
     3832
     3833template< typename pass_type >
     3834void PassVisitor< pass_type >::visit( const Attribute * node ) {
    26403835        VISIT_START( node );
    26413836
     
    26693864        MUTATE_END( TypeSubstitution, node );
    26703865}
     3866
     3867#undef VISIT_START
     3868#undef VISIT_END
     3869
     3870#undef MUTATE_START
     3871#undef MUTATE_END
  • src/Common/PassVisitor.proto.h

    r7951100 rb067d9b  
    118118static inline void postvisit_impl( __attribute__((unused)) pass_type& pass, __attribute__((unused)) node_type * node, __attribute__((unused)) long unused ) {}
    119119
     120template<typename pass_type, typename node_type>
     121static inline auto previsit_impl( pass_type& pass, const node_type * node, __attribute__((unused)) int unused ) -> decltype( pass.previsit( node ), void() ) {
     122        pass.previsit( node );
     123}
     124
     125template<typename pass_type, typename node_type>
     126static inline void previsit_impl( __attribute__((unused)) pass_type& pass, __attribute__((unused)) const node_type * node, __attribute__((unused)) long unused ) {}
     127
     128
     129template<typename pass_type, typename node_type>
     130static inline auto postvisit_impl( pass_type& pass, const node_type * node, __attribute__((unused)) int unused ) -> decltype( pass.postvisit( node ), void() ) {
     131        pass.postvisit( node );
     132}
     133
     134template<typename pass_type, typename node_type>
     135static inline void postvisit_impl( __attribute__((unused)) pass_type& pass, __attribute__((unused)) const node_type * node, __attribute__((unused)) long unused ) {}
     136
    120137//---------------------------------------------------------
    121138// Mutate
     
    165182static inline type * name##_impl( __attribute__((unused)) pass_type& pass, __attribute__((unused)) long unused ) { return nullptr;}    \
    166183
    167 FIELD_PTR( TypeSubstitution *, env )
     184FIELD_PTR( const TypeSubstitution *, env )
    168185FIELD_PTR( std::list< Statement* >, stmtsToAddBefore )
    169186FIELD_PTR( std::list< Statement* >, stmtsToAddAfter  )
     
    174191FIELD_PTR( PassVisitor<pass_type> * const, visitor )
    175192
     193#undef FIELD_PTR
     194
    176195//---------------------------------------------------------
    177196// Indexer
     
    198217        pass.indexer.func( arg );                                                                                                \
    199218}                                                                                                                              \
    200                                                                                                                                \
    201 template<typename pass_type>                                                                                                   \
    202 static inline void indexer_impl_##func ( pass_type &, long, type ) { }                                                          \
     219template<typename pass_type>                                                                                                   \
     220static inline void indexer_impl_##func ( pass_type &, long, type ) { }
    203221
    204222#define INDEXER_FUNC2( func, type1, type2 )                                                                                             \
     
    207225        pass.indexer.func( arg1, arg2 );                                                                                                \
    208226}                                                                                                                              \
    209                                                                                                                                \
    210227template<typename pass_type>                                                                                                   \
    211228static inline void indexer_impl_##func ( pass_type &, long, type1, type2 ) { }
    212229
    213230
    214 INDEXER_FUNC1( addId     , DeclarationWithType *       );
    215 INDEXER_FUNC1( addType   , NamedTypeDecl *             );
    216 INDEXER_FUNC1( addStruct , StructDecl *                );
    217 INDEXER_FUNC1( addEnum   , EnumDecl *                  );
    218 INDEXER_FUNC1( addUnion  , UnionDecl *                 );
    219 INDEXER_FUNC1( addTrait  , TraitDecl *                 );
    220 INDEXER_FUNC2( addWith   , std::list< Expression * > &, BaseSyntaxNode * );
    221 
    222 
    223 template<typename pass_type>
    224 static inline auto indexer_impl_addStructFwd( pass_type & pass, int, StructDecl * decl ) -> decltype( pass.indexer.addStruct( decl ), void() ) {
     231INDEXER_FUNC1( addId     , const DeclarationWithType *       );
     232INDEXER_FUNC1( addType   , const NamedTypeDecl *             );
     233INDEXER_FUNC1( addStruct , const StructDecl *                );
     234INDEXER_FUNC1( addEnum   , const EnumDecl *                  );
     235INDEXER_FUNC1( addUnion  , const UnionDecl *                 );
     236INDEXER_FUNC1( addTrait  , const TraitDecl *                 );
     237INDEXER_FUNC2( addWith   , const std::list< Expression * > &, const Declaration * );
     238
     239#undef INDEXER_FUNC1
     240#undef INDEXER_FUNC2
     241
     242template<typename pass_type>
     243static inline auto indexer_impl_addStructFwd( pass_type & pass, int, const StructDecl * decl ) -> decltype( pass.indexer.addStruct( decl ), void() ) {
    225244        StructDecl * fwd = new StructDecl( decl->name );
    226245        cloneAll( decl->parameters, fwd->parameters );
     
    229248
    230249template<typename pass_type>
    231 static inline auto indexer_impl_addStructFwd( pass_type &, long, StructDecl * ) {}
    232 
    233 template<typename pass_type>
    234 static inline auto indexer_impl_addUnionFwd( pass_type & pass, int, UnionDecl * decl ) -> decltype( pass.indexer.addUnion( decl ), void() ) {
     250static inline auto indexer_impl_addStructFwd( pass_type &, long, const StructDecl * ) {}
     251
     252template<typename pass_type>
     253static inline auto indexer_impl_addUnionFwd( pass_type & pass, int, const UnionDecl * decl ) -> decltype( pass.indexer.addUnion( decl ), void() ) {
    235254        UnionDecl * fwd = new UnionDecl( decl->name );
    236255        cloneAll( decl->parameters, fwd->parameters );
     
    239258
    240259template<typename pass_type>
    241 static inline auto indexer_impl_addUnionFwd( pass_type &, long, UnionDecl * ) {}
     260static inline auto indexer_impl_addUnionFwd( pass_type &, long, const UnionDecl * ) {}
    242261
    243262template<typename pass_type>
  • src/Common/ScopedMap.h

    r7951100 rb067d9b  
    2222#include <vector>
    2323
     24/// Default (empty) ScopedMap note type
     25struct EmptyNote {};
     26
    2427/// A map where the items are placed into nested scopes;
    25 /// inserted items are placed into the innermost scope, lookup looks from the innermost scope outward
    26 template<typename Key, typename Value>
     28/// inserted items are placed into the innermost scope, lookup looks from the innermost scope outward.
     29/// Scopes may be annotated with a value; the annotation defaults to empty
     30template<typename Key, typename Value, typename Note = EmptyNote>
    2731class ScopedMap {
    28         typedef std::map< Key, Value > Scope;
     32        typedef std::map< Key, Value > MapType;
     33        struct Scope {
     34                MapType map;
     35                Note note;
     36
     37                template<typename N>
     38                Scope(N&& n) : map(), note(std::forward<N>(n)) {}
     39               
     40                Scope() = default;
     41                Scope(const Scope&) = default;
     42                Scope(Scope&&) = default;
     43                Scope& operator= (const Scope&) = default;
     44                Scope& operator= (Scope&&) = default;
     45        };
    2946        typedef std::vector< Scope > ScopeList;
    3047
    3148        ScopeList scopes; ///< scoped list of maps
    3249public:
    33         typedef typename Scope::key_type key_type;
    34         typedef typename Scope::mapped_type mapped_type;
    35         typedef typename Scope::value_type value_type;
     50        typedef typename MapType::key_type key_type;
     51        typedef typename MapType::mapped_type mapped_type;
     52        typedef typename MapType::value_type value_type;
    3653        typedef typename ScopeList::size_type size_type;
    3754        typedef typename ScopeList::difference_type difference_type;
    38         typedef typename Scope::reference reference;
    39         typedef typename Scope::const_reference const_reference;
    40         typedef typename Scope::pointer pointer;
    41         typedef typename Scope::const_pointer const_pointer;
     55        typedef typename MapType::reference reference;
     56        typedef typename MapType::const_reference const_reference;
     57        typedef typename MapType::pointer pointer;
     58        typedef typename MapType::const_pointer const_pointer;
    4259
    4360        class iterator : public std::iterator< std::bidirectional_iterator_tag,
     
    4562        friend class ScopedMap;
    4663        friend class const_iterator;
    47                 typedef typename std::map< Key, Value >::iterator wrapped_iterator;
    48                 typedef typename std::vector< std::map< Key, Value > > scope_list;
     64                typedef typename ScopedMap::MapType::iterator wrapped_iterator;
     65                typedef typename ScopedMap::ScopeList scope_list;
    4966                typedef typename scope_list::size_type size_type;
    5067
    5168                /// Checks if this iterator points to a valid item
    5269                bool is_valid() const {
    53                         return it != (*scopes)[level].end();
     70                        return it != (*scopes)[level].map.end();
    5471                }
    5572
     
    7996
    8097                iterator& operator++ () {
    81                         if ( it == (*scopes)[level].end() ) {
     98                        if ( it == (*scopes)[level].map.end() ) {
    8299                                if ( level == 0 ) return *this;
    83100                                --level;
    84                                 it = (*scopes)[level].begin();
     101                                it = (*scopes)[level].map.begin();
    85102                        } else {
    86103                                ++it;
     
    92109                iterator& operator-- () {
    93110                        // may fail if this is the begin iterator; allowed by STL spec
    94                         if ( it == (*scopes)[level].begin() ) {
     111                        if ( it == (*scopes)[level].map.begin() ) {
    95112                                ++level;
    96                                 it = (*scopes)[level].end();
     113                                it = (*scopes)[level].map.end();
    97114                        }
    98115                        --it;
     
    107124
    108125                size_type get_level() const { return level; }
     126
     127                Note& get_note() { return (*scopes)[level].note; }
     128                const Note& get_note() const { return (*scopes)[level].note; }
    109129
    110130        private:
     
    117137                                                     value_type > {
    118138        friend class ScopedMap;
    119                 typedef typename std::map< Key, Value >::iterator wrapped_iterator;
    120                 typedef typename std::map< Key, Value >::const_iterator wrapped_const_iterator;
    121                 typedef typename std::vector< std::map< Key, Value > > scope_list;
     139                typedef typename ScopedMap::MapType::iterator wrapped_iterator;
     140                typedef typename ScopedMap::MapType::const_iterator wrapped_const_iterator;
     141                typedef typename ScopedMap::ScopeList scope_list;
    122142                typedef typename scope_list::size_type size_type;
    123143
    124144                /// Checks if this iterator points to a valid item
    125145                bool is_valid() const {
    126                         return it != (*scopes)[level].end();
     146                        return it != (*scopes)[level].map.end();
    127147                }
    128148
     
    157177
    158178                const_iterator& operator++ () {
    159                         if ( it == (*scopes)[level].end() ) {
     179                        if ( it == (*scopes)[level].map.end() ) {
    160180                                if ( level == 0 ) return *this;
    161181                                --level;
    162                                 it = (*scopes)[level].begin();
     182                                it = (*scopes)[level].map.begin();
    163183                        } else {
    164184                                ++it;
     
    170190                const_iterator& operator-- () {
    171191                        // may fail if this is the begin iterator; allowed by STL spec
    172                         if ( it == (*scopes)[level].begin() ) {
     192                        if ( it == (*scopes)[level].map.begin() ) {
    173193                                ++level;
    174                                 it = (*scopes)[level].end();
     194                                it = (*scopes)[level].map.end();
    175195                        }
    176196                        --it;
     
    185205
    186206                size_type get_level() const { return level; }
     207
     208                const Note& get_note() const { return (*scopes)[level].note; }
    187209
    188210        private:
     
    197219        }
    198220
     221        // Starts a new scope with the given note
     222        template<typename N>
     223        void beginScope( N&& n ) {
     224                scopes.emplace_back( std::forward<N>(n) );
     225        }
     226
    199227        /// Ends a scope; invalidates any iterators pointing to elements of that scope
    200228        void endScope() {
     
    204232
    205233        /// Default constructor initializes with one scope
    206         ScopedMap() { beginScope(); }
    207 
    208         iterator begin() { return iterator(scopes, scopes.back().begin(), currentScope()).next_valid(); }
    209         const_iterator begin() const { return const_iterator(scopes, scopes.back().begin(), currentScope()).next_valid(); }
    210         const_iterator cbegin() const { return const_iterator(scopes, scopes.back().begin(), currentScope()).next_valid(); }
    211         iterator end() { return iterator(scopes, scopes[0].end(), 0); }
    212         const_iterator end() const { return const_iterator(scopes, scopes[0].end(), 0); }
    213         const_iterator cend() const { return const_iterator(scopes, scopes[0].end(), 0); }
     234        ScopedMap() : scopes() { beginScope(); }
     235
     236        /// Constructs with a given note on the outermost scope
     237        template<typename N>
     238        ScopedMap( N&& n ) : scopes() { beginScope(std::forward<N>(n)); }
     239
     240        iterator begin() { return iterator(scopes, scopes.back().map.begin(), currentScope()).next_valid(); }
     241        const_iterator begin() const { return const_iterator(scopes, scopes.back().map.begin(), currentScope()).next_valid(); }
     242        const_iterator cbegin() const { return const_iterator(scopes, scopes.back().map.begin(), currentScope()).next_valid(); }
     243        iterator end() { return iterator(scopes, scopes[0].map.end(), 0); }
     244        const_iterator end() const { return const_iterator(scopes, scopes[0].map.end(), 0); }
     245        const_iterator cend() const { return const_iterator(scopes, scopes[0].map.end(), 0); }
    214246
    215247        /// Gets the index of the current scope (counted from 1)
    216248        size_type currentScope() const { return scopes.size() - 1; }
     249
     250        /// Gets the note at the given scope
     251        Note& getNote( size_type i ) { return scopes[i].note; }
     252        const Note& getNote( size_type i ) const { return scopes[i].note; }
    217253
    218254        /// Finds the given key in the outermost scope it occurs; returns end() for none such
    219255        iterator find( const Key &key ) {
    220256                for ( size_type i = scopes.size() - 1; ; --i ) {
    221                         typename Scope::iterator val = scopes[i].find( key );
    222                         if ( val != scopes[i].end() ) return iterator( scopes, val, i );
     257                        typename MapType::iterator val = scopes[i].map.find( key );
     258                        if ( val != scopes[i].map.end() ) return iterator( scopes, val, i );
    223259                        if ( i == 0 ) break;
    224260                }
     
    226262        }
    227263        const_iterator find( const Key &key ) const {
    228                         return const_iterator( const_cast< ScopedMap< Key, Value >* >(this)->find( key ) );
     264                        return const_iterator( const_cast< ScopedMap< Key, Value, Note >* >(this)->find( key ) );
    229265        }
    230266
    231267        /// Finds the given key in the provided scope; returns end() for none such
    232268        iterator findAt( size_type scope, const Key& key ) {
    233                 typename Scope::iterator val = scopes[scope].find( key );
    234                 if ( val != scopes[scope].end() ) return iterator( scopes, val, scope );
     269                typename MapType::iterator val = scopes[scope].map.find( key );
     270                if ( val != scopes[scope].map.end() ) return iterator( scopes, val, scope );
    235271                return end();
    236272        }
    237273        const_iterator findAt( size_type scope, const Key& key ) const {
    238                 return const_iterator( const_cast< ScopedMap< Key, Value >* >(this)->findAt( scope, key ) );
     274                return const_iterator( const_cast< ScopedMap< Key, Value, Note >* >(this)->findAt( scope, key ) );
    239275        }
    240276
     
    243279                if ( it.level == 0 ) return end();
    244280                for ( size_type i = it.level - 1; ; --i ) {
    245                         typename Scope::iterator val = scopes[i].find( key );
    246                         if ( val != scopes[i].end() ) return iterator( scopes, val, i );
     281                        typename MapType::iterator val = scopes[i].map.find( key );
     282                        if ( val != scopes[i].map.end() ) return iterator( scopes, val, i );
    247283                        if ( i == 0 ) break;
    248284                }
     
    250286        }
    251287        const_iterator findNext( const_iterator &it, const Key &key ) const {
    252                         return const_iterator( const_cast< ScopedMap< Key, Value >* >(this)->findNext( it, key ) );
     288                        return const_iterator( const_cast< ScopedMap< Key, Value, Note >* >(this)->findNext( it, key ) );
    253289        }
    254290
     
    256292        template< typename value_type_t >
    257293        std::pair< iterator, bool > insert( value_type_t&& value ) {
    258                 std::pair< typename Scope::iterator, bool > res = scopes.back().insert( std::forward<value_type_t>( value ) );
     294                std::pair< typename MapType::iterator, bool > res = scopes.back().map.insert( std::forward<value_type_t>( value ) );
    259295                return std::make_pair( iterator(scopes, std::move( res.first ), scopes.size()-1), std::move( res.second ) );
    260296        }
     
    262298        template< typename value_type_t >
    263299        std::pair< iterator, bool > insert( iterator at, value_type_t&& value ) {
    264                 Scope& scope = (*at.scopes) [ at.level ];
    265                 std::pair< typename Scope::iterator, bool > res = scope.insert( std::forward<value_type_t>( value ) );
     300                MapType& scope = (*at.scopes)[ at.level ].map;
     301                std::pair< typename MapType::iterator, bool > res = scope.insert( std::forward<value_type_t>( value ) );
    266302                return std::make_pair( iterator(scopes, std::move( res.first ), at.level), std::move( res.second ) );
    267303        }
     
    272308        template< typename value_type_t >
    273309        std::pair< iterator, bool > insertAt( size_type scope, value_type_t&& value ) {
    274                 std::pair< typename Scope::iterator, bool > res = scopes.at(scope).insert( std::forward<value_type_t>( value ) );
     310                std::pair< typename MapType::iterator, bool > res = scopes.at(scope).map.insert( std::forward<value_type_t>( value ) );
    275311                return std::make_pair( iterator(scopes, std::move( res.first ), scope), std::move( res.second ) );
    276312        }
     
    288324
    289325        iterator erase( iterator pos ) {
    290                 Scope& scope = (*pos.scopes) [ pos.level ];
     326                MapType& scope = (*pos.scopes)[ pos.level ].map;
    291327                const typename iterator::wrapped_iterator& new_it = scope.erase( pos.it );
    292328                iterator it( *pos.scopes, new_it, pos.level );
  • src/Common/SemanticError.h

    r7951100 rb067d9b  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed May 16 15:01:23 2018
    13 // Update Count     : 30
     12// Last Modified On : Thu Jul 19 10:09:17 2018
     13// Update Count     : 31
    1414//
    1515
     
    1717
    1818#include "ErrorObjects.h"
     19#include "AST/Node.hpp"
    1920#include <cstring>
    2021
     
    5657        {"reference-conversion"   , "rvalue to reference conversion of rvalue: %s" , Severity::Warn},
    5758        {"qualifiers-zero_t-one_t", "questionable use of type qualifier %s with %s", Severity::Warn},
     59        {"aggregate-forward-decl" , "forward declaration of nested aggregate: %s"  , Severity::Warn},
     60        {"superfluous-decl"       , "declaration does not allocate storage: %s"    , Severity::Warn},
     61        {"gcc-attributes"         , "invalid attribute: %s"                        , Severity::Warn},
    5862};
    5963
     
    6266        RvalueToReferenceConversion,
    6367        BadQualifiersZeroOne,
    64         NUMBER_OF_WARNINGS, //This MUST be the last warning
     68        AggrForwardDecl,
     69        SuperfluousDecl,
     70        GccAttributes,
     71        NUMBER_OF_WARNINGS, // This MUST be the last warning
    6572};
    6673
  • src/Common/Stats/Heap.h

    r7951100 rb067d9b  
    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

    r7951100 rb067d9b  
    1515###############################################################################
    1616
    17 SRC += Common/SemanticError.cc \
    18        Common/UniqueName.cc \
    19        Common/DebugMalloc.cc \
    20        Common/Assert.cc \
    21        Common/Heap.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

    r7951100 rb067d9b  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun May  6 22:24:16 2018
    13 // Update Count     : 40
     12// Last Modified On : Wed Jul 24 14:28:19 2019
     13// Update Count     : 41
    1414//
    1515
    1616#pragma once
    1717
     18#include <cassert>
    1819#include <cctype>
    1920#include <algorithm>
     
    2627#include <string>
    2728#include <type_traits>
    28 
    29 #include <cassert>
     29#include <utility>
     30#include <vector>
    3031
    3132#include "Common/Indenter.h"
     33
     34class Expression;
     35
     36/// bring std::move into global scope
     37using std::move;
     38
     39/// partner to move that copies any copyable type
     40template<typename T>
     41T copy( const T & x ) { return x; }
    3242
    3343template< typename T >
     
    7181
    7282template< typename Container >
    73 void deleteAll( Container &container ) {
    74         for ( typename Container::iterator i = container.begin(); i != container.end(); ++i ) {
    75                 delete *i;
     83void deleteAll( const Container &container ) {
     84        for ( const auto &i : container ) {
     85                delete i;
    7686        } // for
    7787}
     
    142152                return ret;
    143153        } // switch
     154}
     155
     156/// Splice src onto the end of dst, clearing src
     157template< typename T >
     158void splice( std::vector< T > & dst, std::vector< T > & src ) {
     159        dst.reserve( dst.size() + src.size() );
     160        for ( T & x : src ) { dst.emplace_back( std::move( x ) ); }
     161        src.clear();
     162}
     163
     164/// Splice src onto the begining of dst, clearing src
     165template< typename T >
     166void spliceBegin( std::vector< T > & dst, std::vector< T > & src ) {
     167        splice( src, dst );
     168        dst.swap( src );
    144169}
    145170
     
    456481} // ilog2
    457482
     483// -----------------------------------------------------------------------------
     484/// evaluates expr as a long long int. If second is false, expr could not be evaluated
     485std::pair<long long int, bool> eval(const Expression * expr);
     486
     487namespace ast {
     488        class Expr;
     489}
     490
     491std::pair<long long int, bool> eval(const ast::Expr * expr);
     492
     493// -----------------------------------------------------------------------------
     494/// Reorders the input range in-place so that the minimal-value elements according to the
     495/// comparator are in front;
     496/// returns the iterator after the last minimal-value element.
     497template<typename Iter, typename Compare>
     498Iter sort_mins( Iter begin, Iter end, Compare& lt ) {
     499        if ( begin == end ) return end;
     500
     501        Iter min_pos = begin;
     502        for ( Iter i = begin + 1; i != end; ++i ) {
     503                if ( lt( *i, *min_pos ) ) {
     504                        // new minimum cost; swap into first position
     505                        min_pos = begin;
     506                        std::iter_swap( min_pos, i );
     507                } else if ( ! lt( *min_pos, *i ) ) {
     508                        // duplicate minimum cost; swap into next minimum position
     509                        ++min_pos;
     510                        std::iter_swap( min_pos, i );
     511                }
     512        }
     513        return ++min_pos;
     514}
     515
     516template<typename Iter, typename Compare>
     517inline Iter sort_mins( Iter begin, Iter end, Compare&& lt ) {
     518        return sort_mins( begin, end, lt );
     519}
     520
     521/// sort_mins defaulted to use std::less
     522template<typename Iter>
     523inline Iter sort_mins( Iter begin, Iter end ) {
     524        return sort_mins( begin, end, std::less<typename std::iterator_traits<Iter>::value_type>{} );
     525}
    458526
    459527// Local Variables: //
  • src/Concurrency/Keywords.cc

    r7951100 rb067d9b  
    9797                        "__thrd",
    9898                        "get_thread",
    99                         "thread keyword requires threads to be in scope, add #include <thread>",
     99                        "thread keyword requires threads to be in scope, add #include <thread.hfa>",
    100100                        true,
    101101                        KeywordCastExpr::Thread
     
    129129                        "__cor",
    130130                        "get_coroutine",
    131                         "coroutine keyword requires coroutines to be in scope, add #include <coroutine>",
     131                        "coroutine keyword requires coroutines to be in scope, add #include <coroutine.hfa>",
    132132                        true,
    133133                        KeywordCastExpr::Coroutine
     
    161161                        "__mon",
    162162                        "get_monitor",
    163                         "monitor keyword requires monitors to be in scope, add #include <monitor>",
     163                        "monitor keyword requires monitors to be in scope, add #include <monitor.hfa>",
    164164                        false,
    165165                        KeywordCastExpr::Monitor
     
    488488                // Do we have the required headers
    489489                if( !monitor_decl || !guard_decl || !dtor_guard_decl )
    490                         SemanticError( decl, "mutex keyword requires monitors to be in scope, add #include <monitor>\n" );
     490                        SemanticError( decl, "mutex keyword requires monitors to be in scope, add #include <monitor.hfa>\n" );
    491491
    492492                // Instrument the body
     
    501501        void MutexKeyword::postvisit(StructDecl* decl) {
    502502
    503                 if( decl->name == "monitor_desc" ) {
     503                if( decl->name == "monitor_desc" && decl->body ) {
    504504                        assert( !monitor_decl );
    505505                        monitor_decl = decl;
    506506                }
    507                 else if( decl->name == "monitor_guard_t" ) {
     507                else if( decl->name == "monitor_guard_t" && decl->body ) {
    508508                        assert( !guard_decl );
    509509                        guard_decl = decl;
    510510                }
    511                 else if( decl->name == "monitor_dtor_guard_t" ) {
     511                else if( decl->name == "monitor_dtor_guard_t" && decl->body ) {
    512512                        assert( !dtor_guard_decl );
    513513                        dtor_guard_decl = decl;
     
    575575
    576576                //in reverse order :
    577                 // monitor_guard_t __guard = { __monitors, #, func };
     577                // monitor_dtor_guard_t __guard = { __monitors, func };
    578578                body->push_front(
    579579                        new DeclStmt( new ObjectDecl(
     
    634634                assert(generic_func);
    635635
    636                 //in reverse order :
     636                // in reverse order :
    637637                // monitor_guard_t __guard = { __monitors, #, func };
    638638                body->push_front(
     
    685685                if( type && type->get_baseStruct()->is_thread() ) {
    686686                        if( !thread_decl || !thread_ctor_seen ) {
    687                                 SemanticError( type->get_baseStruct()->location, "thread keyword requires threads to be in scope, add #include <thread>");
     687                                SemanticError( type->get_baseStruct()->location, "thread keyword requires threads to be in scope, add #include <thread.hfa>");
    688688                        }
    689689
  • src/Concurrency/Waitfor.cc

    r7951100 rb067d9b  
    1111// Last Modified By :
    1212// Last Modified On :
    13 // Update Count     : 5
     13// Update Count     : 7
    1414//
    1515
     
    6666void foo() {
    6767        while( true ) {
    68 
    69                 acceptable_t acceptables[3];
    70                 if( a < 1 ) {
    71                         acceptables[0].func = f;
    72                         acceptables[0].mon = a;
    73                 }
    74                 acceptables[1].func = g;
    75                 acceptables[1].mon = a;
    76 
    77                 acceptables[2].func = f;
    78                 acceptables[2].mon = a;
    79                 acceptables[2].is_dtor = true;
    80 
    81                 int ret = waitfor_internal( acceptables, swagl() );
    82 
    83                 switch( ret ) {
    84                         case 0:
    85                         {
    86                                 bar();
     68                {
     69                        acceptable_t acceptables[3];
     70                        if( a < 1 ) {
     71                                acceptables[0].func = f;
     72                                acceptables[0].mon = a;
    8773                        }
    88                         case 1:
    89                         {
    90                                 baz();
     74                        acceptables[1].func = g;
     75                        acceptables[1].mon = a;
     76
     77                        acceptables[2].func = f;
     78                        acceptables[2].mon = a;
     79                        acceptables[2].is_dtor = true;
     80
     81                        int ret = waitfor_internal( acceptables, swagl() );
     82
     83                        switch( ret ) {
     84                                case 0:
     85                                {
     86                                        bar();
     87                                }
     88                                case 1:
     89                                {
     90                                        baz();
     91                                }
     92                                case 2:
     93                                        signal(a);
     94                                        {
     95                                                break;
     96                                        }
    9197                        }
    92                         case 2:
    93                                 signal(a);
    94                                 {
    95                                         break;
    96                                 }
    9798                }
    9899        }
     
    250251        Statement * GenerateWaitForPass::postmutate( WaitForStmt * waitfor ) {
    251252                if( !decl_monitor || !decl_acceptable || !decl_mask )
    252                         SemanticError( waitfor, "waitfor keyword requires monitors to be in scope, add #include <monitor>" );
     253                        SemanticError( waitfor, "waitfor keyword requires monitors to be in scope, add #include <monitor.hfa>" );
    253254
    254255                CompoundStmt * stmt = new CompoundStmt();
     
    555556                                        new ConstantExpr( Constant::from_ulong( i++ ) ),
    556557                                        {
    557                                                 clause.statement,
    558                                                 new BranchStmt(
    559                                                         "",
    560                                                         BranchStmt::Break
    561                                                 )
     558                                                new CompoundStmt({
     559                                                        clause.statement,
     560                                                        new BranchStmt(
     561                                                                "",
     562                                                                BranchStmt::Break
     563                                                        )
     564                                                })
    562565                                        }
    563566                                )
     
    570573                                        new ConstantExpr( Constant::from_int( -2 ) ),
    571574                                        {
    572                                                 waitfor->timeout.statement,
    573                                                 new BranchStmt(
    574                                                         "",
    575                                                         BranchStmt::Break
    576                                                 )
     575                                                new CompoundStmt({
     576                                                        waitfor->timeout.statement,
     577                                                        new BranchStmt(
     578                                                                "",
     579                                                                BranchStmt::Break
     580                                                        )
     581                                                })
    577582                                        }
    578583                                )
     
    585590                                        new ConstantExpr( Constant::from_int( -1 ) ),
    586591                                        {
    587                                                 waitfor->orelse.statement,
    588                                                 new BranchStmt(
    589                                                         "",
    590                                                         BranchStmt::Break
    591                                                 )
     592                                                new CompoundStmt({
     593                                                        waitfor->orelse.statement,
     594                                                        new BranchStmt(
     595                                                                "",
     596                                                                BranchStmt::Break
     597                                                        )
     598                                                })
    592599                                        }
    593600                                )
  • src/Concurrency/module.mk

    r7951100 rb067d9b  
    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

    r7951100 rb067d9b  
    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
     
    319319                        }
    320320
    321                         block->push_back( handler->get_body() );
    322                         handler->set_body( nullptr );
     321                        block->push_back( handler->body );
     322                        handler->body = nullptr;
    323323
    324324                        std::list<Statement *> caseBody
     
    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

    r7951100 rb067d9b  
    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

    r7951100 rb067d9b  
    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

    r7951100 rb067d9b  
    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/MLEMutator.cc

    r7951100 rb067d9b  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Mar  8 17:08:25 2018
    13 // Update Count     : 219
     12// Last Modified On : Tue Oct 22 17:22:44 2019
     13// Update Count     : 220
    1414//
    1515
     
    313313        }
    314314
     315        void MLEMutator::premutate( TryStmt * tryStmt ) {
     316                // generate a label for breaking out of a labeled if
     317                bool labeledBlock = !(tryStmt->get_labels().empty());
     318                if ( labeledBlock ) {
     319                        Label brkLabel = generator->newLabel("blockBreak", tryStmt);
     320                        enclosingControlStructures.push_back( Entry( tryStmt, brkLabel ) );
     321                        GuardAction( [this]() { enclosingControlStructures.pop_back(); } );
     322                } // if
     323        }
     324
     325        Statement * MLEMutator::postmutate( TryStmt * tryStmt ) {
     326                bool labeledBlock = !(tryStmt->get_labels().empty());
     327                if ( labeledBlock ) {
     328                        if ( ! enclosingControlStructures.back().useBreakExit().empty() ) {
     329                                set_breakLabel( enclosingControlStructures.back().useBreakExit() );
     330                        } // if
     331                } // if
     332                return tryStmt;
     333        }
     334
    315335        void MLEMutator::premutate( CaseStmt *caseStmt ) {
    316336                visit_children = false;
  • src/ControlStruct/MLEMutator.h

    r7951100 rb067d9b  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Mar  8 16:42:32 2018
    13 // Update Count     : 41
     12// Last Modified On : Tue Oct 22 17:22:47 2019
     13// Update Count     : 45
    1414//
    1515
     
    4747                void premutate( SwitchStmt *switchStmt );
    4848                Statement * postmutate( SwitchStmt *switchStmt );
     49                void premutate( TryStmt *tryStmt );
     50                Statement * postmutate( TryStmt *tryStmt );
    4951
    5052                Statement *mutateLoop( Statement *bodyLoop, Entry &e );
     
    7375                        explicit Entry( SwitchStmt *stmt, Label breakExit, Label fallDefaultExit ) :
    7476                                stmt( stmt ), breakExit( breakExit ), fallDefaultExit( fallDefaultExit ) {}
     77
     78                        explicit Entry( TryStmt *stmt, Label breakExit ) :
     79                                stmt( stmt ), breakExit( breakExit ) {}
    7580
    7681                        bool operator==( const Statement *other ) { return stmt == other; }
  • src/ControlStruct/module.mk

    r7951100 rb067d9b  
    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

    r7951100 rb067d9b  
    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();
     
    657657                                paramExpr = new AddressExpr( paramExpr );
    658658                        } // if
    659                         arg = appExpr->get_args().insert( arg, paramExpr ); // add argument to function call
     659                        arg = appExpr->args.insert( arg, paramExpr ); // add argument to function call
    660660                        arg++;
    661661                        // Build a comma expression to call the function and emulate a normal return.
    662662                        CommaExpr *commaExpr = new CommaExpr( appExpr, retExpr );
    663                         commaExpr->set_env( appExpr->get_env() );
    664                         appExpr->set_env( 0 );
     663                        commaExpr->env = appExpr->env;
     664                        appExpr->env = nullptr;
    665665                        return commaExpr;
    666666                }
     
    708708//                      if ( ! function->get_returnVals().empty() && isPolyType( function->get_returnVals().front()->get_type(), tyVars ) ) {
    709709                        if ( isDynRet( function, tyVars ) ) {
    710                                 ret = addRetParam( appExpr, function->get_returnVals().front()->get_type(), arg );
     710                                ret = addRetParam( appExpr, function->returnVals.front()->get_type(), arg );
    711711                        } // if
    712712                        std::string mangleName = mangleAdapterName( function, tyVars );
     
    715715                        // cast adaptee to void (*)(), since it may have any type inside a polymorphic function
    716716                        Type * adapteeType = new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) );
    717                         appExpr->get_args().push_front( new CastExpr( appExpr->get_function(), adapteeType ) );
     717                        appExpr->get_args().push_front( new CastExpr( appExpr->function, adapteeType ) );
    718718                        appExpr->set_function( new NameExpr( adapterName ) ); // xxx - result is never set on NameExpr
    719719
     
    725725                        if ( ! needsBoxing( param, arg->result, exprTyVars, env ) ) return;
    726726
    727                         if ( arg->result->get_lvalue() ) {
     727                        if ( arg->get_lvalue() ) {
    728728                                // argument expression may be CFA lvalue, but not C lvalue -- apply generalizedLvalue transformations.
    729729                                // if ( VariableExpr * varExpr = dynamic_cast< VariableExpr * >( arg ) ) {
     
    798798                        for ( Type::ForallList::iterator tyVar = functionType->get_forall().begin(); tyVar != functionType->get_forall().end(); ++tyVar ) {
    799799                                for ( std::list< DeclarationWithType *>::iterator assert = (*tyVar)->assertions.begin(); assert != (*tyVar)->assertions.end(); ++assert ) {
    800                                         InferredParams::const_iterator inferParam = appExpr->get_inferParams().find( (*assert)->get_uniqueId() );
    801                                         assertf( inferParam != appExpr->get_inferParams().end(), "addInferredParams missing inferred parameter: %s in: %s", toString( *assert ).c_str(), toString( appExpr ).c_str() );
     800                                        InferredParams::const_iterator inferParam = appExpr->inferParams.find( (*assert)->get_uniqueId() );
     801                                        assertf( inferParam != appExpr->inferParams.end(), "addInferredParams missing inferred parameter: %s in: %s", toString( *assert ).c_str(), toString( appExpr ).c_str() );
    802802                                        Expression *newExpr = inferParam->second.expr->clone();
    803803                                        addCast( newExpr, (*assert)->get_type(), tyVars );
     
    837837                                        deref->args.push_back( new CastExpr( new VariableExpr( param ), new PointerType( Type::Qualifiers(), arg->get_type()->clone() ) ) );
    838838                                        deref->result = arg->get_type()->clone();
    839                                         deref->result->set_lvalue( true );
    840839                                        return deref;
    841840                                } // if
     
    17641763
    17651764                Expression *PolyGenericCalculator::postmutate( SizeofExpr *sizeofExpr ) {
    1766                         Type *ty = sizeofExpr->get_isType() ? 
     1765                        Type *ty = sizeofExpr->get_isType() ?
    17671766                                sizeofExpr->get_type() : sizeofExpr->get_expr()->get_result();
    1768                        
     1767
    17691768                        Expression * gen = genSizeof( ty );
    17701769                        if ( gen ) {
  • src/GenPoly/GenPoly.cc

    r7951100 rb067d9b  
    2424#include <vector>                       // for vector
    2525
     26#include "AST/Type.hpp"
    2627#include "GenPoly/ErasableScopedMap.h"  // for ErasableScopedMap<>::const_it...
    2728#include "ResolvExpr/typeops.h"         // for flatten
     
    262263                } else {
    263264                        return dynamic_cast< FunctionType* >( ty ); // pointer if FunctionType, NULL otherwise
     265                }
     266        }
     267
     268        const ast::FunctionType * getFunctionType( const ast::Type * ty ) {
     269                if ( auto pty = dynamic_cast< const ast::PointerType * >( ty ) ) {
     270                        return pty->base.as< ast::FunctionType >();
     271                } else {
     272                        return dynamic_cast< const ast::FunctionType * >( ty );
    264273                }
    265274        }
     
    440449        }
    441450
    442         bool needsBoxing( Type * param, Type * arg, const TyVarMap &exprTyVars, TypeSubstitution * env ) {
     451        bool needsBoxing( Type * param, Type * arg, const TyVarMap &exprTyVars, const TypeSubstitution * env ) {
    443452                // is parameter is not polymorphic, don't need to box
    444453                if ( ! isPolyType( param, exprTyVars ) ) return false;
     
    450459        }
    451460
    452         bool needsBoxing( Type * param, Type * arg, ApplicationExpr * appExpr, TypeSubstitution * env ) {
     461        bool needsBoxing( Type * param, Type * arg, ApplicationExpr * appExpr, const TypeSubstitution * env ) {
    453462                FunctionType * function = getFunctionType( appExpr->function->result );
    454463                assertf( function, "ApplicationExpr has non-function type: %s", toString( appExpr->function->result ).c_str() );
     
    459468
    460469        void addToTyVarMap( TypeDecl * tyVar, TyVarMap &tyVarMap ) {
    461                 // xxx - should this actually be insert?
    462                 tyVarMap[ tyVar->get_name() ] = TypeDecl::Data{ tyVar };
     470                tyVarMap.insert( tyVar->name, TypeDecl::Data{ tyVar } );
    463471        }
    464472
  • src/GenPoly/GenPoly.h

    r7951100 rb067d9b  
    2020
    2121#include "ErasableScopedMap.h"    // for ErasableScopedMap
     22#include "AST/Fwd.hpp"
    2223#include "SymTab/Mangler.h"       // for Mangler
    2324#include "SynTree/Declaration.h"  // for TypeDecl::Data, AggregateDecl, Type...
     
    7273        /// Returns a pointer to the base FunctionType if ty is the type of a function (or pointer to one), NULL otherwise
    7374        FunctionType *getFunctionType( Type *ty );
     75        const ast::FunctionType * getFunctionType( const ast::Type * ty );
    7476
    7577        /// If expr (after dereferencing N >= 0 pointers) is a variable expression, returns the variable expression, NULL otherwise;
     
    8183
    8284        /// true if arg requires boxing given exprTyVars
    83         bool needsBoxing( Type * param, Type * arg, const TyVarMap &exprTyVars, TypeSubstitution * env );
     85        bool needsBoxing( Type * param, Type * arg, const TyVarMap &exprTyVars, const TypeSubstitution * env );
    8486
    8587        /// true if arg requires boxing in the call to appExpr
    86         bool needsBoxing( Type * param, Type * arg, ApplicationExpr * appExpr, TypeSubstitution * env );
     88        bool needsBoxing( Type * param, Type * arg, ApplicationExpr * appExpr, const TypeSubstitution * env );
    8789
    8890        /// Adds the type variable `tyVar` to `tyVarMap`
  • src/GenPoly/InstantiateGeneric.cc

    r7951100 rb067d9b  
    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/Lvalue.cc

    r7951100 rb067d9b  
    2121#include "Lvalue.h"
    2222
     23#include "InitTweak/InitTweak.h"
    2324#include "Parser/LinkageSpec.h"          // for Spec, isBuiltin, Intrinsic
    2425#include "ResolvExpr/TypeEnvironment.h"  // for AssertionSet, OpenVarSet
    2526#include "ResolvExpr/Unify.h"            // for unify
    2627#include "ResolvExpr/typeops.h"
    27 #include "SymTab/Autogen.h"
    2828#include "SymTab/Indexer.h"              // for Indexer
    2929#include "SynTree/Declaration.h"         // for Declaration, FunctionDecl
     
    3333#include "SynTree/Type.h"                // for PointerType, Type, FunctionType
    3434#include "SynTree/Visitor.h"             // for Visitor, acceptAll
     35#include "Validate/FindSpecialDecls.h"   // for dereferenceOperator
    3536
    3637#if 0
     
    4445                // TODO: fold this into the general createDeref function??
    4546                Expression * mkDeref( Expression * arg ) {
    46                         if ( SymTab::dereferenceOperator ) {
     47                        if ( Validate::dereferenceOperator ) {
    4748                                // note: reference depth can be arbitrarily deep here, so peel off the outermost pointer/reference, not just pointer because they are effecitvely equivalent in this pass
    48                                 VariableExpr * deref = new VariableExpr( SymTab::dereferenceOperator );
     49                                VariableExpr * deref = new VariableExpr( Validate::dereferenceOperator );
    4950                                deref->result = new PointerType( Type::Qualifiers(), deref->result );
    5051                                Type * base = InitTweak::getPointerBase( arg->result );
     
    5354                                delete ret->result;
    5455                                ret->result = base->clone();
    55                                 ret->result->set_lvalue( true );
    5656                                return ret;
    5757                        } else {
     
    146146
    147147        namespace {
    148                 // true for intrinsic function calls that return a reference
     148                // true for intrinsic function calls that return an lvalue in C
    149149                bool isIntrinsicReference( Expression * expr ) {
     150                        // known intrinsic-reference prelude functions
     151                        static std::set<std::string> lvalueFunctions = { "*?", "?[?]" };
    150152                        if ( UntypedExpr * untyped = dynamic_cast< UntypedExpr * >( expr ) ) {
    151153                                std::string fname = InitTweak::getFunctionName( untyped );
    152                                 // known intrinsic-reference prelude functions
    153                                 return fname == "*?" || fname == "?[?]";
     154                                return lvalueFunctions.count(fname);
    154155                        } else if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * > ( expr ) ) {
    155156                                if ( DeclarationWithType * func = InitTweak::getFunction( appExpr ) ) {
    156                                         // use type of return variable rather than expr result type, since it may have been changed to a pointer type
    157                                         FunctionType * ftype = GenPoly::getFunctionType( func->get_type() );
    158                                         Type * ret = ftype->returnVals.empty() ? nullptr : ftype->returnVals.front()->get_type();
    159                                         return func->linkage == LinkageSpec::Intrinsic && dynamic_cast<ReferenceType *>( ret );
     157                                        return func->linkage == LinkageSpec::Intrinsic && lvalueFunctions.count(func->name);
    160158                                }
    161159                        }
     
    168166                                ReferenceType * result = strict_dynamic_cast< ReferenceType * >( appExpr->result );
    169167                                appExpr->result = result->base->clone();
    170                                 appExpr->result->set_lvalue( true );
    171168                                if ( ! inIntrinsic ) {
    172169                                        // when not in an intrinsic function, add a cast to
     
    197194                                unsigned int i = 0;
    198195                                const unsigned int end = ftype->parameters.size();
     196
     197                                /// The for loop may eagerly dereference the iterators and fail on empty lists
     198                                if(i == end) { return appExpr; }
    199199                                for ( auto p : unsafe_group_iterate( appExpr->args, ftype->parameters ) ) {
    200                                         if (i == end) break;
    201200                                        Expression *& arg = std::get<0>( p );
    202201                                        Type * formal = std::get<1>( p )->get_type();
     
    212211                                                // TODO: it's likely that the second condition should be ... && ! isIntrinsicReference( arg ), but this requires investigation.
    213212
    214                                                 if ( function->get_linkage() != LinkageSpec::Intrinsic && isIntrinsicReference( arg ) ) {
     213                                                if ( function->linkage != LinkageSpec::Intrinsic && isIntrinsicReference( arg ) ) {
    215214                                                        // needed for definition of prelude functions, etc.
    216215                                                        // if argument is dereference or array subscript, the result isn't REALLY a reference, but non-intrinsic functions expect a reference: take address
     
    228227                                                        arg = new AddressExpr( arg );
    229228                                                // } else if ( function->get_linkage() == LinkageSpec::Intrinsic && InitTweak::getPointerBase( arg->result ) ) {
    230                                                 } else if ( function->get_linkage() == LinkageSpec::Intrinsic && arg->result->referenceDepth() != 0 ) {
     229                                                } else if ( function->linkage == LinkageSpec::Intrinsic && arg->result->referenceDepth() != 0 ) {
    231230                                                        // argument is a 'real' reference, but function expects a C lvalue: add a dereference to the reference-typed argument
    232231                                                        PRINT(
     
    243242                                        }
    244243                                        ++i;
     244                                        if (i == end) break;
    245245                                }
    246246                        }
     
    355355                        Type * destType = castExpr->result;
    356356                        Type * srcType = castExpr->arg->result;
     357                        assertf( destType, "Cast to no type in: %s", toCString( castExpr ) );
     358                        assertf( srcType, "Cast from no type in: %s", toCString( castExpr ) );
    357359                        int depth1 = destType->referenceDepth();
    358360                        int depth2 = srcType->referenceDepth();
    359361                        int diff = depth1 - depth2;
    360362
    361                         if ( diff > 0 && ! srcType->get_lvalue() ) {
     363                        if ( diff > 0 && ! castExpr->arg->get_lvalue() ) {
    362364                                // rvalue to reference conversion -- introduce temporary
    363365                                // know that reference depth of cast argument is 0, need to introduce n temporaries for reference depth of n, e.g.
     
    403405                                        ret = new AddressExpr( ret );
    404406                                }
    405                                 if ( srcType->get_lvalue() && ! ResolvExpr::typesCompatible( srcType, strict_dynamic_cast<ReferenceType *>( destType )->base, SymTab::Indexer() ) ) {
     407                                if ( castExpr->arg->get_lvalue() && ! ResolvExpr::typesCompatible( srcType, strict_dynamic_cast<ReferenceType *>( destType )->base, SymTab::Indexer() ) ) {
    406408                                        // must keep cast if cast-to type is different from the actual type
    407409                                        castExpr->arg = ret;
     
    432434                                delete ret->result;
    433435                                ret->result = castExpr->result;
    434                                 ret->result->set_lvalue( true ); // ensure result is lvalue
     436                                assert( ret->get_lvalue() ); // ensure result is lvalue
    435437                                castExpr->env = nullptr;
    436438                                castExpr->arg = nullptr;
  • src/GenPoly/ScopedSet.h

    r7951100 rb067d9b  
    3838                typedef typename Scope::pointer pointer;
    3939                typedef typename Scope::const_pointer const_pointer;
    40                
     40
    4141                class iterator : public std::iterator< std::bidirectional_iterator_tag,
    4242                                                       value_type > {
     
    7272                                return *this;
    7373                        }
    74                        
     74
    7575                        reference operator* () { return *it; }
    7676                        pointer operator-> () { return it.operator->(); }
     
    104104                        bool operator!= (const iterator &that) { return !( *this == that ); }
    105105
     106                        size_type get_level() const { return i; }
     107
    106108                private:
    107109                        scope_list const *scopes;
     
    180182                        bool operator!= (const const_iterator &that) { return !( *this == that ); }
    181183
     184                        size_type get_level() const { return i; }
     185
    182186                private:
    183187                        scope_list const *scopes;
     
    185189                        size_type i;
    186190                };
    187                
     191
    188192                /// Starts a new scope
    189193                void beginScope() {
     
    222226                        return const_iterator( const_cast< ScopedSet< Value >* >(this)->find( key ) );
    223227                }
    224                
     228
    225229                /// Finds the given key in the outermost scope inside the given scope where it occurs
    226230                iterator findNext( const_iterator &it, const Value &key ) {
     
    242246                        return std::make_pair( iterator(scopes, res.first, scopes.size()-1), res.second );
    243247                }
    244                
     248
    245249        };
    246250} // namespace GenPoly
  • src/GenPoly/ScrubTyVars.cc

    r7951100 rb067d9b  
    5050                                delete typeInst;
    5151                                return new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) );
     52                          default:
     53                                assertf(false, "Unhandled tyvar kind: %d", tyVar->second.kind);
    5254                        } // switch
    5355                } // if
  • src/GenPoly/Specialize.cc

    r7951100 rb067d9b  
    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        }
     
    245245                appExpr->env = TypeSubstitution::newFromExpr( appExpr, env );
    246246                if ( inferParams ) {
    247                         appExpr->get_inferParams() = *inferParams;
     247                        appExpr->inferParams = *inferParams;
    248248                } // if
    249249
     
    284284                std::list< Expression* >::iterator actual;
    285285                for ( formal = function->get_parameters().begin(), actual = appExpr->get_args().begin(); formal != function->get_parameters().end() && actual != appExpr->get_args().end(); ++formal, ++actual ) {
    286                         *actual = doSpecialization( (*formal)->get_type(), *actual, &appExpr->get_inferParams() );
     286                        *actual = doSpecialization( (*formal)->get_type(), *actual, &appExpr->inferParams );
    287287                }
    288288        }
     
    295295                        // alternatively, if order starts to matter then copy appExpr's inferParams and pass them to handleExplicitParams.
    296296                        handleExplicitParams( appExpr );
    297                         for ( InferredParams::iterator inferParam = appExpr->get_inferParams().begin(); inferParam != appExpr->get_inferParams().end(); ++inferParam ) {
    298                                 inferParam->second.expr = doSpecialization( inferParam->second.formalType, inferParam->second.expr, inferParam->second.inferParams.get() );
     297                        for ( InferredParams::iterator inferParam = appExpr->inferParams.begin(); inferParam != appExpr->inferParams.end(); ++inferParam ) {
     298                                inferParam->second.expr = doSpecialization( inferParam->second.formalType, inferParam->second.expr, &inferParam->second.expr->inferParams );
    299299                        }
    300300                }
  • src/GenPoly/module.mk

    r7951100 rb067d9b  
    2222       GenPoly/FindFunction.cc \
    2323       GenPoly/InstantiateGeneric.cc
     24
     25SRCDEMANGLE += GenPoly/GenPoly.cc GenPoly/Lvalue.cc
     26
  • src/InitTweak/FixGlobalInit.cc

    r7951100 rb067d9b  
    3737        class GlobalFixer : public WithShortCircuiting {
    3838          public:
    39                 GlobalFixer( const std::string & name, bool inLibrary );
     39                GlobalFixer( bool inLibrary );
    4040
    4141                void previsit( ObjectDecl *objDecl );
     
    5252        };
    5353
    54         void fixGlobalInit( std::list< Declaration * > & translationUnit, const std::string & name, bool inLibrary ) {
    55                 PassVisitor<GlobalFixer> visitor( name, inLibrary );
     54        void fixGlobalInit( std::list< Declaration * > & translationUnit, bool inLibrary ) {
     55                PassVisitor<GlobalFixer> visitor( inLibrary );
    5656                acceptAll( translationUnit, visitor );
    5757                GlobalFixer & fixer = visitor.pass;
     
    7070        }
    7171
    72   std::string globalFunctionName( const std::string & name ) {
    73         // get basename
    74         std::string ret = name.substr( 0, name.find( '.' ) );
    75         // replace invalid characters with _
    76                 static std::string invalid = "/-";
    77         replace_if( ret.begin(), ret.end(), []( char c ) { return invalid.find(c) != std::string::npos; }, '_' );
    78         return ret;
    79   }
    80 
    81         GlobalFixer::GlobalFixer( const std::string & name, bool inLibrary ) : tempNamer( "_global_init" ) {
    82                 std::string fixedName = globalFunctionName( name );
     72        GlobalFixer::GlobalFixer( bool inLibrary ) : tempNamer( "_global_init" ) {
    8373                std::list< Expression * > ctorParameters;
    8474                std::list< Expression * > dtorParameters;
     
    9080                        // for library code are run before constructors and destructors for user code,
    9181                        // specify a priority when building the library. Priorities 0-100 are reserved by gcc.
    92                         ctorParameters.push_back( new ConstantExpr( Constant::from_int( 102 ) ) );
    93                         dtorParameters.push_back( new ConstantExpr( Constant::from_int( 102 ) ) );
     82                        // Priorities 101-200 are reserved by cfa, so use priority 200 for CFA library globals,
     83                        // allowing room for overriding with a higher priority.
     84                        ctorParameters.push_back( new ConstantExpr( Constant::from_int( 200 ) ) );
     85                        dtorParameters.push_back( new ConstantExpr( Constant::from_int( 200 ) ) );
    9486                }
    95                 initFunction = new FunctionDecl( "_init_" + fixedName, Type::StorageClasses( Type::Static ), LinkageSpec::C, new FunctionType( Type::Qualifiers(), false ), new CompoundStmt() );
     87                initFunction = new FunctionDecl( "__global_init__", Type::StorageClasses( Type::Static ), LinkageSpec::C, new FunctionType( Type::Qualifiers(), false ), new CompoundStmt() );
    9688                initFunction->get_attributes().push_back( new Attribute( "constructor", ctorParameters ) );
    97                 destroyFunction = new FunctionDecl( "_destroy_" + fixedName, Type::StorageClasses( Type::Static ), LinkageSpec::C, new FunctionType( Type::Qualifiers(), false ), new CompoundStmt() );
     89                destroyFunction = new FunctionDecl( "__global_destroy__", Type::StorageClasses( Type::Static ), LinkageSpec::C, new FunctionType( Type::Qualifiers(), false ), new CompoundStmt() );
    9890                destroyFunction->get_attributes().push_back( new Attribute( "destructor", dtorParameters ) );
    9991        }
     
    110102                if ( ConstructorInit * ctorInit = dynamic_cast< ConstructorInit * >( objDecl->get_init() ) ) {
    111103                        // a decision should have been made by the resolver, so ctor and init are not both non-NULL
    112                         assert( ! ctorInit->get_ctor() || ! ctorInit->get_init() );
     104                        assert( ! ctorInit->ctor || ! ctorInit->init );
    113105
    114                         Statement * dtor = ctorInit->get_dtor();
     106                        Statement * dtor = ctorInit->dtor;
    115107                        if ( dtor && ! isIntrinsicSingleArgCallStmt( dtor ) ) {
    116108                                // don't need to call intrinsic dtor, because it does nothing, but
    117109                                // non-intrinsic dtors must be called
    118110                                destroyStatements.push_front( dtor );
    119                                 ctorInit->set_dtor( NULL );
     111                                ctorInit->dtor = nullptr;
    120112                        } // if
    121                         if ( Statement * ctor = ctorInit->get_ctor() ) {
     113                        if ( Statement * ctor = ctorInit->ctor ) {
    122114                                initStatements.push_back( ctor );
    123                                 objDecl->set_init( NULL );
    124                                 ctorInit->set_ctor( NULL );
    125                         } else if ( Initializer * init = ctorInit->get_init() ) {
    126                                 objDecl->set_init( init );
    127                                 ctorInit->set_init( NULL );
     115                                objDecl->init = nullptr;
     116                                ctorInit->ctor = nullptr;
     117                        } else if ( Initializer * init = ctorInit->init ) {
     118                                objDecl->init = init;
     119                                ctorInit->init = nullptr;
    128120                        } else {
    129121                                // no constructor and no initializer, which is okay
    130                                 objDecl->set_init( NULL );
     122                                objDecl->init = nullptr;
    131123                        } // if
    132124                        delete ctorInit;
  • src/InitTweak/FixGlobalInit.h

    r7951100 rb067d9b  
    2222
    2323namespace InitTweak {
    24   /// Moves global initialization into an _init function that is unique to the translation unit.
    25   /// Sets the priority of the initialization function depending on whether the initialization
    26   /// function is for library code.
    27   void fixGlobalInit( std::list< Declaration * > & translationUnit, const std::string & name, bool inLibrary );
    28 
    29   /// Apply transformations to a file name to get a valid C identifier which will be used as
    30   /// the name of the generated initializer function.
    31   std::string globalFunctionName( const std::string & name );
     24        /// Moves global initialization into an _init function that is unique to the translation unit.
     25        /// Sets the priority of the initialization function depending on whether the initialization
     26        /// function is for library code.
     27        void fixGlobalInit( std::list< Declaration * > & translationUnit, bool inLibrary );
    3228} // namespace
    3329
  • src/InitTweak/FixInit.cc

    r7951100 rb067d9b  
    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"
     
    5454#include "SynTree/Type.h"              // for Type, Type::StorageClasses
    5555#include "SynTree/TypeSubstitution.h"  // for TypeSubstitution, operator<<
     56#include "SynTree/DeclReplacer.h"      // for DeclReplacer
    5657#include "SynTree/Visitor.h"           // for acceptAll, maybeAccept
     58#include "Validate/FindSpecialDecls.h" // for dtorStmt, dtorStructDestroy
    5759
    5860bool ctordtorp = false; // print all debug
     
    6668namespace InitTweak {
    6769        namespace {
    68                 typedef std::unordered_map< int, int > UnqCount;
    69 
    7070                struct SelfAssignChecker {
    7171                        void previsit( ApplicationExpr * appExpr );
    7272                };
    7373
    74                 struct InsertImplicitCalls : public WithTypeSubstitution {
     74                struct StmtExprResult {
     75                        static void link( std::list< Declaration * > & translationUnit );
     76
     77                        void previsit( StmtExpr * stmtExpr );
     78                };
     79
     80                struct InsertImplicitCalls : public WithConstTypeSubstitution {
    7581                        /// wrap function application expressions as ImplicitCopyCtorExpr nodes so that it is easy to identify which
    7682                        /// function calls need their parameters to be copy constructed
     
    8086                };
    8187
    82                 struct ResolveCopyCtors final : public WithIndexer, public WithShortCircuiting, public WithTypeSubstitution {
     88                struct ResolveCopyCtors final : public WithStmtsToAdd, public WithIndexer, public WithShortCircuiting, public WithTypeSubstitution, public WithVisitorRef<ResolveCopyCtors> {
    8389                        /// generate temporary ObjectDecls for each argument and return value of each ImplicitCopyCtorExpr,
    8490                        /// generate/resolve copy construction expressions for each, and generate/resolve destructors for both
    8591                        /// arguments and return value temporaries
    86                         static void resolveImplicitCalls( std::list< Declaration * > & translationUnit, UnqCount & unqCount );
    87 
    88                         ResolveCopyCtors( UnqCount & unqCount ) : unqCount( unqCount ) {}
    89 
    90                         void postvisit( ImplicitCopyCtorExpr * impCpCtorExpr );
    91                         void postvisit( StmtExpr * stmtExpr );
    92                         void previsit( UniqueExpr * unqExpr );
    93                         void postvisit( UniqueExpr * unqExpr );
     92                        static void resolveImplicitCalls( std::list< Declaration * > & translationUnit );
     93
     94                        Expression * postmutate( ImplicitCopyCtorExpr * impCpCtorExpr );
     95                        void premutate( StmtExpr * stmtExpr );
     96                        void premutate( UniqueExpr * unqExpr );
    9497
    9598                        /// create and resolve ctor/dtor expression: fname(var, [cpArg])
     
    98101                        bool skipCopyConstruct( Type * type );
    99102                        void copyConstructArg( Expression *& arg, ImplicitCopyCtorExpr * impCpCtorExpr, Type * formal );
    100                         void destructRet( ObjectDecl * ret, ImplicitCopyCtorExpr * impCpCtorExpr );
    101 
    102                         UnqCount & unqCount; // count the number of times each unique expr ID appears
    103                         std::unordered_set< int > vars;
     103                        void destructRet( ObjectDecl * ret, ImplicitCopyCtorExpr * impCpCtorExpr, Expression *& arg );
    104104                };
    105105
     
    162162                        using Parent::previsit;
    163163
    164                         void previsit( ObjectDecl * objDecl );
    165164                        void previsit( FunctionDecl * funcDecl );
    166165
    167                         void previsit( CompoundStmt * compoundStmt );
    168                         void postvisit( CompoundStmt * compoundStmt );
    169                         void previsit( ReturnStmt * returnStmt );
    170166                        void previsit( BranchStmt * stmt );
    171167                private:
     
    185181
    186182                        std::list< Declaration * > staticDtorDecls;
    187                 };
    188 
    189                 class FixCopyCtors final : public WithStmtsToAdd, public WithShortCircuiting, public WithVisitorRef<FixCopyCtors>, public WithTypeSubstitution {
    190                   public:
    191                         FixCopyCtors( UnqCount & unqCount ) : unqCount( unqCount ){}
    192                         /// expand ImplicitCopyCtorExpr nodes into the temporary declarations, copy constructors, call expression,
    193                         /// and destructors
    194                         static void fixCopyCtors( std::list< Declaration * > &translationUnit, UnqCount & unqCount );
    195 
    196                         Expression * postmutate( ImplicitCopyCtorExpr * impCpCtorExpr );
    197                         void premutate( StmtExpr * stmtExpr );
    198                         void premutate( UniqueExpr * unqExpr );
    199 
    200                         UnqCount & unqCount;
    201183                };
    202184
     
    236218                        Expression * postmutate( ConstructorExpr * ctorExpr );
    237219                };
     220
     221                struct SplitExpressions : public WithShortCircuiting, public WithTypeSubstitution, public WithStmtsToAdd {
     222                        /// add CompoundStmts around top-level expressions so that temporaries are destroyed in the correct places.
     223                        static void split( std::list< Declaration * > &translationUnit );
     224
     225                        Statement * postmutate( ExprStmt * stmt );
     226                        void premutate( TupleAssignExpr * expr );
     227                };
    238228        } // namespace
    239229
    240         void fix( std::list< Declaration * > & translationUnit, const std::string & filename, bool inLibrary ) {
     230        void fix( std::list< Declaration * > & translationUnit, bool inLibrary ) {
    241231                PassVisitor<SelfAssignChecker> checker;
    242232                acceptAll( translationUnit, checker );
    243233
     234                // fixes StmtExpr to properly link to their resulting expression
     235                StmtExprResult::link( translationUnit );
     236
    244237                // fixes ConstructorInit for global variables. should happen before fixInitializers.
    245                 InitTweak::fixGlobalInit( translationUnit, filename, inLibrary );
    246 
    247                 UnqCount unqCount;
     238                InitTweak::fixGlobalInit( translationUnit, inLibrary );
     239
     240                // must happen before ResolveCopyCtors because temporaries have to be inserted into the correct scope
     241                SplitExpressions::split( translationUnit );
    248242
    249243                InsertImplicitCalls::insert( translationUnit );
    250                 ResolveCopyCtors::resolveImplicitCalls( translationUnit, unqCount );
     244
     245                // Needs to happen before ResolveCopyCtors, because argument/return temporaries should not be considered in
     246                // error checking branch statements
    251247                InsertDtors::insert( translationUnit );
     248
     249                ResolveCopyCtors::resolveImplicitCalls( translationUnit );
    252250                FixInit::fixInitializers( translationUnit );
    253 
    254                 // FixCopyCtors must happen after FixInit, so that destructors are placed correctly
    255                 FixCopyCtors::fixCopyCtors( translationUnit, unqCount );
    256 
    257251                GenStructMemberCalls::generate( translationUnit );
    258252
    259                 // xxx - ctor expansion currently has to be after FixCopyCtors, because there is currently a
    260                 // hack in the way untyped assignments are generated, where the first argument cannot have
    261                 // its address taken because of the way codegeneration handles UntypedExpr vs. ApplicationExpr.
    262                 // Thus such assignment exprs must never pushed through expression resolution (and thus should
    263                 // not go through the FixCopyCtors pass), otherwise they will fail -- guaranteed.
    264                 // Also needs to happen after GenStructMemberCalls, since otherwise member constructors exprs
    265                 // don't look right, and a member can be constructed more than once.
     253                // Needs to happen after GenStructMemberCalls, since otherwise member constructors exprs
     254                // don't have the correct form, and a member can be constructed more than once.
    266255                FixCtorExprs::fix( translationUnit );
    267256        }
    268257
    269258        namespace {
     259                /// find and return the destructor used in `input`. If `input` is not a simple destructor call, generate a thunk
     260                /// that wraps the destructor, insert it into `stmtsToAdd` and return the new function declaration
     261                DeclarationWithType * getDtorFunc( ObjectDecl * objDecl, Statement * input, std::list< Statement * > & stmtsToAdd ) {
     262                        // unwrap implicit statement wrapper
     263                        Statement * dtor = input;
     264                        assert( dtor );
     265                        std::list< Expression * > matches;
     266                        collectCtorDtorCalls( dtor, matches );
     267
     268                        if ( dynamic_cast< ExprStmt * >( dtor ) ) {
     269                                // only one destructor call in the expression
     270                                if ( matches.size() == 1 ) {
     271                                        DeclarationWithType * func = getFunction( matches.front() );
     272                                        assertf( func, "getFunction failed to find function in %s", toString( matches.front() ).c_str() );
     273
     274                                        // cleanup argument must be a function, not an object (including function pointer)
     275                                        if ( FunctionDecl * dtorFunc = dynamic_cast< FunctionDecl * > ( func ) ) {
     276                                                if ( dtorFunc->type->forall.empty() ) {
     277                                                        // simple case where the destructor is a monomorphic function call - can simply
     278                                                        // use that function as the cleanup function.
     279                                                        delete dtor;
     280                                                        return func;
     281                                                }
     282                                        }
     283                                }
     284                        }
     285
     286                        // otherwise the cleanup is more complicated - need to build a single argument cleanup function that
     287                        // wraps the more complicated code.
     288                        static UniqueName dtorNamer( "__cleanup_dtor" );
     289                        std::string name = dtorNamer.newName();
     290                        FunctionDecl * dtorFunc = FunctionDecl::newFunction( name, SymTab::genDefaultType( objDecl->type->stripReferences(), false ), new CompoundStmt() );
     291                        stmtsToAdd.push_back( new DeclStmt( dtorFunc ) );
     292
     293                        // the original code contains uses of objDecl - replace them with the newly generated 'this' parameter.
     294                        ObjectDecl * thisParam = getParamThis( dtorFunc->type );
     295                        Expression * replacement = new VariableExpr( thisParam );
     296
     297                        Type * base = replacement->result->stripReferences();
     298                        if ( dynamic_cast< ArrayType * >( base ) || dynamic_cast< TupleType * > ( base ) ) {
     299                                // need to cast away reference for array types, since the destructor is generated without the reference type,
     300                                // and for tuple types since tuple indexing does not work directly on a reference
     301                                replacement = new CastExpr( replacement, base->clone() );
     302                        }
     303                        DeclReplacer::replace( dtor, { std::make_pair( objDecl, replacement ) } );
     304                        dtorFunc->statements->push_back( strict_dynamic_cast<Statement *>( dtor ) );
     305
     306                        return dtorFunc;
     307                }
     308
     309                void StmtExprResult::link( std::list< Declaration * > & translationUnit ) {
     310                        PassVisitor<StmtExprResult> linker;
     311                        acceptAll( translationUnit, linker );
     312                }
     313
     314                void SplitExpressions::split( std::list< Declaration * > & translationUnit ) {
     315                        PassVisitor<SplitExpressions> splitter;
     316                        mutateAll( translationUnit, splitter );
     317                }
     318
    270319                void InsertImplicitCalls::insert( std::list< Declaration * > & translationUnit ) {
    271320                        PassVisitor<InsertImplicitCalls> inserter;
     
    273322                }
    274323
    275                 void ResolveCopyCtors::resolveImplicitCalls( std::list< Declaration * > & translationUnit, UnqCount & unqCount ) {
    276                         PassVisitor<ResolveCopyCtors> resolver( unqCount );
    277                         acceptAll( translationUnit, resolver );
     324                void ResolveCopyCtors::resolveImplicitCalls( std::list< Declaration * > & translationUnit ) {
     325                        PassVisitor<ResolveCopyCtors> resolver;
     326                        mutateAll( translationUnit, resolver );
    278327                }
    279328
     
    303352                }
    304353
    305                 void FixCopyCtors::fixCopyCtors( std::list< Declaration * > & translationUnit, UnqCount & unqCount ) {
    306                         PassVisitor<FixCopyCtors> fixer( unqCount );
    307                         mutateAll( translationUnit, fixer );
    308                 }
    309 
    310354                void GenStructMemberCalls::generate( std::list< Declaration * > & translationUnit ) {
    311355                        PassVisitor<GenStructMemberCalls> warner;
     
    318362                }
    319363
    320                 namespace {
    321                         // Relatively simple structural comparison for expressions, needed to determine
    322                         // if two expressions are "the same" (used to determine if self assignment occurs)
    323                         struct StructuralChecker {
    324                                 Expression * stripCasts( Expression * expr ) {
    325                                         // this might be too permissive. It's possible that only particular casts are relevant.
    326                                         while ( CastExpr * cast = dynamic_cast< CastExpr * >( expr ) ) {
    327                                                 expr = cast->arg;
    328                                         }
    329                                         return expr;
    330                                 }
    331 
    332                                 void previsit( Expression * ) {
    333                                         // anything else does not qualify
    334                                         isSimilar = false;
    335                                 }
    336 
    337                                 template<typename T>
    338                                 T * cast( Expression * node ) {
    339                                         // all expressions need to ignore casts, so this bit has been factored out
    340                                         return dynamic_cast< T * >( stripCasts( node ) );
    341                                 }
    342 
    343                                 // ignore casts
    344                                 void previsit( CastExpr * ) {}
    345 
    346                                 void previsit( MemberExpr * memExpr ) {
    347                                         if ( MemberExpr * otherMember = cast< MemberExpr >( other ) ) {
    348                                                 if ( otherMember->member == memExpr->member ) {
    349                                                         other = otherMember->aggregate;
    350                                                         return;
    351                                                 }
    352                                         }
    353                                         isSimilar = false;
    354                                 }
    355 
    356                                 void previsit( VariableExpr * varExpr ) {
    357                                         if ( VariableExpr * otherVar = cast< VariableExpr >( other ) ) {
    358                                                 if ( otherVar->var == varExpr->var ) {
    359                                                         return;
    360                                                 }
    361                                         }
    362                                         isSimilar = false;
    363                                 }
    364 
    365                                 void previsit( AddressExpr * ) {
    366                                         if ( AddressExpr * addrExpr = cast< AddressExpr >( other ) ) {
    367                                                 other = addrExpr->arg;
     364                void StmtExprResult::previsit( StmtExpr * stmtExpr ) {
     365                        // we might loose the result expression here so add a pointer to trace back
     366                        assert( stmtExpr->result );
     367                        Type * result = stmtExpr->result;
     368                        if ( ! result->isVoid() ) {
     369                                CompoundStmt * body = stmtExpr->statements;
     370                                assert( ! body->kids.empty() );
     371                                stmtExpr->resultExpr = strict_dynamic_cast< ExprStmt * >( body->kids.back() );
     372                        }
     373                }
     374
     375                Statement * SplitExpressions::postmutate( ExprStmt * stmt ) {
     376                        // wrap each top-level ExprStmt in a block so that destructors for argument and return temporaries are destroyed
     377                        // in the correct places
     378                        CompoundStmt * ret = new CompoundStmt( { stmt } );
     379                        return ret;
     380                }
     381
     382                void SplitExpressions::premutate( TupleAssignExpr * ) {
     383                        // don't do this within TupleAssignExpr, since it is already broken up into multiple expressions
     384                        visit_children = false;
     385                }
     386
     387                // Relatively simple structural comparison for expressions, needed to determine
     388                // if two expressions are "the same" (used to determine if self assignment occurs)
     389                struct StructuralChecker {
     390                        Expression * stripCasts( Expression * expr ) {
     391                                // this might be too permissive. It's possible that only particular casts are relevant.
     392                                while ( CastExpr * cast = dynamic_cast< CastExpr * >( expr ) ) {
     393                                        expr = cast->arg;
     394                                }
     395                                return expr;
     396                        }
     397
     398                        void previsit( Expression * ) {
     399                                // anything else does not qualify
     400                                isSimilar = false;
     401                        }
     402
     403                        template<typename T>
     404                        T * cast( Expression * node ) {
     405                                // all expressions need to ignore casts, so this bit has been factored out
     406                                return dynamic_cast< T * >( stripCasts( node ) );
     407                        }
     408
     409                        // ignore casts
     410                        void previsit( CastExpr * ) {}
     411
     412                        void previsit( MemberExpr * memExpr ) {
     413                                if ( MemberExpr * otherMember = cast< MemberExpr >( other ) ) {
     414                                        if ( otherMember->member == memExpr->member ) {
     415                                                other = otherMember->aggregate;
    368416                                                return;
    369417                                        }
    370                                         isSimilar = false;
    371                                 }
    372 
    373                                 Expression * other = nullptr;
    374                                 bool isSimilar = true;
    375                         };
    376 
    377                         bool structurallySimilar( Expression * e1, Expression * e2 ) {
    378                                 PassVisitor<StructuralChecker> checker;
    379                                 checker.pass.other = e2;
    380                                 e1->accept( checker );
    381                                 return checker.pass.isSimilar;
    382                         }
     418                                }
     419                                isSimilar = false;
     420                        }
     421
     422                        void previsit( VariableExpr * varExpr ) {
     423                                if ( VariableExpr * otherVar = cast< VariableExpr >( other ) ) {
     424                                        if ( otherVar->var == varExpr->var ) {
     425                                                return;
     426                                        }
     427                                }
     428                                isSimilar = false;
     429                        }
     430
     431                        void previsit( AddressExpr * ) {
     432                                if ( AddressExpr * addrExpr = cast< AddressExpr >( other ) ) {
     433                                        other = addrExpr->arg;
     434                                        return;
     435                                }
     436                                isSimilar = false;
     437                        }
     438
     439                        Expression * other = nullptr;
     440                        bool isSimilar = true;
     441                };
     442
     443                bool structurallySimilar( Expression * e1, Expression * e2 ) {
     444                        PassVisitor<StructuralChecker> checker;
     445                        checker.pass.other = e2;
     446                        e1->accept( checker );
     447                        return checker.pass.isSimilar;
    383448                }
    384449
     
    457522                        if ( TupleAssignExpr * assign = dynamic_cast< TupleAssignExpr * >( resolved ) ) {
    458523                                // fix newly generated StmtExpr
    459                                 postvisit( assign->stmtExpr );
     524                                premutate( assign->stmtExpr );
    460525                        }
    461526                        return resolved;
     
    489554                                        // so that the object isn't changed inside of the polymorphic function
    490555                                        if ( ! GenPoly::needsBoxing( formal, result, impCpCtorExpr->callExpr, env ) ) return;
     556                                        // xxx - leaking tmp
    491557                                }
    492558                        }
     
    496562
    497563                        // replace argument to function call with temporary
    498                         arg = new CommaExpr( cpCtor, new VariableExpr( tmp ) );
    499                         impCpCtorExpr->tempDecls.push_back( tmp );
    500                         impCpCtorExpr->dtors.push_front( makeCtorDtor( "^?{}", tmp ) );
    501                 }
    502 
    503                 void ResolveCopyCtors::destructRet( ObjectDecl * ret, ImplicitCopyCtorExpr * impCpCtorExpr ) {
    504                         impCpCtorExpr->get_dtors().push_front( makeCtorDtor( "^?{}", ret ) );
    505                 }
    506 
    507                 void ResolveCopyCtors::postvisit( ImplicitCopyCtorExpr *impCpCtorExpr ) {
     564                        stmtsToAddBefore.push_back( new DeclStmt( tmp ) );
     565                        arg = cpCtor;
     566                        destructRet( tmp, impCpCtorExpr, arg );
     567
     568                        // impCpCtorExpr->dtors.push_front( makeCtorDtor( "^?{}", tmp ) );
     569                }
     570
     571                void ResolveCopyCtors::destructRet( ObjectDecl * ret, ImplicitCopyCtorExpr * /*impCpCtorExpr*/, Expression *& arg ) {
     572                        // TODO: refactor code for generating cleanup attribute, since it's common and reused in ~3-4 places
     573                        // check for existing cleanup attribute before adding another(?)
     574                        // need to add __Destructor for _tmp_cp variables as well
     575
     576                        assertf( Validate::dtorStruct && Validate::dtorStruct->members.size() == 2, "Destructor generation requires __Destructor definition." );
     577                        assertf( Validate::dtorStructDestroy, "Destructor generation requires __destroy_Destructor." );
     578
     579                        // generate a __Destructor for ret that calls the destructor
     580                        Expression * dtor = makeCtorDtor( "^?{}", ret );
     581
     582                        // if the chosen destructor is intrinsic, elide the generated dtor handler
     583                        if ( arg && isIntrinsicCallExpr( dtor ) ) {
     584                                arg = new CommaExpr( arg, new VariableExpr( ret ) );
     585                                return;
     586                        }
     587
     588                        if ( ! dtor->env ) dtor->env = maybeClone( env );
     589                        DeclarationWithType * dtorFunc = getDtorFunc( ret, new ExprStmt( dtor ), stmtsToAddBefore );
     590
     591                        StructInstType * dtorStructType = new StructInstType( Type::Qualifiers(), Validate::dtorStruct );
     592                        dtorStructType->parameters.push_back( new TypeExpr( new VoidType( Type::Qualifiers() ) ) );
     593
     594                        // cast destructor pointer to void (*)(void *), to silence GCC incompatible pointer warnings
     595                        FunctionType * dtorFtype = new FunctionType( Type::Qualifiers(), false );
     596                        dtorFtype->parameters.push_back( ObjectDecl::newObject( "", new PointerType( Type::Qualifiers(), new VoidType( Type::Qualifiers() ) ), nullptr ) );
     597                        Type * dtorType = new PointerType( Type::Qualifiers(), dtorFtype );
     598
     599                        static UniqueName namer( "_ret_dtor" );
     600                        ObjectDecl * retDtor = ObjectDecl::newObject( namer.newName(), dtorStructType, new ListInit( { new SingleInit( new ConstantExpr( Constant::null() ) ), new SingleInit( new CastExpr( new VariableExpr( dtorFunc ), dtorType ) ) } ) );
     601                        retDtor->attributes.push_back( new Attribute( "cleanup", { new VariableExpr( Validate::dtorStructDestroy ) } ) );
     602                        stmtsToAddBefore.push_back( new DeclStmt( retDtor ) );
     603
     604                        if ( arg ) {
     605                                Expression * member = new MemberExpr( strict_dynamic_cast<DeclarationWithType *>( Validate::dtorStruct->members.front() ), new VariableExpr( retDtor ) );
     606                                Expression * object = new CastExpr( new AddressExpr( new VariableExpr( ret ) ), new PointerType( Type::Qualifiers(), new VoidType( Type::Qualifiers() ) ) );
     607                                Expression * assign = createBitwiseAssignment( member, object );
     608                                arg = new CommaExpr( new CommaExpr( arg, assign ), new VariableExpr( ret ) );
     609                        }
     610
     611                        // impCpCtorExpr->get_dtors().push_front( makeCtorDtor( "^?{}", ret ) );
     612                }
     613
     614                Expression * ResolveCopyCtors::postmutate( ImplicitCopyCtorExpr *impCpCtorExpr ) {
    508615                        CP_CTOR_PRINT( std::cerr << "ResolveCopyCtors: " << impCpCtorExpr << std::endl; )
    509616
    510617                        ApplicationExpr * appExpr = impCpCtorExpr->callExpr;
     618                        ObjectDecl * returnDecl = nullptr;
    511619
    512620                        // take each argument and attempt to copy construct it.
     
    517625                        for ( Expression * & arg : appExpr->args ) {
    518626                                Type * formal = nullptr;
    519                                 if ( iter != params.end() ) {
     627                                if ( iter != params.end() ) { // does not copy construct C-style variadic arguments
    520628                                        DeclarationWithType * param = *iter++;
    521629                                        formal = param->get_type();
     
    535643                                ObjectDecl * ret = ObjectDecl::newObject( retNamer.newName(), result, nullptr );
    536644                                ret->type->set_const( false );
    537                                 impCpCtorExpr->returnDecls.push_back( ret );
     645                                returnDecl = ret;
     646                                stmtsToAddBefore.push_back( new DeclStmt( ret ) );
    538647                                CP_CTOR_PRINT( std::cerr << "makeCtorDtor for a return" << std::endl; )
     648                        } // for
     649                        CP_CTOR_PRINT( std::cerr << "after Resolving: " << impCpCtorExpr << std::endl; )
     650                        // ------------------------------------------------------
     651
     652                        CP_CTOR_PRINT( std::cerr << "Coming out the back..." << impCpCtorExpr << std::endl; )
     653
     654                        // detach fields from wrapper node so that it can be deleted without deleting too much
     655                        impCpCtorExpr->callExpr = nullptr;
     656                        std::swap( impCpCtorExpr->env, appExpr->env );
     657                        assert( impCpCtorExpr->env == nullptr );
     658                        delete impCpCtorExpr;
     659
     660                        if ( returnDecl ) {
     661                                Expression * assign = createBitwiseAssignment( new VariableExpr( returnDecl ), appExpr );
    539662                                if ( ! dynamic_cast< ReferenceType * >( result ) ) {
    540663                                        // destructing reference returns is bad because it can cause multiple destructor calls to the same object - the returned object is not a temporary
    541                                         destructRet( ret, impCpCtorExpr );
    542                                 }
     664                                        destructRet( returnDecl, impCpCtorExpr, assign );
     665                                } else {
     666                                        assign = new CommaExpr( assign, new VariableExpr( returnDecl ) );
     667                                }
     668                                // move env from appExpr to retExpr
     669                                std::swap( assign->env, appExpr->env );
     670                                return assign;
     671                        } else {
     672                                return appExpr;
     673                        } // if
     674                }
     675
     676                void ResolveCopyCtors::premutate( StmtExpr * stmtExpr ) {
     677                        // function call temporaries should be placed at statement-level, rather than nested inside of a new statement expression,
     678                        // since temporaries can be shared across sub-expressions, e.g.
     679                        //   [A, A] f();       // decl
     680                        //   g([A] x, [A] y);  // decl
     681                        //   g(f());           // call
     682                        // f is executed once, so the return temporary is shared across the tuple constructors for x and y.
     683                        // Explicitly mutating children instead of mutating the inner compound statement forces the temporaries to be added
     684                        // to the outer context, rather than inside of the statement expression.
     685                        visit_children = false;
     686
     687                        assert( env );
     688
     689                        indexer.enterScope();
     690                        // visit all statements
     691                        std::list< Statement * > & stmts = stmtExpr->statements->get_kids();
     692                        for ( Statement *& stmt : stmts ) {
     693                                stmt = stmt->acceptMutator( *visitor );
    543694                        } // for
    544                         CP_CTOR_PRINT( std::cerr << "after Resolving: " << impCpCtorExpr << std::endl; )
    545                 }
    546 
    547                 void ResolveCopyCtors::postvisit( StmtExpr * stmtExpr ) {
    548                         assert( env );
    549                         assert( stmtExpr->get_result() );
    550                         Type * result = stmtExpr->get_result();
     695                        indexer.leaveScope();
     696
     697                        assert( stmtExpr->result );
     698                        Type * result = stmtExpr->result;
    551699                        if ( ! result->isVoid() ) {
    552700                                static UniqueName retNamer("_tmp_stmtexpr_ret");
     
    562710                                ObjectDecl * ret = ObjectDecl::newObject( retNamer.newName(), result, nullptr );
    563711                                ret->type->set_const( false );
    564                                 stmtExpr->returnDecls.push_front( ret );
     712                                stmtsToAddBefore.push_back( new DeclStmt( ret ) );
     713
     714                                assertf(
     715                                        stmtExpr->resultExpr,
     716                                        "Statement-Expression should have a resulting expression at %s:%d",
     717                                        stmtExpr->location.filename.c_str(),
     718                                        stmtExpr->location.first_line
     719                                );
     720
     721                                ExprStmt * last = stmtExpr->resultExpr;
     722                                try {
     723                                        last->expr = makeCtorDtor( "?{}", ret, last->expr );
     724                                } catch(...) {
     725                                        std::cerr << "*CFA internal error: ";
     726                                        std::cerr << "can't resolve implicit constructor";
     727                                        std::cerr << " at " << stmtExpr->location.filename;
     728                                        std::cerr << ":" << stmtExpr->location.first_line << std::endl;
     729
     730                                        abort();
     731                                }
     732
     733                                // add destructors after current statement
     734                                stmtsToAddAfter.push_back( new ExprStmt( makeCtorDtor( "^?{}", ret ) ) );
    565735
    566736                                // must have a non-empty body, otherwise it wouldn't have a result
    567                                 CompoundStmt * body = stmtExpr->statements;
    568                                 assert( ! body->get_kids().empty() );
    569                                 // must be an ExprStmt, otherwise it wouldn't have a result
    570                                 ExprStmt * last = strict_dynamic_cast< ExprStmt * >( body->get_kids().back() );
    571                                 last->expr = makeCtorDtor( "?{}", ret, last->get_expr() );
    572 
    573                                 stmtExpr->dtors.push_front( makeCtorDtor( "^?{}", ret ) );
     737                                assert( ! stmts.empty() );
     738
     739                                // if there is a return decl, add a use as the last statement; will not have return decl on non-constructable returns
     740                                stmts.push_back( new ExprStmt( new VariableExpr( ret ) ) );
    574741                        } // if
    575                 }
    576 
    577                 void ResolveCopyCtors::previsit( UniqueExpr * unqExpr ) {
    578                         unqCount[ unqExpr->get_id() ]++;  // count the number of unique expressions for each ID
    579                         if ( vars.count( unqExpr->get_id() ) ) {
    580                                 // xxx - hack to prevent double-handling of unique exprs, otherwise too many temporary variables and destructors are generated
    581                                 visit_children = false;
    582                         }
     742
     743                        assert( stmtExpr->returnDecls.empty() );
     744                        assert( stmtExpr->dtors.empty() );
    583745                }
    584746
     
    597759                }
    598760
    599                 void ResolveCopyCtors::postvisit( UniqueExpr * unqExpr ) {
    600                         if ( vars.count( unqExpr->get_id() ) ) {
    601                                 // xxx - hack to prevent double-handling of unique exprs, otherwise too many temporary variables and destructors are generated
    602                                 return;
    603                         }
    604 
    605                         // it should never be necessary to wrap a void-returning expression in a UniqueExpr - if this assumption changes, this needs to be rethought
    606                         assert( unqExpr->get_result() );
    607                         if ( ImplicitCopyCtorExpr * impCpCtorExpr = dynamic_cast<ImplicitCopyCtorExpr*>( unqExpr->get_expr() ) ) {
    608                                 // note the variable used as the result from the call
    609                                 assert( impCpCtorExpr->get_result() && impCpCtorExpr->get_returnDecls().size() == 1 );
    610                                 unqExpr->set_var( new VariableExpr( impCpCtorExpr->get_returnDecls().front() ) );
     761                void ResolveCopyCtors::premutate( UniqueExpr * unqExpr ) {
     762                        visit_children = false;
     763                        // xxx - hack to prevent double-handling of unique exprs, otherwise too many temporary variables and destructors are generated
     764                        static std::unordered_map< int, UniqueExpr * > unqMap;
     765                        if ( ! unqMap.count( unqExpr->get_id() ) ) {
     766                                // resolve expr and find its
     767
     768                                ImplicitCopyCtorExpr * impCpCtorExpr = dynamic_cast< ImplicitCopyCtorExpr * >( unqExpr->expr );
     769                                // PassVisitor<ResolveCopyCtors> fixer;
     770                                unqExpr->expr = unqExpr->expr->acceptMutator( *visitor );
     771
     772                                // it should never be necessary to wrap a void-returning expression in a UniqueExpr - if this assumption changes, this needs to be rethought
     773                                assert( unqExpr->result );
     774                                if ( impCpCtorExpr ) {
     775                                        CommaExpr * comma = strict_dynamic_cast< CommaExpr * >( unqExpr->expr );
     776                                        VariableExpr * var = strict_dynamic_cast<VariableExpr *>( comma->arg2 );
     777                                        // note the variable used as the result from the call
     778                                        unqExpr->var = var->clone();
     779                                } else {
     780                                        // expr isn't a call expr, so create a new temporary variable to use to hold the value of the unique expression
     781                                        unqExpr->object = ObjectDecl::newObject( toString("_unq", unqExpr->get_id()), unqExpr->result->clone(), makeInit( unqExpr->result ) );
     782                                        unqExpr->var = new VariableExpr( unqExpr->object );
     783                                }
     784
     785                                // stmtsToAddBefore.splice( stmtsToAddBefore.end(), fixer.pass.stmtsToAddBefore );
     786                                // stmtsToAddAfter.splice( stmtsToAddAfter.end(), fixer.pass.stmtsToAddAfter );
     787                                unqMap[unqExpr->get_id()] = unqExpr;
    611788                        } else {
    612                                 // expr isn't a call expr, so create a new temporary variable to use to hold the value of the unique expression
    613                                 unqExpr->set_object( ObjectDecl::newObject( toString("_unq", unqExpr->get_id()), unqExpr->get_result()->clone(), makeInit( unqExpr->get_result() ) ) );
    614                                 unqExpr->set_var( new VariableExpr( unqExpr->get_object() ) );
    615                         }
    616                         vars.insert( unqExpr->get_id() );
    617                 }
    618 
    619                 Expression * FixCopyCtors::postmutate( ImplicitCopyCtorExpr * impCpCtorExpr ) {
    620                         CP_CTOR_PRINT( std::cerr << "FixCopyCtors: " << impCpCtorExpr << std::endl; )
    621 
    622                         std::list< ObjectDecl * > & tempDecls = impCpCtorExpr->get_tempDecls();
    623                         std::list< ObjectDecl * > & returnDecls = impCpCtorExpr->get_returnDecls();
    624                         std::list< Expression * > & dtors = impCpCtorExpr->get_dtors();
    625 
    626                         // add all temporary declarations and their constructors
    627                         for ( ObjectDecl * obj : tempDecls ) {
    628                                 stmtsToAddBefore.push_back( new DeclStmt( obj ) );
    629                         } // for
    630                         for ( ObjectDecl * obj : returnDecls ) {
    631                                 stmtsToAddBefore.push_back( new DeclStmt( obj ) );
    632                         } // for
    633 
    634                         // add destructors after current statement
    635                         for ( Expression * dtor : dtors ) {
    636                                 // take relevant bindings from environment
    637                                 assert( ! dtor->env );
    638                                 dtor->env =  maybeClone( env );
    639                                 stmtsToAddAfter.push_back( new ExprStmt( dtor ) );
    640                         } // for
    641 
    642                         ObjectDecl * returnDecl = returnDecls.empty() ? nullptr : returnDecls.front();
    643                         Expression * callExpr = impCpCtorExpr->get_callExpr();
    644 
    645                         CP_CTOR_PRINT( std::cerr << "Coming out the back..." << impCpCtorExpr << std::endl; )
    646 
    647                         // detach fields from wrapper node so that it can be deleted without deleting too much
    648                         dtors.clear();
    649                         tempDecls.clear();
    650                         returnDecls.clear();
    651                         impCpCtorExpr->set_callExpr( nullptr );
    652                         std::swap( impCpCtorExpr->env, callExpr->env );
    653                         assert( impCpCtorExpr->env == nullptr );
    654                         delete impCpCtorExpr;
    655 
    656                         if ( returnDecl ) {
    657                                 ApplicationExpr * assign = createBitwiseAssignment( new VariableExpr( returnDecl ), callExpr );
    658                                 Expression * retExpr = new CommaExpr( assign, new VariableExpr( returnDecl ) );
    659                                 // move env from callExpr to retExpr
    660                                 std::swap( retExpr->env, callExpr->env );
    661                                 return retExpr;
    662                         } else {
    663                                 return callExpr;
    664                         } // if
    665                 }
    666 
    667                 void FixCopyCtors::premutate( StmtExpr * stmtExpr ) {
    668                         // function call temporaries should be placed at statement-level, rather than nested inside of a new statement expression,
    669                         // since temporaries can be shared across sub-expressions, e.g.
    670                         //   [A, A] f();
    671                         //   g([A] x, [A] y);
    672                         //   g(f());
    673                         // f is executed once, so the return temporary is shared across the tuple constructors for x and y.
    674                         // Explicitly mutating children instead of mutating the inner compound statment forces the temporaries to be added
    675                         // to the outer context, rather than inside of the statement expression.
    676                         visit_children = false;
    677                         std::list< Statement * > & stmts = stmtExpr->statements->get_kids();
    678                         for ( Statement *& stmt : stmts ) {
    679                                 stmt = stmt->acceptMutator( *visitor );
    680                         } // for
    681                         assert( stmtExpr->result );
    682                         Type * result = stmtExpr->result;
    683                         if ( ! result->isVoid() ) {
    684                                 for ( ObjectDecl * obj : stmtExpr->returnDecls ) {
    685                                         stmtsToAddBefore.push_back( new DeclStmt( obj ) );
    686                                 } // for
    687                                 // add destructors after current statement
    688                                 for ( Expression * dtor : stmtExpr->dtors ) {
    689                                         stmtsToAddAfter.push_back( new ExprStmt( dtor ) );
    690                                 } // for
    691                                 // must have a non-empty body, otherwise it wouldn't have a result
    692                                 assert( ! stmts.empty() );
    693                                 assertf( ! stmtExpr->returnDecls.empty() || stmtExpr->dtors.empty(), "StmtExpr returns non-void, but no return decls: %s", toString( stmtExpr ).c_str() );
    694                                 // if there is a return decl, add a use as the last statement; will not have return decl on non-constructable returns
    695                                 if ( ! stmtExpr->returnDecls.empty() ) {
    696                                         stmts.push_back( new ExprStmt( new VariableExpr( stmtExpr->returnDecls.front() ) ) );
    697                                 }
    698                                 stmtExpr->returnDecls.clear();
    699                                 stmtExpr->dtors.clear();
    700                         }
    701                         assert( stmtExpr->returnDecls.empty() );
    702                         assert( stmtExpr->dtors.empty() );
    703                 }
    704 
    705                 void FixCopyCtors::premutate( UniqueExpr * unqExpr ) {
    706                         visit_children = false;
    707                         unqCount[ unqExpr->get_id() ]--;
    708                         static std::unordered_map< int, std::list< Statement * > > dtors;
    709                         static std::unordered_map< int, UniqueExpr * > unqMap;
    710                         // has to be done to clean up ImplicitCopyCtorExpr nodes, even when this node was skipped in previous passes
    711                         if ( unqMap.count( unqExpr->get_id() ) ) {
    712789                                // take data from other UniqueExpr to ensure consistency
    713790                                delete unqExpr->get_expr();
    714                                 unqExpr->set_expr( unqMap[unqExpr->get_id()]->get_expr()->clone() );
    715                                 delete unqExpr->get_result();
    716                                 unqExpr->set_result( maybeClone( unqExpr->get_expr()->get_result() ) );
    717                                 if ( unqCount[ unqExpr->get_id() ] == 0 ) {  // insert destructor after the last use of the unique expression
    718                                         stmtsToAddAfter.splice( stmtsToAddAfter.end(), dtors[ unqExpr->get_id() ] );
    719                                 }
    720                                 return;
    721                         }
    722                         PassVisitor<FixCopyCtors> fixer( unqCount );
    723                         unqExpr->set_expr( unqExpr->get_expr()->acceptMutator( fixer ) ); // stmtexprs contained should not be separately fixed, so this must occur after the lookup
    724                         stmtsToAddBefore.splice( stmtsToAddBefore.end(), fixer.pass.stmtsToAddBefore );
    725                         unqMap[unqExpr->get_id()] = unqExpr;
    726                         if ( unqCount[ unqExpr->get_id() ] == 0 ) {  // insert destructor after the last use of the unique expression
    727                                 stmtsToAddAfter.splice( stmtsToAddAfter.end(), dtors[ unqExpr->get_id() ] );
    728                         } else { // remember dtors for last instance of unique expr
    729                                 dtors[ unqExpr->get_id() ] = fixer.pass.stmtsToAddAfter;
    730                         }
    731                         return;
     791                                unqExpr->expr = unqMap[unqExpr->get_id()]->expr->clone();
     792                                delete unqExpr->result;
     793                                unqExpr->result = maybeClone( unqExpr->expr->result );
     794                        }
    732795                }
    733796
     
    844907                                                        ctorInit->ctor = nullptr;
    845908                                                }
     909
     910                                                Statement * dtor = ctorInit->dtor;
     911                                                if ( dtor ) {
     912                                                        ImplicitCtorDtorStmt * implicit = strict_dynamic_cast< ImplicitCtorDtorStmt * >( dtor );
     913                                                        Statement * dtorStmt = implicit->callStmt;
     914
     915                                                        // don't need to call intrinsic dtor, because it does nothing, but
     916                                                        // non-intrinsic dtors must be called
     917                                                        if ( ! isIntrinsicSingleArgCallStmt( dtorStmt ) ) {
     918                                                                // set dtor location to the object's location for error messages
     919                                                                DeclarationWithType * dtorFunc = getDtorFunc( objDecl, dtorStmt, stmtsToAddBefore );
     920                                                                objDecl->attributes.push_back( new Attribute( "cleanup", { new VariableExpr( dtorFunc ) } ) );
     921                                                                ctorInit->dtor = nullptr;
     922                                                        } // if
     923                                                }
    846924                                        } // if
    847925                                } else if ( Initializer * init = ctorInit->init ) {
     
    886964
    887965
    888                 template<typename Iterator, typename OutputIterator>
    889                 void insertDtors( Iterator begin, Iterator end, OutputIterator out ) {
    890                         for ( Iterator it = begin ; it != end ; ++it ) {
    891                                 // extract destructor statement from the object decl and insert it into the output. Note that this is
    892                                 // only called on lists of non-static objects with implicit non-intrinsic dtors, so if the user manually
    893                                 // calls an intrinsic dtor then the call must (and will) still be generated since the argument may
    894                                 // contain side effects.
    895                                 ObjectDecl * objDecl = *it;
    896                                 ConstructorInit * ctorInit = dynamic_cast< ConstructorInit * >( objDecl->get_init() );
    897                                 assert( ctorInit && ctorInit->get_dtor() );
    898                                 *out++ = ctorInit->get_dtor()->clone();
    899                         } // for
    900                 }
    901 
    902                 void InsertDtors::previsit( ObjectDecl * objDecl ) {
    903                         // remember non-static destructed objects so that their destructors can be inserted later
    904                         if ( ! objDecl->get_storageClasses().is_static ) {
    905                                 if ( ConstructorInit * ctorInit = dynamic_cast< ConstructorInit * >( objDecl->get_init() ) ) {
    906                                         // a decision should have been made by the resolver, so ctor and init are not both non-NULL
    907                                         assert( ! ctorInit->get_ctor() || ! ctorInit->get_init() );
    908                                         Statement * dtor = ctorInit->get_dtor();
    909                                         // don't need to call intrinsic dtor, because it does nothing, but
    910                                         // non-intrinsic dtors must be called
    911                                         if ( dtor && ! isIntrinsicSingleArgCallStmt( dtor ) ) {
    912                                                 // set dtor location to the object's location for error messages
    913                                                 ctorInit->dtor->location = objDecl->location;
    914                                                 reverseDeclOrder.front().push_front( objDecl );
    915                                         } // if
    916                                 } // if
    917                         } // if
    918                 }
    919 
    920966                void InsertDtors::previsit( FunctionDecl * funcDecl ) {
    921967                        // each function needs to have its own set of labels
     
    930976                }
    931977
    932                 void InsertDtors::previsit( CompoundStmt * compoundStmt ) {
    933                         // visit statements - this will also populate reverseDeclOrder list.  don't want to dump all destructors
    934                         // when block is left, just the destructors associated with variables defined in this block, so push a new
    935                         // list to the top of the stack so that we can differentiate scopes
    936                         reverseDeclOrder.push_front( OrderedDecls() );
    937                         Parent::previsit( compoundStmt );
    938                 }
    939 
    940                 void InsertDtors::postvisit( CompoundStmt * compoundStmt ) {
    941                         // add destructors for the current scope that we're exiting, unless the last statement is a return, which
    942                         // causes unreachable code warnings
    943                         std::list< Statement * > & statements = compoundStmt->get_kids();
    944                         if ( ! statements.empty() && ! dynamic_cast< ReturnStmt * >( statements.back() ) ) {
    945                                 insertDtors( reverseDeclOrder.front().begin(), reverseDeclOrder.front().end(), back_inserter( statements ) );
    946                         }
    947                         reverseDeclOrder.pop_front();
    948                 }
    949 
    950                 void InsertDtors::previsit( ReturnStmt * ) {
    951                         // return exits all scopes, so dump destructors for all scopes
    952                         for ( OrderedDecls & od : reverseDeclOrder ) {
    953                                 insertDtors( od.begin(), od.end(), back_inserter( stmtsToAddBefore ) );
    954                         } // for
    955                 }
    956 
    957978                // Handle break/continue/goto in the same manner as C++.  Basic idea: any objects that are in scope at the
    958979                // BranchStmt but not at the labelled (target) statement must be destructed.  If there are any objects in scope
     
    973994                                std::cerr << "S_L = " << printSet( lvars ) << std::endl;
    974995                        )
     996
     997
     998                        // std::set_difference requires that the inputs be sorted.
     999                        lvars.sort();
     1000                        curVars.sort();
    9751001
    9761002                        ObjectSet diff;
     
    9821008                        if ( ! diff.empty() ) {
    9831009                                SemanticError( stmt, std::string("jump to label '") + stmt->get_target().get_name() + "' crosses initialization of " + (*diff.begin())->get_name() + " " );
    984                         } // if
    985                         // S_G-S_L results in set of objects that must be destructed
    986                         diff.clear();
    987                         std::set_difference( curVars.begin(), curVars.end(), lvars.begin(), lvars.end(), std::inserter( diff, diff.end() ) );
    988                         DTOR_PRINT(
    989                                 std::cerr << "S_G-S_L = " << printSet( diff ) << std::endl;
    990                         )
    991                         if ( ! diff.empty() ) {
    992                                 // create an auxilliary set for fast lookup -- can't make diff a set, because diff ordering should be consistent for error messages.
    993                                 std::unordered_set<ObjectDecl *> needsDestructor( diff.begin(), diff.end() );
    994 
    995                                 // go through decl ordered list of objectdecl. for each element that occurs in diff, output destructor
    996                                 OrderedDecls ordered;
    997                                 for ( OrderedDecls & rdo : reverseDeclOrder ) {
    998                                         // add elements from reverseDeclOrder into ordered if they occur in diff - it is key that this happens in reverse declaration order.
    999                                         copy_if( rdo.begin(), rdo.end(), back_inserter( ordered ), [&]( ObjectDecl * objDecl ) { return needsDestructor.count( objDecl ); } );
    1000                                 } // for
    1001                                 insertDtors( ordered.begin(), ordered.end(), back_inserter( stmtsToAddBefore ) );
    10021010                        } // if
    10031011                }
     
    11031111                                                arg2 = new MemberExpr( field, new VariableExpr( params.back() ) );
    11041112                                        }
    1105                                         InitExpander srcParam( arg2 );
     1113                                        InitExpander_old srcParam( arg2 );
    11061114                                        // cast away reference type and construct field.
    11071115                                        Expression * thisExpr = new CastExpr( new VariableExpr( thisParam ), thisParam->get_type()->stripReferences()->clone() );
     
    11161124                                                        callStmt->acceptMutator( *visitor );
    11171125                                                        if ( isCtor ) {
    1118                                                                 function->get_statements()->push_front( callStmt );
    1119                                                         } else {
     1126                                                                function->statements->push_front( callStmt );
     1127                                                        } else { // TODO: don't generate destructor function/object for intrinsic calls
    11201128                                                                // destructor statements should be added at the end
    1121                                                                 function->get_statements()->push_back( callStmt );
     1129                                                                // function->get_statements()->push_back( callStmt );
     1130
     1131                                                                // Optimization: do not need to call intrinsic destructors on members
     1132                                                                if ( isIntrinsicSingleArgCallStmt( callStmt ) ) continue;;
     1133
     1134                                                                // __Destructor _dtor0 = { (void *)&b.a1, (void (*)(void *)_destroy_A };
     1135                                                                std::list< Statement * > stmtsToAdd;
     1136
     1137                                                                static UniqueName memberDtorNamer = { "__memberDtor" };
     1138                                                                assertf( Validate::dtorStruct, "builtin __Destructor not found." );
     1139                                                                assertf( Validate::dtorStructDestroy, "builtin __destroy_Destructor not found." );
     1140
     1141                                                                Expression * thisExpr = new CastExpr( new AddressExpr( new VariableExpr( thisParam ) ), new PointerType( Type::Qualifiers(), new VoidType( Type::Qualifiers() ) ) );
     1142                                                                Expression * dtorExpr = new VariableExpr( getDtorFunc( thisParam, callStmt, stmtsToAdd ) );
     1143
     1144                                                                // cast destructor pointer to void (*)(void *), to silence GCC incompatible pointer warnings
     1145                                                                FunctionType * dtorFtype = new FunctionType( Type::Qualifiers(), false );
     1146                                                                dtorFtype->parameters.push_back( ObjectDecl::newObject( "", new PointerType( Type::Qualifiers(), new VoidType( Type::Qualifiers() ) ), nullptr ) );
     1147                                                                Type * dtorType = new PointerType( Type::Qualifiers(), dtorFtype );
     1148
     1149                                                                ObjectDecl * destructor = ObjectDecl::newObject( memberDtorNamer.newName(), new StructInstType( Type::Qualifiers(), Validate::dtorStruct ), new ListInit( { new SingleInit( thisExpr ), new SingleInit( new CastExpr( dtorExpr, dtorType ) ) } ) );
     1150                                                                function->statements->push_front( new DeclStmt( destructor ) );
     1151                                                                destructor->attributes.push_back( new Attribute( "cleanup", { new VariableExpr( Validate::dtorStructDestroy ) } ) );
     1152
     1153                                                                function->statements->kids.splice( function->statements->kids.begin(), stmtsToAdd );
    11221154                                                        }
    11231155                                                } catch ( SemanticErrorException & error ) {
     
    11631195
    11641196                        std::string fname = getFunctionName( appExpr );
    1165                         if ( fname == function->get_name() ) {
     1197                        if ( fname == function->name ) {
    11661198                                // call to same kind of function
    1167                                 Expression * firstParam = appExpr->get_args().front();
     1199                                Expression * firstParam = appExpr->args.front();
    11681200
    11691201                                if ( isThisExpression( firstParam, thisParam ) ) {
     
    11741206                                        // if first parameter is a member expression on the this parameter,
    11751207                                        // then remove the member from unhandled set.
    1176                                         if ( isThisExpression( memberExpr->get_aggregate(), thisParam ) ) {
    1177                                                 unhandled.erase( memberExpr->get_member() );
     1208                                        if ( isThisExpression( memberExpr->aggregate, thisParam ) ) {
     1209                                                unhandled.erase( memberExpr->member );
    11781210                                        }
    11791211                                }
  • src/InitTweak/FixInit.h

    r7951100 rb067d9b  
    2424  /// replace constructor initializers with expression statements
    2525  /// and unwrap basic C-style initializers
    26         void fix( std::list< Declaration * > & translationUnit, const std::string & name, bool inLibrary );
     26        void fix( std::list< Declaration * > & translationUnit, bool inLibrary );
    2727} // namespace
    2828
  • src/InitTweak/GenInit.cc

    r7951100 rb067d9b  
    1515#include "GenInit.h"
    1616
    17 #include <stddef.h>                // for NULL
    18 #include <algorithm>               // for any_of
    19 #include <cassert>                 // for assert, strict_dynamic_cast, assertf
    20 #include <iterator>                // for back_inserter, inserter, back_inse...
    21 #include <list>                    // for _List_iterator, list
    22 
     17#include <stddef.h>                    // for NULL
     18#include <algorithm>                   // for any_of
     19#include <cassert>                     // for assert, strict_dynamic_cast, assertf
     20#include <deque>
     21#include <iterator>                    // for back_inserter, inserter, back_inse...
     22#include <list>                        // for _List_iterator, list
     23
     24#include "AST/Decl.hpp"
     25#include "AST/Init.hpp"
     26#include "AST/Node.hpp"
     27#include "AST/Stmt.hpp"
    2328#include "CodeGen/OperatorTable.h"
    24 #include "Common/PassVisitor.h"    // for PassVisitor, WithGuards, WithShort...
    25 #include "Common/SemanticError.h"  // for SemanticError
    26 #include "Common/UniqueName.h"     // for UniqueName
    27 #include "Common/utility.h"        // for ValueGuard, maybeClone
    28 #include "GenPoly/GenPoly.h"       // for getFunctionType, isPolyType
    29 #include "GenPoly/ScopedSet.h"     // for ScopedSet, ScopedSet<>::const_iter...
    30 #include "InitTweak.h"             // for isConstExpr, InitExpander, checkIn...
    31 #include "Parser/LinkageSpec.h"    // for isOverridable, C
     29#include "Common/PassVisitor.h"        // for PassVisitor, WithGuards, WithShort...
     30#include "Common/SemanticError.h"      // for SemanticError
     31#include "Common/UniqueName.h"         // for UniqueName
     32#include "Common/utility.h"            // for ValueGuard, maybeClone
     33#include "GenPoly/GenPoly.h"           // for getFunctionType, isPolyType
     34#include "GenPoly/ScopedSet.h"         // for ScopedSet, ScopedSet<>::const_iter...
     35#include "InitTweak.h"                 // for isConstExpr, InitExpander, checkIn...
     36#include "Parser/LinkageSpec.h"        // for isOverridable, C
    3237#include "ResolvExpr/Resolver.h"
    33 #include "SymTab/Autogen.h"        // for genImplicitCall, SizeType
    34 #include "SymTab/Mangler.h"        // for Mangler
    35 #include "SynTree/Declaration.h"   // for ObjectDecl, DeclarationWithType
    36 #include "SynTree/Expression.h"    // for VariableExpr, UntypedExpr, Address...
    37 #include "SynTree/Initializer.h"   // for ConstructorInit, SingleInit, Initi...
    38 #include "SynTree/Label.h"         // for Label
    39 #include "SynTree/Mutator.h"       // for mutateAll
    40 #include "SynTree/Statement.h"     // for CompoundStmt, ImplicitCtorDtorStmt
    41 #include "SynTree/Type.h"          // for Type, ArrayType, Type::Qualifiers
    42 #include "SynTree/Visitor.h"       // for acceptAll, maybeAccept
    43 #include "Tuples/Tuples.h"         // for maybeImpure
     38#include "SymTab/Autogen.h"            // for genImplicitCall
     39#include "SymTab/Mangler.h"            // for Mangler
     40#include "SynTree/Declaration.h"       // for ObjectDecl, DeclarationWithType
     41#include "SynTree/Expression.h"        // for VariableExpr, UntypedExpr, Address...
     42#include "SynTree/Initializer.h"       // for ConstructorInit, SingleInit, Initi...
     43#include "SynTree/Label.h"             // for Label
     44#include "SynTree/Mutator.h"           // for mutateAll
     45#include "SynTree/Statement.h"         // for CompoundStmt, ImplicitCtorDtorStmt
     46#include "SynTree/Type.h"              // for Type, ArrayType, Type::Qualifiers
     47#include "SynTree/Visitor.h"           // for acceptAll, maybeAccept
     48#include "Tuples/Tuples.h"             // for maybeImpure
     49#include "Validate/FindSpecialDecls.h" // for SizeType
    4450
    4551namespace InitTweak {
     
    186192
    187193                        // need to resolve array dimensions in order to accurately determine if constexpr
    188                         ResolvExpr::findSingleExpression( arrayType->dimension, SymTab::SizeType->clone(), indexer );
     194                        ResolvExpr::findSingleExpression( arrayType->dimension, Validate::SizeType->clone(), indexer );
    189195                        // array is variable-length when the dimension is not constexpr
    190196                        arrayType->isVarLen = ! isConstExpr( arrayType->dimension );
     
    192198                        if ( ! Tuples::maybeImpure( arrayType->dimension ) ) return;
    193199
    194                         ObjectDecl * arrayDimension = new ObjectDecl( dimensionName.newName(), storageClasses, LinkageSpec::C, 0, SymTab::SizeType->clone(), new SingleInit( arrayType->get_dimension() ) );
     200                        ObjectDecl * arrayDimension = new ObjectDecl( dimensionName.newName(), storageClasses, LinkageSpec::C, 0, Validate::SizeType->clone(), new SingleInit( arrayType->get_dimension() ) );
    195201                        arrayDimension->get_type()->set_const( true );
    196202
     
    273279                assertf( objDecl, "genCtorDtor passed null objDecl" );
    274280                std::list< Statement * > stmts;
    275                 InitExpander srcParam( maybeClone( arg ) );
     281                InitExpander_old srcParam( maybeClone( arg ) );
    276282                SymTab::genImplicitCall( srcParam, new VariableExpr( objDecl ), fname, back_inserter( stmts ), objDecl );
    277283                assert( stmts.size() <= 1 );
     
    285291                std::list< Statement * > dtor;
    286292
    287                 InitExpander srcParam( objDecl->get_init() );
    288                 InitExpander nullParam( (Initializer *)NULL );
     293                InitExpander_old srcParam( objDecl->get_init() );
     294                InitExpander_old nullParam( (Initializer *)NULL );
    289295                SymTab::genImplicitCall( srcParam, new VariableExpr( objDecl ), "?{}", back_inserter( ctor ), objDecl );
    290296                SymTab::genImplicitCall( nullParam, new VariableExpr( objDecl ), "^?{}", front_inserter( dtor ), objDecl, false );
     
    352358                GuardScope( managedTypes );
    353359        }
     360
     361ast::ConstructorInit * genCtorInit( const CodeLocation & loc, const ast::ObjectDecl * objDecl ) {
     362        // call into genImplicitCall from Autogen.h to generate calls to ctor/dtor for each
     363        // constructable object
     364        InitExpander_new srcParam{ objDecl->init }, nullParam{ (const ast::Init *)nullptr };
     365       
     366        ast::ptr< ast::Stmt > ctor = SymTab::genImplicitCall(
     367                srcParam, new ast::VariableExpr{ loc, objDecl }, loc, "?{}", objDecl );
     368        ast::ptr< ast::Stmt > dtor = SymTab::genImplicitCall(
     369                nullParam, new ast::VariableExpr{ loc, objDecl }, loc, "^?{}", objDecl,
     370                SymTab::LoopBackward );
     371       
     372        // check that either both ctor and dtor are present, or neither
     373        assert( (bool)ctor == (bool)dtor );
     374
     375        if ( ctor ) {
     376                // need to remember init expression, in case no ctors exist. If ctor does exist, want to
     377                // use ctor expression instead of init.
     378                ctor.strict_as< ast::ImplicitCtorDtorStmt >();
     379                dtor.strict_as< ast::ImplicitCtorDtorStmt >();
     380
     381                return new ast::ConstructorInit{ loc, ctor, dtor, objDecl->init };
     382        }
     383
     384        return nullptr;
     385}
     386
    354387} // namespace InitTweak
    355388
  • src/InitTweak/GenInit.h

    r7951100 rb067d9b  
    1919#include <string>              // for string
    2020
     21#include "AST/Fwd.hpp"
     22#include "Common/CodeLocation.h"
     23#include "GenPoly/ScopedSet.h" // for ScopedSet
    2124#include "SynTree/SynTree.h"   // for Visitor Nodes
    22 
    23 #include "GenPoly/ScopedSet.h" // for ScopedSet
    2425
    2526namespace InitTweak {
     
    3536        /// creates an appropriate ConstructorInit node which contains a constructor, destructor, and C-initializer
    3637        ConstructorInit * genCtorInit( ObjectDecl * objDecl );
     38        ast::ConstructorInit * genCtorInit( const CodeLocation & loc, const ast::ObjectDecl * objDecl );
    3739
    3840        class ManagedTypes {
  • src/InitTweak/InitTweak.cc

    r7951100 rb067d9b  
     1//
     2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
     3//
     4// The contents of this file are covered under the licence agreement in the
     5// file "LICENCE" distributed with Cforall.
     6//
     7// InitTweak.cc --
     8//
     9// Author           : Rob Schluntz
     10// Created On       : Fri May 13 11:26:36 2016
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Thu Jul 25 22:21:48 2019
     13// Update Count     : 7
     14//
     15
    116#include <algorithm>               // for find, all_of
    217#include <cassert>                 // for assertf, assert, strict_dynamic_cast
     
    419#include <iterator>                // for back_insert_iterator, back_inserter
    520#include <memory>                  // for __shared_ptr
    6 
     21#include <vector>
     22
     23#include "AST/Expr.hpp"
     24#include "AST/Init.hpp"
     25#include "AST/Node.hpp"
     26#include "AST/Pass.hpp"
     27#include "AST/Stmt.hpp"
     28#include "AST/Type.hpp"
    729#include "Common/PassVisitor.h"
    830#include "Common/SemanticError.h"  // for SemanticError
     
    2648#include "Tuples/Tuples.h"         // for Tuples::isTtype
    2749
    28 class UntypedValofExpr;
    29 
    3050namespace InitTweak {
    3151        namespace {
     
    6787                };
    6888
    69                 struct InitFlattener : public WithShortCircuiting {
     89                struct InitFlattener_old : public WithShortCircuiting {
    7090                        void previsit( SingleInit * singleInit ) {
    7191                                visit_children = false;
     
    7595                };
    7696
    77         }
     97                struct InitFlattener_new : public ast::WithShortCircuiting {
     98                        std::vector< ast::ptr< ast::Expr > > argList;
     99
     100                        void previsit( const ast::SingleInit * singleInit ) {
     101                                visit_children = false;
     102                                argList.emplace_back( singleInit->value );
     103                        }
     104                };
     105
     106        } // anonymous namespace
    78107
    79108        std::list< Expression * > makeInitList( Initializer * init ) {
    80                 PassVisitor<InitFlattener> flattener;
     109                PassVisitor<InitFlattener_old> flattener;
    81110                maybeAccept( init, flattener );
    82111                return flattener.pass.argList;
     
    95124        }
    96125
    97         class InitExpander::ExpanderImpl {
     126std::vector< ast::ptr< ast::Expr > > makeInitList( const ast::Init * init ) {
     127        ast::Pass< InitFlattener_new > flattener;
     128        maybe_accept( init, flattener );
     129        return std::move( flattener.pass.argList );
     130}
     131
     132        class InitExpander_old::ExpanderImpl {
    98133        public:
    99134                virtual ~ExpanderImpl() = default;
     
    102137        };
    103138
    104         class InitImpl : public InitExpander::ExpanderImpl {
     139        class InitImpl_old : public InitExpander_old::ExpanderImpl {
    105140        public:
    106                 InitImpl( Initializer * init ) : init( init ) {}
    107                 virtual ~InitImpl() = default;
     141                InitImpl_old( Initializer * init ) : init( init ) {}
     142                virtual ~InitImpl_old() = default;
    108143
    109144                virtual std::list< Expression * > next( __attribute((unused)) std::list< Expression * > & indices ) {
     
    119154        };
    120155
    121         class ExprImpl : public InitExpander::ExpanderImpl {
     156        class ExprImpl_old : public InitExpander_old::ExpanderImpl {
    122157        public:
    123                 ExprImpl( Expression * expr ) : arg( expr ) {}
    124                 virtual ~ExprImpl() { delete arg; }
     158                ExprImpl_old( Expression * expr ) : arg( expr ) {}
     159                virtual ~ExprImpl_old() { delete arg; }
    125160
    126161                virtual std::list< Expression * > next( std::list< Expression * > & indices ) {
     
    146181        };
    147182
    148         InitExpander::InitExpander( Initializer * init ) : expander( new InitImpl( init ) ) {}
    149 
    150         InitExpander::InitExpander( Expression * expr ) : expander( new ExprImpl( expr ) ) {}
    151 
    152         std::list< Expression * > InitExpander::operator*() {
     183        InitExpander_old::InitExpander_old( Initializer * init ) : expander( new InitImpl_old( init ) ) {}
     184
     185        InitExpander_old::InitExpander_old( Expression * expr ) : expander( new ExprImpl_old( expr ) ) {}
     186
     187        std::list< Expression * > InitExpander_old::operator*() {
    153188                return cur;
    154189        }
    155190
    156         InitExpander & InitExpander::operator++() {
     191        InitExpander_old & InitExpander_old::operator++() {
    157192                cur = expander->next( indices );
    158193                return *this;
     
    160195
    161196        // use array indices list to build switch statement
    162         void InitExpander::addArrayIndex( Expression * index, Expression * dimension ) {
     197        void InitExpander_old::addArrayIndex( Expression * index, Expression * dimension ) {
    163198                indices.push_back( index );
    164199                indices.push_back( dimension );
    165200        }
    166201
    167         void InitExpander::clearArrayIndices() {
     202        void InitExpander_old::clearArrayIndices() {
    168203                deleteAll( indices );
    169204                indices.clear();
    170205        }
    171206
    172         bool InitExpander::addReference() {
     207        bool InitExpander_old::addReference() {
    173208                bool added = false;
    174209                for ( Expression *& expr : cur ) {
     
    201236
    202237                template< typename OutIterator >
    203                 void build( UntypedExpr * callExpr, InitExpander::IndexList::iterator idx, InitExpander::IndexList::iterator idxEnd, Initializer * init, OutIterator out ) {
     238                void build( UntypedExpr * callExpr, InitExpander_old::IndexList::iterator idx, InitExpander_old::IndexList::iterator idxEnd, Initializer * init, OutIterator out ) {
    204239                        if ( idx == idxEnd ) return;
    205240                        Expression * index = *idx++;
     
    258293        // remaining elements.
    259294        // To accomplish this, generate switch statement, consuming all of expander's elements
    260         Statement * InitImpl::buildListInit( UntypedExpr * dst, std::list< Expression * > & indices ) {
     295        Statement * InitImpl_old::buildListInit( UntypedExpr * dst, std::list< Expression * > & indices ) {
    261296                if ( ! init ) return nullptr;
    262297                CompoundStmt * block = new CompoundStmt();
     
    271306        }
    272307
    273         Statement * ExprImpl::buildListInit( UntypedExpr *, std::list< Expression * > & ) {
     308        Statement * ExprImpl_old::buildListInit( UntypedExpr *, std::list< Expression * > & ) {
    274309                return nullptr;
    275310        }
    276311
    277         Statement * InitExpander::buildListInit( UntypedExpr * dst ) {
     312        Statement * InitExpander_old::buildListInit( UntypedExpr * dst ) {
    278313                return expander->buildListInit( dst, indices );
    279314        }
     315
     316class InitExpander_new::ExpanderImpl {
     317public:
     318        virtual ~ExpanderImpl() = default;
     319        virtual std::vector< ast::ptr< ast::Expr > > next( IndexList & indices ) = 0;
     320        virtual ast::ptr< ast::Stmt > buildListInit(
     321                ast::UntypedExpr * callExpr, IndexList & indices ) = 0;
     322};
     323
     324namespace {
     325        template< typename Out >
     326        void buildCallExpr(
     327                ast::UntypedExpr * callExpr, const ast::Expr * index, const ast::Expr * dimension,
     328                const ast::Init * init, Out & out
     329        ) {
     330                const CodeLocation & loc = init->location;
     331
     332                auto cond = new ast::UntypedExpr{
     333                        loc, new ast::NameExpr{ loc, "?<?" }, { index, dimension } };
     334
     335                std::vector< ast::ptr< ast::Expr > > args = makeInitList( init );
     336                splice( callExpr->args, args );
     337
     338                out.emplace_back( new ast::IfStmt{ loc, cond, new ast::ExprStmt{ loc, callExpr } } );
     339
     340                out.emplace_back( new ast::ExprStmt{
     341                        loc, new ast::UntypedExpr{ loc, new ast::NameExpr{ loc, "++?" }, { index } } } );
     342        }
     343
     344        template< typename Out >
     345        void build(
     346                ast::UntypedExpr * callExpr, const InitExpander_new::IndexList & indices,
     347                const ast::Init * init, Out & out
     348        ) {
     349                if ( indices.empty() ) return;
     350
     351                unsigned idx = 0;
     352
     353                const ast::Expr * index = indices[idx++];
     354                assert( idx != indices.size() );
     355                const ast::Expr * dimension = indices[idx++];
     356
     357                if ( idx == indices.size() ) {
     358                        if ( auto listInit = dynamic_cast< const ast::ListInit * >( init ) ) {
     359                                for ( const ast::Init * init : *listInit ) {
     360                                        buildCallExpr( callExpr, index, dimension, init, out );
     361                                }
     362                        } else {
     363                                buildCallExpr( callExpr, index, dimension, init, out );
     364                        }
     365                } else {
     366                        const CodeLocation & loc = init->location;
     367
     368                        unsigned long cond = 0;
     369                        auto listInit = dynamic_cast< const ast::ListInit * >( init );
     370                        if ( ! listInit ) { SemanticError( loc, "unbalanced list initializers" ); }
     371
     372                        static UniqueName targetLabel( "L__autogen__" );
     373                        ast::Label switchLabel{
     374                                loc, targetLabel.newName(), { new ast::Attribute{ "unused" } } };
     375
     376                        std::vector< ast::ptr< ast::Stmt > > branches;
     377                        for ( const ast::Init * init : *listInit ) {
     378                                auto condition = ast::ConstantExpr::from_ulong( loc, cond );
     379                                ++cond;
     380
     381                                std::vector< ast::ptr< ast::Stmt > > stmts;
     382                                build( callExpr, indices, init, stmts );
     383                                stmts.emplace_back(
     384                                        new ast::BranchStmt{ loc, ast::BranchStmt::Break, switchLabel } );
     385                                branches.emplace_back( new ast::CaseStmt{ loc, condition, std::move( stmts ) } );
     386                        }
     387                        out.emplace_back( new ast::SwitchStmt{ loc, index, std::move( branches ) } );
     388                        out.emplace_back( new ast::NullStmt{ loc, { switchLabel } } );
     389                }
     390        }
     391
     392        class InitImpl_new final : public InitExpander_new::ExpanderImpl {
     393                ast::ptr< ast::Init > init;
     394        public:
     395                InitImpl_new( const ast::Init * i ) : init( i ) {}
     396
     397                std::vector< ast::ptr< ast::Expr > > next( InitExpander_new::IndexList & ) override {
     398                        return makeInitList( init );
     399                }
     400
     401                ast::ptr< ast::Stmt > buildListInit(
     402                        ast::UntypedExpr * callExpr, InitExpander_new::IndexList & indices
     403                ) override {
     404                        // If array came with an initializer list, initialize each element. We may have more
     405                        // initializers than elements of the array; need to check at each index that we have
     406                        // not exceeded size. We may have fewer initializers than elements in the array; need
     407                        // to default-construct remaining elements. To accomplish this, generate switch
     408                        // statement consuming all of expander's elements
     409
     410                        if ( ! init ) return {};
     411
     412                        std::list< ast::ptr< ast::Stmt > > stmts;
     413                        build( callExpr, indices, init, stmts );
     414                        if ( stmts.empty() ) {
     415                                return {};
     416                        } else {
     417                                auto block = new ast::CompoundStmt{ init->location, std::move( stmts ) };
     418                                init = nullptr;  // consumed in creating the list init
     419                                return block;
     420                        }
     421                }
     422        };
     423
     424        class ExprImpl_new final : public InitExpander_new::ExpanderImpl {
     425                ast::ptr< ast::Expr > arg;
     426        public:
     427                ExprImpl_new( const ast::Expr * a ) : arg( a ) {}
     428
     429                std::vector< ast::ptr< ast::Expr > > next(
     430                        InitExpander_new::IndexList & indices
     431                ) override {
     432                        if ( ! arg ) return {};
     433
     434                        const CodeLocation & loc = arg->location;
     435                        const ast::Expr * expr = arg;
     436                        for ( auto it = indices.rbegin(); it != indices.rend(); ++it ) {
     437                                // go through indices and layer on subscript exprs ?[?]
     438                                ++it;
     439                                expr = new ast::UntypedExpr{
     440                                        loc, new ast::NameExpr{ loc, "?[?]" }, { expr, *it } };
     441                        }
     442                        return { expr };
     443                }
     444
     445                ast::ptr< ast::Stmt > buildListInit(
     446                        ast::UntypedExpr *, InitExpander_new::IndexList &
     447                ) override {
     448                        return {};
     449                }
     450        };
     451} // anonymous namespace
     452
     453InitExpander_new::InitExpander_new( const ast::Init * init )
     454: expander( new InitImpl_new{ init } ), crnt(), indices() {}
     455
     456InitExpander_new::InitExpander_new( const ast::Expr * expr )
     457: expander( new ExprImpl_new{ expr } ), crnt(), indices() {}
     458
     459std::vector< ast::ptr< ast::Expr > > InitExpander_new::operator* () { return crnt; }
     460
     461InitExpander_new & InitExpander_new::operator++ () {
     462        crnt = expander->next( indices );
     463        return *this;
     464}
     465
     466/// builds statement which has the same semantics as a C-style list initializer (for array
     467/// initializers) using callExpr as the base expression to perform initialization
     468ast::ptr< ast::Stmt > InitExpander_new::buildListInit( ast::UntypedExpr * callExpr ) {
     469        return expander->buildListInit( callExpr, indices );
     470}
     471
     472void InitExpander_new::addArrayIndex( const ast::Expr * index, const ast::Expr * dimension ) {
     473        indices.emplace_back( index );
     474        indices.emplace_back( dimension );
     475}
     476
     477void InitExpander_new::clearArrayIndices() { indices.clear(); }
     478
     479bool InitExpander_new::addReference() {
     480        for ( ast::ptr< ast::Expr > & expr : crnt ) {
     481                expr = new ast::AddressExpr{ expr };
     482        }
     483        return ! crnt.empty();
     484}
    280485
    281486        Type * getTypeofThis( FunctionType * ftype ) {
     
    306511        }
    307512
    308         struct CallFinder {
    309                 CallFinder( const std::list< std::string > & names ) : names( names ) {}
     513        struct CallFinder_old {
     514                CallFinder_old( const std::list< std::string > & names ) : names( names ) {}
    310515
    311516                void postvisit( ApplicationExpr * appExpr ) {
     
    330535        };
    331536
     537        struct CallFinder_new final {
     538                std::vector< ast::ptr< ast::Expr > > matches;
     539                const std::vector< std::string > names;
     540
     541                CallFinder_new( std::vector< std::string > && ns ) : matches(), names( std::move(ns) ) {}
     542
     543                void handleCallExpr( const ast::Expr * expr ) {
     544                        std::string fname = getFunctionName( expr );
     545                        if ( std::find( names.begin(), names.end(), fname ) != names.end() ) {
     546                                matches.emplace_back( expr );
     547                        }
     548                }
     549
     550                void postvisit( const ast::ApplicationExpr * expr ) { handleCallExpr( expr ); }
     551                void postvisit( const ast::UntypedExpr *     expr ) { handleCallExpr( expr ); }
     552        };
     553
    332554        void collectCtorDtorCalls( Statement * stmt, std::list< Expression * > & matches ) {
    333                 static PassVisitor<CallFinder> finder( std::list< std::string >{ "?{}", "^?{}" } );
     555                static PassVisitor<CallFinder_old> finder( std::list< std::string >{ "?{}", "^?{}" } );
    334556                finder.pass.matches = &matches;
    335557                maybeAccept( stmt, finder );
     558        }
     559
     560        std::vector< ast::ptr< ast::Expr > > collectCtorDtorCalls( const ast::Stmt * stmt ) {
     561                ast::Pass< CallFinder_new > finder{ std::vector< std::string >{ "?{}", "^?{}" } };
     562                maybe_accept( stmt, finder );
     563                return std::move( finder.pass.matches );
    336564        }
    337565
     
    339567                std::list< Expression * > matches;
    340568                collectCtorDtorCalls( stmt, matches );
    341                 assert( matches.size() <= 1 );
     569                assertf( matches.size() <= 1, "%zd constructor/destructors found in %s", matches.size(), toString( stmt ).c_str() );
    342570                return matches.size() == 1 ? matches.front() : nullptr;
    343571        }
     
    345573        namespace {
    346574                DeclarationWithType * getCalledFunction( Expression * expr );
     575                const ast::DeclWithType * getCalledFunction( const ast::Expr * expr );
    347576
    348577                template<typename CallExpr>
     
    354583                        return getCalledFunction( expr->get_args().front() );
    355584                }
     585
     586                template<typename CallExpr>
     587                const ast::DeclWithType * handleDerefCalledFunction( const CallExpr * expr ) {
     588                        // (*f)(x) => should get "f"
     589                        std::string name = getFunctionName( expr );
     590                        assertf( name == "*?", "Unexpected untyped expression: %s", name.c_str() );
     591                        assertf( ! expr->args.empty(), "Cannot get called function from dereference with no arguments" );
     592                        return getCalledFunction( expr->args.front() );
     593                }
     594
    356595
    357596                DeclarationWithType * getCalledFunction( Expression * expr ) {
     
    374613                        return nullptr;
    375614                }
     615
     616                const ast::DeclWithType * getCalledFunction( const ast::Expr * expr ) {
     617                        assert( expr );
     618                        if ( const ast::VariableExpr * varExpr = dynamic_cast< const ast::VariableExpr * >( expr ) ) {
     619                                return varExpr->var;
     620                        } else if ( const ast::MemberExpr * memberExpr = dynamic_cast< const ast::MemberExpr * >( expr ) ) {
     621                                return memberExpr->member;
     622                        } else if ( const ast::CastExpr * castExpr = dynamic_cast< const ast::CastExpr * >( expr ) ) {
     623                                return getCalledFunction( castExpr->arg );
     624                        } else if ( const ast::UntypedExpr * untypedExpr = dynamic_cast< const ast::UntypedExpr * >( expr ) ) {
     625                                return handleDerefCalledFunction( untypedExpr );
     626                        } else if ( const ast::ApplicationExpr * appExpr = dynamic_cast< const ast::ApplicationExpr * > ( expr ) ) {
     627                                return handleDerefCalledFunction( appExpr );
     628                        } else if ( const ast::AddressExpr * addrExpr = dynamic_cast< const ast::AddressExpr * >( expr ) ) {
     629                                return getCalledFunction( addrExpr->arg );
     630                        } else if ( const ast::CommaExpr * commaExpr = dynamic_cast< const ast::CommaExpr * >( expr ) ) {
     631                                return getCalledFunction( commaExpr->arg2 );
     632                        }
     633                        return nullptr;
     634                }
     635
     636                DeclarationWithType * getFunctionCore( const Expression * expr ) {
     637                        if ( const auto * appExpr = dynamic_cast< const ApplicationExpr * >( expr ) ) {
     638                                return getCalledFunction( appExpr->function );
     639                        } else if ( const auto * untyped = dynamic_cast< const UntypedExpr * >( expr ) ) {
     640                                return getCalledFunction( untyped->function );
     641                        }
     642                        assertf( false, "getFunction with unknown expression: %s", toString( expr ).c_str() );
     643                }
    376644        }
    377645
    378646        DeclarationWithType * getFunction( Expression * expr ) {
    379                 if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( expr ) ) {
    380                         return getCalledFunction( appExpr->get_function() );
    381                 } else if ( UntypedExpr * untyped = dynamic_cast< UntypedExpr * > ( expr ) ) {
    382                         return getCalledFunction( untyped->get_function() );
     647                return getFunctionCore( expr );
     648        }
     649
     650        const DeclarationWithType * getFunction( const Expression * expr ) {
     651                return getFunctionCore( expr );
     652        }
     653
     654        const ast::DeclWithType * getFunction( const ast::Expr * expr ) {
     655                if ( const ast::ApplicationExpr * appExpr = dynamic_cast< const ast::ApplicationExpr * >( expr ) ) {
     656                        return getCalledFunction( appExpr->func );
     657                } else if ( const ast::UntypedExpr * untyped = dynamic_cast< const ast::UntypedExpr * > ( expr ) ) {
     658                        return getCalledFunction( untyped->func );
    383659                }
    384660                assertf( false, "getFunction received unknown expression: %s", toString( expr ).c_str() );
     
    395671        }
    396672
     673        const ast::ApplicationExpr * isIntrinsicCallExpr( const ast::Expr * expr ) {
     674                auto appExpr = dynamic_cast< const ast::ApplicationExpr * >( expr );
     675                if ( ! appExpr ) return nullptr;
     676
     677                const ast::DeclWithType * func = getCalledFunction( appExpr->func );
     678                assertf( func,
     679                        "getCalledFunction returned nullptr: %s", toString( appExpr->func ).c_str() );
     680
     681                // check for Intrinsic only -- don't want to remove all overridable ctor/dtor because
     682                // autogenerated ctor/dtor will call all member dtors, and some members may have a
     683                // user-defined dtor
     684                return func->linkage == ast::Linkage::Intrinsic ? appExpr : nullptr;
     685        }
     686
    397687        namespace {
    398688                template <typename Predicate>
     
    403693                        return std::all_of( callExprs.begin(), callExprs.end(), pred);
    404694                }
     695
     696                template <typename Predicate>
     697                bool allofCtorDtor( const ast::Stmt * stmt, const Predicate & pred ) {
     698                        std::vector< ast::ptr< ast::Expr > > callExprs = collectCtorDtorCalls( stmt );
     699                        return std::all_of( callExprs.begin(), callExprs.end(), pred );
     700                }
    405701        }
    406702
     
    408704                return allofCtorDtor( stmt, []( Expression * callExpr ){
    409705                        if ( ApplicationExpr * appExpr = isIntrinsicCallExpr( callExpr ) ) {
    410                                 FunctionType *funcType = GenPoly::getFunctionType( appExpr->get_function()->get_result() );
     706                                FunctionType *funcType = GenPoly::getFunctionType( appExpr->function->result );
    411707                                assert( funcType );
    412708                                return funcType->get_parameters().size() == 1;
     709                        }
     710                        return false;
     711                });
     712        }
     713
     714        bool isIntrinsicSingleArgCallStmt( const ast::Stmt * stmt ) {
     715                return allofCtorDtor( stmt, []( const ast::Expr * callExpr ){
     716                        if ( const ast::ApplicationExpr * appExpr = isIntrinsicCallExpr( callExpr ) ) {
     717                                const ast::FunctionType * funcType =
     718                                        GenPoly::getFunctionType( appExpr->func->result );
     719                                assert( funcType );
     720                                return funcType->params.size() == 1;
    413721                        }
    414722                        return false;
     
    429737                                if ( pos == 0 ) return arg;
    430738                                pos--;
     739                        }
     740                        assert( false );
     741                }
     742
     743                template<typename CallExpr>
     744                const ast::Expr * callArg( const CallExpr * call, unsigned int pos ) {
     745                        if( pos >= call->args.size() ) {
     746                                assertf( false, "getCallArg for argument that doesn't exist: (%u); %s.",
     747                                        pos, toString( call ).c_str() );
     748                        }
     749                        for ( const ast::Expr * arg : call->args ) {
     750                                if ( pos == 0 ) return arg;
     751                                --pos;
    431752                        }
    432753                        assert( false );
     
    453774        }
    454775
     776        const ast::Expr * getCallArg( const ast::Expr * call, unsigned pos ) {
     777                if ( auto app = dynamic_cast< const ast::ApplicationExpr * >( call ) ) {
     778                        return callArg( app, pos );
     779                } else if ( auto untyped = dynamic_cast< const ast::UntypedExpr * >( call ) ) {
     780                        return callArg( untyped, pos );
     781                } else if ( auto tupleAssn = dynamic_cast< const ast::TupleAssignExpr * >( call ) ) {
     782                        const std::list<ast::ptr<ast::Stmt>>& stmts = tupleAssn->stmtExpr->stmts->kids;
     783                        assertf( ! stmts.empty(), "TupleAssignExpr missing statements." );
     784                        auto stmt  = strict_dynamic_cast< const ast::ExprStmt * >( stmts.back().get() );
     785                        auto tuple = strict_dynamic_cast< const ast::TupleExpr * >( stmt->expr.get() );
     786                        assertf( ! tuple->exprs.empty(), "TupleAssignExpr has empty tuple expr.");
     787                        return getCallArg( tuple->exprs.front(), pos );
     788                } else if ( auto ctor = dynamic_cast< const ast::ImplicitCopyCtorExpr * >( call ) ) {
     789                        return getCallArg( ctor->callExpr, pos );
     790                } else {
     791                        assertf( false, "Unexpected expression type passed to getCallArg: %s",
     792                                toString( call ).c_str() );
     793                }
     794        }
     795
    455796        namespace {
    456797                std::string funcName( Expression * func );
     798                std::string funcName( const ast::Expr * func );
    457799
    458800                template<typename CallExpr>
     
    463805                        assertf( ! expr->get_args().empty(), "Cannot get function name from dereference with no arguments" );
    464806                        return funcName( expr->get_args().front() );
     807                }
     808
     809                template<typename CallExpr>
     810                std::string handleDerefName( const CallExpr * expr ) {
     811                        // (*f)(x) => should get name "f"
     812                        std::string name = getFunctionName( expr );
     813                        assertf( name == "*?", "Unexpected untyped expression: %s", name.c_str() );
     814                        assertf( ! expr->args.empty(), "Cannot get function name from dereference with no arguments" );
     815                        return funcName( expr->args.front() );
    465816                }
    466817
     
    486837                        }
    487838                }
     839
     840                std::string funcName( const ast::Expr * func ) {
     841                        if ( const ast::NameExpr * nameExpr = dynamic_cast< const ast::NameExpr * >( func ) ) {
     842                                return nameExpr->name;
     843                        } else if ( const ast::VariableExpr * varExpr = dynamic_cast< const ast::VariableExpr * >( func ) ) {
     844                                return varExpr->var->name;
     845                        }       else if ( const ast::CastExpr * castExpr = dynamic_cast< const ast::CastExpr * >( func ) ) {
     846                                return funcName( castExpr->arg );
     847                        } else if ( const ast::MemberExpr * memberExpr = dynamic_cast< const ast::MemberExpr * >( func ) ) {
     848                                return memberExpr->member->name;
     849                        } else if ( const ast::UntypedMemberExpr * memberExpr = dynamic_cast< const ast::UntypedMemberExpr * > ( func ) ) {
     850                                return funcName( memberExpr->member );
     851                        } else if ( const ast::UntypedExpr * untypedExpr = dynamic_cast< const ast::UntypedExpr * >( func ) ) {
     852                                return handleDerefName( untypedExpr );
     853                        } else if ( const ast::ApplicationExpr * appExpr = dynamic_cast< const ast::ApplicationExpr * >( func ) ) {
     854                                return handleDerefName( appExpr );
     855                        } else if ( const ast::ConstructorExpr * ctorExpr = dynamic_cast< const ast::ConstructorExpr * >( func ) ) {
     856                                return funcName( getCallArg( ctorExpr->callExpr, 0 ) );
     857                        } else {
     858                                assertf( false, "Unexpected expression type being called as a function in call expression: %s", toString( func ).c_str() );
     859                        }
     860                }
    488861        }
    489862
     
    502875        }
    503876
     877        std::string getFunctionName( const ast::Expr * expr ) {
     878                // there's some unforunate overlap here with getCalledFunction. Ideally this would be able to use getCalledFunction and
     879                // return the name of the DeclarationWithType, but this needs to work for NameExpr and UntypedMemberExpr, where getCalledFunction
     880                // can't possibly do anything reasonable.
     881                if ( const ast::ApplicationExpr * appExpr = dynamic_cast< const ast::ApplicationExpr * >( expr ) ) {
     882                        return funcName( appExpr->func );
     883                } else if ( const ast::UntypedExpr * untypedExpr = dynamic_cast< const ast::UntypedExpr * > ( expr ) ) {
     884                        return funcName( untypedExpr->func );
     885                } else {
     886                        std::cerr << expr << std::endl;
     887                        assertf( false, "Unexpected expression type passed to getFunctionName" );
     888                }
     889        }
     890
    504891        Type * getPointerBase( Type * type ) {
    505892                if ( PointerType * ptrType = dynamic_cast< PointerType * >( type ) ) {
     
    513900                }
    514901        }
     902        const ast::Type* getPointerBase( const ast::Type* t ) {
     903                if ( const auto * p = dynamic_cast< const ast::PointerType * >( t ) ) {
     904                        return p->base;
     905                } else if ( const auto * a = dynamic_cast< const ast::ArrayType * >( t ) ) {
     906                        return a->base;
     907                } else if ( const auto * r = dynamic_cast< const ast::ReferenceType * >( t ) ) {
     908                        return r->base;
     909                } else return nullptr;
     910        }
    515911
    516912        Type * isPointerType( Type * type ) {
     
    561957                void previsit( OffsetofExpr * ) {}
    562958                void previsit( OffsetPackExpr * ) {}
    563                 void previsit( AttrExpr * ) {}
    564959                void previsit( CommaExpr * ) {}
    565960                void previsit( LogicalExpr * ) {}
     
    6091004        bool isCtorDtorAssign( const std::string & str ) { return isCtorDtor( str ) || isAssignment( str ); }
    6101005
    611         FunctionDecl * isCopyFunction( Declaration * decl, const std::string & fname ) {
    612                 FunctionDecl * function = dynamic_cast< FunctionDecl * >( decl );
     1006        const FunctionDecl * isCopyFunction( const Declaration * decl, const std::string & fname ) {
     1007                const FunctionDecl * function = dynamic_cast< const FunctionDecl * >( decl );
    6131008                if ( ! function ) return nullptr;
    6141009                if ( function->name != fname ) return nullptr;
     
    6271022        }
    6281023
    629         FunctionDecl * isAssignment( Declaration * decl ) {
     1024        bool isCopyFunction( const ast::FunctionDecl * decl ) {
     1025                const ast::FunctionType * ftype = decl->type;
     1026                if ( ftype->params.size() != 2 ) return false;
     1027
     1028                const ast::Type * t1 = getPointerBase( ftype->params.front()->get_type() );
     1029                if ( ! t1 ) return false;
     1030                const ast::Type * t2 = ftype->params.back()->get_type();
     1031
     1032                return ResolvExpr::typesCompatibleIgnoreQualifiers( t1, t2, ast::SymbolTable{} );
     1033        }
     1034
     1035        const FunctionDecl * isAssignment( const Declaration * decl ) {
    6301036                return isCopyFunction( decl, "?=?" );
    6311037        }
    632         FunctionDecl * isDestructor( Declaration * decl ) {
    633                 if ( isDestructor( decl->get_name() ) ) {
    634                         return dynamic_cast< FunctionDecl * >( decl );
     1038        const FunctionDecl * isDestructor( const Declaration * decl ) {
     1039                if ( isDestructor( decl->name ) ) {
     1040                        return dynamic_cast< const FunctionDecl * >( decl );
    6351041                }
    6361042                return nullptr;
    6371043        }
    638         FunctionDecl * isDefaultConstructor( Declaration * decl ) {
     1044        const FunctionDecl * isDefaultConstructor( const Declaration * decl ) {
    6391045                if ( isConstructor( decl->name ) ) {
    640                         if ( FunctionDecl * func = dynamic_cast< FunctionDecl * >( decl ) ) {
     1046                        if ( const FunctionDecl * func = dynamic_cast< const FunctionDecl * >( decl ) ) {
    6411047                                if ( func->type->parameters.size() == 1 ) {
    6421048                                        return func;
     
    6461052                return nullptr;
    6471053        }
    648         FunctionDecl * isCopyConstructor( Declaration * decl ) {
     1054        const FunctionDecl * isCopyConstructor( const Declaration * decl ) {
    6491055                return isCopyFunction( decl, "?{}" );
    6501056        }
  • src/InitTweak/InitTweak.h

    r7951100 rb067d9b  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // RemoveInit.h --
     7// InitTweak.h --
    88//
    99// Author           : Rob Schluntz
    1010// Created On       : Fri May 13 11:26:36 2016
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Jul 22 09:30:33 2017
    13 // Update Count     : 4
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Fri Jul 19 14:18:00 2019
     13// Update Count     : 6
    1414//
    1515
     
    1919#include <memory>             // for shared_ptr
    2020#include <string>             // for string, allocator
     21#include <vector>
    2122
     23#include "AST/Fwd.hpp"        // for AST nodes
    2224#include "SynTree/SynTree.h"  // for Visitor Nodes
    2325
    2426// helper functions for initialization
    2527namespace InitTweak {
    26         FunctionDecl * isAssignment( Declaration * decl );
    27         FunctionDecl * isDestructor( Declaration * decl );
    28         FunctionDecl * isDefaultConstructor( Declaration * decl );
    29         FunctionDecl * isCopyConstructor( Declaration * decl );
    30         FunctionDecl * isCopyFunction( Declaration * decl, const std::string & fname );
     28        const FunctionDecl * isAssignment( const Declaration * decl );
     29        const FunctionDecl * isDestructor( const Declaration * decl );
     30        const FunctionDecl * isDefaultConstructor( const Declaration * decl );
     31        const FunctionDecl * isCopyConstructor( const Declaration * decl );
     32        const FunctionDecl * isCopyFunction( const Declaration * decl, const std::string & fname );
     33        bool isCopyFunction( const ast::FunctionDecl * decl );
    3134
    3235        /// returns the base type of the first parameter to a constructor/destructor/assignment function
     
    4144        /// transform Initializer into an argument list that can be passed to a call expression
    4245        std::list< Expression * > makeInitList( Initializer * init );
     46        std::vector< ast::ptr< ast::Expr > > makeInitList( const ast::Init * init );
    4347
    4448        /// True if the resolver should try to construct dwt
     
    5761        /// returns the declaration of the function called by the expr (must be ApplicationExpr or UntypedExpr)
    5862        DeclarationWithType * getFunction( Expression * expr );
     63        const DeclarationWithType * getFunction( const Expression * expr );
     64        const ast::DeclWithType * getFunction( const ast::Expr * expr );
    5965
    6066        /// Non-Null if expr is a call expression whose target function is intrinsic
    6167        ApplicationExpr * isIntrinsicCallExpr( Expression * expr );
     68        const ast::ApplicationExpr * isIntrinsicCallExpr( const ast::Expr * expr);
    6269
    6370        /// True if stmt is a call statement where the function called is intrinsic and takes one parameter.
     
    6572        /// Currently has assertions that make it less than fully general.
    6673        bool isIntrinsicSingleArgCallStmt( Statement * stmt );
     74        bool isIntrinsicSingleArgCallStmt( const ast::Stmt * stmt );
    6775
    6876        /// True if stmt is a call statement where the function called is intrinsic.
     
    7179        /// get all Ctor/Dtor call expressions from a Statement
    7280        void collectCtorDtorCalls( Statement * stmt, std::list< Expression * > & matches );
     81        std::vector< ast::ptr< ast::Expr > > collectCtorDtorCalls( const ast::Stmt * stmt );
    7382
    7483        /// get the Ctor/Dtor call expression from a Statement that looks like a generated ctor/dtor call
     
    7786        /// returns the name of the function being called
    7887        std::string getFunctionName( Expression * expr );
     88        std::string getFunctionName( const ast::Expr * expr );
    7989
    8090        /// returns the argument to a call expression in position N indexed from 0
    8191        Expression *& getCallArg( Expression * callExpr, unsigned int pos );
     92        const ast::Expr * getCallArg( const ast::Expr * call, unsigned pos );
    8293
    8394        /// returns the base type of a PointerType or ArrayType, else returns NULL
    8495        Type * getPointerBase( Type * );
     96        const ast::Type* getPointerBase( const ast::Type* );
    8597
    8698        /// returns the argument if it is a PointerType or ArrayType, else returns NULL
     
    91103        bool isConstExpr( Initializer * init );
    92104
    93         class InitExpander {
     105        class InitExpander_old {
    94106        public:
    95107                // expand by stepping through init to get each list of arguments
    96                 InitExpander( Initializer * init );
     108                InitExpander_old( Initializer * init );
    97109
    98110                // always expand to expr
    99                 InitExpander( Expression * expr );
     111                InitExpander_old( Expression * expr );
    100112
    101113                // iterator-like interface
    102114                std::list< Expression * > operator*();
    103                 InitExpander & operator++();
     115                InitExpander_old & operator++();
    104116
    105117                // builds statement which has the same semantics as a C-style list initializer
     
    120132                IndexList indices;
    121133        };
     134
     135        class InitExpander_new {
     136        public:
     137                using IndexList = std::vector< ast::ptr< ast::Expr > >;
     138                class ExpanderImpl;
     139
     140        private:
     141                std::shared_ptr< ExpanderImpl > expander;
     142                std::vector< ast::ptr< ast::Expr > > crnt;
     143                // invariant: list of size 2N (elements come in pairs [index, dimension])
     144                IndexList indices;
     145
     146        public:
     147                /// Expand by stepping through init to get each list of arguments
     148                InitExpander_new( const ast::Init * init );
     149
     150                /// Always expand to expression
     151                InitExpander_new( const ast::Expr * expr );
     152
     153                std::vector< ast::ptr< ast::Expr > > operator* ();
     154                InitExpander_new & operator++ ();
     155
     156                /// builds statement which has the same semantics as a C-style list initializer (for array
     157                /// initializers) using callExpr as the base expression to perform initialization.
     158                /// Mutates callExpr
     159                ast::ptr< ast::Stmt > buildListInit( ast::UntypedExpr * callExpr );
     160
     161                void addArrayIndex( const ast::Expr * index, const ast::Expr * dimension );
     162
     163                void clearArrayIndices();
     164
     165                bool addReference();
     166        };
    122167} // namespace
    123168
  • src/InitTweak/module.mk

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

    r7951100 rb067d9b  
    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

    r7951100 rb067d9b  
    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 : Mon Aug  5 12:57:46 2019
     14## Update Count     : 98
    1515###############################################################################
    1616
    1717# create object files in directory with source files
    18 AUTOMAKE_OPTIONS = subdir-objects
     18AUTOMAKE_OPTIONS = foreign subdir-objects
     19ACLOCAL_AMFLAGS  = -I automake
    1920
    2021SRC = main.cc \
    21       MakeLibCfa.cc
     22      MakeLibCfa.cc \
     23      CompilationState.cc
     24
     25SRCDEMANGLE = CompilationState.cc
    2226
    2327MAINTAINERCLEANFILES =
     28MOSTLYCLEANFILES =
    2429
    25 # Is there a way to use a variable for the directory names?
     30if WITH_LIBPROFILER
     31LIBPROFILER = -lprofiler
     32endif
    2633
     34if WITH_LIBTCMALLOC
     35LIBTCMALLOC = -ltcmalloc
     36TCMALLOCFLAG = -DTCMALLOC
     37endif
     38
     39include AST/module.mk
    2740include CodeGen/module.mk
    2841include CodeTools/module.mk
     
    3750include SynTree/module.mk
    3851include Tuples/module.mk
     52include Validate/module.mk
    3953include Virtual/module.mk
    4054
     55$(addprefix $(srcdir)/, ResolvExpr/ConversionCost.cc ResolvExpr/CommonType.cc SymTab/ManglerCommon.cc) : $(srcdir)/SynTree/Type.h
     56
     57$(srcdir)/AST/Type.hpp : BasicTypes-gen.cc
     58        ${AM_V_GEN}${CXXCOMPILE} $< -o BasicTypes-gen -Wall -Wextra
     59        @./BasicTypes-gen
     60        @rm BasicTypes-gen
     61
    4162# put into lib for now
    42 cfa_cpplibdir = ${CFA_LIBDIR}
    43 cfa_cpplib_PROGRAMS = driver/cfa-cpp
    44 driver_cfa_cpp_SOURCES = ${SRC}
    45 driver_cfa_cpp_LDADD = -ldl                     # yywrap
    46 driver_cfa_cpp_CXXFLAGS = -Wno-deprecated -Wall -Wextra -DDEBUG_ALL -I${abs_top_srcdir}/src/include -DYY_NO_INPUT -O2 -g -std=c++14
    47 driver_cfa_cpp_LDFLAGS = -Xlinker -export-dynamic
     63cfa_cpplibdir = $(CFA_LIBDIR)
     64cfa_cpplib_PROGRAMS = ../driver/cfa-cpp $(DEMANGLER)
     65EXTRA_PROGRAMS = demangler
     66___driver_cfa_cpp_SOURCES = $(SRC)
     67___driver_cfa_cpp_LDADD = -ldl $(LIBPROFILER) $(LIBTCMALLOC)
     68
     69AM_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)
     70AM_LDFLAGS  = @HOST_FLAGS@ -Xlinker -export-dynamic
     71ARFLAGS     = cr
     72
     73demangler_SOURCES = SymTab/demangler.cc # test driver for the demangler, also useful as a sanity check that libdemangle.a is complete
     74
     75demangler_LDADD = libdemangle.a -ldl                    # yywrap
     76
     77noinst_LIBRARIES = $(LIBDEMANGLE)
     78EXTRA_LIBRARIES = libdemangle.a
     79libdemangle_a_SOURCES = $(SRCDEMANGLE)
    4880
    4981MAINTAINERCLEANFILES += ${libdir}/${notdir ${cfa_cpplib_PROGRAMS}}
  • src/Makefile.in

    r7951100 rb067d9b  
    2121###############################################################################
    2222
     23######################### -*- Mode: Makefile-Gmake -*- ########################
     24###############################################################################
     25
    2326#SRC +=  ArgTweak/Rewriter.cc \
    2427#       ArgTweak/Mutate.cc
     
    5962######################### -*- Mode: Makefile-Gmake -*- ########################
    6063###############################################################################
     64
     65######################### -*- Mode: Makefile-Gmake -*- ########################
     66###############################################################################
     67
    6168
    6269VPATH = @srcdir@
     
    134141build_triplet = @build@
    135142host_triplet = @host@
    136 cfa_cpplib_PROGRAMS = driver/cfa-cpp$(EXEEXT)
     143cfa_cpplib_PROGRAMS = ../driver/cfa-cpp$(EXEEXT) $(DEMANGLER)
     144EXTRA_PROGRAMS = demangler$(EXEEXT)
    137145subdir = src
    138146ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
    139 am__aclocal_m4_deps = $(top_srcdir)/configure.ac
     147am__aclocal_m4_deps = $(top_srcdir)/automake/libtool.m4 \
     148        $(top_srcdir)/automake/ltoptions.m4 \
     149        $(top_srcdir)/automake/ltsugar.m4 \
     150        $(top_srcdir)/automake/ltversion.m4 \
     151        $(top_srcdir)/automake/lt~obsolete.m4 \
     152        $(top_srcdir)/automake/cfa.m4 $(top_srcdir)/configure.ac
    140153am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
    141154        $(ACLOCAL_M4)
     
    145158CONFIG_CLEAN_FILES =
    146159CONFIG_CLEAN_VPATH_FILES =
     160LIBRARIES = $(noinst_LIBRARIES)
     161AM_V_AR = $(am__v_AR_@AM_V@)
     162am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@)
     163am__v_AR_0 = @echo "  AR      " $@;
     164am__v_AR_1 =
     165libdemangle_a_AR = $(AR) $(ARFLAGS)
     166libdemangle_a_LIBADD =
     167am__dirstamp = $(am__leading_dot)dirstamp
     168am__objects_1 = AST/AssertAcyclic.$(OBJEXT) AST/Attribute.$(OBJEXT) \
     169        AST/Convert.$(OBJEXT) AST/Decl.$(OBJEXT) \
     170        AST/DeclReplacer.$(OBJEXT) AST/Expr.$(OBJEXT) \
     171        AST/GenericSubstitution.$(OBJEXT) AST/Init.$(OBJEXT) \
     172        AST/LinkageSpec.$(OBJEXT) AST/Node.$(OBJEXT) \
     173        AST/Pass.$(OBJEXT) AST/Print.$(OBJEXT) AST/Stmt.$(OBJEXT) \
     174        AST/SymbolTable.$(OBJEXT) AST/Type.$(OBJEXT) \
     175        AST/TypeEnvironment.$(OBJEXT) AST/TypeSubstitution.$(OBJEXT)
     176am__objects_2 = CodeGen/CodeGenerator.$(OBJEXT) \
     177        CodeGen/FixMain.$(OBJEXT) CodeGen/GenType.$(OBJEXT) \
     178        CodeGen/OperatorTable.$(OBJEXT)
     179am__objects_3 = Common/Assert.$(OBJEXT) Common/Eval.$(OBJEXT) \
     180        Common/PassVisitor.$(OBJEXT) Common/SemanticError.$(OBJEXT) \
     181        Common/Stats/Counter.$(OBJEXT) Common/Stats/Heap.$(OBJEXT) \
     182        Common/Stats/Stats.$(OBJEXT) Common/Stats/Time.$(OBJEXT) \
     183        Common/UniqueName.$(OBJEXT)
     184am__objects_4 = ControlStruct/ForExprMutator.$(OBJEXT) \
     185        ControlStruct/LabelFixer.$(OBJEXT) \
     186        ControlStruct/LabelGenerator.$(OBJEXT) \
     187        ControlStruct/MLEMutator.$(OBJEXT) \
     188        ControlStruct/Mutate.$(OBJEXT)
     189am__objects_5 = ResolvExpr/AdjustExprType.$(OBJEXT) \
     190        ResolvExpr/Alternative.$(OBJEXT) \
     191        ResolvExpr/AlternativeFinder.$(OBJEXT) \
     192        ResolvExpr/Candidate.$(OBJEXT) \
     193        ResolvExpr/CandidateFinder.$(OBJEXT) \
     194        ResolvExpr/CastCost.$(OBJEXT) ResolvExpr/CommonType.$(OBJEXT) \
     195        ResolvExpr/ConversionCost.$(OBJEXT) \
     196        ResolvExpr/CurrentObject.$(OBJEXT) \
     197        ResolvExpr/ExplodedActual.$(OBJEXT) \
     198        ResolvExpr/ExplodedArg.$(OBJEXT) \
     199        ResolvExpr/FindOpenVars.$(OBJEXT) ResolvExpr/Occurs.$(OBJEXT) \
     200        ResolvExpr/PolyCost.$(OBJEXT) \
     201        ResolvExpr/PtrsAssignable.$(OBJEXT) \
     202        ResolvExpr/PtrsCastable.$(OBJEXT) \
     203        ResolvExpr/RenameVars.$(OBJEXT) \
     204        ResolvExpr/ResolveAssertions.$(OBJEXT) \
     205        ResolvExpr/Resolver.$(OBJEXT) \
     206        ResolvExpr/ResolveTypeof.$(OBJEXT) \
     207        ResolvExpr/SatisfyAssertions.$(OBJEXT) \
     208        ResolvExpr/SpecCost.$(OBJEXT) \
     209        ResolvExpr/TypeEnvironment.$(OBJEXT) \
     210        ResolvExpr/Unify.$(OBJEXT)
     211am__objects_6 = SymTab/Autogen.$(OBJEXT) SymTab/FixFunction.$(OBJEXT) \
     212        SymTab/Indexer.$(OBJEXT) SymTab/Mangler.$(OBJEXT) \
     213        SymTab/ManglerCommon.$(OBJEXT) SymTab/Validate.$(OBJEXT)
     214am__objects_7 = SynTree/Type.$(OBJEXT) SynTree/VoidType.$(OBJEXT) \
     215        SynTree/BasicType.$(OBJEXT) SynTree/PointerType.$(OBJEXT) \
     216        SynTree/ArrayType.$(OBJEXT) SynTree/ReferenceType.$(OBJEXT) \
     217        SynTree/FunctionType.$(OBJEXT) \
     218        SynTree/ReferenceToType.$(OBJEXT) SynTree/TupleType.$(OBJEXT) \
     219        SynTree/TypeofType.$(OBJEXT) SynTree/AttrType.$(OBJEXT) \
     220        SynTree/VarArgsType.$(OBJEXT) SynTree/ZeroOneType.$(OBJEXT) \
     221        SynTree/Constant.$(OBJEXT) SynTree/Expression.$(OBJEXT) \
     222        SynTree/TupleExpr.$(OBJEXT) SynTree/CommaExpr.$(OBJEXT) \
     223        SynTree/TypeExpr.$(OBJEXT) SynTree/ApplicationExpr.$(OBJEXT) \
     224        SynTree/AddressExpr.$(OBJEXT) SynTree/Statement.$(OBJEXT) \
     225        SynTree/CompoundStmt.$(OBJEXT) SynTree/DeclStmt.$(OBJEXT) \
     226        SynTree/Declaration.$(OBJEXT) \
     227        SynTree/DeclarationWithType.$(OBJEXT) \
     228        SynTree/ObjectDecl.$(OBJEXT) SynTree/FunctionDecl.$(OBJEXT) \
     229        SynTree/AggregateDecl.$(OBJEXT) \
     230        SynTree/NamedTypeDecl.$(OBJEXT) SynTree/TypeDecl.$(OBJEXT) \
     231        SynTree/Initializer.$(OBJEXT) \
     232        SynTree/TypeSubstitution.$(OBJEXT) SynTree/Attribute.$(OBJEXT) \
     233        SynTree/DeclReplacer.$(OBJEXT)
     234am__objects_8 = CompilationState.$(OBJEXT) $(am__objects_1) \
     235        $(am__objects_2) Concurrency/Keywords.$(OBJEXT) \
     236        $(am__objects_3) $(am__objects_4) GenPoly/GenPoly.$(OBJEXT) \
     237        GenPoly/Lvalue.$(OBJEXT) InitTweak/GenInit.$(OBJEXT) \
     238        InitTweak/InitTweak.$(OBJEXT) Parser/LinkageSpec.$(OBJEXT) \
     239        $(am__objects_5) $(am__objects_6) SymTab/Demangle.$(OBJEXT) \
     240        $(am__objects_7) Tuples/TupleAssignment.$(OBJEXT) \
     241        Tuples/TupleExpansion.$(OBJEXT) Tuples/Explode.$(OBJEXT) \
     242        Tuples/Tuples.$(OBJEXT) Validate/HandleAttributes.$(OBJEXT) \
     243        Validate/FindSpecialDecls.$(OBJEXT)
     244am_libdemangle_a_OBJECTS = $(am__objects_8)
     245libdemangle_a_OBJECTS = $(am_libdemangle_a_OBJECTS)
    147246am__installdirs = "$(DESTDIR)$(cfa_cpplibdir)"
    148247PROGRAMS = $(cfa_cpplib_PROGRAMS)
    149 am__dirstamp = $(am__leading_dot)dirstamp
    150 am__objects_1 = driver_cfa_cpp-main.$(OBJEXT) \
    151         driver_cfa_cpp-MakeLibCfa.$(OBJEXT) \
    152         CodeGen/driver_cfa_cpp-Generate.$(OBJEXT) \
    153         CodeGen/driver_cfa_cpp-CodeGenerator.$(OBJEXT) \
    154         CodeGen/driver_cfa_cpp-GenType.$(OBJEXT) \
    155         CodeGen/driver_cfa_cpp-FixNames.$(OBJEXT) \
    156         CodeGen/driver_cfa_cpp-FixMain.$(OBJEXT) \
    157         CodeGen/driver_cfa_cpp-OperatorTable.$(OBJEXT) \
    158         CodeTools/driver_cfa_cpp-DeclStats.$(OBJEXT) \
    159         CodeTools/driver_cfa_cpp-TrackLoc.$(OBJEXT) \
    160         Concurrency/driver_cfa_cpp-Keywords.$(OBJEXT) \
    161         Concurrency/driver_cfa_cpp-Waitfor.$(OBJEXT) \
    162         Common/driver_cfa_cpp-SemanticError.$(OBJEXT) \
    163         Common/driver_cfa_cpp-UniqueName.$(OBJEXT) \
    164         Common/driver_cfa_cpp-DebugMalloc.$(OBJEXT) \
    165         Common/driver_cfa_cpp-Assert.$(OBJEXT) \
    166         Common/driver_cfa_cpp-Heap.$(OBJEXT) \
    167         ControlStruct/driver_cfa_cpp-LabelGenerator.$(OBJEXT) \
    168         ControlStruct/driver_cfa_cpp-LabelFixer.$(OBJEXT) \
    169         ControlStruct/driver_cfa_cpp-MLEMutator.$(OBJEXT) \
    170         ControlStruct/driver_cfa_cpp-Mutate.$(OBJEXT) \
    171         ControlStruct/driver_cfa_cpp-ForExprMutator.$(OBJEXT) \
    172         ControlStruct/driver_cfa_cpp-ExceptTranslate.$(OBJEXT) \
    173         GenPoly/driver_cfa_cpp-Box.$(OBJEXT) \
    174         GenPoly/driver_cfa_cpp-GenPoly.$(OBJEXT) \
    175         GenPoly/driver_cfa_cpp-ScrubTyVars.$(OBJEXT) \
    176         GenPoly/driver_cfa_cpp-Lvalue.$(OBJEXT) \
    177         GenPoly/driver_cfa_cpp-Specialize.$(OBJEXT) \
    178         GenPoly/driver_cfa_cpp-FindFunction.$(OBJEXT) \
    179         GenPoly/driver_cfa_cpp-InstantiateGeneric.$(OBJEXT) \
    180         InitTweak/driver_cfa_cpp-GenInit.$(OBJEXT) \
    181         InitTweak/driver_cfa_cpp-FixInit.$(OBJEXT) \
    182         InitTweak/driver_cfa_cpp-FixGlobalInit.$(OBJEXT) \
    183         InitTweak/driver_cfa_cpp-InitTweak.$(OBJEXT) \
    184         Parser/driver_cfa_cpp-parser.$(OBJEXT) \
    185         Parser/driver_cfa_cpp-lex.$(OBJEXT) \
    186         Parser/driver_cfa_cpp-TypedefTable.$(OBJEXT) \
    187         Parser/driver_cfa_cpp-ParseNode.$(OBJEXT) \
    188         Parser/driver_cfa_cpp-DeclarationNode.$(OBJEXT) \
    189         Parser/driver_cfa_cpp-ExpressionNode.$(OBJEXT) \
    190         Parser/driver_cfa_cpp-StatementNode.$(OBJEXT) \
    191         Parser/driver_cfa_cpp-InitializerNode.$(OBJEXT) \
    192         Parser/driver_cfa_cpp-TypeData.$(OBJEXT) \
    193         Parser/driver_cfa_cpp-LinkageSpec.$(OBJEXT) \
    194         Parser/driver_cfa_cpp-parserutility.$(OBJEXT) \
    195         ResolvExpr/driver_cfa_cpp-AlternativeFinder.$(OBJEXT) \
    196         ResolvExpr/driver_cfa_cpp-Alternative.$(OBJEXT) \
    197         ResolvExpr/driver_cfa_cpp-Unify.$(OBJEXT) \
    198         ResolvExpr/driver_cfa_cpp-PtrsAssignable.$(OBJEXT) \
    199         ResolvExpr/driver_cfa_cpp-CommonType.$(OBJEXT) \
    200         ResolvExpr/driver_cfa_cpp-ConversionCost.$(OBJEXT) \
    201         ResolvExpr/driver_cfa_cpp-CastCost.$(OBJEXT) \
    202         ResolvExpr/driver_cfa_cpp-PtrsCastable.$(OBJEXT) \
    203         ResolvExpr/driver_cfa_cpp-AdjustExprType.$(OBJEXT) \
    204         ResolvExpr/driver_cfa_cpp-AlternativePrinter.$(OBJEXT) \
    205         ResolvExpr/driver_cfa_cpp-Resolver.$(OBJEXT) \
    206         ResolvExpr/driver_cfa_cpp-ResolveTypeof.$(OBJEXT) \
    207         ResolvExpr/driver_cfa_cpp-RenameVars.$(OBJEXT) \
    208         ResolvExpr/driver_cfa_cpp-FindOpenVars.$(OBJEXT) \
    209         ResolvExpr/driver_cfa_cpp-PolyCost.$(OBJEXT) \
    210         ResolvExpr/driver_cfa_cpp-Occurs.$(OBJEXT) \
    211         ResolvExpr/driver_cfa_cpp-TypeEnvironment.$(OBJEXT) \
    212         ResolvExpr/driver_cfa_cpp-CurrentObject.$(OBJEXT) \
    213         ResolvExpr/driver_cfa_cpp-ExplodedActual.$(OBJEXT) \
    214         SymTab/driver_cfa_cpp-Indexer.$(OBJEXT) \
    215         SymTab/driver_cfa_cpp-Mangler.$(OBJEXT) \
    216         SymTab/driver_cfa_cpp-Validate.$(OBJEXT) \
    217         SymTab/driver_cfa_cpp-FixFunction.$(OBJEXT) \
    218         SymTab/driver_cfa_cpp-Autogen.$(OBJEXT) \
    219         SynTree/driver_cfa_cpp-Type.$(OBJEXT) \
    220         SynTree/driver_cfa_cpp-VoidType.$(OBJEXT) \
    221         SynTree/driver_cfa_cpp-BasicType.$(OBJEXT) \
    222         SynTree/driver_cfa_cpp-PointerType.$(OBJEXT) \
    223         SynTree/driver_cfa_cpp-ArrayType.$(OBJEXT) \
    224         SynTree/driver_cfa_cpp-ReferenceType.$(OBJEXT) \
    225         SynTree/driver_cfa_cpp-FunctionType.$(OBJEXT) \
    226         SynTree/driver_cfa_cpp-ReferenceToType.$(OBJEXT) \
    227         SynTree/driver_cfa_cpp-TupleType.$(OBJEXT) \
    228         SynTree/driver_cfa_cpp-TypeofType.$(OBJEXT) \
    229         SynTree/driver_cfa_cpp-AttrType.$(OBJEXT) \
    230         SynTree/driver_cfa_cpp-VarArgsType.$(OBJEXT) \
    231         SynTree/driver_cfa_cpp-ZeroOneType.$(OBJEXT) \
    232         SynTree/driver_cfa_cpp-Constant.$(OBJEXT) \
    233         SynTree/driver_cfa_cpp-Expression.$(OBJEXT) \
    234         SynTree/driver_cfa_cpp-TupleExpr.$(OBJEXT) \
    235         SynTree/driver_cfa_cpp-CommaExpr.$(OBJEXT) \
    236         SynTree/driver_cfa_cpp-TypeExpr.$(OBJEXT) \
    237         SynTree/driver_cfa_cpp-ApplicationExpr.$(OBJEXT) \
    238         SynTree/driver_cfa_cpp-AddressExpr.$(OBJEXT) \
    239         SynTree/driver_cfa_cpp-Statement.$(OBJEXT) \
    240         SynTree/driver_cfa_cpp-CompoundStmt.$(OBJEXT) \
    241         SynTree/driver_cfa_cpp-DeclStmt.$(OBJEXT) \
    242         SynTree/driver_cfa_cpp-Declaration.$(OBJEXT) \
    243         SynTree/driver_cfa_cpp-DeclarationWithType.$(OBJEXT) \
    244         SynTree/driver_cfa_cpp-ObjectDecl.$(OBJEXT) \
    245         SynTree/driver_cfa_cpp-FunctionDecl.$(OBJEXT) \
    246         SynTree/driver_cfa_cpp-AggregateDecl.$(OBJEXT) \
    247         SynTree/driver_cfa_cpp-NamedTypeDecl.$(OBJEXT) \
    248         SynTree/driver_cfa_cpp-TypeDecl.$(OBJEXT) \
    249         SynTree/driver_cfa_cpp-Initializer.$(OBJEXT) \
    250         SynTree/driver_cfa_cpp-TypeSubstitution.$(OBJEXT) \
    251         SynTree/driver_cfa_cpp-Attribute.$(OBJEXT) \
    252         SynTree/driver_cfa_cpp-DeclReplacer.$(OBJEXT) \
    253         Tuples/driver_cfa_cpp-TupleAssignment.$(OBJEXT) \
    254         Tuples/driver_cfa_cpp-TupleExpansion.$(OBJEXT) \
    255         Tuples/driver_cfa_cpp-Explode.$(OBJEXT) \
    256         Virtual/driver_cfa_cpp-ExpandCasts.$(OBJEXT)
    257 am_driver_cfa_cpp_OBJECTS = $(am__objects_1)
    258 driver_cfa_cpp_OBJECTS = $(am_driver_cfa_cpp_OBJECTS)
    259 driver_cfa_cpp_DEPENDENCIES =
    260 driver_cfa_cpp_LINK = $(CXXLD) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) \
    261         $(driver_cfa_cpp_LDFLAGS) $(LDFLAGS) -o $@
     248am__objects_9 = main.$(OBJEXT) MakeLibCfa.$(OBJEXT) \
     249        CompilationState.$(OBJEXT) $(am__objects_1) $(am__objects_2) \
     250        CodeGen/Generate.$(OBJEXT) CodeGen/FixNames.$(OBJEXT) \
     251        CodeTools/DeclStats.$(OBJEXT) \
     252        CodeTools/ResolvProtoDump.$(OBJEXT) \
     253        CodeTools/TrackLoc.$(OBJEXT) Concurrency/Keywords.$(OBJEXT) \
     254        Concurrency/Waitfor.$(OBJEXT) $(am__objects_3) \
     255        Common/DebugMalloc.$(OBJEXT) $(am__objects_4) \
     256        ControlStruct/ExceptTranslate.$(OBJEXT) GenPoly/Box.$(OBJEXT) \
     257        GenPoly/GenPoly.$(OBJEXT) GenPoly/ScrubTyVars.$(OBJEXT) \
     258        GenPoly/Lvalue.$(OBJEXT) GenPoly/Specialize.$(OBJEXT) \
     259        GenPoly/FindFunction.$(OBJEXT) \
     260        GenPoly/InstantiateGeneric.$(OBJEXT) \
     261        InitTweak/GenInit.$(OBJEXT) InitTweak/FixInit.$(OBJEXT) \
     262        InitTweak/FixGlobalInit.$(OBJEXT) \
     263        InitTweak/InitTweak.$(OBJEXT) Parser/parser.$(OBJEXT) \
     264        Parser/lex.$(OBJEXT) Parser/TypedefTable.$(OBJEXT) \
     265        Parser/ParseNode.$(OBJEXT) Parser/DeclarationNode.$(OBJEXT) \
     266        Parser/ExpressionNode.$(OBJEXT) Parser/StatementNode.$(OBJEXT) \
     267        Parser/InitializerNode.$(OBJEXT) Parser/TypeData.$(OBJEXT) \
     268        Parser/LinkageSpec.$(OBJEXT) Parser/parserutility.$(OBJEXT) \
     269        $(am__objects_5) ResolvExpr/AlternativePrinter.$(OBJEXT) \
     270        $(am__objects_6) $(am__objects_7) \
     271        Tuples/TupleAssignment.$(OBJEXT) \
     272        Tuples/TupleExpansion.$(OBJEXT) Tuples/Explode.$(OBJEXT) \
     273        Tuples/Tuples.$(OBJEXT) Validate/HandleAttributes.$(OBJEXT) \
     274        Validate/FindSpecialDecls.$(OBJEXT) \
     275        Virtual/ExpandCasts.$(OBJEXT)
     276am____driver_cfa_cpp_OBJECTS = $(am__objects_9)
     277___driver_cfa_cpp_OBJECTS = $(am____driver_cfa_cpp_OBJECTS)
     278am__DEPENDENCIES_1 =
     279___driver_cfa_cpp_DEPENDENCIES = $(am__DEPENDENCIES_1) \
     280        $(am__DEPENDENCIES_1)
     281AM_V_lt = $(am__v_lt_@AM_V@)
     282am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
     283am__v_lt_0 = --silent
     284am__v_lt_1 =
     285am_demangler_OBJECTS = SymTab/demangler.$(OBJEXT)
     286demangler_OBJECTS = $(am_demangler_OBJECTS)
     287demangler_DEPENDENCIES = libdemangle.a
    262288AM_V_P = $(am__v_P_@AM_V@)
    263289am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
     
    276302am__depfiles_maybe = depfiles
    277303am__mv = mv -f
    278 AM_V_lt = $(am__v_lt_@AM_V@)
    279 am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
    280 am__v_lt_0 = --silent
    281 am__v_lt_1 =
    282304CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
    283305        $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
     306LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
     307        $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
     308        $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
     309        $(AM_CXXFLAGS) $(CXXFLAGS)
    284310AM_V_CXX = $(am__v_CXX_@AM_V@)
    285311am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@)
     
    287313am__v_CXX_1 =
    288314CXXLD = $(CXX)
    289 CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \
    290         -o $@
     315CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
     316        $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
     317        $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
    291318AM_V_CXXLD = $(am__v_CXXLD_@AM_V@)
    292319am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@)
    293320am__v_CXXLD_0 = @echo "  CXXLD   " $@;
    294321am__v_CXXLD_1 =
    295 @MAINTAINER_MODE_FALSE@am__skiplex = test -f $@ ||
    296322LEXCOMPILE = $(LEX) $(AM_LFLAGS) $(LFLAGS)
     323LTLEXCOMPILE = $(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) \
     324        $(LIBTOOLFLAGS) --mode=compile $(LEX) $(AM_LFLAGS) $(LFLAGS)
    297325AM_V_LEX = $(am__v_LEX_@AM_V@)
    298326am__v_LEX_ = $(am__v_LEX_@AM_DEFAULT_V@)
     
    300328am__v_LEX_1 =
    301329YLWRAP = $(top_srcdir)/automake/ylwrap
    302 @MAINTAINER_MODE_FALSE@am__skipyacc = test -f $@ ||
    303330am__yacc_c2h = sed -e s/cc$$/hh/ -e s/cpp$$/hpp/ -e s/cxx$$/hxx/ \
    304331                   -e s/c++$$/h++/ -e s/c$$/h/
    305332YACCCOMPILE = $(YACC) $(AM_YFLAGS) $(YFLAGS)
     333LTYACCCOMPILE = $(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) \
     334        $(LIBTOOLFLAGS) --mode=compile $(YACC) $(AM_YFLAGS) $(YFLAGS)
    306335AM_V_YACC = $(am__v_YACC_@AM_V@)
    307336am__v_YACC_ = $(am__v_YACC_@AM_DEFAULT_V@)
     
    310339COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
    311340        $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
     341LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
     342        $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
     343        $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
     344        $(AM_CFLAGS) $(CFLAGS)
    312345AM_V_CC = $(am__v_CC_@AM_V@)
    313346am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
     
    315348am__v_CC_1 =
    316349CCLD = $(CC)
    317 LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
     350LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
     351        $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
     352        $(AM_LDFLAGS) $(LDFLAGS) -o $@
    318353AM_V_CCLD = $(am__v_CCLD_@AM_V@)
    319354am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
    320355am__v_CCLD_0 = @echo "  CCLD    " $@;
    321356am__v_CCLD_1 =
    322 SOURCES = $(driver_cfa_cpp_SOURCES)
    323 DIST_SOURCES = $(driver_cfa_cpp_SOURCES)
     357SOURCES = $(libdemangle_a_SOURCES) $(___driver_cfa_cpp_SOURCES) \
     358        $(demangler_SOURCES)
     359DIST_SOURCES = $(libdemangle_a_SOURCES) $(___driver_cfa_cpp_SOURCES) \
     360        $(demangler_SOURCES)
    324361am__can_run_installinfo = \
    325362  case $$AM_UPDATE_INFO_DIR in \
     
    327364    *) (install-info --version) >/dev/null 2>&1;; \
    328365  esac
    329 am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
     366am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \
     367        $(LISP)config.h.in
    330368# Read a list of newline-separated strings from the standard input,
    331369# and print each of them once, without duplicates.  Input order is
     
    346384ETAGS = etags
    347385CTAGS = ctags
    348 am__DIST_COMMON = $(srcdir)/CodeGen/module.mk \
     386am__DIST_COMMON = $(srcdir)/AST/module.mk $(srcdir)/CodeGen/module.mk \
    349387        $(srcdir)/CodeTools/module.mk $(srcdir)/Common/module.mk \
    350388        $(srcdir)/Concurrency/module.mk \
     
    353391        $(srcdir)/Parser/module.mk $(srcdir)/ResolvExpr/module.mk \
    354392        $(srcdir)/SymTab/module.mk $(srcdir)/SynTree/module.mk \
    355         $(srcdir)/Tuples/module.mk $(srcdir)/Virtual/module.mk \
    356         $(top_srcdir)/automake/depcomp $(top_srcdir)/automake/ylwrap \
    357         Parser/lex.cc Parser/parser.cc Parser/parser.hh
     393        $(srcdir)/Tuples/module.mk $(srcdir)/Validate/module.mk \
     394        $(srcdir)/Virtual/module.mk $(top_srcdir)/automake/depcomp \
     395        $(top_srcdir)/automake/ylwrap Parser/lex.cc Parser/parser.cc \
     396        Parser/parser.hh
    358397DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
    359398ACLOCAL = @ACLOCAL@
    360 ALLOCA = @ALLOCA@
    361399AMTAR = @AMTAR@
    362400AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
     401AR = @AR@
    363402AUTOCONF = @AUTOCONF@
    364403AUTOHEADER = @AUTOHEADER@
    365404AUTOMAKE = @AUTOMAKE@
    366405AWK = @AWK@
    367 BACKEND_CC = @BACKEND_CC@
     406BUILD_IN_TREE_FLAGS = @BUILD_IN_TREE_FLAGS@
    368407CC = @CC@
    369408CCAS = @CCAS@
     
    371410CCASFLAGS = @CCASFLAGS@
    372411CCDEPMODE = @CCDEPMODE@
     412CFACC = @CFACC@
     413CFACC_INSTALL = @CFACC_INSTALL@
     414CFACPP = @CFACPP@
    373415CFA_BACKEND_CC = @CFA_BACKEND_CC@
    374416CFA_BINDIR = @CFA_BINDIR@
     
    382424CPPFLAGS = @CPPFLAGS@
    383425CXX = @CXX@
     426CXXCPP = @CXXCPP@
    384427CXXDEPMODE = @CXXDEPMODE@
    385428CXXFLAGS = @CXXFLAGS@
    386429CYGPATH_W = @CYGPATH_W@
    387430DEFS = @DEFS@
     431DEMANGLER = @DEMANGLER@
    388432DEPDIR = @DEPDIR@
     433DLLTOOL = @DLLTOOL@
     434DRIVER_DIR = @DRIVER_DIR@
     435DSYMUTIL = @DSYMUTIL@
     436DUMPBIN = @DUMPBIN@
    389437ECHO_C = @ECHO_C@
    390438ECHO_N = @ECHO_N@
     
    392440EGREP = @EGREP@
    393441EXEEXT = @EXEEXT@
     442FGREP = @FGREP@
    394443GREP = @GREP@
     444HAS_DISTCC = @HAS_DISTCC@
     445HOST_FLAGS = @HOST_FLAGS@
    395446INSTALL = @INSTALL@
    396447INSTALL_DATA = @INSTALL_DATA@
     
    398449INSTALL_SCRIPT = @INSTALL_SCRIPT@
    399450INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
     451LD = @LD@
    400452LDFLAGS = @LDFLAGS@
    401453LEX = @LEX@
    402454LEXLIB = @LEXLIB@
    403455LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
     456LIBCFA_TARGET_DIRS = @LIBCFA_TARGET_DIRS@
     457LIBCFA_TARGET_MAKEFILES = @LIBCFA_TARGET_MAKEFILES@
     458LIBDEMANGLE = @LIBDEMANGLE@
    404459LIBOBJS = @LIBOBJS@
    405460LIBS = @LIBS@
     461LIBTOOL = @LIBTOOL@
     462LIPO = @LIPO@
     463LN_S = @LN_S@
    406464LTLIBOBJS = @LTLIBOBJS@
    407 MACHINE_TYPE = @MACHINE_TYPE@
    408 MAINT = @MAINT@
     465LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
    409466MAKEINFO = @MAKEINFO@
     467MANIFEST_TOOL = @MANIFEST_TOOL@
    410468MKDIR_P = @MKDIR_P@
     469NM = @NM@
     470NMEDIT = @NMEDIT@
     471OBJDUMP = @OBJDUMP@
    411472OBJEXT = @OBJEXT@
     473OTOOL = @OTOOL@
     474OTOOL64 = @OTOOL64@
    412475PACKAGE = @PACKAGE@
    413476PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
     
    419482PATH_SEPARATOR = @PATH_SEPARATOR@
    420483RANLIB = @RANLIB@
     484SED = @SED@
    421485SET_MAKE = @SET_MAKE@
    422486SHELL = @SHELL@
    423487STRIP = @STRIP@
     488TARGET_HOSTS = @TARGET_HOSTS@
    424489VERSION = @VERSION@
    425490YACC = @YACC@
     
    429494abs_top_builddir = @abs_top_builddir@
    430495abs_top_srcdir = @abs_top_srcdir@
     496ac_ct_AR = @ac_ct_AR@
    431497ac_ct_CC = @ac_ct_CC@
    432498ac_ct_CXX = @ac_ct_CXX@
     499ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
    433500am__include = @am__include@
    434501am__leading_dot = @am__leading_dot@
     
    479546
    480547# create object files in directory with source files
    481 AUTOMAKE_OPTIONS = subdir-objects
    482 SRC = main.cc MakeLibCfa.cc CodeGen/Generate.cc \
    483         CodeGen/CodeGenerator.cc CodeGen/GenType.cc \
    484         CodeGen/FixNames.cc CodeGen/FixMain.cc \
    485         CodeGen/OperatorTable.cc CodeTools/DeclStats.cc \
     548AUTOMAKE_OPTIONS = foreign subdir-objects
     549ACLOCAL_AMFLAGS = -I automake
     550SRC = main.cc MakeLibCfa.cc CompilationState.cc $(SRC_AST) \
     551        $(SRC_CODEGEN) CodeGen/Generate.cc CodeGen/FixNames.cc \
     552        CodeTools/DeclStats.cc CodeTools/ResolvProtoDump.cc \
    486553        CodeTools/TrackLoc.cc Concurrency/Keywords.cc \
    487         Concurrency/Waitfor.cc Common/SemanticError.cc \
    488         Common/UniqueName.cc Common/DebugMalloc.cc Common/Assert.cc \
    489         Common/Heap.cc ControlStruct/LabelGenerator.cc \
    490         ControlStruct/LabelFixer.cc ControlStruct/MLEMutator.cc \
    491         ControlStruct/Mutate.cc ControlStruct/ForExprMutator.cc \
    492         ControlStruct/ExceptTranslate.cc GenPoly/Box.cc \
    493         GenPoly/GenPoly.cc GenPoly/ScrubTyVars.cc GenPoly/Lvalue.cc \
    494         GenPoly/Specialize.cc GenPoly/FindFunction.cc \
    495         GenPoly/InstantiateGeneric.cc InitTweak/GenInit.cc \
    496         InitTweak/FixInit.cc InitTweak/FixGlobalInit.cc \
    497         InitTweak/InitTweak.cc Parser/parser.yy Parser/lex.ll \
    498         Parser/TypedefTable.cc Parser/ParseNode.cc \
    499         Parser/DeclarationNode.cc Parser/ExpressionNode.cc \
    500         Parser/StatementNode.cc Parser/InitializerNode.cc \
    501         Parser/TypeData.cc Parser/LinkageSpec.cc \
    502         Parser/parserutility.cc ResolvExpr/AlternativeFinder.cc \
    503         ResolvExpr/Alternative.cc ResolvExpr/Unify.cc \
    504         ResolvExpr/PtrsAssignable.cc ResolvExpr/CommonType.cc \
    505         ResolvExpr/ConversionCost.cc ResolvExpr/CastCost.cc \
    506         ResolvExpr/PtrsCastable.cc ResolvExpr/AdjustExprType.cc \
    507         ResolvExpr/AlternativePrinter.cc ResolvExpr/Resolver.cc \
    508         ResolvExpr/ResolveTypeof.cc ResolvExpr/RenameVars.cc \
    509         ResolvExpr/FindOpenVars.cc ResolvExpr/PolyCost.cc \
    510         ResolvExpr/Occurs.cc ResolvExpr/TypeEnvironment.cc \
    511         ResolvExpr/CurrentObject.cc ResolvExpr/ExplodedActual.cc \
    512         SymTab/Indexer.cc SymTab/Mangler.cc SymTab/Validate.cc \
    513         SymTab/FixFunction.cc SymTab/Autogen.cc SynTree/Type.cc \
    514         SynTree/VoidType.cc SynTree/BasicType.cc \
    515         SynTree/PointerType.cc SynTree/ArrayType.cc \
    516         SynTree/ReferenceType.cc SynTree/FunctionType.cc \
    517         SynTree/ReferenceToType.cc SynTree/TupleType.cc \
    518         SynTree/TypeofType.cc SynTree/AttrType.cc \
    519         SynTree/VarArgsType.cc SynTree/ZeroOneType.cc \
    520         SynTree/Constant.cc SynTree/Expression.cc SynTree/TupleExpr.cc \
    521         SynTree/CommaExpr.cc SynTree/TypeExpr.cc \
    522         SynTree/ApplicationExpr.cc SynTree/AddressExpr.cc \
    523         SynTree/Statement.cc SynTree/CompoundStmt.cc \
    524         SynTree/DeclStmt.cc SynTree/Declaration.cc \
    525         SynTree/DeclarationWithType.cc SynTree/ObjectDecl.cc \
    526         SynTree/FunctionDecl.cc SynTree/AggregateDecl.cc \
    527         SynTree/NamedTypeDecl.cc SynTree/TypeDecl.cc \
    528         SynTree/Initializer.cc SynTree/TypeSubstitution.cc \
    529         SynTree/Attribute.cc SynTree/DeclReplacer.cc \
     554        Concurrency/Waitfor.cc $(SRC_COMMON) Common/DebugMalloc.cc \
     555        $(SRC_CONTROLSTRUCT) ControlStruct/ExceptTranslate.cc \
     556        GenPoly/Box.cc GenPoly/GenPoly.cc GenPoly/ScrubTyVars.cc \
     557        GenPoly/Lvalue.cc GenPoly/Specialize.cc \
     558        GenPoly/FindFunction.cc GenPoly/InstantiateGeneric.cc \
     559        InitTweak/GenInit.cc InitTweak/FixInit.cc \
     560        InitTweak/FixGlobalInit.cc InitTweak/InitTweak.cc \
     561        Parser/parser.yy Parser/lex.ll Parser/TypedefTable.cc \
     562        Parser/ParseNode.cc Parser/DeclarationNode.cc \
     563        Parser/ExpressionNode.cc Parser/StatementNode.cc \
     564        Parser/InitializerNode.cc Parser/TypeData.cc \
     565        Parser/LinkageSpec.cc Parser/parserutility.cc \
     566        $(SRC_RESOLVEXPR) ResolvExpr/AlternativePrinter.cc \
     567        $(SRC_SYMTAB) $(SRC_SYNTREE) Tuples/TupleAssignment.cc \
     568        Tuples/TupleExpansion.cc Tuples/Explode.cc Tuples/Tuples.cc \
     569        Validate/HandleAttributes.cc Validate/FindSpecialDecls.cc \
     570        Virtual/ExpandCasts.cc
     571SRCDEMANGLE = CompilationState.cc $(SRC_AST) $(SRC_CODEGEN) \
     572        Concurrency/Keywords.cc $(SRC_COMMON) $(SRC_CONTROLSTRUCT) \
     573        GenPoly/GenPoly.cc GenPoly/Lvalue.cc InitTweak/GenInit.cc \
     574        InitTweak/InitTweak.cc Parser/LinkageSpec.cc $(SRC_RESOLVEXPR) \
     575        $(SRC_SYMTAB) SymTab/Demangle.cc $(SRC_SYNTREE) \
    530576        Tuples/TupleAssignment.cc Tuples/TupleExpansion.cc \
    531         Tuples/Explode.cc Virtual/ExpandCasts.cc
    532 MAINTAINERCLEANFILES = Parser/parser.output ${libdir}/${notdir \
    533         ${cfa_cpplib_PROGRAMS}}
     577        Tuples/Explode.cc Tuples/Tuples.cc \
     578        Validate/HandleAttributes.cc Validate/FindSpecialDecls.cc
     579MAINTAINERCLEANFILES = ${libdir}/${notdir ${cfa_cpplib_PROGRAMS}}
     580MOSTLYCLEANFILES = Parser/lex.cc Parser/parser.cc Parser/parser.hh \
     581        Parser/parser.output
     582@WITH_LIBPROFILER_TRUE@LIBPROFILER = -lprofiler
     583@WITH_LIBTCMALLOC_TRUE@LIBTCMALLOC = -ltcmalloc
     584@WITH_LIBTCMALLOC_TRUE@TCMALLOCFLAG = -DTCMALLOC
     585SRC_AST = \
     586        AST/AssertAcyclic.cpp \
     587        AST/Attribute.cpp \
     588        AST/Convert.cpp \
     589        AST/Decl.cpp \
     590        AST/DeclReplacer.cpp \
     591        AST/Expr.cpp \
     592        AST/GenericSubstitution.cpp \
     593        AST/Init.cpp \
     594        AST/LinkageSpec.cpp \
     595        AST/Node.cpp \
     596        AST/Pass.cpp \
     597        AST/Print.cpp \
     598        AST/Stmt.cpp \
     599        AST/SymbolTable.cpp \
     600        AST/Type.cpp \
     601        AST/TypeEnvironment.cpp \
     602        AST/TypeSubstitution.cpp
     603
     604SRC_CODEGEN = \
     605        CodeGen/CodeGenerator.cc \
     606        CodeGen/FixMain.cc \
     607        CodeGen/GenType.cc \
     608        CodeGen/OperatorTable.cc
     609
     610SRC_COMMON = \
     611      Common/Assert.cc \
     612      Common/Eval.cc \
     613      Common/PassVisitor.cc \
     614      Common/SemanticError.cc \
     615      Common/Stats/Counter.cc \
     616      Common/Stats/Heap.cc \
     617      Common/Stats/Stats.cc \
     618      Common/Stats/Time.cc \
     619      Common/UniqueName.cc
     620
     621SRC_CONTROLSTRUCT = \
     622        ControlStruct/ForExprMutator.cc \
     623        ControlStruct/LabelFixer.cc \
     624        ControlStruct/LabelGenerator.cc \
     625        ControlStruct/MLEMutator.cc \
     626        ControlStruct/Mutate.cc
     627
    534628BUILT_SOURCES = Parser/parser.hh
    535629AM_YFLAGS = -d -t -v
    536 
    537 # Is there a way to use a variable for the directory names?
     630SRC_RESOLVEXPR = \
     631      ResolvExpr/AdjustExprType.cc \
     632      ResolvExpr/Alternative.cc \
     633      ResolvExpr/AlternativeFinder.cc \
     634      ResolvExpr/Candidate.cpp \
     635      ResolvExpr/CandidateFinder.cpp \
     636      ResolvExpr/CastCost.cc \
     637      ResolvExpr/CommonType.cc \
     638      ResolvExpr/ConversionCost.cc \
     639      ResolvExpr/CurrentObject.cc \
     640      ResolvExpr/ExplodedActual.cc \
     641      ResolvExpr/ExplodedArg.cpp \
     642      ResolvExpr/FindOpenVars.cc \
     643      ResolvExpr/Occurs.cc \
     644      ResolvExpr/PolyCost.cc \
     645      ResolvExpr/PtrsAssignable.cc \
     646      ResolvExpr/PtrsCastable.cc \
     647      ResolvExpr/RenameVars.cc \
     648      ResolvExpr/ResolveAssertions.cc \
     649      ResolvExpr/Resolver.cc \
     650      ResolvExpr/ResolveTypeof.cc \
     651      ResolvExpr/SatisfyAssertions.cpp \
     652      ResolvExpr/SpecCost.cc \
     653      ResolvExpr/TypeEnvironment.cc \
     654      ResolvExpr/Unify.cc
     655
     656SRC_SYMTAB = \
     657      SymTab/Autogen.cc \
     658      SymTab/FixFunction.cc \
     659      SymTab/Indexer.cc \
     660      SymTab/Mangler.cc \
     661      SymTab/ManglerCommon.cc \
     662      SymTab/Validate.cc
     663
     664SRC_SYNTREE = \
     665      SynTree/Type.cc \
     666      SynTree/VoidType.cc \
     667      SynTree/BasicType.cc \
     668      SynTree/PointerType.cc \
     669      SynTree/ArrayType.cc \
     670      SynTree/ReferenceType.cc \
     671      SynTree/FunctionType.cc \
     672      SynTree/ReferenceToType.cc \
     673      SynTree/TupleType.cc \
     674      SynTree/TypeofType.cc \
     675      SynTree/AttrType.cc \
     676      SynTree/VarArgsType.cc \
     677      SynTree/ZeroOneType.cc \
     678      SynTree/Constant.cc \
     679      SynTree/Expression.cc \
     680      SynTree/TupleExpr.cc \
     681      SynTree/CommaExpr.cc \
     682      SynTree/TypeExpr.cc \
     683      SynTree/ApplicationExpr.cc \
     684      SynTree/AddressExpr.cc \
     685      SynTree/Statement.cc \
     686      SynTree/CompoundStmt.cc \
     687      SynTree/DeclStmt.cc \
     688      SynTree/Declaration.cc \
     689      SynTree/DeclarationWithType.cc \
     690      SynTree/ObjectDecl.cc \
     691      SynTree/FunctionDecl.cc \
     692      SynTree/AggregateDecl.cc \
     693      SynTree/NamedTypeDecl.cc \
     694      SynTree/TypeDecl.cc \
     695      SynTree/Initializer.cc \
     696      SynTree/TypeSubstitution.cc \
     697      SynTree/Attribute.cc \
     698      SynTree/DeclReplacer.cc
     699
    538700
    539701# put into lib for now
    540 cfa_cpplibdir = ${CFA_LIBDIR}
    541 driver_cfa_cpp_SOURCES = ${SRC}
    542 driver_cfa_cpp_LDADD = -ldl                     # yywrap
    543 driver_cfa_cpp_CXXFLAGS = -Wno-deprecated -Wall -Wextra -DDEBUG_ALL -I${abs_top_srcdir}/src/include -DYY_NO_INPUT -O2 -g -std=c++14
    544 driver_cfa_cpp_LDFLAGS = -Xlinker -export-dynamic
     702cfa_cpplibdir = $(CFA_LIBDIR)
     703___driver_cfa_cpp_SOURCES = $(SRC)
     704___driver_cfa_cpp_LDADD = -ldl $(LIBPROFILER) $(LIBTCMALLOC)
     705AM_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)
     706AM_LDFLAGS = @HOST_FLAGS@ -Xlinker -export-dynamic
     707ARFLAGS = cr
     708demangler_SOURCES = SymTab/demangler.cc # test driver for the demangler, also useful as a sanity check that libdemangle.a is complete
     709demangler_LDADD = libdemangle.a -ldl                    # yywrap
     710noinst_LIBRARIES = $(LIBDEMANGLE)
     711EXTRA_LIBRARIES = libdemangle.a
     712libdemangle_a_SOURCES = $(SRCDEMANGLE)
    545713all: $(BUILT_SOURCES)
    546714        $(MAKE) $(AM_MAKEFLAGS) all-am
    547715
    548716.SUFFIXES:
    549 .SUFFIXES: .cc .ll .o .obj .yy
    550 $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(srcdir)/CodeGen/module.mk $(srcdir)/CodeTools/module.mk $(srcdir)/Concurrency/module.mk $(srcdir)/Common/module.mk $(srcdir)/ControlStruct/module.mk $(srcdir)/GenPoly/module.mk $(srcdir)/InitTweak/module.mk $(srcdir)/Parser/module.mk $(srcdir)/ResolvExpr/module.mk $(srcdir)/SymTab/module.mk $(srcdir)/SynTree/module.mk $(srcdir)/Tuples/module.mk $(srcdir)/Virtual/module.mk $(am__configure_deps)
     717.SUFFIXES: .cc .cpp .ll .lo .o .obj .yy
     718$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am $(srcdir)/AST/module.mk $(srcdir)/CodeGen/module.mk $(srcdir)/CodeTools/module.mk $(srcdir)/Concurrency/module.mk $(srcdir)/Common/module.mk $(srcdir)/ControlStruct/module.mk $(srcdir)/GenPoly/module.mk $(srcdir)/InitTweak/module.mk $(srcdir)/Parser/module.mk $(srcdir)/ResolvExpr/module.mk $(srcdir)/SymTab/module.mk $(srcdir)/SynTree/module.mk $(srcdir)/Tuples/module.mk $(srcdir)/Validate/module.mk $(srcdir)/Virtual/module.mk $(am__configure_deps)
    551719        @for dep in $?; do \
    552720          case '$(am__configure_deps)' in \
     
    568736            cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
    569737        esac;
    570 $(srcdir)/CodeGen/module.mk $(srcdir)/CodeTools/module.mk $(srcdir)/Concurrency/module.mk $(srcdir)/Common/module.mk $(srcdir)/ControlStruct/module.mk $(srcdir)/GenPoly/module.mk $(srcdir)/InitTweak/module.mk $(srcdir)/Parser/module.mk $(srcdir)/ResolvExpr/module.mk $(srcdir)/SymTab/module.mk $(srcdir)/SynTree/module.mk $(srcdir)/Tuples/module.mk $(srcdir)/Virtual/module.mk $(am__empty):
     738$(srcdir)/AST/module.mk $(srcdir)/CodeGen/module.mk $(srcdir)/CodeTools/module.mk $(srcdir)/Concurrency/module.mk $(srcdir)/Common/module.mk $(srcdir)/ControlStruct/module.mk $(srcdir)/GenPoly/module.mk $(srcdir)/InitTweak/module.mk $(srcdir)/Parser/module.mk $(srcdir)/ResolvExpr/module.mk $(srcdir)/SymTab/module.mk $(srcdir)/SynTree/module.mk $(srcdir)/Tuples/module.mk $(srcdir)/Validate/module.mk $(srcdir)/Virtual/module.mk $(am__empty):
    571739
    572740$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
    573741        cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
    574742
    575 $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
     743$(top_srcdir)/configure: $(am__configure_deps)
    576744        cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
    577 $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
     745$(ACLOCAL_M4): $(am__aclocal_m4_deps)
    578746        cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
    579747$(am__aclocal_m4_deps):
     748
     749clean-noinstLIBRARIES:
     750        -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
     751AST/$(am__dirstamp):
     752        @$(MKDIR_P) AST
     753        @: > AST/$(am__dirstamp)
     754AST/$(DEPDIR)/$(am__dirstamp):
     755        @$(MKDIR_P) AST/$(DEPDIR)
     756        @: > AST/$(DEPDIR)/$(am__dirstamp)
     757AST/AssertAcyclic.$(OBJEXT): AST/$(am__dirstamp) \
     758        AST/$(DEPDIR)/$(am__dirstamp)
     759AST/Attribute.$(OBJEXT): AST/$(am__dirstamp) \
     760        AST/$(DEPDIR)/$(am__dirstamp)
     761AST/Convert.$(OBJEXT): AST/$(am__dirstamp) \
     762        AST/$(DEPDIR)/$(am__dirstamp)
     763AST/Decl.$(OBJEXT): AST/$(am__dirstamp) AST/$(DEPDIR)/$(am__dirstamp)
     764AST/DeclReplacer.$(OBJEXT): AST/$(am__dirstamp) \
     765        AST/$(DEPDIR)/$(am__dirstamp)
     766AST/Expr.$(OBJEXT): AST/$(am__dirstamp) AST/$(DEPDIR)/$(am__dirstamp)
     767AST/GenericSubstitution.$(OBJEXT): AST/$(am__dirstamp) \
     768        AST/$(DEPDIR)/$(am__dirstamp)
     769AST/Init.$(OBJEXT): AST/$(am__dirstamp) AST/$(DEPDIR)/$(am__dirstamp)
     770AST/LinkageSpec.$(OBJEXT): AST/$(am__dirstamp) \
     771        AST/$(DEPDIR)/$(am__dirstamp)
     772AST/Node.$(OBJEXT): AST/$(am__dirstamp) AST/$(DEPDIR)/$(am__dirstamp)
     773AST/Pass.$(OBJEXT): AST/$(am__dirstamp) AST/$(DEPDIR)/$(am__dirstamp)
     774AST/Print.$(OBJEXT): AST/$(am__dirstamp) AST/$(DEPDIR)/$(am__dirstamp)
     775AST/Stmt.$(OBJEXT): AST/$(am__dirstamp) AST/$(DEPDIR)/$(am__dirstamp)
     776AST/SymbolTable.$(OBJEXT): AST/$(am__dirstamp) \
     777        AST/$(DEPDIR)/$(am__dirstamp)
     778AST/Type.$(OBJEXT): AST/$(am__dirstamp) AST/$(DEPDIR)/$(am__dirstamp)
     779AST/TypeEnvironment.$(OBJEXT): AST/$(am__dirstamp) \
     780        AST/$(DEPDIR)/$(am__dirstamp)
     781AST/TypeSubstitution.$(OBJEXT): AST/$(am__dirstamp) \
     782        AST/$(DEPDIR)/$(am__dirstamp)
     783CodeGen/$(am__dirstamp):
     784        @$(MKDIR_P) CodeGen
     785        @: > CodeGen/$(am__dirstamp)
     786CodeGen/$(DEPDIR)/$(am__dirstamp):
     787        @$(MKDIR_P) CodeGen/$(DEPDIR)
     788        @: > CodeGen/$(DEPDIR)/$(am__dirstamp)
     789CodeGen/CodeGenerator.$(OBJEXT): CodeGen/$(am__dirstamp) \
     790        CodeGen/$(DEPDIR)/$(am__dirstamp)
     791CodeGen/FixMain.$(OBJEXT): CodeGen/$(am__dirstamp) \
     792        CodeGen/$(DEPDIR)/$(am__dirstamp)
     793CodeGen/GenType.$(OBJEXT): CodeGen/$(am__dirstamp) \
     794        CodeGen/$(DEPDIR)/$(am__dirstamp)
     795CodeGen/OperatorTable.$(OBJEXT): CodeGen/$(am__dirstamp) \
     796        CodeGen/$(DEPDIR)/$(am__dirstamp)
     797Concurrency/$(am__dirstamp):
     798        @$(MKDIR_P) Concurrency
     799        @: > Concurrency/$(am__dirstamp)
     800Concurrency/$(DEPDIR)/$(am__dirstamp):
     801        @$(MKDIR_P) Concurrency/$(DEPDIR)
     802        @: > Concurrency/$(DEPDIR)/$(am__dirstamp)
     803Concurrency/Keywords.$(OBJEXT): Concurrency/$(am__dirstamp) \
     804        Concurrency/$(DEPDIR)/$(am__dirstamp)
     805Common/$(am__dirstamp):
     806        @$(MKDIR_P) Common
     807        @: > Common/$(am__dirstamp)
     808Common/$(DEPDIR)/$(am__dirstamp):
     809        @$(MKDIR_P) Common/$(DEPDIR)
     810        @: > Common/$(DEPDIR)/$(am__dirstamp)
     811Common/Assert.$(OBJEXT): Common/$(am__dirstamp) \
     812        Common/$(DEPDIR)/$(am__dirstamp)
     813Common/Eval.$(OBJEXT): Common/$(am__dirstamp) \
     814        Common/$(DEPDIR)/$(am__dirstamp)
     815Common/PassVisitor.$(OBJEXT): Common/$(am__dirstamp) \
     816        Common/$(DEPDIR)/$(am__dirstamp)
     817Common/SemanticError.$(OBJEXT): Common/$(am__dirstamp) \
     818        Common/$(DEPDIR)/$(am__dirstamp)
     819Common/Stats/$(am__dirstamp):
     820        @$(MKDIR_P) Common/Stats
     821        @: > Common/Stats/$(am__dirstamp)
     822Common/Stats/$(DEPDIR)/$(am__dirstamp):
     823        @$(MKDIR_P) Common/Stats/$(DEPDIR)
     824        @: > Common/Stats/$(DEPDIR)/$(am__dirstamp)
     825Common/Stats/Counter.$(OBJEXT): Common/Stats/$(am__dirstamp) \
     826        Common/Stats/$(DEPDIR)/$(am__dirstamp)
     827Common/Stats/Heap.$(OBJEXT): Common/Stats/$(am__dirstamp) \
     828        Common/Stats/$(DEPDIR)/$(am__dirstamp)
     829Common/Stats/Stats.$(OBJEXT): Common/Stats/$(am__dirstamp) \
     830        Common/Stats/$(DEPDIR)/$(am__dirstamp)
     831Common/Stats/Time.$(OBJEXT): Common/Stats/$(am__dirstamp) \
     832        Common/Stats/$(DEPDIR)/$(am__dirstamp)
     833Common/UniqueName.$(OBJEXT): Common/$(am__dirstamp) \
     834        Common/$(DEPDIR)/$(am__dirstamp)
     835ControlStruct/$(am__dirstamp):
     836        @$(MKDIR_P) ControlStruct
     837        @: > ControlStruct/$(am__dirstamp)
     838ControlStruct/$(DEPDIR)/$(am__dirstamp):
     839        @$(MKDIR_P) ControlStruct/$(DEPDIR)
     840        @: > ControlStruct/$(DEPDIR)/$(am__dirstamp)
     841ControlStruct/ForExprMutator.$(OBJEXT): ControlStruct/$(am__dirstamp) \
     842        ControlStruct/$(DEPDIR)/$(am__dirstamp)
     843ControlStruct/LabelFixer.$(OBJEXT): ControlStruct/$(am__dirstamp) \
     844        ControlStruct/$(DEPDIR)/$(am__dirstamp)
     845ControlStruct/LabelGenerator.$(OBJEXT): ControlStruct/$(am__dirstamp) \
     846        ControlStruct/$(DEPDIR)/$(am__dirstamp)
     847ControlStruct/MLEMutator.$(OBJEXT): ControlStruct/$(am__dirstamp) \
     848        ControlStruct/$(DEPDIR)/$(am__dirstamp)
     849ControlStruct/Mutate.$(OBJEXT): ControlStruct/$(am__dirstamp) \
     850        ControlStruct/$(DEPDIR)/$(am__dirstamp)
     851GenPoly/$(am__dirstamp):
     852        @$(MKDIR_P) GenPoly
     853        @: > GenPoly/$(am__dirstamp)
     854GenPoly/$(DEPDIR)/$(am__dirstamp):
     855        @$(MKDIR_P) GenPoly/$(DEPDIR)
     856        @: > GenPoly/$(DEPDIR)/$(am__dirstamp)
     857GenPoly/GenPoly.$(OBJEXT): GenPoly/$(am__dirstamp) \
     858        GenPoly/$(DEPDIR)/$(am__dirstamp)
     859GenPoly/Lvalue.$(OBJEXT): GenPoly/$(am__dirstamp) \
     860        GenPoly/$(DEPDIR)/$(am__dirstamp)
     861InitTweak/$(am__dirstamp):
     862        @$(MKDIR_P) InitTweak
     863        @: > InitTweak/$(am__dirstamp)
     864InitTweak/$(DEPDIR)/$(am__dirstamp):
     865        @$(MKDIR_P) InitTweak/$(DEPDIR)
     866        @: > InitTweak/$(DEPDIR)/$(am__dirstamp)
     867InitTweak/GenInit.$(OBJEXT): InitTweak/$(am__dirstamp) \
     868        InitTweak/$(DEPDIR)/$(am__dirstamp)
     869InitTweak/InitTweak.$(OBJEXT): InitTweak/$(am__dirstamp) \
     870        InitTweak/$(DEPDIR)/$(am__dirstamp)
     871Parser/$(am__dirstamp):
     872        @$(MKDIR_P) Parser
     873        @: > Parser/$(am__dirstamp)
     874Parser/$(DEPDIR)/$(am__dirstamp):
     875        @$(MKDIR_P) Parser/$(DEPDIR)
     876        @: > Parser/$(DEPDIR)/$(am__dirstamp)
     877Parser/LinkageSpec.$(OBJEXT): Parser/$(am__dirstamp) \
     878        Parser/$(DEPDIR)/$(am__dirstamp)
     879ResolvExpr/$(am__dirstamp):
     880        @$(MKDIR_P) ResolvExpr
     881        @: > ResolvExpr/$(am__dirstamp)
     882ResolvExpr/$(DEPDIR)/$(am__dirstamp):
     883        @$(MKDIR_P) ResolvExpr/$(DEPDIR)
     884        @: > ResolvExpr/$(DEPDIR)/$(am__dirstamp)
     885ResolvExpr/AdjustExprType.$(OBJEXT): ResolvExpr/$(am__dirstamp) \
     886        ResolvExpr/$(DEPDIR)/$(am__dirstamp)
     887ResolvExpr/Alternative.$(OBJEXT): ResolvExpr/$(am__dirstamp) \
     888        ResolvExpr/$(DEPDIR)/$(am__dirstamp)
     889ResolvExpr/AlternativeFinder.$(OBJEXT): ResolvExpr/$(am__dirstamp) \
     890        ResolvExpr/$(DEPDIR)/$(am__dirstamp)
     891ResolvExpr/Candidate.$(OBJEXT): ResolvExpr/$(am__dirstamp) \
     892        ResolvExpr/$(DEPDIR)/$(am__dirstamp)
     893ResolvExpr/CandidateFinder.$(OBJEXT): ResolvExpr/$(am__dirstamp) \
     894        ResolvExpr/$(DEPDIR)/$(am__dirstamp)
     895ResolvExpr/CastCost.$(OBJEXT): ResolvExpr/$(am__dirstamp) \
     896        ResolvExpr/$(DEPDIR)/$(am__dirstamp)
     897ResolvExpr/CommonType.$(OBJEXT): ResolvExpr/$(am__dirstamp) \
     898        ResolvExpr/$(DEPDIR)/$(am__dirstamp)
     899ResolvExpr/ConversionCost.$(OBJEXT): ResolvExpr/$(am__dirstamp) \
     900        ResolvExpr/$(DEPDIR)/$(am__dirstamp)
     901ResolvExpr/CurrentObject.$(OBJEXT): ResolvExpr/$(am__dirstamp) \
     902        ResolvExpr/$(DEPDIR)/$(am__dirstamp)
     903ResolvExpr/ExplodedActual.$(OBJEXT): ResolvExpr/$(am__dirstamp) \
     904        ResolvExpr/$(DEPDIR)/$(am__dirstamp)
     905ResolvExpr/ExplodedArg.$(OBJEXT): ResolvExpr/$(am__dirstamp) \
     906        ResolvExpr/$(DEPDIR)/$(am__dirstamp)
     907ResolvExpr/FindOpenVars.$(OBJEXT): ResolvExpr/$(am__dirstamp) \
     908        ResolvExpr/$(DEPDIR)/$(am__dirstamp)
     909ResolvExpr/Occurs.$(OBJEXT): ResolvExpr/$(am__dirstamp) \
     910        ResolvExpr/$(DEPDIR)/$(am__dirstamp)
     911ResolvExpr/PolyCost.$(OBJEXT): ResolvExpr/$(am__dirstamp) \
     912        ResolvExpr/$(DEPDIR)/$(am__dirstamp)
     913ResolvExpr/PtrsAssignable.$(OBJEXT): ResolvExpr/$(am__dirstamp) \
     914        ResolvExpr/$(DEPDIR)/$(am__dirstamp)
     915ResolvExpr/PtrsCastable.$(OBJEXT): ResolvExpr/$(am__dirstamp) \
     916        ResolvExpr/$(DEPDIR)/$(am__dirstamp)
     917ResolvExpr/RenameVars.$(OBJEXT): ResolvExpr/$(am__dirstamp) \
     918        ResolvExpr/$(DEPDIR)/$(am__dirstamp)
     919ResolvExpr/ResolveAssertions.$(OBJEXT): ResolvExpr/$(am__dirstamp) \
     920        ResolvExpr/$(DEPDIR)/$(am__dirstamp)
     921ResolvExpr/Resolver.$(OBJEXT): ResolvExpr/$(am__dirstamp) \
     922        ResolvExpr/$(DEPDIR)/$(am__dirstamp)
     923ResolvExpr/ResolveTypeof.$(OBJEXT): ResolvExpr/$(am__dirstamp) \
     924        ResolvExpr/$(DEPDIR)/$(am__dirstamp)
     925ResolvExpr/SatisfyAssertions.$(OBJEXT): ResolvExpr/$(am__dirstamp) \
     926        ResolvExpr/$(DEPDIR)/$(am__dirstamp)
     927ResolvExpr/SpecCost.$(OBJEXT): ResolvExpr/$(am__dirstamp) \
     928        ResolvExpr/$(DEPDIR)/$(am__dirstamp)
     929ResolvExpr/TypeEnvironment.$(OBJEXT): ResolvExpr/$(am__dirstamp) \
     930        ResolvExpr/$(DEPDIR)/$(am__dirstamp)
     931ResolvExpr/Unify.$(OBJEXT): ResolvExpr/$(am__dirstamp) \
     932        ResolvExpr/$(DEPDIR)/$(am__dirstamp)
     933SymTab/$(am__dirstamp):
     934        @$(MKDIR_P) SymTab
     935        @: > SymTab/$(am__dirstamp)
     936SymTab/$(DEPDIR)/$(am__dirstamp):
     937        @$(MKDIR_P) SymTab/$(DEPDIR)
     938        @: > SymTab/$(DEPDIR)/$(am__dirstamp)
     939SymTab/Autogen.$(OBJEXT): SymTab/$(am__dirstamp) \
     940        SymTab/$(DEPDIR)/$(am__dirstamp)
     941SymTab/FixFunction.$(OBJEXT): SymTab/$(am__dirstamp) \
     942        SymTab/$(DEPDIR)/$(am__dirstamp)
     943SymTab/Indexer.$(OBJEXT): SymTab/$(am__dirstamp) \
     944        SymTab/$(DEPDIR)/$(am__dirstamp)
     945SymTab/Mangler.$(OBJEXT): SymTab/$(am__dirstamp) \
     946        SymTab/$(DEPDIR)/$(am__dirstamp)
     947SymTab/ManglerCommon.$(OBJEXT): SymTab/$(am__dirstamp) \
     948        SymTab/$(DEPDIR)/$(am__dirstamp)
     949SymTab/Validate.$(OBJEXT): SymTab/$(am__dirstamp) \
     950        SymTab/$(DEPDIR)/$(am__dirstamp)
     951SymTab/Demangle.$(OBJEXT): SymTab/$(am__dirstamp) \
     952        SymTab/$(DEPDIR)/$(am__dirstamp)
     953SynTree/$(am__dirstamp):
     954        @$(MKDIR_P) SynTree
     955        @: > SynTree/$(am__dirstamp)
     956SynTree/$(DEPDIR)/$(am__dirstamp):
     957        @$(MKDIR_P) SynTree/$(DEPDIR)
     958        @: > SynTree/$(DEPDIR)/$(am__dirstamp)
     959SynTree/Type.$(OBJEXT): SynTree/$(am__dirstamp) \
     960        SynTree/$(DEPDIR)/$(am__dirstamp)
     961SynTree/VoidType.$(OBJEXT): SynTree/$(am__dirstamp) \
     962        SynTree/$(DEPDIR)/$(am__dirstamp)
     963SynTree/BasicType.$(OBJEXT): SynTree/$(am__dirstamp) \
     964        SynTree/$(DEPDIR)/$(am__dirstamp)
     965SynTree/PointerType.$(OBJEXT): SynTree/$(am__dirstamp) \
     966        SynTree/$(DEPDIR)/$(am__dirstamp)
     967SynTree/ArrayType.$(OBJEXT): SynTree/$(am__dirstamp) \
     968        SynTree/$(DEPDIR)/$(am__dirstamp)
     969SynTree/ReferenceType.$(OBJEXT): SynTree/$(am__dirstamp) \
     970        SynTree/$(DEPDIR)/$(am__dirstamp)
     971SynTree/FunctionType.$(OBJEXT): SynTree/$(am__dirstamp) \
     972        SynTree/$(DEPDIR)/$(am__dirstamp)
     973SynTree/ReferenceToType.$(OBJEXT): SynTree/$(am__dirstamp) \
     974        SynTree/$(DEPDIR)/$(am__dirstamp)
     975SynTree/TupleType.$(OBJEXT): SynTree/$(am__dirstamp) \
     976        SynTree/$(DEPDIR)/$(am__dirstamp)
     977SynTree/TypeofType.$(OBJEXT): SynTree/$(am__dirstamp) \
     978        SynTree/$(DEPDIR)/$(am__dirstamp)
     979SynTree/AttrType.$(OBJEXT): SynTree/$(am__dirstamp) \
     980        SynTree/$(DEPDIR)/$(am__dirstamp)
     981SynTree/VarArgsType.$(OBJEXT): SynTree/$(am__dirstamp) \
     982        SynTree/$(DEPDIR)/$(am__dirstamp)
     983SynTree/ZeroOneType.$(OBJEXT): SynTree/$(am__dirstamp) \
     984        SynTree/$(DEPDIR)/$(am__dirstamp)
     985SynTree/Constant.$(OBJEXT): SynTree/$(am__dirstamp) \
     986        SynTree/$(DEPDIR)/$(am__dirstamp)
     987SynTree/Expression.$(OBJEXT): SynTree/$(am__dirstamp) \
     988        SynTree/$(DEPDIR)/$(am__dirstamp)
     989SynTree/TupleExpr.$(OBJEXT): SynTree/$(am__dirstamp) \
     990        SynTree/$(DEPDIR)/$(am__dirstamp)
     991SynTree/CommaExpr.$(OBJEXT): SynTree/$(am__dirstamp) \
     992        SynTree/$(DEPDIR)/$(am__dirstamp)
     993SynTree/TypeExpr.$(OBJEXT): SynTree/$(am__dirstamp) \
     994        SynTree/$(DEPDIR)/$(am__dirstamp)
     995SynTree/ApplicationExpr.$(OBJEXT): SynTree/$(am__dirstamp) \
     996        SynTree/$(DEPDIR)/$(am__dirstamp)
     997SynTree/AddressExpr.$(OBJEXT): SynTree/$(am__dirstamp) \
     998        SynTree/$(DEPDIR)/$(am__dirstamp)
     999SynTree/Statement.$(OBJEXT): SynTree/$(am__dirstamp) \
     1000        SynTree/$(DEPDIR)/$(am__dirstamp)
     1001SynTree/CompoundStmt.$(OBJEXT): SynTree/$(am__dirstamp) \
     1002        SynTree/$(DEPDIR)/$(am__dirstamp)
     1003SynTree/DeclStmt.$(OBJEXT): SynTree/$(am__dirstamp) \
     1004        SynTree/$(DEPDIR)/$(am__dirstamp)
     1005SynTree/Declaration.$(OBJEXT): SynTree/$(am__dirstamp) \
     1006        SynTree/$(DEPDIR)/$(am__dirstamp)
     1007SynTree/DeclarationWithType.$(OBJEXT): SynTree/$(am__dirstamp) \
     1008        SynTree/$(DEPDIR)/$(am__dirstamp)
     1009SynTree/ObjectDecl.$(OBJEXT): SynTree/$(am__dirstamp) \
     1010        SynTree/$(DEPDIR)/$(am__dirstamp)
     1011SynTree/FunctionDecl.$(OBJEXT): SynTree/$(am__dirstamp) \
     1012        SynTree/$(DEPDIR)/$(am__dirstamp)
     1013SynTree/AggregateDecl.$(OBJEXT): SynTree/$(am__dirstamp) \
     1014        SynTree/$(DEPDIR)/$(am__dirstamp)
     1015SynTree/NamedTypeDecl.$(OBJEXT): SynTree/$(am__dirstamp) \
     1016        SynTree/$(DEPDIR)/$(am__dirstamp)
     1017SynTree/TypeDecl.$(OBJEXT): SynTree/$(am__dirstamp) \
     1018        SynTree/$(DEPDIR)/$(am__dirstamp)
     1019SynTree/Initializer.$(OBJEXT): SynTree/$(am__dirstamp) \
     1020        SynTree/$(DEPDIR)/$(am__dirstamp)
     1021SynTree/TypeSubstitution.$(OBJEXT): SynTree/$(am__dirstamp) \
     1022        SynTree/$(DEPDIR)/$(am__dirstamp)
     1023SynTree/Attribute.$(OBJEXT): SynTree/$(am__dirstamp) \
     1024        SynTree/$(DEPDIR)/$(am__dirstamp)
     1025SynTree/DeclReplacer.$(OBJEXT): SynTree/$(am__dirstamp) \
     1026        SynTree/$(DEPDIR)/$(am__dirstamp)
     1027Tuples/$(am__dirstamp):
     1028        @$(MKDIR_P) Tuples
     1029        @: > Tuples/$(am__dirstamp)
     1030Tuples/$(DEPDIR)/$(am__dirstamp):
     1031        @$(MKDIR_P) Tuples/$(DEPDIR)
     1032        @: > Tuples/$(DEPDIR)/$(am__dirstamp)
     1033Tuples/TupleAssignment.$(OBJEXT): Tuples/$(am__dirstamp) \
     1034        Tuples/$(DEPDIR)/$(am__dirstamp)
     1035Tuples/TupleExpansion.$(OBJEXT): Tuples/$(am__dirstamp) \
     1036        Tuples/$(DEPDIR)/$(am__dirstamp)
     1037Tuples/Explode.$(OBJEXT): Tuples/$(am__dirstamp) \
     1038        Tuples/$(DEPDIR)/$(am__dirstamp)
     1039Tuples/Tuples.$(OBJEXT): Tuples/$(am__dirstamp) \
     1040        Tuples/$(DEPDIR)/$(am__dirstamp)
     1041Validate/$(am__dirstamp):
     1042        @$(MKDIR_P) Validate
     1043        @: > Validate/$(am__dirstamp)
     1044Validate/$(DEPDIR)/$(am__dirstamp):
     1045        @$(MKDIR_P) Validate/$(DEPDIR)
     1046        @: > Validate/$(DEPDIR)/$(am__dirstamp)
     1047Validate/HandleAttributes.$(OBJEXT): Validate/$(am__dirstamp) \
     1048        Validate/$(DEPDIR)/$(am__dirstamp)
     1049Validate/FindSpecialDecls.$(OBJEXT): Validate/$(am__dirstamp) \
     1050        Validate/$(DEPDIR)/$(am__dirstamp)
     1051
     1052libdemangle.a: $(libdemangle_a_OBJECTS) $(libdemangle_a_DEPENDENCIES) $(EXTRA_libdemangle_a_DEPENDENCIES)
     1053        $(AM_V_at)-rm -f libdemangle.a
     1054        $(AM_V_AR)$(libdemangle_a_AR) libdemangle.a $(libdemangle_a_OBJECTS) $(libdemangle_a_LIBADD)
     1055        $(AM_V_at)$(RANLIB) libdemangle.a
    5801056install-cfa_cpplibPROGRAMS: $(cfa_cpplib_PROGRAMS)
    5811057        @$(NORMAL_INSTALL)
     
    5881064        sed 's/$(EXEEXT)$$//' | \
    5891065        while read p p1; do if test -f $$p \
     1066         || test -f $$p1 \
    5901067          ; then echo "$$p"; echo "$$p"; else :; fi; \
    5911068        done | \
     
    6021079            if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
    6031080            test -z "$$files" || { \
    604               echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(cfa_cpplibdir)$$dir'"; \
    605               $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(cfa_cpplibdir)$$dir" || exit $$?; \
     1081            echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(cfa_cpplibdir)$$dir'"; \
     1082            $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(cfa_cpplibdir)$$dir" || exit $$?; \
    6061083            } \
    6071084        ; done
     
    6191096
    6201097clean-cfa_cpplibPROGRAMS:
    621         -test -z "$(cfa_cpplib_PROGRAMS)" || rm -f $(cfa_cpplib_PROGRAMS)
    622 CodeGen/$(am__dirstamp):
    623         @$(MKDIR_P) CodeGen
    624         @: > CodeGen/$(am__dirstamp)
    625 CodeGen/$(DEPDIR)/$(am__dirstamp):
    626         @$(MKDIR_P) CodeGen/$(DEPDIR)
    627         @: > CodeGen/$(DEPDIR)/$(am__dirstamp)
    628 CodeGen/driver_cfa_cpp-Generate.$(OBJEXT): CodeGen/$(am__dirstamp) \
     1098        @list='$(cfa_cpplib_PROGRAMS)'; test -n "$$list" || exit 0; \
     1099        echo " rm -f" $$list; \
     1100        rm -f $$list || exit $$?; \
     1101        test -n "$(EXEEXT)" || exit 0; \
     1102        list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
     1103        echo " rm -f" $$list; \
     1104        rm -f $$list
     1105CodeGen/Generate.$(OBJEXT): CodeGen/$(am__dirstamp) \
    6291106        CodeGen/$(DEPDIR)/$(am__dirstamp)
    630 CodeGen/driver_cfa_cpp-CodeGenerator.$(OBJEXT):  \
    631         CodeGen/$(am__dirstamp) CodeGen/$(DEPDIR)/$(am__dirstamp)
    632 CodeGen/driver_cfa_cpp-GenType.$(OBJEXT): CodeGen/$(am__dirstamp) \
     1107CodeGen/FixNames.$(OBJEXT): CodeGen/$(am__dirstamp) \
    6331108        CodeGen/$(DEPDIR)/$(am__dirstamp)
    634 CodeGen/driver_cfa_cpp-FixNames.$(OBJEXT): CodeGen/$(am__dirstamp) \
    635         CodeGen/$(DEPDIR)/$(am__dirstamp)
    636 CodeGen/driver_cfa_cpp-FixMain.$(OBJEXT): CodeGen/$(am__dirstamp) \
    637         CodeGen/$(DEPDIR)/$(am__dirstamp)
    638 CodeGen/driver_cfa_cpp-OperatorTable.$(OBJEXT):  \
    639         CodeGen/$(am__dirstamp) CodeGen/$(DEPDIR)/$(am__dirstamp)
    6401109CodeTools/$(am__dirstamp):
    6411110        @$(MKDIR_P) CodeTools
     
    6441113        @$(MKDIR_P) CodeTools/$(DEPDIR)
    6451114        @: > CodeTools/$(DEPDIR)/$(am__dirstamp)
    646 CodeTools/driver_cfa_cpp-DeclStats.$(OBJEXT):  \
    647         CodeTools/$(am__dirstamp) CodeTools/$(DEPDIR)/$(am__dirstamp)
    648 CodeTools/driver_cfa_cpp-TrackLoc.$(OBJEXT):  \
    649         CodeTools/$(am__dirstamp) CodeTools/$(DEPDIR)/$(am__dirstamp)
    650 Concurrency/$(am__dirstamp):
    651         @$(MKDIR_P) Concurrency
    652         @: > Concurrency/$(am__dirstamp)
    653 Concurrency/$(DEPDIR)/$(am__dirstamp):
    654         @$(MKDIR_P) Concurrency/$(DEPDIR)
    655         @: > Concurrency/$(DEPDIR)/$(am__dirstamp)
    656 Concurrency/driver_cfa_cpp-Keywords.$(OBJEXT):  \
    657         Concurrency/$(am__dirstamp) \
     1115CodeTools/DeclStats.$(OBJEXT): CodeTools/$(am__dirstamp) \
     1116        CodeTools/$(DEPDIR)/$(am__dirstamp)
     1117CodeTools/ResolvProtoDump.$(OBJEXT): CodeTools/$(am__dirstamp) \
     1118        CodeTools/$(DEPDIR)/$(am__dirstamp)
     1119CodeTools/TrackLoc.$(OBJEXT): CodeTools/$(am__dirstamp) \
     1120        CodeTools/$(DEPDIR)/$(am__dirstamp)
     1121Concurrency/Waitfor.$(OBJEXT): Concurrency/$(am__dirstamp) \
    6581122        Concurrency/$(DEPDIR)/$(am__dirstamp)
    659 Concurrency/driver_cfa_cpp-Waitfor.$(OBJEXT):  \
    660         Concurrency/$(am__dirstamp) \
    661         Concurrency/$(DEPDIR)/$(am__dirstamp)
    662 Common/$(am__dirstamp):
    663         @$(MKDIR_P) Common
    664         @: > Common/$(am__dirstamp)
    665 Common/$(DEPDIR)/$(am__dirstamp):
    666         @$(MKDIR_P) Common/$(DEPDIR)
    667         @: > Common/$(DEPDIR)/$(am__dirstamp)
    668 Common/driver_cfa_cpp-SemanticError.$(OBJEXT): Common/$(am__dirstamp) \
     1123Common/DebugMalloc.$(OBJEXT): Common/$(am__dirstamp) \
    6691124        Common/$(DEPDIR)/$(am__dirstamp)
    670 Common/driver_cfa_cpp-UniqueName.$(OBJEXT): Common/$(am__dirstamp) \
    671         Common/$(DEPDIR)/$(am__dirstamp)
    672 Common/driver_cfa_cpp-DebugMalloc.$(OBJEXT): Common/$(am__dirstamp) \
    673         Common/$(DEPDIR)/$(am__dirstamp)
    674 Common/driver_cfa_cpp-Assert.$(OBJEXT): Common/$(am__dirstamp) \
    675         Common/$(DEPDIR)/$(am__dirstamp)
    676 Common/driver_cfa_cpp-Heap.$(OBJEXT): Common/$(am__dirstamp) \
    677         Common/$(DEPDIR)/$(am__dirstamp)
    678 ControlStruct/$(am__dirstamp):
    679         @$(MKDIR_P) ControlStruct
    680         @: > ControlStruct/$(am__dirstamp)
    681 ControlStruct/$(DEPDIR)/$(am__dirstamp):
    682         @$(MKDIR_P) ControlStruct/$(DEPDIR)
    683         @: > ControlStruct/$(DEPDIR)/$(am__dirstamp)
    684 ControlStruct/driver_cfa_cpp-LabelGenerator.$(OBJEXT):  \
     1125ControlStruct/ExceptTranslate.$(OBJEXT):  \
    6851126        ControlStruct/$(am__dirstamp) \
    6861127        ControlStruct/$(DEPDIR)/$(am__dirstamp)
    687 ControlStruct/driver_cfa_cpp-LabelFixer.$(OBJEXT):  \
    688         ControlStruct/$(am__dirstamp) \
    689         ControlStruct/$(DEPDIR)/$(am__dirstamp)
    690 ControlStruct/driver_cfa_cpp-MLEMutator.$(OBJEXT):  \
    691         ControlStruct/$(am__dirstamp) \
    692         ControlStruct/$(DEPDIR)/$(am__dirstamp)
    693 ControlStruct/driver_cfa_cpp-Mutate.$(OBJEXT):  \
    694         ControlStruct/$(am__dirstamp) \
    695         ControlStruct/$(DEPDIR)/$(am__dirstamp)
    696 ControlStruct/driver_cfa_cpp-ForExprMutator.$(OBJEXT):  \
    697         ControlStruct/$(am__dirstamp) \
    698         ControlStruct/$(DEPDIR)/$(am__dirstamp)
    699 ControlStruct/driver_cfa_cpp-ExceptTranslate.$(OBJEXT):  \
    700         ControlStruct/$(am__dirstamp) \
    701         ControlStruct/$(DEPDIR)/$(am__dirstamp)
    702 GenPoly/$(am__dirstamp):
    703         @$(MKDIR_P) GenPoly
    704         @: > GenPoly/$(am__dirstamp)
    705 GenPoly/$(DEPDIR)/$(am__dirstamp):
    706         @$(MKDIR_P) GenPoly/$(DEPDIR)
    707         @: > GenPoly/$(DEPDIR)/$(am__dirstamp)
    708 GenPoly/driver_cfa_cpp-Box.$(OBJEXT): GenPoly/$(am__dirstamp) \
     1128GenPoly/Box.$(OBJEXT): GenPoly/$(am__dirstamp) \
    7091129        GenPoly/$(DEPDIR)/$(am__dirstamp)
    710 GenPoly/driver_cfa_cpp-GenPoly.$(OBJEXT): GenPoly/$(am__dirstamp) \
     1130GenPoly/ScrubTyVars.$(OBJEXT): GenPoly/$(am__dirstamp) \
    7111131        GenPoly/$(DEPDIR)/$(am__dirstamp)
    712 GenPoly/driver_cfa_cpp-ScrubTyVars.$(OBJEXT): GenPoly/$(am__dirstamp) \
     1132GenPoly/Specialize.$(OBJEXT): GenPoly/$(am__dirstamp) \
    7131133        GenPoly/$(DEPDIR)/$(am__dirstamp)
    714 GenPoly/driver_cfa_cpp-Lvalue.$(OBJEXT): GenPoly/$(am__dirstamp) \
     1134GenPoly/FindFunction.$(OBJEXT): GenPoly/$(am__dirstamp) \
    7151135        GenPoly/$(DEPDIR)/$(am__dirstamp)
    716 GenPoly/driver_cfa_cpp-Specialize.$(OBJEXT): GenPoly/$(am__dirstamp) \
     1136GenPoly/InstantiateGeneric.$(OBJEXT): GenPoly/$(am__dirstamp) \
    7171137        GenPoly/$(DEPDIR)/$(am__dirstamp)
    718 GenPoly/driver_cfa_cpp-FindFunction.$(OBJEXT):  \
    719         GenPoly/$(am__dirstamp) GenPoly/$(DEPDIR)/$(am__dirstamp)
    720 GenPoly/driver_cfa_cpp-InstantiateGeneric.$(OBJEXT):  \
    721         GenPoly/$(am__dirstamp) GenPoly/$(DEPDIR)/$(am__dirstamp)
    722 InitTweak/$(am__dirstamp):
    723         @$(MKDIR_P) InitTweak
    724         @: > InitTweak/$(am__dirstamp)
    725 InitTweak/$(DEPDIR)/$(am__dirstamp):
    726         @$(MKDIR_P) InitTweak/$(DEPDIR)
    727         @: > InitTweak/$(DEPDIR)/$(am__dirstamp)
    728 InitTweak/driver_cfa_cpp-GenInit.$(OBJEXT): InitTweak/$(am__dirstamp) \
     1138InitTweak/FixInit.$(OBJEXT): InitTweak/$(am__dirstamp) \
    7291139        InitTweak/$(DEPDIR)/$(am__dirstamp)
    730 InitTweak/driver_cfa_cpp-FixInit.$(OBJEXT): InitTweak/$(am__dirstamp) \
     1140InitTweak/FixGlobalInit.$(OBJEXT): InitTweak/$(am__dirstamp) \
    7311141        InitTweak/$(DEPDIR)/$(am__dirstamp)
    732 InitTweak/driver_cfa_cpp-FixGlobalInit.$(OBJEXT):  \
    733         InitTweak/$(am__dirstamp) InitTweak/$(DEPDIR)/$(am__dirstamp)
    734 InitTweak/driver_cfa_cpp-InitTweak.$(OBJEXT):  \
    735         InitTweak/$(am__dirstamp) InitTweak/$(DEPDIR)/$(am__dirstamp)
    7361142Parser/parser.hh: Parser/parser.cc
    7371143        @if test ! -f $@; then rm -f Parser/parser.cc; else :; fi
    7381144        @if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) Parser/parser.cc; else :; fi
    739 Parser/$(am__dirstamp):
    740         @$(MKDIR_P) Parser
    741         @: > Parser/$(am__dirstamp)
    742 Parser/$(DEPDIR)/$(am__dirstamp):
    743         @$(MKDIR_P) Parser/$(DEPDIR)
    744         @: > Parser/$(DEPDIR)/$(am__dirstamp)
    745 Parser/driver_cfa_cpp-parser.$(OBJEXT): Parser/$(am__dirstamp) \
     1145Parser/parser.$(OBJEXT): Parser/$(am__dirstamp) \
    7461146        Parser/$(DEPDIR)/$(am__dirstamp)
    747 Parser/driver_cfa_cpp-lex.$(OBJEXT): Parser/$(am__dirstamp) \
     1147Parser/lex.$(OBJEXT): Parser/$(am__dirstamp) \
    7481148        Parser/$(DEPDIR)/$(am__dirstamp)
    749 Parser/driver_cfa_cpp-TypedefTable.$(OBJEXT): Parser/$(am__dirstamp) \
     1149Parser/TypedefTable.$(OBJEXT): Parser/$(am__dirstamp) \
    7501150        Parser/$(DEPDIR)/$(am__dirstamp)
    751 Parser/driver_cfa_cpp-ParseNode.$(OBJEXT): Parser/$(am__dirstamp) \
     1151Parser/ParseNode.$(OBJEXT): Parser/$(am__dirstamp) \
    7521152        Parser/$(DEPDIR)/$(am__dirstamp)
    753 Parser/driver_cfa_cpp-DeclarationNode.$(OBJEXT):  \
    754         Parser/$(am__dirstamp) Parser/$(DEPDIR)/$(am__dirstamp)
    755 Parser/driver_cfa_cpp-ExpressionNode.$(OBJEXT):  \
    756         Parser/$(am__dirstamp) Parser/$(DEPDIR)/$(am__dirstamp)
    757 Parser/driver_cfa_cpp-StatementNode.$(OBJEXT): Parser/$(am__dirstamp) \
     1153Parser/DeclarationNode.$(OBJEXT): Parser/$(am__dirstamp) \
    7581154        Parser/$(DEPDIR)/$(am__dirstamp)
    759 Parser/driver_cfa_cpp-InitializerNode.$(OBJEXT):  \
    760         Parser/$(am__dirstamp) Parser/$(DEPDIR)/$(am__dirstamp)
    761 Parser/driver_cfa_cpp-TypeData.$(OBJEXT): Parser/$(am__dirstamp) \
     1155Parser/ExpressionNode.$(OBJEXT): Parser/$(am__dirstamp) \
    7621156        Parser/$(DEPDIR)/$(am__dirstamp)
    763 Parser/driver_cfa_cpp-LinkageSpec.$(OBJEXT): Parser/$(am__dirstamp) \
     1157Parser/StatementNode.$(OBJEXT): Parser/$(am__dirstamp) \
    7641158        Parser/$(DEPDIR)/$(am__dirstamp)
    765 Parser/driver_cfa_cpp-parserutility.$(OBJEXT): Parser/$(am__dirstamp) \
     1159Parser/InitializerNode.$(OBJEXT): Parser/$(am__dirstamp) \
    7661160        Parser/$(DEPDIR)/$(am__dirstamp)
    767 ResolvExpr/$(am__dirstamp):
    768         @$(MKDIR_P) ResolvExpr
    769         @: > ResolvExpr/$(am__dirstamp)
    770 ResolvExpr/$(DEPDIR)/$(am__dirstamp):
    771         @$(MKDIR_P) ResolvExpr/$(DEPDIR)
    772         @: > ResolvExpr/$(DEPDIR)/$(am__dirstamp)
    773 ResolvExpr/driver_cfa_cpp-AlternativeFinder.$(OBJEXT):  \
    774         ResolvExpr/$(am__dirstamp) \
    775         ResolvExpr/$(DEPDIR)/$(am__dirstamp)
    776 ResolvExpr/driver_cfa_cpp-Alternative.$(OBJEXT):  \
    777         ResolvExpr/$(am__dirstamp) \
    778         ResolvExpr/$(DEPDIR)/$(am__dirstamp)
    779 ResolvExpr/driver_cfa_cpp-Unify.$(OBJEXT): ResolvExpr/$(am__dirstamp) \
    780         ResolvExpr/$(DEPDIR)/$(am__dirstamp)
    781 ResolvExpr/driver_cfa_cpp-PtrsAssignable.$(OBJEXT):  \
    782         ResolvExpr/$(am__dirstamp) \
    783         ResolvExpr/$(DEPDIR)/$(am__dirstamp)
    784 ResolvExpr/driver_cfa_cpp-CommonType.$(OBJEXT):  \
    785         ResolvExpr/$(am__dirstamp) \
    786         ResolvExpr/$(DEPDIR)/$(am__dirstamp)
    787 ResolvExpr/driver_cfa_cpp-ConversionCost.$(OBJEXT):  \
    788         ResolvExpr/$(am__dirstamp) \
    789         ResolvExpr/$(DEPDIR)/$(am__dirstamp)
    790 ResolvExpr/driver_cfa_cpp-CastCost.$(OBJEXT):  \
    791         ResolvExpr/$(am__dirstamp) \
    792         ResolvExpr/$(DEPDIR)/$(am__dirstamp)
    793 ResolvExpr/driver_cfa_cpp-PtrsCastable.$(OBJEXT):  \
    794         ResolvExpr/$(am__dirstamp) \
    795         ResolvExpr/$(DEPDIR)/$(am__dirstamp)
    796 ResolvExpr/driver_cfa_cpp-AdjustExprType.$(OBJEXT):  \
    797         ResolvExpr/$(am__dirstamp) \
    798         ResolvExpr/$(DEPDIR)/$(am__dirstamp)
    799 ResolvExpr/driver_cfa_cpp-AlternativePrinter.$(OBJEXT):  \
    800         ResolvExpr/$(am__dirstamp) \
    801         ResolvExpr/$(DEPDIR)/$(am__dirstamp)
    802 ResolvExpr/driver_cfa_cpp-Resolver.$(OBJEXT):  \
    803         ResolvExpr/$(am__dirstamp) \
    804         ResolvExpr/$(DEPDIR)/$(am__dirstamp)
    805 ResolvExpr/driver_cfa_cpp-ResolveTypeof.$(OBJEXT):  \
    806         ResolvExpr/$(am__dirstamp) \
    807         ResolvExpr/$(DEPDIR)/$(am__dirstamp)
    808 ResolvExpr/driver_cfa_cpp-RenameVars.$(OBJEXT):  \
    809         ResolvExpr/$(am__dirstamp) \
    810         ResolvExpr/$(DEPDIR)/$(am__dirstamp)
    811 ResolvExpr/driver_cfa_cpp-FindOpenVars.$(OBJEXT):  \
    812         ResolvExpr/$(am__dirstamp) \
    813         ResolvExpr/$(DEPDIR)/$(am__dirstamp)
    814 ResolvExpr/driver_cfa_cpp-PolyCost.$(OBJEXT):  \
    815         ResolvExpr/$(am__dirstamp) \
    816         ResolvExpr/$(DEPDIR)/$(am__dirstamp)
    817 ResolvExpr/driver_cfa_cpp-Occurs.$(OBJEXT):  \
    818         ResolvExpr/$(am__dirstamp) \
    819         ResolvExpr/$(DEPDIR)/$(am__dirstamp)
    820 ResolvExpr/driver_cfa_cpp-TypeEnvironment.$(OBJEXT):  \
    821         ResolvExpr/$(am__dirstamp) \
    822         ResolvExpr/$(DEPDIR)/$(am__dirstamp)
    823 ResolvExpr/driver_cfa_cpp-CurrentObject.$(OBJEXT):  \
    824         ResolvExpr/$(am__dirstamp) \
    825         ResolvExpr/$(DEPDIR)/$(am__dirstamp)
    826 ResolvExpr/driver_cfa_cpp-ExplodedActual.$(OBJEXT):  \
    827         ResolvExpr/$(am__dirstamp) \
    828         ResolvExpr/$(DEPDIR)/$(am__dirstamp)
    829 SymTab/$(am__dirstamp):
    830         @$(MKDIR_P) SymTab
    831         @: > SymTab/$(am__dirstamp)
    832 SymTab/$(DEPDIR)/$(am__dirstamp):
    833         @$(MKDIR_P) SymTab/$(DEPDIR)
    834         @: > SymTab/$(DEPDIR)/$(am__dirstamp)
    835 SymTab/driver_cfa_cpp-Indexer.$(OBJEXT): SymTab/$(am__dirstamp) \
    836         SymTab/$(DEPDIR)/$(am__dirstamp)
    837 SymTab/driver_cfa_cpp-Mangler.$(OBJEXT): SymTab/$(am__dirstamp) \
    838         SymTab/$(DEPDIR)/$(am__dirstamp)
    839 SymTab/driver_cfa_cpp-Validate.$(OBJEXT): SymTab/$(am__dirstamp) \
    840         SymTab/$(DEPDIR)/$(am__dirstamp)
    841 SymTab/driver_cfa_cpp-FixFunction.$(OBJEXT): SymTab/$(am__dirstamp) \
    842         SymTab/$(DEPDIR)/$(am__dirstamp)
    843 SymTab/driver_cfa_cpp-Autogen.$(OBJEXT): SymTab/$(am__dirstamp) \
    844         SymTab/$(DEPDIR)/$(am__dirstamp)
    845 SynTree/$(am__dirstamp):
    846         @$(MKDIR_P) SynTree
    847         @: > SynTree/$(am__dirstamp)
    848 SynTree/$(DEPDIR)/$(am__dirstamp):
    849         @$(MKDIR_P) SynTree/$(DEPDIR)
    850         @: > SynTree/$(DEPDIR)/$(am__dirstamp)
    851 SynTree/driver_cfa_cpp-Type.$(OBJEXT): SynTree/$(am__dirstamp) \
    852         SynTree/$(DEPDIR)/$(am__dirstamp)
    853 SynTree/driver_cfa_cpp-VoidType.$(OBJEXT): SynTree/$(am__dirstamp) \
    854         SynTree/$(DEPDIR)/$(am__dirstamp)
    855 SynTree/driver_cfa_cpp-BasicType.$(OBJEXT): SynTree/$(am__dirstamp) \
    856         SynTree/$(DEPDIR)/$(am__dirstamp)
    857 SynTree/driver_cfa_cpp-PointerType.$(OBJEXT): SynTree/$(am__dirstamp) \
    858         SynTree/$(DEPDIR)/$(am__dirstamp)
    859 SynTree/driver_cfa_cpp-ArrayType.$(OBJEXT): SynTree/$(am__dirstamp) \
    860         SynTree/$(DEPDIR)/$(am__dirstamp)
    861 SynTree/driver_cfa_cpp-ReferenceType.$(OBJEXT):  \
    862         SynTree/$(am__dirstamp) SynTree/$(DEPDIR)/$(am__dirstamp)
    863 SynTree/driver_cfa_cpp-FunctionType.$(OBJEXT):  \
    864         SynTree/$(am__dirstamp) SynTree/$(DEPDIR)/$(am__dirstamp)
    865 SynTree/driver_cfa_cpp-ReferenceToType.$(OBJEXT):  \
    866         SynTree/$(am__dirstamp) SynTree/$(DEPDIR)/$(am__dirstamp)
    867 SynTree/driver_cfa_cpp-TupleType.$(OBJEXT): SynTree/$(am__dirstamp) \
    868         SynTree/$(DEPDIR)/$(am__dirstamp)
    869 SynTree/driver_cfa_cpp-TypeofType.$(OBJEXT): SynTree/$(am__dirstamp) \
    870         SynTree/$(DEPDIR)/$(am__dirstamp)
    871 SynTree/driver_cfa_cpp-AttrType.$(OBJEXT): SynTree/$(am__dirstamp) \
    872         SynTree/$(DEPDIR)/$(am__dirstamp)
    873 SynTree/driver_cfa_cpp-VarArgsType.$(OBJEXT): SynTree/$(am__dirstamp) \
    874         SynTree/$(DEPDIR)/$(am__dirstamp)
    875 SynTree/driver_cfa_cpp-ZeroOneType.$(OBJEXT): SynTree/$(am__dirstamp) \
    876         SynTree/$(DEPDIR)/$(am__dirstamp)
    877 SynTree/driver_cfa_cpp-Constant.$(OBJEXT): SynTree/$(am__dirstamp) \
    878         SynTree/$(DEPDIR)/$(am__dirstamp)
    879 SynTree/driver_cfa_cpp-Expression.$(OBJEXT): SynTree/$(am__dirstamp) \
    880         SynTree/$(DEPDIR)/$(am__dirstamp)
    881 SynTree/driver_cfa_cpp-TupleExpr.$(OBJEXT): SynTree/$(am__dirstamp) \
    882         SynTree/$(DEPDIR)/$(am__dirstamp)
    883 SynTree/driver_cfa_cpp-CommaExpr.$(OBJEXT): SynTree/$(am__dirstamp) \
    884         SynTree/$(DEPDIR)/$(am__dirstamp)
    885 SynTree/driver_cfa_cpp-TypeExpr.$(OBJEXT): SynTree/$(am__dirstamp) \
    886         SynTree/$(DEPDIR)/$(am__dirstamp)
    887 SynTree/driver_cfa_cpp-ApplicationExpr.$(OBJEXT):  \
    888         SynTree/$(am__dirstamp) SynTree/$(DEPDIR)/$(am__dirstamp)
    889 SynTree/driver_cfa_cpp-AddressExpr.$(OBJEXT): SynTree/$(am__dirstamp) \
    890         SynTree/$(DEPDIR)/$(am__dirstamp)
    891 SynTree/driver_cfa_cpp-Statement.$(OBJEXT): SynTree/$(am__dirstamp) \
    892         SynTree/$(DEPDIR)/$(am__dirstamp)
    893 SynTree/driver_cfa_cpp-CompoundStmt.$(OBJEXT):  \
    894         SynTree/$(am__dirstamp) SynTree/$(DEPDIR)/$(am__dirstamp)
    895 SynTree/driver_cfa_cpp-DeclStmt.$(OBJEXT): SynTree/$(am__dirstamp) \
    896         SynTree/$(DEPDIR)/$(am__dirstamp)
    897 SynTree/driver_cfa_cpp-Declaration.$(OBJEXT): SynTree/$(am__dirstamp) \
    898         SynTree/$(DEPDIR)/$(am__dirstamp)
    899 SynTree/driver_cfa_cpp-DeclarationWithType.$(OBJEXT):  \
    900         SynTree/$(am__dirstamp) SynTree/$(DEPDIR)/$(am__dirstamp)
    901 SynTree/driver_cfa_cpp-ObjectDecl.$(OBJEXT): SynTree/$(am__dirstamp) \
    902         SynTree/$(DEPDIR)/$(am__dirstamp)
    903 SynTree/driver_cfa_cpp-FunctionDecl.$(OBJEXT):  \
    904         SynTree/$(am__dirstamp) SynTree/$(DEPDIR)/$(am__dirstamp)
    905 SynTree/driver_cfa_cpp-AggregateDecl.$(OBJEXT):  \
    906         SynTree/$(am__dirstamp) SynTree/$(DEPDIR)/$(am__dirstamp)
    907 SynTree/driver_cfa_cpp-NamedTypeDecl.$(OBJEXT):  \
    908         SynTree/$(am__dirstamp) SynTree/$(DEPDIR)/$(am__dirstamp)
    909 SynTree/driver_cfa_cpp-TypeDecl.$(OBJEXT): SynTree/$(am__dirstamp) \
    910         SynTree/$(DEPDIR)/$(am__dirstamp)
    911 SynTree/driver_cfa_cpp-Initializer.$(OBJEXT): SynTree/$(am__dirstamp) \
    912         SynTree/$(DEPDIR)/$(am__dirstamp)
    913 SynTree/driver_cfa_cpp-TypeSubstitution.$(OBJEXT):  \
    914         SynTree/$(am__dirstamp) SynTree/$(DEPDIR)/$(am__dirstamp)
    915 SynTree/driver_cfa_cpp-Attribute.$(OBJEXT): SynTree/$(am__dirstamp) \
    916         SynTree/$(DEPDIR)/$(am__dirstamp)
    917 SynTree/driver_cfa_cpp-DeclReplacer.$(OBJEXT):  \
    918         SynTree/$(am__dirstamp) SynTree/$(DEPDIR)/$(am__dirstamp)
    919 Tuples/$(am__dirstamp):
    920         @$(MKDIR_P) Tuples
    921         @: > Tuples/$(am__dirstamp)
    922 Tuples/$(DEPDIR)/$(am__dirstamp):
    923         @$(MKDIR_P) Tuples/$(DEPDIR)
    924         @: > Tuples/$(DEPDIR)/$(am__dirstamp)
    925 Tuples/driver_cfa_cpp-TupleAssignment.$(OBJEXT):  \
    926         Tuples/$(am__dirstamp) Tuples/$(DEPDIR)/$(am__dirstamp)
    927 Tuples/driver_cfa_cpp-TupleExpansion.$(OBJEXT):  \
    928         Tuples/$(am__dirstamp) Tuples/$(DEPDIR)/$(am__dirstamp)
    929 Tuples/driver_cfa_cpp-Explode.$(OBJEXT): Tuples/$(am__dirstamp) \
    930         Tuples/$(DEPDIR)/$(am__dirstamp)
     1161Parser/TypeData.$(OBJEXT): Parser/$(am__dirstamp) \
     1162        Parser/$(DEPDIR)/$(am__dirstamp)
     1163Parser/parserutility.$(OBJEXT): Parser/$(am__dirstamp) \
     1164        Parser/$(DEPDIR)/$(am__dirstamp)
     1165ResolvExpr/AlternativePrinter.$(OBJEXT): ResolvExpr/$(am__dirstamp) \
     1166        ResolvExpr/$(DEPDIR)/$(am__dirstamp)
    9311167Virtual/$(am__dirstamp):
    9321168        @$(MKDIR_P) Virtual
     
    9351171        @$(MKDIR_P) Virtual/$(DEPDIR)
    9361172        @: > Virtual/$(DEPDIR)/$(am__dirstamp)
    937 Virtual/driver_cfa_cpp-ExpandCasts.$(OBJEXT): Virtual/$(am__dirstamp) \
     1173Virtual/ExpandCasts.$(OBJEXT): Virtual/$(am__dirstamp) \
    9381174        Virtual/$(DEPDIR)/$(am__dirstamp)
    939 driver/$(am__dirstamp):
    940         @$(MKDIR_P) driver
    941         @: > driver/$(am__dirstamp)
    942 
    943 driver/cfa-cpp$(EXEEXT): $(driver_cfa_cpp_OBJECTS) $(driver_cfa_cpp_DEPENDENCIES) $(EXTRA_driver_cfa_cpp_DEPENDENCIES) driver/$(am__dirstamp)
    944         @rm -f driver/cfa-cpp$(EXEEXT)
    945         $(AM_V_CXXLD)$(driver_cfa_cpp_LINK) $(driver_cfa_cpp_OBJECTS) $(driver_cfa_cpp_LDADD) $(LIBS)
     1175../driver/$(am__dirstamp):
     1176        @$(MKDIR_P) ../driver
     1177        @: > ../driver/$(am__dirstamp)
     1178
     1179../driver/cfa-cpp$(EXEEXT): $(___driver_cfa_cpp_OBJECTS) $(___driver_cfa_cpp_DEPENDENCIES) $(EXTRA____driver_cfa_cpp_DEPENDENCIES) ../driver/$(am__dirstamp)
     1180        @rm -f ../driver/cfa-cpp$(EXEEXT)
     1181        $(AM_V_CXXLD)$(CXXLINK) $(___driver_cfa_cpp_OBJECTS) $(___driver_cfa_cpp_LDADD) $(LIBS)
     1182SymTab/demangler.$(OBJEXT): SymTab/$(am__dirstamp) \
     1183        SymTab/$(DEPDIR)/$(am__dirstamp)
     1184
     1185demangler$(EXEEXT): $(demangler_OBJECTS) $(demangler_DEPENDENCIES) $(EXTRA_demangler_DEPENDENCIES)
     1186        @rm -f demangler$(EXEEXT)
     1187        $(AM_V_CXXLD)$(CXXLINK) $(demangler_OBJECTS) $(demangler_LDADD) $(LIBS)
    9461188
    9471189mostlyclean-compile:
    9481190        -rm -f *.$(OBJEXT)
     1191        -rm -f AST/*.$(OBJEXT)
    9491192        -rm -f CodeGen/*.$(OBJEXT)
    9501193        -rm -f CodeTools/*.$(OBJEXT)
    9511194        -rm -f Common/*.$(OBJEXT)
     1195        -rm -f Common/Stats/*.$(OBJEXT)
    9521196        -rm -f Concurrency/*.$(OBJEXT)
    9531197        -rm -f ControlStruct/*.$(OBJEXT)
     
    9591203        -rm -f SynTree/*.$(OBJEXT)
    9601204        -rm -f Tuples/*.$(OBJEXT)
     1205        -rm -f Validate/*.$(OBJEXT)
    9611206        -rm -f Virtual/*.$(OBJEXT)
    9621207
     
    9641209        -rm -f *.tab.c
    9651210
    966 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/driver_cfa_cpp-MakeLibCfa.Po@am__quote@
    967 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/driver_cfa_cpp-main.Po@am__quote@
    968 @AMDEP_TRUE@@am__include@ @am__quote@CodeGen/$(DEPDIR)/driver_cfa_cpp-CodeGenerator.Po@am__quote@
    969 @AMDEP_TRUE@@am__include@ @am__quote@CodeGen/$(DEPDIR)/driver_cfa_cpp-FixMain.Po@am__quote@
    970 @AMDEP_TRUE@@am__include@ @am__quote@CodeGen/$(DEPDIR)/driver_cfa_cpp-FixNames.Po@am__quote@
    971 @AMDEP_TRUE@@am__include@ @am__quote@CodeGen/$(DEPDIR)/driver_cfa_cpp-GenType.Po@am__quote@
    972 @AMDEP_TRUE@@am__include@ @am__quote@CodeGen/$(DEPDIR)/driver_cfa_cpp-Generate.Po@am__quote@
    973 @AMDEP_TRUE@@am__include@ @am__quote@CodeGen/$(DEPDIR)/driver_cfa_cpp-OperatorTable.Po@am__quote@
    974 @AMDEP_TRUE@@am__include@ @am__quote@CodeTools/$(DEPDIR)/driver_cfa_cpp-DeclStats.Po@am__quote@
    975 @AMDEP_TRUE@@am__include@ @am__quote@CodeTools/$(DEPDIR)/driver_cfa_cpp-TrackLoc.Po@am__quote@
    976 @AMDEP_TRUE@@am__include@ @am__quote@Common/$(DEPDIR)/driver_cfa_cpp-Assert.Po@am__quote@
    977 @AMDEP_TRUE@@am__include@ @am__quote@Common/$(DEPDIR)/driver_cfa_cpp-DebugMalloc.Po@am__quote@
    978 @AMDEP_TRUE@@am__include@ @am__quote@Common/$(DEPDIR)/driver_cfa_cpp-Heap.Po@am__quote@
    979 @AMDEP_TRUE@@am__include@ @am__quote@Common/$(DEPDIR)/driver_cfa_cpp-SemanticError.Po@am__quote@
    980 @AMDEP_TRUE@@am__include@ @am__quote@Common/$(DEPDIR)/driver_cfa_cpp-UniqueName.Po@am__quote@
    981 @AMDEP_TRUE@@am__include@ @am__quote@Concurrency/$(DEPDIR)/driver_cfa_cpp-Keywords.Po@am__quote@
    982 @AMDEP_TRUE@@am__include@ @am__quote@Concurrency/$(DEPDIR)/driver_cfa_cpp-Waitfor.Po@am__quote@
    983 @AMDEP_TRUE@@am__include@ @am__quote@ControlStruct/$(DEPDIR)/driver_cfa_cpp-ExceptTranslate.Po@am__quote@
    984 @AMDEP_TRUE@@am__include@ @am__quote@ControlStruct/$(DEPDIR)/driver_cfa_cpp-ForExprMutator.Po@am__quote@
    985 @AMDEP_TRUE@@am__include@ @am__quote@ControlStruct/$(DEPDIR)/driver_cfa_cpp-LabelFixer.Po@am__quote@
    986 @AMDEP_TRUE@@am__include@ @am__quote@ControlStruct/$(DEPDIR)/driver_cfa_cpp-LabelGenerator.Po@am__quote@
    987 @AMDEP_TRUE@@am__include@ @am__quote@ControlStruct/$(DEPDIR)/driver_cfa_cpp-MLEMutator.Po@am__quote@
    988 @AMDEP_TRUE@@am__include@ @am__quote@ControlStruct/$(DEPDIR)/driver_cfa_cpp-Mutate.Po@am__quote@
    989 @AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-Box.Po@am__quote@
    990 @AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-FindFunction.Po@am__quote@
    991 @AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-GenPoly.Po@am__quote@
    992 @AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-InstantiateGeneric.Po@am__quote@
    993 @AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-Lvalue.Po@am__quote@
    994 @AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-ScrubTyVars.Po@am__quote@
    995 @AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-Specialize.Po@am__quote@
    996 @AMDEP_TRUE@@am__include@ @am__quote@InitTweak/$(DEPDIR)/driver_cfa_cpp-FixGlobalInit.Po@am__quote@
    997 @AMDEP_TRUE@@am__include@ @am__quote@InitTweak/$(DEPDIR)/driver_cfa_cpp-FixInit.Po@am__quote@
    998 @AMDEP_TRUE@@am__include@ @am__quote@InitTweak/$(DEPDIR)/driver_cfa_cpp-GenInit.Po@am__quote@
    999 @AMDEP_TRUE@@am__include@ @am__quote@InitTweak/$(DEPDIR)/driver_cfa_cpp-InitTweak.Po@am__quote@
    1000 @AMDEP_TRUE@@am__include@ @am__quote@Parser/$(DEPDIR)/driver_cfa_cpp-DeclarationNode.Po@am__quote@
    1001 @AMDEP_TRUE@@am__include@ @am__quote@Parser/$(DEPDIR)/driver_cfa_cpp-ExpressionNode.Po@am__quote@
    1002 @AMDEP_TRUE@@am__include@ @am__quote@Parser/$(DEPDIR)/driver_cfa_cpp-InitializerNode.Po@am__quote@
    1003 @AMDEP_TRUE@@am__include@ @am__quote@Parser/$(DEPDIR)/driver_cfa_cpp-LinkageSpec.Po@am__quote@
    1004 @AMDEP_TRUE@@am__include@ @am__quote@Parser/$(DEPDIR)/driver_cfa_cpp-ParseNode.Po@am__quote@
    1005 @AMDEP_TRUE@@am__include@ @am__quote@Parser/$(DEPDIR)/driver_cfa_cpp-StatementNode.Po@am__quote@
    1006 @AMDEP_TRUE@@am__include@ @am__quote@Parser/$(DEPDIR)/driver_cfa_cpp-TypeData.Po@am__quote@
    1007 @AMDEP_TRUE@@am__include@ @am__quote@Parser/$(DEPDIR)/driver_cfa_cpp-TypedefTable.Po@am__quote@
    1008 @AMDEP_TRUE@@am__include@ @am__quote@Parser/$(DEPDIR)/driver_cfa_cpp-lex.Po@am__quote@
    1009 @AMDEP_TRUE@@am__include@ @am__quote@Parser/$(DEPDIR)/driver_cfa_cpp-parser.Po@am__quote@
    1010 @AMDEP_TRUE@@am__include@ @am__quote@Parser/$(DEPDIR)/driver_cfa_cpp-parserutility.Po@am__quote@
    1011 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-AdjustExprType.Po@am__quote@
    1012 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Alternative.Po@am__quote@
    1013 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-AlternativeFinder.Po@am__quote@
    1014 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-AlternativePrinter.Po@am__quote@
    1015 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CastCost.Po@am__quote@
    1016 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CommonType.Po@am__quote@
    1017 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ConversionCost.Po@am__quote@
    1018 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CurrentObject.Po@am__quote@
    1019 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ExplodedActual.Po@am__quote@
    1020 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-FindOpenVars.Po@am__quote@
    1021 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Occurs.Po@am__quote@
    1022 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-PolyCost.Po@am__quote@
    1023 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-PtrsAssignable.Po@am__quote@
    1024 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-PtrsCastable.Po@am__quote@
    1025 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-RenameVars.Po@am__quote@
    1026 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ResolveTypeof.Po@am__quote@
    1027 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Resolver.Po@am__quote@
    1028 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-TypeEnvironment.Po@am__quote@
    1029 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Unify.Po@am__quote@
    1030 @AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/driver_cfa_cpp-Autogen.Po@am__quote@
    1031 @AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/driver_cfa_cpp-FixFunction.Po@am__quote@
    1032 @AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/driver_cfa_cpp-Indexer.Po@am__quote@
    1033 @AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/driver_cfa_cpp-Mangler.Po@am__quote@
    1034 @AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/driver_cfa_cpp-Validate.Po@am__quote@
    1035 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-AddressExpr.Po@am__quote@
    1036 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-AggregateDecl.Po@am__quote@
    1037 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-ApplicationExpr.Po@am__quote@
    1038 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-ArrayType.Po@am__quote@
    1039 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-AttrType.Po@am__quote@
    1040 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-Attribute.Po@am__quote@
    1041 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-BasicType.Po@am__quote@
    1042 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-CommaExpr.Po@am__quote@
    1043 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-CompoundStmt.Po@am__quote@
    1044 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-Constant.Po@am__quote@
    1045 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-DeclReplacer.Po@am__quote@
    1046 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-DeclStmt.Po@am__quote@
    1047 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-Declaration.Po@am__quote@
    1048 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-DeclarationWithType.Po@am__quote@
    1049 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-Expression.Po@am__quote@
    1050 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-FunctionDecl.Po@am__quote@
    1051 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-FunctionType.Po@am__quote@
    1052 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-Initializer.Po@am__quote@
    1053 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-NamedTypeDecl.Po@am__quote@
    1054 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-ObjectDecl.Po@am__quote@
    1055 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-PointerType.Po@am__quote@
    1056 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-ReferenceToType.Po@am__quote@
    1057 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-ReferenceType.Po@am__quote@
    1058 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-Statement.Po@am__quote@
    1059 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-TupleExpr.Po@am__quote@
    1060 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-TupleType.Po@am__quote@
    1061 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-Type.Po@am__quote@
    1062 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-TypeDecl.Po@am__quote@
    1063 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-TypeExpr.Po@am__quote@
    1064 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-TypeSubstitution.Po@am__quote@
    1065 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-TypeofType.Po@am__quote@
    1066 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-VarArgsType.Po@am__quote@
    1067 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-VoidType.Po@am__quote@
    1068 @AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/driver_cfa_cpp-ZeroOneType.Po@am__quote@
    1069 @AMDEP_TRUE@@am__include@ @am__quote@Tuples/$(DEPDIR)/driver_cfa_cpp-Explode.Po@am__quote@
    1070 @AMDEP_TRUE@@am__include@ @am__quote@Tuples/$(DEPDIR)/driver_cfa_cpp-TupleAssignment.Po@am__quote@
    1071 @AMDEP_TRUE@@am__include@ @am__quote@Tuples/$(DEPDIR)/driver_cfa_cpp-TupleExpansion.Po@am__quote@
    1072 @AMDEP_TRUE@@am__include@ @am__quote@Virtual/$(DEPDIR)/driver_cfa_cpp-ExpandCasts.Po@am__quote@
     1211@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CompilationState.Po@am__quote@
     1212@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/MakeLibCfa.Po@am__quote@
     1213@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@
     1214@AMDEP_TRUE@@am__include@ @am__quote@AST/$(DEPDIR)/AssertAcyclic.Po@am__quote@
     1215@AMDEP_TRUE@@am__include@ @am__quote@AST/$(DEPDIR)/Attribute.Po@am__quote@
     1216@AMDEP_TRUE@@am__include@ @am__quote@AST/$(DEPDIR)/Convert.Po@am__quote@
     1217@AMDEP_TRUE@@am__include@ @am__quote@AST/$(DEPDIR)/Decl.Po@am__quote@
     1218@AMDEP_TRUE@@am__include@ @am__quote@AST/$(DEPDIR)/DeclReplacer.Po@am__quote@
     1219@AMDEP_TRUE@@am__include@ @am__quote@AST/$(DEPDIR)/Expr.Po@am__quote@
     1220@AMDEP_TRUE@@am__include@ @am__quote@AST/$(DEPDIR)/GenericSubstitution.Po@am__quote@
     1221@AMDEP_TRUE@@am__include@ @am__quote@AST/$(DEPDIR)/Init.Po@am__quote@
     1222@AMDEP_TRUE@@am__include@ @am__quote@AST/$(DEPDIR)/LinkageSpec.Po@am__quote@
     1223@AMDEP_TRUE@@am__include@ @am__quote@AST/$(DEPDIR)/Node.Po@am__quote@
     1224@AMDEP_TRUE@@am__include@ @am__quote@AST/$(DEPDIR)/Pass.Po@am__quote@
     1225@AMDEP_TRUE@@am__include@ @am__quote@AST/$(DEPDIR)/Print.Po@am__quote@
     1226@AMDEP_TRUE@@am__include@ @am__quote@AST/$(DEPDIR)/Stmt.Po@am__quote@
     1227@AMDEP_TRUE@@am__include@ @am__quote@AST/$(DEPDIR)/SymbolTable.Po@am__quote@
     1228@AMDEP_TRUE@@am__include@ @am__quote@AST/$(DEPDIR)/Type.Po@am__quote@
     1229@AMDEP_TRUE@@am__include@ @am__quote@AST/$(DEPDIR)/TypeEnvironment.Po@am__quote@
     1230@AMDEP_TRUE@@am__include@ @am__quote@AST/$(DEPDIR)/TypeSubstitution.Po@am__quote@
     1231@AMDEP_TRUE@@am__include@ @am__quote@CodeGen/$(DEPDIR)/CodeGenerator.Po@am__quote@
     1232@AMDEP_TRUE@@am__include@ @am__quote@CodeGen/$(DEPDIR)/FixMain.Po@am__quote@
     1233@AMDEP_TRUE@@am__include@ @am__quote@CodeGen/$(DEPDIR)/FixNames.Po@am__quote@
     1234@AMDEP_TRUE@@am__include@ @am__quote@CodeGen/$(DEPDIR)/GenType.Po@am__quote@
     1235@AMDEP_TRUE@@am__include@ @am__quote@CodeGen/$(DEPDIR)/Generate.Po@am__quote@
     1236@AMDEP_TRUE@@am__include@ @am__quote@CodeGen/$(DEPDIR)/OperatorTable.Po@am__quote@
     1237@AMDEP_TRUE@@am__include@ @am__quote@CodeTools/$(DEPDIR)/DeclStats.Po@am__quote@
     1238@AMDEP_TRUE@@am__include@ @am__quote@CodeTools/$(DEPDIR)/ResolvProtoDump.Po@am__quote@
     1239@AMDEP_TRUE@@am__include@ @am__quote@CodeTools/$(DEPDIR)/TrackLoc.Po@am__quote@
     1240@AMDEP_TRUE@@am__include@ @am__quote@Common/$(DEPDIR)/Assert.Po@am__quote@
     1241@AMDEP_TRUE@@am__include@ @am__quote@Common/$(DEPDIR)/DebugMalloc.Po@am__quote@
     1242@AMDEP_TRUE@@am__include@ @am__quote@Common/$(DEPDIR)/Eval.Po@am__quote@
     1243@AMDEP_TRUE@@am__include@ @am__quote@Common/$(DEPDIR)/PassVisitor.Po@am__quote@
     1244@AMDEP_TRUE@@am__include@ @am__quote@Common/$(DEPDIR)/SemanticError.Po@am__quote@
     1245@AMDEP_TRUE@@am__include@ @am__quote@Common/$(DEPDIR)/UniqueName.Po@am__quote@
     1246@AMDEP_TRUE@@am__include@ @am__quote@Common/Stats/$(DEPDIR)/Counter.Po@am__quote@
     1247@AMDEP_TRUE@@am__include@ @am__quote@Common/Stats/$(DEPDIR)/Heap.Po@am__quote@
     1248@AMDEP_TRUE@@am__include@ @am__quote@Common/Stats/$(DEPDIR)/Stats.Po@am__quote@
     1249@AMDEP_TRUE@@am__include@ @am__quote@Common/Stats/$(DEPDIR)/Time.Po@am__quote@
     1250@AMDEP_TRUE@@am__include@ @am__quote@Concurrency/$(DEPDIR)/Keywords.Po@am__quote@
     1251@AMDEP_TRUE@@am__include@ @am__quote@Concurrency/$(DEPDIR)/Waitfor.Po@am__quote@
     1252@AMDEP_TRUE@@am__include@ @am__quote@ControlStruct/$(DEPDIR)/ExceptTranslate.Po@am__quote@
     1253@AMDEP_TRUE@@am__include@ @am__quote@ControlStruct/$(DEPDIR)/ForExprMutator.Po@am__quote@
     1254@AMDEP_TRUE@@am__include@ @am__quote@ControlStruct/$(DEPDIR)/LabelFixer.Po@am__quote@
     1255@AMDEP_TRUE@@am__include@ @am__quote@ControlStruct/$(DEPDIR)/LabelGenerator.Po@am__quote@
     1256@AMDEP_TRUE@@am__include@ @am__quote@ControlStruct/$(DEPDIR)/MLEMutator.Po@am__quote@
     1257@AMDEP_TRUE@@am__include@ @am__quote@ControlStruct/$(DEPDIR)/Mutate.Po@am__quote@
     1258@AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/Box.Po@am__quote@
     1259@AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/FindFunction.Po@am__quote@
     1260@AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/GenPoly.Po@am__quote@
     1261@AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/InstantiateGeneric.Po@am__quote@
     1262@AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/Lvalue.Po@am__quote@
     1263@AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/ScrubTyVars.Po@am__quote@
     1264@AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/Specialize.Po@am__quote@
     1265@AMDEP_TRUE@@am__include@ @am__quote@InitTweak/$(DEPDIR)/FixGlobalInit.Po@am__quote@
     1266@AMDEP_TRUE@@am__include@ @am__quote@InitTweak/$(DEPDIR)/FixInit.Po@am__quote@
     1267@AMDEP_TRUE@@am__include@ @am__quote@InitTweak/$(DEPDIR)/GenInit.Po@am__quote@
     1268@AMDEP_TRUE@@am__include@ @am__quote@InitTweak/$(DEPDIR)/InitTweak.Po@am__quote@
     1269@AMDEP_TRUE@@am__include@ @am__quote@Parser/$(DEPDIR)/DeclarationNode.Po@am__quote@
     1270@AMDEP_TRUE@@am__include@ @am__quote@Parser/$(DEPDIR)/ExpressionNode.Po@am__quote@
     1271@AMDEP_TRUE@@am__include@ @am__quote@Parser/$(DEPDIR)/InitializerNode.Po@am__quote@
     1272@AMDEP_TRUE@@am__include@ @am__quote@Parser/$(DEPDIR)/LinkageSpec.Po@am__quote@
     1273@AMDEP_TRUE@@am__include@ @am__quote@Parser/$(DEPDIR)/ParseNode.Po@am__quote@
     1274@AMDEP_TRUE@@am__include@ @am__quote@Parser/$(DEPDIR)/StatementNode.Po@am__quote@
     1275@AMDEP_TRUE@@am__include@ @am__quote@Parser/$(DEPDIR)/TypeData.Po@am__quote@
     1276@AMDEP_TRUE@@am__include@ @am__quote@Parser/$(DEPDIR)/TypedefTable.Po@am__quote@
     1277@AMDEP_TRUE@@am__include@ @am__quote@Parser/$(DEPDIR)/lex.Po@am__quote@
     1278@AMDEP_TRUE@@am__include@ @am__quote@Parser/$(DEPDIR)/parser.Po@am__quote@
     1279@AMDEP_TRUE@@am__include@ @am__quote@Parser/$(DEPDIR)/parserutility.Po@am__quote@
     1280@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/AdjustExprType.Po@am__quote@
     1281@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/Alternative.Po@am__quote@
     1282@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/AlternativeFinder.Po@am__quote@
     1283@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/AlternativePrinter.Po@am__quote@
     1284@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/Candidate.Po@am__quote@
     1285@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/CandidateFinder.Po@am__quote@
     1286@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/CastCost.Po@am__quote@
     1287@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/CommonType.Po@am__quote@
     1288@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/ConversionCost.Po@am__quote@
     1289@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/CurrentObject.Po@am__quote@
     1290@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/ExplodedActual.Po@am__quote@
     1291@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/ExplodedArg.Po@am__quote@
     1292@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/FindOpenVars.Po@am__quote@
     1293@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/Occurs.Po@am__quote@
     1294@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/PolyCost.Po@am__quote@
     1295@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/PtrsAssignable.Po@am__quote@
     1296@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/PtrsCastable.Po@am__quote@
     1297@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/RenameVars.Po@am__quote@
     1298@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/ResolveAssertions.Po@am__quote@
     1299@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/ResolveTypeof.Po@am__quote@
     1300@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/Resolver.Po@am__quote@
     1301@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/SatisfyAssertions.Po@am__quote@
     1302@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/SpecCost.Po@am__quote@
     1303@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/TypeEnvironment.Po@am__quote@
     1304@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/Unify.Po@am__quote@
     1305@AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/Autogen.Po@am__quote@
     1306@AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/Demangle.Po@am__quote@
     1307@AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/FixFunction.Po@am__quote@
     1308@AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/Indexer.Po@am__quote@
     1309@AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/Mangler.Po@am__quote@
     1310@AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/ManglerCommon.Po@am__quote@
     1311@AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/Validate.Po@am__quote@
     1312@AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/demangler.Po@am__quote@
     1313@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/AddressExpr.Po@am__quote@
     1314@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/AggregateDecl.Po@am__quote@
     1315@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/ApplicationExpr.Po@am__quote@
     1316@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/ArrayType.Po@am__quote@
     1317@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/AttrType.Po@am__quote@
     1318@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/Attribute.Po@am__quote@
     1319@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/BasicType.Po@am__quote@
     1320@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/CommaExpr.Po@am__quote@
     1321@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/CompoundStmt.Po@am__quote@
     1322@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/Constant.Po@am__quote@
     1323@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/DeclReplacer.Po@am__quote@
     1324@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/DeclStmt.Po@am__quote@
     1325@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/Declaration.Po@am__quote@
     1326@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/DeclarationWithType.Po@am__quote@
     1327@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/Expression.Po@am__quote@
     1328@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/FunctionDecl.Po@am__quote@
     1329@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/FunctionType.Po@am__quote@
     1330@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/Initializer.Po@am__quote@
     1331@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/NamedTypeDecl.Po@am__quote@
     1332@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/ObjectDecl.Po@am__quote@
     1333@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/PointerType.Po@am__quote@
     1334@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/ReferenceToType.Po@am__quote@
     1335@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/ReferenceType.Po@am__quote@
     1336@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/Statement.Po@am__quote@
     1337@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/TupleExpr.Po@am__quote@
     1338@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/TupleType.Po@am__quote@
     1339@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/Type.Po@am__quote@
     1340@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/TypeDecl.Po@am__quote@
     1341@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/TypeExpr.Po@am__quote@
     1342@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/TypeSubstitution.Po@am__quote@
     1343@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/TypeofType.Po@am__quote@
     1344@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/VarArgsType.Po@am__quote@
     1345@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/VoidType.Po@am__quote@
     1346@AMDEP_TRUE@@am__include@ @am__quote@SynTree/$(DEPDIR)/ZeroOneType.Po@am__quote@
     1347@AMDEP_TRUE@@am__include@ @am__quote@Tuples/$(DEPDIR)/Explode.Po@am__quote@
     1348@AMDEP_TRUE@@am__include@ @am__quote@Tuples/$(DEPDIR)/TupleAssignment.Po@am__quote@
     1349@AMDEP_TRUE@@am__include@ @am__quote@Tuples/$(DEPDIR)/TupleExpansion.Po@am__quote@
     1350@AMDEP_TRUE@@am__include@ @am__quote@Tuples/$(DEPDIR)/Tuples.Po@am__quote@
     1351@AMDEP_TRUE@@am__include@ @am__quote@Validate/$(DEPDIR)/FindSpecialDecls.Po@am__quote@
     1352@AMDEP_TRUE@@am__include@ @am__quote@Validate/$(DEPDIR)/HandleAttributes.Po@am__quote@
     1353@AMDEP_TRUE@@am__include@ @am__quote@Virtual/$(DEPDIR)/ExpandCasts.Po@am__quote@
    10731354
    10741355.cc.o:
     
    10881369@am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
    10891370
    1090 driver_cfa_cpp-main.o: main.cc
    1091 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT driver_cfa_cpp-main.o -MD -MP -MF $(DEPDIR)/driver_cfa_cpp-main.Tpo -c -o driver_cfa_cpp-main.o `test -f 'main.cc' || echo '$(srcdir)/'`main.cc
    1092 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) $(DEPDIR)/driver_cfa_cpp-main.Tpo $(DEPDIR)/driver_cfa_cpp-main.Po
    1093 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='main.cc' object='driver_cfa_cpp-main.o' libtool=no @AMDEPBACKSLASH@
     1371.cc.lo:
     1372@am__fastdepCXX_TRUE@   $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
     1373@am__fastdepCXX_TRUE@   $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
     1374@am__fastdepCXX_TRUE@   $(am__mv) $$depbase.Tpo $$depbase.Plo
     1375@AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
    10941376@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1095 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o driver_cfa_cpp-main.o `test -f 'main.cc' || echo '$(srcdir)/'`main.cc
    1096 
    1097 driver_cfa_cpp-main.obj: main.cc
    1098 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT driver_cfa_cpp-main.obj -MD -MP -MF $(DEPDIR)/driver_cfa_cpp-main.Tpo -c -o driver_cfa_cpp-main.obj `if test -f 'main.cc'; then $(CYGPATH_W) 'main.cc'; else $(CYGPATH_W) '$(srcdir)/main.cc'; fi`
    1099 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) $(DEPDIR)/driver_cfa_cpp-main.Tpo $(DEPDIR)/driver_cfa_cpp-main.Po
    1100 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='main.cc' object='driver_cfa_cpp-main.obj' libtool=no @AMDEPBACKSLASH@
     1377@am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
     1378
     1379.cpp.o:
     1380@am__fastdepCXX_TRUE@   $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\
     1381@am__fastdepCXX_TRUE@   $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
     1382@am__fastdepCXX_TRUE@   $(am__mv) $$depbase.Tpo $$depbase.Po
     1383@AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
    11011384@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1102 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o driver_cfa_cpp-main.obj `if test -f 'main.cc'; then $(CYGPATH_W) 'main.cc'; else $(CYGPATH_W) '$(srcdir)/main.cc'; fi`
    1103 
    1104 driver_cfa_cpp-MakeLibCfa.o: MakeLibCfa.cc
    1105 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT driver_cfa_cpp-MakeLibCfa.o -MD -MP -MF $(DEPDIR)/driver_cfa_cpp-MakeLibCfa.Tpo -c -o driver_cfa_cpp-MakeLibCfa.o `test -f 'MakeLibCfa.cc' || echo '$(srcdir)/'`MakeLibCfa.cc
    1106 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) $(DEPDIR)/driver_cfa_cpp-MakeLibCfa.Tpo $(DEPDIR)/driver_cfa_cpp-MakeLibCfa.Po
    1107 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='MakeLibCfa.cc' object='driver_cfa_cpp-MakeLibCfa.o' libtool=no @AMDEPBACKSLASH@
     1385@am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $<
     1386
     1387.cpp.obj:
     1388@am__fastdepCXX_TRUE@   $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\
     1389@am__fastdepCXX_TRUE@   $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\
     1390@am__fastdepCXX_TRUE@   $(am__mv) $$depbase.Tpo $$depbase.Po
     1391@AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
    11081392@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1109 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o driver_cfa_cpp-MakeLibCfa.o `test -f 'MakeLibCfa.cc' || echo '$(srcdir)/'`MakeLibCfa.cc
    1110 
    1111 driver_cfa_cpp-MakeLibCfa.obj: MakeLibCfa.cc
    1112 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT driver_cfa_cpp-MakeLibCfa.obj -MD -MP -MF $(DEPDIR)/driver_cfa_cpp-MakeLibCfa.Tpo -c -o driver_cfa_cpp-MakeLibCfa.obj `if test -f 'MakeLibCfa.cc'; then $(CYGPATH_W) 'MakeLibCfa.cc'; else $(CYGPATH_W) '$(srcdir)/MakeLibCfa.cc'; fi`
    1113 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) $(DEPDIR)/driver_cfa_cpp-MakeLibCfa.Tpo $(DEPDIR)/driver_cfa_cpp-MakeLibCfa.Po
    1114 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='MakeLibCfa.cc' object='driver_cfa_cpp-MakeLibCfa.obj' libtool=no @AMDEPBACKSLASH@
     1393@am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
     1394
     1395.cpp.lo:
     1396@am__fastdepCXX_TRUE@   $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\
     1397@am__fastdepCXX_TRUE@   $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\
     1398@am__fastdepCXX_TRUE@   $(am__mv) $$depbase.Tpo $$depbase.Plo
     1399@AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
    11151400@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1116 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o driver_cfa_cpp-MakeLibCfa.obj `if test -f 'MakeLibCfa.cc'; then $(CYGPATH_W) 'MakeLibCfa.cc'; else $(CYGPATH_W) '$(srcdir)/MakeLibCfa.cc'; fi`
    1117 
    1118 CodeGen/driver_cfa_cpp-Generate.o: CodeGen/Generate.cc
    1119 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT CodeGen/driver_cfa_cpp-Generate.o -MD -MP -MF CodeGen/$(DEPDIR)/driver_cfa_cpp-Generate.Tpo -c -o CodeGen/driver_cfa_cpp-Generate.o `test -f 'CodeGen/Generate.cc' || echo '$(srcdir)/'`CodeGen/Generate.cc
    1120 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) CodeGen/$(DEPDIR)/driver_cfa_cpp-Generate.Tpo CodeGen/$(DEPDIR)/driver_cfa_cpp-Generate.Po
    1121 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='CodeGen/Generate.cc' object='CodeGen/driver_cfa_cpp-Generate.o' libtool=no @AMDEPBACKSLASH@
    1122 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1123 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o CodeGen/driver_cfa_cpp-Generate.o `test -f 'CodeGen/Generate.cc' || echo '$(srcdir)/'`CodeGen/Generate.cc
    1124 
    1125 CodeGen/driver_cfa_cpp-Generate.obj: CodeGen/Generate.cc
    1126 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT CodeGen/driver_cfa_cpp-Generate.obj -MD -MP -MF CodeGen/$(DEPDIR)/driver_cfa_cpp-Generate.Tpo -c -o CodeGen/driver_cfa_cpp-Generate.obj `if test -f 'CodeGen/Generate.cc'; then $(CYGPATH_W) 'CodeGen/Generate.cc'; else $(CYGPATH_W) '$(srcdir)/CodeGen/Generate.cc'; fi`
    1127 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) CodeGen/$(DEPDIR)/driver_cfa_cpp-Generate.Tpo CodeGen/$(DEPDIR)/driver_cfa_cpp-Generate.Po
    1128 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='CodeGen/Generate.cc' object='CodeGen/driver_cfa_cpp-Generate.obj' libtool=no @AMDEPBACKSLASH@
    1129 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1130 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o CodeGen/driver_cfa_cpp-Generate.obj `if test -f 'CodeGen/Generate.cc'; then $(CYGPATH_W) 'CodeGen/Generate.cc'; else $(CYGPATH_W) '$(srcdir)/CodeGen/Generate.cc'; fi`
    1131 
    1132 CodeGen/driver_cfa_cpp-CodeGenerator.o: CodeGen/CodeGenerator.cc
    1133 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT CodeGen/driver_cfa_cpp-CodeGenerator.o -MD -MP -MF CodeGen/$(DEPDIR)/driver_cfa_cpp-CodeGenerator.Tpo -c -o CodeGen/driver_cfa_cpp-CodeGenerator.o `test -f 'CodeGen/CodeGenerator.cc' || echo '$(srcdir)/'`CodeGen/CodeGenerator.cc
    1134 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) CodeGen/$(DEPDIR)/driver_cfa_cpp-CodeGenerator.Tpo CodeGen/$(DEPDIR)/driver_cfa_cpp-CodeGenerator.Po
    1135 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='CodeGen/CodeGenerator.cc' object='CodeGen/driver_cfa_cpp-CodeGenerator.o' libtool=no @AMDEPBACKSLASH@
    1136 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1137 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o CodeGen/driver_cfa_cpp-CodeGenerator.o `test -f 'CodeGen/CodeGenerator.cc' || echo '$(srcdir)/'`CodeGen/CodeGenerator.cc
    1138 
    1139 CodeGen/driver_cfa_cpp-CodeGenerator.obj: CodeGen/CodeGenerator.cc
    1140 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT CodeGen/driver_cfa_cpp-CodeGenerator.obj -MD -MP -MF CodeGen/$(DEPDIR)/driver_cfa_cpp-CodeGenerator.Tpo -c -o CodeGen/driver_cfa_cpp-CodeGenerator.obj `if test -f 'CodeGen/CodeGenerator.cc'; then $(CYGPATH_W) 'CodeGen/CodeGenerator.cc'; else $(CYGPATH_W) '$(srcdir)/CodeGen/CodeGenerator.cc'; fi`
    1141 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) CodeGen/$(DEPDIR)/driver_cfa_cpp-CodeGenerator.Tpo CodeGen/$(DEPDIR)/driver_cfa_cpp-CodeGenerator.Po
    1142 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='CodeGen/CodeGenerator.cc' object='CodeGen/driver_cfa_cpp-CodeGenerator.obj' libtool=no @AMDEPBACKSLASH@
    1143 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1144 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o CodeGen/driver_cfa_cpp-CodeGenerator.obj `if test -f 'CodeGen/CodeGenerator.cc'; then $(CYGPATH_W) 'CodeGen/CodeGenerator.cc'; else $(CYGPATH_W) '$(srcdir)/CodeGen/CodeGenerator.cc'; fi`
    1145 
    1146 CodeGen/driver_cfa_cpp-GenType.o: CodeGen/GenType.cc
    1147 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT CodeGen/driver_cfa_cpp-GenType.o -MD -MP -MF CodeGen/$(DEPDIR)/driver_cfa_cpp-GenType.Tpo -c -o CodeGen/driver_cfa_cpp-GenType.o `test -f 'CodeGen/GenType.cc' || echo '$(srcdir)/'`CodeGen/GenType.cc
    1148 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) CodeGen/$(DEPDIR)/driver_cfa_cpp-GenType.Tpo CodeGen/$(DEPDIR)/driver_cfa_cpp-GenType.Po
    1149 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='CodeGen/GenType.cc' object='CodeGen/driver_cfa_cpp-GenType.o' libtool=no @AMDEPBACKSLASH@
    1150 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1151 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o CodeGen/driver_cfa_cpp-GenType.o `test -f 'CodeGen/GenType.cc' || echo '$(srcdir)/'`CodeGen/GenType.cc
    1152 
    1153 CodeGen/driver_cfa_cpp-GenType.obj: CodeGen/GenType.cc
    1154 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT CodeGen/driver_cfa_cpp-GenType.obj -MD -MP -MF CodeGen/$(DEPDIR)/driver_cfa_cpp-GenType.Tpo -c -o CodeGen/driver_cfa_cpp-GenType.obj `if test -f 'CodeGen/GenType.cc'; then $(CYGPATH_W) 'CodeGen/GenType.cc'; else $(CYGPATH_W) '$(srcdir)/CodeGen/GenType.cc'; fi`
    1155 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) CodeGen/$(DEPDIR)/driver_cfa_cpp-GenType.Tpo CodeGen/$(DEPDIR)/driver_cfa_cpp-GenType.Po
    1156 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='CodeGen/GenType.cc' object='CodeGen/driver_cfa_cpp-GenType.obj' libtool=no @AMDEPBACKSLASH@
    1157 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1158 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o CodeGen/driver_cfa_cpp-GenType.obj `if test -f 'CodeGen/GenType.cc'; then $(CYGPATH_W) 'CodeGen/GenType.cc'; else $(CYGPATH_W) '$(srcdir)/CodeGen/GenType.cc'; fi`
    1159 
    1160 CodeGen/driver_cfa_cpp-FixNames.o: CodeGen/FixNames.cc
    1161 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT CodeGen/driver_cfa_cpp-FixNames.o -MD -MP -MF CodeGen/$(DEPDIR)/driver_cfa_cpp-FixNames.Tpo -c -o CodeGen/driver_cfa_cpp-FixNames.o `test -f 'CodeGen/FixNames.cc' || echo '$(srcdir)/'`CodeGen/FixNames.cc
    1162 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) CodeGen/$(DEPDIR)/driver_cfa_cpp-FixNames.Tpo CodeGen/$(DEPDIR)/driver_cfa_cpp-FixNames.Po
    1163 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='CodeGen/FixNames.cc' object='CodeGen/driver_cfa_cpp-FixNames.o' libtool=no @AMDEPBACKSLASH@
    1164 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1165 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o CodeGen/driver_cfa_cpp-FixNames.o `test -f 'CodeGen/FixNames.cc' || echo '$(srcdir)/'`CodeGen/FixNames.cc
    1166 
    1167 CodeGen/driver_cfa_cpp-FixNames.obj: CodeGen/FixNames.cc
    1168 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT CodeGen/driver_cfa_cpp-FixNames.obj -MD -MP -MF CodeGen/$(DEPDIR)/driver_cfa_cpp-FixNames.Tpo -c -o CodeGen/driver_cfa_cpp-FixNames.obj `if test -f 'CodeGen/FixNames.cc'; then $(CYGPATH_W) 'CodeGen/FixNames.cc'; else $(CYGPATH_W) '$(srcdir)/CodeGen/FixNames.cc'; fi`
    1169 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) CodeGen/$(DEPDIR)/driver_cfa_cpp-FixNames.Tpo CodeGen/$(DEPDIR)/driver_cfa_cpp-FixNames.Po
    1170 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='CodeGen/FixNames.cc' object='CodeGen/driver_cfa_cpp-FixNames.obj' libtool=no @AMDEPBACKSLASH@
    1171 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1172 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o CodeGen/driver_cfa_cpp-FixNames.obj `if test -f 'CodeGen/FixNames.cc'; then $(CYGPATH_W) 'CodeGen/FixNames.cc'; else $(CYGPATH_W) '$(srcdir)/CodeGen/FixNames.cc'; fi`
    1173 
    1174 CodeGen/driver_cfa_cpp-FixMain.o: CodeGen/FixMain.cc
    1175 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT CodeGen/driver_cfa_cpp-FixMain.o -MD -MP -MF CodeGen/$(DEPDIR)/driver_cfa_cpp-FixMain.Tpo -c -o CodeGen/driver_cfa_cpp-FixMain.o `test -f 'CodeGen/FixMain.cc' || echo '$(srcdir)/'`CodeGen/FixMain.cc
    1176 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) CodeGen/$(DEPDIR)/driver_cfa_cpp-FixMain.Tpo CodeGen/$(DEPDIR)/driver_cfa_cpp-FixMain.Po
    1177 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='CodeGen/FixMain.cc' object='CodeGen/driver_cfa_cpp-FixMain.o' libtool=no @AMDEPBACKSLASH@
    1178 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1179 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o CodeGen/driver_cfa_cpp-FixMain.o `test -f 'CodeGen/FixMain.cc' || echo '$(srcdir)/'`CodeGen/FixMain.cc
    1180 
    1181 CodeGen/driver_cfa_cpp-FixMain.obj: CodeGen/FixMain.cc
    1182 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT CodeGen/driver_cfa_cpp-FixMain.obj -MD -MP -MF CodeGen/$(DEPDIR)/driver_cfa_cpp-FixMain.Tpo -c -o CodeGen/driver_cfa_cpp-FixMain.obj `if test -f 'CodeGen/FixMain.cc'; then $(CYGPATH_W) 'CodeGen/FixMain.cc'; else $(CYGPATH_W) '$(srcdir)/CodeGen/FixMain.cc'; fi`
    1183 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) CodeGen/$(DEPDIR)/driver_cfa_cpp-FixMain.Tpo CodeGen/$(DEPDIR)/driver_cfa_cpp-FixMain.Po
    1184 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='CodeGen/FixMain.cc' object='CodeGen/driver_cfa_cpp-FixMain.obj' libtool=no @AMDEPBACKSLASH@
    1185 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1186 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o CodeGen/driver_cfa_cpp-FixMain.obj `if test -f 'CodeGen/FixMain.cc'; then $(CYGPATH_W) 'CodeGen/FixMain.cc'; else $(CYGPATH_W) '$(srcdir)/CodeGen/FixMain.cc'; fi`
    1187 
    1188 CodeGen/driver_cfa_cpp-OperatorTable.o: CodeGen/OperatorTable.cc
    1189 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT CodeGen/driver_cfa_cpp-OperatorTable.o -MD -MP -MF CodeGen/$(DEPDIR)/driver_cfa_cpp-OperatorTable.Tpo -c -o CodeGen/driver_cfa_cpp-OperatorTable.o `test -f 'CodeGen/OperatorTable.cc' || echo '$(srcdir)/'`CodeGen/OperatorTable.cc
    1190 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) CodeGen/$(DEPDIR)/driver_cfa_cpp-OperatorTable.Tpo CodeGen/$(DEPDIR)/driver_cfa_cpp-OperatorTable.Po
    1191 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='CodeGen/OperatorTable.cc' object='CodeGen/driver_cfa_cpp-OperatorTable.o' libtool=no @AMDEPBACKSLASH@
    1192 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1193 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o CodeGen/driver_cfa_cpp-OperatorTable.o `test -f 'CodeGen/OperatorTable.cc' || echo '$(srcdir)/'`CodeGen/OperatorTable.cc
    1194 
    1195 CodeGen/driver_cfa_cpp-OperatorTable.obj: CodeGen/OperatorTable.cc
    1196 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT CodeGen/driver_cfa_cpp-OperatorTable.obj -MD -MP -MF CodeGen/$(DEPDIR)/driver_cfa_cpp-OperatorTable.Tpo -c -o CodeGen/driver_cfa_cpp-OperatorTable.obj `if test -f 'CodeGen/OperatorTable.cc'; then $(CYGPATH_W) 'CodeGen/OperatorTable.cc'; else $(CYGPATH_W) '$(srcdir)/CodeGen/OperatorTable.cc'; fi`
    1197 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) CodeGen/$(DEPDIR)/driver_cfa_cpp-OperatorTable.Tpo CodeGen/$(DEPDIR)/driver_cfa_cpp-OperatorTable.Po
    1198 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='CodeGen/OperatorTable.cc' object='CodeGen/driver_cfa_cpp-OperatorTable.obj' libtool=no @AMDEPBACKSLASH@
    1199 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1200 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o CodeGen/driver_cfa_cpp-OperatorTable.obj `if test -f 'CodeGen/OperatorTable.cc'; then $(CYGPATH_W) 'CodeGen/OperatorTable.cc'; else $(CYGPATH_W) '$(srcdir)/CodeGen/OperatorTable.cc'; fi`
    1201 
    1202 CodeTools/driver_cfa_cpp-DeclStats.o: CodeTools/DeclStats.cc
    1203 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT CodeTools/driver_cfa_cpp-DeclStats.o -MD -MP -MF CodeTools/$(DEPDIR)/driver_cfa_cpp-DeclStats.Tpo -c -o CodeTools/driver_cfa_cpp-DeclStats.o `test -f 'CodeTools/DeclStats.cc' || echo '$(srcdir)/'`CodeTools/DeclStats.cc
    1204 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) CodeTools/$(DEPDIR)/driver_cfa_cpp-DeclStats.Tpo CodeTools/$(DEPDIR)/driver_cfa_cpp-DeclStats.Po
    1205 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='CodeTools/DeclStats.cc' object='CodeTools/driver_cfa_cpp-DeclStats.o' libtool=no @AMDEPBACKSLASH@
    1206 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1207 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o CodeTools/driver_cfa_cpp-DeclStats.o `test -f 'CodeTools/DeclStats.cc' || echo '$(srcdir)/'`CodeTools/DeclStats.cc
    1208 
    1209 CodeTools/driver_cfa_cpp-DeclStats.obj: CodeTools/DeclStats.cc
    1210 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT CodeTools/driver_cfa_cpp-DeclStats.obj -MD -MP -MF CodeTools/$(DEPDIR)/driver_cfa_cpp-DeclStats.Tpo -c -o CodeTools/driver_cfa_cpp-DeclStats.obj `if test -f 'CodeTools/DeclStats.cc'; then $(CYGPATH_W) 'CodeTools/DeclStats.cc'; else $(CYGPATH_W) '$(srcdir)/CodeTools/DeclStats.cc'; fi`
    1211 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) CodeTools/$(DEPDIR)/driver_cfa_cpp-DeclStats.Tpo CodeTools/$(DEPDIR)/driver_cfa_cpp-DeclStats.Po
    1212 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='CodeTools/DeclStats.cc' object='CodeTools/driver_cfa_cpp-DeclStats.obj' libtool=no @AMDEPBACKSLASH@
    1213 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1214 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o CodeTools/driver_cfa_cpp-DeclStats.obj `if test -f 'CodeTools/DeclStats.cc'; then $(CYGPATH_W) 'CodeTools/DeclStats.cc'; else $(CYGPATH_W) '$(srcdir)/CodeTools/DeclStats.cc'; fi`
    1215 
    1216 CodeTools/driver_cfa_cpp-TrackLoc.o: CodeTools/TrackLoc.cc
    1217 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT CodeTools/driver_cfa_cpp-TrackLoc.o -MD -MP -MF CodeTools/$(DEPDIR)/driver_cfa_cpp-TrackLoc.Tpo -c -o CodeTools/driver_cfa_cpp-TrackLoc.o `test -f 'CodeTools/TrackLoc.cc' || echo '$(srcdir)/'`CodeTools/TrackLoc.cc
    1218 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) CodeTools/$(DEPDIR)/driver_cfa_cpp-TrackLoc.Tpo CodeTools/$(DEPDIR)/driver_cfa_cpp-TrackLoc.Po
    1219 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='CodeTools/TrackLoc.cc' object='CodeTools/driver_cfa_cpp-TrackLoc.o' libtool=no @AMDEPBACKSLASH@
    1220 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1221 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o CodeTools/driver_cfa_cpp-TrackLoc.o `test -f 'CodeTools/TrackLoc.cc' || echo '$(srcdir)/'`CodeTools/TrackLoc.cc
    1222 
    1223 CodeTools/driver_cfa_cpp-TrackLoc.obj: CodeTools/TrackLoc.cc
    1224 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT CodeTools/driver_cfa_cpp-TrackLoc.obj -MD -MP -MF CodeTools/$(DEPDIR)/driver_cfa_cpp-TrackLoc.Tpo -c -o CodeTools/driver_cfa_cpp-TrackLoc.obj `if test -f 'CodeTools/TrackLoc.cc'; then $(CYGPATH_W) 'CodeTools/TrackLoc.cc'; else $(CYGPATH_W) '$(srcdir)/CodeTools/TrackLoc.cc'; fi`
    1225 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) CodeTools/$(DEPDIR)/driver_cfa_cpp-TrackLoc.Tpo CodeTools/$(DEPDIR)/driver_cfa_cpp-TrackLoc.Po
    1226 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='CodeTools/TrackLoc.cc' object='CodeTools/driver_cfa_cpp-TrackLoc.obj' libtool=no @AMDEPBACKSLASH@
    1227 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1228 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o CodeTools/driver_cfa_cpp-TrackLoc.obj `if test -f 'CodeTools/TrackLoc.cc'; then $(CYGPATH_W) 'CodeTools/TrackLoc.cc'; else $(CYGPATH_W) '$(srcdir)/CodeTools/TrackLoc.cc'; fi`
    1229 
    1230 Concurrency/driver_cfa_cpp-Keywords.o: Concurrency/Keywords.cc
    1231 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Concurrency/driver_cfa_cpp-Keywords.o -MD -MP -MF Concurrency/$(DEPDIR)/driver_cfa_cpp-Keywords.Tpo -c -o Concurrency/driver_cfa_cpp-Keywords.o `test -f 'Concurrency/Keywords.cc' || echo '$(srcdir)/'`Concurrency/Keywords.cc
    1232 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) Concurrency/$(DEPDIR)/driver_cfa_cpp-Keywords.Tpo Concurrency/$(DEPDIR)/driver_cfa_cpp-Keywords.Po
    1233 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='Concurrency/Keywords.cc' object='Concurrency/driver_cfa_cpp-Keywords.o' libtool=no @AMDEPBACKSLASH@
    1234 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1235 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Concurrency/driver_cfa_cpp-Keywords.o `test -f 'Concurrency/Keywords.cc' || echo '$(srcdir)/'`Concurrency/Keywords.cc
    1236 
    1237 Concurrency/driver_cfa_cpp-Keywords.obj: Concurrency/Keywords.cc
    1238 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Concurrency/driver_cfa_cpp-Keywords.obj -MD -MP -MF Concurrency/$(DEPDIR)/driver_cfa_cpp-Keywords.Tpo -c -o Concurrency/driver_cfa_cpp-Keywords.obj `if test -f 'Concurrency/Keywords.cc'; then $(CYGPATH_W) 'Concurrency/Keywords.cc'; else $(CYGPATH_W) '$(srcdir)/Concurrency/Keywords.cc'; fi`
    1239 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) Concurrency/$(DEPDIR)/driver_cfa_cpp-Keywords.Tpo Concurrency/$(DEPDIR)/driver_cfa_cpp-Keywords.Po
    1240 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='Concurrency/Keywords.cc' object='Concurrency/driver_cfa_cpp-Keywords.obj' libtool=no @AMDEPBACKSLASH@
    1241 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1242 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Concurrency/driver_cfa_cpp-Keywords.obj `if test -f 'Concurrency/Keywords.cc'; then $(CYGPATH_W) 'Concurrency/Keywords.cc'; else $(CYGPATH_W) '$(srcdir)/Concurrency/Keywords.cc'; fi`
    1243 
    1244 Concurrency/driver_cfa_cpp-Waitfor.o: Concurrency/Waitfor.cc
    1245 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Concurrency/driver_cfa_cpp-Waitfor.o -MD -MP -MF Concurrency/$(DEPDIR)/driver_cfa_cpp-Waitfor.Tpo -c -o Concurrency/driver_cfa_cpp-Waitfor.o `test -f 'Concurrency/Waitfor.cc' || echo '$(srcdir)/'`Concurrency/Waitfor.cc
    1246 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) Concurrency/$(DEPDIR)/driver_cfa_cpp-Waitfor.Tpo Concurrency/$(DEPDIR)/driver_cfa_cpp-Waitfor.Po
    1247 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='Concurrency/Waitfor.cc' object='Concurrency/driver_cfa_cpp-Waitfor.o' libtool=no @AMDEPBACKSLASH@
    1248 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1249 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Concurrency/driver_cfa_cpp-Waitfor.o `test -f 'Concurrency/Waitfor.cc' || echo '$(srcdir)/'`Concurrency/Waitfor.cc
    1250 
    1251 Concurrency/driver_cfa_cpp-Waitfor.obj: Concurrency/Waitfor.cc
    1252 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Concurrency/driver_cfa_cpp-Waitfor.obj -MD -MP -MF Concurrency/$(DEPDIR)/driver_cfa_cpp-Waitfor.Tpo -c -o Concurrency/driver_cfa_cpp-Waitfor.obj `if test -f 'Concurrency/Waitfor.cc'; then $(CYGPATH_W) 'Concurrency/Waitfor.cc'; else $(CYGPATH_W) '$(srcdir)/Concurrency/Waitfor.cc'; fi`
    1253 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) Concurrency/$(DEPDIR)/driver_cfa_cpp-Waitfor.Tpo Concurrency/$(DEPDIR)/driver_cfa_cpp-Waitfor.Po
    1254 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='Concurrency/Waitfor.cc' object='Concurrency/driver_cfa_cpp-Waitfor.obj' libtool=no @AMDEPBACKSLASH@
    1255 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1256 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Concurrency/driver_cfa_cpp-Waitfor.obj `if test -f 'Concurrency/Waitfor.cc'; then $(CYGPATH_W) 'Concurrency/Waitfor.cc'; else $(CYGPATH_W) '$(srcdir)/Concurrency/Waitfor.cc'; fi`
    1257 
    1258 Common/driver_cfa_cpp-SemanticError.o: Common/SemanticError.cc
    1259 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Common/driver_cfa_cpp-SemanticError.o -MD -MP -MF Common/$(DEPDIR)/driver_cfa_cpp-SemanticError.Tpo -c -o Common/driver_cfa_cpp-SemanticError.o `test -f 'Common/SemanticError.cc' || echo '$(srcdir)/'`Common/SemanticError.cc
    1260 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) Common/$(DEPDIR)/driver_cfa_cpp-SemanticError.Tpo Common/$(DEPDIR)/driver_cfa_cpp-SemanticError.Po
    1261 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='Common/SemanticError.cc' object='Common/driver_cfa_cpp-SemanticError.o' libtool=no @AMDEPBACKSLASH@
    1262 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1263 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Common/driver_cfa_cpp-SemanticError.o `test -f 'Common/SemanticError.cc' || echo '$(srcdir)/'`Common/SemanticError.cc
    1264 
    1265 Common/driver_cfa_cpp-SemanticError.obj: Common/SemanticError.cc
    1266 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Common/driver_cfa_cpp-SemanticError.obj -MD -MP -MF Common/$(DEPDIR)/driver_cfa_cpp-SemanticError.Tpo -c -o Common/driver_cfa_cpp-SemanticError.obj `if test -f 'Common/SemanticError.cc'; then $(CYGPATH_W) 'Common/SemanticError.cc'; else $(CYGPATH_W) '$(srcdir)/Common/SemanticError.cc'; fi`
    1267 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) Common/$(DEPDIR)/driver_cfa_cpp-SemanticError.Tpo Common/$(DEPDIR)/driver_cfa_cpp-SemanticError.Po
    1268 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='Common/SemanticError.cc' object='Common/driver_cfa_cpp-SemanticError.obj' libtool=no @AMDEPBACKSLASH@
    1269 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1270 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Common/driver_cfa_cpp-SemanticError.obj `if test -f 'Common/SemanticError.cc'; then $(CYGPATH_W) 'Common/SemanticError.cc'; else $(CYGPATH_W) '$(srcdir)/Common/SemanticError.cc'; fi`
    1271 
    1272 Common/driver_cfa_cpp-UniqueName.o: Common/UniqueName.cc
    1273 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Common/driver_cfa_cpp-UniqueName.o -MD -MP -MF Common/$(DEPDIR)/driver_cfa_cpp-UniqueName.Tpo -c -o Common/driver_cfa_cpp-UniqueName.o `test -f 'Common/UniqueName.cc' || echo '$(srcdir)/'`Common/UniqueName.cc
    1274 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) Common/$(DEPDIR)/driver_cfa_cpp-UniqueName.Tpo Common/$(DEPDIR)/driver_cfa_cpp-UniqueName.Po
    1275 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='Common/UniqueName.cc' object='Common/driver_cfa_cpp-UniqueName.o' libtool=no @AMDEPBACKSLASH@
    1276 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1277 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Common/driver_cfa_cpp-UniqueName.o `test -f 'Common/UniqueName.cc' || echo '$(srcdir)/'`Common/UniqueName.cc
    1278 
    1279 Common/driver_cfa_cpp-UniqueName.obj: Common/UniqueName.cc
    1280 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Common/driver_cfa_cpp-UniqueName.obj -MD -MP -MF Common/$(DEPDIR)/driver_cfa_cpp-UniqueName.Tpo -c -o Common/driver_cfa_cpp-UniqueName.obj `if test -f 'Common/UniqueName.cc'; then $(CYGPATH_W) 'Common/UniqueName.cc'; else $(CYGPATH_W) '$(srcdir)/Common/UniqueName.cc'; fi`
    1281 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) Common/$(DEPDIR)/driver_cfa_cpp-UniqueName.Tpo Common/$(DEPDIR)/driver_cfa_cpp-UniqueName.Po
    1282 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='Common/UniqueName.cc' object='Common/driver_cfa_cpp-UniqueName.obj' libtool=no @AMDEPBACKSLASH@
    1283 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1284 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Common/driver_cfa_cpp-UniqueName.obj `if test -f 'Common/UniqueName.cc'; then $(CYGPATH_W) 'Common/UniqueName.cc'; else $(CYGPATH_W) '$(srcdir)/Common/UniqueName.cc'; fi`
    1285 
    1286 Common/driver_cfa_cpp-DebugMalloc.o: Common/DebugMalloc.cc
    1287 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Common/driver_cfa_cpp-DebugMalloc.o -MD -MP -MF Common/$(DEPDIR)/driver_cfa_cpp-DebugMalloc.Tpo -c -o Common/driver_cfa_cpp-DebugMalloc.o `test -f 'Common/DebugMalloc.cc' || echo '$(srcdir)/'`Common/DebugMalloc.cc
    1288 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) Common/$(DEPDIR)/driver_cfa_cpp-DebugMalloc.Tpo Common/$(DEPDIR)/driver_cfa_cpp-DebugMalloc.Po
    1289 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='Common/DebugMalloc.cc' object='Common/driver_cfa_cpp-DebugMalloc.o' libtool=no @AMDEPBACKSLASH@
    1290 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1291 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Common/driver_cfa_cpp-DebugMalloc.o `test -f 'Common/DebugMalloc.cc' || echo '$(srcdir)/'`Common/DebugMalloc.cc
    1292 
    1293 Common/driver_cfa_cpp-DebugMalloc.obj: Common/DebugMalloc.cc
    1294 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Common/driver_cfa_cpp-DebugMalloc.obj -MD -MP -MF Common/$(DEPDIR)/driver_cfa_cpp-DebugMalloc.Tpo -c -o Common/driver_cfa_cpp-DebugMalloc.obj `if test -f 'Common/DebugMalloc.cc'; then $(CYGPATH_W) 'Common/DebugMalloc.cc'; else $(CYGPATH_W) '$(srcdir)/Common/DebugMalloc.cc'; fi`
    1295 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) Common/$(DEPDIR)/driver_cfa_cpp-DebugMalloc.Tpo Common/$(DEPDIR)/driver_cfa_cpp-DebugMalloc.Po
    1296 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='Common/DebugMalloc.cc' object='Common/driver_cfa_cpp-DebugMalloc.obj' libtool=no @AMDEPBACKSLASH@
    1297 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1298 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Common/driver_cfa_cpp-DebugMalloc.obj `if test -f 'Common/DebugMalloc.cc'; then $(CYGPATH_W) 'Common/DebugMalloc.cc'; else $(CYGPATH_W) '$(srcdir)/Common/DebugMalloc.cc'; fi`
    1299 
    1300 Common/driver_cfa_cpp-Assert.o: Common/Assert.cc
    1301 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Common/driver_cfa_cpp-Assert.o -MD -MP -MF Common/$(DEPDIR)/driver_cfa_cpp-Assert.Tpo -c -o Common/driver_cfa_cpp-Assert.o `test -f 'Common/Assert.cc' || echo '$(srcdir)/'`Common/Assert.cc
    1302 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) Common/$(DEPDIR)/driver_cfa_cpp-Assert.Tpo Common/$(DEPDIR)/driver_cfa_cpp-Assert.Po
    1303 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='Common/Assert.cc' object='Common/driver_cfa_cpp-Assert.o' libtool=no @AMDEPBACKSLASH@
    1304 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1305 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Common/driver_cfa_cpp-Assert.o `test -f 'Common/Assert.cc' || echo '$(srcdir)/'`Common/Assert.cc
    1306 
    1307 Common/driver_cfa_cpp-Assert.obj: Common/Assert.cc
    1308 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Common/driver_cfa_cpp-Assert.obj -MD -MP -MF Common/$(DEPDIR)/driver_cfa_cpp-Assert.Tpo -c -o Common/driver_cfa_cpp-Assert.obj `if test -f 'Common/Assert.cc'; then $(CYGPATH_W) 'Common/Assert.cc'; else $(CYGPATH_W) '$(srcdir)/Common/Assert.cc'; fi`
    1309 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) Common/$(DEPDIR)/driver_cfa_cpp-Assert.Tpo Common/$(DEPDIR)/driver_cfa_cpp-Assert.Po
    1310 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='Common/Assert.cc' object='Common/driver_cfa_cpp-Assert.obj' libtool=no @AMDEPBACKSLASH@
    1311 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1312 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Common/driver_cfa_cpp-Assert.obj `if test -f 'Common/Assert.cc'; then $(CYGPATH_W) 'Common/Assert.cc'; else $(CYGPATH_W) '$(srcdir)/Common/Assert.cc'; fi`
    1313 
    1314 Common/driver_cfa_cpp-Heap.o: Common/Heap.cc
    1315 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Common/driver_cfa_cpp-Heap.o -MD -MP -MF Common/$(DEPDIR)/driver_cfa_cpp-Heap.Tpo -c -o Common/driver_cfa_cpp-Heap.o `test -f 'Common/Heap.cc' || echo '$(srcdir)/'`Common/Heap.cc
    1316 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) Common/$(DEPDIR)/driver_cfa_cpp-Heap.Tpo Common/$(DEPDIR)/driver_cfa_cpp-Heap.Po
    1317 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='Common/Heap.cc' object='Common/driver_cfa_cpp-Heap.o' libtool=no @AMDEPBACKSLASH@
    1318 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1319 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Common/driver_cfa_cpp-Heap.o `test -f 'Common/Heap.cc' || echo '$(srcdir)/'`Common/Heap.cc
    1320 
    1321 Common/driver_cfa_cpp-Heap.obj: Common/Heap.cc
    1322 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Common/driver_cfa_cpp-Heap.obj -MD -MP -MF Common/$(DEPDIR)/driver_cfa_cpp-Heap.Tpo -c -o Common/driver_cfa_cpp-Heap.obj `if test -f 'Common/Heap.cc'; then $(CYGPATH_W) 'Common/Heap.cc'; else $(CYGPATH_W) '$(srcdir)/Common/Heap.cc'; fi`
    1323 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) Common/$(DEPDIR)/driver_cfa_cpp-Heap.Tpo Common/$(DEPDIR)/driver_cfa_cpp-Heap.Po
    1324 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='Common/Heap.cc' object='Common/driver_cfa_cpp-Heap.obj' libtool=no @AMDEPBACKSLASH@
    1325 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1326 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Common/driver_cfa_cpp-Heap.obj `if test -f 'Common/Heap.cc'; then $(CYGPATH_W) 'Common/Heap.cc'; else $(CYGPATH_W) '$(srcdir)/Common/Heap.cc'; fi`
    1327 
    1328 ControlStruct/driver_cfa_cpp-LabelGenerator.o: ControlStruct/LabelGenerator.cc
    1329 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ControlStruct/driver_cfa_cpp-LabelGenerator.o -MD -MP -MF ControlStruct/$(DEPDIR)/driver_cfa_cpp-LabelGenerator.Tpo -c -o ControlStruct/driver_cfa_cpp-LabelGenerator.o `test -f 'ControlStruct/LabelGenerator.cc' || echo '$(srcdir)/'`ControlStruct/LabelGenerator.cc
    1330 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) ControlStruct/$(DEPDIR)/driver_cfa_cpp-LabelGenerator.Tpo ControlStruct/$(DEPDIR)/driver_cfa_cpp-LabelGenerator.Po
    1331 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='ControlStruct/LabelGenerator.cc' object='ControlStruct/driver_cfa_cpp-LabelGenerator.o' libtool=no @AMDEPBACKSLASH@
    1332 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1333 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ControlStruct/driver_cfa_cpp-LabelGenerator.o `test -f 'ControlStruct/LabelGenerator.cc' || echo '$(srcdir)/'`ControlStruct/LabelGenerator.cc
    1334 
    1335 ControlStruct/driver_cfa_cpp-LabelGenerator.obj: ControlStruct/LabelGenerator.cc
    1336 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ControlStruct/driver_cfa_cpp-LabelGenerator.obj -MD -MP -MF ControlStruct/$(DEPDIR)/driver_cfa_cpp-LabelGenerator.Tpo -c -o ControlStruct/driver_cfa_cpp-LabelGenerator.obj `if test -f 'ControlStruct/LabelGenerator.cc'; then $(CYGPATH_W) 'ControlStruct/LabelGenerator.cc'; else $(CYGPATH_W) '$(srcdir)/ControlStruct/LabelGenerator.cc'; fi`
    1337 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) ControlStruct/$(DEPDIR)/driver_cfa_cpp-LabelGenerator.Tpo ControlStruct/$(DEPDIR)/driver_cfa_cpp-LabelGenerator.Po
    1338 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='ControlStruct/LabelGenerator.cc' object='ControlStruct/driver_cfa_cpp-LabelGenerator.obj' libtool=no @AMDEPBACKSLASH@
    1339 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1340 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ControlStruct/driver_cfa_cpp-LabelGenerator.obj `if test -f 'ControlStruct/LabelGenerator.cc'; then $(CYGPATH_W) 'ControlStruct/LabelGenerator.cc'; else $(CYGPATH_W) '$(srcdir)/ControlStruct/LabelGenerator.cc'; fi`
    1341 
    1342 ControlStruct/driver_cfa_cpp-LabelFixer.o: ControlStruct/LabelFixer.cc
    1343 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ControlStruct/driver_cfa_cpp-LabelFixer.o -MD -MP -MF ControlStruct/$(DEPDIR)/driver_cfa_cpp-LabelFixer.Tpo -c -o ControlStruct/driver_cfa_cpp-LabelFixer.o `test -f 'ControlStruct/LabelFixer.cc' || echo '$(srcdir)/'`ControlStruct/LabelFixer.cc
    1344 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) ControlStruct/$(DEPDIR)/driver_cfa_cpp-LabelFixer.Tpo ControlStruct/$(DEPDIR)/driver_cfa_cpp-LabelFixer.Po
    1345 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='ControlStruct/LabelFixer.cc' object='ControlStruct/driver_cfa_cpp-LabelFixer.o' libtool=no @AMDEPBACKSLASH@
    1346 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1347 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ControlStruct/driver_cfa_cpp-LabelFixer.o `test -f 'ControlStruct/LabelFixer.cc' || echo '$(srcdir)/'`ControlStruct/LabelFixer.cc
    1348 
    1349 ControlStruct/driver_cfa_cpp-LabelFixer.obj: ControlStruct/LabelFixer.cc
    1350 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ControlStruct/driver_cfa_cpp-LabelFixer.obj -MD -MP -MF ControlStruct/$(DEPDIR)/driver_cfa_cpp-LabelFixer.Tpo -c -o ControlStruct/driver_cfa_cpp-LabelFixer.obj `if test -f 'ControlStruct/LabelFixer.cc'; then $(CYGPATH_W) 'ControlStruct/LabelFixer.cc'; else $(CYGPATH_W) '$(srcdir)/ControlStruct/LabelFixer.cc'; fi`
    1351 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) ControlStruct/$(DEPDIR)/driver_cfa_cpp-LabelFixer.Tpo ControlStruct/$(DEPDIR)/driver_cfa_cpp-LabelFixer.Po
    1352 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='ControlStruct/LabelFixer.cc' object='ControlStruct/driver_cfa_cpp-LabelFixer.obj' libtool=no @AMDEPBACKSLASH@
    1353 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1354 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ControlStruct/driver_cfa_cpp-LabelFixer.obj `if test -f 'ControlStruct/LabelFixer.cc'; then $(CYGPATH_W) 'ControlStruct/LabelFixer.cc'; else $(CYGPATH_W) '$(srcdir)/ControlStruct/LabelFixer.cc'; fi`
    1355 
    1356 ControlStruct/driver_cfa_cpp-MLEMutator.o: ControlStruct/MLEMutator.cc
    1357 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ControlStruct/driver_cfa_cpp-MLEMutator.o -MD -MP -MF ControlStruct/$(DEPDIR)/driver_cfa_cpp-MLEMutator.Tpo -c -o ControlStruct/driver_cfa_cpp-MLEMutator.o `test -f 'ControlStruct/MLEMutator.cc' || echo '$(srcdir)/'`ControlStruct/MLEMutator.cc
    1358 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) ControlStruct/$(DEPDIR)/driver_cfa_cpp-MLEMutator.Tpo ControlStruct/$(DEPDIR)/driver_cfa_cpp-MLEMutator.Po
    1359 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='ControlStruct/MLEMutator.cc' object='ControlStruct/driver_cfa_cpp-MLEMutator.o' libtool=no @AMDEPBACKSLASH@
    1360 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1361 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ControlStruct/driver_cfa_cpp-MLEMutator.o `test -f 'ControlStruct/MLEMutator.cc' || echo '$(srcdir)/'`ControlStruct/MLEMutator.cc
    1362 
    1363 ControlStruct/driver_cfa_cpp-MLEMutator.obj: ControlStruct/MLEMutator.cc
    1364 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ControlStruct/driver_cfa_cpp-MLEMutator.obj -MD -MP -MF ControlStruct/$(DEPDIR)/driver_cfa_cpp-MLEMutator.Tpo -c -o ControlStruct/driver_cfa_cpp-MLEMutator.obj `if test -f 'ControlStruct/MLEMutator.cc'; then $(CYGPATH_W) 'ControlStruct/MLEMutator.cc'; else $(CYGPATH_W) '$(srcdir)/ControlStruct/MLEMutator.cc'; fi`
    1365 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) ControlStruct/$(DEPDIR)/driver_cfa_cpp-MLEMutator.Tpo ControlStruct/$(DEPDIR)/driver_cfa_cpp-MLEMutator.Po
    1366 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='ControlStruct/MLEMutator.cc' object='ControlStruct/driver_cfa_cpp-MLEMutator.obj' libtool=no @AMDEPBACKSLASH@
    1367 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1368 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ControlStruct/driver_cfa_cpp-MLEMutator.obj `if test -f 'ControlStruct/MLEMutator.cc'; then $(CYGPATH_W) 'ControlStruct/MLEMutator.cc'; else $(CYGPATH_W) '$(srcdir)/ControlStruct/MLEMutator.cc'; fi`
    1369 
    1370 ControlStruct/driver_cfa_cpp-Mutate.o: ControlStruct/Mutate.cc
    1371 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ControlStruct/driver_cfa_cpp-Mutate.o -MD -MP -MF ControlStruct/$(DEPDIR)/driver_cfa_cpp-Mutate.Tpo -c -o ControlStruct/driver_cfa_cpp-Mutate.o `test -f 'ControlStruct/Mutate.cc' || echo '$(srcdir)/'`ControlStruct/Mutate.cc
    1372 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) ControlStruct/$(DEPDIR)/driver_cfa_cpp-Mutate.Tpo ControlStruct/$(DEPDIR)/driver_cfa_cpp-Mutate.Po
    1373 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='ControlStruct/Mutate.cc' object='ControlStruct/driver_cfa_cpp-Mutate.o' libtool=no @AMDEPBACKSLASH@
    1374 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1375 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ControlStruct/driver_cfa_cpp-Mutate.o `test -f 'ControlStruct/Mutate.cc' || echo '$(srcdir)/'`ControlStruct/Mutate.cc
    1376 
    1377 ControlStruct/driver_cfa_cpp-Mutate.obj: ControlStruct/Mutate.cc
    1378 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ControlStruct/driver_cfa_cpp-Mutate.obj -MD -MP -MF ControlStruct/$(DEPDIR)/driver_cfa_cpp-Mutate.Tpo -c -o ControlStruct/driver_cfa_cpp-Mutate.obj `if test -f 'ControlStruct/Mutate.cc'; then $(CYGPATH_W) 'ControlStruct/Mutate.cc'; else $(CYGPATH_W) '$(srcdir)/ControlStruct/Mutate.cc'; fi`
    1379 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) ControlStruct/$(DEPDIR)/driver_cfa_cpp-Mutate.Tpo ControlStruct/$(DEPDIR)/driver_cfa_cpp-Mutate.Po
    1380 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='ControlStruct/Mutate.cc' object='ControlStruct/driver_cfa_cpp-Mutate.obj' libtool=no @AMDEPBACKSLASH@
    1381 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1382 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ControlStruct/driver_cfa_cpp-Mutate.obj `if test -f 'ControlStruct/Mutate.cc'; then $(CYGPATH_W) 'ControlStruct/Mutate.cc'; else $(CYGPATH_W) '$(srcdir)/ControlStruct/Mutate.cc'; fi`
    1383 
    1384 ControlStruct/driver_cfa_cpp-ForExprMutator.o: ControlStruct/ForExprMutator.cc
    1385 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ControlStruct/driver_cfa_cpp-ForExprMutator.o -MD -MP -MF ControlStruct/$(DEPDIR)/driver_cfa_cpp-ForExprMutator.Tpo -c -o ControlStruct/driver_cfa_cpp-ForExprMutator.o `test -f 'ControlStruct/ForExprMutator.cc' || echo '$(srcdir)/'`ControlStruct/ForExprMutator.cc
    1386 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) ControlStruct/$(DEPDIR)/driver_cfa_cpp-ForExprMutator.Tpo ControlStruct/$(DEPDIR)/driver_cfa_cpp-ForExprMutator.Po
    1387 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='ControlStruct/ForExprMutator.cc' object='ControlStruct/driver_cfa_cpp-ForExprMutator.o' libtool=no @AMDEPBACKSLASH@
    1388 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1389 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ControlStruct/driver_cfa_cpp-ForExprMutator.o `test -f 'ControlStruct/ForExprMutator.cc' || echo '$(srcdir)/'`ControlStruct/ForExprMutator.cc
    1390 
    1391 ControlStruct/driver_cfa_cpp-ForExprMutator.obj: ControlStruct/ForExprMutator.cc
    1392 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ControlStruct/driver_cfa_cpp-ForExprMutator.obj -MD -MP -MF ControlStruct/$(DEPDIR)/driver_cfa_cpp-ForExprMutator.Tpo -c -o ControlStruct/driver_cfa_cpp-ForExprMutator.obj `if test -f 'ControlStruct/ForExprMutator.cc'; then $(CYGPATH_W) 'ControlStruct/ForExprMutator.cc'; else $(CYGPATH_W) '$(srcdir)/ControlStruct/ForExprMutator.cc'; fi`
    1393 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) ControlStruct/$(DEPDIR)/driver_cfa_cpp-ForExprMutator.Tpo ControlStruct/$(DEPDIR)/driver_cfa_cpp-ForExprMutator.Po
    1394 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='ControlStruct/ForExprMutator.cc' object='ControlStruct/driver_cfa_cpp-ForExprMutator.obj' libtool=no @AMDEPBACKSLASH@
    1395 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1396 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ControlStruct/driver_cfa_cpp-ForExprMutator.obj `if test -f 'ControlStruct/ForExprMutator.cc'; then $(CYGPATH_W) 'ControlStruct/ForExprMutator.cc'; else $(CYGPATH_W) '$(srcdir)/ControlStruct/ForExprMutator.cc'; fi`
    1397 
    1398 ControlStruct/driver_cfa_cpp-ExceptTranslate.o: ControlStruct/ExceptTranslate.cc
    1399 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ControlStruct/driver_cfa_cpp-ExceptTranslate.o -MD -MP -MF ControlStruct/$(DEPDIR)/driver_cfa_cpp-ExceptTranslate.Tpo -c -o ControlStruct/driver_cfa_cpp-ExceptTranslate.o `test -f 'ControlStruct/ExceptTranslate.cc' || echo '$(srcdir)/'`ControlStruct/ExceptTranslate.cc
    1400 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) ControlStruct/$(DEPDIR)/driver_cfa_cpp-ExceptTranslate.Tpo ControlStruct/$(DEPDIR)/driver_cfa_cpp-ExceptTranslate.Po
    1401 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='ControlStruct/ExceptTranslate.cc' object='ControlStruct/driver_cfa_cpp-ExceptTranslate.o' libtool=no @AMDEPBACKSLASH@
    1402 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1403 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ControlStruct/driver_cfa_cpp-ExceptTranslate.o `test -f 'ControlStruct/ExceptTranslate.cc' || echo '$(srcdir)/'`ControlStruct/ExceptTranslate.cc
    1404 
    1405 ControlStruct/driver_cfa_cpp-ExceptTranslate.obj: ControlStruct/ExceptTranslate.cc
    1406 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ControlStruct/driver_cfa_cpp-ExceptTranslate.obj -MD -MP -MF ControlStruct/$(DEPDIR)/driver_cfa_cpp-ExceptTranslate.Tpo -c -o ControlStruct/driver_cfa_cpp-ExceptTranslate.obj `if test -f 'ControlStruct/ExceptTranslate.cc'; then $(CYGPATH_W) 'ControlStruct/ExceptTranslate.cc'; else $(CYGPATH_W) '$(srcdir)/ControlStruct/ExceptTranslate.cc'; fi`
    1407 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) ControlStruct/$(DEPDIR)/driver_cfa_cpp-ExceptTranslate.Tpo ControlStruct/$(DEPDIR)/driver_cfa_cpp-ExceptTranslate.Po
    1408 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='ControlStruct/ExceptTranslate.cc' object='ControlStruct/driver_cfa_cpp-ExceptTranslate.obj' libtool=no @AMDEPBACKSLASH@
    1409 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1410 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ControlStruct/driver_cfa_cpp-ExceptTranslate.obj `if test -f 'ControlStruct/ExceptTranslate.cc'; then $(CYGPATH_W) 'ControlStruct/ExceptTranslate.cc'; else $(CYGPATH_W) '$(srcdir)/ControlStruct/ExceptTranslate.cc'; fi`
    1411 
    1412 GenPoly/driver_cfa_cpp-Box.o: GenPoly/Box.cc
    1413 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/driver_cfa_cpp-Box.o -MD -MP -MF GenPoly/$(DEPDIR)/driver_cfa_cpp-Box.Tpo -c -o GenPoly/driver_cfa_cpp-Box.o `test -f 'GenPoly/Box.cc' || echo '$(srcdir)/'`GenPoly/Box.cc
    1414 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) GenPoly/$(DEPDIR)/driver_cfa_cpp-Box.Tpo GenPoly/$(DEPDIR)/driver_cfa_cpp-Box.Po
    1415 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='GenPoly/Box.cc' object='GenPoly/driver_cfa_cpp-Box.o' libtool=no @AMDEPBACKSLASH@
    1416 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1417 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o GenPoly/driver_cfa_cpp-Box.o `test -f 'GenPoly/Box.cc' || echo '$(srcdir)/'`GenPoly/Box.cc
    1418 
    1419 GenPoly/driver_cfa_cpp-Box.obj: GenPoly/Box.cc
    1420 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/driver_cfa_cpp-Box.obj -MD -MP -MF GenPoly/$(DEPDIR)/driver_cfa_cpp-Box.Tpo -c -o GenPoly/driver_cfa_cpp-Box.obj `if test -f 'GenPoly/Box.cc'; then $(CYGPATH_W) 'GenPoly/Box.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/Box.cc'; fi`
    1421 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) GenPoly/$(DEPDIR)/driver_cfa_cpp-Box.Tpo GenPoly/$(DEPDIR)/driver_cfa_cpp-Box.Po
    1422 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='GenPoly/Box.cc' object='GenPoly/driver_cfa_cpp-Box.obj' libtool=no @AMDEPBACKSLASH@
    1423 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1424 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o GenPoly/driver_cfa_cpp-Box.obj `if test -f 'GenPoly/Box.cc'; then $(CYGPATH_W) 'GenPoly/Box.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/Box.cc'; fi`
    1425 
    1426 GenPoly/driver_cfa_cpp-GenPoly.o: GenPoly/GenPoly.cc
    1427 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/driver_cfa_cpp-GenPoly.o -MD -MP -MF GenPoly/$(DEPDIR)/driver_cfa_cpp-GenPoly.Tpo -c -o GenPoly/driver_cfa_cpp-GenPoly.o `test -f 'GenPoly/GenPoly.cc' || echo '$(srcdir)/'`GenPoly/GenPoly.cc
    1428 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) GenPoly/$(DEPDIR)/driver_cfa_cpp-GenPoly.Tpo GenPoly/$(DEPDIR)/driver_cfa_cpp-GenPoly.Po
    1429 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='GenPoly/GenPoly.cc' object='GenPoly/driver_cfa_cpp-GenPoly.o' libtool=no @AMDEPBACKSLASH@
    1430 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1431 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o GenPoly/driver_cfa_cpp-GenPoly.o `test -f 'GenPoly/GenPoly.cc' || echo '$(srcdir)/'`GenPoly/GenPoly.cc
    1432 
    1433 GenPoly/driver_cfa_cpp-GenPoly.obj: GenPoly/GenPoly.cc
    1434 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/driver_cfa_cpp-GenPoly.obj -MD -MP -MF GenPoly/$(DEPDIR)/driver_cfa_cpp-GenPoly.Tpo -c -o GenPoly/driver_cfa_cpp-GenPoly.obj `if test -f 'GenPoly/GenPoly.cc'; then $(CYGPATH_W) 'GenPoly/GenPoly.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/GenPoly.cc'; fi`
    1435 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) GenPoly/$(DEPDIR)/driver_cfa_cpp-GenPoly.Tpo GenPoly/$(DEPDIR)/driver_cfa_cpp-GenPoly.Po
    1436 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='GenPoly/GenPoly.cc' object='GenPoly/driver_cfa_cpp-GenPoly.obj' libtool=no @AMDEPBACKSLASH@
    1437 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1438 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o GenPoly/driver_cfa_cpp-GenPoly.obj `if test -f 'GenPoly/GenPoly.cc'; then $(CYGPATH_W) 'GenPoly/GenPoly.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/GenPoly.cc'; fi`
    1439 
    1440 GenPoly/driver_cfa_cpp-ScrubTyVars.o: GenPoly/ScrubTyVars.cc
    1441 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/driver_cfa_cpp-ScrubTyVars.o -MD -MP -MF GenPoly/$(DEPDIR)/driver_cfa_cpp-ScrubTyVars.Tpo -c -o GenPoly/driver_cfa_cpp-ScrubTyVars.o `test -f 'GenPoly/ScrubTyVars.cc' || echo '$(srcdir)/'`GenPoly/ScrubTyVars.cc
    1442 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) GenPoly/$(DEPDIR)/driver_cfa_cpp-ScrubTyVars.Tpo GenPoly/$(DEPDIR)/driver_cfa_cpp-ScrubTyVars.Po
    1443 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='GenPoly/ScrubTyVars.cc' object='GenPoly/driver_cfa_cpp-ScrubTyVars.o' libtool=no @AMDEPBACKSLASH@
    1444 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1445 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o GenPoly/driver_cfa_cpp-ScrubTyVars.o `test -f 'GenPoly/ScrubTyVars.cc' || echo '$(srcdir)/'`GenPoly/ScrubTyVars.cc
    1446 
    1447 GenPoly/driver_cfa_cpp-ScrubTyVars.obj: GenPoly/ScrubTyVars.cc
    1448 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/driver_cfa_cpp-ScrubTyVars.obj -MD -MP -MF GenPoly/$(DEPDIR)/driver_cfa_cpp-ScrubTyVars.Tpo -c -o GenPoly/driver_cfa_cpp-ScrubTyVars.obj `if test -f 'GenPoly/ScrubTyVars.cc'; then $(CYGPATH_W) 'GenPoly/ScrubTyVars.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/ScrubTyVars.cc'; fi`
    1449 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) GenPoly/$(DEPDIR)/driver_cfa_cpp-ScrubTyVars.Tpo GenPoly/$(DEPDIR)/driver_cfa_cpp-ScrubTyVars.Po
    1450 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='GenPoly/ScrubTyVars.cc' object='GenPoly/driver_cfa_cpp-ScrubTyVars.obj' libtool=no @AMDEPBACKSLASH@
    1451 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1452 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o GenPoly/driver_cfa_cpp-ScrubTyVars.obj `if test -f 'GenPoly/ScrubTyVars.cc'; then $(CYGPATH_W) 'GenPoly/ScrubTyVars.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/ScrubTyVars.cc'; fi`
    1453 
    1454 GenPoly/driver_cfa_cpp-Lvalue.o: GenPoly/Lvalue.cc
    1455 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/driver_cfa_cpp-Lvalue.o -MD -MP -MF GenPoly/$(DEPDIR)/driver_cfa_cpp-Lvalue.Tpo -c -o GenPoly/driver_cfa_cpp-Lvalue.o `test -f 'GenPoly/Lvalue.cc' || echo '$(srcdir)/'`GenPoly/Lvalue.cc
    1456 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) GenPoly/$(DEPDIR)/driver_cfa_cpp-Lvalue.Tpo GenPoly/$(DEPDIR)/driver_cfa_cpp-Lvalue.Po
    1457 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='GenPoly/Lvalue.cc' object='GenPoly/driver_cfa_cpp-Lvalue.o' libtool=no @AMDEPBACKSLASH@
    1458 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1459 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o GenPoly/driver_cfa_cpp-Lvalue.o `test -f 'GenPoly/Lvalue.cc' || echo '$(srcdir)/'`GenPoly/Lvalue.cc
    1460 
    1461 GenPoly/driver_cfa_cpp-Lvalue.obj: GenPoly/Lvalue.cc
    1462 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/driver_cfa_cpp-Lvalue.obj -MD -MP -MF GenPoly/$(DEPDIR)/driver_cfa_cpp-Lvalue.Tpo -c -o GenPoly/driver_cfa_cpp-Lvalue.obj `if test -f 'GenPoly/Lvalue.cc'; then $(CYGPATH_W) 'GenPoly/Lvalue.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/Lvalue.cc'; fi`
    1463 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) GenPoly/$(DEPDIR)/driver_cfa_cpp-Lvalue.Tpo GenPoly/$(DEPDIR)/driver_cfa_cpp-Lvalue.Po
    1464 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='GenPoly/Lvalue.cc' object='GenPoly/driver_cfa_cpp-Lvalue.obj' libtool=no @AMDEPBACKSLASH@
    1465 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1466 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o GenPoly/driver_cfa_cpp-Lvalue.obj `if test -f 'GenPoly/Lvalue.cc'; then $(CYGPATH_W) 'GenPoly/Lvalue.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/Lvalue.cc'; fi`
    1467 
    1468 GenPoly/driver_cfa_cpp-Specialize.o: GenPoly/Specialize.cc
    1469 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/driver_cfa_cpp-Specialize.o -MD -MP -MF GenPoly/$(DEPDIR)/driver_cfa_cpp-Specialize.Tpo -c -o GenPoly/driver_cfa_cpp-Specialize.o `test -f 'GenPoly/Specialize.cc' || echo '$(srcdir)/'`GenPoly/Specialize.cc
    1470 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) GenPoly/$(DEPDIR)/driver_cfa_cpp-Specialize.Tpo GenPoly/$(DEPDIR)/driver_cfa_cpp-Specialize.Po
    1471 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='GenPoly/Specialize.cc' object='GenPoly/driver_cfa_cpp-Specialize.o' libtool=no @AMDEPBACKSLASH@
    1472 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1473 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o GenPoly/driver_cfa_cpp-Specialize.o `test -f 'GenPoly/Specialize.cc' || echo '$(srcdir)/'`GenPoly/Specialize.cc
    1474 
    1475 GenPoly/driver_cfa_cpp-Specialize.obj: GenPoly/Specialize.cc
    1476 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/driver_cfa_cpp-Specialize.obj -MD -MP -MF GenPoly/$(DEPDIR)/driver_cfa_cpp-Specialize.Tpo -c -o GenPoly/driver_cfa_cpp-Specialize.obj `if test -f 'GenPoly/Specialize.cc'; then $(CYGPATH_W) 'GenPoly/Specialize.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/Specialize.cc'; fi`
    1477 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) GenPoly/$(DEPDIR)/driver_cfa_cpp-Specialize.Tpo GenPoly/$(DEPDIR)/driver_cfa_cpp-Specialize.Po
    1478 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='GenPoly/Specialize.cc' object='GenPoly/driver_cfa_cpp-Specialize.obj' libtool=no @AMDEPBACKSLASH@
    1479 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1480 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o GenPoly/driver_cfa_cpp-Specialize.obj `if test -f 'GenPoly/Specialize.cc'; then $(CYGPATH_W) 'GenPoly/Specialize.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/Specialize.cc'; fi`
    1481 
    1482 GenPoly/driver_cfa_cpp-FindFunction.o: GenPoly/FindFunction.cc
    1483 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/driver_cfa_cpp-FindFunction.o -MD -MP -MF GenPoly/$(DEPDIR)/driver_cfa_cpp-FindFunction.Tpo -c -o GenPoly/driver_cfa_cpp-FindFunction.o `test -f 'GenPoly/FindFunction.cc' || echo '$(srcdir)/'`GenPoly/FindFunction.cc
    1484 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) GenPoly/$(DEPDIR)/driver_cfa_cpp-FindFunction.Tpo GenPoly/$(DEPDIR)/driver_cfa_cpp-FindFunction.Po
    1485 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='GenPoly/FindFunction.cc' object='GenPoly/driver_cfa_cpp-FindFunction.o' libtool=no @AMDEPBACKSLASH@
    1486 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1487 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o GenPoly/driver_cfa_cpp-FindFunction.o `test -f 'GenPoly/FindFunction.cc' || echo '$(srcdir)/'`GenPoly/FindFunction.cc
    1488 
    1489 GenPoly/driver_cfa_cpp-FindFunction.obj: GenPoly/FindFunction.cc
    1490 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/driver_cfa_cpp-FindFunction.obj -MD -MP -MF GenPoly/$(DEPDIR)/driver_cfa_cpp-FindFunction.Tpo -c -o GenPoly/driver_cfa_cpp-FindFunction.obj `if test -f 'GenPoly/FindFunction.cc'; then $(CYGPATH_W) 'GenPoly/FindFunction.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/FindFunction.cc'; fi`
    1491 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) GenPoly/$(DEPDIR)/driver_cfa_cpp-FindFunction.Tpo GenPoly/$(DEPDIR)/driver_cfa_cpp-FindFunction.Po
    1492 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='GenPoly/FindFunction.cc' object='GenPoly/driver_cfa_cpp-FindFunction.obj' libtool=no @AMDEPBACKSLASH@
    1493 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1494 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o GenPoly/driver_cfa_cpp-FindFunction.obj `if test -f 'GenPoly/FindFunction.cc'; then $(CYGPATH_W) 'GenPoly/FindFunction.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/FindFunction.cc'; fi`
    1495 
    1496 GenPoly/driver_cfa_cpp-InstantiateGeneric.o: GenPoly/InstantiateGeneric.cc
    1497 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/driver_cfa_cpp-InstantiateGeneric.o -MD -MP -MF GenPoly/$(DEPDIR)/driver_cfa_cpp-InstantiateGeneric.Tpo -c -o GenPoly/driver_cfa_cpp-InstantiateGeneric.o `test -f 'GenPoly/InstantiateGeneric.cc' || echo '$(srcdir)/'`GenPoly/InstantiateGeneric.cc
    1498 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) GenPoly/$(DEPDIR)/driver_cfa_cpp-InstantiateGeneric.Tpo GenPoly/$(DEPDIR)/driver_cfa_cpp-InstantiateGeneric.Po
    1499 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='GenPoly/InstantiateGeneric.cc' object='GenPoly/driver_cfa_cpp-InstantiateGeneric.o' libtool=no @AMDEPBACKSLASH@
    1500 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1501 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o GenPoly/driver_cfa_cpp-InstantiateGeneric.o `test -f 'GenPoly/InstantiateGeneric.cc' || echo '$(srcdir)/'`GenPoly/InstantiateGeneric.cc
    1502 
    1503 GenPoly/driver_cfa_cpp-InstantiateGeneric.obj: GenPoly/InstantiateGeneric.cc
    1504 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/driver_cfa_cpp-InstantiateGeneric.obj -MD -MP -MF GenPoly/$(DEPDIR)/driver_cfa_cpp-InstantiateGeneric.Tpo -c -o GenPoly/driver_cfa_cpp-InstantiateGeneric.obj `if test -f 'GenPoly/InstantiateGeneric.cc'; then $(CYGPATH_W) 'GenPoly/InstantiateGeneric.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/InstantiateGeneric.cc'; fi`
    1505 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) GenPoly/$(DEPDIR)/driver_cfa_cpp-InstantiateGeneric.Tpo GenPoly/$(DEPDIR)/driver_cfa_cpp-InstantiateGeneric.Po
    1506 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='GenPoly/InstantiateGeneric.cc' object='GenPoly/driver_cfa_cpp-InstantiateGeneric.obj' libtool=no @AMDEPBACKSLASH@
    1507 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1508 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o GenPoly/driver_cfa_cpp-InstantiateGeneric.obj `if test -f 'GenPoly/InstantiateGeneric.cc'; then $(CYGPATH_W) 'GenPoly/InstantiateGeneric.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/InstantiateGeneric.cc'; fi`
    1509 
    1510 InitTweak/driver_cfa_cpp-GenInit.o: InitTweak/GenInit.cc
    1511 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT InitTweak/driver_cfa_cpp-GenInit.o -MD -MP -MF InitTweak/$(DEPDIR)/driver_cfa_cpp-GenInit.Tpo -c -o InitTweak/driver_cfa_cpp-GenInit.o `test -f 'InitTweak/GenInit.cc' || echo '$(srcdir)/'`InitTweak/GenInit.cc
    1512 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) InitTweak/$(DEPDIR)/driver_cfa_cpp-GenInit.Tpo InitTweak/$(DEPDIR)/driver_cfa_cpp-GenInit.Po
    1513 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='InitTweak/GenInit.cc' object='InitTweak/driver_cfa_cpp-GenInit.o' libtool=no @AMDEPBACKSLASH@
    1514 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1515 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o InitTweak/driver_cfa_cpp-GenInit.o `test -f 'InitTweak/GenInit.cc' || echo '$(srcdir)/'`InitTweak/GenInit.cc
    1516 
    1517 InitTweak/driver_cfa_cpp-GenInit.obj: InitTweak/GenInit.cc
    1518 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT InitTweak/driver_cfa_cpp-GenInit.obj -MD -MP -MF InitTweak/$(DEPDIR)/driver_cfa_cpp-GenInit.Tpo -c -o InitTweak/driver_cfa_cpp-GenInit.obj `if test -f 'InitTweak/GenInit.cc'; then $(CYGPATH_W) 'InitTweak/GenInit.cc'; else $(CYGPATH_W) '$(srcdir)/InitTweak/GenInit.cc'; fi`
    1519 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) InitTweak/$(DEPDIR)/driver_cfa_cpp-GenInit.Tpo InitTweak/$(DEPDIR)/driver_cfa_cpp-GenInit.Po
    1520 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='InitTweak/GenInit.cc' object='InitTweak/driver_cfa_cpp-GenInit.obj' libtool=no @AMDEPBACKSLASH@
    1521 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1522 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o InitTweak/driver_cfa_cpp-GenInit.obj `if test -f 'InitTweak/GenInit.cc'; then $(CYGPATH_W) 'InitTweak/GenInit.cc'; else $(CYGPATH_W) '$(srcdir)/InitTweak/GenInit.cc'; fi`
    1523 
    1524 InitTweak/driver_cfa_cpp-FixInit.o: InitTweak/FixInit.cc
    1525 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT InitTweak/driver_cfa_cpp-FixInit.o -MD -MP -MF InitTweak/$(DEPDIR)/driver_cfa_cpp-FixInit.Tpo -c -o InitTweak/driver_cfa_cpp-FixInit.o `test -f 'InitTweak/FixInit.cc' || echo '$(srcdir)/'`InitTweak/FixInit.cc
    1526 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) InitTweak/$(DEPDIR)/driver_cfa_cpp-FixInit.Tpo InitTweak/$(DEPDIR)/driver_cfa_cpp-FixInit.Po
    1527 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='InitTweak/FixInit.cc' object='InitTweak/driver_cfa_cpp-FixInit.o' libtool=no @AMDEPBACKSLASH@
    1528 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1529 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o InitTweak/driver_cfa_cpp-FixInit.o `test -f 'InitTweak/FixInit.cc' || echo '$(srcdir)/'`InitTweak/FixInit.cc
    1530 
    1531 InitTweak/driver_cfa_cpp-FixInit.obj: InitTweak/FixInit.cc
    1532 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT InitTweak/driver_cfa_cpp-FixInit.obj -MD -MP -MF InitTweak/$(DEPDIR)/driver_cfa_cpp-FixInit.Tpo -c -o InitTweak/driver_cfa_cpp-FixInit.obj `if test -f 'InitTweak/FixInit.cc'; then $(CYGPATH_W) 'InitTweak/FixInit.cc'; else $(CYGPATH_W) '$(srcdir)/InitTweak/FixInit.cc'; fi`
    1533 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) InitTweak/$(DEPDIR)/driver_cfa_cpp-FixInit.Tpo InitTweak/$(DEPDIR)/driver_cfa_cpp-FixInit.Po
    1534 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='InitTweak/FixInit.cc' object='InitTweak/driver_cfa_cpp-FixInit.obj' libtool=no @AMDEPBACKSLASH@
    1535 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1536 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o InitTweak/driver_cfa_cpp-FixInit.obj `if test -f 'InitTweak/FixInit.cc'; then $(CYGPATH_W) 'InitTweak/FixInit.cc'; else $(CYGPATH_W) '$(srcdir)/InitTweak/FixInit.cc'; fi`
    1537 
    1538 InitTweak/driver_cfa_cpp-FixGlobalInit.o: InitTweak/FixGlobalInit.cc
    1539 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT InitTweak/driver_cfa_cpp-FixGlobalInit.o -MD -MP -MF InitTweak/$(DEPDIR)/driver_cfa_cpp-FixGlobalInit.Tpo -c -o InitTweak/driver_cfa_cpp-FixGlobalInit.o `test -f 'InitTweak/FixGlobalInit.cc' || echo '$(srcdir)/'`InitTweak/FixGlobalInit.cc
    1540 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) InitTweak/$(DEPDIR)/driver_cfa_cpp-FixGlobalInit.Tpo InitTweak/$(DEPDIR)/driver_cfa_cpp-FixGlobalInit.Po
    1541 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='InitTweak/FixGlobalInit.cc' object='InitTweak/driver_cfa_cpp-FixGlobalInit.o' libtool=no @AMDEPBACKSLASH@
    1542 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1543 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o InitTweak/driver_cfa_cpp-FixGlobalInit.o `test -f 'InitTweak/FixGlobalInit.cc' || echo '$(srcdir)/'`InitTweak/FixGlobalInit.cc
    1544 
    1545 InitTweak/driver_cfa_cpp-FixGlobalInit.obj: InitTweak/FixGlobalInit.cc
    1546 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT InitTweak/driver_cfa_cpp-FixGlobalInit.obj -MD -MP -MF InitTweak/$(DEPDIR)/driver_cfa_cpp-FixGlobalInit.Tpo -c -o InitTweak/driver_cfa_cpp-FixGlobalInit.obj `if test -f 'InitTweak/FixGlobalInit.cc'; then $(CYGPATH_W) 'InitTweak/FixGlobalInit.cc'; else $(CYGPATH_W) '$(srcdir)/InitTweak/FixGlobalInit.cc'; fi`
    1547 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) InitTweak/$(DEPDIR)/driver_cfa_cpp-FixGlobalInit.Tpo InitTweak/$(DEPDIR)/driver_cfa_cpp-FixGlobalInit.Po
    1548 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='InitTweak/FixGlobalInit.cc' object='InitTweak/driver_cfa_cpp-FixGlobalInit.obj' libtool=no @AMDEPBACKSLASH@
    1549 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1550 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o InitTweak/driver_cfa_cpp-FixGlobalInit.obj `if test -f 'InitTweak/FixGlobalInit.cc'; then $(CYGPATH_W) 'InitTweak/FixGlobalInit.cc'; else $(CYGPATH_W) '$(srcdir)/InitTweak/FixGlobalInit.cc'; fi`
    1551 
    1552 InitTweak/driver_cfa_cpp-InitTweak.o: InitTweak/InitTweak.cc
    1553 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT InitTweak/driver_cfa_cpp-InitTweak.o -MD -MP -MF InitTweak/$(DEPDIR)/driver_cfa_cpp-InitTweak.Tpo -c -o InitTweak/driver_cfa_cpp-InitTweak.o `test -f 'InitTweak/InitTweak.cc' || echo '$(srcdir)/'`InitTweak/InitTweak.cc
    1554 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) InitTweak/$(DEPDIR)/driver_cfa_cpp-InitTweak.Tpo InitTweak/$(DEPDIR)/driver_cfa_cpp-InitTweak.Po
    1555 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='InitTweak/InitTweak.cc' object='InitTweak/driver_cfa_cpp-InitTweak.o' libtool=no @AMDEPBACKSLASH@
    1556 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1557 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o InitTweak/driver_cfa_cpp-InitTweak.o `test -f 'InitTweak/InitTweak.cc' || echo '$(srcdir)/'`InitTweak/InitTweak.cc
    1558 
    1559 InitTweak/driver_cfa_cpp-InitTweak.obj: InitTweak/InitTweak.cc
    1560 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT InitTweak/driver_cfa_cpp-InitTweak.obj -MD -MP -MF InitTweak/$(DEPDIR)/driver_cfa_cpp-InitTweak.Tpo -c -o InitTweak/driver_cfa_cpp-InitTweak.obj `if test -f 'InitTweak/InitTweak.cc'; then $(CYGPATH_W) 'InitTweak/InitTweak.cc'; else $(CYGPATH_W) '$(srcdir)/InitTweak/InitTweak.cc'; fi`
    1561 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) InitTweak/$(DEPDIR)/driver_cfa_cpp-InitTweak.Tpo InitTweak/$(DEPDIR)/driver_cfa_cpp-InitTweak.Po
    1562 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='InitTweak/InitTweak.cc' object='InitTweak/driver_cfa_cpp-InitTweak.obj' libtool=no @AMDEPBACKSLASH@
    1563 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1564 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o InitTweak/driver_cfa_cpp-InitTweak.obj `if test -f 'InitTweak/InitTweak.cc'; then $(CYGPATH_W) 'InitTweak/InitTweak.cc'; else $(CYGPATH_W) '$(srcdir)/InitTweak/InitTweak.cc'; fi`
    1565 
    1566 Parser/driver_cfa_cpp-parser.o: Parser/parser.cc
    1567 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Parser/driver_cfa_cpp-parser.o -MD -MP -MF Parser/$(DEPDIR)/driver_cfa_cpp-parser.Tpo -c -o Parser/driver_cfa_cpp-parser.o `test -f 'Parser/parser.cc' || echo '$(srcdir)/'`Parser/parser.cc
    1568 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) Parser/$(DEPDIR)/driver_cfa_cpp-parser.Tpo Parser/$(DEPDIR)/driver_cfa_cpp-parser.Po
    1569 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='Parser/parser.cc' object='Parser/driver_cfa_cpp-parser.o' libtool=no @AMDEPBACKSLASH@
    1570 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1571 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Parser/driver_cfa_cpp-parser.o `test -f 'Parser/parser.cc' || echo '$(srcdir)/'`Parser/parser.cc
    1572 
    1573 Parser/driver_cfa_cpp-parser.obj: Parser/parser.cc
    1574 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Parser/driver_cfa_cpp-parser.obj -MD -MP -MF Parser/$(DEPDIR)/driver_cfa_cpp-parser.Tpo -c -o Parser/driver_cfa_cpp-parser.obj `if test -f 'Parser/parser.cc'; then $(CYGPATH_W) 'Parser/parser.cc'; else $(CYGPATH_W) '$(srcdir)/Parser/parser.cc'; fi`
    1575 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) Parser/$(DEPDIR)/driver_cfa_cpp-parser.Tpo Parser/$(DEPDIR)/driver_cfa_cpp-parser.Po
    1576 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='Parser/parser.cc' object='Parser/driver_cfa_cpp-parser.obj' libtool=no @AMDEPBACKSLASH@
    1577 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1578 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Parser/driver_cfa_cpp-parser.obj `if test -f 'Parser/parser.cc'; then $(CYGPATH_W) 'Parser/parser.cc'; else $(CYGPATH_W) '$(srcdir)/Parser/parser.cc'; fi`
    1579 
    1580 Parser/driver_cfa_cpp-lex.o: Parser/lex.cc
    1581 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Parser/driver_cfa_cpp-lex.o -MD -MP -MF Parser/$(DEPDIR)/driver_cfa_cpp-lex.Tpo -c -o Parser/driver_cfa_cpp-lex.o `test -f 'Parser/lex.cc' || echo '$(srcdir)/'`Parser/lex.cc
    1582 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) Parser/$(DEPDIR)/driver_cfa_cpp-lex.Tpo Parser/$(DEPDIR)/driver_cfa_cpp-lex.Po
    1583 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='Parser/lex.cc' object='Parser/driver_cfa_cpp-lex.o' libtool=no @AMDEPBACKSLASH@
    1584 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1585 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Parser/driver_cfa_cpp-lex.o `test -f 'Parser/lex.cc' || echo '$(srcdir)/'`Parser/lex.cc
    1586 
    1587 Parser/driver_cfa_cpp-lex.obj: Parser/lex.cc
    1588 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Parser/driver_cfa_cpp-lex.obj -MD -MP -MF Parser/$(DEPDIR)/driver_cfa_cpp-lex.Tpo -c -o Parser/driver_cfa_cpp-lex.obj `if test -f 'Parser/lex.cc'; then $(CYGPATH_W) 'Parser/lex.cc'; else $(CYGPATH_W) '$(srcdir)/Parser/lex.cc'; fi`
    1589 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) Parser/$(DEPDIR)/driver_cfa_cpp-lex.Tpo Parser/$(DEPDIR)/driver_cfa_cpp-lex.Po
    1590 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='Parser/lex.cc' object='Parser/driver_cfa_cpp-lex.obj' libtool=no @AMDEPBACKSLASH@
    1591 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1592 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Parser/driver_cfa_cpp-lex.obj `if test -f 'Parser/lex.cc'; then $(CYGPATH_W) 'Parser/lex.cc'; else $(CYGPATH_W) '$(srcdir)/Parser/lex.cc'; fi`
    1593 
    1594 Parser/driver_cfa_cpp-TypedefTable.o: Parser/TypedefTable.cc
    1595 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Parser/driver_cfa_cpp-TypedefTable.o -MD -MP -MF Parser/$(DEPDIR)/driver_cfa_cpp-TypedefTable.Tpo -c -o Parser/driver_cfa_cpp-TypedefTable.o `test -f 'Parser/TypedefTable.cc' || echo '$(srcdir)/'`Parser/TypedefTable.cc
    1596 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) Parser/$(DEPDIR)/driver_cfa_cpp-TypedefTable.Tpo Parser/$(DEPDIR)/driver_cfa_cpp-TypedefTable.Po
    1597 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='Parser/TypedefTable.cc' object='Parser/driver_cfa_cpp-TypedefTable.o' libtool=no @AMDEPBACKSLASH@
    1598 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1599 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Parser/driver_cfa_cpp-TypedefTable.o `test -f 'Parser/TypedefTable.cc' || echo '$(srcdir)/'`Parser/TypedefTable.cc
    1600 
    1601 Parser/driver_cfa_cpp-TypedefTable.obj: Parser/TypedefTable.cc
    1602 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Parser/driver_cfa_cpp-TypedefTable.obj -MD -MP -MF Parser/$(DEPDIR)/driver_cfa_cpp-TypedefTable.Tpo -c -o Parser/driver_cfa_cpp-TypedefTable.obj `if test -f 'Parser/TypedefTable.cc'; then $(CYGPATH_W) 'Parser/TypedefTable.cc'; else $(CYGPATH_W) '$(srcdir)/Parser/TypedefTable.cc'; fi`
    1603 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) Parser/$(DEPDIR)/driver_cfa_cpp-TypedefTable.Tpo Parser/$(DEPDIR)/driver_cfa_cpp-TypedefTable.Po
    1604 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='Parser/TypedefTable.cc' object='Parser/driver_cfa_cpp-TypedefTable.obj' libtool=no @AMDEPBACKSLASH@
    1605 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1606 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Parser/driver_cfa_cpp-TypedefTable.obj `if test -f 'Parser/TypedefTable.cc'; then $(CYGPATH_W) 'Parser/TypedefTable.cc'; else $(CYGPATH_W) '$(srcdir)/Parser/TypedefTable.cc'; fi`
    1607 
    1608 Parser/driver_cfa_cpp-ParseNode.o: Parser/ParseNode.cc
    1609 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Parser/driver_cfa_cpp-ParseNode.o -MD -MP -MF Parser/$(DEPDIR)/driver_cfa_cpp-ParseNode.Tpo -c -o Parser/driver_cfa_cpp-ParseNode.o `test -f 'Parser/ParseNode.cc' || echo '$(srcdir)/'`Parser/ParseNode.cc
    1610 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) Parser/$(DEPDIR)/driver_cfa_cpp-ParseNode.Tpo Parser/$(DEPDIR)/driver_cfa_cpp-ParseNode.Po
    1611 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='Parser/ParseNode.cc' object='Parser/driver_cfa_cpp-ParseNode.o' libtool=no @AMDEPBACKSLASH@
    1612 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1613 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Parser/driver_cfa_cpp-ParseNode.o `test -f 'Parser/ParseNode.cc' || echo '$(srcdir)/'`Parser/ParseNode.cc
    1614 
    1615 Parser/driver_cfa_cpp-ParseNode.obj: Parser/ParseNode.cc
    1616 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Parser/driver_cfa_cpp-ParseNode.obj -MD -MP -MF Parser/$(DEPDIR)/driver_cfa_cpp-ParseNode.Tpo -c -o Parser/driver_cfa_cpp-ParseNode.obj `if test -f 'Parser/ParseNode.cc'; then $(CYGPATH_W) 'Parser/ParseNode.cc'; else $(CYGPATH_W) '$(srcdir)/Parser/ParseNode.cc'; fi`
    1617 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) Parser/$(DEPDIR)/driver_cfa_cpp-ParseNode.Tpo Parser/$(DEPDIR)/driver_cfa_cpp-ParseNode.Po
    1618 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='Parser/ParseNode.cc' object='Parser/driver_cfa_cpp-ParseNode.obj' libtool=no @AMDEPBACKSLASH@
    1619 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1620 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Parser/driver_cfa_cpp-ParseNode.obj `if test -f 'Parser/ParseNode.cc'; then $(CYGPATH_W) 'Parser/ParseNode.cc'; else $(CYGPATH_W) '$(srcdir)/Parser/ParseNode.cc'; fi`
    1621 
    1622 Parser/driver_cfa_cpp-DeclarationNode.o: Parser/DeclarationNode.cc
    1623 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Parser/driver_cfa_cpp-DeclarationNode.o -MD -MP -MF Parser/$(DEPDIR)/driver_cfa_cpp-DeclarationNode.Tpo -c -o Parser/driver_cfa_cpp-DeclarationNode.o `test -f 'Parser/DeclarationNode.cc' || echo '$(srcdir)/'`Parser/DeclarationNode.cc
    1624 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) Parser/$(DEPDIR)/driver_cfa_cpp-DeclarationNode.Tpo Parser/$(DEPDIR)/driver_cfa_cpp-DeclarationNode.Po
    1625 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='Parser/DeclarationNode.cc' object='Parser/driver_cfa_cpp-DeclarationNode.o' libtool=no @AMDEPBACKSLASH@
    1626 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1627 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Parser/driver_cfa_cpp-DeclarationNode.o `test -f 'Parser/DeclarationNode.cc' || echo '$(srcdir)/'`Parser/DeclarationNode.cc
    1628 
    1629 Parser/driver_cfa_cpp-DeclarationNode.obj: Parser/DeclarationNode.cc
    1630 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Parser/driver_cfa_cpp-DeclarationNode.obj -MD -MP -MF Parser/$(DEPDIR)/driver_cfa_cpp-DeclarationNode.Tpo -c -o Parser/driver_cfa_cpp-DeclarationNode.obj `if test -f 'Parser/DeclarationNode.cc'; then $(CYGPATH_W) 'Parser/DeclarationNode.cc'; else $(CYGPATH_W) '$(srcdir)/Parser/DeclarationNode.cc'; fi`
    1631 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) Parser/$(DEPDIR)/driver_cfa_cpp-DeclarationNode.Tpo Parser/$(DEPDIR)/driver_cfa_cpp-DeclarationNode.Po
    1632 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='Parser/DeclarationNode.cc' object='Parser/driver_cfa_cpp-DeclarationNode.obj' libtool=no @AMDEPBACKSLASH@
    1633 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1634 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Parser/driver_cfa_cpp-DeclarationNode.obj `if test -f 'Parser/DeclarationNode.cc'; then $(CYGPATH_W) 'Parser/DeclarationNode.cc'; else $(CYGPATH_W) '$(srcdir)/Parser/DeclarationNode.cc'; fi`
    1635 
    1636 Parser/driver_cfa_cpp-ExpressionNode.o: Parser/ExpressionNode.cc
    1637 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Parser/driver_cfa_cpp-ExpressionNode.o -MD -MP -MF Parser/$(DEPDIR)/driver_cfa_cpp-ExpressionNode.Tpo -c -o Parser/driver_cfa_cpp-ExpressionNode.o `test -f 'Parser/ExpressionNode.cc' || echo '$(srcdir)/'`Parser/ExpressionNode.cc
    1638 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) Parser/$(DEPDIR)/driver_cfa_cpp-ExpressionNode.Tpo Parser/$(DEPDIR)/driver_cfa_cpp-ExpressionNode.Po
    1639 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='Parser/ExpressionNode.cc' object='Parser/driver_cfa_cpp-ExpressionNode.o' libtool=no @AMDEPBACKSLASH@
    1640 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1641 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Parser/driver_cfa_cpp-ExpressionNode.o `test -f 'Parser/ExpressionNode.cc' || echo '$(srcdir)/'`Parser/ExpressionNode.cc
    1642 
    1643 Parser/driver_cfa_cpp-ExpressionNode.obj: Parser/ExpressionNode.cc
    1644 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Parser/driver_cfa_cpp-ExpressionNode.obj -MD -MP -MF Parser/$(DEPDIR)/driver_cfa_cpp-ExpressionNode.Tpo -c -o Parser/driver_cfa_cpp-ExpressionNode.obj `if test -f 'Parser/ExpressionNode.cc'; then $(CYGPATH_W) 'Parser/ExpressionNode.cc'; else $(CYGPATH_W) '$(srcdir)/Parser/ExpressionNode.cc'; fi`
    1645 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) Parser/$(DEPDIR)/driver_cfa_cpp-ExpressionNode.Tpo Parser/$(DEPDIR)/driver_cfa_cpp-ExpressionNode.Po
    1646 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='Parser/ExpressionNode.cc' object='Parser/driver_cfa_cpp-ExpressionNode.obj' libtool=no @AMDEPBACKSLASH@
    1647 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1648 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Parser/driver_cfa_cpp-ExpressionNode.obj `if test -f 'Parser/ExpressionNode.cc'; then $(CYGPATH_W) 'Parser/ExpressionNode.cc'; else $(CYGPATH_W) '$(srcdir)/Parser/ExpressionNode.cc'; fi`
    1649 
    1650 Parser/driver_cfa_cpp-StatementNode.o: Parser/StatementNode.cc
    1651 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Parser/driver_cfa_cpp-StatementNode.o -MD -MP -MF Parser/$(DEPDIR)/driver_cfa_cpp-StatementNode.Tpo -c -o Parser/driver_cfa_cpp-StatementNode.o `test -f 'Parser/StatementNode.cc' || echo '$(srcdir)/'`Parser/StatementNode.cc
    1652 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) Parser/$(DEPDIR)/driver_cfa_cpp-StatementNode.Tpo Parser/$(DEPDIR)/driver_cfa_cpp-StatementNode.Po
    1653 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='Parser/StatementNode.cc' object='Parser/driver_cfa_cpp-StatementNode.o' libtool=no @AMDEPBACKSLASH@
    1654 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1655 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Parser/driver_cfa_cpp-StatementNode.o `test -f 'Parser/StatementNode.cc' || echo '$(srcdir)/'`Parser/StatementNode.cc
    1656 
    1657 Parser/driver_cfa_cpp-StatementNode.obj: Parser/StatementNode.cc
    1658 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Parser/driver_cfa_cpp-StatementNode.obj -MD -MP -MF Parser/$(DEPDIR)/driver_cfa_cpp-StatementNode.Tpo -c -o Parser/driver_cfa_cpp-StatementNode.obj `if test -f 'Parser/StatementNode.cc'; then $(CYGPATH_W) 'Parser/StatementNode.cc'; else $(CYGPATH_W) '$(srcdir)/Parser/StatementNode.cc'; fi`
    1659 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) Parser/$(DEPDIR)/driver_cfa_cpp-StatementNode.Tpo Parser/$(DEPDIR)/driver_cfa_cpp-StatementNode.Po
    1660 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='Parser/StatementNode.cc' object='Parser/driver_cfa_cpp-StatementNode.obj' libtool=no @AMDEPBACKSLASH@
    1661 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1662 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Parser/driver_cfa_cpp-StatementNode.obj `if test -f 'Parser/StatementNode.cc'; then $(CYGPATH_W) 'Parser/StatementNode.cc'; else $(CYGPATH_W) '$(srcdir)/Parser/StatementNode.cc'; fi`
    1663 
    1664 Parser/driver_cfa_cpp-InitializerNode.o: Parser/InitializerNode.cc
    1665 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Parser/driver_cfa_cpp-InitializerNode.o -MD -MP -MF Parser/$(DEPDIR)/driver_cfa_cpp-InitializerNode.Tpo -c -o Parser/driver_cfa_cpp-InitializerNode.o `test -f 'Parser/InitializerNode.cc' || echo '$(srcdir)/'`Parser/InitializerNode.cc
    1666 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) Parser/$(DEPDIR)/driver_cfa_cpp-InitializerNode.Tpo Parser/$(DEPDIR)/driver_cfa_cpp-InitializerNode.Po
    1667 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='Parser/InitializerNode.cc' object='Parser/driver_cfa_cpp-InitializerNode.o' libtool=no @AMDEPBACKSLASH@
    1668 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1669 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Parser/driver_cfa_cpp-InitializerNode.o `test -f 'Parser/InitializerNode.cc' || echo '$(srcdir)/'`Parser/InitializerNode.cc
    1670 
    1671 Parser/driver_cfa_cpp-InitializerNode.obj: Parser/InitializerNode.cc
    1672 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Parser/driver_cfa_cpp-InitializerNode.obj -MD -MP -MF Parser/$(DEPDIR)/driver_cfa_cpp-InitializerNode.Tpo -c -o Parser/driver_cfa_cpp-InitializerNode.obj `if test -f 'Parser/InitializerNode.cc'; then $(CYGPATH_W) 'Parser/InitializerNode.cc'; else $(CYGPATH_W) '$(srcdir)/Parser/InitializerNode.cc'; fi`
    1673 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) Parser/$(DEPDIR)/driver_cfa_cpp-InitializerNode.Tpo Parser/$(DEPDIR)/driver_cfa_cpp-InitializerNode.Po
    1674 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='Parser/InitializerNode.cc' object='Parser/driver_cfa_cpp-InitializerNode.obj' libtool=no @AMDEPBACKSLASH@
    1675 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1676 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Parser/driver_cfa_cpp-InitializerNode.obj `if test -f 'Parser/InitializerNode.cc'; then $(CYGPATH_W) 'Parser/InitializerNode.cc'; else $(CYGPATH_W) '$(srcdir)/Parser/InitializerNode.cc'; fi`
    1677 
    1678 Parser/driver_cfa_cpp-TypeData.o: Parser/TypeData.cc
    1679 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Parser/driver_cfa_cpp-TypeData.o -MD -MP -MF Parser/$(DEPDIR)/driver_cfa_cpp-TypeData.Tpo -c -o Parser/driver_cfa_cpp-TypeData.o `test -f 'Parser/TypeData.cc' || echo '$(srcdir)/'`Parser/TypeData.cc
    1680 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) Parser/$(DEPDIR)/driver_cfa_cpp-TypeData.Tpo Parser/$(DEPDIR)/driver_cfa_cpp-TypeData.Po
    1681 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='Parser/TypeData.cc' object='Parser/driver_cfa_cpp-TypeData.o' libtool=no @AMDEPBACKSLASH@
    1682 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1683 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Parser/driver_cfa_cpp-TypeData.o `test -f 'Parser/TypeData.cc' || echo '$(srcdir)/'`Parser/TypeData.cc
    1684 
    1685 Parser/driver_cfa_cpp-TypeData.obj: Parser/TypeData.cc
    1686 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Parser/driver_cfa_cpp-TypeData.obj -MD -MP -MF Parser/$(DEPDIR)/driver_cfa_cpp-TypeData.Tpo -c -o Parser/driver_cfa_cpp-TypeData.obj `if test -f 'Parser/TypeData.cc'; then $(CYGPATH_W) 'Parser/TypeData.cc'; else $(CYGPATH_W) '$(srcdir)/Parser/TypeData.cc'; fi`
    1687 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) Parser/$(DEPDIR)/driver_cfa_cpp-TypeData.Tpo Parser/$(DEPDIR)/driver_cfa_cpp-TypeData.Po
    1688 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='Parser/TypeData.cc' object='Parser/driver_cfa_cpp-TypeData.obj' libtool=no @AMDEPBACKSLASH@
    1689 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1690 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Parser/driver_cfa_cpp-TypeData.obj `if test -f 'Parser/TypeData.cc'; then $(CYGPATH_W) 'Parser/TypeData.cc'; else $(CYGPATH_W) '$(srcdir)/Parser/TypeData.cc'; fi`
    1691 
    1692 Parser/driver_cfa_cpp-LinkageSpec.o: Parser/LinkageSpec.cc
    1693 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Parser/driver_cfa_cpp-LinkageSpec.o -MD -MP -MF Parser/$(DEPDIR)/driver_cfa_cpp-LinkageSpec.Tpo -c -o Parser/driver_cfa_cpp-LinkageSpec.o `test -f 'Parser/LinkageSpec.cc' || echo '$(srcdir)/'`Parser/LinkageSpec.cc
    1694 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) Parser/$(DEPDIR)/driver_cfa_cpp-LinkageSpec.Tpo Parser/$(DEPDIR)/driver_cfa_cpp-LinkageSpec.Po
    1695 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='Parser/LinkageSpec.cc' object='Parser/driver_cfa_cpp-LinkageSpec.o' libtool=no @AMDEPBACKSLASH@
    1696 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1697 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Parser/driver_cfa_cpp-LinkageSpec.o `test -f 'Parser/LinkageSpec.cc' || echo '$(srcdir)/'`Parser/LinkageSpec.cc
    1698 
    1699 Parser/driver_cfa_cpp-LinkageSpec.obj: Parser/LinkageSpec.cc
    1700 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Parser/driver_cfa_cpp-LinkageSpec.obj -MD -MP -MF Parser/$(DEPDIR)/driver_cfa_cpp-LinkageSpec.Tpo -c -o Parser/driver_cfa_cpp-LinkageSpec.obj `if test -f 'Parser/LinkageSpec.cc'; then $(CYGPATH_W) 'Parser/LinkageSpec.cc'; else $(CYGPATH_W) '$(srcdir)/Parser/LinkageSpec.cc'; fi`
    1701 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) Parser/$(DEPDIR)/driver_cfa_cpp-LinkageSpec.Tpo Parser/$(DEPDIR)/driver_cfa_cpp-LinkageSpec.Po
    1702 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='Parser/LinkageSpec.cc' object='Parser/driver_cfa_cpp-LinkageSpec.obj' libtool=no @AMDEPBACKSLASH@
    1703 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1704 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Parser/driver_cfa_cpp-LinkageSpec.obj `if test -f 'Parser/LinkageSpec.cc'; then $(CYGPATH_W) 'Parser/LinkageSpec.cc'; else $(CYGPATH_W) '$(srcdir)/Parser/LinkageSpec.cc'; fi`
    1705 
    1706 Parser/driver_cfa_cpp-parserutility.o: Parser/parserutility.cc
    1707 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Parser/driver_cfa_cpp-parserutility.o -MD -MP -MF Parser/$(DEPDIR)/driver_cfa_cpp-parserutility.Tpo -c -o Parser/driver_cfa_cpp-parserutility.o `test -f 'Parser/parserutility.cc' || echo '$(srcdir)/'`Parser/parserutility.cc
    1708 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) Parser/$(DEPDIR)/driver_cfa_cpp-parserutility.Tpo Parser/$(DEPDIR)/driver_cfa_cpp-parserutility.Po
    1709 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='Parser/parserutility.cc' object='Parser/driver_cfa_cpp-parserutility.o' libtool=no @AMDEPBACKSLASH@
    1710 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1711 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Parser/driver_cfa_cpp-parserutility.o `test -f 'Parser/parserutility.cc' || echo '$(srcdir)/'`Parser/parserutility.cc
    1712 
    1713 Parser/driver_cfa_cpp-parserutility.obj: Parser/parserutility.cc
    1714 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Parser/driver_cfa_cpp-parserutility.obj -MD -MP -MF Parser/$(DEPDIR)/driver_cfa_cpp-parserutility.Tpo -c -o Parser/driver_cfa_cpp-parserutility.obj `if test -f 'Parser/parserutility.cc'; then $(CYGPATH_W) 'Parser/parserutility.cc'; else $(CYGPATH_W) '$(srcdir)/Parser/parserutility.cc'; fi`
    1715 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) Parser/$(DEPDIR)/driver_cfa_cpp-parserutility.Tpo Parser/$(DEPDIR)/driver_cfa_cpp-parserutility.Po
    1716 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='Parser/parserutility.cc' object='Parser/driver_cfa_cpp-parserutility.obj' libtool=no @AMDEPBACKSLASH@
    1717 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1718 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Parser/driver_cfa_cpp-parserutility.obj `if test -f 'Parser/parserutility.cc'; then $(CYGPATH_W) 'Parser/parserutility.cc'; else $(CYGPATH_W) '$(srcdir)/Parser/parserutility.cc'; fi`
    1719 
    1720 ResolvExpr/driver_cfa_cpp-AlternativeFinder.o: ResolvExpr/AlternativeFinder.cc
    1721 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-AlternativeFinder.o -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-AlternativeFinder.Tpo -c -o ResolvExpr/driver_cfa_cpp-AlternativeFinder.o `test -f 'ResolvExpr/AlternativeFinder.cc' || echo '$(srcdir)/'`ResolvExpr/AlternativeFinder.cc
    1722 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-AlternativeFinder.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-AlternativeFinder.Po
    1723 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='ResolvExpr/AlternativeFinder.cc' object='ResolvExpr/driver_cfa_cpp-AlternativeFinder.o' libtool=no @AMDEPBACKSLASH@
    1724 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1725 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-AlternativeFinder.o `test -f 'ResolvExpr/AlternativeFinder.cc' || echo '$(srcdir)/'`ResolvExpr/AlternativeFinder.cc
    1726 
    1727 ResolvExpr/driver_cfa_cpp-AlternativeFinder.obj: ResolvExpr/AlternativeFinder.cc
    1728 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-AlternativeFinder.obj -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-AlternativeFinder.Tpo -c -o ResolvExpr/driver_cfa_cpp-AlternativeFinder.obj `if test -f 'ResolvExpr/AlternativeFinder.cc'; then $(CYGPATH_W) 'ResolvExpr/AlternativeFinder.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/AlternativeFinder.cc'; fi`
    1729 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-AlternativeFinder.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-AlternativeFinder.Po
    1730 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='ResolvExpr/AlternativeFinder.cc' object='ResolvExpr/driver_cfa_cpp-AlternativeFinder.obj' libtool=no @AMDEPBACKSLASH@
    1731 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1732 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-AlternativeFinder.obj `if test -f 'ResolvExpr/AlternativeFinder.cc'; then $(CYGPATH_W) 'ResolvExpr/AlternativeFinder.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/AlternativeFinder.cc'; fi`
    1733 
    1734 ResolvExpr/driver_cfa_cpp-Alternative.o: ResolvExpr/Alternative.cc
    1735 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-Alternative.o -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Alternative.Tpo -c -o ResolvExpr/driver_cfa_cpp-Alternative.o `test -f 'ResolvExpr/Alternative.cc' || echo '$(srcdir)/'`ResolvExpr/Alternative.cc
    1736 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Alternative.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Alternative.Po
    1737 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='ResolvExpr/Alternative.cc' object='ResolvExpr/driver_cfa_cpp-Alternative.o' libtool=no @AMDEPBACKSLASH@
    1738 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1739 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-Alternative.o `test -f 'ResolvExpr/Alternative.cc' || echo '$(srcdir)/'`ResolvExpr/Alternative.cc
    1740 
    1741 ResolvExpr/driver_cfa_cpp-Alternative.obj: ResolvExpr/Alternative.cc
    1742 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-Alternative.obj -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Alternative.Tpo -c -o ResolvExpr/driver_cfa_cpp-Alternative.obj `if test -f 'ResolvExpr/Alternative.cc'; then $(CYGPATH_W) 'ResolvExpr/Alternative.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/Alternative.cc'; fi`
    1743 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Alternative.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Alternative.Po
    1744 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='ResolvExpr/Alternative.cc' object='ResolvExpr/driver_cfa_cpp-Alternative.obj' libtool=no @AMDEPBACKSLASH@
    1745 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1746 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-Alternative.obj `if test -f 'ResolvExpr/Alternative.cc'; then $(CYGPATH_W) 'ResolvExpr/Alternative.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/Alternative.cc'; fi`
    1747 
    1748 ResolvExpr/driver_cfa_cpp-Unify.o: ResolvExpr/Unify.cc
    1749 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-Unify.o -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Unify.Tpo -c -o ResolvExpr/driver_cfa_cpp-Unify.o `test -f 'ResolvExpr/Unify.cc' || echo '$(srcdir)/'`ResolvExpr/Unify.cc
    1750 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Unify.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Unify.Po
    1751 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='ResolvExpr/Unify.cc' object='ResolvExpr/driver_cfa_cpp-Unify.o' libtool=no @AMDEPBACKSLASH@
    1752 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1753 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-Unify.o `test -f 'ResolvExpr/Unify.cc' || echo '$(srcdir)/'`ResolvExpr/Unify.cc
    1754 
    1755 ResolvExpr/driver_cfa_cpp-Unify.obj: ResolvExpr/Unify.cc
    1756 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-Unify.obj -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Unify.Tpo -c -o ResolvExpr/driver_cfa_cpp-Unify.obj `if test -f 'ResolvExpr/Unify.cc'; then $(CYGPATH_W) 'ResolvExpr/Unify.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/Unify.cc'; fi`
    1757 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Unify.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Unify.Po
    1758 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='ResolvExpr/Unify.cc' object='ResolvExpr/driver_cfa_cpp-Unify.obj' libtool=no @AMDEPBACKSLASH@
    1759 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1760 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-Unify.obj `if test -f 'ResolvExpr/Unify.cc'; then $(CYGPATH_W) 'ResolvExpr/Unify.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/Unify.cc'; fi`
    1761 
    1762 ResolvExpr/driver_cfa_cpp-PtrsAssignable.o: ResolvExpr/PtrsAssignable.cc
    1763 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-PtrsAssignable.o -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-PtrsAssignable.Tpo -c -o ResolvExpr/driver_cfa_cpp-PtrsAssignable.o `test -f 'ResolvExpr/PtrsAssignable.cc' || echo '$(srcdir)/'`ResolvExpr/PtrsAssignable.cc
    1764 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-PtrsAssignable.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-PtrsAssignable.Po
    1765 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='ResolvExpr/PtrsAssignable.cc' object='ResolvExpr/driver_cfa_cpp-PtrsAssignable.o' libtool=no @AMDEPBACKSLASH@
    1766 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1767 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-PtrsAssignable.o `test -f 'ResolvExpr/PtrsAssignable.cc' || echo '$(srcdir)/'`ResolvExpr/PtrsAssignable.cc
    1768 
    1769 ResolvExpr/driver_cfa_cpp-PtrsAssignable.obj: ResolvExpr/PtrsAssignable.cc
    1770 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-PtrsAssignable.obj -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-PtrsAssignable.Tpo -c -o ResolvExpr/driver_cfa_cpp-PtrsAssignable.obj `if test -f 'ResolvExpr/PtrsAssignable.cc'; then $(CYGPATH_W) 'ResolvExpr/PtrsAssignable.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/PtrsAssignable.cc'; fi`
    1771 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-PtrsAssignable.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-PtrsAssignable.Po
    1772 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='ResolvExpr/PtrsAssignable.cc' object='ResolvExpr/driver_cfa_cpp-PtrsAssignable.obj' libtool=no @AMDEPBACKSLASH@
    1773 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1774 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-PtrsAssignable.obj `if test -f 'ResolvExpr/PtrsAssignable.cc'; then $(CYGPATH_W) 'ResolvExpr/PtrsAssignable.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/PtrsAssignable.cc'; fi`
    1775 
    1776 ResolvExpr/driver_cfa_cpp-CommonType.o: ResolvExpr/CommonType.cc
    1777 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-CommonType.o -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CommonType.Tpo -c -o ResolvExpr/driver_cfa_cpp-CommonType.o `test -f 'ResolvExpr/CommonType.cc' || echo '$(srcdir)/'`ResolvExpr/CommonType.cc
    1778 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CommonType.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CommonType.Po
    1779 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='ResolvExpr/CommonType.cc' object='ResolvExpr/driver_cfa_cpp-CommonType.o' libtool=no @AMDEPBACKSLASH@
    1780 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1781 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-CommonType.o `test -f 'ResolvExpr/CommonType.cc' || echo '$(srcdir)/'`ResolvExpr/CommonType.cc
    1782 
    1783 ResolvExpr/driver_cfa_cpp-CommonType.obj: ResolvExpr/CommonType.cc
    1784 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-CommonType.obj -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CommonType.Tpo -c -o ResolvExpr/driver_cfa_cpp-CommonType.obj `if test -f 'ResolvExpr/CommonType.cc'; then $(CYGPATH_W) 'ResolvExpr/CommonType.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/CommonType.cc'; fi`
    1785 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CommonType.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CommonType.Po
    1786 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='ResolvExpr/CommonType.cc' object='ResolvExpr/driver_cfa_cpp-CommonType.obj' libtool=no @AMDEPBACKSLASH@
    1787 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1788 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-CommonType.obj `if test -f 'ResolvExpr/CommonType.cc'; then $(CYGPATH_W) 'ResolvExpr/CommonType.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/CommonType.cc'; fi`
    1789 
    1790 ResolvExpr/driver_cfa_cpp-ConversionCost.o: ResolvExpr/ConversionCost.cc
    1791 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-ConversionCost.o -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ConversionCost.Tpo -c -o ResolvExpr/driver_cfa_cpp-ConversionCost.o `test -f 'ResolvExpr/ConversionCost.cc' || echo '$(srcdir)/'`ResolvExpr/ConversionCost.cc
    1792 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ConversionCost.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ConversionCost.Po
    1793 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='ResolvExpr/ConversionCost.cc' object='ResolvExpr/driver_cfa_cpp-ConversionCost.o' libtool=no @AMDEPBACKSLASH@
    1794 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1795 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-ConversionCost.o `test -f 'ResolvExpr/ConversionCost.cc' || echo '$(srcdir)/'`ResolvExpr/ConversionCost.cc
    1796 
    1797 ResolvExpr/driver_cfa_cpp-ConversionCost.obj: ResolvExpr/ConversionCost.cc
    1798 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-ConversionCost.obj -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ConversionCost.Tpo -c -o ResolvExpr/driver_cfa_cpp-ConversionCost.obj `if test -f 'ResolvExpr/ConversionCost.cc'; then $(CYGPATH_W) 'ResolvExpr/ConversionCost.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/ConversionCost.cc'; fi`
    1799 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ConversionCost.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ConversionCost.Po
    1800 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='ResolvExpr/ConversionCost.cc' object='ResolvExpr/driver_cfa_cpp-ConversionCost.obj' libtool=no @AMDEPBACKSLASH@
    1801 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1802 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-ConversionCost.obj `if test -f 'ResolvExpr/ConversionCost.cc'; then $(CYGPATH_W) 'ResolvExpr/ConversionCost.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/ConversionCost.cc'; fi`
    1803 
    1804 ResolvExpr/driver_cfa_cpp-CastCost.o: ResolvExpr/CastCost.cc
    1805 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-CastCost.o -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CastCost.Tpo -c -o ResolvExpr/driver_cfa_cpp-CastCost.o `test -f 'ResolvExpr/CastCost.cc' || echo '$(srcdir)/'`ResolvExpr/CastCost.cc
    1806 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CastCost.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CastCost.Po
    1807 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='ResolvExpr/CastCost.cc' object='ResolvExpr/driver_cfa_cpp-CastCost.o' libtool=no @AMDEPBACKSLASH@
    1808 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1809 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-CastCost.o `test -f 'ResolvExpr/CastCost.cc' || echo '$(srcdir)/'`ResolvExpr/CastCost.cc
    1810 
    1811 ResolvExpr/driver_cfa_cpp-CastCost.obj: ResolvExpr/CastCost.cc
    1812 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-CastCost.obj -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CastCost.Tpo -c -o ResolvExpr/driver_cfa_cpp-CastCost.obj `if test -f 'ResolvExpr/CastCost.cc'; then $(CYGPATH_W) 'ResolvExpr/CastCost.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/CastCost.cc'; fi`
    1813 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CastCost.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CastCost.Po
    1814 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='ResolvExpr/CastCost.cc' object='ResolvExpr/driver_cfa_cpp-CastCost.obj' libtool=no @AMDEPBACKSLASH@
    1815 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1816 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-CastCost.obj `if test -f 'ResolvExpr/CastCost.cc'; then $(CYGPATH_W) 'ResolvExpr/CastCost.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/CastCost.cc'; fi`
    1817 
    1818 ResolvExpr/driver_cfa_cpp-PtrsCastable.o: ResolvExpr/PtrsCastable.cc
    1819 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-PtrsCastable.o -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-PtrsCastable.Tpo -c -o ResolvExpr/driver_cfa_cpp-PtrsCastable.o `test -f 'ResolvExpr/PtrsCastable.cc' || echo '$(srcdir)/'`ResolvExpr/PtrsCastable.cc
    1820 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-PtrsCastable.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-PtrsCastable.Po
    1821 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='ResolvExpr/PtrsCastable.cc' object='ResolvExpr/driver_cfa_cpp-PtrsCastable.o' libtool=no @AMDEPBACKSLASH@
    1822 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1823 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-PtrsCastable.o `test -f 'ResolvExpr/PtrsCastable.cc' || echo '$(srcdir)/'`ResolvExpr/PtrsCastable.cc
    1824 
    1825 ResolvExpr/driver_cfa_cpp-PtrsCastable.obj: ResolvExpr/PtrsCastable.cc
    1826 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-PtrsCastable.obj -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-PtrsCastable.Tpo -c -o ResolvExpr/driver_cfa_cpp-PtrsCastable.obj `if test -f 'ResolvExpr/PtrsCastable.cc'; then $(CYGPATH_W) 'ResolvExpr/PtrsCastable.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/PtrsCastable.cc'; fi`
    1827 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-PtrsCastable.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-PtrsCastable.Po
    1828 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='ResolvExpr/PtrsCastable.cc' object='ResolvExpr/driver_cfa_cpp-PtrsCastable.obj' libtool=no @AMDEPBACKSLASH@
    1829 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1830 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-PtrsCastable.obj `if test -f 'ResolvExpr/PtrsCastable.cc'; then $(CYGPATH_W) 'ResolvExpr/PtrsCastable.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/PtrsCastable.cc'; fi`
    1831 
    1832 ResolvExpr/driver_cfa_cpp-AdjustExprType.o: ResolvExpr/AdjustExprType.cc
    1833 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-AdjustExprType.o -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-AdjustExprType.Tpo -c -o ResolvExpr/driver_cfa_cpp-AdjustExprType.o `test -f 'ResolvExpr/AdjustExprType.cc' || echo '$(srcdir)/'`ResolvExpr/AdjustExprType.cc
    1834 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-AdjustExprType.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-AdjustExprType.Po
    1835 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='ResolvExpr/AdjustExprType.cc' object='ResolvExpr/driver_cfa_cpp-AdjustExprType.o' libtool=no @AMDEPBACKSLASH@
    1836 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1837 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-AdjustExprType.o `test -f 'ResolvExpr/AdjustExprType.cc' || echo '$(srcdir)/'`ResolvExpr/AdjustExprType.cc
    1838 
    1839 ResolvExpr/driver_cfa_cpp-AdjustExprType.obj: ResolvExpr/AdjustExprType.cc
    1840 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-AdjustExprType.obj -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-AdjustExprType.Tpo -c -o ResolvExpr/driver_cfa_cpp-AdjustExprType.obj `if test -f 'ResolvExpr/AdjustExprType.cc'; then $(CYGPATH_W) 'ResolvExpr/AdjustExprType.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/AdjustExprType.cc'; fi`
    1841 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-AdjustExprType.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-AdjustExprType.Po
    1842 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='ResolvExpr/AdjustExprType.cc' object='ResolvExpr/driver_cfa_cpp-AdjustExprType.obj' libtool=no @AMDEPBACKSLASH@
    1843 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1844 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-AdjustExprType.obj `if test -f 'ResolvExpr/AdjustExprType.cc'; then $(CYGPATH_W) 'ResolvExpr/AdjustExprType.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/AdjustExprType.cc'; fi`
    1845 
    1846 ResolvExpr/driver_cfa_cpp-AlternativePrinter.o: ResolvExpr/AlternativePrinter.cc
    1847 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-AlternativePrinter.o -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-AlternativePrinter.Tpo -c -o ResolvExpr/driver_cfa_cpp-AlternativePrinter.o `test -f 'ResolvExpr/AlternativePrinter.cc' || echo '$(srcdir)/'`ResolvExpr/AlternativePrinter.cc
    1848 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-AlternativePrinter.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-AlternativePrinter.Po
    1849 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='ResolvExpr/AlternativePrinter.cc' object='ResolvExpr/driver_cfa_cpp-AlternativePrinter.o' libtool=no @AMDEPBACKSLASH@
    1850 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1851 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-AlternativePrinter.o `test -f 'ResolvExpr/AlternativePrinter.cc' || echo '$(srcdir)/'`ResolvExpr/AlternativePrinter.cc
    1852 
    1853 ResolvExpr/driver_cfa_cpp-AlternativePrinter.obj: ResolvExpr/AlternativePrinter.cc
    1854 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-AlternativePrinter.obj -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-AlternativePrinter.Tpo -c -o ResolvExpr/driver_cfa_cpp-AlternativePrinter.obj `if test -f 'ResolvExpr/AlternativePrinter.cc'; then $(CYGPATH_W) 'ResolvExpr/AlternativePrinter.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/AlternativePrinter.cc'; fi`
    1855 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-AlternativePrinter.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-AlternativePrinter.Po
    1856 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='ResolvExpr/AlternativePrinter.cc' object='ResolvExpr/driver_cfa_cpp-AlternativePrinter.obj' libtool=no @AMDEPBACKSLASH@
    1857 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1858 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-AlternativePrinter.obj `if test -f 'ResolvExpr/AlternativePrinter.cc'; then $(CYGPATH_W) 'ResolvExpr/AlternativePrinter.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/AlternativePrinter.cc'; fi`
    1859 
    1860 ResolvExpr/driver_cfa_cpp-Resolver.o: ResolvExpr/Resolver.cc
    1861 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-Resolver.o -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Resolver.Tpo -c -o ResolvExpr/driver_cfa_cpp-Resolver.o `test -f 'ResolvExpr/Resolver.cc' || echo '$(srcdir)/'`ResolvExpr/Resolver.cc
    1862 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Resolver.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Resolver.Po
    1863 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='ResolvExpr/Resolver.cc' object='ResolvExpr/driver_cfa_cpp-Resolver.o' libtool=no @AMDEPBACKSLASH@
    1864 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1865 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-Resolver.o `test -f 'ResolvExpr/Resolver.cc' || echo '$(srcdir)/'`ResolvExpr/Resolver.cc
    1866 
    1867 ResolvExpr/driver_cfa_cpp-Resolver.obj: ResolvExpr/Resolver.cc
    1868 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-Resolver.obj -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Resolver.Tpo -c -o ResolvExpr/driver_cfa_cpp-Resolver.obj `if test -f 'ResolvExpr/Resolver.cc'; then $(CYGPATH_W) 'ResolvExpr/Resolver.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/Resolver.cc'; fi`
    1869 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Resolver.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Resolver.Po
    1870 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='ResolvExpr/Resolver.cc' object='ResolvExpr/driver_cfa_cpp-Resolver.obj' libtool=no @AMDEPBACKSLASH@
    1871 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1872 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-Resolver.obj `if test -f 'ResolvExpr/Resolver.cc'; then $(CYGPATH_W) 'ResolvExpr/Resolver.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/Resolver.cc'; fi`
    1873 
    1874 ResolvExpr/driver_cfa_cpp-ResolveTypeof.o: ResolvExpr/ResolveTypeof.cc
    1875 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-ResolveTypeof.o -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ResolveTypeof.Tpo -c -o ResolvExpr/driver_cfa_cpp-ResolveTypeof.o `test -f 'ResolvExpr/ResolveTypeof.cc' || echo '$(srcdir)/'`ResolvExpr/ResolveTypeof.cc
    1876 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ResolveTypeof.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ResolveTypeof.Po
    1877 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='ResolvExpr/ResolveTypeof.cc' object='ResolvExpr/driver_cfa_cpp-ResolveTypeof.o' libtool=no @AMDEPBACKSLASH@
    1878 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1879 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-ResolveTypeof.o `test -f 'ResolvExpr/ResolveTypeof.cc' || echo '$(srcdir)/'`ResolvExpr/ResolveTypeof.cc
    1880 
    1881 ResolvExpr/driver_cfa_cpp-ResolveTypeof.obj: ResolvExpr/ResolveTypeof.cc
    1882 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-ResolveTypeof.obj -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ResolveTypeof.Tpo -c -o ResolvExpr/driver_cfa_cpp-ResolveTypeof.obj `if test -f 'ResolvExpr/ResolveTypeof.cc'; then $(CYGPATH_W) 'ResolvExpr/ResolveTypeof.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/ResolveTypeof.cc'; fi`
    1883 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ResolveTypeof.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ResolveTypeof.Po
    1884 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='ResolvExpr/ResolveTypeof.cc' object='ResolvExpr/driver_cfa_cpp-ResolveTypeof.obj' libtool=no @AMDEPBACKSLASH@
    1885 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1886 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-ResolveTypeof.obj `if test -f 'ResolvExpr/ResolveTypeof.cc'; then $(CYGPATH_W) 'ResolvExpr/ResolveTypeof.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/ResolveTypeof.cc'; fi`
    1887 
    1888 ResolvExpr/driver_cfa_cpp-RenameVars.o: ResolvExpr/RenameVars.cc
    1889 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-RenameVars.o -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-RenameVars.Tpo -c -o ResolvExpr/driver_cfa_cpp-RenameVars.o `test -f 'ResolvExpr/RenameVars.cc' || echo '$(srcdir)/'`ResolvExpr/RenameVars.cc
    1890 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-RenameVars.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-RenameVars.Po
    1891 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='ResolvExpr/RenameVars.cc' object='ResolvExpr/driver_cfa_cpp-RenameVars.o' libtool=no @AMDEPBACKSLASH@
    1892 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1893 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-RenameVars.o `test -f 'ResolvExpr/RenameVars.cc' || echo '$(srcdir)/'`ResolvExpr/RenameVars.cc
    1894 
    1895 ResolvExpr/driver_cfa_cpp-RenameVars.obj: ResolvExpr/RenameVars.cc
    1896 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-RenameVars.obj -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-RenameVars.Tpo -c -o ResolvExpr/driver_cfa_cpp-RenameVars.obj `if test -f 'ResolvExpr/RenameVars.cc'; then $(CYGPATH_W) 'ResolvExpr/RenameVars.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/RenameVars.cc'; fi`
    1897 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-RenameVars.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-RenameVars.Po
    1898 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='ResolvExpr/RenameVars.cc' object='ResolvExpr/driver_cfa_cpp-RenameVars.obj' libtool=no @AMDEPBACKSLASH@
    1899 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1900 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-RenameVars.obj `if test -f 'ResolvExpr/RenameVars.cc'; then $(CYGPATH_W) 'ResolvExpr/RenameVars.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/RenameVars.cc'; fi`
    1901 
    1902 ResolvExpr/driver_cfa_cpp-FindOpenVars.o: ResolvExpr/FindOpenVars.cc
    1903 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-FindOpenVars.o -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-FindOpenVars.Tpo -c -o ResolvExpr/driver_cfa_cpp-FindOpenVars.o `test -f 'ResolvExpr/FindOpenVars.cc' || echo '$(srcdir)/'`ResolvExpr/FindOpenVars.cc
    1904 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-FindOpenVars.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-FindOpenVars.Po
    1905 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='ResolvExpr/FindOpenVars.cc' object='ResolvExpr/driver_cfa_cpp-FindOpenVars.o' libtool=no @AMDEPBACKSLASH@
    1906 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1907 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-FindOpenVars.o `test -f 'ResolvExpr/FindOpenVars.cc' || echo '$(srcdir)/'`ResolvExpr/FindOpenVars.cc
    1908 
    1909 ResolvExpr/driver_cfa_cpp-FindOpenVars.obj: ResolvExpr/FindOpenVars.cc
    1910 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-FindOpenVars.obj -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-FindOpenVars.Tpo -c -o ResolvExpr/driver_cfa_cpp-FindOpenVars.obj `if test -f 'ResolvExpr/FindOpenVars.cc'; then $(CYGPATH_W) 'ResolvExpr/FindOpenVars.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/FindOpenVars.cc'; fi`
    1911 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-FindOpenVars.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-FindOpenVars.Po
    1912 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='ResolvExpr/FindOpenVars.cc' object='ResolvExpr/driver_cfa_cpp-FindOpenVars.obj' libtool=no @AMDEPBACKSLASH@
    1913 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1914 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-FindOpenVars.obj `if test -f 'ResolvExpr/FindOpenVars.cc'; then $(CYGPATH_W) 'ResolvExpr/FindOpenVars.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/FindOpenVars.cc'; fi`
    1915 
    1916 ResolvExpr/driver_cfa_cpp-PolyCost.o: ResolvExpr/PolyCost.cc
    1917 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-PolyCost.o -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-PolyCost.Tpo -c -o ResolvExpr/driver_cfa_cpp-PolyCost.o `test -f 'ResolvExpr/PolyCost.cc' || echo '$(srcdir)/'`ResolvExpr/PolyCost.cc
    1918 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-PolyCost.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-PolyCost.Po
    1919 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='ResolvExpr/PolyCost.cc' object='ResolvExpr/driver_cfa_cpp-PolyCost.o' libtool=no @AMDEPBACKSLASH@
    1920 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1921 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-PolyCost.o `test -f 'ResolvExpr/PolyCost.cc' || echo '$(srcdir)/'`ResolvExpr/PolyCost.cc
    1922 
    1923 ResolvExpr/driver_cfa_cpp-PolyCost.obj: ResolvExpr/PolyCost.cc
    1924 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-PolyCost.obj -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-PolyCost.Tpo -c -o ResolvExpr/driver_cfa_cpp-PolyCost.obj `if test -f 'ResolvExpr/PolyCost.cc'; then $(CYGPATH_W) 'ResolvExpr/PolyCost.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/PolyCost.cc'; fi`
    1925 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-PolyCost.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-PolyCost.Po
    1926 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='ResolvExpr/PolyCost.cc' object='ResolvExpr/driver_cfa_cpp-PolyCost.obj' libtool=no @AMDEPBACKSLASH@
    1927 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1928 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-PolyCost.obj `if test -f 'ResolvExpr/PolyCost.cc'; then $(CYGPATH_W) 'ResolvExpr/PolyCost.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/PolyCost.cc'; fi`
    1929 
    1930 ResolvExpr/driver_cfa_cpp-Occurs.o: ResolvExpr/Occurs.cc
    1931 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-Occurs.o -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Occurs.Tpo -c -o ResolvExpr/driver_cfa_cpp-Occurs.o `test -f 'ResolvExpr/Occurs.cc' || echo '$(srcdir)/'`ResolvExpr/Occurs.cc
    1932 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Occurs.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Occurs.Po
    1933 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='ResolvExpr/Occurs.cc' object='ResolvExpr/driver_cfa_cpp-Occurs.o' libtool=no @AMDEPBACKSLASH@
    1934 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1935 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-Occurs.o `test -f 'ResolvExpr/Occurs.cc' || echo '$(srcdir)/'`ResolvExpr/Occurs.cc
    1936 
    1937 ResolvExpr/driver_cfa_cpp-Occurs.obj: ResolvExpr/Occurs.cc
    1938 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-Occurs.obj -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Occurs.Tpo -c -o ResolvExpr/driver_cfa_cpp-Occurs.obj `if test -f 'ResolvExpr/Occurs.cc'; then $(CYGPATH_W) 'ResolvExpr/Occurs.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/Occurs.cc'; fi`
    1939 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Occurs.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Occurs.Po
    1940 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='ResolvExpr/Occurs.cc' object='ResolvExpr/driver_cfa_cpp-Occurs.obj' libtool=no @AMDEPBACKSLASH@
    1941 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1942 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-Occurs.obj `if test -f 'ResolvExpr/Occurs.cc'; then $(CYGPATH_W) 'ResolvExpr/Occurs.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/Occurs.cc'; fi`
    1943 
    1944 ResolvExpr/driver_cfa_cpp-TypeEnvironment.o: ResolvExpr/TypeEnvironment.cc
    1945 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-TypeEnvironment.o -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-TypeEnvironment.Tpo -c -o ResolvExpr/driver_cfa_cpp-TypeEnvironment.o `test -f 'ResolvExpr/TypeEnvironment.cc' || echo '$(srcdir)/'`ResolvExpr/TypeEnvironment.cc
    1946 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-TypeEnvironment.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-TypeEnvironment.Po
    1947 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='ResolvExpr/TypeEnvironment.cc' object='ResolvExpr/driver_cfa_cpp-TypeEnvironment.o' libtool=no @AMDEPBACKSLASH@
    1948 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1949 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-TypeEnvironment.o `test -f 'ResolvExpr/TypeEnvironment.cc' || echo '$(srcdir)/'`ResolvExpr/TypeEnvironment.cc
    1950 
    1951 ResolvExpr/driver_cfa_cpp-TypeEnvironment.obj: ResolvExpr/TypeEnvironment.cc
    1952 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-TypeEnvironment.obj -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-TypeEnvironment.Tpo -c -o ResolvExpr/driver_cfa_cpp-TypeEnvironment.obj `if test -f 'ResolvExpr/TypeEnvironment.cc'; then $(CYGPATH_W) 'ResolvExpr/TypeEnvironment.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/TypeEnvironment.cc'; fi`
    1953 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-TypeEnvironment.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-TypeEnvironment.Po
    1954 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='ResolvExpr/TypeEnvironment.cc' object='ResolvExpr/driver_cfa_cpp-TypeEnvironment.obj' libtool=no @AMDEPBACKSLASH@
    1955 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1956 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-TypeEnvironment.obj `if test -f 'ResolvExpr/TypeEnvironment.cc'; then $(CYGPATH_W) 'ResolvExpr/TypeEnvironment.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/TypeEnvironment.cc'; fi`
    1957 
    1958 ResolvExpr/driver_cfa_cpp-CurrentObject.o: ResolvExpr/CurrentObject.cc
    1959 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-CurrentObject.o -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CurrentObject.Tpo -c -o ResolvExpr/driver_cfa_cpp-CurrentObject.o `test -f 'ResolvExpr/CurrentObject.cc' || echo '$(srcdir)/'`ResolvExpr/CurrentObject.cc
    1960 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CurrentObject.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CurrentObject.Po
    1961 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='ResolvExpr/CurrentObject.cc' object='ResolvExpr/driver_cfa_cpp-CurrentObject.o' libtool=no @AMDEPBACKSLASH@
    1962 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1963 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-CurrentObject.o `test -f 'ResolvExpr/CurrentObject.cc' || echo '$(srcdir)/'`ResolvExpr/CurrentObject.cc
    1964 
    1965 ResolvExpr/driver_cfa_cpp-CurrentObject.obj: ResolvExpr/CurrentObject.cc
    1966 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-CurrentObject.obj -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CurrentObject.Tpo -c -o ResolvExpr/driver_cfa_cpp-CurrentObject.obj `if test -f 'ResolvExpr/CurrentObject.cc'; then $(CYGPATH_W) 'ResolvExpr/CurrentObject.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/CurrentObject.cc'; fi`
    1967 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CurrentObject.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-CurrentObject.Po
    1968 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='ResolvExpr/CurrentObject.cc' object='ResolvExpr/driver_cfa_cpp-CurrentObject.obj' libtool=no @AMDEPBACKSLASH@
    1969 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1970 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-CurrentObject.obj `if test -f 'ResolvExpr/CurrentObject.cc'; then $(CYGPATH_W) 'ResolvExpr/CurrentObject.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/CurrentObject.cc'; fi`
    1971 
    1972 ResolvExpr/driver_cfa_cpp-ExplodedActual.o: ResolvExpr/ExplodedActual.cc
    1973 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-ExplodedActual.o -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ExplodedActual.Tpo -c -o ResolvExpr/driver_cfa_cpp-ExplodedActual.o `test -f 'ResolvExpr/ExplodedActual.cc' || echo '$(srcdir)/'`ResolvExpr/ExplodedActual.cc
    1974 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ExplodedActual.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ExplodedActual.Po
    1975 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='ResolvExpr/ExplodedActual.cc' object='ResolvExpr/driver_cfa_cpp-ExplodedActual.o' libtool=no @AMDEPBACKSLASH@
    1976 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1977 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-ExplodedActual.o `test -f 'ResolvExpr/ExplodedActual.cc' || echo '$(srcdir)/'`ResolvExpr/ExplodedActual.cc
    1978 
    1979 ResolvExpr/driver_cfa_cpp-ExplodedActual.obj: ResolvExpr/ExplodedActual.cc
    1980 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT ResolvExpr/driver_cfa_cpp-ExplodedActual.obj -MD -MP -MF ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ExplodedActual.Tpo -c -o ResolvExpr/driver_cfa_cpp-ExplodedActual.obj `if test -f 'ResolvExpr/ExplodedActual.cc'; then $(CYGPATH_W) 'ResolvExpr/ExplodedActual.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/ExplodedActual.cc'; fi`
    1981 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ExplodedActual.Tpo ResolvExpr/$(DEPDIR)/driver_cfa_cpp-ExplodedActual.Po
    1982 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='ResolvExpr/ExplodedActual.cc' object='ResolvExpr/driver_cfa_cpp-ExplodedActual.obj' libtool=no @AMDEPBACKSLASH@
    1983 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1984 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-ExplodedActual.obj `if test -f 'ResolvExpr/ExplodedActual.cc'; then $(CYGPATH_W) 'ResolvExpr/ExplodedActual.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/ExplodedActual.cc'; fi`
    1985 
    1986 SymTab/driver_cfa_cpp-Indexer.o: SymTab/Indexer.cc
    1987 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SymTab/driver_cfa_cpp-Indexer.o -MD -MP -MF SymTab/$(DEPDIR)/driver_cfa_cpp-Indexer.Tpo -c -o SymTab/driver_cfa_cpp-Indexer.o `test -f 'SymTab/Indexer.cc' || echo '$(srcdir)/'`SymTab/Indexer.cc
    1988 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SymTab/$(DEPDIR)/driver_cfa_cpp-Indexer.Tpo SymTab/$(DEPDIR)/driver_cfa_cpp-Indexer.Po
    1989 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SymTab/Indexer.cc' object='SymTab/driver_cfa_cpp-Indexer.o' libtool=no @AMDEPBACKSLASH@
    1990 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1991 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SymTab/driver_cfa_cpp-Indexer.o `test -f 'SymTab/Indexer.cc' || echo '$(srcdir)/'`SymTab/Indexer.cc
    1992 
    1993 SymTab/driver_cfa_cpp-Indexer.obj: SymTab/Indexer.cc
    1994 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SymTab/driver_cfa_cpp-Indexer.obj -MD -MP -MF SymTab/$(DEPDIR)/driver_cfa_cpp-Indexer.Tpo -c -o SymTab/driver_cfa_cpp-Indexer.obj `if test -f 'SymTab/Indexer.cc'; then $(CYGPATH_W) 'SymTab/Indexer.cc'; else $(CYGPATH_W) '$(srcdir)/SymTab/Indexer.cc'; fi`
    1995 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SymTab/$(DEPDIR)/driver_cfa_cpp-Indexer.Tpo SymTab/$(DEPDIR)/driver_cfa_cpp-Indexer.Po
    1996 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SymTab/Indexer.cc' object='SymTab/driver_cfa_cpp-Indexer.obj' libtool=no @AMDEPBACKSLASH@
    1997 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1998 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SymTab/driver_cfa_cpp-Indexer.obj `if test -f 'SymTab/Indexer.cc'; then $(CYGPATH_W) 'SymTab/Indexer.cc'; else $(CYGPATH_W) '$(srcdir)/SymTab/Indexer.cc'; fi`
    1999 
    2000 SymTab/driver_cfa_cpp-Mangler.o: SymTab/Mangler.cc
    2001 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SymTab/driver_cfa_cpp-Mangler.o -MD -MP -MF SymTab/$(DEPDIR)/driver_cfa_cpp-Mangler.Tpo -c -o SymTab/driver_cfa_cpp-Mangler.o `test -f 'SymTab/Mangler.cc' || echo '$(srcdir)/'`SymTab/Mangler.cc
    2002 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SymTab/$(DEPDIR)/driver_cfa_cpp-Mangler.Tpo SymTab/$(DEPDIR)/driver_cfa_cpp-Mangler.Po
    2003 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SymTab/Mangler.cc' object='SymTab/driver_cfa_cpp-Mangler.o' libtool=no @AMDEPBACKSLASH@
    2004 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2005 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SymTab/driver_cfa_cpp-Mangler.o `test -f 'SymTab/Mangler.cc' || echo '$(srcdir)/'`SymTab/Mangler.cc
    2006 
    2007 SymTab/driver_cfa_cpp-Mangler.obj: SymTab/Mangler.cc
    2008 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SymTab/driver_cfa_cpp-Mangler.obj -MD -MP -MF SymTab/$(DEPDIR)/driver_cfa_cpp-Mangler.Tpo -c -o SymTab/driver_cfa_cpp-Mangler.obj `if test -f 'SymTab/Mangler.cc'; then $(CYGPATH_W) 'SymTab/Mangler.cc'; else $(CYGPATH_W) '$(srcdir)/SymTab/Mangler.cc'; fi`
    2009 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SymTab/$(DEPDIR)/driver_cfa_cpp-Mangler.Tpo SymTab/$(DEPDIR)/driver_cfa_cpp-Mangler.Po
    2010 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SymTab/Mangler.cc' object='SymTab/driver_cfa_cpp-Mangler.obj' libtool=no @AMDEPBACKSLASH@
    2011 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2012 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SymTab/driver_cfa_cpp-Mangler.obj `if test -f 'SymTab/Mangler.cc'; then $(CYGPATH_W) 'SymTab/Mangler.cc'; else $(CYGPATH_W) '$(srcdir)/SymTab/Mangler.cc'; fi`
    2013 
    2014 SymTab/driver_cfa_cpp-Validate.o: SymTab/Validate.cc
    2015 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SymTab/driver_cfa_cpp-Validate.o -MD -MP -MF SymTab/$(DEPDIR)/driver_cfa_cpp-Validate.Tpo -c -o SymTab/driver_cfa_cpp-Validate.o `test -f 'SymTab/Validate.cc' || echo '$(srcdir)/'`SymTab/Validate.cc
    2016 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SymTab/$(DEPDIR)/driver_cfa_cpp-Validate.Tpo SymTab/$(DEPDIR)/driver_cfa_cpp-Validate.Po
    2017 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SymTab/Validate.cc' object='SymTab/driver_cfa_cpp-Validate.o' libtool=no @AMDEPBACKSLASH@
    2018 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2019 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SymTab/driver_cfa_cpp-Validate.o `test -f 'SymTab/Validate.cc' || echo '$(srcdir)/'`SymTab/Validate.cc
    2020 
    2021 SymTab/driver_cfa_cpp-Validate.obj: SymTab/Validate.cc
    2022 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SymTab/driver_cfa_cpp-Validate.obj -MD -MP -MF SymTab/$(DEPDIR)/driver_cfa_cpp-Validate.Tpo -c -o SymTab/driver_cfa_cpp-Validate.obj `if test -f 'SymTab/Validate.cc'; then $(CYGPATH_W) 'SymTab/Validate.cc'; else $(CYGPATH_W) '$(srcdir)/SymTab/Validate.cc'; fi`
    2023 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SymTab/$(DEPDIR)/driver_cfa_cpp-Validate.Tpo SymTab/$(DEPDIR)/driver_cfa_cpp-Validate.Po
    2024 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SymTab/Validate.cc' object='SymTab/driver_cfa_cpp-Validate.obj' libtool=no @AMDEPBACKSLASH@
    2025 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2026 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SymTab/driver_cfa_cpp-Validate.obj `if test -f 'SymTab/Validate.cc'; then $(CYGPATH_W) 'SymTab/Validate.cc'; else $(CYGPATH_W) '$(srcdir)/SymTab/Validate.cc'; fi`
    2027 
    2028 SymTab/driver_cfa_cpp-FixFunction.o: SymTab/FixFunction.cc
    2029 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SymTab/driver_cfa_cpp-FixFunction.o -MD -MP -MF SymTab/$(DEPDIR)/driver_cfa_cpp-FixFunction.Tpo -c -o SymTab/driver_cfa_cpp-FixFunction.o `test -f 'SymTab/FixFunction.cc' || echo '$(srcdir)/'`SymTab/FixFunction.cc
    2030 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SymTab/$(DEPDIR)/driver_cfa_cpp-FixFunction.Tpo SymTab/$(DEPDIR)/driver_cfa_cpp-FixFunction.Po
    2031 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SymTab/FixFunction.cc' object='SymTab/driver_cfa_cpp-FixFunction.o' libtool=no @AMDEPBACKSLASH@
    2032 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2033 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SymTab/driver_cfa_cpp-FixFunction.o `test -f 'SymTab/FixFunction.cc' || echo '$(srcdir)/'`SymTab/FixFunction.cc
    2034 
    2035 SymTab/driver_cfa_cpp-FixFunction.obj: SymTab/FixFunction.cc
    2036 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SymTab/driver_cfa_cpp-FixFunction.obj -MD -MP -MF SymTab/$(DEPDIR)/driver_cfa_cpp-FixFunction.Tpo -c -o SymTab/driver_cfa_cpp-FixFunction.obj `if test -f 'SymTab/FixFunction.cc'; then $(CYGPATH_W) 'SymTab/FixFunction.cc'; else $(CYGPATH_W) '$(srcdir)/SymTab/FixFunction.cc'; fi`
    2037 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SymTab/$(DEPDIR)/driver_cfa_cpp-FixFunction.Tpo SymTab/$(DEPDIR)/driver_cfa_cpp-FixFunction.Po
    2038 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SymTab/FixFunction.cc' object='SymTab/driver_cfa_cpp-FixFunction.obj' libtool=no @AMDEPBACKSLASH@
    2039 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2040 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SymTab/driver_cfa_cpp-FixFunction.obj `if test -f 'SymTab/FixFunction.cc'; then $(CYGPATH_W) 'SymTab/FixFunction.cc'; else $(CYGPATH_W) '$(srcdir)/SymTab/FixFunction.cc'; fi`
    2041 
    2042 SymTab/driver_cfa_cpp-Autogen.o: SymTab/Autogen.cc
    2043 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SymTab/driver_cfa_cpp-Autogen.o -MD -MP -MF SymTab/$(DEPDIR)/driver_cfa_cpp-Autogen.Tpo -c -o SymTab/driver_cfa_cpp-Autogen.o `test -f 'SymTab/Autogen.cc' || echo '$(srcdir)/'`SymTab/Autogen.cc
    2044 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SymTab/$(DEPDIR)/driver_cfa_cpp-Autogen.Tpo SymTab/$(DEPDIR)/driver_cfa_cpp-Autogen.Po
    2045 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SymTab/Autogen.cc' object='SymTab/driver_cfa_cpp-Autogen.o' libtool=no @AMDEPBACKSLASH@
    2046 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2047 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SymTab/driver_cfa_cpp-Autogen.o `test -f 'SymTab/Autogen.cc' || echo '$(srcdir)/'`SymTab/Autogen.cc
    2048 
    2049 SymTab/driver_cfa_cpp-Autogen.obj: SymTab/Autogen.cc
    2050 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SymTab/driver_cfa_cpp-Autogen.obj -MD -MP -MF SymTab/$(DEPDIR)/driver_cfa_cpp-Autogen.Tpo -c -o SymTab/driver_cfa_cpp-Autogen.obj `if test -f 'SymTab/Autogen.cc'; then $(CYGPATH_W) 'SymTab/Autogen.cc'; else $(CYGPATH_W) '$(srcdir)/SymTab/Autogen.cc'; fi`
    2051 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SymTab/$(DEPDIR)/driver_cfa_cpp-Autogen.Tpo SymTab/$(DEPDIR)/driver_cfa_cpp-Autogen.Po
    2052 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SymTab/Autogen.cc' object='SymTab/driver_cfa_cpp-Autogen.obj' libtool=no @AMDEPBACKSLASH@
    2053 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2054 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SymTab/driver_cfa_cpp-Autogen.obj `if test -f 'SymTab/Autogen.cc'; then $(CYGPATH_W) 'SymTab/Autogen.cc'; else $(CYGPATH_W) '$(srcdir)/SymTab/Autogen.cc'; fi`
    2055 
    2056 SynTree/driver_cfa_cpp-Type.o: SynTree/Type.cc
    2057 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-Type.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-Type.Tpo -c -o SynTree/driver_cfa_cpp-Type.o `test -f 'SynTree/Type.cc' || echo '$(srcdir)/'`SynTree/Type.cc
    2058 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-Type.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-Type.Po
    2059 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/Type.cc' object='SynTree/driver_cfa_cpp-Type.o' libtool=no @AMDEPBACKSLASH@
    2060 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2061 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-Type.o `test -f 'SynTree/Type.cc' || echo '$(srcdir)/'`SynTree/Type.cc
    2062 
    2063 SynTree/driver_cfa_cpp-Type.obj: SynTree/Type.cc
    2064 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-Type.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-Type.Tpo -c -o SynTree/driver_cfa_cpp-Type.obj `if test -f 'SynTree/Type.cc'; then $(CYGPATH_W) 'SynTree/Type.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/Type.cc'; fi`
    2065 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-Type.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-Type.Po
    2066 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/Type.cc' object='SynTree/driver_cfa_cpp-Type.obj' libtool=no @AMDEPBACKSLASH@
    2067 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2068 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-Type.obj `if test -f 'SynTree/Type.cc'; then $(CYGPATH_W) 'SynTree/Type.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/Type.cc'; fi`
    2069 
    2070 SynTree/driver_cfa_cpp-VoidType.o: SynTree/VoidType.cc
    2071 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-VoidType.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-VoidType.Tpo -c -o SynTree/driver_cfa_cpp-VoidType.o `test -f 'SynTree/VoidType.cc' || echo '$(srcdir)/'`SynTree/VoidType.cc
    2072 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-VoidType.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-VoidType.Po
    2073 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/VoidType.cc' object='SynTree/driver_cfa_cpp-VoidType.o' libtool=no @AMDEPBACKSLASH@
    2074 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2075 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-VoidType.o `test -f 'SynTree/VoidType.cc' || echo '$(srcdir)/'`SynTree/VoidType.cc
    2076 
    2077 SynTree/driver_cfa_cpp-VoidType.obj: SynTree/VoidType.cc
    2078 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-VoidType.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-VoidType.Tpo -c -o SynTree/driver_cfa_cpp-VoidType.obj `if test -f 'SynTree/VoidType.cc'; then $(CYGPATH_W) 'SynTree/VoidType.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/VoidType.cc'; fi`
    2079 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-VoidType.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-VoidType.Po
    2080 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/VoidType.cc' object='SynTree/driver_cfa_cpp-VoidType.obj' libtool=no @AMDEPBACKSLASH@
    2081 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2082 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-VoidType.obj `if test -f 'SynTree/VoidType.cc'; then $(CYGPATH_W) 'SynTree/VoidType.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/VoidType.cc'; fi`
    2083 
    2084 SynTree/driver_cfa_cpp-BasicType.o: SynTree/BasicType.cc
    2085 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-BasicType.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-BasicType.Tpo -c -o SynTree/driver_cfa_cpp-BasicType.o `test -f 'SynTree/BasicType.cc' || echo '$(srcdir)/'`SynTree/BasicType.cc
    2086 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-BasicType.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-BasicType.Po
    2087 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/BasicType.cc' object='SynTree/driver_cfa_cpp-BasicType.o' libtool=no @AMDEPBACKSLASH@
    2088 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2089 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-BasicType.o `test -f 'SynTree/BasicType.cc' || echo '$(srcdir)/'`SynTree/BasicType.cc
    2090 
    2091 SynTree/driver_cfa_cpp-BasicType.obj: SynTree/BasicType.cc
    2092 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-BasicType.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-BasicType.Tpo -c -o SynTree/driver_cfa_cpp-BasicType.obj `if test -f 'SynTree/BasicType.cc'; then $(CYGPATH_W) 'SynTree/BasicType.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/BasicType.cc'; fi`
    2093 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-BasicType.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-BasicType.Po
    2094 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/BasicType.cc' object='SynTree/driver_cfa_cpp-BasicType.obj' libtool=no @AMDEPBACKSLASH@
    2095 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2096 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-BasicType.obj `if test -f 'SynTree/BasicType.cc'; then $(CYGPATH_W) 'SynTree/BasicType.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/BasicType.cc'; fi`
    2097 
    2098 SynTree/driver_cfa_cpp-PointerType.o: SynTree/PointerType.cc
    2099 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-PointerType.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-PointerType.Tpo -c -o SynTree/driver_cfa_cpp-PointerType.o `test -f 'SynTree/PointerType.cc' || echo '$(srcdir)/'`SynTree/PointerType.cc
    2100 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-PointerType.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-PointerType.Po
    2101 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/PointerType.cc' object='SynTree/driver_cfa_cpp-PointerType.o' libtool=no @AMDEPBACKSLASH@
    2102 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2103 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-PointerType.o `test -f 'SynTree/PointerType.cc' || echo '$(srcdir)/'`SynTree/PointerType.cc
    2104 
    2105 SynTree/driver_cfa_cpp-PointerType.obj: SynTree/PointerType.cc
    2106 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-PointerType.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-PointerType.Tpo -c -o SynTree/driver_cfa_cpp-PointerType.obj `if test -f 'SynTree/PointerType.cc'; then $(CYGPATH_W) 'SynTree/PointerType.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/PointerType.cc'; fi`
    2107 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-PointerType.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-PointerType.Po
    2108 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/PointerType.cc' object='SynTree/driver_cfa_cpp-PointerType.obj' libtool=no @AMDEPBACKSLASH@
    2109 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2110 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-PointerType.obj `if test -f 'SynTree/PointerType.cc'; then $(CYGPATH_W) 'SynTree/PointerType.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/PointerType.cc'; fi`
    2111 
    2112 SynTree/driver_cfa_cpp-ArrayType.o: SynTree/ArrayType.cc
    2113 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-ArrayType.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-ArrayType.Tpo -c -o SynTree/driver_cfa_cpp-ArrayType.o `test -f 'SynTree/ArrayType.cc' || echo '$(srcdir)/'`SynTree/ArrayType.cc
    2114 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-ArrayType.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-ArrayType.Po
    2115 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/ArrayType.cc' object='SynTree/driver_cfa_cpp-ArrayType.o' libtool=no @AMDEPBACKSLASH@
    2116 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2117 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-ArrayType.o `test -f 'SynTree/ArrayType.cc' || echo '$(srcdir)/'`SynTree/ArrayType.cc
    2118 
    2119 SynTree/driver_cfa_cpp-ArrayType.obj: SynTree/ArrayType.cc
    2120 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-ArrayType.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-ArrayType.Tpo -c -o SynTree/driver_cfa_cpp-ArrayType.obj `if test -f 'SynTree/ArrayType.cc'; then $(CYGPATH_W) 'SynTree/ArrayType.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/ArrayType.cc'; fi`
    2121 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-ArrayType.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-ArrayType.Po
    2122 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/ArrayType.cc' object='SynTree/driver_cfa_cpp-ArrayType.obj' libtool=no @AMDEPBACKSLASH@
    2123 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2124 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-ArrayType.obj `if test -f 'SynTree/ArrayType.cc'; then $(CYGPATH_W) 'SynTree/ArrayType.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/ArrayType.cc'; fi`
    2125 
    2126 SynTree/driver_cfa_cpp-ReferenceType.o: SynTree/ReferenceType.cc
    2127 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-ReferenceType.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-ReferenceType.Tpo -c -o SynTree/driver_cfa_cpp-ReferenceType.o `test -f 'SynTree/ReferenceType.cc' || echo '$(srcdir)/'`SynTree/ReferenceType.cc
    2128 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-ReferenceType.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-ReferenceType.Po
    2129 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/ReferenceType.cc' object='SynTree/driver_cfa_cpp-ReferenceType.o' libtool=no @AMDEPBACKSLASH@
    2130 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2131 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-ReferenceType.o `test -f 'SynTree/ReferenceType.cc' || echo '$(srcdir)/'`SynTree/ReferenceType.cc
    2132 
    2133 SynTree/driver_cfa_cpp-ReferenceType.obj: SynTree/ReferenceType.cc
    2134 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-ReferenceType.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-ReferenceType.Tpo -c -o SynTree/driver_cfa_cpp-ReferenceType.obj `if test -f 'SynTree/ReferenceType.cc'; then $(CYGPATH_W) 'SynTree/ReferenceType.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/ReferenceType.cc'; fi`
    2135 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-ReferenceType.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-ReferenceType.Po
    2136 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/ReferenceType.cc' object='SynTree/driver_cfa_cpp-ReferenceType.obj' libtool=no @AMDEPBACKSLASH@
    2137 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2138 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-ReferenceType.obj `if test -f 'SynTree/ReferenceType.cc'; then $(CYGPATH_W) 'SynTree/ReferenceType.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/ReferenceType.cc'; fi`
    2139 
    2140 SynTree/driver_cfa_cpp-FunctionType.o: SynTree/FunctionType.cc
    2141 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-FunctionType.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-FunctionType.Tpo -c -o SynTree/driver_cfa_cpp-FunctionType.o `test -f 'SynTree/FunctionType.cc' || echo '$(srcdir)/'`SynTree/FunctionType.cc
    2142 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-FunctionType.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-FunctionType.Po
    2143 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/FunctionType.cc' object='SynTree/driver_cfa_cpp-FunctionType.o' libtool=no @AMDEPBACKSLASH@
    2144 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2145 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-FunctionType.o `test -f 'SynTree/FunctionType.cc' || echo '$(srcdir)/'`SynTree/FunctionType.cc
    2146 
    2147 SynTree/driver_cfa_cpp-FunctionType.obj: SynTree/FunctionType.cc
    2148 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-FunctionType.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-FunctionType.Tpo -c -o SynTree/driver_cfa_cpp-FunctionType.obj `if test -f 'SynTree/FunctionType.cc'; then $(CYGPATH_W) 'SynTree/FunctionType.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/FunctionType.cc'; fi`
    2149 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-FunctionType.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-FunctionType.Po
    2150 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/FunctionType.cc' object='SynTree/driver_cfa_cpp-FunctionType.obj' libtool=no @AMDEPBACKSLASH@
    2151 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2152 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-FunctionType.obj `if test -f 'SynTree/FunctionType.cc'; then $(CYGPATH_W) 'SynTree/FunctionType.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/FunctionType.cc'; fi`
    2153 
    2154 SynTree/driver_cfa_cpp-ReferenceToType.o: SynTree/ReferenceToType.cc
    2155 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-ReferenceToType.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-ReferenceToType.Tpo -c -o SynTree/driver_cfa_cpp-ReferenceToType.o `test -f 'SynTree/ReferenceToType.cc' || echo '$(srcdir)/'`SynTree/ReferenceToType.cc
    2156 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-ReferenceToType.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-ReferenceToType.Po
    2157 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/ReferenceToType.cc' object='SynTree/driver_cfa_cpp-ReferenceToType.o' libtool=no @AMDEPBACKSLASH@
    2158 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2159 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-ReferenceToType.o `test -f 'SynTree/ReferenceToType.cc' || echo '$(srcdir)/'`SynTree/ReferenceToType.cc
    2160 
    2161 SynTree/driver_cfa_cpp-ReferenceToType.obj: SynTree/ReferenceToType.cc
    2162 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-ReferenceToType.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-ReferenceToType.Tpo -c -o SynTree/driver_cfa_cpp-ReferenceToType.obj `if test -f 'SynTree/ReferenceToType.cc'; then $(CYGPATH_W) 'SynTree/ReferenceToType.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/ReferenceToType.cc'; fi`
    2163 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-ReferenceToType.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-ReferenceToType.Po
    2164 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/ReferenceToType.cc' object='SynTree/driver_cfa_cpp-ReferenceToType.obj' libtool=no @AMDEPBACKSLASH@
    2165 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2166 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-ReferenceToType.obj `if test -f 'SynTree/ReferenceToType.cc'; then $(CYGPATH_W) 'SynTree/ReferenceToType.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/ReferenceToType.cc'; fi`
    2167 
    2168 SynTree/driver_cfa_cpp-TupleType.o: SynTree/TupleType.cc
    2169 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-TupleType.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-TupleType.Tpo -c -o SynTree/driver_cfa_cpp-TupleType.o `test -f 'SynTree/TupleType.cc' || echo '$(srcdir)/'`SynTree/TupleType.cc
    2170 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-TupleType.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-TupleType.Po
    2171 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/TupleType.cc' object='SynTree/driver_cfa_cpp-TupleType.o' libtool=no @AMDEPBACKSLASH@
    2172 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2173 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-TupleType.o `test -f 'SynTree/TupleType.cc' || echo '$(srcdir)/'`SynTree/TupleType.cc
    2174 
    2175 SynTree/driver_cfa_cpp-TupleType.obj: SynTree/TupleType.cc
    2176 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-TupleType.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-TupleType.Tpo -c -o SynTree/driver_cfa_cpp-TupleType.obj `if test -f 'SynTree/TupleType.cc'; then $(CYGPATH_W) 'SynTree/TupleType.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/TupleType.cc'; fi`
    2177 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-TupleType.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-TupleType.Po
    2178 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/TupleType.cc' object='SynTree/driver_cfa_cpp-TupleType.obj' libtool=no @AMDEPBACKSLASH@
    2179 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2180 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-TupleType.obj `if test -f 'SynTree/TupleType.cc'; then $(CYGPATH_W) 'SynTree/TupleType.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/TupleType.cc'; fi`
    2181 
    2182 SynTree/driver_cfa_cpp-TypeofType.o: SynTree/TypeofType.cc
    2183 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-TypeofType.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-TypeofType.Tpo -c -o SynTree/driver_cfa_cpp-TypeofType.o `test -f 'SynTree/TypeofType.cc' || echo '$(srcdir)/'`SynTree/TypeofType.cc
    2184 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-TypeofType.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-TypeofType.Po
    2185 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/TypeofType.cc' object='SynTree/driver_cfa_cpp-TypeofType.o' libtool=no @AMDEPBACKSLASH@
    2186 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2187 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-TypeofType.o `test -f 'SynTree/TypeofType.cc' || echo '$(srcdir)/'`SynTree/TypeofType.cc
    2188 
    2189 SynTree/driver_cfa_cpp-TypeofType.obj: SynTree/TypeofType.cc
    2190 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-TypeofType.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-TypeofType.Tpo -c -o SynTree/driver_cfa_cpp-TypeofType.obj `if test -f 'SynTree/TypeofType.cc'; then $(CYGPATH_W) 'SynTree/TypeofType.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/TypeofType.cc'; fi`
    2191 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-TypeofType.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-TypeofType.Po
    2192 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/TypeofType.cc' object='SynTree/driver_cfa_cpp-TypeofType.obj' libtool=no @AMDEPBACKSLASH@
    2193 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2194 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-TypeofType.obj `if test -f 'SynTree/TypeofType.cc'; then $(CYGPATH_W) 'SynTree/TypeofType.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/TypeofType.cc'; fi`
    2195 
    2196 SynTree/driver_cfa_cpp-AttrType.o: SynTree/AttrType.cc
    2197 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-AttrType.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-AttrType.Tpo -c -o SynTree/driver_cfa_cpp-AttrType.o `test -f 'SynTree/AttrType.cc' || echo '$(srcdir)/'`SynTree/AttrType.cc
    2198 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-AttrType.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-AttrType.Po
    2199 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/AttrType.cc' object='SynTree/driver_cfa_cpp-AttrType.o' libtool=no @AMDEPBACKSLASH@
    2200 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2201 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-AttrType.o `test -f 'SynTree/AttrType.cc' || echo '$(srcdir)/'`SynTree/AttrType.cc
    2202 
    2203 SynTree/driver_cfa_cpp-AttrType.obj: SynTree/AttrType.cc
    2204 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-AttrType.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-AttrType.Tpo -c -o SynTree/driver_cfa_cpp-AttrType.obj `if test -f 'SynTree/AttrType.cc'; then $(CYGPATH_W) 'SynTree/AttrType.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/AttrType.cc'; fi`
    2205 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-AttrType.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-AttrType.Po
    2206 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/AttrType.cc' object='SynTree/driver_cfa_cpp-AttrType.obj' libtool=no @AMDEPBACKSLASH@
    2207 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2208 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-AttrType.obj `if test -f 'SynTree/AttrType.cc'; then $(CYGPATH_W) 'SynTree/AttrType.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/AttrType.cc'; fi`
    2209 
    2210 SynTree/driver_cfa_cpp-VarArgsType.o: SynTree/VarArgsType.cc
    2211 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-VarArgsType.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-VarArgsType.Tpo -c -o SynTree/driver_cfa_cpp-VarArgsType.o `test -f 'SynTree/VarArgsType.cc' || echo '$(srcdir)/'`SynTree/VarArgsType.cc
    2212 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-VarArgsType.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-VarArgsType.Po
    2213 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/VarArgsType.cc' object='SynTree/driver_cfa_cpp-VarArgsType.o' libtool=no @AMDEPBACKSLASH@
    2214 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2215 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-VarArgsType.o `test -f 'SynTree/VarArgsType.cc' || echo '$(srcdir)/'`SynTree/VarArgsType.cc
    2216 
    2217 SynTree/driver_cfa_cpp-VarArgsType.obj: SynTree/VarArgsType.cc
    2218 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-VarArgsType.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-VarArgsType.Tpo -c -o SynTree/driver_cfa_cpp-VarArgsType.obj `if test -f 'SynTree/VarArgsType.cc'; then $(CYGPATH_W) 'SynTree/VarArgsType.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/VarArgsType.cc'; fi`
    2219 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-VarArgsType.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-VarArgsType.Po
    2220 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/VarArgsType.cc' object='SynTree/driver_cfa_cpp-VarArgsType.obj' libtool=no @AMDEPBACKSLASH@
    2221 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2222 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-VarArgsType.obj `if test -f 'SynTree/VarArgsType.cc'; then $(CYGPATH_W) 'SynTree/VarArgsType.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/VarArgsType.cc'; fi`
    2223 
    2224 SynTree/driver_cfa_cpp-ZeroOneType.o: SynTree/ZeroOneType.cc
    2225 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-ZeroOneType.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-ZeroOneType.Tpo -c -o SynTree/driver_cfa_cpp-ZeroOneType.o `test -f 'SynTree/ZeroOneType.cc' || echo '$(srcdir)/'`SynTree/ZeroOneType.cc
    2226 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-ZeroOneType.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-ZeroOneType.Po
    2227 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/ZeroOneType.cc' object='SynTree/driver_cfa_cpp-ZeroOneType.o' libtool=no @AMDEPBACKSLASH@
    2228 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2229 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-ZeroOneType.o `test -f 'SynTree/ZeroOneType.cc' || echo '$(srcdir)/'`SynTree/ZeroOneType.cc
    2230 
    2231 SynTree/driver_cfa_cpp-ZeroOneType.obj: SynTree/ZeroOneType.cc
    2232 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-ZeroOneType.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-ZeroOneType.Tpo -c -o SynTree/driver_cfa_cpp-ZeroOneType.obj `if test -f 'SynTree/ZeroOneType.cc'; then $(CYGPATH_W) 'SynTree/ZeroOneType.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/ZeroOneType.cc'; fi`
    2233 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-ZeroOneType.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-ZeroOneType.Po
    2234 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/ZeroOneType.cc' object='SynTree/driver_cfa_cpp-ZeroOneType.obj' libtool=no @AMDEPBACKSLASH@
    2235 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2236 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-ZeroOneType.obj `if test -f 'SynTree/ZeroOneType.cc'; then $(CYGPATH_W) 'SynTree/ZeroOneType.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/ZeroOneType.cc'; fi`
    2237 
    2238 SynTree/driver_cfa_cpp-Constant.o: SynTree/Constant.cc
    2239 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-Constant.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-Constant.Tpo -c -o SynTree/driver_cfa_cpp-Constant.o `test -f 'SynTree/Constant.cc' || echo '$(srcdir)/'`SynTree/Constant.cc
    2240 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-Constant.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-Constant.Po
    2241 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/Constant.cc' object='SynTree/driver_cfa_cpp-Constant.o' libtool=no @AMDEPBACKSLASH@
    2242 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2243 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-Constant.o `test -f 'SynTree/Constant.cc' || echo '$(srcdir)/'`SynTree/Constant.cc
    2244 
    2245 SynTree/driver_cfa_cpp-Constant.obj: SynTree/Constant.cc
    2246 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-Constant.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-Constant.Tpo -c -o SynTree/driver_cfa_cpp-Constant.obj `if test -f 'SynTree/Constant.cc'; then $(CYGPATH_W) 'SynTree/Constant.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/Constant.cc'; fi`
    2247 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-Constant.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-Constant.Po
    2248 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/Constant.cc' object='SynTree/driver_cfa_cpp-Constant.obj' libtool=no @AMDEPBACKSLASH@
    2249 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2250 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-Constant.obj `if test -f 'SynTree/Constant.cc'; then $(CYGPATH_W) 'SynTree/Constant.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/Constant.cc'; fi`
    2251 
    2252 SynTree/driver_cfa_cpp-Expression.o: SynTree/Expression.cc
    2253 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-Expression.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-Expression.Tpo -c -o SynTree/driver_cfa_cpp-Expression.o `test -f 'SynTree/Expression.cc' || echo '$(srcdir)/'`SynTree/Expression.cc
    2254 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-Expression.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-Expression.Po
    2255 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/Expression.cc' object='SynTree/driver_cfa_cpp-Expression.o' libtool=no @AMDEPBACKSLASH@
    2256 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2257 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-Expression.o `test -f 'SynTree/Expression.cc' || echo '$(srcdir)/'`SynTree/Expression.cc
    2258 
    2259 SynTree/driver_cfa_cpp-Expression.obj: SynTree/Expression.cc
    2260 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-Expression.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-Expression.Tpo -c -o SynTree/driver_cfa_cpp-Expression.obj `if test -f 'SynTree/Expression.cc'; then $(CYGPATH_W) 'SynTree/Expression.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/Expression.cc'; fi`
    2261 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-Expression.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-Expression.Po
    2262 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/Expression.cc' object='SynTree/driver_cfa_cpp-Expression.obj' libtool=no @AMDEPBACKSLASH@
    2263 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2264 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-Expression.obj `if test -f 'SynTree/Expression.cc'; then $(CYGPATH_W) 'SynTree/Expression.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/Expression.cc'; fi`
    2265 
    2266 SynTree/driver_cfa_cpp-TupleExpr.o: SynTree/TupleExpr.cc
    2267 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-TupleExpr.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-TupleExpr.Tpo -c -o SynTree/driver_cfa_cpp-TupleExpr.o `test -f 'SynTree/TupleExpr.cc' || echo '$(srcdir)/'`SynTree/TupleExpr.cc
    2268 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-TupleExpr.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-TupleExpr.Po
    2269 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/TupleExpr.cc' object='SynTree/driver_cfa_cpp-TupleExpr.o' libtool=no @AMDEPBACKSLASH@
    2270 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2271 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-TupleExpr.o `test -f 'SynTree/TupleExpr.cc' || echo '$(srcdir)/'`SynTree/TupleExpr.cc
    2272 
    2273 SynTree/driver_cfa_cpp-TupleExpr.obj: SynTree/TupleExpr.cc
    2274 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-TupleExpr.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-TupleExpr.Tpo -c -o SynTree/driver_cfa_cpp-TupleExpr.obj `if test -f 'SynTree/TupleExpr.cc'; then $(CYGPATH_W) 'SynTree/TupleExpr.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/TupleExpr.cc'; fi`
    2275 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-TupleExpr.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-TupleExpr.Po
    2276 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/TupleExpr.cc' object='SynTree/driver_cfa_cpp-TupleExpr.obj' libtool=no @AMDEPBACKSLASH@
    2277 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2278 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-TupleExpr.obj `if test -f 'SynTree/TupleExpr.cc'; then $(CYGPATH_W) 'SynTree/TupleExpr.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/TupleExpr.cc'; fi`
    2279 
    2280 SynTree/driver_cfa_cpp-CommaExpr.o: SynTree/CommaExpr.cc
    2281 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-CommaExpr.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-CommaExpr.Tpo -c -o SynTree/driver_cfa_cpp-CommaExpr.o `test -f 'SynTree/CommaExpr.cc' || echo '$(srcdir)/'`SynTree/CommaExpr.cc
    2282 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-CommaExpr.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-CommaExpr.Po
    2283 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/CommaExpr.cc' object='SynTree/driver_cfa_cpp-CommaExpr.o' libtool=no @AMDEPBACKSLASH@
    2284 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2285 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-CommaExpr.o `test -f 'SynTree/CommaExpr.cc' || echo '$(srcdir)/'`SynTree/CommaExpr.cc
    2286 
    2287 SynTree/driver_cfa_cpp-CommaExpr.obj: SynTree/CommaExpr.cc
    2288 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-CommaExpr.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-CommaExpr.Tpo -c -o SynTree/driver_cfa_cpp-CommaExpr.obj `if test -f 'SynTree/CommaExpr.cc'; then $(CYGPATH_W) 'SynTree/CommaExpr.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/CommaExpr.cc'; fi`
    2289 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-CommaExpr.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-CommaExpr.Po
    2290 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/CommaExpr.cc' object='SynTree/driver_cfa_cpp-CommaExpr.obj' libtool=no @AMDEPBACKSLASH@
    2291 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2292 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-CommaExpr.obj `if test -f 'SynTree/CommaExpr.cc'; then $(CYGPATH_W) 'SynTree/CommaExpr.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/CommaExpr.cc'; fi`
    2293 
    2294 SynTree/driver_cfa_cpp-TypeExpr.o: SynTree/TypeExpr.cc
    2295 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-TypeExpr.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-TypeExpr.Tpo -c -o SynTree/driver_cfa_cpp-TypeExpr.o `test -f 'SynTree/TypeExpr.cc' || echo '$(srcdir)/'`SynTree/TypeExpr.cc
    2296 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-TypeExpr.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-TypeExpr.Po
    2297 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/TypeExpr.cc' object='SynTree/driver_cfa_cpp-TypeExpr.o' libtool=no @AMDEPBACKSLASH@
    2298 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2299 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-TypeExpr.o `test -f 'SynTree/TypeExpr.cc' || echo '$(srcdir)/'`SynTree/TypeExpr.cc
    2300 
    2301 SynTree/driver_cfa_cpp-TypeExpr.obj: SynTree/TypeExpr.cc
    2302 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-TypeExpr.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-TypeExpr.Tpo -c -o SynTree/driver_cfa_cpp-TypeExpr.obj `if test -f 'SynTree/TypeExpr.cc'; then $(CYGPATH_W) 'SynTree/TypeExpr.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/TypeExpr.cc'; fi`
    2303 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-TypeExpr.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-TypeExpr.Po
    2304 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/TypeExpr.cc' object='SynTree/driver_cfa_cpp-TypeExpr.obj' libtool=no @AMDEPBACKSLASH@
    2305 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2306 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-TypeExpr.obj `if test -f 'SynTree/TypeExpr.cc'; then $(CYGPATH_W) 'SynTree/TypeExpr.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/TypeExpr.cc'; fi`
    2307 
    2308 SynTree/driver_cfa_cpp-ApplicationExpr.o: SynTree/ApplicationExpr.cc
    2309 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-ApplicationExpr.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-ApplicationExpr.Tpo -c -o SynTree/driver_cfa_cpp-ApplicationExpr.o `test -f 'SynTree/ApplicationExpr.cc' || echo '$(srcdir)/'`SynTree/ApplicationExpr.cc
    2310 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-ApplicationExpr.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-ApplicationExpr.Po
    2311 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/ApplicationExpr.cc' object='SynTree/driver_cfa_cpp-ApplicationExpr.o' libtool=no @AMDEPBACKSLASH@
    2312 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2313 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-ApplicationExpr.o `test -f 'SynTree/ApplicationExpr.cc' || echo '$(srcdir)/'`SynTree/ApplicationExpr.cc
    2314 
    2315 SynTree/driver_cfa_cpp-ApplicationExpr.obj: SynTree/ApplicationExpr.cc
    2316 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-ApplicationExpr.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-ApplicationExpr.Tpo -c -o SynTree/driver_cfa_cpp-ApplicationExpr.obj `if test -f 'SynTree/ApplicationExpr.cc'; then $(CYGPATH_W) 'SynTree/ApplicationExpr.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/ApplicationExpr.cc'; fi`
    2317 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-ApplicationExpr.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-ApplicationExpr.Po
    2318 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/ApplicationExpr.cc' object='SynTree/driver_cfa_cpp-ApplicationExpr.obj' libtool=no @AMDEPBACKSLASH@
    2319 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2320 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-ApplicationExpr.obj `if test -f 'SynTree/ApplicationExpr.cc'; then $(CYGPATH_W) 'SynTree/ApplicationExpr.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/ApplicationExpr.cc'; fi`
    2321 
    2322 SynTree/driver_cfa_cpp-AddressExpr.o: SynTree/AddressExpr.cc
    2323 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-AddressExpr.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-AddressExpr.Tpo -c -o SynTree/driver_cfa_cpp-AddressExpr.o `test -f 'SynTree/AddressExpr.cc' || echo '$(srcdir)/'`SynTree/AddressExpr.cc
    2324 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-AddressExpr.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-AddressExpr.Po
    2325 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/AddressExpr.cc' object='SynTree/driver_cfa_cpp-AddressExpr.o' libtool=no @AMDEPBACKSLASH@
    2326 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2327 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-AddressExpr.o `test -f 'SynTree/AddressExpr.cc' || echo '$(srcdir)/'`SynTree/AddressExpr.cc
    2328 
    2329 SynTree/driver_cfa_cpp-AddressExpr.obj: SynTree/AddressExpr.cc
    2330 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-AddressExpr.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-AddressExpr.Tpo -c -o SynTree/driver_cfa_cpp-AddressExpr.obj `if test -f 'SynTree/AddressExpr.cc'; then $(CYGPATH_W) 'SynTree/AddressExpr.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/AddressExpr.cc'; fi`
    2331 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-AddressExpr.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-AddressExpr.Po
    2332 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/AddressExpr.cc' object='SynTree/driver_cfa_cpp-AddressExpr.obj' libtool=no @AMDEPBACKSLASH@
    2333 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2334 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-AddressExpr.obj `if test -f 'SynTree/AddressExpr.cc'; then $(CYGPATH_W) 'SynTree/AddressExpr.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/AddressExpr.cc'; fi`
    2335 
    2336 SynTree/driver_cfa_cpp-Statement.o: SynTree/Statement.cc
    2337 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-Statement.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-Statement.Tpo -c -o SynTree/driver_cfa_cpp-Statement.o `test -f 'SynTree/Statement.cc' || echo '$(srcdir)/'`SynTree/Statement.cc
    2338 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-Statement.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-Statement.Po
    2339 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/Statement.cc' object='SynTree/driver_cfa_cpp-Statement.o' libtool=no @AMDEPBACKSLASH@
    2340 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2341 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-Statement.o `test -f 'SynTree/Statement.cc' || echo '$(srcdir)/'`SynTree/Statement.cc
    2342 
    2343 SynTree/driver_cfa_cpp-Statement.obj: SynTree/Statement.cc
    2344 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-Statement.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-Statement.Tpo -c -o SynTree/driver_cfa_cpp-Statement.obj `if test -f 'SynTree/Statement.cc'; then $(CYGPATH_W) 'SynTree/Statement.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/Statement.cc'; fi`
    2345 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-Statement.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-Statement.Po
    2346 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/Statement.cc' object='SynTree/driver_cfa_cpp-Statement.obj' libtool=no @AMDEPBACKSLASH@
    2347 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2348 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-Statement.obj `if test -f 'SynTree/Statement.cc'; then $(CYGPATH_W) 'SynTree/Statement.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/Statement.cc'; fi`
    2349 
    2350 SynTree/driver_cfa_cpp-CompoundStmt.o: SynTree/CompoundStmt.cc
    2351 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-CompoundStmt.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-CompoundStmt.Tpo -c -o SynTree/driver_cfa_cpp-CompoundStmt.o `test -f 'SynTree/CompoundStmt.cc' || echo '$(srcdir)/'`SynTree/CompoundStmt.cc
    2352 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-CompoundStmt.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-CompoundStmt.Po
    2353 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/CompoundStmt.cc' object='SynTree/driver_cfa_cpp-CompoundStmt.o' libtool=no @AMDEPBACKSLASH@
    2354 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2355 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-CompoundStmt.o `test -f 'SynTree/CompoundStmt.cc' || echo '$(srcdir)/'`SynTree/CompoundStmt.cc
    2356 
    2357 SynTree/driver_cfa_cpp-CompoundStmt.obj: SynTree/CompoundStmt.cc
    2358 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-CompoundStmt.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-CompoundStmt.Tpo -c -o SynTree/driver_cfa_cpp-CompoundStmt.obj `if test -f 'SynTree/CompoundStmt.cc'; then $(CYGPATH_W) 'SynTree/CompoundStmt.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/CompoundStmt.cc'; fi`
    2359 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-CompoundStmt.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-CompoundStmt.Po
    2360 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/CompoundStmt.cc' object='SynTree/driver_cfa_cpp-CompoundStmt.obj' libtool=no @AMDEPBACKSLASH@
    2361 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2362 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-CompoundStmt.obj `if test -f 'SynTree/CompoundStmt.cc'; then $(CYGPATH_W) 'SynTree/CompoundStmt.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/CompoundStmt.cc'; fi`
    2363 
    2364 SynTree/driver_cfa_cpp-DeclStmt.o: SynTree/DeclStmt.cc
    2365 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-DeclStmt.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-DeclStmt.Tpo -c -o SynTree/driver_cfa_cpp-DeclStmt.o `test -f 'SynTree/DeclStmt.cc' || echo '$(srcdir)/'`SynTree/DeclStmt.cc
    2366 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-DeclStmt.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-DeclStmt.Po
    2367 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/DeclStmt.cc' object='SynTree/driver_cfa_cpp-DeclStmt.o' libtool=no @AMDEPBACKSLASH@
    2368 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2369 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-DeclStmt.o `test -f 'SynTree/DeclStmt.cc' || echo '$(srcdir)/'`SynTree/DeclStmt.cc
    2370 
    2371 SynTree/driver_cfa_cpp-DeclStmt.obj: SynTree/DeclStmt.cc
    2372 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-DeclStmt.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-DeclStmt.Tpo -c -o SynTree/driver_cfa_cpp-DeclStmt.obj `if test -f 'SynTree/DeclStmt.cc'; then $(CYGPATH_W) 'SynTree/DeclStmt.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/DeclStmt.cc'; fi`
    2373 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-DeclStmt.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-DeclStmt.Po
    2374 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/DeclStmt.cc' object='SynTree/driver_cfa_cpp-DeclStmt.obj' libtool=no @AMDEPBACKSLASH@
    2375 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2376 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-DeclStmt.obj `if test -f 'SynTree/DeclStmt.cc'; then $(CYGPATH_W) 'SynTree/DeclStmt.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/DeclStmt.cc'; fi`
    2377 
    2378 SynTree/driver_cfa_cpp-Declaration.o: SynTree/Declaration.cc
    2379 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-Declaration.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-Declaration.Tpo -c -o SynTree/driver_cfa_cpp-Declaration.o `test -f 'SynTree/Declaration.cc' || echo '$(srcdir)/'`SynTree/Declaration.cc
    2380 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-Declaration.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-Declaration.Po
    2381 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/Declaration.cc' object='SynTree/driver_cfa_cpp-Declaration.o' libtool=no @AMDEPBACKSLASH@
    2382 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2383 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-Declaration.o `test -f 'SynTree/Declaration.cc' || echo '$(srcdir)/'`SynTree/Declaration.cc
    2384 
    2385 SynTree/driver_cfa_cpp-Declaration.obj: SynTree/Declaration.cc
    2386 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-Declaration.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-Declaration.Tpo -c -o SynTree/driver_cfa_cpp-Declaration.obj `if test -f 'SynTree/Declaration.cc'; then $(CYGPATH_W) 'SynTree/Declaration.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/Declaration.cc'; fi`
    2387 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-Declaration.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-Declaration.Po
    2388 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/Declaration.cc' object='SynTree/driver_cfa_cpp-Declaration.obj' libtool=no @AMDEPBACKSLASH@
    2389 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2390 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-Declaration.obj `if test -f 'SynTree/Declaration.cc'; then $(CYGPATH_W) 'SynTree/Declaration.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/Declaration.cc'; fi`
    2391 
    2392 SynTree/driver_cfa_cpp-DeclarationWithType.o: SynTree/DeclarationWithType.cc
    2393 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-DeclarationWithType.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-DeclarationWithType.Tpo -c -o SynTree/driver_cfa_cpp-DeclarationWithType.o `test -f 'SynTree/DeclarationWithType.cc' || echo '$(srcdir)/'`SynTree/DeclarationWithType.cc
    2394 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-DeclarationWithType.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-DeclarationWithType.Po
    2395 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/DeclarationWithType.cc' object='SynTree/driver_cfa_cpp-DeclarationWithType.o' libtool=no @AMDEPBACKSLASH@
    2396 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2397 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-DeclarationWithType.o `test -f 'SynTree/DeclarationWithType.cc' || echo '$(srcdir)/'`SynTree/DeclarationWithType.cc
    2398 
    2399 SynTree/driver_cfa_cpp-DeclarationWithType.obj: SynTree/DeclarationWithType.cc
    2400 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-DeclarationWithType.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-DeclarationWithType.Tpo -c -o SynTree/driver_cfa_cpp-DeclarationWithType.obj `if test -f 'SynTree/DeclarationWithType.cc'; then $(CYGPATH_W) 'SynTree/DeclarationWithType.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/DeclarationWithType.cc'; fi`
    2401 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-DeclarationWithType.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-DeclarationWithType.Po
    2402 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/DeclarationWithType.cc' object='SynTree/driver_cfa_cpp-DeclarationWithType.obj' libtool=no @AMDEPBACKSLASH@
    2403 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2404 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-DeclarationWithType.obj `if test -f 'SynTree/DeclarationWithType.cc'; then $(CYGPATH_W) 'SynTree/DeclarationWithType.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/DeclarationWithType.cc'; fi`
    2405 
    2406 SynTree/driver_cfa_cpp-ObjectDecl.o: SynTree/ObjectDecl.cc
    2407 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-ObjectDecl.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-ObjectDecl.Tpo -c -o SynTree/driver_cfa_cpp-ObjectDecl.o `test -f 'SynTree/ObjectDecl.cc' || echo '$(srcdir)/'`SynTree/ObjectDecl.cc
    2408 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-ObjectDecl.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-ObjectDecl.Po
    2409 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/ObjectDecl.cc' object='SynTree/driver_cfa_cpp-ObjectDecl.o' libtool=no @AMDEPBACKSLASH@
    2410 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2411 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-ObjectDecl.o `test -f 'SynTree/ObjectDecl.cc' || echo '$(srcdir)/'`SynTree/ObjectDecl.cc
    2412 
    2413 SynTree/driver_cfa_cpp-ObjectDecl.obj: SynTree/ObjectDecl.cc
    2414 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-ObjectDecl.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-ObjectDecl.Tpo -c -o SynTree/driver_cfa_cpp-ObjectDecl.obj `if test -f 'SynTree/ObjectDecl.cc'; then $(CYGPATH_W) 'SynTree/ObjectDecl.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/ObjectDecl.cc'; fi`
    2415 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-ObjectDecl.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-ObjectDecl.Po
    2416 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/ObjectDecl.cc' object='SynTree/driver_cfa_cpp-ObjectDecl.obj' libtool=no @AMDEPBACKSLASH@
    2417 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2418 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-ObjectDecl.obj `if test -f 'SynTree/ObjectDecl.cc'; then $(CYGPATH_W) 'SynTree/ObjectDecl.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/ObjectDecl.cc'; fi`
    2419 
    2420 SynTree/driver_cfa_cpp-FunctionDecl.o: SynTree/FunctionDecl.cc
    2421 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-FunctionDecl.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-FunctionDecl.Tpo -c -o SynTree/driver_cfa_cpp-FunctionDecl.o `test -f 'SynTree/FunctionDecl.cc' || echo '$(srcdir)/'`SynTree/FunctionDecl.cc
    2422 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-FunctionDecl.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-FunctionDecl.Po
    2423 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/FunctionDecl.cc' object='SynTree/driver_cfa_cpp-FunctionDecl.o' libtool=no @AMDEPBACKSLASH@
    2424 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2425 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-FunctionDecl.o `test -f 'SynTree/FunctionDecl.cc' || echo '$(srcdir)/'`SynTree/FunctionDecl.cc
    2426 
    2427 SynTree/driver_cfa_cpp-FunctionDecl.obj: SynTree/FunctionDecl.cc
    2428 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-FunctionDecl.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-FunctionDecl.Tpo -c -o SynTree/driver_cfa_cpp-FunctionDecl.obj `if test -f 'SynTree/FunctionDecl.cc'; then $(CYGPATH_W) 'SynTree/FunctionDecl.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/FunctionDecl.cc'; fi`
    2429 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-FunctionDecl.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-FunctionDecl.Po
    2430 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/FunctionDecl.cc' object='SynTree/driver_cfa_cpp-FunctionDecl.obj' libtool=no @AMDEPBACKSLASH@
    2431 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2432 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-FunctionDecl.obj `if test -f 'SynTree/FunctionDecl.cc'; then $(CYGPATH_W) 'SynTree/FunctionDecl.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/FunctionDecl.cc'; fi`
    2433 
    2434 SynTree/driver_cfa_cpp-AggregateDecl.o: SynTree/AggregateDecl.cc
    2435 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-AggregateDecl.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-AggregateDecl.Tpo -c -o SynTree/driver_cfa_cpp-AggregateDecl.o `test -f 'SynTree/AggregateDecl.cc' || echo '$(srcdir)/'`SynTree/AggregateDecl.cc
    2436 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-AggregateDecl.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-AggregateDecl.Po
    2437 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/AggregateDecl.cc' object='SynTree/driver_cfa_cpp-AggregateDecl.o' libtool=no @AMDEPBACKSLASH@
    2438 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2439 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-AggregateDecl.o `test -f 'SynTree/AggregateDecl.cc' || echo '$(srcdir)/'`SynTree/AggregateDecl.cc
    2440 
    2441 SynTree/driver_cfa_cpp-AggregateDecl.obj: SynTree/AggregateDecl.cc
    2442 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-AggregateDecl.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-AggregateDecl.Tpo -c -o SynTree/driver_cfa_cpp-AggregateDecl.obj `if test -f 'SynTree/AggregateDecl.cc'; then $(CYGPATH_W) 'SynTree/AggregateDecl.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/AggregateDecl.cc'; fi`
    2443 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-AggregateDecl.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-AggregateDecl.Po
    2444 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/AggregateDecl.cc' object='SynTree/driver_cfa_cpp-AggregateDecl.obj' libtool=no @AMDEPBACKSLASH@
    2445 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2446 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-AggregateDecl.obj `if test -f 'SynTree/AggregateDecl.cc'; then $(CYGPATH_W) 'SynTree/AggregateDecl.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/AggregateDecl.cc'; fi`
    2447 
    2448 SynTree/driver_cfa_cpp-NamedTypeDecl.o: SynTree/NamedTypeDecl.cc
    2449 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-NamedTypeDecl.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-NamedTypeDecl.Tpo -c -o SynTree/driver_cfa_cpp-NamedTypeDecl.o `test -f 'SynTree/NamedTypeDecl.cc' || echo '$(srcdir)/'`SynTree/NamedTypeDecl.cc
    2450 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-NamedTypeDecl.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-NamedTypeDecl.Po
    2451 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/NamedTypeDecl.cc' object='SynTree/driver_cfa_cpp-NamedTypeDecl.o' libtool=no @AMDEPBACKSLASH@
    2452 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2453 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-NamedTypeDecl.o `test -f 'SynTree/NamedTypeDecl.cc' || echo '$(srcdir)/'`SynTree/NamedTypeDecl.cc
    2454 
    2455 SynTree/driver_cfa_cpp-NamedTypeDecl.obj: SynTree/NamedTypeDecl.cc
    2456 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-NamedTypeDecl.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-NamedTypeDecl.Tpo -c -o SynTree/driver_cfa_cpp-NamedTypeDecl.obj `if test -f 'SynTree/NamedTypeDecl.cc'; then $(CYGPATH_W) 'SynTree/NamedTypeDecl.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/NamedTypeDecl.cc'; fi`
    2457 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-NamedTypeDecl.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-NamedTypeDecl.Po
    2458 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/NamedTypeDecl.cc' object='SynTree/driver_cfa_cpp-NamedTypeDecl.obj' libtool=no @AMDEPBACKSLASH@
    2459 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2460 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-NamedTypeDecl.obj `if test -f 'SynTree/NamedTypeDecl.cc'; then $(CYGPATH_W) 'SynTree/NamedTypeDecl.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/NamedTypeDecl.cc'; fi`
    2461 
    2462 SynTree/driver_cfa_cpp-TypeDecl.o: SynTree/TypeDecl.cc
    2463 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-TypeDecl.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-TypeDecl.Tpo -c -o SynTree/driver_cfa_cpp-TypeDecl.o `test -f 'SynTree/TypeDecl.cc' || echo '$(srcdir)/'`SynTree/TypeDecl.cc
    2464 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-TypeDecl.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-TypeDecl.Po
    2465 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/TypeDecl.cc' object='SynTree/driver_cfa_cpp-TypeDecl.o' libtool=no @AMDEPBACKSLASH@
    2466 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2467 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-TypeDecl.o `test -f 'SynTree/TypeDecl.cc' || echo '$(srcdir)/'`SynTree/TypeDecl.cc
    2468 
    2469 SynTree/driver_cfa_cpp-TypeDecl.obj: SynTree/TypeDecl.cc
    2470 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-TypeDecl.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-TypeDecl.Tpo -c -o SynTree/driver_cfa_cpp-TypeDecl.obj `if test -f 'SynTree/TypeDecl.cc'; then $(CYGPATH_W) 'SynTree/TypeDecl.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/TypeDecl.cc'; fi`
    2471 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-TypeDecl.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-TypeDecl.Po
    2472 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/TypeDecl.cc' object='SynTree/driver_cfa_cpp-TypeDecl.obj' libtool=no @AMDEPBACKSLASH@
    2473 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2474 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-TypeDecl.obj `if test -f 'SynTree/TypeDecl.cc'; then $(CYGPATH_W) 'SynTree/TypeDecl.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/TypeDecl.cc'; fi`
    2475 
    2476 SynTree/driver_cfa_cpp-Initializer.o: SynTree/Initializer.cc
    2477 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-Initializer.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-Initializer.Tpo -c -o SynTree/driver_cfa_cpp-Initializer.o `test -f 'SynTree/Initializer.cc' || echo '$(srcdir)/'`SynTree/Initializer.cc
    2478 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-Initializer.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-Initializer.Po
    2479 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/Initializer.cc' object='SynTree/driver_cfa_cpp-Initializer.o' libtool=no @AMDEPBACKSLASH@
    2480 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2481 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-Initializer.o `test -f 'SynTree/Initializer.cc' || echo '$(srcdir)/'`SynTree/Initializer.cc
    2482 
    2483 SynTree/driver_cfa_cpp-Initializer.obj: SynTree/Initializer.cc
    2484 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-Initializer.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-Initializer.Tpo -c -o SynTree/driver_cfa_cpp-Initializer.obj `if test -f 'SynTree/Initializer.cc'; then $(CYGPATH_W) 'SynTree/Initializer.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/Initializer.cc'; fi`
    2485 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-Initializer.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-Initializer.Po
    2486 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/Initializer.cc' object='SynTree/driver_cfa_cpp-Initializer.obj' libtool=no @AMDEPBACKSLASH@
    2487 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2488 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-Initializer.obj `if test -f 'SynTree/Initializer.cc'; then $(CYGPATH_W) 'SynTree/Initializer.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/Initializer.cc'; fi`
    2489 
    2490 SynTree/driver_cfa_cpp-TypeSubstitution.o: SynTree/TypeSubstitution.cc
    2491 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-TypeSubstitution.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-TypeSubstitution.Tpo -c -o SynTree/driver_cfa_cpp-TypeSubstitution.o `test -f 'SynTree/TypeSubstitution.cc' || echo '$(srcdir)/'`SynTree/TypeSubstitution.cc
    2492 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-TypeSubstitution.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-TypeSubstitution.Po
    2493 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/TypeSubstitution.cc' object='SynTree/driver_cfa_cpp-TypeSubstitution.o' libtool=no @AMDEPBACKSLASH@
    2494 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2495 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-TypeSubstitution.o `test -f 'SynTree/TypeSubstitution.cc' || echo '$(srcdir)/'`SynTree/TypeSubstitution.cc
    2496 
    2497 SynTree/driver_cfa_cpp-TypeSubstitution.obj: SynTree/TypeSubstitution.cc
    2498 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-TypeSubstitution.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-TypeSubstitution.Tpo -c -o SynTree/driver_cfa_cpp-TypeSubstitution.obj `if test -f 'SynTree/TypeSubstitution.cc'; then $(CYGPATH_W) 'SynTree/TypeSubstitution.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/TypeSubstitution.cc'; fi`
    2499 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-TypeSubstitution.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-TypeSubstitution.Po
    2500 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/TypeSubstitution.cc' object='SynTree/driver_cfa_cpp-TypeSubstitution.obj' libtool=no @AMDEPBACKSLASH@
    2501 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2502 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-TypeSubstitution.obj `if test -f 'SynTree/TypeSubstitution.cc'; then $(CYGPATH_W) 'SynTree/TypeSubstitution.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/TypeSubstitution.cc'; fi`
    2503 
    2504 SynTree/driver_cfa_cpp-Attribute.o: SynTree/Attribute.cc
    2505 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-Attribute.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-Attribute.Tpo -c -o SynTree/driver_cfa_cpp-Attribute.o `test -f 'SynTree/Attribute.cc' || echo '$(srcdir)/'`SynTree/Attribute.cc
    2506 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-Attribute.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-Attribute.Po
    2507 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/Attribute.cc' object='SynTree/driver_cfa_cpp-Attribute.o' libtool=no @AMDEPBACKSLASH@
    2508 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2509 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-Attribute.o `test -f 'SynTree/Attribute.cc' || echo '$(srcdir)/'`SynTree/Attribute.cc
    2510 
    2511 SynTree/driver_cfa_cpp-Attribute.obj: SynTree/Attribute.cc
    2512 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-Attribute.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-Attribute.Tpo -c -o SynTree/driver_cfa_cpp-Attribute.obj `if test -f 'SynTree/Attribute.cc'; then $(CYGPATH_W) 'SynTree/Attribute.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/Attribute.cc'; fi`
    2513 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-Attribute.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-Attribute.Po
    2514 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/Attribute.cc' object='SynTree/driver_cfa_cpp-Attribute.obj' libtool=no @AMDEPBACKSLASH@
    2515 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2516 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-Attribute.obj `if test -f 'SynTree/Attribute.cc'; then $(CYGPATH_W) 'SynTree/Attribute.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/Attribute.cc'; fi`
    2517 
    2518 SynTree/driver_cfa_cpp-DeclReplacer.o: SynTree/DeclReplacer.cc
    2519 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-DeclReplacer.o -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-DeclReplacer.Tpo -c -o SynTree/driver_cfa_cpp-DeclReplacer.o `test -f 'SynTree/DeclReplacer.cc' || echo '$(srcdir)/'`SynTree/DeclReplacer.cc
    2520 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-DeclReplacer.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-DeclReplacer.Po
    2521 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/DeclReplacer.cc' object='SynTree/driver_cfa_cpp-DeclReplacer.o' libtool=no @AMDEPBACKSLASH@
    2522 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2523 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-DeclReplacer.o `test -f 'SynTree/DeclReplacer.cc' || echo '$(srcdir)/'`SynTree/DeclReplacer.cc
    2524 
    2525 SynTree/driver_cfa_cpp-DeclReplacer.obj: SynTree/DeclReplacer.cc
    2526 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SynTree/driver_cfa_cpp-DeclReplacer.obj -MD -MP -MF SynTree/$(DEPDIR)/driver_cfa_cpp-DeclReplacer.Tpo -c -o SynTree/driver_cfa_cpp-DeclReplacer.obj `if test -f 'SynTree/DeclReplacer.cc'; then $(CYGPATH_W) 'SynTree/DeclReplacer.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/DeclReplacer.cc'; fi`
    2527 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) SynTree/$(DEPDIR)/driver_cfa_cpp-DeclReplacer.Tpo SynTree/$(DEPDIR)/driver_cfa_cpp-DeclReplacer.Po
    2528 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='SynTree/DeclReplacer.cc' object='SynTree/driver_cfa_cpp-DeclReplacer.obj' libtool=no @AMDEPBACKSLASH@
    2529 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2530 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SynTree/driver_cfa_cpp-DeclReplacer.obj `if test -f 'SynTree/DeclReplacer.cc'; then $(CYGPATH_W) 'SynTree/DeclReplacer.cc'; else $(CYGPATH_W) '$(srcdir)/SynTree/DeclReplacer.cc'; fi`
    2531 
    2532 Tuples/driver_cfa_cpp-TupleAssignment.o: Tuples/TupleAssignment.cc
    2533 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Tuples/driver_cfa_cpp-TupleAssignment.o -MD -MP -MF Tuples/$(DEPDIR)/driver_cfa_cpp-TupleAssignment.Tpo -c -o Tuples/driver_cfa_cpp-TupleAssignment.o `test -f 'Tuples/TupleAssignment.cc' || echo '$(srcdir)/'`Tuples/TupleAssignment.cc
    2534 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) Tuples/$(DEPDIR)/driver_cfa_cpp-TupleAssignment.Tpo Tuples/$(DEPDIR)/driver_cfa_cpp-TupleAssignment.Po
    2535 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='Tuples/TupleAssignment.cc' object='Tuples/driver_cfa_cpp-TupleAssignment.o' libtool=no @AMDEPBACKSLASH@
    2536 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2537 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Tuples/driver_cfa_cpp-TupleAssignment.o `test -f 'Tuples/TupleAssignment.cc' || echo '$(srcdir)/'`Tuples/TupleAssignment.cc
    2538 
    2539 Tuples/driver_cfa_cpp-TupleAssignment.obj: Tuples/TupleAssignment.cc
    2540 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Tuples/driver_cfa_cpp-TupleAssignment.obj -MD -MP -MF Tuples/$(DEPDIR)/driver_cfa_cpp-TupleAssignment.Tpo -c -o Tuples/driver_cfa_cpp-TupleAssignment.obj `if test -f 'Tuples/TupleAssignment.cc'; then $(CYGPATH_W) 'Tuples/TupleAssignment.cc'; else $(CYGPATH_W) '$(srcdir)/Tuples/TupleAssignment.cc'; fi`
    2541 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) Tuples/$(DEPDIR)/driver_cfa_cpp-TupleAssignment.Tpo Tuples/$(DEPDIR)/driver_cfa_cpp-TupleAssignment.Po
    2542 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='Tuples/TupleAssignment.cc' object='Tuples/driver_cfa_cpp-TupleAssignment.obj' libtool=no @AMDEPBACKSLASH@
    2543 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2544 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Tuples/driver_cfa_cpp-TupleAssignment.obj `if test -f 'Tuples/TupleAssignment.cc'; then $(CYGPATH_W) 'Tuples/TupleAssignment.cc'; else $(CYGPATH_W) '$(srcdir)/Tuples/TupleAssignment.cc'; fi`
    2545 
    2546 Tuples/driver_cfa_cpp-TupleExpansion.o: Tuples/TupleExpansion.cc
    2547 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Tuples/driver_cfa_cpp-TupleExpansion.o -MD -MP -MF Tuples/$(DEPDIR)/driver_cfa_cpp-TupleExpansion.Tpo -c -o Tuples/driver_cfa_cpp-TupleExpansion.o `test -f 'Tuples/TupleExpansion.cc' || echo '$(srcdir)/'`Tuples/TupleExpansion.cc
    2548 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) Tuples/$(DEPDIR)/driver_cfa_cpp-TupleExpansion.Tpo Tuples/$(DEPDIR)/driver_cfa_cpp-TupleExpansion.Po
    2549 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='Tuples/TupleExpansion.cc' object='Tuples/driver_cfa_cpp-TupleExpansion.o' libtool=no @AMDEPBACKSLASH@
    2550 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2551 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Tuples/driver_cfa_cpp-TupleExpansion.o `test -f 'Tuples/TupleExpansion.cc' || echo '$(srcdir)/'`Tuples/TupleExpansion.cc
    2552 
    2553 Tuples/driver_cfa_cpp-TupleExpansion.obj: Tuples/TupleExpansion.cc
    2554 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Tuples/driver_cfa_cpp-TupleExpansion.obj -MD -MP -MF Tuples/$(DEPDIR)/driver_cfa_cpp-TupleExpansion.Tpo -c -o Tuples/driver_cfa_cpp-TupleExpansion.obj `if test -f 'Tuples/TupleExpansion.cc'; then $(CYGPATH_W) 'Tuples/TupleExpansion.cc'; else $(CYGPATH_W) '$(srcdir)/Tuples/TupleExpansion.cc'; fi`
    2555 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) Tuples/$(DEPDIR)/driver_cfa_cpp-TupleExpansion.Tpo Tuples/$(DEPDIR)/driver_cfa_cpp-TupleExpansion.Po
    2556 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='Tuples/TupleExpansion.cc' object='Tuples/driver_cfa_cpp-TupleExpansion.obj' libtool=no @AMDEPBACKSLASH@
    2557 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2558 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Tuples/driver_cfa_cpp-TupleExpansion.obj `if test -f 'Tuples/TupleExpansion.cc'; then $(CYGPATH_W) 'Tuples/TupleExpansion.cc'; else $(CYGPATH_W) '$(srcdir)/Tuples/TupleExpansion.cc'; fi`
    2559 
    2560 Tuples/driver_cfa_cpp-Explode.o: Tuples/Explode.cc
    2561 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Tuples/driver_cfa_cpp-Explode.o -MD -MP -MF Tuples/$(DEPDIR)/driver_cfa_cpp-Explode.Tpo -c -o Tuples/driver_cfa_cpp-Explode.o `test -f 'Tuples/Explode.cc' || echo '$(srcdir)/'`Tuples/Explode.cc
    2562 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) Tuples/$(DEPDIR)/driver_cfa_cpp-Explode.Tpo Tuples/$(DEPDIR)/driver_cfa_cpp-Explode.Po
    2563 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='Tuples/Explode.cc' object='Tuples/driver_cfa_cpp-Explode.o' libtool=no @AMDEPBACKSLASH@
    2564 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2565 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Tuples/driver_cfa_cpp-Explode.o `test -f 'Tuples/Explode.cc' || echo '$(srcdir)/'`Tuples/Explode.cc
    2566 
    2567 Tuples/driver_cfa_cpp-Explode.obj: Tuples/Explode.cc
    2568 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Tuples/driver_cfa_cpp-Explode.obj -MD -MP -MF Tuples/$(DEPDIR)/driver_cfa_cpp-Explode.Tpo -c -o Tuples/driver_cfa_cpp-Explode.obj `if test -f 'Tuples/Explode.cc'; then $(CYGPATH_W) 'Tuples/Explode.cc'; else $(CYGPATH_W) '$(srcdir)/Tuples/Explode.cc'; fi`
    2569 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) Tuples/$(DEPDIR)/driver_cfa_cpp-Explode.Tpo Tuples/$(DEPDIR)/driver_cfa_cpp-Explode.Po
    2570 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='Tuples/Explode.cc' object='Tuples/driver_cfa_cpp-Explode.obj' libtool=no @AMDEPBACKSLASH@
    2571 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2572 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Tuples/driver_cfa_cpp-Explode.obj `if test -f 'Tuples/Explode.cc'; then $(CYGPATH_W) 'Tuples/Explode.cc'; else $(CYGPATH_W) '$(srcdir)/Tuples/Explode.cc'; fi`
    2573 
    2574 Virtual/driver_cfa_cpp-ExpandCasts.o: Virtual/ExpandCasts.cc
    2575 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Virtual/driver_cfa_cpp-ExpandCasts.o -MD -MP -MF Virtual/$(DEPDIR)/driver_cfa_cpp-ExpandCasts.Tpo -c -o Virtual/driver_cfa_cpp-ExpandCasts.o `test -f 'Virtual/ExpandCasts.cc' || echo '$(srcdir)/'`Virtual/ExpandCasts.cc
    2576 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) Virtual/$(DEPDIR)/driver_cfa_cpp-ExpandCasts.Tpo Virtual/$(DEPDIR)/driver_cfa_cpp-ExpandCasts.Po
    2577 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='Virtual/ExpandCasts.cc' object='Virtual/driver_cfa_cpp-ExpandCasts.o' libtool=no @AMDEPBACKSLASH@
    2578 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2579 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Virtual/driver_cfa_cpp-ExpandCasts.o `test -f 'Virtual/ExpandCasts.cc' || echo '$(srcdir)/'`Virtual/ExpandCasts.cc
    2580 
    2581 Virtual/driver_cfa_cpp-ExpandCasts.obj: Virtual/ExpandCasts.cc
    2582 @am__fastdepCXX_TRUE@   $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT Virtual/driver_cfa_cpp-ExpandCasts.obj -MD -MP -MF Virtual/$(DEPDIR)/driver_cfa_cpp-ExpandCasts.Tpo -c -o Virtual/driver_cfa_cpp-ExpandCasts.obj `if test -f 'Virtual/ExpandCasts.cc'; then $(CYGPATH_W) 'Virtual/ExpandCasts.cc'; else $(CYGPATH_W) '$(srcdir)/Virtual/ExpandCasts.cc'; fi`
    2583 @am__fastdepCXX_TRUE@   $(AM_V_at)$(am__mv) Virtual/$(DEPDIR)/driver_cfa_cpp-ExpandCasts.Tpo Virtual/$(DEPDIR)/driver_cfa_cpp-ExpandCasts.Po
    2584 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      $(AM_V_CXX)source='Virtual/ExpandCasts.cc' object='Virtual/driver_cfa_cpp-ExpandCasts.obj' libtool=no @AMDEPBACKSLASH@
    2585 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    2586 @am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o Virtual/driver_cfa_cpp-ExpandCasts.obj `if test -f 'Virtual/ExpandCasts.cc'; then $(CYGPATH_W) 'Virtual/ExpandCasts.cc'; else $(CYGPATH_W) '$(srcdir)/Virtual/ExpandCasts.cc'; fi`
     1401@am__fastdepCXX_FALSE@  $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
    25871402
    25881403.ll.cc:
     
    25911406.yy.cc:
    25921407        $(AM_V_YACC)$(am__skipyacc) $(SHELL) $(YLWRAP) $< y.tab.c $@ y.tab.h `echo $@ | $(am__yacc_c2h)` y.output $*.output -- $(YACCCOMPILE)
     1408
     1409mostlyclean-libtool:
     1410        -rm -f *.lo
     1411
     1412clean-libtool:
     1413        -rm -rf .libs _libs
     1414        -rm -rf ../driver/.libs ../driver/_libs
    25931415
    25941416ID: $(am__tagged_files)
     
    26771499check: $(BUILT_SOURCES)
    26781500        $(MAKE) $(AM_MAKEFLAGS) check-am
    2679 all-am: Makefile $(PROGRAMS)
     1501all-am: Makefile $(LIBRARIES) $(PROGRAMS)
    26801502installdirs:
    26811503        for dir in "$(DESTDIR)$(cfa_cpplibdir)"; do \
     
    27031525        fi
    27041526mostlyclean-generic:
     1527        -test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES)
    27051528
    27061529clean-generic:
     
    27091532        -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
    27101533        -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
     1534        -rm -f ../driver/$(am__dirstamp)
     1535        -rm -f AST/$(DEPDIR)/$(am__dirstamp)
     1536        -rm -f AST/$(am__dirstamp)
    27111537        -rm -f CodeGen/$(DEPDIR)/$(am__dirstamp)
    27121538        -rm -f CodeGen/$(am__dirstamp)
     
    27151541        -rm -f Common/$(DEPDIR)/$(am__dirstamp)
    27161542        -rm -f Common/$(am__dirstamp)
     1543        -rm -f Common/Stats/$(DEPDIR)/$(am__dirstamp)
     1544        -rm -f Common/Stats/$(am__dirstamp)
    27171545        -rm -f Concurrency/$(DEPDIR)/$(am__dirstamp)
    27181546        -rm -f Concurrency/$(am__dirstamp)
     
    27331561        -rm -f Tuples/$(DEPDIR)/$(am__dirstamp)
    27341562        -rm -f Tuples/$(am__dirstamp)
     1563        -rm -f Validate/$(DEPDIR)/$(am__dirstamp)
     1564        -rm -f Validate/$(am__dirstamp)
    27351565        -rm -f Virtual/$(DEPDIR)/$(am__dirstamp)
    27361566        -rm -f Virtual/$(am__dirstamp)
    2737         -rm -f driver/$(am__dirstamp)
    27381567
    27391568maintainer-clean-generic:
     
    27471576clean: clean-am
    27481577
    2749 clean-am: clean-cfa_cpplibPROGRAMS clean-generic mostlyclean-am
     1578clean-am: clean-cfa_cpplibPROGRAMS clean-generic clean-libtool \
     1579        clean-noinstLIBRARIES mostlyclean-am
    27501580
    27511581distclean: distclean-am
    2752         -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) Virtual/$(DEPDIR)
     1582        -rm -rf ./$(DEPDIR) AST/$(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)
    27531583        -rm -f Makefile
    27541584distclean-am: clean-am distclean-compile distclean-generic \
     
    27961626
    27971627maintainer-clean: maintainer-clean-am
    2798         -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) Virtual/$(DEPDIR)
     1628        -rm -rf ./$(DEPDIR) AST/$(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)
    27991629        -rm -f Makefile
    28001630maintainer-clean-am: distclean-am maintainer-clean-generic
     
    28021632mostlyclean: mostlyclean-am
    28031633
    2804 mostlyclean-am: mostlyclean-compile mostlyclean-generic
     1634mostlyclean-am: mostlyclean-compile mostlyclean-generic \
     1635        mostlyclean-libtool
    28051636
    28061637pdf: pdf-am
     
    28171648
    28181649.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \
    2819         clean-cfa_cpplibPROGRAMS clean-generic cscopelist-am ctags \
    2820         ctags-am distclean distclean-compile distclean-generic \
     1650        clean-cfa_cpplibPROGRAMS clean-generic clean-libtool \
     1651        clean-noinstLIBRARIES cscopelist-am ctags ctags-am distclean \
     1652        distclean-compile distclean-generic distclean-libtool \
    28211653        distclean-tags distdir dvi dvi-am html html-am info info-am \
    28221654        install install-am install-cfa_cpplibPROGRAMS install-data \
     
    28271659        installcheck-am installdirs maintainer-clean \
    28281660        maintainer-clean-generic mostlyclean mostlyclean-compile \
    2829         mostlyclean-generic pdf pdf-am ps ps-am tags tags-am uninstall \
    2830         uninstall-am uninstall-cfa_cpplibPROGRAMS
     1661        mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
     1662        tags tags-am uninstall uninstall-am \
     1663        uninstall-cfa_cpplibPROGRAMS
    28311664
    28321665.PRECIOUS: Makefile
    28331666
     1667
     1668$(addprefix $(srcdir)/, ResolvExpr/ConversionCost.cc ResolvExpr/CommonType.cc SymTab/ManglerCommon.cc) : $(srcdir)/SynTree/Type.h
     1669
     1670$(srcdir)/AST/Type.hpp : BasicTypes-gen.cc
     1671        ${AM_V_GEN}${CXXCOMPILE} $< -o BasicTypes-gen -Wall -Wextra
     1672        @./BasicTypes-gen
     1673        @rm BasicTypes-gen
    28341674
    28351675# Tell versions [3.59,3.63) of GNU make to not export all variables.
  • src/Parser/DeclarationNode.cc

    r7951100 rb067d9b  
    1010// Created On       : Sat May 16 12:34:05 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Jun  7 12:08:55 2018
    13 // Update Count     : 1079
     12// Last Modified On : Thu Jul 25 22:17:10 2019
     13// Update Count     : 1116
    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" };
    4749const char * DeclarationNode::aggregateNames[] = { "struct", "union", "trait", "coroutine", "monitor", "thread", "NoAggregateNames" };
    4850const char * DeclarationNode::typeClassNames[] = { "otype", "dtype", "ftype", "NoTypeClassNames" };
    49 const char * DeclarationNode::builtinTypeNames[] = { "__builtin_va_list", "zero_t", "one_t", "NoBuiltinTypeNames" };
     51const char * DeclarationNode::builtinTypeNames[] = { "__builtin_va_list", "__auto_type", "zero_t", "one_t", "NoBuiltinTypeNames" };
    5052
    5153UniqueName DeclarationNode::anonymous( "__anonymous" );
     
    5456
    5557DeclarationNode::DeclarationNode() :
    56                 builtin( NoBuiltinType ),
    57                 type( nullptr ),
    58                 bitfieldWidth( nullptr ),
    59                 hasEllipsis( false ),
    60                 linkage( ::linkage ),
    61                 asmName( nullptr ),
    62                 initializer( nullptr ),
    63                 extension( false ),
    64                 asmStmt( nullptr ) {
     58        linkage( ::linkage ) {
    6559
    6660//      variable.name = nullptr;
     
    10498        newnode->builtin = NoBuiltinType;
    10599        newnode->type = maybeClone( type );
     100        newnode->inLine = inLine;
    106101        newnode->storageClasses = storageClasses;
    107102        newnode->funcSpecs = funcSpecs;
     
    131126} // DeclarationNode::clone
    132127
    133 void DeclarationNode::print( std::ostream &os, int indent ) const {
     128void DeclarationNode::print( std::ostream & os, int indent ) const {
    134129        os << string( indent, ' ' );
    135130        if ( name ) {
     
    167162}
    168163
    169 void DeclarationNode::printList( std::ostream &os, int indent ) const {
     164void DeclarationNode::printList( std::ostream & os, int indent ) const {
    170165        ParseNode::printList( os, indent );
    171166        if ( hasEllipsis ) {
     
    254249} // DeclarationNode::newFromTypedef
    255250
     251DeclarationNode * DeclarationNode::newFromGlobalScope() {
     252        DeclarationNode * newnode = new DeclarationNode;
     253        newnode->type = new TypeData( TypeData::GlobalScope );
     254        return newnode;
     255}
     256
     257DeclarationNode * DeclarationNode::newQualifiedType( DeclarationNode * parent, DeclarationNode * child) {
     258        DeclarationNode * newnode = new DeclarationNode;
     259        newnode->type = new TypeData( TypeData::Qualified );
     260        newnode->type->qualified.parent = parent->type;
     261        newnode->type->qualified.child = child->type;
     262        parent->type = nullptr;
     263        child->type = nullptr;
     264        delete parent;
     265        delete child;
     266        return newnode;
     267}
     268
    256269DeclarationNode * DeclarationNode::newAggregate( Aggregate kind, const string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body ) {
    257         assert( name );
    258270        DeclarationNode * newnode = new DeclarationNode;
    259271        newnode->type = new TypeData( TypeData::Aggregate );
    260272        newnode->type->aggregate.kind = kind;
    261         newnode->type->aggregate.name = name;
     273        newnode->type->aggregate.name =  name == nullptr ? new string( DeclarationNode::anonymous.newName() ) : name;
    262274        newnode->type->aggregate.actuals = actuals;
    263275        newnode->type->aggregate.fields = fields;
     
    265277        newnode->type->aggregate.tagged = false;
    266278        newnode->type->aggregate.parent = nullptr;
     279        newnode->type->aggregate.anon = name == nullptr;
    267280        return newnode;
    268281} // DeclarationNode::newAggregate
    269282
    270283DeclarationNode * DeclarationNode::newEnum( const string * name, DeclarationNode * constants, bool body ) {
    271         assert( name );
    272284        DeclarationNode * newnode = new DeclarationNode;
    273285        newnode->type = new TypeData( TypeData::Enum );
    274         newnode->type->enumeration.name = name;
     286        newnode->type->enumeration.name = name == nullptr ? new string( DeclarationNode::anonymous.newName() ) : name;
    275287        newnode->type->enumeration.constants = constants;
    276288        newnode->type->enumeration.body = body;
     289        newnode->type->enumeration.anon = name == nullptr;
    277290        return newnode;
    278291} // DeclarationNode::newEnum
     
    391404}
    392405
    393 DeclarationNode * DeclarationNode::newTypeof( ExpressionNode * expr ) {
    394         DeclarationNode * newnode = new DeclarationNode;
    395         newnode->type = new TypeData( TypeData::Typeof );
     406DeclarationNode * DeclarationNode::newTypeof( ExpressionNode * expr, bool basetypeof ) {
     407        DeclarationNode * newnode = new DeclarationNode;
     408        newnode->type = new TypeData( basetypeof ? TypeData::Basetypeof : TypeData::Typeof );
    396409        newnode->type->typeexpr = expr;
    397410        return newnode;
     
    405418        return newnode;
    406419} // DeclarationNode::newBuiltinType
    407 
    408 DeclarationNode * DeclarationNode::newAttr( const string * name, ExpressionNode * expr ) {
    409         DeclarationNode * newnode = new DeclarationNode;
    410         newnode->type = nullptr;
    411 //      newnode->attr.name = name;
    412         newnode->name = name;
    413         newnode->attr.expr = expr;
    414         return newnode;
    415 }
    416 
    417 DeclarationNode * DeclarationNode::newAttr( const string * name, DeclarationNode * type ) {
    418         DeclarationNode * newnode = new DeclarationNode;
    419         newnode->type = nullptr;
    420 //      newnode->attr.name = name;
    421         newnode->name = name;
    422         newnode->attr.type = type;
    423         return newnode;
    424 }
    425420
    426421DeclarationNode * DeclarationNode::newAttribute( const string * name, ExpressionNode * expr ) {
     
    503498} // DeclarationNode::copySpecifiers
    504499
    505 static void addQualifiersToType( TypeData *&src, TypeData * dst ) {
    506         if ( src->forall && dst->kind == TypeData::Function ) {
    507                 if ( dst->forall ) {
    508                         dst->forall->appendList( src->forall );
    509                 } else {
    510                         dst->forall = src->forall;
    511                 } // if
    512                 src->forall = nullptr;
    513         } // if
     500static void addQualifiersToType( TypeData *& src, TypeData * dst ) {
    514501        if ( dst->base ) {
    515502                addQualifiersToType( src, dst->base );
     
    564551} // addQualifiers
    565552
    566 static void addTypeToType( TypeData *&src, TypeData *&dst ) {
     553static void addTypeToType( TypeData *& src, TypeData *& dst ) {
    567554        if ( src->forall && dst->kind == TypeData::Function ) {
    568555                if ( dst->forall ) {
     
    955942}
    956943
    957 void buildList( const DeclarationNode * firstNode, std::list< Declaration * > &outputList ) {
     944void buildList( const DeclarationNode * firstNode, std::list< Declaration * > & outputList ) {
    958945        SemanticErrorException errors;
    959946        std::back_insert_iterator< std::list< Declaration * > > out( outputList );
     
    961948        for ( const DeclarationNode * cur = firstNode; cur; cur = dynamic_cast< DeclarationNode * >( cur->get_next() ) ) {
    962949                try {
     950                        bool extracted = false;
     951                        bool anon = false;
    963952                        if ( DeclarationNode * extr = cur->extractAggregate() ) {
    964953                                // handle the case where a structure declaration is contained within an object or type declaration
    965954                                Declaration * decl = extr->build();
    966955                                if ( decl ) {
     956                                        // hoist the structure declaration
    967957                                        decl->location = cur->location;
    968958                                        * out++ = decl;
     959
     960                                        // need to remember the cases where a declaration contains an anonymous aggregate definition
     961                                        extracted = true;
     962                                        assert( extr->type );
     963                                        if ( extr->type->kind == TypeData::Aggregate ) {
     964                                                anon = extr->type->aggregate.anon;
     965                                        } else if ( extr->type->kind == TypeData::Enum ) {
     966                                                // xxx - is it useful to have an implicit anonymous enum member?
     967                                                anon = extr->type->enumeration.anon;
     968                                        }
    969969                                } // if
    970970                                delete extr;
     
    973973                        Declaration * decl = cur->build();
    974974                        if ( decl ) {
    975                                 decl->location = cur->location;
    976                                 * out++ = decl;
     975                                // don't include anonymous declaration for named aggregates, but do include them for anonymous aggregates, e.g.:
     976                                // struct S {
     977                                //   struct T { int x; }; // no anonymous member
     978                                //   struct { int y; };   // anonymous member
     979                                //   struct T;            // anonymous member
     980                                // };
     981                                if ( ! (extracted && decl->name == "" && ! anon && ! cur->get_inLine()) ) {
     982                                        if ( decl->name == "" ) {
     983                                                if ( DeclarationWithType * dwt = dynamic_cast<DeclarationWithType *>( decl ) ) {
     984                                                        if ( ReferenceToType * aggr = dynamic_cast<ReferenceToType *>( dwt->get_type() ) ) {
     985                                                                if ( aggr->name.find("anonymous") == std::string::npos ) {
     986                                                                        if ( ! cur->get_inLine() ) {
     987                                                                                // temporary: warn about anonymous member declarations of named types, since
     988                                                                                // this conflicts with the syntax for the forward declaration of an anonymous type
     989                                                                                SemanticWarning( cur->location, Warning::AggrForwardDecl, aggr->name.c_str() );
     990                                                                        } // if
     991                                                                } // if
     992                                                        } // if
     993                                                } // if
     994                                        } // if
     995                                        decl->location = cur->location;
     996                                        *out++ = decl;
     997                                } // if
    977998                        } // if
    978                 } catch( SemanticErrorException &e ) {
     999                } catch( SemanticErrorException & e ) {
    9791000                        errors.append( e );
    9801001                } // try
    981         } // while
     1002        } // for
    9821003
    9831004        if ( ! errors.isEmpty() ) {
     
    9861007} // buildList
    9871008
    988 void buildList( const DeclarationNode * firstNode, std::list< DeclarationWithType * > &outputList ) {
     1009// currently only builds assertions, function parameters, and return values
     1010void buildList( const DeclarationNode * firstNode, std::list< DeclarationWithType * > & outputList ) {
    9891011        SemanticErrorException errors;
    9901012        std::back_insert_iterator< std::list< DeclarationWithType * > > out( outputList );
     
    9931015                try {
    9941016                        Declaration * decl = cur->build();
    995                         if ( decl ) {
    996                                 if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType * >( decl ) ) {
    997                                         dwt->location = cur->location;
    998                                         * out++ = dwt;
    999                                 } else if ( StructDecl * agg = dynamic_cast< StructDecl * >( decl ) ) {
    1000                                         StructInstType * inst = new StructInstType( Type::Qualifiers(), agg->get_name() );
    1001                                         auto obj = new ObjectDecl( "", Type::StorageClasses(), linkage, nullptr, inst, nullptr );
    1002                                         obj->location = cur->location;
    1003                                         * out++ = obj;
    1004                                         delete agg;
    1005                                 } else if ( UnionDecl * agg = dynamic_cast< UnionDecl * >( decl ) ) {
    1006                                         UnionInstType * inst = new UnionInstType( Type::Qualifiers(), agg->get_name() );
    1007                                         auto obj = new ObjectDecl( "", Type::StorageClasses(), linkage, nullptr, inst, nullptr );
    1008                                         obj->location = cur->location;
    1009                                         * out++ = obj;
    1010                                 } // if
     1017                        assert( decl );
     1018                        if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType * >( decl ) ) {
     1019                                dwt->location = cur->location;
     1020                                * out++ = dwt;
     1021                        } else if ( StructDecl * agg = dynamic_cast< StructDecl * >( decl ) ) {
     1022                                // e.g., int foo(struct S) {}
     1023                                StructInstType * inst = new StructInstType( Type::Qualifiers(), agg->name );
     1024                                auto obj = new ObjectDecl( "", Type::StorageClasses(), linkage, nullptr, inst, nullptr );
     1025                                obj->location = cur->location;
     1026                                * out++ = obj;
     1027                                delete agg;
     1028                        } else if ( UnionDecl * agg = dynamic_cast< UnionDecl * >( decl ) ) {
     1029                                // e.g., int foo(union U) {}
     1030                                UnionInstType * inst = new UnionInstType( Type::Qualifiers(), agg->name );
     1031                                auto obj = new ObjectDecl( "", Type::StorageClasses(), linkage, nullptr, inst, nullptr );
     1032                                obj->location = cur->location;
     1033                                * out++ = obj;
     1034                        } else if ( EnumDecl * agg = dynamic_cast< EnumDecl * >( decl ) ) {
     1035                                // e.g., int foo(enum E) {}
     1036                                EnumInstType * inst = new EnumInstType( Type::Qualifiers(), agg->name );
     1037                                auto obj = new ObjectDecl( "", Type::StorageClasses(), linkage, nullptr, inst, nullptr );
     1038                                obj->location = cur->location;
     1039                                * out++ = obj;
    10111040                        } // if
    1012                 } catch( SemanticErrorException &e ) {
     1041                } catch( SemanticErrorException & e ) {
    10131042                        errors.append( e );
    10141043                } // try
     
    10201049} // buildList
    10211050
    1022 void buildTypeList( const DeclarationNode * firstNode, std::list< Type * > &outputList ) {
     1051void buildTypeList( const DeclarationNode * firstNode, std::list< Type * > & outputList ) {
    10231052        SemanticErrorException errors;
    10241053        std::back_insert_iterator< std::list< Type * > > out( outputList );
     
    10281057                try {
    10291058                        * out++ = cur->buildType();
    1030                 } catch( SemanticErrorException &e ) {
     1059                } catch( SemanticErrorException & e ) {
    10311060                        errors.append( e );
    10321061                } // try
     
    10641093                if ( type->kind != TypeData::Function && funcSpecs.any() ) {
    10651094                        SemanticError( this, "invalid function specifier for " );
     1095                } // if
     1096                // Forall qualifier can only appear on a function/aggregate definition/declaration.
     1097                //
     1098                //    forall int f();                                   // allowed
     1099                //    forall int g( int i );                    // allowed
     1100                //    forall int i;                                             // disallowed
     1101                if ( type->kind != TypeData::Function && type->forall ) {
     1102                        SemanticError( this, "invalid type qualifier for " );
    10661103                } // if
    10671104                bool isDelete = initializer && initializer->get_isDelete();
  • src/Parser/ExpressionNode.cc

    r7951100 rb067d9b  
    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 Aug  4 20:57:55 2019
     13// Update Count     : 978
    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 ) {
    97111        static const BasicType::Kind kind[2][6] = {
    98                 // short (h) must be before char (hh)
     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
     
    338357                                                                        new ConstantExpr( Constant::from_ulong( str.size() + 1 - 2 ) ), // +1 for '\0' and -2 for '"'
    339358                                                                        false, false );
    340         Expression * ret = new ConstantExpr( Constant( at, str, (unsigned long long int)0 ) ); // constant 0 is ignored for pure string value
     359        Expression * ret = new ConstantExpr( Constant( at, str, std::nullopt ) );
    341360        if ( units.length() != 0 ) {
    342361                ret = new UntypedExpr( new NameExpr( units ), { ret } );
  • src/Parser/LinkageSpec.cc

    r7951100 rb067d9b  
    1010// Created On       : Sat May 16 13:22:09 2015
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Fri Jul  7 11:11:00 2017
    13 // Update Count     : 25
     12// Last Modified On : Thr Spt 12 15:59:00 2018
     13// Update Count     : 26
    1414//
    1515
     
    2323
    2424namespace LinkageSpec {
    25 
    26 Spec linkageCheck( CodeLocation location, const string * spec ) {
    27         assert( spec );
    28         unique_ptr<const string> guard( spec ); // allocated by lexer
    29         if ( *spec == "\"Cforall\"" ) {
    30                 return Cforall;
    31         } else if ( *spec == "\"C\"" ) {
    32                 return C;
    33         } else if ( *spec == "\"BuiltinC\"" ) {
    34                 return BuiltinC;
    35         } else {
    36                 SemanticError( location, "Invalid linkage specifier " + *spec );
    37         } // if
    38 }
    3925
    4026Spec linkageUpdate( CodeLocation location, Spec old_spec, const string * cmd ) {
  • src/Parser/LinkageSpec.h

    r7951100 rb067d9b  
    1010// Created On       : Sat May 16 13:24:28 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Jul 22 09:32:16 2017
    13 // Update Count     : 14
     12// Last Modified On : Wed Jul 10 16:02:34 2019
     13// Update Count     : 18
    1414//
    1515
     
    2222namespace LinkageSpec {
    2323        // All linkage specs are some combination of these flags:
    24         enum {
    25                 Mangle = 1 << 0,
    26                 Generate = 1 << 1,
    27                 Overrideable = 1 << 2,
    28                 Builtin = 1 << 3,
    29                 GccBuiltin = 1 << 4,
    30 
    31                 NoOfSpecs = 1 << 5,
    32         };
     24        enum { Mangle = 1 << 0, Generate = 1 << 1, Overrideable = 1 << 2, Builtin = 1 << 3, GccBuiltin = 1 << 4, NoOfSpecs = 1 << 5, };
    3325
    3426        union Spec {
     
    4234                };
    4335                constexpr Spec( unsigned int val ) : val( val ) {}
    44                 constexpr Spec( Spec const &other ) : val( other.val ) {}
     36                constexpr Spec( Spec const & other ) : val( other.val ) {}
     37                constexpr Spec & operator=( const Spec & ) = default;
    4538                // Operators may go here.
    4639                // Supports == and !=
    47                 constexpr operator unsigned int () const { return val; }
     40                constexpr operator unsigned int() const { return val; }
    4841        };
    4942
    5043
    51         Spec linkageCheck( CodeLocation location, const std::string * );
    52         // Returns the Spec with the given name (limited to C, Cforall & BuiltinC)
    5344        Spec linkageUpdate( CodeLocation location, Spec old_spec, const std::string * cmd );
    5445        /* If cmd = "C" returns a Spec that is old_spec with is_mangled = false
  • src/Parser/ParseNode.h

    r7951100 rb067d9b  
    1010// Created On       : Sat May 16 13:28:16 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Jun  6 16:17:18 2018
    13 // Update Count     : 843
     12// Last Modified On : Thu Jul 25 22:17:10 2019
     13// Update Count     : 876
    1414//
    1515
     
    6868        }
    6969
    70         virtual void print( __attribute__((unused)) std::ostream &os, __attribute__((unused)) int indent = 0 ) const {}
    71         virtual void printList( std::ostream &os, int indent = 0 ) const {
     70        virtual void print( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const {}
     71        virtual void printList( std::ostream & os, int indent = 0 ) const {
    7272                print( os, indent );
    7373                if ( next ) next->print( os, indent );
     
    103103        InitializerNode * next_init() const { return kids; }
    104104
    105         void print( std::ostream &os, int indent = 0 ) const;
     105        void print( std::ostream & os, int indent = 0 ) const;
    106106        void printOneLine( std::ostream & ) const;
    107107
     
    127127        ExpressionNode * set_extension( bool exten ) { extension = exten; return this; }
    128128
    129         virtual void print( std::ostream &os, __attribute__((unused)) int indent = 0 ) const override {
    130                 os << expr.get() << std::endl;
    131         }
    132         void printOneLine( __attribute__((unused)) std::ostream &os, __attribute__((unused)) int indent = 0 ) const {}
     129        virtual void print( std::ostream & os, __attribute__((unused)) int indent = 0 ) const override {
     130                os << expr.get();
     131        }
     132        void printOneLine( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const {}
    133133
    134134        template<typename T>
     
    136136
    137137        Expression * build() const { return const_cast<ExpressionNode *>(this)->expr.release(); }
     138
     139        std::unique_ptr<Expression> expr;                                       // public because of lifetime implications
    138140  private:
    139141        bool extension = false;
    140         std::unique_ptr<Expression> expr;
    141142}; // ExpressionNode
    142143
     
    205206class DeclarationNode : public ParseNode {
    206207  public:
    207         // These enumerations must harmonize with their names.
    208         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 };
    209212        static const char * basicTypeNames[];
    210         enum ComplexType { Complex, Imaginary, NoComplexType };
     213        enum ComplexType { Complex, NoComplexType, Imaginary }; // Imaginary unsupported => parse, but make invisible and print error message
    211214        static const char * complexTypeNames[];
    212215        enum Signedness { Signed, Unsigned, NoSignedness };
     
    218221        enum TypeClass { Otype, Dtype, Ftype, Ttype, NoTypeClass };
    219222        static const char * typeClassNames[];
    220         enum BuiltinType { Valist, Zero, One, NoBuiltinType };
     223        enum BuiltinType { Valist, AutoType, Zero, One, NoBuiltinType };
    221224        static const char * builtinTypeNames[];
    222225
     
    231234        static DeclarationNode * newForall( DeclarationNode * );
    232235        static DeclarationNode * newFromTypedef( const std::string * );
     236        static DeclarationNode * newFromGlobalScope();
     237        static DeclarationNode * newQualifiedType( DeclarationNode *, DeclarationNode * );
    233238        static DeclarationNode * newFunction( const std::string * name, DeclarationNode * ret, DeclarationNode * param, StatementNode * body );
    234239        static DeclarationNode * newAggregate( Aggregate kind, const std::string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body );
     
    246251        static DeclarationNode * newBitfield( ExpressionNode * size );
    247252        static DeclarationNode * newTuple( DeclarationNode * members );
    248         static DeclarationNode * newTypeof( ExpressionNode * expr );
    249         static DeclarationNode * newAttr( const std::string *, ExpressionNode * expr ); // @ attributes
    250         static DeclarationNode * newAttr( const std::string *, DeclarationNode * type ); // @ attributes
     253        static DeclarationNode * newTypeof( ExpressionNode * expr, bool basetypeof = false );
    251254        static DeclarationNode * newAttribute( const std::string *, ExpressionNode * expr = nullptr ); // gcc attributes
    252255        static DeclarationNode * newAsmStmt( StatementNode * stmt ); // gcc external asm statement
     
    288291        }
    289292
    290         virtual void print( __attribute__((unused)) std::ostream &os, __attribute__((unused)) int indent = 0 ) const override;
    291         virtual void printList( __attribute__((unused)) std::ostream &os, __attribute__((unused)) int indent = 0 ) const override;
     293        virtual void print( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const override;
     294        virtual void printList( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const override;
    292295
    293296        Declaration * build() const;
     
    301304        bool get_extension() const { return extension; }
    302305        DeclarationNode * set_extension( bool exten ) { extension = exten; return this; }
     306
     307        bool get_inLine() const { return inLine; }
     308        DeclarationNode * set_inLine( bool inL ) { inLine = inL; return this; }
    303309  public:
    304310        DeclarationNode * get_last() { return (DeclarationNode *)ParseNode::get_last(); }
     
    325331        StaticAssert_t assert;
    326332
    327         BuiltinType builtin;
    328 
    329         TypeData * type;
    330 
     333        BuiltinType builtin = NoBuiltinType;
     334
     335        TypeData * type = nullptr;
     336
     337        bool inLine = false;
    331338        Type::FuncSpecifiers funcSpecs;
    332339        Type::StorageClasses storageClasses;
    333340
    334         ExpressionNode * bitfieldWidth;
     341        ExpressionNode * bitfieldWidth = nullptr;
    335342        std::unique_ptr<ExpressionNode> enumeratorValue;
    336         bool hasEllipsis;
     343        bool hasEllipsis = false;
    337344        LinkageSpec::Spec linkage;
    338         Expression * asmName;
     345        Expression * asmName = nullptr;
    339346        std::list< Attribute * > attributes;
    340         InitializerNode * initializer;
     347        InitializerNode * initializer = nullptr;
    341348        bool extension = false;
    342349        std::string error;
    343         StatementNode * asmStmt;
     350        StatementNode * asmStmt = nullptr;
    344351
    345352        static UniqueName anonymous;
     
    375382        virtual StatementNode * append_last_case( StatementNode * );
    376383
    377         virtual void print( std::ostream &os, __attribute__((unused)) int indent = 0 ) const override {
     384        virtual void print( std::ostream & os, __attribute__((unused)) int indent = 0 ) const override {
    378385                os << stmt.get() << std::endl;
    379386        }
     
    384391Statement * build_expr( ExpressionNode * ctl );
    385392
    386 struct IfCtl {
    387         IfCtl( DeclarationNode * decl, ExpressionNode * condition ) :
     393struct IfCtrl {
     394        IfCtrl( DeclarationNode * decl, ExpressionNode * condition ) :
    388395                init( decl ? new StatementNode( decl ) : nullptr ), condition( condition ) {}
    389396
     
    392399};
    393400
    394 struct ForCtl {
    395         ForCtl( ExpressionNode * expr, ExpressionNode * condition, ExpressionNode * change ) :
     401struct ForCtrl {
     402        ForCtrl( ExpressionNode * expr, ExpressionNode * condition, ExpressionNode * change ) :
    396403                init( new StatementNode( build_expr( expr ) ) ), condition( condition ), change( change ) {}
    397         ForCtl( DeclarationNode * decl, ExpressionNode * condition, ExpressionNode * change ) :
     404        ForCtrl( DeclarationNode * decl, ExpressionNode * condition, ExpressionNode * change ) :
    398405                init( new StatementNode( decl ) ), condition( condition ), change( change ) {}
    399406
     
    403410};
    404411
    405 Expression * build_if_control( IfCtl * ctl, std::list< Statement * > & init );
    406 Statement * build_if( IfCtl * ctl, StatementNode * then_stmt, StatementNode * else_stmt );
     412Expression * build_if_control( IfCtrl * ctl, std::list< Statement * > & init );
     413Statement * build_if( IfCtrl * ctl, StatementNode * then_stmt, StatementNode * else_stmt );
    407414Statement * build_switch( bool isSwitch, ExpressionNode * ctl, StatementNode * stmt );
    408415Statement * build_case( ExpressionNode * ctl );
    409416Statement * build_default();
    410 Statement * build_while( IfCtl * ctl, StatementNode * stmt );
     417Statement * build_while( IfCtrl * ctl, StatementNode * stmt );
    411418Statement * build_do_while( ExpressionNode * ctl, StatementNode * stmt );
    412 Statement * build_for( ForCtl * forctl, StatementNode * stmt );
     419Statement * build_for( ForCtrl * forctl, StatementNode * stmt );
    413420Statement * build_branch( BranchStmt::Type kind );
    414421Statement * build_branch( std::string * identifier, BranchStmt::Type kind );
     
    428435WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when );
    429436WaitForStmt * build_waitfor_timeout( ExpressionNode * timeout, StatementNode * stmt, ExpressionNode * when, StatementNode * else_stmt, ExpressionNode * else_when );
    430 WithStmt * build_with( ExpressionNode * exprs, StatementNode * stmt );
     437Statement * build_with( ExpressionNode * exprs, StatementNode * stmt );
    431438
    432439//##############################################################################
    433440
    434441template< typename SynTreeType, typename NodeType, template< typename, typename...> class Container, typename... Args >
    435 void buildList( const NodeType * firstNode, Container< SynTreeType *, Args... > &outputList ) {
     442void buildList( const NodeType * firstNode, Container< SynTreeType *, Args... > & outputList ) {
    436443        SemanticErrorException errors;
    437444        std::back_insert_iterator< Container< SynTreeType *, Args... > > out( outputList );
     
    447454                                assertf(false, "buildList unknown type");
    448455                        } // if
    449                 } catch( SemanticErrorException &e ) {
     456                } catch( SemanticErrorException & e ) {
    450457                        errors.append( e );
    451458                } // try
     
    458465
    459466// in DeclarationNode.cc
    460 void buildList( const DeclarationNode * firstNode, std::list< Declaration * > &outputList );
    461 void buildList( const DeclarationNode * firstNode, std::list< DeclarationWithType * > &outputList );
    462 void buildTypeList( const DeclarationNode * firstNode, std::list< Type * > &outputList );
     467void buildList( const DeclarationNode * firstNode, std::list< Declaration * > & outputList );
     468void buildList( const DeclarationNode * firstNode, std::list< DeclarationWithType * > & outputList );
     469void buildTypeList( const DeclarationNode * firstNode, std::list< Type * > & outputList );
    463470
    464471template< typename SynTreeType, typename NodeType >
    465 void buildMoveList( const NodeType * firstNode, std::list< SynTreeType * > &outputList ) {
     472void buildMoveList( const NodeType * firstNode, std::list< SynTreeType * > & outputList ) {
    466473        buildList( firstNode, outputList );
    467474        delete firstNode;
  • src/Parser/StatementNode.cc

    r7951100 rb067d9b  
    1010// Created On       : Sat May 16 14:59:41 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Jun  5 08:58:34 2018
    13 // Update Count     : 362
     12// Last Modified On : Sat Aug  4 09:39:25 2018
     13// Update Count     : 363
    1414//
    1515
     
    7878} // build_expr
    7979
    80 Expression * build_if_control( IfCtl * ctl, std::list< Statement * > & init ) {
     80Expression * build_if_control( IfCtrl * ctl, std::list< Statement * > & init ) {
    8181        if ( ctl->init != 0 ) {
    8282                buildMoveList( ctl->init, init );
     
    100100} // build_if_control
    101101
    102 Statement * build_if( IfCtl * ctl, StatementNode * then_stmt, StatementNode * else_stmt ) {
     102Statement * build_if( IfCtrl * ctl, StatementNode * then_stmt, StatementNode * else_stmt ) {
    103103        Statement * thenb, * elseb = nullptr;
    104104        std::list< Statement * > branches;
     
    145145} // build_default
    146146
    147 Statement * build_while( IfCtl * ctl, StatementNode * stmt ) {
     147Statement * build_while( IfCtrl * ctl, StatementNode * stmt ) {
    148148        std::list< Statement * > branches;
    149149        buildMoveList< Statement, StatementNode >( stmt, branches );
     
    164164} // build_do_while
    165165
    166 Statement * build_for( ForCtl * forctl, StatementNode * stmt ) {
     166Statement * build_for( ForCtrl * forctl, StatementNode * stmt ) {
    167167        std::list< Statement * > branches;
    168168        buildMoveList< Statement, StatementNode >( stmt, branches );
     
    317317} // build_waitfor_timeout
    318318
    319 WithStmt * build_with( ExpressionNode * exprs, StatementNode * stmt ) {
     319Statement * build_with( ExpressionNode * exprs, StatementNode * stmt ) {
    320320        std::list< Expression * > e;
    321321        buildMoveList( exprs, e );
    322322        Statement * s = maybeMoveBuild<Statement>( stmt );
    323         return new WithStmt( e, s );
     323        return new DeclStmt( new WithStmt( e, s ) );
    324324} // build_with
    325325
  • src/Parser/TypeData.cc

    r7951100 rb067d9b  
    1010// Created On       : Sat May 16 15:12:51 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Jun  6 17:40:33 2018
    13 // Update Count     : 604
     12// Last Modified On : Wed Feb 13 18:16:23 2019
     13// Update Count     : 649
    1414//
    1515
     
    3737          case Reference:
    3838          case EnumConstant:
     39          case GlobalScope:
    3940                // nothing else to initialize
    4041                break;
     
    6263                enumeration.constants = nullptr;
    6364                enumeration.body = false;
     65                enumeration.anon = false;
    6466                break;
    6567          case Aggregate:
     
    7375                aggregate.tagged = false;
    7476                aggregate.parent = nullptr;
     77                aggregate.anon = false;
    7578                break;
    7679          case AggregateInst:
     
    7881                aggInst.aggregate = nullptr;
    7982                aggInst.params = nullptr;
    80                 aggInst.hoistType = false;;
     83                aggInst.hoistType = false;
    8184                break;
    8285          case Symbolic:
     
    9396                break;
    9497          case Typeof:
     98          case Basetypeof:
    9599                // typeexpr = new Typeof_t;
    96100                typeexpr = nullptr;
     
    98102          case Builtin:
    99103                // builtin = new Builtin_t;
     104                case Qualified:
     105                qualified.parent = nullptr;
     106                qualified.child = nullptr;
    100107                break;
    101108        } // switch
     
    112119          case Reference:
    113120          case EnumConstant:
     121          case GlobalScope:
    114122                // nothing to destroy
    115123                break;
     
    159167                break;
    160168          case Typeof:
     169          case Basetypeof:
    161170                // delete typeexpr->expr;
    162171                delete typeexpr;
     
    165174                // delete builtin;
    166175                break;
     176          case Qualified:
     177                delete qualified.parent;
     178                delete qualified.child;
    167179        } // switch
    168180} // TypeData::~TypeData
     
    180192          case Pointer:
    181193          case Reference:
     194          case GlobalScope:
    182195                // nothing else to copy
    183196                break;
     
    207220                newtype->aggregate.fields = maybeClone( aggregate.fields );
    208221                newtype->aggregate.body = aggregate.body;
     222                newtype->aggregate.anon = aggregate.anon;
    209223                newtype->aggregate.tagged = aggregate.tagged;
    210224                newtype->aggregate.parent = aggregate.parent ? new string( *aggregate.parent ) : nullptr;
     
    219233                newtype->enumeration.constants = maybeClone( enumeration.constants );
    220234                newtype->enumeration.body = enumeration.body;
     235                newtype->enumeration.anon = enumeration.anon;
    221236                break;
    222237          case Symbolic:
     
    232247                break;
    233248          case Typeof:
     249          case Basetypeof:
    234250                newtype->typeexpr = maybeClone( typeexpr );
    235251                break;
     
    237253                assert( builtintype == DeclarationNode::Zero || builtintype == DeclarationNode::One );
    238254                newtype->builtintype = builtintype;
     255                break;
     256                case Qualified:
     257                newtype->qualified.parent = maybeClone( qualified.parent );
     258                newtype->qualified.child = maybeClone( qualified.child );
    239259                break;
    240260        } // switch
     
    254274
    255275        switch ( kind ) {
    256           case Unknown:
    257                 os << "entity of unknown type ";
     276          case Basic:
     277                if ( signedness != DeclarationNode::NoSignedness ) os << DeclarationNode::signednessNames[ signedness ] << " ";
     278                if ( length != DeclarationNode::NoLength ) os << DeclarationNode::lengthNames[ length ] << " ";
     279                if ( complextype == DeclarationNode::NoComplexType ) { // basic type
     280                        assert( basictype != DeclarationNode::NoBasicType );
     281                        os << DeclarationNode::basicTypeNames[ basictype ] << " ";
     282                } else {                                                                                // complex type
     283                        // handle double _Complex
     284                        if ( basictype != DeclarationNode::NoBasicType ) os << DeclarationNode::basicTypeNames[ basictype ] << " ";
     285                        os << DeclarationNode::complexTypeNames[ complextype ] << " ";
     286                } // if
    258287                break;
    259288          case Pointer:
     
    264293                } // if
    265294                break;
    266           case EnumConstant:
    267                 os << "enumeration constant ";
    268                 break;
    269           case Basic:
    270                 if ( signedness != DeclarationNode::NoSignedness ) os << DeclarationNode::signednessNames[ signedness ] << " ";
    271                 if ( length != DeclarationNode::NoLength ) os << DeclarationNode::lengthNames[ length ] << " ";
    272                 assert( basictype != DeclarationNode::NoBasicType );
    273                 os << DeclarationNode::basicTypeNames[ basictype ] << " ";
    274                 if ( complextype != DeclarationNode::NoComplexType ) os << DeclarationNode::complexTypeNames[ complextype ] << " ";
     295          case Reference:
     296                os << "reference ";
     297                if ( base ) {
     298                        os << "to ";
     299                        base->print( os, indent );
     300                } // if
    275301                break;
    276302          case Array:
     
    296322                        function.params->printList( os, indent + 4 );
    297323                } else {
    298                         os << string( indent + 2, ' ' ) << "with no parameters " << endl;
     324                        os << string( indent + 2, ' ' ) << "with no parameters" << endl;
    299325                } // if
    300326                if ( function.idList ) {
     
    321347                os << DeclarationNode::aggregateNames[ aggregate.kind ] << ' ' << *aggregate.name << endl;
    322348                if ( aggregate.params ) {
    323                         os << string( indent + 2, ' ' ) << "with type parameters " << endl;
     349                        os << string( indent + 2, ' ' ) << "with type parameters" << endl;
    324350                        aggregate.params->printList( os, indent + 4 );
    325351                } // if
    326352                if ( aggregate.actuals ) {
    327                         os << string( indent + 2, ' ' ) << "instantiated with actual parameters " << endl;
     353                        os << string( indent + 2, ' ' ) << "instantiated with actual parameters" << endl;
    328354                        aggregate.actuals->printList( os, indent + 4 );
    329355                } // if
    330356                if ( aggregate.fields ) {
    331                         os << string( indent + 2, ' ' ) << "with members " << endl;
     357                        os << string( indent + 2, ' ' ) << "with members" << endl;
    332358                        aggregate.fields->printList( os, indent + 4 );
    333359                } // if
    334360                if ( aggregate.body ) {
    335                         os << string( indent + 2, ' ' ) << " with body " << endl;
     361                        os << string( indent + 2, ' ' ) << " with body" << endl;
    336362                } // if
    337363                break;
     
    344370                } // if
    345371                if ( aggInst.params ) {
    346                         os << string( indent + 2, ' ' ) << "with parameters " << endl;
     372                        os << string( indent + 2, ' ' ) << "with parameters" << endl;
    347373                        aggInst.params->printList( os, indent + 2 );
    348374                } // if
     
    355381                } // if
    356382                if ( enumeration.body ) {
    357                         os << string( indent + 2, ' ' ) << " with body " << endl;
    358                 } // if
    359                 break;
    360           case SymbolicInst:
    361                 os << "instance of type " << *symbolic.name;
    362                 if ( symbolic.actuals ) {
    363                         os << " with parameters" << endl;
    364                         symbolic.actuals->printList( os, indent + 2 );
    365                 } // if
     383                        os << string( indent + 2, ' ' ) << " with body" << endl;
     384                } // if
     385                break;
     386          case EnumConstant:
     387                os << "enumeration constant ";
    366388                break;
    367389          case Symbolic:
     
    385407                } // if
    386408                break;
     409          case SymbolicInst:
     410                os << *symbolic.name;
     411                if ( symbolic.actuals ) {
     412                        os << "(";
     413                        symbolic.actuals->printList( os, indent + 2 );
     414                        os << ")";
     415                } // if
     416                break;
    387417          case Tuple:
    388418                os << "tuple ";
    389419                if ( tuple ) {
    390                         os << "with members " << endl;
     420                        os << "with members" << endl;
    391421                        tuple->printList( os, indent + 2 );
    392422                } // if
    393423                break;
     424          case Basetypeof:
     425                os << "base-";
     426                #if defined(__GNUC__) && __GNUC__ >= 7
     427                        __attribute__((fallthrough));
     428                #endif
    394429          case Typeof:
    395430                os << "type-of expression ";
     
    400435          case Builtin:
    401436                os << DeclarationNode::builtinTypeNames[builtintype];
     437                break;
     438          case GlobalScope:
     439                break;
     440          case Qualified:
     441                qualified.parent->print( os );
     442                os << ".";
     443                qualified.child->print( os );
     444                break;
     445          case Unknown:
     446                os << "entity of unknown type ";
    402447                break;
    403448          default:
     
    406451        } // switch
    407452} // TypeData::print
     453
     454const std::string * TypeData::leafName() const {
     455        switch ( kind ) {
     456          case Unknown:
     457          case Pointer:
     458          case Reference:
     459          case EnumConstant:
     460          case GlobalScope:
     461          case Array:
     462          case Basic:
     463          case Function:
     464          case AggregateInst:
     465          case Tuple:
     466          case Typeof:
     467          case Basetypeof:
     468          case Builtin:
     469                assertf(false, "Tried to get leaf name from kind without a name: %d", kind);
     470                break;
     471          case Aggregate:
     472                return aggregate.name;
     473          case Enum:
     474                return enumeration.name;
     475          case Symbolic:
     476          case SymbolicInst:
     477                return symbolic.name;
     478          case Qualified:
     479                return qualified.child->leafName();
     480        } // switch
     481        assert(false);
     482}
    408483
    409484
     
    447522        switch ( td->kind ) {
    448523          case TypeData::Unknown:
    449                 // fill in implicit int
    450                 return new BasicType( buildQualifiers( td ), BasicType::SignedInt );
     524                        // fill in implicit int
     525                        return new BasicType( buildQualifiers( td ), BasicType::SignedInt );
    451526          case TypeData::Basic:
    452                 return buildBasicType( td );
     527                        return buildBasicType( td );
    453528          case TypeData::Pointer:
    454                 return buildPointer( td );
     529                        return buildPointer( td );
    455530          case TypeData::Array:
    456                 return buildArray( td );
     531                        return buildArray( td );
    457532          case TypeData::Reference:
    458                 return buildReference( td );
     533                        return buildReference( td );
    459534          case TypeData::Function:
    460                 return buildFunction( td );
     535                        return buildFunction( td );
    461536          case TypeData::AggregateInst:
    462                 return buildAggInst( td );
     537                        return buildAggInst( td );
    463538          case TypeData::EnumConstant:
    464                 // the name gets filled in later -- by SymTab::Validate
    465                 return new EnumInstType( buildQualifiers( td ), "" );
     539                        // the name gets filled in later -- by SymTab::Validate
     540                        return new EnumInstType( buildQualifiers( td ), "" );
    466541          case TypeData::SymbolicInst:
    467                 return buildSymbolicInst( td );;
     542                        return buildSymbolicInst( td );
    468543          case TypeData::Tuple:
    469                 return buildTuple( td );
     544                        return buildTuple( td );
    470545          case TypeData::Typeof:
    471                 return buildTypeof( td );
     546          case TypeData::Basetypeof:
     547                        return buildTypeof( td );
    472548          case TypeData::Builtin:
    473                 if(td->builtintype == DeclarationNode::Zero) {
    474                         return new ZeroType( noQualifiers );
    475                 }
    476                 else if(td->builtintype == DeclarationNode::One) {
    477                         return new OneType( noQualifiers );
    478                 }
    479                 else {
    480                         return new VarArgsType( buildQualifiers( td ) );
    481                 }
     549                        if (td->builtintype == DeclarationNode::Zero) {
     550                                return new ZeroType( noQualifiers );
     551                        }
     552                        else if (td->builtintype == DeclarationNode::One) {
     553                                return new OneType( noQualifiers );
     554                        }
     555                        else {
     556                                return new VarArgsType( buildQualifiers( td ) );
     557                        }
     558          case TypeData::GlobalScope:
     559                        return new GlobalScopeType();
     560                case TypeData::Qualified:
     561                        return new QualifiedType( buildQualifiers( td ), typebuild( td->qualified.parent ), typebuild( td->qualified.child ) );
    482562          case TypeData::Symbolic:
    483563          case TypeData::Enum:
    484564          case TypeData::Aggregate:
    485                 assert( false );
     565                        assert( false );
    486566        } // switch
     567
    487568        return nullptr;
    488569} // typebuild
     
    585666
    586667          case DeclarationNode::Float:
    587           case DeclarationNode::Float80:
    588           case DeclarationNode::Float128:
    589668          case DeclarationNode::Double:
    590669          case DeclarationNode::LongDouble:                                     // not set until below
    591                 static BasicType::Kind floattype[3][3] = {
    592                         { BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex },
    593                         { BasicType::FloatImaginary, BasicType::DoubleImaginary, BasicType::LongDoubleImaginary },
    594                         { 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, },
    595682                };
    596683
     
    605692                        genTSError( DeclarationNode::lengthNames[ td->length ], td->basictype );
    606693                } // 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
    607700                if ( td->length == DeclarationNode::Long ) {
    608701                        const_cast<TypeData *>(td)->basictype = DeclarationNode::LongDouble;
    609702                } // if
    610703
    611                 if ( td->basictype == DeclarationNode::Float80 || td->basictype == DeclarationNode::Float128 ) {
    612                         // if ( td->complextype != DeclarationNode::NoComplexType ) {
    613                         //      genTSError( DeclarationNode::complexTypeNames[ td->complextype ], td->basictype );
    614                         // }
    615                         if ( td->basictype == DeclarationNode::Float80 ) ret = BasicType::Float80;
    616                         else ret = BasicType::Float128;
    617                         break;
    618                 }
    619 
    620704                ret = floattype[ td->complextype ][ td->basictype - DeclarationNode::Float ];
     705                //printf( "XXXX %d %d %d %d\n", td->complextype, td->basictype, DeclarationNode::Float, ret );
    621706                break;
    622707
     
    858943
    859944TypeofType * buildTypeof( const TypeData * td ) {
    860         assert( td->kind == TypeData::Typeof );
     945        assert( td->kind == TypeData::Typeof || td->kind == TypeData::Basetypeof );
    861946        assert( td->typeexpr );
    862947        // assert( td->typeexpr->expr );
    863         return new TypeofType( buildQualifiers( td ), td->typeexpr->build() );
     948        return new TypeofType{
     949                buildQualifiers( td ), td->typeexpr->build(), td->kind == TypeData::Basetypeof };
    864950} // buildTypeof
    865951
     
    893979        assert( td->kind == TypeData::Function );
    894980        FunctionType * ft = new FunctionType( buildQualifiers( td ), ! td->function.params || td->function.params->hasEllipsis );
    895         buildList( td->function.params, ft->get_parameters() );
    896         buildForall( td->forall, ft->get_forall() );
     981        buildList( td->function.params, ft->parameters );
     982        buildForall( td->forall, ft->forall );
    897983        if ( td->base ) {
    898984                switch ( td->base->kind ) {
    899985                  case TypeData::Tuple:
    900                         buildList( td->base->tuple, ft->get_returnVals() );
     986                        buildList( td->base->tuple, ft->returnVals );
    901987                        break;
    902988                  default:
  • src/Parser/TypeData.h

    r7951100 rb067d9b  
    1010// Created On       : Sat May 16 15:18:36 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Feb 22 15:21:23 2018
    13 // Update Count     : 191
     12// Last Modified On : Thu Nov  1 20:56:46 2018
     13// Update Count     : 196
    1414//
    1515
     
    2626
    2727struct TypeData {
    28         enum Kind { Basic, Pointer, Array, Reference, Function, Aggregate, AggregateInst, Enum, EnumConstant, Symbolic,
    29                                 SymbolicInst, Tuple, Typeof, Builtin, Unknown };
     28        enum Kind { Basic, Pointer, Reference, Array, Function, Aggregate, AggregateInst, Enum, EnumConstant, Symbolic,
     29                                SymbolicInst, Tuple, Typeof, Basetypeof, Builtin, GlobalScope, Qualified, Unknown };
    3030
    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;
     38                bool anon;
    3839
    3940                bool tagged;
    40                 const std::string * parent;
     41                const std::string * parent = nullptr;
    4142        };
    4243
    4344        struct AggInst_t {
    44                 TypeData * aggregate;
    45                 ExpressionNode * params;
     45                TypeData * aggregate = nullptr;
     46                ExpressionNode * params = nullptr;
    4647                bool hoistType;
    4748        };
    4849
    4950        struct Array_t {
    50                 ExpressionNode * dimension;
     51                ExpressionNode * dimension = nullptr;
    5152                bool isVarLen;
    5253                bool isStatic;
     
    5455
    5556        struct Enumeration_t {
    56                 const std::string * name;
    57                 DeclarationNode * constants;
     57                const std::string * name = nullptr;
     58                DeclarationNode * constants = nullptr;
    5859                bool body;
     60                bool anon;
    5961        };
    6062
    6163        struct Function_t {
    62                 mutable DeclarationNode * params;                               // mutables modified in buildKRFunction
    63                 mutable DeclarationNode * idList;                               // old-style
    64                 mutable DeclarationNode * oldDeclList;
    65                 StatementNode * body;
    66                 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
    6769        };
    6870
    6971        struct Symbolic_t {
    70                 const std::string * name;
     72                const std::string * name = nullptr;
    7173                bool isTypedef;                                                                 // false => TYPEGENname, true => TYPEDEFname
    72                 DeclarationNode * params;
    73                 ExpressionNode * actuals;
    74                 DeclarationNode * assertions;
     74                DeclarationNode * params = nullptr;
     75                ExpressionNode * actuals = nullptr;
     76                DeclarationNode * assertions = nullptr;
     77        };
     78
     79        struct Qualified_t {                                                            // qualified type S.T
     80                TypeData * parent = nullptr;
     81                TypeData * child = nullptr;
    7582        };
    7683
     
    8693
    8794        Type::Qualifiers qualifiers;
    88         DeclarationNode * forall;
     95        DeclarationNode * forall = nullptr;
    8996
    90         // Basic_t basic;
    9197        Aggregate_t aggregate;
    9298        AggInst_t aggInst;
    9399        Array_t array;
    94100        Enumeration_t enumeration;
    95         // Variable_t variable;
    96101        Function_t function;
    97102        Symbolic_t symbolic;
    98         DeclarationNode * tuple;
    99         ExpressionNode * typeexpr;
     103        Qualified_t qualified;
     104        DeclarationNode * tuple = nullptr;
     105        ExpressionNode * typeexpr = nullptr;
    100106
    101107        TypeData( Kind k = Unknown );
     
    103109        void print( std::ostream &, int indent = 0 ) const;
    104110        TypeData * clone() const;
     111
     112        const std::string * leafName() const;
    105113};
    106114
     
    120128TupleType * buildTuple( const TypeData * );
    121129TypeofType * buildTypeof( const TypeData * );
    122 Declaration * buildDecl( const TypeData *, const std::string &, Type::StorageClasses, Expression *, Type::FuncSpecifiers funcSpec, LinkageSpec::Spec, Expression * asmName, Initializer * init = nullptr, std::list< class Attribute * > attributes = std::list< class Attribute * >() );
     130Declaration * buildDecl( const TypeData *, const std::string &, Type::StorageClasses, Expression *, Type::FuncSpecifiers funcSpec, LinkageSpec::Spec, Expression * asmName,
     131                                                 Initializer * init = nullptr, std::list< class Attribute * > attributes = std::list< class Attribute * >() );
    123132FunctionType * buildFunction( const TypeData * );
    124133void buildKRFunction( const TypeData::Function_t & function );
  • src/Parser/TypedefTable.cc

    r7951100 rb067d9b  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // TypedefTable.cc -- 
     7// TypedefTable.cc --
    88//
    99// Author           : Peter A. Buhr
    1010// Created On       : Sat May 16 15:20:13 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Jun  7 13:17:56 2018
    13 // Update Count     : 192
     12// Last Modified On : Wed Jul 25 15:32:35 2018
     13// Update Count     : 258
    1414//
    1515
     
    5151} // TypedefTable::exists
    5252
     53bool TypedefTable::existsCurr( const string & identifier ) {
     54        return kindTable.findAt( kindTable.currentScope() - 1, identifier ) != kindTable.end();
     55} // TypedefTable::exists
     56
    5357int TypedefTable::isKind( const string & identifier ) const {
    5458        KindTable::const_iterator posn = kindTable.find( identifier );
     
    7781        auto scope = kindTable.currentScope();
    7882        debugPrint( cerr << "Adding current at " << locn << " " << identifier << " as " << kindName( kind ) << " scope " << scope << endl );
    79         auto ret = kindTable.insertAt( scope, identifier, kind );
    80         if ( ! ret.second ) ret.first->second = kind;           // exists => update
     83        kindTable.insertAt( scope, identifier, kind );
    8184} // TypedefTable::addToScope
    8285
    8386void TypedefTable::addToEnclosingScope( const string & identifier, int kind, const char * locn __attribute__((unused)) ) {
    84         assert( kindTable.currentScope() >= 1 );
    85         auto scope = kindTable.currentScope() - 1;
    86         debugPrint( cerr << "Adding enclosing at " << locn << " " << identifier << " as " << kindName( kind ) << " scope " << scope << endl );
     87        auto scope = kindTable.currentScope() - 1 - kindTable.getNote( kindTable.currentScope() - 1 ).level;
     88//      auto scope = level - kindTable.getNote( kindTable.currentScope() - 1 ).level;
     89        debugPrint( cerr << "Adding enclosing at " << locn << " " << identifier << " as " << kindName( kind ) << " scope " << scope << " level " << level << " note " << kindTable.getNote( kindTable.currentScope() - 1 ).level << endl );
    8790        auto ret = kindTable.insertAt( scope, identifier, kind );
    88         if ( ! ret.second ) ret.first->second = kind;           // exists => update
     91        if ( ! ret.second ) ret.first->second = kind;   // exists => update
    8992} // TypedefTable::addToEnclosingScope
    9093
    9194void TypedefTable::enterScope() {
    92         kindTable.beginScope();
    93         debugPrint( cerr << "Entering scope " << kindTable.currentScope() << endl );
    94         debugPrint( print() );
     95        kindTable.beginScope( (Note){ 0, false } );
     96        debugPrint( cerr << "Entering scope " << kindTable.currentScope() << " level " << level << endl; print() );
    9597} // TypedefTable::enterScope
    9698
    9799void TypedefTable::leaveScope() {
    98         debugPrint( cerr << "Leaving scope " << kindTable.currentScope() << endl );
    99         debugPrint( print() );
     100        debugPrint( cerr << "Leaving scope " << kindTable.currentScope() << endl; print() );
    100101        kindTable.endScope();
    101102} // TypedefTable::leaveScope
    102103
     104void TypedefTable::up( bool forall ) {
     105        level += 1;
     106        kindTable.getNote( kindTable.currentScope() ) = (Note){ level, forall || getEnclForall() };
     107        debugPrint( cerr << "Up " << " level " << level << " note " << kindTable.getNote( level ).level << ", " << kindTable.getNote( level ).forall << endl; );
     108} // TypedefTable::up
     109
     110void TypedefTable::down() {
     111        level -= 1;
     112        debugPrint( cerr << "Down " << " level " << level << " note " << kindTable.getNote( level ).level << endl; );
     113} // TypedefTable::down
     114
    103115void TypedefTable::print( void ) const {
    104116        KindTable::size_type scope = kindTable.currentScope();
    105         debugPrint( cerr << "[" << scope << "]" );
     117        debugPrint( cerr << "[" << scope << "] " << kindTable.getNote( scope ).level << ", " << kindTable.getNote( scope ).forall << ":" );
    106118        for ( KindTable::const_iterator i = kindTable.begin(); i != kindTable.end(); i++ ) {
    107119                while ( i.get_level() != scope ) {
    108120                        --scope;
    109                         debugPrint( cerr << endl << "[" << scope << "]" );
     121                        debugPrint( cerr << endl << "[" << scope << "] " << kindTable.getNote( scope ).level << ", " << kindTable.getNote( scope ).forall << ":" );
    110122                } // while
    111123                debugPrint( cerr << " " << (*i).first << ":" << kindName( (*i).second ) );
     
    113125        while ( scope > 0 ) {
    114126                --scope;
    115                 debugPrint( cerr << endl << "[" << scope << "]" );
    116         }
     127                debugPrint( cerr << endl << "[" << scope << "] " << kindTable.getNote( scope ).level << ", " << kindTable.getNote( scope ).forall << ":" );
     128        } // while
    117129        debugPrint( cerr << endl );
    118 }
     130} // TypedefTable::print
    119131
    120132// Local Variables: //
  • src/Parser/TypedefTable.h

    r7951100 rb067d9b  
    1010// Created On       : Sat May 16 15:24:36 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Jun  7 12:10:17 2018
    13 // Update Count     : 85
     12// Last Modified On : Wed Jul 25 15:33:55 2018
     13// Update Count     : 114
    1414//
    1515
     
    2323
    2424class TypedefTable {
    25         typedef ScopedMap< std::string, int > KindTable;
     25        struct Note { size_t level; bool forall; };
     26        typedef ScopedMap< std::string, int, Note > KindTable;
    2627        KindTable kindTable;   
     28        unsigned int level = 0;
    2729  public:
    2830        ~TypedefTable();
    2931
    3032        bool exists( const std::string & identifier );
     33        bool existsCurr( const std::string & identifier );
    3134        int isKind( const std::string & identifier ) const;
    3235        void makeTypedef( const std::string & name, int kind = TYPEDEFname );
    3336        void addToScope( const std::string & identifier, int kind, const char * );
    3437        void addToEnclosingScope( const std::string & identifier, int kind, const char * );
     38        bool getEnclForall() { return kindTable.getNote( kindTable.currentScope() -  1 ).forall; }
    3539
    3640        void enterScope();
    3741        void leaveScope();
     42
     43        void up( bool );
     44        void down();
    3845
    3946        void print( void ) const;
  • src/Parser/lex.ll

    r7951100 rb067d9b  
    1010 * Created On       : Sat Sep 22 08:58:10 2001
    1111 * Last Modified By : Peter A. Buhr
    12  * Last Modified On : Thu Jun  7 08:27:40 2018
    13  * Update Count     : 679
     12 * Last Modified On : Sun Aug  4 20:53:47 2019
     13 * Update Count     : 719
    1414 */
    1515
     
    2525//**************************** Includes and Defines ****************************
    2626
     27// trigger before each matching rule's action
     28#define YY_USER_ACTION \
     29        yylloc.first_line = yylineno; \
     30        yylloc.first_column = column; \
     31        column += yyleng; \
     32        yylloc.last_column = column; \
     33        yylloc.last_line = yylineno; \
     34        yylloc.filename = yyfilename ? yyfilename : "";
    2735unsigned int column = 0;                                                                // position of the end of the last token parsed
    28 #define YY_USER_ACTION yylloc.first_line = yylineno; yylloc.first_column = column; column += yyleng; yylloc.last_column = column; yylloc.last_line = yylineno; yylloc.filename = yyfilename ? yyfilename : "";                          // trigger before each matching rule's action
    2936
    3037#include <string>
     
    3239using namespace std;
    3340
     41#include "config.h"                                                                             // configure info
    3442#include "ParseNode.h"
    3543#include "TypedefTable.h"
     
    4957#define NUMERIC_RETURN(x)       rm_underscore(); RETURN_VAL( x ) // numeric constant
    5058#define KEYWORD_RETURN(x)       RETURN_CHAR( x )                        // keyword
    51 #define QKEYWORD_RETURN(x)      typedefTable.isKind( yytext ); RETURN_VAL(x); // quasi-keyword
     59#define QKEYWORD_RETURN(x)      RETURN_VAL(x);                          // quasi-keyword
    5260#define IDENTIFIER_RETURN()     RETURN_VAL( typedefTable.isKind( yytext ) )
    53 #define ATTRIBUTE_RETURN()      RETURN_VAL( ATTR_IDENTIFIER )
     61
     62#ifdef HAVE_KEYWORDS_FLOATXX                                                            // GCC >= 7 => keyword, otherwise typedef
     63#define FLOATXX(v) KEYWORD_RETURN(v);
     64#else
     65#define FLOATXX(v) IDENTIFIER_RETURN();
     66#endif // HAVE_KEYWORDS_FLOATXX
    5467
    5568void rm_underscore() {
     
    7992identifier ([a-zA-Z_$]|{universal_char})([0-9a-zA-Z_$]|{universal_char})*
    8093
    81                                 // attribute identifier, GCC: $ in identifier
    82 attr_identifier "@"{identifier}
    83 
    8494                                // numeric constants, CFA: '_' in constant
    8595hex_quad {hex}("_"?{hex}){3}
    8696size_opt (8|16|32|64|128)?
    87 length ("ll"|"LL"|[lL]{size_opt})|("hh"|"HH"|[hH])
    88 integer_suffix_opt ("_"?(([uU]({length}?[iI]?)|([iI]{length}))|([iI]({length}?[uU]?)|([uU]{length}))|({length}([iI]?[uU]?)|([uU][iI]))|[zZ]))?
     97                                // CFA: explicit l8/l16/l32/l64/l128, char 'hh', short 'h', int 'n'
     98length ("ll"|"LL"|[lL]{size_opt})|("hh"|"HH"|[hHnN])
     99                                // CFA: size_t 'z', pointer 'p', which define a sign and length
     100integer_suffix_opt ("_"?(([uU]({length}?[iI]?)|([iI]{length}))|([iI]({length}?[uU]?)|([uU]{length}))|({length}([iI]?[uU]?)|([uU][iI]))|[zZ]|[pP]))?
    89101
    90102octal_digits ({octal})|({octal}({octal}|"_")*{octal})
     
    105117                                // GCC: D (double) and iI (imaginary) suffixes, and DL (long double)
    106118exponent "_"?[eE]"_"?[+-]?{decimal_digits}
    107 floating_size 32|64|80|128
    108 floating_length ([fFdDlL]|[lL]{floating_size})
     119floating_size 16|32|32x|64|64x|80|128|128x
     120floating_length ([fFdDlLwWqQ]|[fF]{floating_size})
    109121floating_suffix ({floating_length}?[iI]?)|([iI]{floating_length})
    110122floating_suffix_opt ("_"?({floating_suffix}|"DL"))?
     
    202214__attribute__   { KEYWORD_RETURN(ATTRIBUTE); }                  // GCC
    203215auto                    { KEYWORD_RETURN(AUTO); }
     216__auto_type             { KEYWORD_RETURN(AUTO_TYPE); }
     217basetypeof              { KEYWORD_RETURN(BASETYPEOF); }                 // CFA
    204218_Bool                   { KEYWORD_RETURN(BOOL); }                               // C99
    205219break                   { KEYWORD_RETURN(BREAK); }
     
    209223char                    { KEYWORD_RETURN(CHAR); }
    210224choose                  { KEYWORD_RETURN(CHOOSE); }                             // CFA
     225coerce                  { KEYWORD_RETURN(COERCE); }                             // CFA
    211226_Complex                { KEYWORD_RETURN(COMPLEX); }                    // C99
    212227__complex               { KEYWORD_RETURN(COMPLEX); }                    // GCC
     
    232247finally                 { KEYWORD_RETURN(FINALLY); }                    // CFA
    233248float                   { KEYWORD_RETURN(FLOAT); }
    234 _Float32                { KEYWORD_RETURN(FLOAT); }                              // GCC
    235 _Float32x               { KEYWORD_RETURN(FLOAT); }                              // GCC
    236 _Float64                { KEYWORD_RETURN(DOUBLE); }                             // GCC
    237 _Float64x               { KEYWORD_RETURN(DOUBLE); }                             // GCC
    238 __float80               { KEYWORD_RETURN(FLOAT80); }                    // GCC
    239 float80                 { KEYWORD_RETURN(FLOAT80); }                    // GCC
    240 _Float128               { KEYWORD_RETURN(FLOAT128); }                   // GCC
    241 _Float128x              { KEYWORD_RETURN(FLOAT128); }                   // GCC
    242 __float128              { KEYWORD_RETURN(FLOAT128); }                   // GCC
    243 float128                { KEYWORD_RETURN(FLOAT128); }                   // GCC
     249__float80               { KEYWORD_RETURN(uuFLOAT80); }                  // GCC
     250float80                 { KEYWORD_RETURN(uuFLOAT80); }                  // GCC
     251__float128              { KEYWORD_RETURN(uuFLOAT128); }                 // GCC
     252float128                { KEYWORD_RETURN(uuFLOAT128); }                 // GCC
     253_Float16                { FLOATXX(uFLOAT16); }                                  // GCC
     254_Float32                { FLOATXX(uFLOAT32); }                                  // GCC
     255_Float32x               { FLOATXX(uFLOAT32X); }                                 // GCC
     256_Float64                { FLOATXX(uFLOAT64); }                                  // GCC
     257_Float64x               { FLOATXX(uFLOAT64X); }                                 // GCC
     258_Float128               { FLOATXX(uFLOAT128); }                                 // GCC
     259_Float128x              { FLOATXX(uFLOAT128); }                                 // GCC
    244260for                             { KEYWORD_RETURN(FOR); }
    245261forall                  { KEYWORD_RETURN(FORALL); }                             // CFA
    246262fortran                 { KEYWORD_RETURN(FORTRAN); }
    247263ftype                   { KEYWORD_RETURN(FTYPE); }                              // CFA
     264generator               { KEYWORD_RETURN(GENERATOR); }                  // CFA
    248265_Generic                { KEYWORD_RETURN(GENERIC); }                    // C11
    249266goto                    { KEYWORD_RETURN(GOTO); }
     
    256273__inline__              { KEYWORD_RETURN(INLINE); }                             // GCC
    257274int                             { KEYWORD_RETURN(INT); }
     275int128                  { KEYWORD_RETURN(INT128); }                             // CFA
    258276__int128                { KEYWORD_RETURN(INT128); }                             // GCC
    259 int128                  { KEYWORD_RETURN(INT128); }                             // GCC
     277__int128_t              { KEYWORD_RETURN(INT128); }                             // GCC
    260278__label__               { KEYWORD_RETURN(LABEL); }                              // GCC
    261279long                    { KEYWORD_RETURN(LONG); }
     
    272290__restrict__    { KEYWORD_RETURN(RESTRICT); }                   // GCC
    273291return                  { KEYWORD_RETURN(RETURN); }
     292        /* resume                       { KEYWORD_RETURN(RESUME); }                             // CFA */
    274293short                   { KEYWORD_RETURN(SHORT); }
    275294signed                  { KEYWORD_RETURN(SIGNED); }
     
    280299_Static_assert  { KEYWORD_RETURN(STATICASSERT); }               // C11
    281300struct                  { KEYWORD_RETURN(STRUCT); }
     301        /* suspend                      { KEYWORD_RETURN(SUSPEND); }                    // CFA */
    282302switch                  { KEYWORD_RETURN(SWITCH); }
    283303thread                  { KEYWORD_RETURN(THREAD); }                             // C11
     
    294314__typeof__              { KEYWORD_RETURN(TYPEOF); }                             // GCC
    295315union                   { KEYWORD_RETURN(UNION); }
     316__uint128_t             { KEYWORD_RETURN(UINT128); }                    // GCC
    296317unsigned                { KEYWORD_RETURN(UNSIGNED); }
    297318__builtin_va_list { KEYWORD_RETURN(VALIST); }                   // GCC
     
    313334        IDENTIFIER_RETURN();
    314335}
    315 {attr_identifier} { ATTRIBUTE_RETURN(); }
    316336
    317337                                /* numeric constants */
     
    404424
    405425"@="                    { NAMEDOP_RETURN(ATassign); }                   // CFA
     426"~="                    { NAMEDOP_RETURN(ErangeUpEq); }                 // CFA
     427"-~"                    { NAMEDOP_RETURN(ErangeDown); }                 // CFA
     428"-~="                   { NAMEDOP_RETURN(ErangeDownEq); }               // CFA
    406429
    407430                                /* CFA, operator identifier */
     
    457480void yyerror( const char * errmsg ) {
    458481        SemanticErrorThrow = true;
    459         cout << (yyfilename ? yyfilename : "*unknown file*") << ':' << yylineno << ':' << column - yyleng + 1
     482        cerr << (yyfilename ? yyfilename : "*unknown file*") << ':' << yylineno << ':' << column - yyleng + 1
    460483                 << ": " << ErrorHelpers::error_str() << errmsg << " at token \"" << (yytext[0] == '\0' ? "EOF" : yytext) << '"' << endl;
    461484}
  • src/Parser/module.mk

    r7951100 rb067d9b  
    66## file "LICENCE" distributed with Cforall.
    77##
    8 ## module.mk -- 
     8## module.mk --
    99##
    1010## Author           : Peter A. Buhr
     
    3131       Parser/parserutility.cc
    3232
    33 MAINTAINERCLEANFILES += Parser/parser.output
     33SRCDEMANGLE += \
     34        Parser/LinkageSpec.cc
     35
     36
     37MOSTLYCLEANFILES += Parser/lex.cc Parser/parser.cc Parser/parser.hh Parser/parser.output
  • src/Parser/parser.yy

    r7951100 rb067d9b  
    1010// Created On       : Sat Sep  1 20:22:55 2001
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Jun  7 10:07:12 2018
    13 // Update Count     : 3527
     12// Last Modified On : Sun Aug  4 21:48:23 2019
     13// Update Count     : 4364
    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
     
    114112        } // for
    115113} // distExt
     114
     115void distInl( DeclarationNode * declaration ) {
     116        // distribute EXTENSION across all declarations
     117        for ( DeclarationNode *iter = declaration; iter != nullptr; iter = (DeclarationNode *)iter->get_next() ) {
     118                iter->set_inLine( true );
     119        } // for
     120} // distInl
     121
     122void distQual( DeclarationNode * declaration, DeclarationNode * qualifiers ) {
     123        // distribute qualifiers across all non-variable declarations in a distribution statemement
     124        for ( DeclarationNode * iter = declaration; iter != nullptr; iter = (DeclarationNode *)iter->get_next() ) {
     125                // SKULLDUGGERY: Distributions are parsed inside out, so qualifiers are added to declarations inside out. Since
     126                // addQualifiers appends to the back of the list, the forall clauses are in the wrong order (right to left). To
     127                // get the qualifiers in the correct order and still use addQualifiers (otherwise, 90% of addQualifiers has to
     128                // be copied to add to front), the appropriate forall pointers are interchanged before calling addQualifiers.
     129                DeclarationNode * clone = qualifiers->clone();
     130                if ( qualifiers->type ) {                                               // forall clause ? (handles SC)
     131                        if ( iter->type->kind == TypeData::Aggregate ) { // struct/union ?
     132                                swap( clone->type->forall, iter->type->aggregate.params );
     133                                iter->addQualifiers( clone );
     134                        } else if ( iter->type->kind == TypeData::AggregateInst && iter->type->aggInst.aggregate->aggregate.body ) { // struct/union ?
     135                                // Create temporary node to hold aggregate, call addQualifiers as above, then put nodes back together.
     136                                DeclarationNode newnode;
     137                                swap( newnode.type, iter->type->aggInst.aggregate );
     138                                swap( clone->type->forall, newnode.type->aggregate.params );
     139                                newnode.addQualifiers( clone );
     140                                swap( newnode.type, iter->type->aggInst.aggregate );
     141                        } else if ( iter->type->kind == TypeData::Function ) { // routines ?
     142                                swap( clone->type->forall, iter->type->forall );
     143                                iter->addQualifiers( clone );
     144                        } // if
     145                } else {                                                                                // just SC qualifiers
     146                        iter->addQualifiers( clone );
     147                } // if
     148        } // for
     149        delete qualifiers;
     150} // distQual
    116151
    117152// There is an ambiguity for inline generic-routine return-types and generic routines.
     
    136171} // build_postfix_name
    137172
    138 bool forall = false, xxx = false;                                               // aggregate have one or more forall qualifiers ?
     173DeclarationNode * fieldDecl( DeclarationNode * typeSpec, DeclarationNode * fieldList ) {
     174        if ( ! fieldList ) {                                                            // field declarator ?
     175                if ( ! ( typeSpec->type && (typeSpec->type->kind == TypeData::Aggregate || typeSpec->type->kind == TypeData::Enum) ) ) {
     176                        stringstream ss;
     177                        typeSpec->type->print( ss );
     178                        SemanticWarning( yylloc, Warning::SuperfluousDecl, ss.str().c_str() );
     179                        return nullptr;
     180                } // if
     181                fieldList = DeclarationNode::newName( nullptr );
     182        } // if
     183        return distAttr( typeSpec, fieldList );                         // mark all fields in list
     184} // fieldDecl
     185
     186ForCtrl * forCtrl( ExpressionNode * type, string * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {
     187        ConstantExpr * constant = dynamic_cast<ConstantExpr *>(type->expr.get());
     188        if ( constant && (constant->get_constant()->get_value() == "0" || constant->get_constant()->get_value() == "1") ) {
     189        type = new ExpressionNode( new CastExpr( maybeMoveBuild< Expression >(type), new BasicType( Type::Qualifiers(), BasicType::SignedInt ) ) );
     190        } // if
     191        return new ForCtrl(
     192                distAttr( DeclarationNode::newTypeof( type, true ), DeclarationNode::newName( index )->addInitializer( new InitializerNode( start ) ) ),
     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 );
     197} // forCtrl
     198
     199ForCtrl * forCtrl( ExpressionNode * type, ExpressionNode * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {
     200        if ( NameExpr * identifier = dynamic_cast<NameExpr *>(index->expr.get()) ) {
     201                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
     208        } else {
     209                SemanticError( yylloc, "Expression disallowed. Only loop-index name allowed" ); return nullptr;
     210        } // if
     211} // forCtrl
     212
     213
     214bool forall = false, yyy = false;                                               // aggregate have one or more forall qualifiers ?
    139215
    140216// https://www.gnu.org/software/bison/manual/bison.html#Location-Type
     
    156232
    157233// Types declaration for productions
    158 %union
    159 {
     234%union {
    160235        Token tok;
    161236        ParseNode * pn;
     
    167242        WaitForStmt * wfs;
    168243        Expression * constant;
    169         IfCtl * ifctl;
    170         ForCtl * fctl;
     244        IfCtrl * ifctl;
     245        ForCtrl * fctl;
     246        enum OperKinds compop;
    171247        LabelNode * label;
    172248        InitializerNode * in;
     
    189265%token RESTRICT                                                                                 // C99
    190266%token ATOMIC                                                                                   // C11
    191 %token FORALL MUTEX VIRTUAL                                                             // CFA
     267%token FORALL MUTEX VIRTUAL COERCE                                              // CFA
    192268%token VOID CHAR SHORT INT LONG FLOAT DOUBLE SIGNED UNSIGNED
    193269%token BOOL COMPLEX IMAGINARY                                                   // C99
    194 %token INT128 FLOAT80 FLOAT128                                                  // GCC
     270%token INT128 UINT128 uuFLOAT80 uuFLOAT128                              // GCC
     271%token uFLOAT16 uFLOAT32 uFLOAT32X uFLOAT64 uFLOAT64X uFLOAT128 // GCC
    195272%token ZERO_T ONE_T                                                                             // CFA
    196273%token VALIST                                                                                   // GCC
    197 %token TYPEOF LABEL                                                                             // GCC
     274%token AUTO_TYPE                                                                                // GCC
     275%token TYPEOF BASETYPEOF LABEL                                                  // GCC
    198276%token ENUM STRUCT UNION
    199277%token EXCEPTION                                                                                // CFA
    200 %token COROUTINE MONITOR THREAD                                                 // CFA
     278%token GENERATOR COROUTINE MONITOR THREAD                               // CFA
    201279%token OTYPE FTYPE DTYPE TTYPE TRAIT                                    // CFA
    202280%token SIZEOF OFFSETOF
     281// %token SUSPEND RESUME                                                                        // CFA
    203282%token ATTRIBUTE EXTENSION                                                              // GCC
    204283%token IF ELSE SWITCH CASE DEFAULT DO WHILE FOR BREAK CONTINUE GOTO RETURN
     
    210289%token<tok> IDENTIFIER                  QUOTED_IDENTIFIER               TYPEDEFname                             TYPEGENname
    211290%token<tok> TIMEOUT                             WOR
    212 %token<tok> ATTR_IDENTIFIER             ATTR_TYPEDEFname                ATTR_TYPEGENname
    213291%token<tok> INTEGERconstant             CHARACTERconstant               STRINGliteral
    214292%token<tok> DIRECTIVE
     
    231309%token ANDassign        ERassign        ORassign                                // &=   ^=      |=
    232310
     311%token ErangeUpEq       ErangeDown      ErangeDownEq                    // ~=   -~      -~=
    233312%token ATassign                                                                                 // @=
    234313
    235 %type<tok> identifier  no_attr_identifier
    236 %type<tok> identifier_or_type_name  no_attr_identifier_or_type_name  attr_name
     314%type<tok> identifier
     315%type<tok> identifier_or_type_name  attr_name
    237316%type<tok> quasi_keyword
    238317%type<constant> string_literal
     
    252331%type<en> argument_expression_list              argument_expression                     default_initialize_opt
    253332%type<ifctl> if_control_expression
    254 %type<fctl> for_control_expression
     333%type<fctl> for_control_expression              for_control_expression_list
     334%type<compop> inclexcl
    255335%type<en> subrange
    256336%type<decl> asm_name_opt
    257 %type<en> asm_operands_opt asm_operands_list asm_operand
     337%type<en> asm_operands_opt                              asm_operands_list                       asm_operand
    258338%type<label> label_list
    259339%type<en> asm_clobbers_list_opt
    260340%type<flag> asm_volatile_opt
    261341%type<en> handler_predicate_opt
    262 %type<genexpr> generic_association generic_assoc_list
     342%type<genexpr> generic_association              generic_assoc_list
    263343
    264344// statements
     
    304384%type<en> enumerator_value_opt
    305385
    306 %type<decl> exception_declaration external_definition external_definition_list external_definition_list_no_pop_push external_definition_list_opt
    307 
    308 %type<decl> field_declaration field_declaration_list_opt field_declarator_opt field_declaring_list
    309 %type<en> field field_list field_name fraction_constants_opt
     386%type<decl> external_definition external_definition_list external_definition_list_opt
     387
     388%type<decl> exception_declaration
     389
     390%type<decl> field_declaration_list_opt field_declaration field_declaring_list_opt field_declarator field_abstract_list_opt field_abstract
     391%type<en> field field_name_list field_name fraction_constants_opt
    310392
    311393%type<decl> external_function_definition function_definition function_array function_declarator function_no_ptr function_ptr
     
    320402%type<decl> cfa_array_parameter_1st_dimension
    321403
    322 %type<decl> cfa_trait_declaring_list cfa_declaration cfa_field_declaring_list
     404%type<decl> cfa_trait_declaring_list cfa_declaration cfa_field_declaring_list cfa_field_abstract_list
    323405%type<decl> cfa_function_declaration cfa_function_return cfa_function_specifier
    324406
     
    355437%type<decl> type_parameter type_parameter_list type_initializer_opt
    356438
    357 %type<en> type_list
     439%type<en> type_parameters_opt type_list
    358440
    359441%type<decl> type_qualifier type_qualifier_name forall type_qualifier_list_opt type_qualifier_list
     
    390472//   Foo ( *fp )( int );
    391473//   `---'                                              matches start of TYPEGENname '('
    392 // Must be:
     474// must be:
    393475//   Foo( int ) ( *fp )( int );
     476// The same problem occurs here:
     477//   forall( otype T ) struct Foo { T v; } ( *fp )( int );
     478// must be:
     479//   forall( otype T ) struct Foo { T v; } ( int ) ( *fp )( int );
    394480
    395481// Order of these lines matters (low-to-high precedence).
    396482%precedence TYPEGENname
     483%precedence '}'
    397484%precedence '('
     485
     486// %precedence RESUME
     487// %precedence '{'
     488// %precedence ')'
    398489
    399490%locations                                                                                              // support location tracking for error messages
     
    457548identifier:
    458549        IDENTIFIER
    459         | ATTR_IDENTIFIER                                                                       // CFA
    460550        | quasi_keyword
    461         ;
    462 
    463 no_attr_identifier:
    464         IDENTIFIER
    465         | quasi_keyword
     551        | '@'                                                                                           // CFA
     552                { Token tok = { new string( DeclarationNode::anonymous.newName() ), yylval.tok.loc }; $$ = tok; }
    466553        ;
    467554
     
    502589        | '(' comma_expression ')' '`' IDENTIFIER                       // CFA, postfix call
    503590                { $$ = new ExpressionNode( build_func( new ExpressionNode( build_postfix_name( $5 ) ), $2 ) ); }
    504         | type_name '.' no_attr_identifier                                      // CFA, nested type
    505                 // { SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; }
    506                 { $$ = nullptr; }
    507         | type_name '.' '[' field_list ']'                                      // CFA, nested type / tuple field selector
    508                 // { SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; }
    509                 { $$ = nullptr; }
     591        | type_name '.' identifier                                                      // CFA, nested type
     592                { SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; }
     593        | type_name '.' '[' field_name_list ']'                         // CFA, nested type / tuple field selector
     594                { SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; }
    510595        | GENERIC '(' assignment_expression ',' generic_assoc_list ')' // C11
    511596                {
     
    514599                        $$ = new ExpressionNode( $5 );
    515600                }
     601        // | RESUME '(' comma_expression ')'
     602        //      { SemanticError( yylloc, "Resume expression is currently unimplemented." ); $$ = nullptr; }
     603        // | RESUME '(' comma_expression ')' compound_statement
     604        //      { SemanticError( yylloc, "Resume expression is currently unimplemented." ); $$ = nullptr; }
    516605        ;
    517606
     
    553642        | postfix_expression '(' argument_expression_list ')'
    554643                { $$ = new ExpressionNode( build_func( $1, $3 ) ); }
    555         | postfix_expression '.' no_attr_identifier
     644        | postfix_expression '.' identifier
    556645                { $$ = new ExpressionNode( build_fieldSel( $1, build_varref( $3 ) ) ); }
    557646        | postfix_expression '.' INTEGERconstant                        // CFA, tuple index
     
    559648        | postfix_expression FLOATING_FRACTIONconstant          // CFA, tuple index
    560649                { $$ = new ExpressionNode( build_fieldSel( $1, build_field_name_FLOATING_FRACTIONconstant( *$2 ) ) ); }
    561         | postfix_expression '.' '[' field_list ']'                     // CFA, tuple field selector
     650        | postfix_expression '.' '[' field_name_list ']'        // CFA, tuple field selector
    562651                { $$ = new ExpressionNode( build_fieldSel( $1, build_tuple( $4 ) ) ); }
    563         | postfix_expression ARROW no_attr_identifier
    564                 {
    565                         $$ = new ExpressionNode( build_pfieldSel( $1, *$3 == "0" || *$3 == "1" ? build_constantInteger( *$3 ) : build_varref( $3 ) ) );
    566                 }
     652        | postfix_expression ARROW identifier
     653                { $$ = new ExpressionNode( build_pfieldSel( $1, build_varref( $3 ) ) ); }
    567654        | postfix_expression ARROW INTEGERconstant                      // CFA, tuple index
    568655                { $$ = new ExpressionNode( build_pfieldSel( $1, build_constantInteger( *$3 ) ) ); }
    569         | postfix_expression ARROW '[' field_list ']'           // CFA, tuple field selector
     656        | postfix_expression ARROW '[' field_name_list ']'      // CFA, tuple field selector
    570657                { $$ = new ExpressionNode( build_pfieldSel( $1, build_tuple( $4 ) ) ); }
    571658        | postfix_expression ICR
     
    586673
    587674argument_expression_list:
    588         argument_expression
     675        // empty
     676                { $$ = nullptr; }
     677        | argument_expression
    589678        | argument_expression_list ',' argument_expression
    590679                { $$ = (ExpressionNode *)( $1->set_last( $3 )); }
     
    592681
    593682argument_expression:
    594         // empty
    595                 { $$ = nullptr; }
    596         // | '@'                                                                                                // use default argument
    597         //      { $$ = new ExpressionNode( build_constantInteger( *new string( "2" ) ) ); }
     683        '@'                                                                                                     // CFA, default parameter
     684                { SemanticError( yylloc, "Default parameter for argument is currently unimplemented." ); $$ = nullptr; }
     685                // { $$ = new ExpressionNode( build_constantInteger( *new string( "2" ) ) ); }
    598686        | assignment_expression
    599687        ;
    600688
    601 field_list:                                                                                             // CFA, tuple field selector
     689field_name_list:                                                                                // CFA, tuple field selector
    602690        field
    603         | field_list ',' field                                          { $$ = (ExpressionNode *)$1->set_last( $3 ); }
     691        | field_name_list ',' field                                     { $$ = (ExpressionNode *)$1->set_last( $3 ); }
    604692        ;
    605693
     
    608696        | FLOATING_DECIMALconstant field
    609697                { $$ = new ExpressionNode( build_fieldSel( new ExpressionNode( build_field_name_FLOATING_DECIMALconstant( *$1 ) ), maybeMoveBuild<Expression>( $2 ) ) ); }
    610         | FLOATING_DECIMALconstant '[' field_list ']'
     698        | FLOATING_DECIMALconstant '[' field_name_list ']'
    611699                { $$ = new ExpressionNode( build_fieldSel( new ExpressionNode( build_field_name_FLOATING_DECIMALconstant( *$1 ) ), build_tuple( $3 ) ) ); }
    612700        | field_name '.' field
    613701                { $$ = new ExpressionNode( build_fieldSel( $1, maybeMoveBuild<Expression>( $3 ) ) ); }
    614         | field_name '.' '[' field_list ']'
     702        | field_name '.' '[' field_name_list ']'
    615703                { $$ = new ExpressionNode( build_fieldSel( $1, build_tuple( $4 ) ) ); }
    616704        | field_name ARROW field
    617705                { $$ = new ExpressionNode( build_pfieldSel( $1, maybeMoveBuild<Expression>( $3 ) ) ); }
    618         | field_name ARROW '[' field_list ']'
     706        | field_name ARROW '[' field_name_list ']'
    619707                { $$ = new ExpressionNode( build_pfieldSel( $1, build_tuple( $4 ) ) ); }
    620708        ;
     
    625713        | FLOATINGconstant fraction_constants_opt
    626714                { $$ = new ExpressionNode( build_field_name_fraction_constants( build_field_name_FLOATINGconstant( *$1 ), $2 ) ); }
    627         | no_attr_identifier fraction_constants_opt
     715        | identifier fraction_constants_opt
    628716                {
    629717                        $$ = new ExpressionNode( build_field_name_fraction_constants( build_varref( $1 ), $2 ) );
     
    683771        | ALIGNOF '(' type_no_function ')'                                      // GCC, type alignment
    684772                { $$ = new ExpressionNode( new AlignofExpr( maybeMoveBuildType( $3 ) ) ); }
    685         | OFFSETOF '(' type_no_function ',' no_attr_identifier ')'
     773        | OFFSETOF '(' type_no_function ',' identifier ')'
    686774                { $$ = new ExpressionNode( build_offsetOf( $3, build_varref( $5 ) ) ); }
    687         | ATTR_IDENTIFIER
    688                 { $$ = new ExpressionNode( new AttrExpr( build_varref( $1 ), maybeMoveBuild< Expression >( (ExpressionNode *)nullptr ) ) ); }
    689         | ATTR_IDENTIFIER '(' argument_expression ')'
    690                 { $$ = new ExpressionNode( new AttrExpr( build_varref( $1 ), maybeMoveBuild< Expression >( $3 ) ) ); }
    691         | ATTR_IDENTIFIER '(' type ')'
    692                 { $$ = new ExpressionNode( new AttrExpr( build_varref( $1 ), maybeMoveBuildType( $3 ) ) ); }
    693775        ;
    694776
     
    711793        | '(' type_no_function ')' cast_expression
    712794                { $$ = new ExpressionNode( build_cast( $2, $4 ) ); }
     795                // keyword cast cannot be grouped because of reduction in aggregate_key
     796        | '(' GENERATOR '&' ')' cast_expression                         // CFA
     797                { $$ = new ExpressionNode( build_keyword_cast( KeywordCastExpr::Coroutine, $5 ) ); }
    713798        | '(' COROUTINE '&' ')' cast_expression                         // CFA
    714799                { $$ = new ExpressionNode( build_keyword_cast( KeywordCastExpr::Coroutine, $5 ) ); }
     
    722807        | '(' VIRTUAL type_no_function ')' cast_expression      // CFA
    723808                { $$ = new ExpressionNode( new VirtualCastExpr( maybeMoveBuild< Expression >( $5 ), maybeMoveBuildType( $3 ) ) ); }
     809        | '(' RETURN type_no_function ')' cast_expression       // CFA
     810                { SemanticError( yylloc, "Return cast is currently unimplemented." ); $$ = nullptr; }
     811        | '(' COERCE type_no_function ')' cast_expression       // CFA
     812                { SemanticError( yylloc, "Coerce cast is currently unimplemented." ); $$ = nullptr; }
     813        | '(' qualifier_cast_list ')' cast_expression           // CFA
     814                { SemanticError( yylloc, "Qualifier cast is currently unimplemented." ); $$ = nullptr; }
    724815//      | '(' type_no_function ')' tuple
    725816//              { $$ = new ExpressionNode( build_cast( $2, $4 ) ); }
     817        ;
     818
     819qualifier_cast_list:
     820        cast_modifier type_qualifier_name
     821        | cast_modifier MUTEX
     822        | qualifier_cast_list cast_modifier type_qualifier_name
     823        | qualifier_cast_list cast_modifier MUTEX
     824        ;
     825
     826cast_modifier:
     827        '-'
     828        | '+'
    726829        ;
    727830
     
    9041007
    9051008labeled_statement:
    906                 // labels cannot be identifiers 0 or 1 or ATTR_IDENTIFIER
     1009                // labels cannot be identifiers 0 or 1
    9071010        identifier_or_type_name ':' attribute_list_opt statement
    908                 {
    909                         $$ = $4->add_label( $1, $3 );
    910                 }
     1011                { $$ = $4->add_label( $1, $3 ); }
    9111012        ;
    9121013
     
    9241025        statement_decl
    9251026        | statement_decl_list statement_decl
    926                 { if ( $1 != 0 ) { $1->set_last( $2 ); $$ = $1; } }
     1027                { assert( $1 ); $1->set_last( $2 ); $$ = $1; }
    9271028        ;
    9281029
     
    9311032                { $$ = new StatementNode( $1 ); }
    9321033        | EXTENSION declaration                                                         // GCC
    933                 {
    934                         distExt( $2 );
    935                         $$ = new StatementNode( $2 );
    936                 }
     1034                { distExt( $2 ); $$ = new StatementNode( $2 ); }
    9371035        | function_definition
    9381036                { $$ = new StatementNode( $1 ); }
    9391037        | EXTENSION function_definition                                         // GCC
    940                 {
    941                         distExt( $2 );
    942                         $$ = new StatementNode( $2 );
    943                 }
     1038                { distExt( $2 ); $$ = new StatementNode( $2 ); }
    9441039        | statement
    9451040        ;
     
    9481043        statement
    9491044        | statement_list_nodecl statement
    950                 { if ( $1 != 0 ) { $1->set_last( $2 ); $$ = $1; } }
     1045                { assert( $1 ); $1->set_last( $2 ); $$ = $1; }
    9511046        ;
    9521047
     
    9921087if_control_expression:
    9931088        comma_expression
    994                 { $$ = new IfCtl( nullptr, $1 ); }
     1089                { $$ = new IfCtrl( nullptr, $1 ); }
    9951090        | c_declaration                                                                         // no semi-colon
    996                 { $$ = new IfCtl( $1, nullptr ); }
     1091                { $$ = new IfCtrl( $1, nullptr ); }
    9971092        | cfa_declaration                                                                       // no semi-colon
    998                 { $$ = new IfCtl( $1, nullptr ); }
     1093                { $$ = new IfCtrl( $1, nullptr ); }
    9991094        | declaration comma_expression                                          // semi-colon separated
    1000                 { $$ = new IfCtl( $1, $2 ); }
     1095                { $$ = new IfCtrl( $1, $2 ); }
    10011096        ;
    10021097
     
    10541149        WHILE '(' push if_control_expression ')' statement pop
    10551150                { $$ = new StatementNode( build_while( $4, $6 ) ); }
     1151        | WHILE '(' ')' statement                                                       // CFA => while ( 1 )
     1152                { $$ = new StatementNode( build_while( new IfCtrl( nullptr, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ), $4 ) ); }
    10561153        | DO statement WHILE '(' comma_expression ')' ';'
    10571154                { $$ = new StatementNode( build_do_while( $5, $2 ) ); }
    1058         | FOR '(' push for_control_expression ')' statement pop
     1155        | DO statement WHILE '(' ')' ';'                                        // CFA => do while( 1 )
     1156                { $$ = new StatementNode( build_do_while( new ExpressionNode( build_constantInteger( *new string( "1" ) ) ), $2 ) ); }
     1157        | FOR '(' push for_control_expression_list ')' statement pop
    10591158                { $$ = new StatementNode( build_for( $4, $6 ) ); }
     1159        | FOR '(' ')' statement                                                         // CFA => for ( ;; )
     1160                { $$ = new StatementNode( build_for( new ForCtrl( (ExpressionNode * )nullptr, (ExpressionNode * )nullptr, (ExpressionNode * )nullptr ), $4 ) ); }
     1161        ;
     1162
     1163for_control_expression_list:
     1164        for_control_expression
     1165        | for_control_expression_list ':' for_control_expression
     1166                // ForCtrl + ForCtrl:
     1167                //    init + init => multiple declaration statements that are hoisted
     1168                //    condition + condition => (expression) && (expression)
     1169                //    change + change => (expression), (expression)
     1170                {
     1171                        $1->init->set_last( $3->init );
     1172                        if ( $1->condition ) {
     1173                                if ( $3->condition ) {
     1174                                        $1->condition->expr.reset( new LogicalExpr( $1->condition->expr.release(), $3->condition->expr.release(), true ) );
     1175                                } // if
     1176                        } else $1->condition = $3->condition;
     1177                        if ( $1->change ) {
     1178                                if ( $3->change ) {
     1179                                        $1->change->expr.reset( new CommaExpr( $1->change->expr.release(), $3->change->expr.release() ) );
     1180                                } // if
     1181                        } else $1->change = $3->change;
     1182                        $$ = $1;
     1183                }
    10601184        ;
    10611185
    10621186for_control_expression:
    1063         comma_expression_opt ';' comma_expression_opt ';' comma_expression_opt
    1064                 { $$ = new ForCtl( $1, $3, $5 ); }
    1065         | declaration comma_expression_opt ';' comma_expression_opt // C99
    1066                 { $$ = new ForCtl( $1, $2, $4 ); }
     1187        ';' comma_expression_opt ';' comma_expression_opt
     1188                { $$ = new ForCtrl( (ExpressionNode * )nullptr, $2, $4 ); }
     1189        | comma_expression ';' comma_expression_opt ';' comma_expression_opt
     1190                { $$ = new ForCtrl( $1, $3, $5 ); }
     1191        | declaration comma_expression_opt ';' comma_expression_opt // C99, declaration has ';'
     1192                { $$ = new ForCtrl( $1, $2, $4 ); }
     1193
     1194        | comma_expression                                                                      // CFA
     1195                { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), new ExpressionNode( build_constantInteger( *new string( "0" ) ) ),
     1196                                                OperKinds::LThan, $1->clone(), new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); }
     1197        | comma_expression inclexcl comma_expression            // CFA
     1198                { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), $1->clone(), $2, $3, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); }
     1199        | comma_expression inclexcl comma_expression '~' comma_expression // CFA
     1200                { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), $1->clone(), $2, $3, $5 ); }
     1201        | comma_expression ';' comma_expression                         // CFA
     1202                { $$ = forCtrl( $3, $1, new ExpressionNode( build_constantInteger( *new string( "0" ) ) ),
     1203                                                OperKinds::LThan, $3->clone(), new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); }
     1204        | comma_expression ';' comma_expression inclexcl comma_expression // CFA
     1205                { $$ = forCtrl( $3, $1, $3->clone(), $4, $5, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); }
     1206        | comma_expression ';' comma_expression inclexcl comma_expression '~' comma_expression // CFA
     1207                { $$ = forCtrl( $3, $1, $3->clone(), $4, $5, $7 ); }
     1208
     1209                // There is a S/R conflicit if ~ and -~ are factored out.
     1210        | comma_expression ';' comma_expression '~' '@'         // CFA
     1211                { $$ = forCtrl( $3, $1, $3->clone(), OperKinds::LThan, nullptr, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); }
     1212        | comma_expression ';' comma_expression ErangeDown '@' // CFA
     1213                { $$ = forCtrl( $3, $1, $3->clone(), OperKinds::GThan, nullptr, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); }
     1214        | comma_expression ';' comma_expression '~' '@' '~' comma_expression // CFA
     1215                { $$ = forCtrl( $3, $1, $3->clone(), OperKinds::LThan, nullptr, $7 ); }
     1216        | comma_expression ';' comma_expression ErangeDown '@' '~' comma_expression // CFA
     1217                { $$ = forCtrl( $3, $1, $3->clone(), OperKinds::GThan, nullptr, $7 ); }
     1218        | comma_expression ';' comma_expression '~' '@' '~' '@' // CFA
     1219                { $$ = forCtrl( $3, $1, $3->clone(), OperKinds::LThan, nullptr, nullptr ); }
     1220        ;
     1221
     1222inclexcl:
     1223        '~'
     1224                { $$ = OperKinds::LThan; }
     1225        | ErangeUpEq
     1226                { $$ = OperKinds::LEThan; }
     1227        | ErangeDown
     1228                { $$ = OperKinds::GThan; }
     1229        | ErangeDownEq
     1230                { $$ = OperKinds::GEThan; }
    10671231        ;
    10681232
     
    10971261        | RETURN comma_expression_opt ';'
    10981262                { $$ = new StatementNode( build_return( $2 ) ); }
    1099         | RETURN '{' initializer_list_opt comma_opt '}'
     1263        | RETURN '{' initializer_list_opt comma_opt '}' ';'
    11001264                { SemanticError( yylloc, "Initializer return is currently unimplemented." ); $$ = nullptr; }
     1265        // | SUSPEND ';'
     1266        //      { SemanticError( yylloc, "Suspend expression is currently unimplemented." ); $$ = nullptr; }
     1267        // | SUSPEND compound_statement ';'
     1268        //      { SemanticError( yylloc, "Suspend expression is currently unimplemented." ); $$ = nullptr; }
    11011269        | THROW assignment_expression_opt ';'                           // handles rethrow
    11021270                { $$ = new StatementNode( build_throw( $2 ) ); }
     
    11361304
    11371305waitfor:
    1138         WAITFOR '(' identifier ')'
    1139                 {
    1140                         $$ = new ExpressionNode( new NameExpr( *$3 ) );
    1141                         delete $3;
    1142                 }
    1143         | WAITFOR '(' identifier ',' argument_expression_list ')'
    1144                 {
    1145                         $$ = new ExpressionNode( new NameExpr( *$3 ) );
    1146                         $$->set_last( $5 );
    1147                         delete $3;
    1148                 }
     1306        WAITFOR '(' cast_expression ')'
     1307                { $$ = $3; }
     1308        | WAITFOR '(' cast_expression ',' argument_expression_list ')'
     1309                { $$ = (ExpressionNode *)$3->set_last( $5 ); }
    11491310        ;
    11501311
     
    11631324                { $$ = build_waitfor_timeout( nullptr, $3, $1 ); }
    11641325                // "else" must be conditional after timeout or timeout is never triggered (i.e., it is meaningless)
     1326        | when_clause_opt timeout statement WOR ELSE statement
     1327                { SemanticError( yylloc, "else clause must be conditional after timeout or timeout never triggered." ); $$ = nullptr; }
    11651328        | when_clause_opt timeout statement WOR when_clause ELSE statement
    11661329                { $$ = build_waitfor_timeout( $2, $3, $1, $7, $5 ); }
     
    11841347
    11851348handler_clause:
    1186         handler_key '(' push exception_declaration pop handler_predicate_opt ')' compound_statement pop
     1349        handler_key '(' push exception_declaration pop handler_predicate_opt ')' compound_statement
    11871350                { $$ = new StatementNode( build_catch( $1, $4, $6, $8 ) ); }
    1188         | handler_clause handler_key '(' push exception_declaration pop handler_predicate_opt ')' compound_statement pop
     1351        | handler_clause handler_key '(' push exception_declaration pop handler_predicate_opt ')' compound_statement
    11891352                { $$ = (StatementNode *)$1->set_last( new StatementNode( build_catch( $2, $5, $7, $9 ) ) ); }
    11901353        ;
     
    12121375        | type_specifier_nobody variable_abstract_declarator
    12131376                { $$ = $2->addType( $1 ); }
    1214         | cfa_abstract_declarator_tuple no_attr_identifier      // CFA
     1377        | cfa_abstract_declarator_tuple identifier                      // CFA
    12151378                { $$ = $1->addName( $2 ); }
    12161379        | cfa_abstract_declarator_tuple                                         // CFA
     
    12761439
    12771440label_list:
    1278         no_attr_identifier
     1441        identifier
    12791442                {
    12801443                        $$ = new LabelNode(); $$->labels.push_back( *$1 );
    12811444                        delete $1;                                                                      // allocated by lexer
    12821445                }
    1283         | label_list ',' no_attr_identifier
     1446        | label_list ',' identifier
    12841447                {
    12851448                        $$ = $1; $1->labels.push_back( *$3 );
     
    13261489
    13271490local_label_list:                                                                               // GCC, local label
    1328         no_attr_identifier_or_type_name
    1329         | local_label_list ',' no_attr_identifier_or_type_name
     1491        identifier_or_type_name
     1492        | local_label_list ',' identifier_or_type_name
    13301493        ;
    13311494
     
    14491612                        $$ = $2->addTypedef();
    14501613                }
    1451         | cfa_typedef_declaration pop ',' push no_attr_identifier
     1614        | cfa_typedef_declaration pop ',' push identifier
    14521615                {
    14531616                        typedefTable.addToEnclosingScope( *$5, TYPEDEFname, "3" );
     
    14891652typedef_expression:
    14901653                // GCC, naming expression type: typedef name = exp; gives a name to the type of an expression
    1491         TYPEDEF no_attr_identifier '=' assignment_expression
     1654        TYPEDEF identifier '=' assignment_expression
    14921655                {
    14931656                        // $$ = DeclarationNode::newName( 0 );                  // unimplemented
    14941657                        SemanticError( yylloc, "Typedef expression is currently unimplemented." ); $$ = nullptr;
    14951658                }
    1496         | typedef_expression pop ',' push no_attr_identifier '=' assignment_expression
     1659        | typedef_expression pop ',' push identifier '=' assignment_expression
    14971660                {
    14981661                        // $$ = DeclarationNode::newName( 0 );                  // unimplemented
     
    16631826        | INT128
    16641827                { $$ = DeclarationNode::newBasicType( DeclarationNode::Int128 ); }
     1828        | UINT128
     1829                { $$ = DeclarationNode::newBasicType( DeclarationNode::Int128 )->addType( DeclarationNode::newSignedNess( DeclarationNode::Unsigned ) ); }
    16651830        | FLOAT
    16661831                { $$ = DeclarationNode::newBasicType( DeclarationNode::Float ); }
    1667         | FLOAT80
    1668                 { $$ = DeclarationNode::newBasicType( DeclarationNode::Float80 ); }
    1669         | FLOAT128
    1670                 { $$ = DeclarationNode::newBasicType( DeclarationNode::Float128 ); }
    16711832        | DOUBLE
    16721833                { $$ = DeclarationNode::newBasicType( DeclarationNode::Double ); }
     1834        | uuFLOAT80
     1835                { $$ = DeclarationNode::newBasicType( DeclarationNode::uuFloat80 ); }
     1836        | uuFLOAT128
     1837                { $$ = DeclarationNode::newBasicType( DeclarationNode::uuFloat128 ); }
     1838        | uFLOAT16
     1839                { $$ = DeclarationNode::newBasicType( DeclarationNode::uFloat16 ); }
     1840        | uFLOAT32
     1841                { $$ = DeclarationNode::newBasicType( DeclarationNode::uFloat32 ); }
     1842        | uFLOAT32X
     1843                { $$ = DeclarationNode::newBasicType( DeclarationNode::uFloat32x ); }
     1844        | uFLOAT64
     1845                { $$ = DeclarationNode::newBasicType( DeclarationNode::uFloat64 ); }
     1846        | uFLOAT64X
     1847                { $$ = DeclarationNode::newBasicType( DeclarationNode::uFloat64x ); }
     1848        | uFLOAT128
     1849                { $$ = DeclarationNode::newBasicType( DeclarationNode::uFloat128 ); }
    16731850        | COMPLEX                                                                                       // C99
    16741851                { $$ = DeclarationNode::newComplexType( DeclarationNode::Complex ); }
     
    16851862        | VALIST                                                                                        // GCC, __builtin_va_list
    16861863                { $$ = DeclarationNode::newBuiltinType( DeclarationNode::Valist ); }
     1864        | AUTO_TYPE
     1865                { $$ = DeclarationNode::newBuiltinType( DeclarationNode::AutoType ); }
    16871866        ;
    16881867
     
    17181897
    17191898indirect_type:
    1720         TYPEOF '(' type ')'                                                                     // GCC: typeof(x) y;
     1899        TYPEOF '(' type ')'                                                                     // GCC: typeof( x ) y;
    17211900                { $$ = $3; }
    1722         | TYPEOF '(' comma_expression ')'                                       // GCC: typeof(a+b) y;
     1901        | TYPEOF '(' comma_expression ')'                                       // GCC: typeof( a+b ) y;
    17231902                { $$ = DeclarationNode::newTypeof( $3 ); }
    1724         | ATTR_TYPEGENname '(' type ')'                                         // CFA: e.g., @type(x) y;
    1725                 { $$ = DeclarationNode::newAttr( $1, $3 ); }
    1726         | ATTR_TYPEGENname '(' comma_expression ')'                     // CFA: e.g., @type(a+b) y;
    1727                 { $$ = DeclarationNode::newAttr( $1, $3 ); }
     1903        | BASETYPEOF '(' type ')'                                                       // CFA: basetypeof( x ) y;
     1904                { $$ = DeclarationNode::newTypeof( new ExpressionNode( new TypeExpr( maybeMoveBuildType( $3 ) ) ), true ); }
     1905        | BASETYPEOF '(' comma_expression ')'                           // CFA: basetypeof( a+b ) y;
     1906                { $$ = DeclarationNode::newTypeof( $3, true ); }
    17281907        | ZERO_T                                                                                        // CFA
    17291908                { $$ = DeclarationNode::newBuiltinType( DeclarationNode::Zero ); }
     
    17491928                { $$ = $3->addQualifiers( $1 ); }
    17501929        | sue_type_specifier type_qualifier
    1751                 { $$ = $1->addQualifiers( $2 ); }
     1930                {
     1931                        if ( $2->type != nullptr && $2->type->forall ) forall = true; // remember generic type
     1932                        $$ = $1->addQualifiers( $2 );
     1933                }
    17521934        ;
    17531935
     
    17921974                { $$ = DeclarationNode::newFromTypedef( $1 ); }
    17931975        | '.' TYPEDEFname
    1794                 { SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; }
     1976                { $$ = DeclarationNode::newQualifiedType( DeclarationNode::newFromGlobalScope(), DeclarationNode::newFromTypedef( $2 ) ); }
    17951977        | type_name '.' TYPEDEFname
    1796                 { SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; }
     1978                { $$ = DeclarationNode::newQualifiedType( $1, DeclarationNode::newFromTypedef( $3 ) ); }
    17971979        | typegen_name
    17981980        | '.' typegen_name
    1799                 { SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; }
     1981                { $$ = DeclarationNode::newQualifiedType( DeclarationNode::newFromGlobalScope(), $2 ); }
    18001982        | type_name '.' typegen_name
    1801                 { SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; }
     1983                { $$ = DeclarationNode::newQualifiedType( $1, $3 ); }
    18021984        ;
    18031985
     
    18212003        ;
    18222004
     2005fred:
     2006        // empty
     2007                { yyy = false; }
     2008        ;
     2009
    18232010aggregate_type:                                                                                 // struct, union
    1824         aggregate_key attribute_list_opt '{' field_declaration_list_opt '}'
    1825                 { $$ = DeclarationNode::newAggregate( $1, new string( DeclarationNode::anonymous.newName() ), nullptr, $4, true )->addQualifiers( $2 ); }
    1826         | aggregate_key attribute_list_opt no_attr_identifier
    1827                 {
    1828                         typedefTable.makeTypedef( *$3, forall ? TYPEGENname : TYPEDEFname ); // create typedef
    1829                         //if ( forall ) typedefTable.changeKind( *$3, TYPEGENname ); // possibly update
     2011        aggregate_key attribute_list_opt
     2012                { forall = false; }                                                             // reset
     2013          '{' field_declaration_list_opt '}' type_parameters_opt
     2014                { $$ = DeclarationNode::newAggregate( $1, nullptr, $7, $5, true )->addQualifiers( $2 ); }
     2015        | aggregate_key attribute_list_opt identifier fred
     2016                {
     2017                        typedefTable.makeTypedef( *$3, forall || typedefTable.getEnclForall() ? TYPEGENname : TYPEDEFname ); // create typedef
    18302018                        forall = false;                                                         // reset
    18312019                }
    1832           '{' field_declaration_list_opt '}'
    1833                 { $$ = DeclarationNode::newAggregate( $1, $3, nullptr, $6, true )->addQualifiers( $2 ); }
    1834         | aggregate_key attribute_list_opt type_name
    1835                 {
    1836                         typedefTable.makeTypedef( *$3->type->symbolic.name, forall ? TYPEGENname : TYPEDEFname ); // create typedef
    1837                         //if ( forall ) typedefTable.changeKind( *$3->type->symbolic.name, TYPEGENname ); // possibly update
     2020          '{' field_declaration_list_opt '}' type_parameters_opt
     2021                { $$ = DeclarationNode::newAggregate( $1, $3, $9, $7, true )->addQualifiers( $2 ); }
     2022        | aggregate_key attribute_list_opt type_name fred
     2023                {
     2024                        // for type_name can be a qualified type name S.T, in which case only the last name in the chain needs a typedef (other names in the chain should already have one)
     2025                        typedefTable.makeTypedef( *$3->type->leafName(), forall || typedefTable.getEnclForall() ? TYPEGENname : TYPEDEFname ); // create typedef
    18382026                        forall = false;                                                         // reset
    18392027                }
    1840           '{' field_declaration_list_opt '}'
    1841                 { $$ = DeclarationNode::newAggregate( $1, $3->type->symbolic.name, nullptr, $6, true )->addQualifiers( $2 ); }
    1842         | aggregate_key attribute_list_opt '(' type_list ')' '{' field_declaration_list_opt '}' // CFA
    1843                 { $$ = DeclarationNode::newAggregate( $1, new string( DeclarationNode::anonymous.newName() ), $4, $7, false )->addQualifiers( $2 ); }
     2028          '{' field_declaration_list_opt '}' type_parameters_opt
     2029                { $$ = DeclarationNode::newAggregate( $1, $3->type->symbolic.name, $9, $7, true )->addQualifiers( $2 ); }
    18442030        | aggregate_type_nobody
    18452031        ;
    18462032
     2033type_parameters_opt:
     2034        // empty
     2035                { $$ = nullptr; }                                                               %prec '}'
     2036        | '(' type_list ')'
     2037                { $$ = $2; }
     2038        ;
     2039
    18472040aggregate_type_nobody:                                                                  // struct, union - {...}
    1848         aggregate_key attribute_list_opt no_attr_identifier
    1849                 {
    1850                         typedefTable.makeTypedef( *$3, forall ? TYPEGENname : TYPEDEFname );
    1851                         //if ( forall ) typedefTable.changeKind( *$3, TYPEGENname ); // possibly update
     2041        aggregate_key attribute_list_opt identifier fred
     2042                {
     2043                        typedefTable.makeTypedef( *$3, forall || typedefTable.getEnclForall() ? TYPEGENname : TYPEDEFname );
    18522044                        forall = false;                                                         // reset
    18532045                        $$ = DeclarationNode::newAggregate( $1, $3, nullptr, nullptr, false )->addQualifiers( $2 );
    18542046                }
    1855         | aggregate_key attribute_list_opt type_name
    1856                 {
     2047        | aggregate_key attribute_list_opt type_name fred
     2048                {
     2049                        forall = false;                                                         // reset
    18572050                        // Create new generic declaration with same name as previous forward declaration, where the IDENTIFIER is
    18582051                        // switched to a TYPEGENname. Link any generic arguments from typegen_name to new generic declaration and
     
    18672060aggregate_key:
    18682061        STRUCT
    1869                 { $$ = DeclarationNode::Struct; }
     2062                { yyy = true; $$ = DeclarationNode::Struct; }
    18702063        | UNION
    1871                 { $$ = DeclarationNode::Union; }
     2064                { yyy = true; $$ = DeclarationNode::Union; }
    18722065        | EXCEPTION
    1873                 { $$ = DeclarationNode::Exception; }
     2066                { yyy = true; $$ = DeclarationNode::Exception; }
     2067        | GENERATOR
     2068                { yyy = true; $$ = DeclarationNode::Coroutine; }
    18742069        | COROUTINE
    1875                 { $$ = DeclarationNode::Coroutine; }
     2070                { yyy = true; $$ = DeclarationNode::Coroutine; }
    18762071        | MONITOR
    1877                 { $$ = DeclarationNode::Monitor; }
     2072                { yyy = true; $$ = DeclarationNode::Monitor; }
    18782073        | THREAD
    1879                 { $$ = DeclarationNode::Thread; }
     2074                { yyy = true; $$ = DeclarationNode::Thread; }
    18802075        ;
    18812076
     
    18882083
    18892084field_declaration:
    1890         type_specifier field_declaring_list ';'
    1891                 { $$ = distAttr( $1, $2 ); }
    1892         | EXTENSION type_specifier field_declaring_list ';'     // GCC
    1893                 { distExt( $3 ); $$ = distAttr( $2, $3 ); }             // mark all fields in list
     2085        type_specifier field_declaring_list_opt ';'
     2086                { $$ = fieldDecl( $1, $2 ); }
     2087        | EXTENSION type_specifier field_declaring_list_opt ';' // GCC
     2088                { $$ = fieldDecl( $2, $3 ); distExt( $$ ); }
     2089        | INLINE type_specifier field_abstract_list_opt ';'     // CFA
     2090                {
     2091                        if ( ! $3 ) {                                                           // field declarator ?
     2092                                $3 = DeclarationNode::newName( nullptr );
     2093                        } // if
     2094                        $3->inLine = true;
     2095                        $$ = distAttr( $2, $3 );                                        // mark all fields in list
     2096                        distInl( $3 );
     2097                }
    18942098        | typedef_declaration ';'                                                       // CFA
    1895                 { SemanticError( yylloc, "Typedef in aggregate is currently unimplemented." ); $$ = nullptr; }
    18962099        | cfa_field_declaring_list ';'                                          // CFA, new style field declaration
    18972100        | EXTENSION cfa_field_declaring_list ';'                        // GCC
    18982101                { distExt( $2 ); $$ = $2; }                                             // mark all fields in list
     2102        | INLINE cfa_field_abstract_list ';'                            // CFA, new style field declaration
     2103                { $$ = $2; }                                                                    // mark all fields in list
    18992104        | cfa_typedef_declaration ';'                                           // CFA
    1900                 { SemanticError( yylloc, "Typedef in aggregate is currently unimplemented." ); $$ = nullptr; }
    19012105        | static_assert                                                                         // C11
    19022106        ;
    19032107
    1904 cfa_field_declaring_list:                                                               // CFA, new style field declaration
    1905         cfa_abstract_declarator_tuple                                           // CFA, no field name
    1906         | cfa_abstract_declarator_tuple no_attr_identifier_or_type_name
    1907                 { $$ = $1->addName( $2 ); }
    1908         | cfa_field_declaring_list ',' no_attr_identifier_or_type_name
    1909                 { $$ = $1->appendList( $1->cloneType( $3 ) ); }
    1910         | cfa_field_declaring_list ','                                          // CFA, no field name
    1911                 { $$ = $1->appendList( $1->cloneType( 0 ) ); }
    1912         ;
    1913 
    1914 field_declaring_list:
    1915         field_declarator_opt
    1916         | field_declaring_list ',' attribute_list_opt field_declarator_opt
     2108field_declaring_list_opt:
     2109        // empty
     2110                { $$ = nullptr; }
     2111        | field_declarator
     2112        | field_declaring_list_opt ',' attribute_list_opt field_declarator
    19172113                { $$ = $1->appendList( $4->addQualifiers( $3 ) ); }
    19182114        ;
    19192115
    1920 field_declarator_opt:
    1921         // empty
    1922                 { $$ = DeclarationNode::newName( 0 ); /* XXX */ } // CFA, no field name
    1923         // '@'
    1924         //      { $$ = DeclarationNode::newName( new string( DeclarationNode::anonymous.newName() ) ); } // CFA, no field name
    1925         | bit_subrange_size                                                                     // no field name
     2116field_declarator:
     2117        bit_subrange_size                                                                       // C special case, no field name
    19262118                { $$ = DeclarationNode::newBitfield( $1 ); }
    19272119        | variable_declarator bit_subrange_size_opt
    1928                 // A semantic check is required to ensure bit_subrange only appears on base type int.
     2120                // A semantic check is required to ensure bit_subrange only appears on integral types.
    19292121                { $$ = $1->addBitfield( $2 ); }
    19302122        | variable_type_redeclarator bit_subrange_size_opt
    1931                 // A semantic check is required to ensure bit_subrange only appears on base type int.
     2123                // A semantic check is required to ensure bit_subrange only appears on integral types.
    19322124                { $$ = $1->addBitfield( $2 ); }
    1933         | variable_abstract_declarator                                          // CFA, no field name
     2125        ;
     2126
     2127field_abstract_list_opt:
     2128        // empty
     2129                { $$ = nullptr; }
     2130        | field_abstract
     2131        | field_abstract_list_opt ',' attribute_list_opt field_abstract
     2132                { $$ = $1->appendList( $4->addQualifiers( $3 ) ); }
     2133        ;
     2134
     2135field_abstract:
     2136                //      no bit fields
     2137        variable_abstract_declarator
     2138        ;
     2139
     2140cfa_field_declaring_list:                                                               // CFA, new style field declaration
     2141        // bit-fields are handled by C declarations
     2142        cfa_abstract_declarator_tuple identifier_or_type_name
     2143                { $$ = $1->addName( $2 ); }
     2144        | cfa_field_declaring_list ',' identifier_or_type_name
     2145                { $$ = $1->appendList( $1->cloneType( $3 ) ); }
     2146        ;
     2147
     2148cfa_field_abstract_list:                                                                // CFA, new style field declaration
     2149        // bit-fields are handled by C declarations
     2150        cfa_abstract_declarator_tuple
     2151        | cfa_field_abstract_list ','
     2152                { $$ = $1->appendList( $1->cloneType( 0 ) ); }
    19342153        ;
    19352154
     
    19412160
    19422161bit_subrange_size:
    1943         ':' constant_expression
     2162        ':' assignment_expression
    19442163                { $$ = $2; }
    19452164        ;
     
    19472166enum_type:                                                                                              // enum
    19482167        ENUM attribute_list_opt '{' enumerator_list comma_opt '}'
    1949                 { $$ = DeclarationNode::newEnum( new string( DeclarationNode::anonymous.newName() ), $4, true )->addQualifiers( $2 ); }
    1950         | ENUM attribute_list_opt no_attr_identifier
     2168                { $$ = DeclarationNode::newEnum( nullptr, $4, true )->addQualifiers( $2 ); }
     2169        | ENUM attribute_list_opt identifier
    19512170                { typedefTable.makeTypedef( *$3 ); }
    19522171          '{' enumerator_list comma_opt '}'
     
    19592178
    19602179enum_type_nobody:                                                                               // enum - {...}
    1961         ENUM attribute_list_opt no_attr_identifier
     2180        ENUM attribute_list_opt identifier
    19622181                {
    19632182                        typedefTable.makeTypedef( *$3 );
     
    19722191
    19732192enumerator_list:
    1974         no_attr_identifier_or_type_name enumerator_value_opt
     2193        identifier_or_type_name enumerator_value_opt
    19752194                { $$ = DeclarationNode::newEnumConstant( $1, $2 ); }
    1976         | enumerator_list ',' no_attr_identifier_or_type_name enumerator_value_opt
     2195        | enumerator_list ',' identifier_or_type_name enumerator_value_opt
    19772196                { $$ = $1->appendList( DeclarationNode::newEnumConstant( $3, $4 ) ); }
    19782197        ;
     
    20822301
    20832302identifier_list:                                                                                // K&R-style parameter list => no types
    2084         no_attr_identifier
     2303        identifier
    20852304                { $$ = DeclarationNode::newName( $1 ); }
    2086         | identifier_list ',' no_attr_identifier
     2305        | identifier_list ',' identifier
    20872306                { $$ = $1->appendList( DeclarationNode::newName( $3 ) ); }
    20882307        ;
     
    20902309identifier_or_type_name:
    20912310        identifier
    2092         | TYPEDEFname
    2093         | TYPEGENname
    2094         ;
    2095 
    2096 no_attr_identifier_or_type_name:
    2097         no_attr_identifier
    20982311        | TYPEDEFname
    20992312        | TYPEGENname
     
    21502363designation:
    21512364        designator_list ':'                                                                     // C99, CFA uses ":" instead of "="
    2152         | no_attr_identifier ':'                                                        // GCC, field name
     2365        | identifier ':'                                                                        // GCC, field name
    21532366                { $$ = new ExpressionNode( build_varref( $1 ) ); }
    21542367        ;
     
    21622375
    21632376designator:
    2164         '.' no_attr_identifier                                                          // C99, field name
     2377        '.' identifier                                                                          // C99, field name
    21652378                { $$ = new ExpressionNode( build_varref( $2 ) ); }
    21662379        | '[' push assignment_expression pop ']'                        // C99, single array element
     
    21712384        | '[' push constant_expression ELLIPSIS constant_expression pop ']' // GCC, multiple array elements
    21722385                { $$ = new ExpressionNode( new RangeExpr( maybeMoveBuild< Expression >( $3 ), maybeMoveBuild< Expression >( $5 ) ) ); }
    2173         | '.' '[' push field_list pop ']'                                       // CFA, tuple field selector
     2386        | '.' '[' push field_name_list pop ']'                          // CFA, tuple field selector
    21742387                { $$ = $4; }
    21752388        ;
     
    22072420
    22082421type_parameter:                                                                                 // CFA
    2209         type_class no_attr_identifier_or_type_name
     2422        type_class identifier_or_type_name
    22102423                { typedefTable.addToScope( *$2, TYPEDEFname, "9" ); }
    22112424          type_initializer_opt assertion_list_opt
     
    22402453
    22412454assertion:                                                                                              // CFA
    2242         '|' no_attr_identifier_or_type_name '(' type_list ')'
     2455        '|' identifier_or_type_name '(' type_list ')'
    22432456                { $$ = DeclarationNode::newTraitUse( $2, $4 ); }
    22442457        | '|' '{' push trait_declaration_list pop '}'
     
    22522465                { $$ = new ExpressionNode( new TypeExpr( maybeMoveBuildType( $1 ) ) ); }
    22532466        | assignment_expression
     2467                { SemanticError( yylloc, toString("Expression generic parameters are currently unimplemented: ", $1->build()) ); $$ = nullptr; }
    22542468        | type_list ',' type
    22552469                { $$ = (ExpressionNode *)( $1->set_last( new ExpressionNode( new TypeExpr( maybeMoveBuildType( $3 ) ) ) ) ); }
    22562470        | type_list ',' assignment_expression
    2257                 { $$ = (ExpressionNode *)( $1->set_last( $3 )); }
     2471                { SemanticError( yylloc, toString("Expression generic parameters are currently unimplemented: ", $3->build()) ); $$ = nullptr; }
     2472                // { $$ = (ExpressionNode *)( $1->set_last( $3 )); }
    22582473        ;
    22592474
     
    22752490
    22762491type_declarator_name:                                                                   // CFA
    2277         no_attr_identifier_or_type_name
     2492        identifier_or_type_name
    22782493                {
    22792494                        typedefTable.addToEnclosingScope( *$1, TYPEDEFname, "10" );
    22802495                        $$ = DeclarationNode::newTypeDecl( $1, 0 );
    22812496                }
    2282         | no_attr_identifier_or_type_name '(' type_parameter_list ')'
     2497        | identifier_or_type_name '(' type_parameter_list ')'
    22832498                {
    22842499                        typedefTable.addToEnclosingScope( *$1, TYPEGENname, "11" );
     
    22882503
    22892504trait_specifier:                                                                                // CFA
    2290         TRAIT no_attr_identifier_or_type_name '(' type_parameter_list ')' '{' '}'
     2505        TRAIT identifier_or_type_name '(' type_parameter_list ')' '{' '}'
    22912506                { $$ = DeclarationNode::newTrait( $2, $4, 0 ); }
    2292         | TRAIT no_attr_identifier_or_type_name '(' type_parameter_list ')' '{' push trait_declaration_list pop '}'
     2507        | TRAIT identifier_or_type_name '(' type_parameter_list ')' '{' push trait_declaration_list pop '}'
    22932508                { $$ = DeclarationNode::newTrait( $2, $4, $8 ); }
    22942509        ;
     
    23222537
    23232538translation_unit:
    2324         // empty
    2325                 {}                                                                                              // empty input file
     2539        // empty, input file
    23262540        | external_definition_list
    23272541                { parseTree = parseTree ? parseTree->appendList( $1 ) : $1;     }
     
    23312545        push external_definition pop
    23322546                { $$ = $2; }
    2333         | external_definition_list
    2334                 { forall = xxx; }
    2335           push external_definition pop
    2336                 { $$ = $1 ? $1->appendList( $4 ) : $4; }
    2337         ;
    2338 
    2339         // SKULLDUGGERY: Declarations in extern "X" and distribution need to be added to the current lexical scope.
    2340         // However, external_definition_list creates a new scope around each external_definition, but the pop loses all the
    2341         // types in the extern "X" and distribution at the end of the block. This version of external_definition_list does
    2342 
    2343         // not do push/pop for declarations at the level of the extern "X" and distribution block. Any recursive uses of
    2344         // external_definition_list within the extern "X" and distribution block correctly pushes/pops for that scope level.
    2345 external_definition_list_no_pop_push:
    2346         external_definition
    2347         | external_definition_list_no_pop_push
    2348                 { forall = xxx; }
    2349           external_definition
     2547        | external_definition_list push external_definition pop
    23502548                { $$ = $1 ? $1->appendList( $3 ) : $3; }
    23512549        ;
     
    23542552        // empty
    23552553                { $$ = nullptr; }
    2356         | external_definition_list_no_pop_push
     2554        | external_definition_list
     2555        ;
     2556
     2557up:
     2558                { typedefTable.up( forall ); forall = false; }
     2559        ;
     2560
     2561down:
     2562                { typedefTable.down(); }
    23572563        ;
    23582564
     
    23742580                        linkage = LinkageSpec::linkageUpdate( yylloc, linkage, $2 );
    23752581                }
    2376           '{' external_definition_list_opt '}'
     2582          '{' up external_definition_list_opt down '}'
    23772583                {
    23782584                        linkage = linkageStack.top();
    23792585                        linkageStack.pop();
     2586                        $$ = $6;
     2587                }
     2588        | type_qualifier_list
     2589                {
     2590                        if ( $1->type->qualifiers.val ) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); }
     2591                        if ( $1->type->forall ) forall = true;          // remember generic type
     2592                }
     2593          '{' up external_definition_list_opt down '}'          // CFA, namespace
     2594                {
     2595                        distQual( $5, $1 );
     2596                        forall = false;
    23802597                        $$ = $5;
    23812598                }
    2382         | type_qualifier_list
    2383                 { if ( $1->type->forall ) xxx = forall = true; } // remember generic type
    2384           '{' external_definition_list_opt '}'                          // CFA, namespace
    2385                 {
    2386                         for ( DeclarationNode * iter = $4; iter != nullptr; iter = (DeclarationNode *)iter->get_next() ) {
    2387                                 if ( isMangled( iter->linkage ) ) {             // ignore extern "C"
    2388                                         iter->addQualifiers( $1->clone() );
    2389                                 } // if
    2390                         } // for
    2391                         xxx = false;
    2392                         delete $1;
    2393                         $$ = $4;
    2394                 }
    23952599        | declaration_qualifier_list
    2396                 { if ( $1->type->forall ) xxx = forall = true; } // remember generic type
    2397           '{' external_definition_list_opt '}'                          // CFA, namespace
    2398                 {
    2399                         for ( DeclarationNode * iter = $4; iter != nullptr; iter = (DeclarationNode *)iter->get_next() ) {
    2400                                 if ( isMangled( iter->linkage ) ) {             // ignore extern "C"
    2401                                         iter->addQualifiers( $1->clone() );
    2402                                 } // if
    2403                         } // for
    2404                         xxx = false;
    2405                         delete $1;
    2406                         $$ = $4;
     2600                {
     2601                        if ( $1->type && $1->type->qualifiers.val ) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); }
     2602                        if ( $1->type && $1->type->forall ) forall = true; // remember generic type
     2603                }
     2604          '{' up external_definition_list_opt down '}'          // CFA, namespace
     2605                {
     2606                        distQual( $5, $1 );
     2607                        forall = false;
     2608                        $$ = $5;
    24072609                }
    24082610        | declaration_qualifier_list type_qualifier_list
    24092611                {
    2410                         // forall must be in the type_qualifier_list
    2411                         if ( $2->type->forall ) xxx = forall = true; // remember generic type
    2412                 }
    2413           '{' external_definition_list_opt '}'                          // CFA, namespace
    2414                 {
    2415                         for ( DeclarationNode * iter = $5; iter != nullptr; iter = (DeclarationNode *)iter->get_next() ) {
    2416                                 if ( isMangled( iter->linkage ) && isMangled( $2->linkage ) ) { // ignore extern "C"
    2417                                         iter->addQualifiers( $1->clone() );
    2418                                         iter->addQualifiers( $2->clone() );
    2419                                 } // if
    2420                         } // for
    2421                         xxx = false;
    2422                         delete $1;
    2423                         delete $2;
    2424                         $$ = $5;
     2612                        if ( ($1->type && $1->type->qualifiers.val) || $2->type->qualifiers.val ) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); }
     2613                        if ( ($1->type && $1->type->forall) || $2->type->forall ) forall = true; // remember generic type
     2614                }
     2615          '{' up external_definition_list_opt down '}'          // CFA, namespace
     2616                {
     2617                        distQual( $6, $1->addQualifiers( $2 ) );
     2618                        forall = false;
     2619                        $$ = $6;
    24252620                }
    24262621        ;
     
    27322927        typedef
    27332928                // hide type name in enclosing scope by variable name
    2734                 { typedefTable.addToEnclosingScope( *$1->name, IDENTIFIER, "ID" ); }
     2929                {
     2930                        // if ( ! typedefTable.existsCurr( *$1->name ) ) {
     2931                                typedefTable.addToEnclosingScope( *$1->name, IDENTIFIER, "ID" );
     2932                        // } else {
     2933                        //      SemanticError( yylloc, string("'") + *$1->name + "' redeclared as different kind of symbol." ); $$ = nullptr;
     2934                        // } // if
     2935                }
    27352936        | '(' paren_type ')'
    27362937                { $$ = $2; }
     
    27432944                { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); }
    27442945        | '(' type_ptr ')' attribute_list_opt
    2745                 { $$ = $2->addQualifiers( $4 ); }
     2946                { $$ = $2->addQualifiers( $4 ); }                               // redundant parenthesis
    27462947        ;
    27472948
  • src/ResolvExpr/AdjustExprType.cc

    r7951100 rb067d9b  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // AdjustExprType.cc --
     7// AdjustExprType_old.cc --
    88//
    99// Author           : Richard C. Bilson
     
    1414//
    1515
     16#include "AST/Node.hpp"
     17#include "AST/Pass.hpp"
     18#include "AST/SymbolTable.hpp"
     19#include "AST/Type.hpp"
     20#include "AST/TypeEnvironment.hpp"
    1621#include "Common/PassVisitor.h"
    1722#include "SymTab/Indexer.h"       // for Indexer
     
    2227
    2328namespace ResolvExpr {
    24         class AdjustExprType : public WithShortCircuiting {
    25           public:
    26                 AdjustExprType( const TypeEnvironment & env, const SymTab::Indexer & indexer );
     29
     30namespace {
     31        class AdjustExprType_old final : public WithShortCircuiting {
     32                public:
     33                AdjustExprType_old( const TypeEnvironment & env, const SymTab::Indexer & indexer );
    2734                void premutate( VoidType * ) { visit_children = false; }
    2835                void premutate( BasicType * ) { visit_children = false; }
     
    4047                void premutate( OneType * ) { visit_children = false; }
    4148
    42                 Type * postmutate( ArrayType *arrayType );
    43                 Type * postmutate( FunctionType *functionType );
    44                 Type * postmutate( TypeInstType *aggregateUseType );
     49                Type * postmutate( ArrayType * arrayType );
     50                Type * postmutate( FunctionType * functionType );
     51                Type * postmutate( TypeInstType * aggregateUseType );
    4552
    46           private:
     53                private:
    4754                const TypeEnvironment & env;
    4855                const SymTab::Indexer & indexer;
    4956        };
    5057
    51         void adjustExprType( Type *&type, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
    52                 PassVisitor<AdjustExprType> adjuster( env, indexer );
    53                 Type *newType = type->acceptMutator( adjuster );
    54                 type = newType;
    55         }
    56 
    57         void adjustExprType( Type *& type ) {
    58                 TypeEnvironment env;
    59                 SymTab::Indexer indexer;
    60                 adjustExprType( type, env, indexer );
    61         }
    62 
    63         AdjustExprType::AdjustExprType( const TypeEnvironment &env, const SymTab::Indexer &indexer )
     58        AdjustExprType_old::AdjustExprType_old( const TypeEnvironment &env, const SymTab::Indexer &indexer )
    6459                : env( env ), indexer( indexer ) {
    6560        }
    6661
    67         Type * AdjustExprType::postmutate( ArrayType * arrayType ) {
    68                 PointerType *pointerType = new PointerType{ arrayType->get_qualifiers(), arrayType->base };
     62        Type * AdjustExprType_old::postmutate( ArrayType * arrayType ) {
     63                PointerType * pointerType = new PointerType{ arrayType->get_qualifiers(), arrayType->base };
    6964                arrayType->base = nullptr;
    7065                delete arrayType;
     
    7267        }
    7368
    74         Type * AdjustExprType::postmutate( FunctionType * functionType ) {
     69        Type * AdjustExprType_old::postmutate( FunctionType * functionType ) {
    7570                return new PointerType{ Type::Qualifiers(), functionType };
    7671        }
    7772
    78         Type * AdjustExprType::postmutate( TypeInstType * typeInst ) {
    79                 if ( const EqvClass* eqvClass = env.lookup( typeInst->get_name() ) ) {
     73        Type * AdjustExprType_old::postmutate( TypeInstType * typeInst ) {
     74                if ( const EqvClass * eqvClass = env.lookup( typeInst->get_name() ) ) {
    8075                        if ( eqvClass->data.kind == TypeDecl::Ftype ) {
    8176                                return new PointerType{ Type::Qualifiers(), typeInst };
    8277                        }
    83                 } else if ( NamedTypeDecl *ntDecl = indexer.lookupType( typeInst->get_name() ) ) {
    84                         if ( TypeDecl *tyDecl = dynamic_cast< TypeDecl* >( ntDecl ) ) {
     78                } else if ( const NamedTypeDecl * ntDecl = indexer.lookupType( typeInst->get_name() ) ) {
     79                        if ( const TypeDecl * tyDecl = dynamic_cast< const TypeDecl * >( ntDecl ) ) {
    8580                                if ( tyDecl->get_kind() == TypeDecl::Ftype ) {
    8681                                        return new PointerType{ Type::Qualifiers(), typeInst };
     
    9085                return typeInst;
    9186        }
     87} // anonymous namespace
     88
     89void adjustExprType( Type *&type, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
     90        PassVisitor<AdjustExprType_old> adjuster( env, indexer );
     91        Type * newType = type->acceptMutator( adjuster );
     92        type = newType;
     93}
     94
     95void adjustExprType( Type *& type ) {
     96        TypeEnvironment env;
     97        SymTab::Indexer indexer;
     98        adjustExprType( type, env, indexer );
     99}
     100
     101namespace {
     102        struct AdjustExprType_new final : public ast::WithShortCircuiting {
     103                const ast::TypeEnvironment & tenv;
     104                const ast::SymbolTable & symtab;
     105
     106                AdjustExprType_new( const ast::TypeEnvironment & e, const ast::SymbolTable & syms )
     107                : tenv( e ), symtab( syms ) {}
     108
     109                void premutate( const ast::VoidType * ) { visit_children = false; }
     110                void premutate( const ast::BasicType * ) { visit_children = false; }
     111                void premutate( const ast::PointerType * ) { visit_children = false; }
     112                void premutate( const ast::ArrayType * ) { visit_children = false; }
     113                void premutate( const ast::FunctionType * ) { visit_children = false; }
     114                void premutate( const ast::StructInstType * ) { visit_children = false; }
     115                void premutate( const ast::UnionInstType * ) { visit_children = false; }
     116                void premutate( const ast::EnumInstType * ) { visit_children = false; }
     117                void premutate( const ast::TraitInstType * ) { visit_children = false; }
     118                void premutate( const ast::TypeInstType * ) { visit_children = false; }
     119                void premutate( const ast::TupleType * ) { visit_children = false; }
     120                void premutate( const ast::VarArgsType * ) { visit_children = false; }
     121                void premutate( const ast::ZeroType * ) { visit_children = false; }
     122                void premutate( const ast::OneType * ) { visit_children = false; }
     123
     124                const ast::Type * postmutate( const ast::ArrayType * at ) {
     125                        return new ast::PointerType{ at->base, at->qualifiers };
     126                }
     127
     128                const ast::Type * postmutate( const ast::FunctionType * ft ) {
     129                        return new ast::PointerType{ ft };
     130                }
     131
     132                const ast::Type * postmutate( const ast::TypeInstType * inst ) {
     133                        // replace known function-type-variables with pointer-to-function
     134                        if ( const ast::EqvClass * eqvClass = tenv.lookup( inst->name ) ) {
     135                                if ( eqvClass->data.kind == ast::TypeVar::Ftype ) {
     136                                        return new ast::PointerType{ inst };
     137                                }
     138                        } else if ( const ast::NamedTypeDecl * ntDecl = symtab.lookupType( inst->name ) ) {
     139                                if ( auto tyDecl = dynamic_cast< const ast::TypeDecl * >( ntDecl ) ) {
     140                                        if ( tyDecl->kind == ast::TypeVar::Ftype ) {
     141                                                return new ast::PointerType{ inst };
     142                                        }
     143                                }
     144                        }
     145                        return inst;
     146                }
     147        };
     148} // anonymous namespace
     149
     150const ast::Type * adjustExprType(
     151        const ast::Type * type, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab
     152) {
     153        ast::Pass<AdjustExprType_new> adjuster{ env, symtab };
     154        return type->accept( adjuster );
     155}
     156
    92157} // namespace ResolvExpr
    93158
  • src/ResolvExpr/Alternative.cc

    r7951100 rb067d9b  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sat May 16 23:44:23 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat May 16 23:54:23 2015
    13 // Update Count     : 2
     11// Last Modified By : Aaron B. Moss
     12// Last Modified On : Thu Oct 11 10:55:00 2018
     13// Update Count     : 3
    1414//
    1515
     
    2020#include <utility>                       // for move
    2121
    22 #include "Common/utility.h"              // for maybeClone
     22#include "Common/utility.h"              // for cloneAll
    2323#include "ResolvExpr/Cost.h"             // for Cost, Cost::zero, operator<<
    2424#include "ResolvExpr/TypeEnvironment.h"  // for TypeEnvironment
     
    2727
    2828namespace ResolvExpr {
    29         Alternative::Alternative() : cost( Cost::zero ), cvtCost( Cost::zero ), expr( nullptr ) {}
     29        Alternative::Alternative()
     30        : cost( Cost::zero ), cvtCost( Cost::zero ), expr( nullptr ), env(), openVars(), need() {}
    3031
    31         Alternative::Alternative( Expression *expr, const TypeEnvironment &env, const Cost& cost )
    32                 : cost( cost ), cvtCost( Cost::zero ), expr( expr ), env( env ) {}
     32        Alternative::Alternative( Expression *expr, const TypeEnvironment &env )
     33        : cost( Cost::zero ), cvtCost( Cost::zero ), expr( expr ), env( env ), openVars(), need() {}
     34       
     35        Alternative::Alternative( const Alternative &o, Expression *expr, const Cost &cost )
     36        : cost( cost ), cvtCost( Cost::zero ), expr( expr ), env( o.env ), openVars( o.openVars ),
     37          need() { cloneAll( o.need, need ); }
    3338
    34         Alternative::Alternative( Expression *expr, const TypeEnvironment &env, const Cost& cost, const Cost &cvtCost )
    35                 : cost( cost ), cvtCost( cvtCost ), expr( expr ), env( env ) {}
     39        Alternative::Alternative( Expression *expr, const TypeEnvironment &env,
     40                const OpenVarSet& openVars, const AssertionList& oneed, const Cost& cost )
     41        : cost( cost ), cvtCost( Cost::zero ), expr( expr ), env( env ), openVars( openVars ),
     42          need() { cloneAll( oneed, need ); }
    3643
    37         Alternative::Alternative( const Alternative &other ) : cost( other.cost ), cvtCost( other.cvtCost ), expr( maybeClone( other.expr ) ), env( other.env ) {
    38         }
     44        Alternative::Alternative( Expression *expr, const TypeEnvironment &env,
     45                const OpenVarSet& openVars, const AssertionList& oneed, const Cost& cost,
     46                const Cost &cvtCost )
     47        : cost( cost ), cvtCost( cvtCost ), expr( expr ), env( env ), openVars( openVars ),
     48          need() { cloneAll( oneed, need ); }
     49       
     50        Alternative::Alternative( Expression *expr, const TypeEnvironment &env,
     51                const OpenVarSet &openVars, const AssertionSet &oneed, const Cost &cost)
     52        : cost( cost ), cvtCost( Cost::zero ), expr( expr ), env( env ), openVars( openVars ),
     53          need() { cloneAll( oneed, need ); }
     54       
     55        Alternative::Alternative( Expression *expr, const TypeEnvironment &env,
     56                const OpenVarSet &openVars, const AssertionSet &oneed, const Cost &cost,
     57                const Cost& cvtCost )
     58        : cost( cost ), cvtCost( cvtCost ), expr( expr ), env( env ), openVars( openVars ),
     59          need() { cloneAll( oneed, need ); }
     60       
     61        Alternative::Alternative( Expression *expr, TypeEnvironment &&env, OpenVarSet &&openVars,
     62                AssertionSet &&needSet, const Cost &cost )
     63        : cost( cost ), cvtCost( Cost::zero ), expr( expr ), env( std::move(env) ),
     64          openVars( std::move(openVars) ), need( needSet.begin(), needSet.end() ) {}
     65       
     66        Alternative::Alternative( Expression *expr, TypeEnvironment &&env, OpenVarSet &&openVars,
     67                AssertionSet &&needSet, const Cost &cost, const Cost &cvtCost )
     68        : cost( cost ), cvtCost( cvtCost ), expr( expr ), env( std::move(env) ),
     69          openVars( std::move(openVars) ), need( needSet.begin(), needSet.end() ) {}
     70
     71        Alternative::Alternative( const Alternative &other )
     72        : cost( other.cost ), cvtCost( other.cvtCost ), expr( maybeClone( other.expr ) ),
     73          env( other.env ), openVars( other.openVars ), need() { cloneAll( other.need, need ); }
    3974
    4075        Alternative &Alternative::operator=( const Alternative &other ) {
     
    4580                expr = maybeClone( other.expr );
    4681                env = other.env;
     82                openVars = other.openVars;
     83                need.clear();
     84                cloneAll( other.need, need );
    4785                return *this;
    4886        }
    4987
    50         Alternative::Alternative( Alternative && other ) : cost( other.cost ), cvtCost( other.cvtCost ), expr( other.expr ), env( std::move( other.env ) ) {
    51                 other.expr = nullptr;
    52         }
     88        Alternative::Alternative( Alternative && other )
     89        : cost( other.cost ), cvtCost( other.cvtCost ), expr( other.expr ),
     90          env( std::move( other.env ) ), openVars( std::move( other.openVars ) ),
     91          need( std::move( other.need ) ) { other.expr = nullptr; }
    5392
    5493        Alternative & Alternative::operator=( Alternative && other ) {
     
    5998                expr = other.expr;
    6099                env = std::move( other.env );
     100                openVars = std::move( other.openVars );
     101                need = std::move( other.need );
    61102                other.expr = nullptr;
    62103                return *this;
     
    64105
    65106        Alternative::~Alternative() {
     107                for ( AssertionItem& n : need ) { delete n.decl; }
    66108                delete expr;
    67109        }
     
    78120                        os << "Null expression!" << std::endl;
    79121                } // if
    80                 os << indent << "Environment: ";
     122                os << indent << "Environment:";
    81123                env.print( os, indent+1 );
    82124                os << std::endl;
    83         }
    84 
    85         void splice( AltList& dst, AltList& src ) {
    86                 dst.reserve( dst.size() + src.size() );
    87                 for ( Alternative& alt : src ) {
    88                         dst.push_back( std::move(alt) );
    89                 }
    90                 src.clear();
    91         }
    92 
    93         void spliceBegin( AltList& dst, AltList& src ) {
    94                 splice( src, dst );
    95                 dst.swap( src );
    96125        }
    97126
  • src/ResolvExpr/Alternative.h

    r7951100 rb067d9b  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sat May 16 23:45:43 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Jul 22 09:36:36 2017
    13 // Update Count     : 3
     11// Last Modified By : Aaron B. Moss
     12// Last Modified On : Thu Oct 11 10:55:00 2018
     13// Update Count     : 4
    1414//
    1515
     
    2020
    2121#include "Cost.h"             // for Cost
    22 #include "TypeEnvironment.h"  // for TypeEnvironment
     22#include "TypeEnvironment.h"  // for TypeEnvironment, AssertionSetValue
     23
     24#include "Common/utility.h"   // for maybeClone
    2325
    2426class Expression;
    2527
    2628namespace ResolvExpr {
     29        /// One assertion to resolve
     30        struct AssertionItem {
     31                const DeclarationWithType* decl;
     32                AssertionSetValue info;
     33
     34                AssertionItem() = default;
     35                AssertionItem( const DeclarationWithType* decl, const AssertionSetValue& info )
     36                : decl(decl), info(info) {}
     37                AssertionItem( const AssertionSet::value_type& e ) : decl(e.first), info(e.second) {}
     38                operator AssertionSet::value_type () const { return { decl, info }; }
     39
     40                // to support cloneAll
     41                AssertionItem clone() const { return { maybeClone(decl), info }; }
     42        };
     43        /// A list of unresolved assertions
     44        using AssertionList = std::vector<AssertionItem>;
     45
     46        /// Clones an assertion list into an assertion set
     47        static inline void cloneAll( const AssertionList& src, AssertionSet& dst ) {
     48                for ( const AssertionItem& item : src ) {
     49                        dst.emplace( maybeClone(item.decl), item.info );
     50                }
     51        }
     52
     53        /// Clones an assertion set into an assertion list
     54        static inline void cloneAll( const AssertionSet& src, AssertionList& dst ) {
     55                dst.reserve( dst.size() + src.size() );
     56                for ( const auto& entry : src ) {
     57                        dst.emplace_back( maybeClone(entry.first), entry.second );
     58                }
     59        }
     60
     61        /// Clones an assertion list into an assertion list
     62        static inline void cloneAll( const AssertionList& src, AssertionList& dst ) {
     63                dst.reserve( dst.size() + src.size() );
     64                for ( const AssertionItem& item : src ) {
     65                        dst.emplace_back( maybeClone(item.decl), item.info );
     66                }
     67        }
     68
     69        /// One option for resolution of an expression
    2770        struct Alternative {
    2871                Alternative();
    29                 Alternative( Expression *expr, const TypeEnvironment &env, const Cost &cost );
    30                 Alternative( Expression *expr, const TypeEnvironment &env, const Cost &cost, const Cost &cvtCost );
     72                Alternative( Expression *expr, const TypeEnvironment &env );
     73                Alternative( const Alternative &o, Expression *expr, const Cost &cost );
     74                Alternative( Expression *expr, const TypeEnvironment &env, const OpenVarSet& openVars,
     75                        const AssertionList& need, const Cost &cost );
     76                Alternative( Expression *expr, const TypeEnvironment &env, const OpenVarSet& openVars,
     77                        const AssertionList& need, const Cost &cost, const Cost &cvtCost );
     78                Alternative( Expression *expr, const TypeEnvironment &env, const OpenVarSet &openVars,
     79                        const AssertionSet &need, const Cost &cost);
     80                Alternative( Expression *expr, const TypeEnvironment &env, const OpenVarSet &openVars,
     81                        const AssertionSet &need, const Cost &cost, const Cost& cvtCost );
     82                Alternative( Expression *expr, TypeEnvironment &&env, OpenVarSet &&openVars,
     83                        AssertionSet &&need, const Cost &cost );
     84                Alternative( Expression *expr, TypeEnvironment &&env, OpenVarSet &&openVars,
     85                        AssertionSet &&need, const Cost &cost, const Cost &cvtCost );
    3186                Alternative( const Alternative &other );
    3287                Alternative &operator=( const Alternative &other );
     
    4499                }
    45100
    46                 Cost cost;
    47                 Cost cvtCost;
    48                 Expression *expr;
    49                 TypeEnvironment env;
     101                /// Sorts by cost
     102                bool operator< ( const Alternative& o ) const { return cost < o.cost; }
     103
     104                Cost cost;            ///< Cost of the whole expression
     105                Cost cvtCost;         ///< Cost of conversions to the satisfying expression
     106                Expression *expr;     ///< Satisfying expression
     107                TypeEnvironment env;  ///< Containing type environment
     108                OpenVarSet openVars;  ///< Open variables for environment
     109                AssertionList need;   ///< Assertions which need to be resolved
    50110        };
    51111
    52112        typedef std::vector< Alternative > AltList;
    53 
    54         /// Moves all elements from src to the end of dst
    55         void splice( AltList& dst, AltList& src );
    56 
    57         /// Moves all elements from src to the beginning of dst
    58         void spliceBegin( AltList& dst, AltList& src );
    59113
    60114        static inline std::ostream & operator<<(std::ostream & os, const ResolvExpr::Alternative & alt) {
  • src/ResolvExpr/AlternativeFinder.cc

    r7951100 rb067d9b  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sat May 16 23:52:08 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Feb 17 11:19:39 2018
    13 // Update Count     : 33
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Thu Aug  8 16:35:00 2019
     13// Update Count     : 38
    1414//
    1515
     
    2525#include <vector>                  // for vector
    2626
     27#include "CompilationState.h"      // for resolvep
    2728#include "Alternative.h"           // for AltList, Alternative
    2829#include "AlternativeFinder.h"
     30#include "AST/Expr.hpp"
     31#include "AST/SymbolTable.hpp"
     32#include "AST/Type.hpp"
    2933#include "Common/SemanticError.h"  // for SemanticError
    3034#include "Common/utility.h"        // for deleteAll, printAll, CodeLocation
     
    3337#include "InitTweak/InitTweak.h"   // for getFunctionName
    3438#include "RenameVars.h"            // for RenameVars, global_renamer
     39#include "ResolveAssertions.h"     // for resolveAssertions
    3540#include "ResolveTypeof.h"         // for resolveTypeof
    3641#include "Resolver.h"              // for resolveStmtExpr
     
    4954#include "typeops.h"               // for adjustExprType, polyCost, castCost
    5055
    51 extern bool resolvep;
    5256#define PRINT( text ) if ( resolvep ) { text }
    5357//#define DEBUG_COST
    54 
    55 using std::move;
    56 
    57 /// copies any copyable type
    58 template<typename T>
    59 T copy(const T& x) { return x; }
    6058
    6159namespace ResolvExpr {
     
    8179                void postvisit( OffsetofExpr * offsetofExpr );
    8280                void postvisit( OffsetPackExpr * offsetPackExpr );
    83                 void postvisit( AttrExpr * attrExpr );
    8481                void postvisit( LogicalExpr * logicalExpr );
    8582                void postvisit( ConditionalExpr * conditionalExpr );
     
    10299                void addAnonConversions( const Alternative & alt );
    103100                /// Adds alternatives for member expressions, given the aggregate, conversion cost for that aggregate, and name of the member
    104                 template< typename StructOrUnionType > void addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, const std::string & name );
     101                template< typename StructOrUnionType > void addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Alternative &alt, const Cost &newCost, const std::string & name );
    105102                /// Adds alternatives for member expressions where the left side has tuple type
    106                 void addTupleMembers( TupleType * tupleType, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member );
     103                void addTupleMembers( TupleType *tupleType, Expression *expr, const Alternative &alt, const Cost &newCost, Expression *member );
    107104                /// Adds alternatives for offsetof expressions, given the base type and name of the member
    108105                template< typename StructOrUnionType > void addOffsetof( StructOrUnionType *aggInst, const std::string &name );
     
    112109                /// Finds matching alternatives for a function, given a set of arguments
    113110                template<typename OutputIterator>
    114                 void makeFunctionAlternatives( const Alternative &func, FunctionType *funcType, const ExplodedArgs& args, OutputIterator out );
    115                 /// Checks if assertion parameters match for a new alternative
     111                void makeFunctionAlternatives( const Alternative &func, FunctionType *funcType, const ExplodedArgs_old& args, OutputIterator out );
     112                /// Sets up parameter inference for an output alternative
    116113                template< typename OutputIterator >
    117                 void inferParameters( const AssertionSet &need, AssertionSet &have, const Alternative &newAlt, OpenVarSet &openVars, OutputIterator out );
     114                void inferParameters( Alternative &newAlt, OutputIterator out );
    118115        private:
    119116                AlternativeFinder & altFinder;
     
    133130
    134131        void printAlts( const AltList &list, std::ostream &os, unsigned int indentAmt ) {
    135                 Indenter indent = { Indenter::tabsize, indentAmt };
     132                Indenter indent = { indentAmt };
    136133                for ( AltList::const_iterator i = list.begin(); i != list.end(); ++i ) {
    137134                        i->print( os, indent );
     
    176173                                                selected[ mangleName ] = current;
    177174                                        } else if ( candidate->cost == mapPlace->second.candidate->cost ) {
    178                                                 PRINT(
    179                                                         std::cerr << "marking ambiguous" << std::endl;
    180                                                 )
    181                                                 mapPlace->second.isAmbiguous = true;
     175                                                // if one of the candidates contains a deleted identifier, can pick the other, since
     176                                                // deleted expressions should not be ambiguous if there is another option that is at least as good
     177                                                if ( findDeletedExpr( candidate->expr ) ) {
     178                                                        // do nothing
     179                                                        PRINT( std::cerr << "candidate is deleted" << std::endl; )
     180                                                } else if ( findDeletedExpr( mapPlace->second.candidate->expr ) ) {
     181                                                        PRINT( std::cerr << "current is deleted" << std::endl; )
     182                                                        selected[ mangleName ] = current;
     183                                                } else {
     184                                                        PRINT(
     185                                                                std::cerr << "marking ambiguous" << std::endl;
     186                                                        )
     187                                                        mapPlace->second.isAmbiguous = true;
     188                                                }
    182189                                        } else {
    183190                                                PRINT(
     
    234241        }
    235242
    236         void AlternativeFinder::find( Expression *expr, bool adjust, bool prune, bool failFast ) {
     243        void AlternativeFinder::find( Expression *expr, ResolvMode mode ) {
    237244                PassVisitor<Finder> finder( *this );
    238245                expr->accept( finder );
    239                 if ( failFast && alternatives.empty() ) {
     246                if ( mode.failFast && alternatives.empty() ) {
    240247                        PRINT(
    241248                                std::cerr << "No reasonable alternatives for expression " << expr << std::endl;
     
    243250                        SemanticError( expr, "No reasonable alternatives for expression " );
    244251                }
    245                 if ( prune ) {
     252                if ( mode.satisfyAssns || mode.prune ) {
     253                        // trim candidates just to those where the assertions resolve
     254                        // - necessary pre-requisite to pruning
     255                        AltList candidates;
     256                        std::list<std::string> errors;
     257                        for ( unsigned i = 0; i < alternatives.size(); ++i ) {
     258                                resolveAssertions( alternatives[i], indexer, candidates, errors );
     259                        }
     260                        // fail early if none such
     261                        if ( mode.failFast && candidates.empty() ) {
     262                                std::ostringstream stream;
     263                                stream << "No alternatives with satisfiable assertions for " << expr << "\n";
     264                                //        << "Alternatives with failing assertions are:\n";
     265                                // printAlts( alternatives, stream, 1 );
     266                                for ( const auto& err : errors ) {
     267                                        stream << err;
     268                                }
     269                                SemanticError( expr->location, stream.str() );
     270                        }
     271                        // reset alternatives
     272                        alternatives = std::move( candidates );
     273                }
     274                if ( mode.prune ) {
    246275                        auto oldsize = alternatives.size();
    247276                        PRINT(
     
    251280                        AltList pruned;
    252281                        pruneAlternatives( alternatives.begin(), alternatives.end(), back_inserter( pruned ) );
    253                         if ( failFast && pruned.empty() ) {
     282                        if ( mode.failFast && pruned.empty() ) {
    254283                                std::ostringstream stream;
    255284                                AltList winners;
     
    270299                }
    271300                // adjust types after pruning so that types substituted by pruneAlternatives are correctly adjusted
    272                 for ( AltList::iterator i = alternatives.begin(); i != alternatives.end(); ++i ) {
    273                         if ( adjust ) {
    274                                 adjustExprType( i->expr->get_result(), i->env, indexer );
     301                if ( mode.adjust ) {
     302                        for ( Alternative& i : alternatives ) {
     303                                adjustExprType( i.expr->get_result(), i.env, indexer );
    275304                        }
    276305                }
     
    284313
    285314        void AlternativeFinder::findWithAdjustment( Expression *expr ) {
    286                 find( expr, true );
     315                find( expr, ResolvMode::withAdjustment() );
    287316        }
    288317
    289318        void AlternativeFinder::findWithoutPrune( Expression * expr ) {
    290                 find( expr, true, false );
     319                find( expr, ResolvMode::withoutPrune() );
    291320        }
    292321
    293322        void AlternativeFinder::maybeFind( Expression * expr ) {
    294                 find( expr, true, true, false );
     323                find( expr, ResolvMode::withoutFailFast() );
    295324        }
    296325
     
    306335                }
    307336
    308                 if ( StructInstType *structInst = dynamic_cast< StructInstType* >( aggrExpr->result ) ) {
    309                         addAggMembers( structInst, aggrExpr.get(), alt.cost+Cost::safe, alt.env, "" );
    310                 } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( aggrExpr->result ) ) {
    311                         addAggMembers( unionInst, aggrExpr.get(), alt.cost+Cost::safe, alt.env, "" );
     337                if ( StructInstType * structInst = dynamic_cast< StructInstType* >( aggrExpr->result ) ) {
     338                        addAggMembers( structInst, aggrExpr.get(), alt, alt.cost+Cost::safe, "" );
     339                } else if ( UnionInstType * unionInst = dynamic_cast< UnionInstType* >( aggrExpr->result ) ) {
     340                        addAggMembers( unionInst, aggrExpr.get(), alt, alt.cost+Cost::safe, "" );
    312341                } // if
    313342        }
    314343
    315344        template< typename StructOrUnionType >
    316         void AlternativeFinder::Finder::addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, const std::string & name ) {
     345        void AlternativeFinder::Finder::addAggMembers( StructOrUnionType * aggInst, Expression * expr, const Alternative& alt, const Cost &newCost, const std::string & name ) {
    317346                std::list< Declaration* > members;
    318347                aggInst->lookup( name, members );
    319348
    320349                for ( Declaration * decl : members ) {
    321                         if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( decl ) ) {
     350                        if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType* >( decl ) ) {
    322351                                // addAnonAlternatives uses vector::push_back, which invalidates references to existing elements, so
    323352                                // can't construct in place and use vector::back
    324                                 Alternative newAlt( new MemberExpr( dwt, expr->clone() ), env, newCost );
     353                                Alternative newAlt{ alt, new MemberExpr{ dwt, expr->clone() }, newCost };
    325354                                renameTypes( newAlt.expr );
    326355                                addAnonConversions( newAlt ); // add anonymous member interpretations whenever an aggregate value type is seen as a member expression.
     
    332361        }
    333362
    334         void AlternativeFinder::Finder::addTupleMembers( TupleType * tupleType, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member ) {
     363        void AlternativeFinder::Finder::addTupleMembers( TupleType * tupleType, Expression * expr, const Alternative &alt, const Cost &newCost, Expression * member ) {
    335364                if ( ConstantExpr * constantExpr = dynamic_cast< ConstantExpr * >( member ) ) {
    336365                        // get the value of the constant expression as an int, must be between 0 and the length of the tuple type to have meaning
    337                         // xxx - this should be improved by memoizing the value of constant exprs
    338                         // during parsing and reusing that information here.
    339                         std::stringstream ss( constantExpr->get_constant()->get_value() );
    340                         int val = 0;
     366                        auto val = constantExpr->intValue();
    341367                        std::string tmp;
    342                         if ( ss >> val && ! (ss >> tmp) ) {
    343                                 if ( val >= 0 && (unsigned int)val < tupleType->size() ) {
    344                                         alternatives.push_back( Alternative( new TupleIndexExpr( expr->clone(), val ), env, newCost ) );
    345                                 } // if
     368                        if ( val >= 0 && (unsigned long long)val < tupleType->size() ) {
     369                                alternatives.push_back( Alternative{
     370                                        alt, new TupleIndexExpr( expr->clone(), val ), newCost } );
    346371                        } // if
    347                 } else if ( NameExpr * nameExpr = dynamic_cast< NameExpr * >( member ) ) {
    348                         // xxx - temporary hack until 0/1 are int constants
    349                         if ( nameExpr->get_name() == "0" || nameExpr->get_name() == "1" ) {
    350                                 std::stringstream ss( nameExpr->get_name() );
    351                                 int val;
    352                                 ss >> val;
    353                                 alternatives.push_back( Alternative( new TupleIndexExpr( expr->clone(), val ), env, newCost ) );
    354                         }
    355372                } // if
    356373        }
    357374
    358         void AlternativeFinder::Finder::postvisit( ApplicationExpr *applicationExpr ) {
    359                 alternatives.push_back( Alternative( applicationExpr->clone(), env, Cost::zero ) );
    360         }
    361 
    362         Cost computeConversionCost( Type * actualType, Type * formalType, const SymTab::Indexer &indexer, const TypeEnvironment & env ) {
     375        void AlternativeFinder::Finder::postvisit( ApplicationExpr * applicationExpr ) {
     376                alternatives.push_back( Alternative{ applicationExpr->clone(), env } );
     377        }
     378
     379        Cost computeConversionCost( Type * actualType, Type * formalType, bool actualIsLvalue,
     380                        const SymTab::Indexer &indexer, const TypeEnvironment & env ) {
    363381                PRINT(
    364382                        std::cerr << std::endl << "converting ";
     
    370388                        std::cerr << std::endl;
    371389                )
    372                 Cost convCost = conversionCost( actualType, formalType, indexer, env );
     390                Cost convCost = conversionCost( actualType, formalType, actualIsLvalue, indexer, env );
    373391                PRINT(
    374392                        std::cerr << std::endl << "cost is " << convCost << std::endl;
     
    385403
    386404        Cost computeExpressionConversionCost( Expression *& actualExpr, Type * formalType, const SymTab::Indexer &indexer, const TypeEnvironment & env ) {
    387                 Cost convCost = computeConversionCost( actualExpr->result, formalType, indexer, env );
     405                Cost convCost = computeConversionCost(
     406                        actualExpr->result, formalType, actualExpr->get_lvalue(), indexer, env );
    388407
    389408                // if there is a non-zero conversion cost, ignoring poly cost, then the expression requires conversion.
     
    413432        Cost computeApplicationConversionCost( Alternative &alt, const SymTab::Indexer &indexer ) {
    414433                ApplicationExpr *appExpr = strict_dynamic_cast< ApplicationExpr* >( alt.expr );
    415                 PointerType *pointer = strict_dynamic_cast< PointerType* >( appExpr->get_function()->get_result() );
    416                 FunctionType *function = strict_dynamic_cast< FunctionType* >( pointer->get_base() );
     434                PointerType *pointer = strict_dynamic_cast< PointerType* >( appExpr->function->result );
     435                FunctionType *function = strict_dynamic_cast< FunctionType* >( pointer->base );
    417436
    418437                Cost convCost = Cost::zero;
    419                 std::list< DeclarationWithType* >& formals = function->get_parameters();
     438                std::list< DeclarationWithType* >& formals = function->parameters;
    420439                std::list< DeclarationWithType* >::iterator formal = formals.begin();
    421                 std::list< Expression* >& actuals = appExpr->get_args();
    422 
    423                 for ( std::list< Expression* >::iterator actualExpr = actuals.begin(); actualExpr != actuals.end(); ++actualExpr ) {
    424                         Type * actualType = (*actualExpr)->get_result();
     440                std::list< Expression* >& actuals = appExpr->args;
     441
     442                for ( Expression*& actualExpr : actuals ) {
     443                        Type * actualType = actualExpr->result;
    425444                        PRINT(
    426445                                std::cerr << "actual expression:" << std::endl;
    427                                 (*actualExpr)->print( std::cerr, 8 );
     446                                actualExpr->print( std::cerr, 8 );
    428447                                std::cerr << "--- results are" << std::endl;
    429448                                actualType->print( std::cerr, 8 );
    430449                        )
    431450                        if ( formal == formals.end() ) {
    432                                 if ( function->get_isVarArgs() ) {
     451                                if ( function->isVarArgs ) {
    433452                                        convCost.incUnsafe();
    434453                                        PRINT( std::cerr << "end of formals with varargs function: inc unsafe: " << convCost << std::endl; ; )
    435454                                        // convert reference-typed expressions to value-typed expressions
    436                                         referenceToRvalueConversion( *actualExpr, convCost );
     455                                        referenceToRvalueConversion( actualExpr, convCost );
    437456                                        continue;
    438457                                } else {
     
    440459                                }
    441460                        }
     461                        if ( DefaultArgExpr * def = dynamic_cast< DefaultArgExpr * >( actualExpr ) ) {
     462                                // default arguments should be free - don't include conversion cost.
     463                                // Unwrap them here because they are not relevant to the rest of the system.
     464                                actualExpr = def->expr;
     465                                ++formal;
     466                                continue;
     467                        }
     468                        // mark conversion cost to formal and also specialization cost of formal type
    442469                        Type * formalType = (*formal)->get_type();
    443                         convCost += computeExpressionConversionCost( *actualExpr, formalType, indexer, alt.env );
     470                        convCost += computeExpressionConversionCost( actualExpr, formalType, indexer, alt.env );
     471                        convCost.decSpec( specCost( formalType ) );
    444472                        ++formal; // can't be in for-loop update because of the continue
    445473                }
     
    448476                }
    449477
    450                 for ( InferredParams::const_iterator assert = appExpr->get_inferParams().begin(); assert != appExpr->get_inferParams().end(); ++assert ) {
    451                         convCost += computeConversionCost( assert->second.actualType, assert->second.formalType, indexer, alt.env );
     478                // specialization cost of return types can't be accounted for directly, it disables
     479                // otherwise-identical calls, like this example based on auto-newline in the I/O lib:
     480                //
     481                //   forall(otype OS) {
     482                //     void ?|?(OS&, int);  // with newline
     483                //     OS&  ?|?(OS&, int);  // no newline, always chosen due to more specialization
     484                //   }
     485
     486                // mark type variable and specialization cost of forall clause
     487                convCost.incVar( function->forall.size() );
     488                for ( TypeDecl* td : function->forall ) {
     489                        convCost.decSpec( td->assertions.size() );
    452490                }
    453491
     
    462500                                needAssertions[ *assert ].isUsed = true;
    463501                        }
    464 ///     needAssertions.insert( needAssertions.end(), (*tyvar)->get_assertions().begin(), (*tyvar)->get_assertions().end() );
    465                 }
    466         }
    467 
    468         static const int recursionLimit = /*10*/ 4;  ///< Limit to depth of recursion satisfaction
    469 
    470         void addToIndexer( AssertionSet &assertSet, SymTab::Indexer &indexer ) {
    471                 for ( AssertionSet::iterator i = assertSet.begin(); i != assertSet.end(); ++i ) {
    472                         if ( i->second.isUsed ) {
    473                                 indexer.addId( i->first );
    474                         }
    475                 }
    476         }
    477 
    478         template< typename ForwardIterator, typename OutputIterator >
    479         void inferRecursive( ForwardIterator begin, ForwardIterator end, const Alternative &newAlt, OpenVarSet &openVars, const SymTab::Indexer &decls, const AssertionSet &newNeed, int level, const SymTab::Indexer &indexer, OutputIterator out ) {
    480                 if ( begin == end ) {
    481                         if ( newNeed.empty() ) {
    482                                 PRINT(
    483                                         std::cerr << "all assertions satisfied, output alternative: ";
    484                                         newAlt.print( std::cerr );
    485                                         std::cerr << std::endl;
    486                                 );
    487                                 *out++ = newAlt;
    488                                 return;
    489                         } else if ( level >= recursionLimit ) {
    490                                 SemanticError( newAlt.expr->location, "Too many recursive assertions" );
    491                         } else {
    492                                 AssertionSet newerNeed;
    493                                 PRINT(
    494                                         std::cerr << "recursing with new set:" << std::endl;
    495                                         printAssertionSet( newNeed, std::cerr, 8 );
    496                                 )
    497                                 inferRecursive( newNeed.begin(), newNeed.end(), newAlt, openVars, decls, newerNeed, level+1, indexer, out );
    498                                 return;
    499                         }
    500                 }
    501 
    502                 ForwardIterator cur = begin++;
    503                 if ( ! cur->second.isUsed ) {
    504                         inferRecursive( begin, end, newAlt, openVars, decls, newNeed, level, indexer, out );
    505                         return; // xxx - should this continue? previously this wasn't here, and it looks like it should be
    506                 }
    507                 DeclarationWithType *curDecl = cur->first;
    508 
    509                 PRINT(
    510                         std::cerr << "inferRecursive: assertion is ";
    511                         curDecl->print( std::cerr );
    512                         std::cerr << std::endl;
    513                 )
    514                 std::list< SymTab::Indexer::IdData > candidates;
    515                 decls.lookupId( curDecl->get_name(), candidates );
    516 ///   if ( candidates.empty() ) { std::cerr << "no candidates!" << std::endl; }
    517                 for ( const auto & data : candidates ) {
    518                         DeclarationWithType * candidate = data.id;
    519                         PRINT(
    520                                 std::cerr << "inferRecursive: candidate is ";
    521                                 candidate->print( std::cerr );
    522                                 std::cerr << std::endl;
    523                         )
    524 
    525                         AssertionSet newHave, newerNeed( newNeed );
    526                         TypeEnvironment newEnv( newAlt.env );
    527                         OpenVarSet newOpenVars( openVars );
    528                         Type *adjType = candidate->get_type()->clone();
    529                         adjustExprType( adjType, newEnv, indexer );
    530                         renameTyVars( adjType );
    531                         PRINT(
    532                                 std::cerr << "unifying ";
    533                                 curDecl->get_type()->print( std::cerr );
    534                                 std::cerr << " with ";
    535                                 adjType->print( std::cerr );
    536                                 std::cerr << std::endl;
    537                         )
    538                         if ( unify( curDecl->get_type(), adjType, newEnv, newerNeed, newHave, newOpenVars, indexer ) ) {
    539                                 PRINT(
    540                                         std::cerr << "success!" << std::endl;
    541                                 )
    542                                 SymTab::Indexer newDecls( decls );
    543                                 addToIndexer( newHave, newDecls );
    544                                 Alternative newerAlt( newAlt );
    545                                 newerAlt.env = newEnv;
    546                                 assertf( candidate->get_uniqueId(), "Assertion candidate does not have a unique ID: %s", toString( candidate ).c_str() );
    547 
    548                                 // everything with an empty idChain was pulled in by the current assertion.
    549                                 // add current assertion's idChain + current assertion's ID so that the correct inferParameters can be found.
    550                                 for ( auto & a : newerNeed ) {
    551                                         if ( a.second.idChain.empty() ) {
    552                                                 a.second.idChain = cur->second.idChain;
    553                                                 a.second.idChain.push_back( curDecl->get_uniqueId() );
    554                                         }
    555                                 }
    556 
    557                                 Expression *varExpr = data.combine( newerAlt.cvtCost );
    558                                 delete varExpr->get_result();
    559                                 varExpr->set_result( adjType->clone() );
    560                                 PRINT(
    561                                         std::cerr << "satisfying assertion " << curDecl->get_uniqueId() << " ";
    562                                         curDecl->print( std::cerr );
    563                                         std::cerr << " with declaration " << candidate->get_uniqueId() << " ";
    564                                         candidate->print( std::cerr );
    565                                         std::cerr << std::endl;
    566                                 )
    567                                 // follow the current assertion's ID chain to find the correct set of inferred parameters to add the candidate to (i.e. the set of inferred parameters belonging to the entity which requested the assertion parameter).
    568                                 InferredParams * inferParameters = &newerAlt.expr->get_inferParams();
    569                                 for ( UniqueId id : cur->second.idChain ) {
    570                                         inferParameters = (*inferParameters)[ id ].inferParams.get();
    571                                 }
    572                                 // XXX: this is a memory leak, but adjType can't be deleted because it might contain assertions
    573                                 (*inferParameters)[ curDecl->get_uniqueId() ] = ParamEntry( candidate->get_uniqueId(), adjType->clone(), curDecl->get_type()->clone(), varExpr );
    574                                 inferRecursive( begin, end, newerAlt, newOpenVars, newDecls, newerNeed, level, indexer, out );
    575                         } else {
    576                                 delete adjType;
    577                         }
    578                 }
    579         }
     502                }
     503        }
     504
     505        /// Unique identifier for matching expression resolutions to their requesting expression (located in CandidateFinder.cpp)
     506        extern UniqueId globalResnSlot;
    580507
    581508        template< typename OutputIterator >
    582         void AlternativeFinder::Finder::inferParameters( const AssertionSet &need, AssertionSet &have, const Alternative &newAlt, OpenVarSet &openVars, OutputIterator out ) {
    583 //      PRINT(
    584 //          std::cerr << "inferParameters: assertions needed are" << std::endl;
    585 //          printAll( need, std::cerr, 8 );
    586 //          )
    587                 SymTab::Indexer decls( indexer );
    588                 // PRINT(
    589                 //      std::cerr << "============= original indexer" << std::endl;
    590                 //      indexer.print( std::cerr );
    591                 //      std::cerr << "============= new indexer" << std::endl;
    592                 //      decls.print( std::cerr );
    593                 // )
    594                 addToIndexer( have, decls );
    595                 AssertionSet newNeed;
    596                 PRINT(
    597                         std::cerr << "env is: " << std::endl;
    598                         newAlt.env.print( std::cerr, 0 );
    599                         std::cerr << std::endl;
    600                 )
    601 
    602                 inferRecursive( need.begin(), need.end(), newAlt, openVars, decls, newNeed, 0, indexer, out );
    603 //      PRINT(
    604 //          std::cerr << "declaration 14 is ";
    605 //          Declaration::declFromId
    606 //          *out++ = newAlt;
    607 //          )
     509        void AlternativeFinder::Finder::inferParameters( Alternative &newAlt, OutputIterator out ) {
     510                // Set need bindings for any unbound assertions
     511                UniqueId crntResnSlot = 0;  // matching ID for this expression's assertions
     512                for ( auto& assn : newAlt.need ) {
     513                        // skip already-matched assertions
     514                        if ( assn.info.resnSlot != 0 ) continue;
     515                        // assign slot for expression if needed
     516                        if ( crntResnSlot == 0 ) { crntResnSlot = ++globalResnSlot; }
     517                        // fix slot to assertion
     518                        assn.info.resnSlot = crntResnSlot;
     519                }
     520                // pair slot to expression
     521                if ( crntResnSlot != 0 ) { newAlt.expr->resnSlots.push_back( crntResnSlot ); }
     522
     523                // add to output list, assertion resolution is deferred
     524                *out++ = newAlt;
    608525        }
    609526
     
    611528        ConstantExpr* getDefaultValue( Initializer* init ) {
    612529                if ( SingleInit* si = dynamic_cast<SingleInit*>( init ) ) {
    613                         if ( CastExpr* ce = dynamic_cast<CastExpr*>( si->get_value() ) ) {
    614                                 return dynamic_cast<ConstantExpr*>( ce->get_arg() );
     530                        if ( CastExpr* ce = dynamic_cast<CastExpr*>( si->value ) ) {
     531                                return dynamic_cast<ConstantExpr*>( ce->arg );
     532                        } else {
     533                                return dynamic_cast<ConstantExpr*>( si->value );
    615534                        }
    616535                }
     
    659578
    660579                /// Gets the list of exploded alternatives for this pack
    661                 const ExplodedActual& getExpl( const ExplodedArgs& args ) const {
     580                const ExplodedActual& getExpl( const ExplodedArgs_old& args ) const {
    662581                        return args[nextArg-1][explAlt];
    663582                }
     
    683602        /// Instantiates an argument to match a formal, returns false if no results left
    684603        bool instantiateArgument( Type* formalType, Initializer* initializer,
    685                         const ExplodedArgs& args, std::vector<ArgPack>& results, std::size_t& genStart,
     604                        const ExplodedArgs_old& args, std::vector<ArgPack>& results, std::size_t& genStart,
    686605                        const SymTab::Indexer& indexer, unsigned nTuples = 0 ) {
    687606                if ( TupleType * tupleType = dynamic_cast<TupleType*>( formalType ) ) {
     
    873792                                                                indexer ) ) {
    874793                                                        results.emplace_back(
    875                                                                 i, cnstExpr, move(env), move(need), move(have),
     794                                                                i, new DefaultArgExpr( cnstExpr ), move(env), move(need), move(have),
    876795                                                                move(openVars), nextArg, nTuples );
    877796                                                }
     
    944863                }
    945864                // build and validate new alternative
    946                 Alternative newAlt( appExpr, result.env, cost );
     865                Alternative newAlt{ appExpr, result.env, result.openVars, result.need, cost };
    947866                PRINT(
    948867                        std::cerr << "instantiate function success: " << appExpr << std::endl;
     
    950869                        printAssertionSet( result.need, std::cerr, 8 );
    951870                )
    952                 inferParameters( result.need, result.have, newAlt, result.openVars, out );
     871                inferParameters( newAlt, out );
    953872        }
    954873
    955874        template<typename OutputIterator>
    956875        void AlternativeFinder::Finder::makeFunctionAlternatives( const Alternative &func,
    957                         FunctionType *funcType, const ExplodedArgs &args, OutputIterator out ) {
     876                        FunctionType *funcType, const ExplodedArgs_old &args, OutputIterator out ) {
    958877                OpenVarSet funcOpenVars;
    959878                AssertionSet funcNeed, funcHave;
     
    1065984                funcFinder.findWithAdjustment( untypedExpr->function );
    1066985                // if there are no function alternatives, then proceeding is a waste of time.
     986                // xxx - findWithAdjustment throws, so this check and others like it shouldn't be necessary.
    1067987                if ( funcFinder.alternatives.empty() ) return;
    1068988
     
    10861006
    10871007                // pre-explode arguments
    1088                 ExplodedArgs argExpansions;
     1008                ExplodedArgs_old argExpansions;
    10891009                argExpansions.reserve( argAlternatives.size() );
    10901010
     
    10921012                        argExpansions.emplace_back();
    10931013                        auto& argE = argExpansions.back();
    1094                         argE.reserve( arg.alternatives.size() );
     1014                        // argE.reserve( arg.alternatives.size() );
    10951015
    10961016                        for ( const Alternative& actual : arg ) {
     
    11781098                                std::cerr << "bindings are:" << std::endl;
    11791099                                withFunc.env.print( std::cerr, 8 );
     1100                                std::cerr << "cost is: " << withFunc.cost << std::endl;
    11801101                                std::cerr << "cost of conversion is:" << cvtCost << std::endl;
    11811102                        )
     
    11931114
    11941115                // function may return struct or union value, in which case we need to add alternatives
    1195                 // for implicitconversions to each of the anonymous members, must happen after findMinCost
     1116                // for implicit conversions to each of the anonymous members, must happen after findMinCost
    11961117                // since anon conversions are never the cheapest expression
    11971118                for ( const Alternative & alt : winners ) {
     
    12161137        bool isLvalue( Expression *expr ) {
    12171138                // xxx - recurse into tuples?
    1218                 return expr->result && ( expr->result->get_lvalue() || dynamic_cast< ReferenceType * >( expr->result ) );
     1139                return expr->result && ( expr->get_lvalue() || dynamic_cast< ReferenceType * >( expr->result ) );
    12191140        }
    12201141
     
    12251146                        if ( isLvalue( alt.expr ) ) {
    12261147                                alternatives.push_back(
    1227                                         Alternative{ new AddressExpr( alt.expr->clone() ), alt.env, alt.cost } );
     1148                                        Alternative{ alt, new AddressExpr( alt.expr->clone() ), alt.cost } );
    12281149                        } // if
    12291150                } // for
     
    12311152
    12321153        void AlternativeFinder::Finder::postvisit( LabelAddressExpr * expr ) {
    1233                 alternatives.push_back( Alternative{ expr->clone(), env, Cost::zero } );
     1154                alternatives.push_back( Alternative{ expr->clone(), env } );
    12341155        }
    12351156
     
    12671188                assert( toType );
    12681189                toType = resolveTypeof( toType, indexer );
     1190                assert(!dynamic_cast<TypeofType *>(toType));
    12691191                SymTab::validateType( toType, &indexer );
    12701192                adjustExprType( toType, env, indexer );
     
    12761198                AltList candidates;
    12771199                for ( Alternative & alt : finder.alternatives ) {
    1278                         AssertionSet needAssertions, haveAssertions;
    1279                         OpenVarSet openVars;
     1200                        AssertionSet needAssertions( alt.need.begin(), alt.need.end() );
     1201                        AssertionSet haveAssertions;
     1202                        OpenVarSet openVars{ alt.openVars };
    12801203
    12811204                        alt.env.extractOpenVars( openVars );
     
    12921215                        unify( castExpr->result, alt.expr->result, alt.env, needAssertions,
    12931216                                haveAssertions, openVars, indexer );
    1294                         Cost thisCost = castCost( alt.expr->result, castExpr->result, indexer,
    1295                                 alt.env );
     1217                        Cost thisCost = castCost( alt.expr->result, castExpr->result, alt.expr->get_lvalue(),
     1218                                indexer, alt.env );
    12961219                        PRINT(
    12971220                                std::cerr << "working on cast with result: " << castExpr->result << std::endl;
     
    13051228                                // count one safe conversion for each value that is thrown away
    13061229                                thisCost.incSafe( discardedValues );
    1307                                 Alternative newAlt( restructureCast( alt.expr->clone(), toType, castExpr->isGenerated ), alt.env,
    1308                                         alt.cost, thisCost );
    1309                                 inferParameters( needAssertions, haveAssertions, newAlt, openVars,
    1310                                         back_inserter( candidates ) );
     1230                                Alternative newAlt{
     1231                                        restructureCast( alt.expr->clone(), toType, castExpr->isGenerated ),
     1232                                        alt.env, openVars, needAssertions, alt.cost, alt.cost + thisCost };
     1233                                inferParameters( newAlt, back_inserter( candidates ) );
    13111234                        } // if
    13121235                } // for
     
    13211244
    13221245        void AlternativeFinder::Finder::postvisit( VirtualCastExpr * castExpr ) {
    1323                 assertf( castExpr->get_result(), "Implicate virtual cast targets not yet supported." );
     1246                assertf( castExpr->get_result(), "Implicit virtual cast targets not yet supported." );
    13241247                AlternativeFinder finder( indexer, env );
    13251248                // don't prune here, since it's guaranteed all alternatives will have the same type
    13261249                finder.findWithoutPrune( castExpr->get_arg() );
    13271250                for ( Alternative & alt : finder.alternatives ) {
    1328                         alternatives.push_back( Alternative(
    1329                                 new VirtualCastExpr( alt.expr->clone(), castExpr->get_result()->clone() ),
    1330                                 alt.env, alt.cost ) );
     1251                        alternatives.push_back( Alternative{
     1252                                alt, new VirtualCastExpr{ alt.expr->clone(), castExpr->get_result()->clone() },
     1253                                alt.cost } );
    13311254                }
    13321255        }
     
    13351258                /// Gets name from untyped member expression (member must be NameExpr)
    13361259                const std::string& get_member_name( UntypedMemberExpr *memberExpr ) {
     1260                        if ( dynamic_cast< ConstantExpr * >( memberExpr->get_member() ) ) {
     1261                                SemanticError( memberExpr, "Indexed access to struct fields unsupported: " );
     1262                        } // if
    13371263                        NameExpr * nameExpr = dynamic_cast< NameExpr * >( memberExpr->get_member() );
    13381264                        assert( nameExpr );
     
    13531279                        // find member of the given type
    13541280                        if ( StructInstType *structInst = dynamic_cast< StructInstType* >( aggrExpr->get_result() ) ) {
    1355                                 addAggMembers( structInst, aggrExpr, cost, agg->env, get_member_name(memberExpr) );
     1281                                addAggMembers( structInst, aggrExpr, *agg, cost, get_member_name(memberExpr) );
    13561282                        } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( aggrExpr->get_result() ) ) {
    1357                                 addAggMembers( unionInst, aggrExpr, cost, agg->env, get_member_name(memberExpr) );
     1283                                addAggMembers( unionInst, aggrExpr, *agg, cost, get_member_name(memberExpr) );
    13581284                        } else if ( TupleType * tupleType = dynamic_cast< TupleType * >( aggrExpr->get_result() ) ) {
    1359                                 addTupleMembers( tupleType, aggrExpr, cost, agg->env, memberExpr->get_member() );
     1285                                addTupleMembers( tupleType, aggrExpr, *agg, cost, memberExpr->get_member() );
    13601286                        } // if
    13611287                } // for
     
    13631289
    13641290        void AlternativeFinder::Finder::postvisit( MemberExpr *memberExpr ) {
    1365                 alternatives.push_back( Alternative( memberExpr->clone(), env, Cost::zero ) );
     1291                alternatives.push_back( Alternative{ memberExpr->clone(), env } );
    13661292        }
    13671293
     
    13761302                        // addAnonAlternatives uses vector::push_back, which invalidates references to existing elements, so
    13771303                        // can't construct in place and use vector::back
    1378                         Alternative newAlt( newExpr, env, Cost::zero, cost );
     1304                        Alternative newAlt{ newExpr, env, OpenVarSet{}, AssertionList{}, Cost::zero, cost };
    13791305                        PRINT(
    13801306                                std::cerr << "decl is ";
     
    13941320                // not sufficient to clone here, because variable's type may have changed
    13951321                // since the VariableExpr was originally created.
    1396                 alternatives.push_back( Alternative( new VariableExpr( variableExpr->var ), env, Cost::zero ) );
     1322                alternatives.push_back( Alternative{ new VariableExpr{ variableExpr->var }, env } );
    13971323        }
    13981324
    13991325        void AlternativeFinder::Finder::postvisit( ConstantExpr *constantExpr ) {
    1400                 alternatives.push_back( Alternative( constantExpr->clone(), env, Cost::zero ) );
     1326                alternatives.push_back( Alternative{ constantExpr->clone(), env } );
    14011327        }
    14021328
     
    14041330                if ( sizeofExpr->get_isType() ) {
    14051331                        Type * newType = sizeofExpr->get_type()->clone();
    1406                         alternatives.push_back( Alternative( new SizeofExpr( resolveTypeof( newType, indexer ) ), env, Cost::zero ) );
     1332                        alternatives.push_back( Alternative{
     1333                                new SizeofExpr{ resolveTypeof( newType, indexer ) }, env } );
    14071334                } else {
    14081335                        // find all alternatives for the argument to sizeof
     
    14181345                        Alternative &choice = winners.front();
    14191346                        referenceToRvalueConversion( choice.expr, choice.cost );
    1420                         alternatives.push_back( Alternative( new SizeofExpr( choice.expr->clone() ), choice.env, Cost::zero ) );
     1347                        alternatives.push_back( Alternative{
     1348                                choice, new SizeofExpr( choice.expr->clone() ), Cost::zero } );
    14211349                } // if
    14221350        }
     
    14251353                if ( alignofExpr->get_isType() ) {
    14261354                        Type * newType = alignofExpr->get_type()->clone();
    1427                         alternatives.push_back( Alternative( new AlignofExpr( resolveTypeof( newType, indexer ) ), env, Cost::zero ) );
     1355                        alternatives.push_back( Alternative{
     1356                                new AlignofExpr{ resolveTypeof( newType, indexer ) }, env } );
    14281357                } else {
    14291358                        // find all alternatives for the argument to sizeof
     
    14391368                        Alternative &choice = winners.front();
    14401369                        referenceToRvalueConversion( choice.expr, choice.cost );
    1441                         alternatives.push_back( Alternative( new AlignofExpr( choice.expr->clone() ), choice.env, Cost::zero ) );
     1370                        alternatives.push_back( Alternative{
     1371                                choice, new AlignofExpr{ choice.expr->clone() }, Cost::zero } );
    14421372                } // if
    14431373        }
     
    14491379                for ( std::list< Declaration* >::const_iterator i = members.begin(); i != members.end(); ++i ) {
    14501380                        if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( *i ) ) {
    1451                                 alternatives.push_back( Alternative( new OffsetofExpr( aggInst->clone(), dwt ), env, Cost::zero ) );
     1381                                alternatives.push_back( Alternative{
     1382                                        new OffsetofExpr{ aggInst->clone(), dwt }, env } );
    14521383                                renameTypes( alternatives.back().expr );
    14531384                        } else {
     
    14681399
    14691400        void AlternativeFinder::Finder::postvisit( OffsetofExpr *offsetofExpr ) {
    1470                 alternatives.push_back( Alternative( offsetofExpr->clone(), env, Cost::zero ) );
     1401                alternatives.push_back( Alternative{ offsetofExpr->clone(), env } );
    14711402        }
    14721403
    14731404        void AlternativeFinder::Finder::postvisit( OffsetPackExpr *offsetPackExpr ) {
    1474                 alternatives.push_back( Alternative( offsetPackExpr->clone(), env, Cost::zero ) );
    1475         }
    1476 
    1477         namespace {
    1478                 void resolveAttr( SymTab::Indexer::IdData data, FunctionType *function, Type *argType, const TypeEnvironment &env, AlternativeFinder & finder ) {
    1479                         // assume no polymorphism
    1480                         // assume no implicit conversions
    1481                         assert( function->get_parameters().size() == 1 );
    1482                         PRINT(
    1483                                 std::cerr << "resolvAttr: funcDecl is ";
    1484                                 data.id->print( std::cerr );
    1485                                 std::cerr << " argType is ";
    1486                                 argType->print( std::cerr );
    1487                                 std::cerr << std::endl;
    1488                         )
    1489                         const SymTab::Indexer & indexer = finder.get_indexer();
    1490                         AltList & alternatives = finder.get_alternatives();
    1491                         if ( typesCompatibleIgnoreQualifiers( argType, function->get_parameters().front()->get_type(), indexer, env ) ) {
    1492                                 Cost cost = Cost::zero;
    1493                                 Expression * newExpr = data.combine( cost );
    1494                                 alternatives.push_back( Alternative( new AttrExpr( newExpr, argType->clone() ), env, Cost::zero, cost ) );
    1495                                 for ( DeclarationWithType * retVal : function->returnVals ) {
    1496                                         alternatives.back().expr->result = retVal->get_type()->clone();
    1497                                 } // for
    1498                         } // if
    1499                 }
    1500         }
    1501 
    1502         void AlternativeFinder::Finder::postvisit( AttrExpr *attrExpr ) {
    1503                 // assume no 'pointer-to-attribute'
    1504                 NameExpr *nameExpr = dynamic_cast< NameExpr* >( attrExpr->get_attr() );
    1505                 assert( nameExpr );
    1506                 std::list< SymTab::Indexer::IdData > attrList;
    1507                 indexer.lookupId( nameExpr->get_name(), attrList );
    1508                 if ( attrExpr->get_isType() || attrExpr->get_expr() ) {
    1509                         for ( auto & data : attrList ) {
    1510                                 DeclarationWithType * id = data.id;
    1511                                 // check if the type is function
    1512                                 if ( FunctionType *function = dynamic_cast< FunctionType* >( id->get_type() ) ) {
    1513                                         // assume exactly one parameter
    1514                                         if ( function->get_parameters().size() == 1 ) {
    1515                                                 if ( attrExpr->get_isType() ) {
    1516                                                         resolveAttr( data, function, attrExpr->get_type(), env, altFinder);
    1517                                                 } else {
    1518                                                         AlternativeFinder finder( indexer, env );
    1519                                                         finder.find( attrExpr->get_expr() );
    1520                                                         for ( AltList::iterator choice = finder.alternatives.begin(); choice != finder.alternatives.end(); ++choice ) {
    1521                                                                 if ( choice->expr->get_result()->size() == 1 ) {
    1522                                                                         resolveAttr(data, function, choice->expr->get_result(), choice->env, altFinder );
    1523                                                                 } // fi
    1524                                                         } // for
    1525                                                 } // if
    1526                                         } // if
    1527                                 } // if
    1528                         } // for
    1529                 } else {
    1530                         for ( auto & data : attrList ) {
    1531                                 Cost cost = Cost::zero;
    1532                                 Expression * newExpr = data.combine( cost );
    1533                                 alternatives.push_back( Alternative( newExpr, env, Cost::zero, cost ) );
    1534                                 renameTypes( alternatives.back().expr );
    1535                         } // for
    1536                 } // if
    1537         }
    1538 
    1539         void AlternativeFinder::Finder::postvisit( LogicalExpr *logicalExpr ) {
     1405                alternatives.push_back( Alternative{ offsetPackExpr->clone(), env } );
     1406        }
     1407
     1408        void AlternativeFinder::Finder::postvisit( LogicalExpr * logicalExpr ) {
    15401409                AlternativeFinder firstFinder( indexer, env );
    15411410                firstFinder.findWithAdjustment( logicalExpr->get_arg1() );
     
    15461415                for ( const Alternative & first : firstFinder.alternatives ) {
    15471416                        for ( const Alternative & second : secondFinder.alternatives ) {
    1548                                 TypeEnvironment compositeEnv;
    1549                                 compositeEnv.simpleCombine( first.env );
     1417                                TypeEnvironment compositeEnv{ first.env };
    15501418                                compositeEnv.simpleCombine( second.env );
    1551 
    1552                                 LogicalExpr *newExpr = new LogicalExpr( first.expr->clone(), second.expr->clone(), logicalExpr->get_isAnd() );
    1553                                 alternatives.push_back( Alternative( newExpr, compositeEnv, first.cost + second.cost ) );
     1419                                OpenVarSet openVars{ first.openVars };
     1420                                mergeOpenVars( openVars, second.openVars );
     1421                                AssertionSet need;
     1422                                cloneAll( first.need, need );
     1423                                cloneAll( second.need, need );
     1424
     1425                                LogicalExpr *newExpr = new LogicalExpr{
     1426                                        first.expr->clone(), second.expr->clone(), logicalExpr->get_isAnd() };
     1427                                alternatives.push_back( Alternative{
     1428                                        newExpr, std::move(compositeEnv), std::move(openVars),
     1429                                        AssertionList( need.begin(), need.end() ), first.cost + second.cost } );
    15541430                        }
    15551431                }
     
    15721448                        for ( const Alternative & second : secondFinder.alternatives ) {
    15731449                                for ( const Alternative & third : thirdFinder.alternatives ) {
    1574                                         TypeEnvironment compositeEnv;
    1575                                         compositeEnv.simpleCombine( first.env );
     1450                                        TypeEnvironment compositeEnv{ first.env };
    15761451                                        compositeEnv.simpleCombine( second.env );
    15771452                                        compositeEnv.simpleCombine( third.env );
     1453                                        OpenVarSet openVars{ first.openVars };
     1454                                        mergeOpenVars( openVars, second.openVars );
     1455                                        mergeOpenVars( openVars, third.openVars );
     1456                                        AssertionSet need;
     1457                                        cloneAll( first.need, need );
     1458                                        cloneAll( second.need, need );
     1459                                        cloneAll( third.need, need );
     1460                                        AssertionSet have;
    15781461
    15791462                                        // unify true and false types, then infer parameters to produce new alternatives
    1580                                         OpenVarSet openVars;
    1581                                         AssertionSet needAssertions, haveAssertions;
    1582                                         Alternative newAlt( 0, compositeEnv, first.cost + second.cost + third.cost );
    15831463                                        Type* commonType = nullptr;
    1584                                         if ( unify( second.expr->result, third.expr->result, newAlt.env, needAssertions, haveAssertions, openVars, indexer, commonType ) ) {
    1585                                                 ConditionalExpr *newExpr = new ConditionalExpr( first.expr->clone(), second.expr->clone(), third.expr->clone() );
     1464                                        if ( unify( second.expr->result, third.expr->result, compositeEnv,
     1465                                                        need, have, openVars, indexer, commonType ) ) {
     1466                                                ConditionalExpr *newExpr = new ConditionalExpr{
     1467                                                        first.expr->clone(), second.expr->clone(), third.expr->clone() };
    15861468                                                newExpr->result = commonType ? commonType : second.expr->result->clone();
    15871469                                                // convert both options to the conditional result type
    1588                                                 newAlt.cost += computeExpressionConversionCost( newExpr->arg2, newExpr->result, indexer, newAlt.env );
    1589                                                 newAlt.cost += computeExpressionConversionCost( newExpr->arg3, newExpr->result, indexer, newAlt.env );
    1590                                                 newAlt.expr = newExpr;
    1591                                                 inferParameters( needAssertions, haveAssertions, newAlt, openVars, back_inserter( alternatives ) );
     1470                                                Cost cost = first.cost + second.cost + third.cost;
     1471                                                cost += computeExpressionConversionCost(
     1472                                                        newExpr->arg2, newExpr->result, indexer, compositeEnv );
     1473                                                cost += computeExpressionConversionCost(
     1474                                                        newExpr->arg3, newExpr->result, indexer, compositeEnv );
     1475                                                // output alternative
     1476                                                Alternative newAlt{
     1477                                                        newExpr, std::move(compositeEnv), std::move(openVars),
     1478                                                        AssertionList( need.begin(), need.end() ), cost };
     1479                                                inferParameters( newAlt, back_inserter( alternatives ) );
    15921480                                        } // if
    15931481                                } // for
     
    16021490                secondFinder.findWithAdjustment( commaExpr->get_arg2() );
    16031491                for ( const Alternative & alt : secondFinder.alternatives ) {
    1604                         alternatives.push_back( Alternative( new CommaExpr( newFirstArg->clone(), alt.expr->clone() ), alt.env, alt.cost ) );
     1492                        alternatives.push_back( Alternative{
     1493                                alt, new CommaExpr{ newFirstArg->clone(), alt.expr->clone() }, alt.cost } );
    16051494                } // for
    16061495                delete newFirstArg;
     
    16171506                for ( const Alternative & first : firstFinder.alternatives ) {
    16181507                        for ( const Alternative & second : secondFinder.alternatives ) {
    1619                                 TypeEnvironment compositeEnv;
    1620                                 compositeEnv.simpleCombine( first.env );
     1508                                TypeEnvironment compositeEnv{ first.env };
    16211509                                compositeEnv.simpleCombine( second.env );
    1622                                 OpenVarSet openVars;
    1623                                 AssertionSet needAssertions, haveAssertions;
    1624                                 Alternative newAlt( 0, compositeEnv, first.cost + second.cost );
     1510                                OpenVarSet openVars{ first.openVars };
     1511                                mergeOpenVars( openVars, second.openVars );
     1512                                AssertionSet need;
     1513                                cloneAll( first.need, need );
     1514                                cloneAll( second.need, need );
     1515                                AssertionSet have;
     1516
    16251517                                Type* commonType = nullptr;
    1626                                 if ( unify( first.expr->result, second.expr->result, newAlt.env, needAssertions, haveAssertions, openVars, indexer, commonType ) ) {
    1627                                         RangeExpr * newExpr = new RangeExpr( first.expr->clone(), second.expr->clone() );
     1518                                if ( unify( first.expr->result, second.expr->result, compositeEnv, need, have,
     1519                                                openVars, indexer, commonType ) ) {
     1520                                        RangeExpr * newExpr =
     1521                                                new RangeExpr{ first.expr->clone(), second.expr->clone() };
    16281522                                        newExpr->result = commonType ? commonType : first.expr->result->clone();
    1629                                         newAlt.expr = newExpr;
    1630                                         inferParameters( needAssertions, haveAssertions, newAlt, openVars, back_inserter( alternatives ) );
     1523                                        Alternative newAlt{
     1524                                                newExpr, std::move(compositeEnv), std::move(openVars),
     1525                                                AssertionList( need.begin(), need.end() ), first.cost + second.cost };
     1526                                        inferParameters( newAlt, back_inserter( alternatives ) );
    16311527                                } // if
    16321528                        } // for
     
    16461542
    16471543                        TypeEnvironment compositeEnv;
    1648                         simpleCombineEnvironments( alts.begin(), alts.end(), compositeEnv );
    1649                         alternatives.push_back(
    1650                                 Alternative{ new TupleExpr( exprs ), compositeEnv, sumCost( alts ) } );
     1544                        OpenVarSet openVars;
     1545                        AssertionSet need;
     1546                        for ( const Alternative& alt : alts ) {
     1547                                compositeEnv.simpleCombine( alt.env );
     1548                                mergeOpenVars( openVars, alt.openVars );
     1549                                cloneAll( alt.need, need );
     1550                        }
     1551
     1552                        alternatives.push_back( Alternative{
     1553                                new TupleExpr{ exprs }, std::move(compositeEnv), std::move(openVars),
     1554                                AssertionList( need.begin(), need.end() ), sumCost( alts ) } );
    16511555                } // for
    16521556        }
    16531557
    16541558        void AlternativeFinder::Finder::postvisit( TupleExpr *tupleExpr ) {
    1655                 alternatives.push_back( Alternative( tupleExpr->clone(), env, Cost::zero ) );
     1559                alternatives.push_back( Alternative{ tupleExpr->clone(), env } );
    16561560        }
    16571561
    16581562        void AlternativeFinder::Finder::postvisit( ImplicitCopyCtorExpr * impCpCtorExpr ) {
    1659                 alternatives.push_back( Alternative( impCpCtorExpr->clone(), env, Cost::zero ) );
     1563                alternatives.push_back( Alternative{ impCpCtorExpr->clone(), env } );
    16601564        }
    16611565
     
    16661570                finder.findWithoutPrune( ctorExpr->get_callExpr() );
    16671571                for ( Alternative & alt : finder.alternatives ) {
    1668                         alternatives.push_back( Alternative( new ConstructorExpr( alt.expr->clone() ), alt.env, alt.cost ) );
     1572                        alternatives.push_back( Alternative{
     1573                                alt, new ConstructorExpr( alt.expr->clone() ), alt.cost } );
    16691574                }
    16701575        }
    16711576
    16721577        void AlternativeFinder::Finder::postvisit( TupleIndexExpr *tupleExpr ) {
    1673                 alternatives.push_back( Alternative( tupleExpr->clone(), env, Cost::zero ) );
     1578                alternatives.push_back( Alternative{ tupleExpr->clone(), env } );
    16741579        }
    16751580
    16761581        void AlternativeFinder::Finder::postvisit( TupleAssignExpr *tupleAssignExpr ) {
    1677                 alternatives.push_back( Alternative( tupleAssignExpr->clone(), env, Cost::zero ) );
     1582                alternatives.push_back( Alternative{ tupleAssignExpr->clone(), env } );
    16781583        }
    16791584
     
    16841589                        // ensure that the id is passed on to the UniqueExpr alternative so that the expressions are "linked"
    16851590                        UniqueExpr * newUnqExpr = new UniqueExpr( alt.expr->clone(), unqExpr->get_id() );
    1686                         alternatives.push_back( Alternative( newUnqExpr, alt.env, alt.cost ) );
     1591                        alternatives.push_back( Alternative{ alt, newUnqExpr, alt.cost } );
    16871592                }
    16881593        }
     
    16921597                ResolvExpr::resolveStmtExpr( newStmtExpr, indexer );
    16931598                // xxx - this env is almost certainly wrong, and needs to somehow contain the combined environments from all of the statements in the stmtExpr...
    1694                 alternatives.push_back( Alternative( newStmtExpr, env, Cost::zero ) );
     1599                alternatives.push_back( Alternative{ newStmtExpr, env } );
    16951600        }
    16961601
     
    17141619                        for ( Alternative & alt : finder.get_alternatives() ) {
    17151620                                TypeEnvironment newEnv( alt.env );
    1716                                 AssertionSet needAssertions, haveAssertions;
    1717                                 OpenVarSet openVars;  // find things in env that don't have a "representative type" and claim those are open vars?
     1621                                AssertionSet need;
     1622                                cloneAll( alt.need, need );
     1623                                AssertionSet have;
     1624                                OpenVarSet openVars( alt.openVars );
     1625                                // xxx - find things in env that don't have a "representative type" and claim
     1626                                // those are open vars?
    17181627                                PRINT(
    17191628                                        std::cerr << "  @ " << toType << " " << initAlt.designation << std::endl;
    17201629                                )
    1721                                 // It's possible that a cast can throw away some values in a multiply-valued expression.  (An example is a
    1722                                 // cast-to-void, which casts from one value to zero.)  Figure out the prefix of the subexpression results
    1723                                 // that are cast directly.  The candidate is invalid if it has fewer results than there are types to cast
    1724                                 // to.
     1630                                // It's possible that a cast can throw away some values in a multiply-valued
     1631                                // expression. (An example is a cast-to-void, which casts from one value to
     1632                                // zero.)  Figure out the prefix of the subexpression results that are cast
     1633                                // directly.  The candidate is invalid if it has fewer results than there are
     1634                                // types to cast to.
    17251635                                int discardedValues = alt.expr->result->size() - toType->size();
    17261636                                if ( discardedValues < 0 ) continue;
    1727                                 // xxx - may need to go into tuple types and extract relevant types and use unifyList. Note that currently, this does not
    1728                                 // allow casting a tuple to an atomic type (e.g. (int)([1, 2, 3]))
     1637                                // xxx - may need to go into tuple types and extract relevant types and use
     1638                                // unifyList. Note that currently, this does not allow casting a tuple to an
     1639                                // atomic type (e.g. (int)([1, 2, 3]))
     1640
    17291641                                // unification run for side-effects
    1730                                 unify( toType, alt.expr->result, newEnv, needAssertions, haveAssertions, openVars, indexer ); // xxx - do some inspecting on this line... why isn't result bound to initAlt.type??
    1731 
    1732                                 Cost thisCost = castCost( alt.expr->result, toType, indexer, newEnv );
     1642                                unify( toType, alt.expr->result, newEnv, need, have, openVars, indexer );
     1643                                // xxx - do some inspecting on this line... why isn't result bound to initAlt.type?
     1644
     1645                                Cost thisCost = castCost( alt.expr->result, toType, alt.expr->get_lvalue(),
     1646                                        indexer, newEnv );
    17331647                                if ( thisCost != Cost::infinity ) {
    17341648                                        // count one safe conversion for each value that is thrown away
    17351649                                        thisCost.incSafe( discardedValues );
    1736                                         Alternative newAlt( new InitExpr( restructureCast( alt.expr->clone(), toType, true ), initAlt.designation->clone() ), newEnv, alt.cost, thisCost );
    1737                                         inferParameters( needAssertions, haveAssertions, newAlt, openVars, back_inserter( candidates ) );
     1650                                        Alternative newAlt{
     1651                                                new InitExpr{
     1652                                                        restructureCast( alt.expr->clone(), toType, true ), initAlt.designation->clone() },
     1653                                                std::move(newEnv), std::move(openVars),
     1654                                                AssertionList( need.begin(), need.end() ), alt.cost, thisCost };
     1655                                        inferParameters( newAlt, back_inserter( candidates ) );
    17381656                                }
    17391657                        }
  • src/ResolvExpr/AlternativeFinder.h

    r7951100 rb067d9b  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sat May 16 23:56:12 2015
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Wed Jul 26 11:24:00 2017
    13 // Update Count     : 4
     11// Last Modified By : Aaron B. Moss
     12// Last Modified On : Fri Oct -5 10:01:00 2018
     13// Update Count     : 5
    1414//
    1515
     
    2424#include "ResolvExpr/Cost.h"             // for Cost, Cost::infinity
    2525#include "ResolvExpr/TypeEnvironment.h"  // for AssertionSet, OpenVarSet
     26#include "ResolvMode.h"                  // for ResolvMode
    2627#include "SynTree/Visitor.h"             // for Visitor
    2728#include "SynTree/SynTree.h"             // for Visitor Nodes
     
    3637        /// First index is which argument, second index is which alternative for that argument,
    3738        /// third index is which exploded element of that alternative
    38         using ExplodedArgs = std::vector< std::vector< ExplodedActual > >;
     39        using ExplodedArgs_old = std::vector< std::vector< ExplodedActual > >;
    3940
    4041        class AlternativeFinder {
     
    6869                }
    6970
    70                 void find( Expression *expr, bool adjust = false, bool prune = true, bool failFast = true );
     71                void find( Expression *expr, ResolvMode mode = ResolvMode{} );
    7172                /// Calls find with the adjust flag set; adjustment turns array and function types into equivalent pointer types
    7273                void findWithAdjustment( Expression *expr );
  • src/ResolvExpr/CastCost.cc

    r7951100 rb067d9b  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 06:57:43 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Feb  2 15:34:36 2016
    13 // Update Count     : 7
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Thu Aug  8 16:12:00 2019
     13// Update Count     : 8
    1414//
    1515
    1616#include <cassert>                       // for assert
    1717
     18#include "AST/Print.hpp"
     19#include "AST/SymbolTable.hpp"
     20#include "AST/Type.hpp"
     21#include "AST/TypeEnvironment.hpp"
    1822#include "ConversionCost.h"              // for ConversionCost
    1923#include "Cost.h"                        // for Cost, Cost::infinity
     
    3135
    3236namespace ResolvExpr {
    33         struct CastCost : public ConversionCost {
     37        struct CastCost_old : public ConversionCost {
    3438          public:
    35                 CastCost( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc );
     39                CastCost_old( const Type * dest, bool srcIsLvalue,
     40                        const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc );
    3641
    3742                using ConversionCost::previsit;
    3843                using ConversionCost::postvisit;
    39                 void postvisit( BasicType * basicType );
    40                 void postvisit( PointerType * pointerType );
     44                void postvisit( const BasicType * basicType );
     45                void postvisit( const PointerType * pointerType );
    4146        };
    4247
    43         Cost castCost( Type *src, Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
    44                 if ( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) {
    45                         if ( const EqvClass* eqvClass = env.lookup( destAsTypeInst->get_name() ) ) {
     48        Cost castCost( const Type * src, const Type * dest, bool srcIsLvalue,
     49                        const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
     50                if ( const TypeInstType * destAsTypeInst = dynamic_cast< const TypeInstType * >( dest ) ) {
     51                        if ( const EqvClass * eqvClass = env.lookup( destAsTypeInst->name ) ) {
    4652                                if ( eqvClass->type ) {
    47                                         return castCost( src, eqvClass->type, indexer, env );
     53                                        return castCost( src, eqvClass->type, srcIsLvalue, indexer, env );
    4854                                } else {
    4955                                        return Cost::infinity;
    5056                                }
    51                         } else if ( NamedTypeDecl *namedType = indexer.lookupType( destAsTypeInst->get_name() ) ) {
     57                        } else if ( const NamedTypeDecl * namedType = indexer.lookupType( destAsTypeInst->name ) ) {
    5258                                // all typedefs should be gone by this point
    53                                 TypeDecl *type = strict_dynamic_cast< TypeDecl* >( namedType );
     59                                const TypeDecl * type = strict_dynamic_cast< const TypeDecl * >( namedType );
    5460                                if ( type->base ) {
    55                                         return castCost( src, type->base, indexer, env ) + Cost::safe;
     61                                        return castCost( src, type->base, srcIsLvalue, indexer, env ) + Cost::safe;
    5662                                } // if
    5763                        } // if
     
    7076                        PRINT( std::cerr << "compatible!" << std::endl; )
    7177                        return Cost::zero;
    72                 } else if ( dynamic_cast< VoidType* >( dest ) ) {
     78                } else if ( dynamic_cast< const VoidType * >( dest ) ) {
    7379                        return Cost::safe;
    74                 } else if ( ReferenceType * refType = dynamic_cast< ReferenceType * > ( dest ) ) {
     80                } else if ( const ReferenceType * refType = dynamic_cast< const ReferenceType * > ( dest ) ) {
    7581                        PRINT( std::cerr << "conversionCost: dest is reference" << std::endl; )
    76                         return convertToReferenceCost( src, refType, indexer, env, [](Type * t1, Type * t2, const SymTab::Indexer & indexer, const TypeEnvironment & env ) {
     82                        return convertToReferenceCost( src, refType, srcIsLvalue, indexer, env, [](const Type * t1, const Type * t2, const SymTab::Indexer & indexer, const TypeEnvironment & env ) {
    7783                                return ptrsCastable( t1, t2, env, indexer );
    7884                        });
    7985                } else {
    80                         PassVisitor<CastCost> converter( dest, indexer, env, castCost );
     86                        PassVisitor<CastCost_old> converter(
     87                                dest, srcIsLvalue, indexer, env,
     88                                (Cost (*)( const Type *, const Type *, bool, const SymTab::Indexer &, const TypeEnvironment & ))
     89                                        castCost );
    8190                        src->accept( converter );
    8291                        if ( converter.pass.get_cost() == Cost::infinity ) {
     
    8998        }
    9099
    91         CastCost::CastCost( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc )
    92                 : ConversionCost( dest, indexer, env, costFunc ) {
    93         }
    94 
    95         void CastCost::postvisit( BasicType *basicType ) {
    96                 PointerType *destAsPointer = dynamic_cast< PointerType* >( dest );
     100        CastCost_old::CastCost_old( const Type * dest, bool srcIsLvalue,
     101                        const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc )
     102                : ConversionCost( dest, srcIsLvalue, indexer, env, costFunc ) {
     103        }
     104
     105        void CastCost_old::postvisit( const BasicType * basicType ) {
     106                const PointerType * destAsPointer = dynamic_cast< const PointerType * >( dest );
    97107                if ( destAsPointer && basicType->isInteger() ) {
    98                         // necessary for, e.g. unsigned long => void*
     108                        // necessary for, e.g. unsigned long => void *
    99109                        cost = Cost::unsafe;
    100110                } else {
    101                         cost = conversionCost( basicType, dest, indexer, env );
     111                        cost = conversionCost( basicType, dest, srcIsLvalue, indexer, env );
    102112                } // if
    103113        }
    104114
    105         void CastCost::postvisit( PointerType *pointerType ) {
    106                 if ( PointerType *destAsPtr = dynamic_cast< PointerType* >( dest ) ) {
    107                         if ( pointerType->get_qualifiers() <= destAsPtr->get_qualifiers() && typesCompatibleIgnoreQualifiers( pointerType->base, destAsPtr->base, indexer, env ) ) {
     115        void CastCost_old::postvisit( const PointerType * pointerType ) {
     116                if ( const PointerType * destAsPtr = dynamic_cast< const PointerType * >( dest ) ) {
     117                        if ( pointerType->tq <= destAsPtr->tq && typesCompatibleIgnoreQualifiers( pointerType->base, destAsPtr->base, indexer, env ) ) {
    108118                                cost = Cost::safe;
    109119                        } else {
     
    118128                                } // if
    119129                        } // if
    120                 } else if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {
     130                } else if ( const BasicType * destAsBasic = dynamic_cast< const BasicType * >( dest ) ) {
    121131                        if ( destAsBasic->isInteger() ) {
    122                                 // necessary for, e.g. void* => unsigned long
     132                                // necessary for, e.g. void * => unsigned long
    123133                                cost = Cost::unsafe;
    124134                        } // if
    125135                }
    126136        }
     137
     138namespace {
     139        struct CastCost_new : public ConversionCost_new {
     140                using ConversionCost_new::previsit;
     141                using ConversionCost_new::postvisit;
     142
     143                CastCost_new(
     144                        const ast::Type * dst, const ast::SymbolTable & symtab,
     145                        const ast::TypeEnvironment & env, CostCalculation costFunc )
     146                : ConversionCost_new( dst, symtab, env, costFunc ) {}
     147
     148                void postvisit( const ast::BasicType * basicType ) {
     149                        auto ptr = dynamic_cast< const ast::PointerType * >( dst );
     150                        if ( ptr && basicType->isInteger() ) {
     151                                // needed for, e.g. unsigned long => void *
     152                                cost = Cost::unsafe;
     153                        } else {
     154                                cost = conversionCost( basicType, dst, symtab, env );
     155                        }
     156                }
     157
     158                void postvisit( const ast::PointerType * pointerType ) {
     159                        if ( auto ptr = dynamic_cast< const ast::PointerType * >( dst ) ) {
     160                                if (
     161                                        pointerType->qualifiers <= ptr->qualifiers
     162                                        && typesCompatibleIgnoreQualifiers( pointerType->base, ptr->base, symtab, env )
     163                                ) {
     164                                        cost = Cost::safe;
     165                                } else {
     166                                        ast::TypeEnvironment newEnv{ env };
     167                                        if ( auto wParams = pointerType->base.as< ast::ParameterizedType >() ) {
     168                                                newEnv.add( wParams->forall );
     169                                        }
     170                                        int castResult = ptrsCastable( pointerType->base, ptr->base, symtab, newEnv );
     171                                        if ( castResult > 0 ) {
     172                                                cost = Cost::safe;
     173                                        } else if ( castResult < 0 ) {
     174                                                cost = Cost::infinity;
     175                                        }
     176                                }
     177                        } else if ( auto basic = dynamic_cast< const ast::BasicType * >( dst ) ) {
     178                                if ( basic->isInteger() ) {
     179                                        // necessary for, e.g. void * => unsigned long
     180                                        cost = Cost::unsafe;
     181                                }
     182                        }
     183                }
     184        };
     185} // anonymous namespace
     186
     187Cost castCost(
     188        const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab,
     189        const ast::TypeEnvironment & env
     190) {
     191        if ( auto typeInst = dynamic_cast< const ast::TypeInstType * >( dst ) ) {
     192                if ( const ast::EqvClass * eqvClass = env.lookup( typeInst->name ) ) {
     193                        // check cast cost against bound type, if present
     194                        if ( eqvClass->bound ) {
     195                                return castCost( src, eqvClass->bound, symtab, env );
     196                        } else {
     197                                return Cost::infinity;
     198                        }
     199                } else if ( const ast::NamedTypeDecl * named = symtab.lookupType( typeInst->name ) ) {
     200                        // all typedefs should be gone by now
     201                        auto type = strict_dynamic_cast< const ast::TypeDecl * >( named );
     202                        if ( type->base ) {
     203                                return castCost( src, type->base, symtab, env ) + Cost::safe;
     204                        }
     205                }
     206        }
     207
     208        PRINT(
     209                std::cerr << "castCost ::: src is ";
     210                ast::print( std::cerr, src );
     211                std::cerr << std::endl << "dest is ";
     212                ast::print( std::cerr, dst );
     213                std::cerr << std::endl << "env is" << std::endl;
     214                ast::print( std::cerr, env, 2 );
     215        )
     216
     217        if ( typesCompatibleIgnoreQualifiers( src, dst, symtab, env ) ) {
     218                PRINT( std::cerr << "compatible!" << std::endl; )
     219                return Cost::zero;
     220        } else if ( dynamic_cast< const ast::VoidType * >( dst ) ) {
     221                return Cost::safe;
     222        } else if ( auto refType = dynamic_cast< const ast::ReferenceType * >( dst ) ) {
     223                PRINT( std::cerr << "conversionCost: dest is reference" << std::endl; )
     224                #warning cast on ptrsCastable artifact of having two functions, remove when port done
     225                return convertToReferenceCost(
     226                        src, refType, symtab, env,
     227                        ( int (*)(
     228                                const ast::Type *, const ast::Type *, const ast::SymbolTable &,
     229                                const ast::TypeEnvironment & )
     230                        ) ptrsCastable );
     231        } else {
     232                #warning cast on castCost artifact of having two functions, remove when port done
     233                ast::Pass< CastCost_new > converter{
     234                        dst, symtab, env,
     235                        ( Cost (*)(
     236                                const ast::Type *, const ast::Type *, const ast::SymbolTable &,
     237                                const ast::TypeEnvironment & )
     238                        ) castCost };
     239                src->accept( converter );
     240                return converter.pass.cost;
     241        }
     242}
     243
    127244} // namespace ResolvExpr
    128245
  • src/ResolvExpr/CommonType.cc

    r7951100 rb067d9b  
    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
     
    1818#include <utility>                       // for pair
    1919
     20#include "AST/Decl.hpp"
     21#include "AST/Type.hpp"
    2022#include "Common/PassVisitor.h"
    2123#include "ResolvExpr/TypeEnvironment.h"  // for OpenVarSet, AssertionSet
     
    2426#include "SynTree/Type.h"                // for BasicType, BasicType::Kind::...
    2527#include "SynTree/Visitor.h"             // for Visitor
    26 #include "Unify.h"                       // for unifyExact, bindVar, WidenMode
     28#include "Unify.h"                       // for unifyExact, WidenMode
    2729#include "typeops.h"                     // for isFtype
    2830
     
    3537
    3638namespace ResolvExpr {
    37         struct CommonType : public WithShortCircuiting {
    38                 CommonType( Type *type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars );
    39                 Type *get_result() const { return result; }
     39        struct CommonType_old : public WithShortCircuiting {
     40                CommonType_old( Type * type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars );
     41                Type * get_result() const { return result; }
    4042
    4143                void previsit( BaseSyntaxNode * ) { visit_children = false; }
     
    5860
    5961          private:
    60                 template< typename Pointer > void getCommonWithVoidPointer( Pointer* voidPointer, Pointer* otherPointer );
    61                 template< typename RefType > void handleRefType( RefType *inst, Type *other );
    62 
    63                 Type *result;
    64                 Type *type2;                            // inherited
     62                template< typename Pointer > void getCommonWithVoidPointer( Pointer * voidPointer, Pointer * otherPointer );
     63                template< typename RefType > void handleRefType( RefType * inst, Type * other );
     64
     65                Type * result;
     66                Type * type2;                           // inherited
    6567                bool widenFirst, widenSecond;
    6668                const SymTab::Indexer &indexer;
     
    7880                                std::cerr << "unify success: " << widenFirst << " " << widenSecond << std::endl;
    7981                        )
    80                         if ( (widenFirst || t2->get_qualifiers() <= t1->get_qualifiers()) && (widenSecond || t1->get_qualifiers() <= t2->get_qualifiers()) ) {
     82                        if ( (widenFirst || t2->tq <= t1->tq) && (widenSecond || t1->tq <= t2->tq) ) {
    8183                                PRINT(
    8284                                        std::cerr << "widen okay" << std::endl;
    8385                                )
    84                                 common->get_qualifiers() |= t1->get_qualifiers();
    85                                 common->get_qualifiers() |= t2->get_qualifiers();
     86                                common->tq |= t1->tq;
     87                                common->tq |= t2->tq;
    8688                                return common;
    8789                        }
     
    9395        }
    9496
    95         Type *commonType( Type *type1, Type *type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars ) {
    96                 PassVisitor<CommonType> visitor( type2, widenFirst, widenSecond, indexer, env, openVars );
     97        Type * commonType( Type * type1, Type * type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars ) {
     98                PassVisitor<CommonType_old> visitor( type2, widenFirst, widenSecond, indexer, env, openVars );
    9799
    98100                int depth1 = type1->referenceDepth();
     
    125127                                                std::cerr << "formal is reference; result should be reference" << std::endl;
    126128                                        )
    127                                         result = new ReferenceType( ref1->get_qualifiers(), result );
     129                                        result = new ReferenceType( ref1->tq, result );
    128130                                }
    129131                                PRINT(
     
    136138
    137139                type1->accept( visitor );
    138                 Type *result = visitor.pass.get_result();
     140                Type * result = visitor.pass.get_result();
    139141                if ( ! result ) {
    140142                        // this appears to be handling for opaque type declarations
    141143                        if ( widenSecond ) {
    142                                 if ( TypeInstType *inst = dynamic_cast< TypeInstType* >( type2 ) ) {
    143                                         if ( NamedTypeDecl *nt = indexer.lookupType( inst->get_name() ) ) {
    144                                                 TypeDecl *type = strict_dynamic_cast< TypeDecl* >( nt );
     144                                if ( const TypeInstType * inst = dynamic_cast< const TypeInstType * >( type2 ) ) {
     145                                        if ( const NamedTypeDecl * nt = indexer.lookupType( inst->get_name() ) ) {
     146                                                const TypeDecl * type = strict_dynamic_cast< const TypeDecl * >( nt );
    145147                                                if ( type->get_base() ) {
    146                                                         Type::Qualifiers tq1 = type1->get_qualifiers(), tq2 = type2->get_qualifiers();
     148                                                        Type::Qualifiers tq1 = type1->tq, tq2 = type2->tq;
    147149                                                        AssertionSet have, need;
    148150                                                        OpenVarSet newOpen( openVars );
    149                                                         type1->get_qualifiers() = Type::Qualifiers();
    150                                                         type->get_base()->get_qualifiers() = tq1;
     151                                                        type1->tq = Type::Qualifiers();
     152                                                        type->get_base()->tq = tq1;
    151153                                                        if ( unifyExact( type1, type->get_base(), env, have, need, newOpen, indexer ) ) {
    152154                                                                result = type1->clone();
    153                                                                 result->get_qualifiers() = tq1 | tq2;
     155                                                                result->tq = tq1 | tq2;
    154156                                                        } // if
    155                                                         type1->get_qualifiers() = tq1;
    156                                                         type->get_base()->get_qualifiers() = Type::Qualifiers();
     157                                                        type1->tq = tq1;
     158                                                        type->get_base()->tq = Type::Qualifiers();
    157159                                                } // if
    158160                                        } // if
     
    176178        }
    177179
    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         };
     180        // GENERATED START, DO NOT EDIT
     181        // GENERATED BY BasicTypes-gen.cc
     182        #define BT BasicType::
     183        static const BasicType::Kind commonTypes[BasicType::NUMBER_OF_BASIC_TYPES][BasicType::NUMBER_OF_BASIC_TYPES] = { // nearest common ancestor
     184                /*                                      B                       C                      SC                      UC                      SI                     SUI
     185                                                        I                      UI                      LI                     LUI                     LLI                    LLUI
     186                                                       IB                     UIB                     _FH                     _FH                      _F                     _FC
     187                                                        F                      FC                     _FX                    _FXC                      FD                    _FDC
     188                                                        D                      DC                    F80X                   _FDXC                     F80                     _FB
     189                                                    _FLDC                      FB                      LD                     LDC                    _FBX                  _FLDXC
     190                                 */
     191                                  {
     192                /*      B */                BT Bool,                BT Char,          BT SignedChar,        BT UnsignedChar,      BT ShortSignedInt,    BT ShortUnsignedInt,
     193                                             BT SignedInt,         BT UnsignedInt,       BT LongSignedInt,     BT LongUnsignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
     194                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     195                                                 BT Float,        BT FloatComplex,           BT uFloat32x,    BT uFloat32xComplex,            BT uFloat64,     BT uFloat64Complex,
     196                                                BT Double,       BT DoubleComplex,           BT uFloat64x,    BT uFloat64xComplex,           BT uuFloat80,           BT uFloat128,
     197                                      BT uFloat128Complex,          BT uuFloat128,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
     198                                  },
     199                                  {
     200                /*      C */                BT Char,                BT Char,          BT SignedChar,        BT UnsignedChar,      BT ShortSignedInt,    BT ShortUnsignedInt,
     201                                             BT SignedInt,         BT UnsignedInt,       BT LongSignedInt,     BT LongUnsignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
     202                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     203                                                 BT Float,        BT FloatComplex,           BT uFloat32x,    BT uFloat32xComplex,            BT uFloat64,     BT uFloat64Complex,
     204                                                BT Double,       BT DoubleComplex,           BT uFloat64x,    BT uFloat64xComplex,           BT uuFloat80,           BT uFloat128,
     205                                      BT uFloat128Complex,          BT uuFloat128,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
     206                                  },
     207                                  {
     208                /*     SC */          BT SignedChar,          BT SignedChar,          BT SignedChar,        BT UnsignedChar,      BT ShortSignedInt,    BT ShortUnsignedInt,
     209                                             BT SignedInt,         BT UnsignedInt,       BT LongSignedInt,     BT LongUnsignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
     210                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     211                                                 BT Float,        BT FloatComplex,           BT uFloat32x,    BT uFloat32xComplex,            BT uFloat64,     BT uFloat64Complex,
     212                                                BT Double,       BT DoubleComplex,           BT uFloat64x,    BT uFloat64xComplex,           BT uuFloat80,           BT uFloat128,
     213                                      BT uFloat128Complex,          BT uuFloat128,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
     214                                  },
     215                                  {
     216                /*     UC */        BT UnsignedChar,        BT UnsignedChar,        BT UnsignedChar,        BT UnsignedChar,      BT ShortSignedInt,    BT ShortUnsignedInt,
     217                                             BT SignedInt,         BT UnsignedInt,       BT LongSignedInt,     BT LongUnsignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
     218                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     219                                                 BT Float,        BT FloatComplex,           BT uFloat32x,    BT uFloat32xComplex,            BT uFloat64,     BT uFloat64Complex,
     220                                                BT Double,       BT DoubleComplex,           BT uFloat64x,    BT uFloat64xComplex,           BT uuFloat80,           BT uFloat128,
     221                                      BT uFloat128Complex,          BT uuFloat128,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
     222                                  },
     223                                  {
     224                /*     SI */      BT ShortSignedInt,      BT ShortSignedInt,      BT ShortSignedInt,      BT ShortSignedInt,      BT ShortSignedInt,    BT ShortUnsignedInt,
     225                                             BT SignedInt,         BT UnsignedInt,       BT LongSignedInt,     BT LongUnsignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
     226                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     227                                                 BT Float,        BT FloatComplex,           BT uFloat32x,    BT uFloat32xComplex,            BT uFloat64,     BT uFloat64Complex,
     228                                                BT Double,       BT DoubleComplex,           BT uFloat64x,    BT uFloat64xComplex,           BT uuFloat80,           BT uFloat128,
     229                                      BT uFloat128Complex,          BT uuFloat128,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
     230                                  },
     231                                  {
     232                /*    SUI */    BT ShortUnsignedInt,    BT ShortUnsignedInt,    BT ShortUnsignedInt,    BT ShortUnsignedInt,    BT ShortUnsignedInt,    BT ShortUnsignedInt,
     233                                             BT SignedInt,         BT UnsignedInt,       BT LongSignedInt,     BT LongUnsignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
     234                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     235                                                 BT Float,        BT FloatComplex,           BT uFloat32x,    BT uFloat32xComplex,            BT uFloat64,     BT uFloat64Complex,
     236                                                BT Double,       BT DoubleComplex,           BT uFloat64x,    BT uFloat64xComplex,           BT uuFloat80,           BT uFloat128,
     237                                      BT uFloat128Complex,          BT uuFloat128,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
     238                                  },
     239                                  {
     240                /*      I */           BT SignedInt,           BT SignedInt,           BT SignedInt,           BT SignedInt,           BT SignedInt,           BT SignedInt,
     241                                             BT SignedInt,         BT UnsignedInt,       BT LongSignedInt,     BT LongUnsignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
     242                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     243                                                 BT Float,        BT FloatComplex,           BT uFloat32x,    BT uFloat32xComplex,            BT uFloat64,     BT uFloat64Complex,
     244                                                BT Double,       BT DoubleComplex,           BT uFloat64x,    BT uFloat64xComplex,           BT uuFloat80,           BT uFloat128,
     245                                      BT uFloat128Complex,          BT uuFloat128,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
     246                                  },
     247                                  {
     248                /*     UI */         BT UnsignedInt,         BT UnsignedInt,         BT UnsignedInt,         BT UnsignedInt,         BT UnsignedInt,         BT UnsignedInt,
     249                                           BT UnsignedInt,         BT UnsignedInt,       BT LongSignedInt,     BT LongUnsignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
     250                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     251                                                 BT Float,        BT FloatComplex,           BT uFloat32x,    BT uFloat32xComplex,            BT uFloat64,     BT uFloat64Complex,
     252                                                BT Double,       BT DoubleComplex,           BT uFloat64x,    BT uFloat64xComplex,           BT uuFloat80,           BT uFloat128,
     253                                      BT uFloat128Complex,          BT uuFloat128,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
     254                                  },
     255                                  {
     256                /*     LI */       BT LongSignedInt,       BT LongSignedInt,       BT LongSignedInt,       BT LongSignedInt,       BT LongSignedInt,       BT LongSignedInt,
     257                                         BT LongSignedInt,       BT LongSignedInt,       BT LongSignedInt,     BT LongUnsignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
     258                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     259                                                 BT Float,        BT FloatComplex,           BT uFloat32x,    BT uFloat32xComplex,            BT uFloat64,     BT uFloat64Complex,
     260                                                BT Double,       BT DoubleComplex,           BT uFloat64x,    BT uFloat64xComplex,           BT uuFloat80,           BT uFloat128,
     261                                      BT uFloat128Complex,          BT uuFloat128,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
     262                                  },
     263                                  {
     264                /*    LUI */     BT LongUnsignedInt,     BT LongUnsignedInt,     BT LongUnsignedInt,     BT LongUnsignedInt,     BT LongUnsignedInt,     BT LongUnsignedInt,
     265                                       BT LongUnsignedInt,     BT LongUnsignedInt,     BT LongUnsignedInt,     BT LongUnsignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
     266                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     267                                                 BT Float,        BT FloatComplex,           BT uFloat32x,    BT uFloat32xComplex,            BT uFloat64,     BT uFloat64Complex,
     268                                                BT Double,       BT DoubleComplex,           BT uFloat64x,    BT uFloat64xComplex,           BT uuFloat80,           BT uFloat128,
     269                                      BT uFloat128Complex,          BT uuFloat128,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
     270                                  },
     271                                  {
     272                /*    LLI */   BT LongLongSignedInt,   BT LongLongSignedInt,   BT LongLongSignedInt,   BT LongLongSignedInt,   BT LongLongSignedInt,   BT LongLongSignedInt,
     273                                     BT LongLongSignedInt,   BT LongLongSignedInt,   BT LongLongSignedInt,   BT LongLongSignedInt,   BT LongLongSignedInt, BT LongLongUnsignedInt,
     274                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     275                                                 BT Float,        BT FloatComplex,           BT uFloat32x,    BT uFloat32xComplex,            BT uFloat64,     BT uFloat64Complex,
     276                                                BT Double,       BT DoubleComplex,           BT uFloat64x,    BT uFloat64xComplex,           BT uuFloat80,           BT uFloat128,
     277                                      BT uFloat128Complex,          BT uuFloat128,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
     278                                  },
     279                                  {
     280                /*   LLUI */ BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt,
     281                                   BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt,
     282                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     283                                                 BT Float,        BT FloatComplex,           BT uFloat32x,    BT uFloat32xComplex,            BT uFloat64,     BT uFloat64Complex,
     284                                                BT Double,       BT DoubleComplex,           BT uFloat64x,    BT uFloat64xComplex,           BT uuFloat80,           BT uFloat128,
     285                                      BT uFloat128Complex,          BT uuFloat128,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
     286                                  },
     287                                  {
     288                /*     IB */        BT SignedInt128,        BT SignedInt128,        BT SignedInt128,        BT SignedInt128,        BT SignedInt128,        BT SignedInt128,
     289                                          BT SignedInt128,        BT SignedInt128,        BT SignedInt128,        BT SignedInt128,        BT SignedInt128,        BT SignedInt128,
     290                                          BT SignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     291                                                 BT Float,        BT FloatComplex,           BT uFloat32x,    BT uFloat32xComplex,            BT uFloat64,     BT uFloat64Complex,
     292                                                BT Double,       BT DoubleComplex,           BT uFloat64x,    BT uFloat64xComplex,           BT uuFloat80,           BT uFloat128,
     293                                      BT uFloat128Complex,          BT uuFloat128,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
     294                                  },
     295                                  {
     296                /*    UIB */      BT UnsignedInt128,      BT UnsignedInt128,      BT UnsignedInt128,      BT UnsignedInt128,      BT UnsignedInt128,      BT UnsignedInt128,
     297                                        BT UnsignedInt128,      BT UnsignedInt128,      BT UnsignedInt128,      BT UnsignedInt128,      BT UnsignedInt128,      BT UnsignedInt128,
     298                                        BT UnsignedInt128,      BT UnsignedInt128,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     299                                                 BT Float,        BT FloatComplex,           BT uFloat32x,    BT uFloat32xComplex,            BT uFloat64,     BT uFloat64Complex,
     300                                                BT Double,       BT DoubleComplex,           BT uFloat64x,    BT uFloat64xComplex,           BT uuFloat80,           BT uFloat128,
     301                                      BT uFloat128Complex,          BT uuFloat128,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
     302                                  },
     303                                  {
     304                /*    _FH */            BT uFloat16,            BT uFloat16,            BT uFloat16,            BT uFloat16,            BT uFloat16,            BT uFloat16,
     305                                              BT uFloat16,            BT uFloat16,            BT uFloat16,            BT uFloat16,            BT uFloat16,            BT uFloat16,
     306                                              BT uFloat16,            BT uFloat16,            BT uFloat16,     BT uFloat16Complex,            BT uFloat32,     BT uFloat32Complex,
     307                                                 BT Float,        BT FloatComplex,           BT uFloat32x,    BT uFloat32xComplex,            BT uFloat64,     BT uFloat64Complex,
     308                                                BT Double,       BT DoubleComplex,           BT uFloat64x,    BT uFloat64xComplex,           BT uuFloat80,           BT uFloat128,
     309                                      BT uFloat128Complex,          BT uuFloat128,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
     310                                  },
     311                                  {
     312                /*    _FH */     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,
     313                                       BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,
     314                                       BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat16Complex,     BT uFloat32Complex,     BT uFloat32Complex,
     315                                          BT FloatComplex,        BT FloatComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,     BT uFloat64Complex,     BT uFloat64Complex,
     316                                         BT DoubleComplex,       BT DoubleComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat128Complex,
     317                                      BT uFloat128Complex,    BT uFloat128Complex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,
     318                                  },
     319                                  {
     320                /*     _F */            BT uFloat32,            BT uFloat32,            BT uFloat32,            BT uFloat32,            BT uFloat32,            BT uFloat32,
     321                                              BT uFloat32,            BT uFloat32,            BT uFloat32,            BT uFloat32,            BT uFloat32,            BT uFloat32,
     322                                              BT uFloat32,            BT uFloat32,            BT uFloat32,     BT uFloat32Complex,            BT uFloat32,     BT uFloat32Complex,
     323                                                 BT Float,        BT FloatComplex,           BT uFloat32x,    BT uFloat32xComplex,            BT uFloat64,     BT uFloat64Complex,
     324                                                BT Double,       BT DoubleComplex,           BT uFloat64x,    BT uFloat64xComplex,           BT uuFloat80,           BT uFloat128,
     325                                      BT uFloat128Complex,          BT uuFloat128,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
     326                                  },
     327                                  {
     328                /*    _FC */     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,
     329                                       BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,
     330                                       BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,     BT uFloat32Complex,
     331                                          BT FloatComplex,        BT FloatComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,     BT uFloat64Complex,     BT uFloat64Complex,
     332                                         BT DoubleComplex,       BT DoubleComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat128Complex,
     333                                      BT uFloat128Complex,    BT uFloat128Complex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,
     334                                  },
     335                                  {
     336                /*      F */               BT Float,               BT Float,               BT Float,               BT Float,               BT Float,               BT Float,
     337                                                 BT Float,               BT Float,               BT Float,               BT Float,               BT Float,               BT Float,
     338                                                 BT Float,               BT Float,               BT Float,        BT FloatComplex,               BT Float,        BT FloatComplex,
     339                                                 BT Float,        BT FloatComplex,           BT uFloat32x,    BT uFloat32xComplex,            BT uFloat64,     BT uFloat64Complex,
     340                                                BT Double,       BT DoubleComplex,           BT uFloat64x,    BT uFloat64xComplex,           BT uuFloat80,           BT uFloat128,
     341                                      BT uFloat128Complex,          BT uuFloat128,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
     342                                  },
     343                                  {
     344                /*     FC */        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,
     345                                          BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,
     346                                          BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,        BT FloatComplex,
     347                                          BT FloatComplex,        BT FloatComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,     BT uFloat64Complex,     BT uFloat64Complex,
     348                                         BT DoubleComplex,       BT DoubleComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat128Complex,
     349                                      BT uFloat128Complex,    BT uFloat128Complex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,
     350                                  },
     351                                  {
     352                /*    _FX */           BT uFloat32x,           BT uFloat32x,           BT uFloat32x,           BT uFloat32x,           BT uFloat32x,           BT uFloat32x,
     353                                             BT uFloat32x,           BT uFloat32x,           BT uFloat32x,           BT uFloat32x,           BT uFloat32x,           BT uFloat32x,
     354                                             BT uFloat32x,           BT uFloat32x,           BT uFloat32x,    BT uFloat32xComplex,           BT uFloat32x,    BT uFloat32xComplex,
     355                                             BT uFloat32x,    BT uFloat32xComplex,           BT uFloat32x,    BT uFloat32xComplex,            BT uFloat64,     BT uFloat64Complex,
     356                                                BT Double,       BT DoubleComplex,           BT uFloat64x,    BT uFloat64xComplex,           BT uuFloat80,           BT uFloat128,
     357                                      BT uFloat128Complex,          BT uuFloat128,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
     358                                  },
     359                                  {
     360                /*   _FXC */    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,
     361                                      BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,
     362                                      BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,
     363                                      BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,    BT uFloat32xComplex,     BT uFloat64Complex,     BT uFloat64Complex,
     364                                         BT DoubleComplex,       BT DoubleComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat128Complex,
     365                                      BT uFloat128Complex,    BT uFloat128Complex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,
     366                                  },
     367                                  {
     368                /*     FD */            BT uFloat64,            BT uFloat64,            BT uFloat64,            BT uFloat64,            BT uFloat64,            BT uFloat64,
     369                                              BT uFloat64,            BT uFloat64,            BT uFloat64,            BT uFloat64,            BT uFloat64,            BT uFloat64,
     370                                              BT uFloat64,            BT uFloat64,            BT uFloat64,     BT uFloat64Complex,            BT uFloat64,     BT uFloat64Complex,
     371                                              BT uFloat64,     BT uFloat64Complex,            BT uFloat64,     BT uFloat64Complex,            BT uFloat64,     BT uFloat64Complex,
     372                                                BT Double,       BT DoubleComplex,           BT uFloat64x,    BT uFloat64xComplex,           BT uuFloat80,           BT uFloat128,
     373                                      BT uFloat128Complex,          BT uuFloat128,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
     374                                  },
     375                                  {
     376                /*   _FDC */     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 uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,
     379                                       BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,     BT uFloat64Complex,
     380                                         BT DoubleComplex,       BT DoubleComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat128Complex,
     381                                      BT uFloat128Complex,    BT uFloat128Complex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,
     382                                  },
     383                                  {
     384                /*      D */              BT Double,              BT Double,              BT Double,              BT Double,              BT Double,              BT Double,
     385                                                BT Double,              BT Double,              BT Double,              BT Double,              BT Double,              BT Double,
     386                                                BT Double,              BT Double,              BT Double,       BT DoubleComplex,              BT Double,       BT DoubleComplex,
     387                                                BT Double,       BT DoubleComplex,              BT Double,       BT DoubleComplex,              BT Double,       BT DoubleComplex,
     388                                                BT Double,       BT DoubleComplex,           BT uFloat64x,    BT uFloat64xComplex,           BT uuFloat80,           BT uFloat128,
     389                                      BT uFloat128Complex,          BT uuFloat128,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
     390                                  },
     391                                  {
     392                /*     DC */       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 DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,
     395                                         BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,       BT DoubleComplex,
     396                                         BT DoubleComplex,       BT DoubleComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat128Complex,
     397                                      BT uFloat128Complex,    BT uFloat128Complex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,
     398                                  },
     399                                  {
     400                /*   F80X */           BT uFloat64x,           BT uFloat64x,           BT uFloat64x,           BT uFloat64x,           BT uFloat64x,           BT uFloat64x,
     401                                             BT uFloat64x,           BT uFloat64x,           BT uFloat64x,           BT uFloat64x,           BT uFloat64x,           BT uFloat64x,
     402                                             BT uFloat64x,           BT uFloat64x,           BT uFloat64x,    BT uFloat64xComplex,           BT uFloat64x,    BT uFloat64xComplex,
     403                                             BT uFloat64x,    BT uFloat64xComplex,           BT uFloat64x,    BT uFloat64xComplex,           BT uFloat64x,    BT uFloat64xComplex,
     404                                             BT uFloat64x,    BT uFloat64xComplex,           BT uFloat64x,    BT uFloat64xComplex,           BT uuFloat80,           BT uFloat128,
     405                                      BT uFloat128Complex,          BT uuFloat128,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
     406                                  },
     407                                  {
     408                /*  _FDXC */    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 uFloat64xComplex,
     411                                      BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,
     412                                      BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat64xComplex,    BT uFloat128Complex,
     413                                      BT uFloat128Complex,    BT uFloat128Complex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,
     414                                  },
     415                                  {
     416                /*    F80 */           BT uuFloat80,           BT uuFloat80,           BT uuFloat80,           BT uuFloat80,           BT uuFloat80,           BT uuFloat80,
     417                                             BT uuFloat80,           BT uuFloat80,           BT uuFloat80,           BT uuFloat80,           BT uuFloat80,           BT uuFloat80,
     418                                             BT uuFloat80,           BT uuFloat80,           BT uuFloat80,    BT uFloat64xComplex,           BT uuFloat80,    BT uFloat64xComplex,
     419                                             BT uuFloat80,    BT uFloat64xComplex,           BT uuFloat80,    BT uFloat64xComplex,           BT uuFloat80,    BT uFloat64xComplex,
     420                                             BT uuFloat80,    BT uFloat64xComplex,           BT uuFloat80,    BT uFloat64xComplex,           BT uuFloat80,           BT uFloat128,
     421                                      BT uFloat128Complex,          BT uuFloat128,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
     422                                  },
     423                                  {
     424                /*    _FB */           BT uFloat128,           BT uFloat128,           BT uFloat128,           BT uFloat128,           BT uFloat128,           BT uFloat128,
     425                                             BT uFloat128,           BT uFloat128,           BT uFloat128,           BT uFloat128,           BT uFloat128,           BT uFloat128,
     426                                             BT uFloat128,           BT uFloat128,           BT uFloat128,    BT uFloat128Complex,           BT uFloat128,    BT uFloat128Complex,
     427                                             BT uFloat128,    BT uFloat128Complex,           BT uFloat128,    BT uFloat128Complex,           BT uFloat128,    BT uFloat128Complex,
     428                                             BT uFloat128,    BT uFloat128Complex,           BT uFloat128,    BT uFloat128Complex,           BT uFloat128,           BT uFloat128,
     429                                      BT uFloat128Complex,          BT uuFloat128,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
     430                                  },
     431                                  {
     432                /*  _FLDC */    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 uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,
     436                                      BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,    BT uFloat128Complex,
     437                                      BT uFloat128Complex,    BT uFloat128Complex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,
     438                                  },
     439                                  {
     440                /*     FB */          BT uuFloat128,          BT uuFloat128,          BT uuFloat128,          BT uuFloat128,          BT uuFloat128,          BT uuFloat128,
     441                                            BT uuFloat128,          BT uuFloat128,          BT uuFloat128,          BT uuFloat128,          BT uuFloat128,          BT uuFloat128,
     442                                            BT uuFloat128,          BT uuFloat128,          BT uuFloat128,    BT uFloat128Complex,          BT uuFloat128,    BT uFloat128Complex,
     443                                            BT uuFloat128,    BT uFloat128Complex,          BT uuFloat128,    BT uFloat128Complex,          BT uuFloat128,    BT uFloat128Complex,
     444                                            BT uuFloat128,    BT uFloat128Complex,          BT uuFloat128,    BT uFloat128Complex,          BT uuFloat128,          BT uuFloat128,
     445                                      BT uFloat128Complex,          BT uuFloat128,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
     446                                  },
     447                                  {
     448                /*     LD */          BT LongDouble,          BT LongDouble,          BT LongDouble,          BT LongDouble,          BT LongDouble,          BT LongDouble,
     449                                            BT LongDouble,          BT LongDouble,          BT LongDouble,          BT LongDouble,          BT LongDouble,          BT LongDouble,
     450                                            BT LongDouble,          BT LongDouble,          BT LongDouble,   BT LongDoubleComplex,          BT LongDouble,   BT LongDoubleComplex,
     451                                            BT LongDouble,   BT LongDoubleComplex,          BT LongDouble,   BT LongDoubleComplex,          BT LongDouble,   BT LongDoubleComplex,
     452                                            BT LongDouble,   BT LongDoubleComplex,          BT LongDouble,   BT LongDoubleComplex,          BT LongDouble,          BT LongDouble,
     453                                     BT LongDoubleComplex,          BT LongDouble,          BT LongDouble,   BT LongDoubleComplex,          BT uFloat128x,   BT uFloat128xComplex,
     454                                  },
     455                                  {
     456                /*    LDC */   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 LongDoubleComplex,   BT LongDoubleComplex,
     460                                     BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,
     461                                     BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT LongDoubleComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,
     462                                  },
     463                                  {
     464                /*   _FBX */          BT uFloat128x,          BT uFloat128x,          BT uFloat128x,          BT uFloat128x,          BT uFloat128x,          BT uFloat128x,
     465                                            BT uFloat128x,          BT uFloat128x,          BT uFloat128x,          BT uFloat128x,          BT uFloat128x,          BT uFloat128x,
     466                                            BT uFloat128x,          BT uFloat128x,          BT uFloat128x,   BT uFloat128xComplex,          BT uFloat128x,   BT uFloat128xComplex,
     467                                            BT uFloat128x,   BT uFloat128xComplex,          BT uFloat128x,   BT uFloat128xComplex,          BT uFloat128x,   BT uFloat128xComplex,
     468                                            BT uFloat128x,   BT uFloat128xComplex,          BT uFloat128x,   BT uFloat128xComplex,          BT uFloat128x,          BT uFloat128x,
     469                                     BT uFloat128xComplex,          BT uFloat128x,          BT uFloat128x,   BT uFloat128xComplex,          BT uFloat128x,   BT uFloat128xComplex,
     470                                  },
     471                                  {
     472                /* _FLDXC */   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                                     BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,
     477                                     BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,   BT uFloat128xComplex,
     478                                  },
     479        }; // commonTypes
     480        #undef BT
     481        // GENERATED END
    207482        static_assert(
    208                 sizeof(combinedType)/sizeof(combinedType[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES*BasicType::NUMBER_OF_BASIC_TYPES,
     483                sizeof(commonTypes)/sizeof(commonTypes[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES * BasicType::NUMBER_OF_BASIC_TYPES,
    209484                "Each basic type kind should have a corresponding row in the combined type matrix"
    210485        );
    211486
    212         CommonType::CommonType( Type *type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars )
     487        CommonType_old::CommonType_old( Type * type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars )
    213488                : result( 0 ), type2( type2 ), widenFirst( widenFirst ), widenSecond( widenSecond ), indexer( indexer ), env( env ), openVars( openVars ) {
    214489        }
    215490
    216         void CommonType::postvisit( VoidType * ) {}
    217 
    218         void CommonType::postvisit( BasicType *basicType ) {
    219                 if ( BasicType *otherBasic = dynamic_cast< BasicType* >( type2 ) ) {
    220                         BasicType::Kind newType = combinedType[ basicType->get_kind() ][ otherBasic->get_kind() ];
    221                         if ( ( ( newType == basicType->get_kind() && basicType->get_qualifiers() >= otherBasic->get_qualifiers() ) || widenFirst ) && ( ( newType == otherBasic->get_kind() && basicType->get_qualifiers() <= otherBasic->get_qualifiers() ) || widenSecond ) ) {
    222                                 result = new BasicType( basicType->get_qualifiers() | otherBasic->get_qualifiers(), newType );
     491        void CommonType_old::postvisit( VoidType * ) {}
     492
     493        void CommonType_old::postvisit( BasicType * basicType ) {
     494                if ( BasicType * otherBasic = dynamic_cast< BasicType * >( type2 ) ) {
     495                        BasicType::Kind newType = commonTypes[ basicType->get_kind() ][ otherBasic->get_kind() ];
     496                        if ( ( ( newType == basicType->get_kind() && basicType->tq >= otherBasic->tq ) || widenFirst ) && ( ( newType == otherBasic->get_kind() && basicType->tq <= otherBasic->tq ) || widenSecond ) ) {
     497                                result = new BasicType( basicType->tq | otherBasic->tq, newType );
    223498                        } // if
    224                 } else if ( dynamic_cast< EnumInstType * > ( type2 ) || dynamic_cast< ZeroType* >( type2 ) || dynamic_cast< OneType* >( type2 ) ) {
     499                } else if ( dynamic_cast< EnumInstType * > ( type2 ) || dynamic_cast< ZeroType * >( type2 ) || dynamic_cast< OneType * >( type2 ) ) {
    225500                        // use signed int in lieu of the enum/zero/one type
    226                         BasicType::Kind newType = combinedType[ basicType->get_kind() ][ BasicType::SignedInt ];
    227                         if ( ( ( newType == basicType->get_kind() && basicType->get_qualifiers() >= type2->get_qualifiers() ) || widenFirst ) && ( ( newType != basicType->get_kind() && basicType->get_qualifiers() <= type2->get_qualifiers() ) || widenSecond ) ) {
    228                                 result = new BasicType( basicType->get_qualifiers() | type2->get_qualifiers(), newType );
     501                        BasicType::Kind newType = commonTypes[ basicType->get_kind() ][ BasicType::SignedInt ];
     502                        if ( ( ( newType == basicType->get_kind() && basicType->tq >= type2->tq ) || widenFirst ) && ( ( newType != basicType->get_kind() && basicType->tq <= type2->tq ) || widenSecond ) ) {
     503                                result = new BasicType( basicType->tq | type2->tq, newType );
    229504                        } // if
    230505                } // if
     
    232507
    233508        template< typename Pointer >
    234         void CommonType::getCommonWithVoidPointer( Pointer* voidPointer, Pointer* otherPointer ) {
    235                 if ( TypeInstType* var = dynamic_cast< TypeInstType* >( otherPointer->get_base() ) ) {
     509        void CommonType_old::getCommonWithVoidPointer( Pointer * voidPointer, Pointer * otherPointer ) {
     510                if ( TypeInstType * var = dynamic_cast< TypeInstType * >( otherPointer->get_base() ) ) {
    236511                        OpenVarSet::const_iterator entry = openVars.find( var->get_name() );
    237512                        if ( entry != openVars.end() ) {
    238513                                AssertionSet need, have;
    239514                                WidenMode widen( widenFirst, widenSecond );
    240                                 if ( entry != openVars.end() && ! bindVar(var, voidPointer->get_base(), entry->second, env, need, have, openVars, widen, indexer ) ) return;
     515                                if ( entry != openVars.end() && ! env.bindVar(var, voidPointer->get_base(), entry->second, need, have, openVars, widen, indexer ) ) return;
    241516                        }
    242517                }
    243518                result = voidPointer->clone();
    244                 result->get_qualifiers() |= otherPointer->get_qualifiers();
    245         }
    246 
    247         void CommonType::postvisit( PointerType *pointerType ) {
    248                 if ( PointerType *otherPointer = dynamic_cast< PointerType* >( type2 ) ) {
     519                result->tq |= otherPointer->tq;
     520        }
     521
     522        void CommonType_old::postvisit( PointerType * pointerType ) {
     523                if ( PointerType * otherPointer = dynamic_cast< PointerType * >( type2 ) ) {
    249524                        // std::cerr << "commonType: two pointers: " << pointerType << " / " << otherPointer << std::endl;
    250                         if ( widenFirst && dynamic_cast< VoidType* >( otherPointer->get_base() ) && ! isFtype(pointerType->get_base()) ) {
     525                        if ( widenFirst && dynamic_cast< VoidType * >( otherPointer->get_base() ) && ! isFtype(pointerType->get_base()) ) {
    251526                                getCommonWithVoidPointer( otherPointer, pointerType );
    252                         } else if ( widenSecond && dynamic_cast< VoidType* >( pointerType->get_base() ) && ! isFtype(otherPointer->get_base()) ) {
     527                        } else if ( widenSecond && dynamic_cast< VoidType * >( pointerType->get_base() ) && ! isFtype(otherPointer->get_base()) ) {
    253528                                getCommonWithVoidPointer( pointerType, otherPointer );
    254                         } else if ( ( pointerType->get_base()->get_qualifiers() >= otherPointer->get_base()->get_qualifiers() || widenFirst )
    255                                            && ( pointerType->get_base()->get_qualifiers() <= otherPointer->get_base()->get_qualifiers() || widenSecond ) ) {
     529                        } else if ( ( pointerType->get_base()->tq >= otherPointer->get_base()->tq || widenFirst )
     530                                           && ( pointerType->get_base()->tq <= otherPointer->get_base()->tq || widenSecond ) ) {
    256531                                // std::cerr << "middle case" << std::endl;
    257                                 Type::Qualifiers tq1 = pointerType->get_base()->get_qualifiers(), tq2 = otherPointer->get_base()->get_qualifiers();
    258                                 pointerType->get_base()->get_qualifiers() = Type::Qualifiers();
    259                                 otherPointer->get_base()->get_qualifiers() = Type::Qualifiers();
     532                                Type::Qualifiers tq1 = pointerType->get_base()->tq, tq2 = otherPointer->get_base()->tq;
     533                                pointerType->get_base()->tq = Type::Qualifiers();
     534                                otherPointer->get_base()->tq = Type::Qualifiers();
    260535                                AssertionSet have, need;
    261536                                OpenVarSet newOpen( openVars );
     
    267542                                                result = otherPointer->clone();
    268543                                        } // if
    269                                         result->get_qualifiers() = tq1 | tq2;
     544                                        strict_dynamic_cast<PointerType *>(result)->base->tq = tq1 | tq2;
    270545                                } else {
    271546                                        /// std::cerr << "place for ptr-to-type" << std::endl;
    272547                                } // if
    273                                 pointerType->get_base()->get_qualifiers() = tq1;
    274                                 otherPointer->get_base()->get_qualifiers() = tq2;
     548                                pointerType->get_base()->tq = tq1;
     549                                otherPointer->get_base()->tq = tq2;
    275550                        } // if
    276                 } else if ( widenSecond && dynamic_cast< ZeroType* >( type2 ) ) {
     551                } else if ( widenSecond && dynamic_cast< ZeroType * >( type2 ) ) {
    277552                        result = pointerType->clone();
    278                         result->get_qualifiers() |= type2->get_qualifiers();
     553                        result->tq |= type2->tq;
    279554                } // if
    280555        }
    281556
    282         void CommonType::postvisit( ArrayType * ) {}
    283 
    284         void CommonType::postvisit( ReferenceType *refType ) {
    285                 if ( ReferenceType *otherRef = dynamic_cast< ReferenceType* >( type2 ) ) {
     557        void CommonType_old::postvisit( ArrayType * ) {}
     558
     559        void CommonType_old::postvisit( ReferenceType * refType ) {
     560                if ( ReferenceType * otherRef = dynamic_cast< ReferenceType * >( type2 ) ) {
    286561                        // std::cerr << "commonType: both references: " << refType << " / " << otherRef << std::endl;
    287                         // std::cerr << ( refType->get_base()->get_qualifiers() >= otherRef->get_base()->get_qualifiers() || widenFirst ) << (refType->get_base()->get_qualifiers() <= otherRef->get_base()->get_qualifiers() || widenSecond) << std::endl;
    288                         if ( widenFirst && dynamic_cast< VoidType* >( otherRef->get_base() ) && ! isFtype(refType->get_base()) ) {
     562                        // std::cerr << ( refType->get_base()->tq >= otherRef->get_base()->tq || widenFirst ) << (refType->get_base()->tq <= otherRef->get_base()->tq || widenSecond) << std::endl;
     563                        if ( widenFirst && dynamic_cast< VoidType * >( otherRef->get_base() ) && ! isFtype(refType->get_base()) ) {
    289564                                getCommonWithVoidPointer( otherRef, refType );
    290                         } else if ( widenSecond && dynamic_cast< VoidType* >( refType->get_base() ) && ! isFtype(otherRef->get_base()) ) {
     565                        } else if ( widenSecond && dynamic_cast< VoidType * >( refType->get_base() ) && ! isFtype(otherRef->get_base()) ) {
    291566                                getCommonWithVoidPointer( refType, otherRef );
    292                         } else if ( ( refType->get_base()->get_qualifiers() >= otherRef->get_base()->get_qualifiers() || widenFirst )
    293                                            && ( refType->get_base()->get_qualifiers() <= otherRef->get_base()->get_qualifiers() || widenSecond ) ) {
     567                        } else if ( ( refType->get_base()->tq >= otherRef->get_base()->tq || widenFirst )
     568                                           && ( refType->get_base()->tq <= otherRef->get_base()->tq || widenSecond ) ) {
    294569                                // std::cerr << "middle case" << std::endl;
    295                                 Type::Qualifiers tq1 = refType->get_base()->get_qualifiers(), tq2 = otherRef->get_base()->get_qualifiers();
    296                                 refType->get_base()->get_qualifiers() = Type::Qualifiers();
    297                                 otherRef->get_base()->get_qualifiers() = Type::Qualifiers();
     570                                Type::Qualifiers tq1 = refType->get_base()->tq, tq2 = otherRef->get_base()->tq;
     571                                refType->get_base()->tq = Type::Qualifiers();
     572                                otherRef->get_base()->tq = Type::Qualifiers();
    298573                                AssertionSet have, need;
    299574                                OpenVarSet newOpen( openVars );
     
    304579                                                result = otherRef->clone();
    305580                                        } // if
    306                                         result->get_qualifiers() = tq1 | tq2;
     581                                        strict_dynamic_cast<ReferenceType *>(result)->base->tq = tq1 | tq2;
    307582                                } else {
    308583                                        /// std::cerr << "place for ptr-to-type" << std::endl;
    309584                                } // if
    310                                 refType->get_base()->get_qualifiers() = tq1;
    311                                 otherRef->get_base()->get_qualifiers() = tq2;
     585                                refType->get_base()->tq = tq1;
     586                                otherRef->get_base()->tq = tq2;
    312587                        } // if
    313                 } else if ( widenSecond && dynamic_cast< ZeroType* >( type2 ) ) {
     588                } else if ( widenSecond && dynamic_cast< ZeroType * >( type2 ) ) {
    314589                        result = refType->clone();
    315                         result->get_qualifiers() |= type2->get_qualifiers();
     590                        result->tq |= type2->tq;
    316591                } // if
    317592        }
    318593
    319         void CommonType::postvisit( FunctionType * ) {}
    320         void CommonType::postvisit( StructInstType * ) {}
    321         void CommonType::postvisit( UnionInstType * ) {}
    322 
    323         void CommonType::postvisit( EnumInstType *enumInstType ) {
    324                 if ( dynamic_cast< BasicType * >( type2 ) || dynamic_cast< ZeroType* >( type2 ) || dynamic_cast< OneType* >( type2 ) ) {
     594        void CommonType_old::postvisit( FunctionType * ) {}
     595        void CommonType_old::postvisit( StructInstType * ) {}
     596        void CommonType_old::postvisit( UnionInstType * ) {}
     597
     598        void CommonType_old::postvisit( EnumInstType * enumInstType ) {
     599                if ( dynamic_cast< BasicType * >( type2 ) || dynamic_cast< ZeroType * >( type2 ) || dynamic_cast< OneType * >( type2 ) ) {
    325600                        // reuse BasicType, EnumInstType code by swapping type2 with enumInstType
    326601                        result = commonType( type2, enumInstType, widenSecond, widenFirst, indexer, env, openVars );
     
    328603        }
    329604
    330         void CommonType::postvisit( TraitInstType * ) {
    331         }
    332 
    333         void CommonType::postvisit( TypeInstType *inst ) {
     605        void CommonType_old::postvisit( TraitInstType * ) {
     606        }
     607
     608        void CommonType_old::postvisit( TypeInstType * inst ) {
    334609                if ( widenFirst ) {
    335                         NamedTypeDecl *nt = indexer.lookupType( inst->get_name() );
     610                        const NamedTypeDecl * nt = indexer.lookupType( inst->get_name() );
    336611                        if ( nt ) {
    337                                 TypeDecl *type = strict_dynamic_cast< TypeDecl* >( nt );
     612                                const TypeDecl * type = strict_dynamic_cast< const TypeDecl * >( nt );
    338613                                if ( type->get_base() ) {
    339                                         Type::Qualifiers tq1 = inst->get_qualifiers(), tq2 = type2->get_qualifiers();
     614                                        Type::Qualifiers tq1 = inst->tq, tq2 = type2->tq;
    340615                                        AssertionSet have, need;
    341616                                        OpenVarSet newOpen( openVars );
    342                                         type2->get_qualifiers() = Type::Qualifiers();
    343                                         type->get_base()->get_qualifiers() = tq1;
     617                                        type2->tq = Type::Qualifiers();
     618                                        type->get_base()->tq = tq1;
    344619                                        if ( unifyExact( type->get_base(), type2, env, have, need, newOpen, indexer ) ) {
    345620                                                result = type2->clone();
    346                                                 result->get_qualifiers() = tq1 | tq2;
     621                                                result->tq = tq1 | tq2;
    347622                                        } // if
    348                                         type2->get_qualifiers() = tq2;
    349                                         type->get_base()->get_qualifiers() = Type::Qualifiers();
     623                                        type2->tq = tq2;
     624                                        type->get_base()->tq = Type::Qualifiers();
    350625                                } // if
    351626                        } // if
     
    353628        }
    354629
    355         void CommonType::postvisit( TupleType * ) {}
    356         void CommonType::postvisit( VarArgsType * ) {}
    357 
    358         void CommonType::postvisit( ZeroType *zeroType ) {
     630        void CommonType_old::postvisit( TupleType * ) {}
     631        void CommonType_old::postvisit( VarArgsType * ) {}
     632
     633        void CommonType_old::postvisit( ZeroType * zeroType ) {
    359634                if ( widenFirst ) {
    360                         if ( dynamic_cast< BasicType* >( type2 ) || dynamic_cast< PointerType* >( type2 ) || dynamic_cast< EnumInstType* >( type2 ) ) {
    361                                 if ( widenSecond || zeroType->get_qualifiers() <= type2->get_qualifiers() ) {
     635                        if ( dynamic_cast< BasicType * >( type2 ) || dynamic_cast< PointerType * >( type2 ) || dynamic_cast< EnumInstType * >( type2 ) ) {
     636                                if ( widenSecond || zeroType->tq <= type2->tq ) {
    362637                                        result = type2->clone();
    363                                         result->get_qualifiers() |= zeroType->get_qualifiers();
    364                                 }
    365                         } else if ( widenSecond && dynamic_cast< OneType* >( type2 ) ) {
    366                                 result = new BasicType( zeroType->get_qualifiers(), BasicType::SignedInt );
    367                                 result->get_qualifiers() |= type2->get_qualifiers();
    368                         }
    369                 }
    370         }
    371 
    372         void CommonType::postvisit( OneType *oneType ) {
     638                                        result->tq |= zeroType->tq;
     639                                }
     640                        } else if ( widenSecond && dynamic_cast< OneType * >( type2 ) ) {
     641                                result = new BasicType( zeroType->tq, BasicType::SignedInt );
     642                                result->tq |= type2->tq;
     643                        }
     644                }
     645        }
     646
     647        void CommonType_old::postvisit( OneType * oneType ) {
    373648                if ( widenFirst ) {
    374                         if ( dynamic_cast< BasicType* >( type2 ) || dynamic_cast< EnumInstType* >( type2 ) ) {
    375                                 if ( widenSecond || oneType->get_qualifiers() <= type2->get_qualifiers() ) {
     649                        if ( dynamic_cast< BasicType * >( type2 ) || dynamic_cast< EnumInstType * >( type2 ) ) {
     650                                if ( widenSecond || oneType->tq <= type2->tq ) {
    376651                                        result = type2->clone();
    377                                         result->get_qualifiers() |= oneType->get_qualifiers();
    378                                 }
    379                         } else if ( widenSecond && dynamic_cast< ZeroType* >( type2 ) ) {
    380                                 result = new BasicType( oneType->get_qualifiers(), BasicType::SignedInt );
    381                                 result->get_qualifiers() |= type2->get_qualifiers();
    382                         }
    383                 }
    384         }
     652                                        result->tq |= oneType->tq;
     653                                }
     654                        } else if ( widenSecond && dynamic_cast< ZeroType * >( type2 ) ) {
     655                                result = new BasicType( oneType->tq, BasicType::SignedInt );
     656                                result->tq |= type2->tq;
     657                        }
     658                }
     659        }
     660
     661        class CommonType_new final : public ast::WithShortCircuiting {
     662                const ast::Type * type2;
     663                WidenMode widen;
     664                const ast::SymbolTable & symtab;
     665                ast::TypeEnvironment & tenv;
     666                const ast::OpenVarSet & open;
     667        public:
     668                ast::ptr< ast::Type > result;
     669
     670                CommonType_new(
     671                        const ast::Type * t2, WidenMode w, const ast::SymbolTable & st,
     672                        ast::TypeEnvironment & env, const ast::OpenVarSet & o )
     673                : type2( t2 ), widen( w ), symtab( st ), tenv( env ), open( o ), result() {}
     674
     675                void previsit( const ast::Node * ) { visit_children = false; }
     676
     677                void postvisit( const ast::VoidType * ) {}
     678
     679                void postvisit( const ast::BasicType * basic ) {
     680                        if ( auto basic2 = dynamic_cast< const ast::BasicType * >( type2 ) ) {
     681                                #warning remove casts when `commonTypes` moved to new AST
     682                                ast::BasicType::Kind kind = (ast::BasicType::Kind)(int)commonTypes[ (BasicType::Kind)(int)basic->kind ][ (BasicType::Kind)(int)basic2->kind ];
     683                                if (
     684                                        ( ( kind == basic->kind && basic->qualifiers >= basic2->qualifiers )
     685                                                || widen.first )
     686                                        && ( ( kind == basic2->kind && basic->qualifiers <= basic2->qualifiers )
     687                                                || widen.second )
     688                                ) {
     689                                        result = new ast::BasicType{ kind, basic->qualifiers | basic2->qualifiers };
     690                                }
     691                        } else if (
     692                                dynamic_cast< const ast::EnumInstType * >( type2 )
     693                                || dynamic_cast< const ast::ZeroType * >( type2 )
     694                                || dynamic_cast< const ast::OneType * >( type2 )
     695                        ) {
     696                                #warning remove casts when `commonTypes` moved to new AST
     697                                ast::BasicType::Kind kind = (ast::BasicType::Kind)(int)commonTypes[ (BasicType::Kind)(int)basic->kind ][ (BasicType::Kind)(int)ast::BasicType::SignedInt ];
     698                                if (
     699                                        ( ( kind == basic->kind && basic->qualifiers >= type2->qualifiers )
     700                                                || widen.first )
     701                                        && ( ( kind != basic->kind && basic->qualifiers <= type2->qualifiers )
     702                                                || widen.second )
     703                                ) {
     704                                        result = new ast::BasicType{ kind, basic->qualifiers | type2->qualifiers };
     705                                }
     706                        }
     707                }
     708
     709        private:
     710                template< typename Pointer >
     711                void getCommonWithVoidPointer( const Pointer * voidPtr, const Pointer * oPtr ) {
     712                        const ast::Type * base = oPtr->base;
     713                        if ( auto var = dynamic_cast< const ast::TypeInstType * >( base ) ) {
     714                                auto entry = open.find( var->name );
     715                                if ( entry != open.end() ) {
     716                                        ast::AssertionSet need, have;
     717                                        if ( ! tenv.bindVar(
     718                                                var, voidPtr->base, entry->second, need, have, open, widen, symtab )
     719                                        ) return;
     720                                }
     721                        }
     722                        result = voidPtr;
     723                        add_qualifiers( result, oPtr->qualifiers );
     724                }
     725
     726        public:
     727                void postvisit( const ast::PointerType * pointer ) {
     728                        if ( auto pointer2 = dynamic_cast< const ast::PointerType * >( type2 ) ) {
     729                                if (
     730                                        widen.first
     731                                        && pointer2->base.as< ast::VoidType >()
     732                                        && ! ast::isFtype( pointer->base )
     733                                ) {
     734                                        getCommonWithVoidPointer( pointer2, pointer );
     735                                } else if (
     736                                        widen.second
     737                                        && pointer->base.as< ast::VoidType >()
     738                                        && ! ast::isFtype( pointer2->base )
     739                                ) {
     740                                        getCommonWithVoidPointer( pointer, pointer2 );
     741                                } else if (
     742                                        ( pointer->base->qualifiers >= pointer2->base->qualifiers || widen.first )
     743                                        && ( pointer->base->qualifiers <= pointer2->base->qualifiers || widen.second )
     744                                ) {
     745                                        ast::CV::Qualifiers q1 = pointer->base->qualifiers;
     746                                        ast::CV::Qualifiers q2 = pointer2->base->qualifiers;
     747
     748                                        // force t{1,2} to be cloned if their qualifiers must be stripped, so that
     749                                        // pointer{,2}->base are unchanged
     750                                        ast::ptr< ast::Type > t1{ pointer->base }, t2{ pointer2->base };
     751                                        reset_qualifiers( t1 );
     752                                        reset_qualifiers( t2 );
     753
     754                                        ast::AssertionSet have, need;
     755                                        ast::OpenVarSet newOpen{ open };
     756                                        if ( unifyExact( t1, t2, tenv, have, need, newOpen, noWiden(), symtab ) ) {
     757                                                result = pointer;
     758                                                if ( q1.val != q2.val ) {
     759                                                        // reset result->base->qualifiers to be union of two base qualifiers
     760                                                        strict_dynamic_cast< ast::PointerType * >(
     761                                                                result.get_and_mutate()
     762                                                        )->base.get_and_mutate()->qualifiers = q1 | q2;
     763                                                }
     764                                        }
     765                                }
     766                        } else if ( widen.second && dynamic_cast< const ast::ZeroType * >( type2 ) ) {
     767                                result = pointer;
     768                                add_qualifiers( result, type2->qualifiers );
     769                        }
     770                }
     771
     772                void postvisit( const ast::ArrayType * ) {}
     773
     774                void postvisit( const ast::ReferenceType * ref ) {
     775                        if ( auto ref2 = dynamic_cast< const ast::ReferenceType * >( type2 ) ) {
     776                                if (
     777                                        widen.first && ref2->base.as< ast::VoidType >() && ! ast::isFtype( ref->base )
     778                                ) {
     779                                        getCommonWithVoidPointer( ref2, ref );
     780                                } else if (
     781                                        widen.second && ref->base.as< ast::VoidType>() && ! ast::isFtype( ref2->base )
     782                                ) {
     783                                        getCommonWithVoidPointer( ref, ref2 );
     784                                } else if (
     785                                        ( ref->base->qualifiers >= ref2->base->qualifiers || widen.first )
     786                                        && ( ref->base->qualifiers <= ref2->base->qualifiers || widen.second )
     787                                ) {
     788                                        ast::CV::Qualifiers q1 = ref->base->qualifiers, q2 = ref2->base->qualifiers;
     789
     790                                        // force t{1,2} to be cloned if their qualifiers must be stripped, so that
     791                                        // ref{,2}->base are unchanged
     792                                        ast::ptr< ast::Type > t1{ ref->base }, t2{ ref2->base };
     793                                        reset_qualifiers( t1 );
     794                                        reset_qualifiers( t2 );
     795
     796                                        ast::AssertionSet have, need;
     797                                        ast::OpenVarSet newOpen{ open };
     798                                        if ( unifyExact( t1, t2, tenv, have, need, newOpen, noWiden(), symtab ) ) {
     799                                                result = ref;
     800                                                if ( q1.val != q2.val ) {
     801                                                        // reset result->base->qualifiers to be union of two base qualifiers
     802                                                        strict_dynamic_cast< ast::ReferenceType * >(
     803                                                                result.get_and_mutate()
     804                                                        )->base.get_and_mutate()->qualifiers = q1 | q2;
     805                                                }
     806                                        }
     807                                }
     808                        } else if ( widen.second && dynamic_cast< const ast::ZeroType * >( type2 ) ) {
     809                                result = ref;
     810                                add_qualifiers( result, type2->qualifiers );
     811                        }
     812                }
     813
     814                void postvisit( const ast::FunctionType * ) {}
     815
     816                void postvisit( const ast::StructInstType * ) {}
     817
     818                void postvisit( const ast::UnionInstType * ) {}
     819
     820                void postvisit( const ast::EnumInstType * enumInst ) {
     821                        if (
     822                                dynamic_cast< const ast::BasicType * >( type2 )
     823                                || dynamic_cast< const ast::ZeroType * >( type2 )
     824                                || dynamic_cast< const ast::OneType * >( type2 )
     825                        ) {
     826                                // reuse BasicType/EnumInstType common type by swapping
     827                                result = commonType( type2, enumInst, widen, symtab, tenv, open );
     828                        }
     829                }
     830
     831                void postvisit( const ast::TraitInstType * ) {}
     832
     833                void postvisit( const ast::TypeInstType * inst ) {
     834                        if ( ! widen.first ) return;
     835                        if ( const ast::NamedTypeDecl * nt = symtab.lookupType( inst->name ) ) {
     836                                if ( const ast::Type * base =
     837                                                strict_dynamic_cast< const ast::TypeDecl * >( nt )->base
     838                                ) {
     839                                        ast::CV::Qualifiers q1 = inst->qualifiers, q2 = type2->qualifiers;
     840
     841                                        // force t{1,2} to be cloned if their qualifiers must be mutated
     842                                        ast::ptr< ast::Type > t1{ base }, t2{ type2 };
     843                                        reset_qualifiers( t1, q1 );
     844                                        reset_qualifiers( t2 );
     845
     846                                        ast::AssertionSet have, need;
     847                                        ast::OpenVarSet newOpen{ open };
     848                                        if ( unifyExact( t1, t2, tenv, have, need, newOpen, noWiden(), symtab ) ) {
     849                                                result = type2;
     850                                                reset_qualifiers( result, q1 | q2 );
     851                                        }
     852                                }
     853                        }
     854                }
     855
     856                void postvisit( const ast::TupleType * ) {}
     857
     858                void postvisit( const ast::VarArgsType * ) {}
     859
     860                void postvisit( const ast::ZeroType * zero ) {
     861                        if ( ! widen.first ) return;
     862                        if (
     863                                dynamic_cast< const ast::BasicType * >( type2 )
     864                                || dynamic_cast< const ast::PointerType * >( type2 )
     865                                || dynamic_cast< const ast::EnumInstType * >( type2 )
     866                        ) {
     867                                if ( widen.second || zero->qualifiers <= type2->qualifiers ) {
     868                                        result = type2;
     869                                        add_qualifiers( result, zero->qualifiers );
     870                                }
     871                        } else if ( widen.second && dynamic_cast< const ast::OneType * >( type2 ) ) {
     872                                result = new ast::BasicType{
     873                                        ast::BasicType::SignedInt, zero->qualifiers | type2->qualifiers };
     874                        }
     875                }
     876
     877                void postvisit( const ast::OneType * one ) {
     878                        if ( ! widen.first ) return;
     879                        if (
     880                                dynamic_cast< const ast::BasicType * >( type2 )
     881                                || dynamic_cast< const ast::EnumInstType * >( type2 )
     882                        ) {
     883                                if ( widen.second || one->qualifiers <= type2->qualifiers ) {
     884                                        result = type2;
     885                                        add_qualifiers( result, one->qualifiers );
     886                                }
     887                        } else if ( widen.second && dynamic_cast< const ast::ZeroType * >( type2 ) ) {
     888                                result = new ast::BasicType{
     889                                        ast::BasicType::SignedInt, one->qualifiers | type2->qualifiers };
     890                        }
     891                }
     892
     893        };
     894
     895        namespace {
     896                ast::ptr< ast::Type > handleReference(
     897                        const ast::ptr< ast::Type > & t1, const ast::ptr< ast::Type > & t2, WidenMode widen,
     898                        const ast::SymbolTable & symtab, ast::TypeEnvironment & env,
     899                        const ast::OpenVarSet & open
     900                ) {
     901                        ast::ptr<ast::Type> common;
     902                        ast::AssertionSet have, need;
     903                        ast::OpenVarSet newOpen{ open };
     904
     905                        // need unify to bind type variables
     906                        if ( unify( t1, t2, env, have, need, newOpen, symtab, common ) ) {
     907                                ast::CV::Qualifiers q1 = t1->qualifiers, q2 = t2->qualifiers;
     908                                PRINT(
     909                                        std::cerr << "unify success: " << widenFirst << " " << widenSecond << std::endl;
     910                                )
     911                                if ( ( widen.first || q2 <= q1 ) && ( widen.second || q1 <= q2 ) ) {
     912                                        PRINT(
     913                                                std::cerr << "widen okay" << std::endl;
     914                                        )
     915                                        add_qualifiers( common, q1 | q2 );
     916                                        return common;
     917                                }
     918                        }
     919
     920                        PRINT(
     921                                std::cerr << "exact unify failed: " << t1 << " " << t2 << std::endl;
     922                        )
     923                        return { nullptr };
     924                }
     925        }
     926
     927        ast::ptr< ast::Type > commonType(
     928                        const ast::ptr< ast::Type > & type1, const ast::ptr< ast::Type > & type2,
     929                        WidenMode widen, const ast::SymbolTable & symtab, ast::TypeEnvironment & env,
     930                        const ast::OpenVarSet & open
     931        ) {
     932                unsigned depth1 = type1->referenceDepth();
     933                unsigned depth2 = type2->referenceDepth();
     934
     935                if ( depth1 != depth2 ) {  // implies depth1 > 0 || depth2 > 0
     936                        PRINT(
     937                                std::cerr << "reference depth diff: " << (depth1-depth2) << std::endl;
     938                        )
     939                        ast::ptr< ast::Type > result;
     940                        const ast::ReferenceType * ref1 = type1.as< ast::ReferenceType >();
     941                        const ast::ReferenceType * ref2 = type1.as< ast::ReferenceType >();
     942
     943                        if ( depth1 > depth2 ) {
     944                                assert( ref1 );
     945                                result = handleReference( ref1->base, type2, widen, symtab, env, open );
     946                        } else {  // implies depth1 < depth2
     947                                assert( ref2 );
     948                                result = handleReference( type1, ref2->base, widen, symtab, env, open );
     949                        }
     950
     951                        if ( result && ref1 ) {
     952                                // formal is reference, so result should be reference
     953                                PRINT(
     954                                        std::cerr << "formal is reference; result should be reference" << std::endl;
     955                                )
     956                                result = new ast::ReferenceType{ result, ref1->qualifiers };
     957                        }
     958
     959                        PRINT(
     960                                std::cerr << "common type of reference [" << type1 << "] and [" << type2 << "] is "
     961                                "[" << result << "]" << std::endl;
     962                        )
     963                        return result;
     964                }
     965                // otherwise both are reference types of the same depth and this is handled by the visitor
     966                ast::Pass<CommonType_new> visitor{ type2, widen, symtab, env, open };
     967                type1->accept( visitor );
     968                ast::ptr< ast::Type > result = visitor.pass.result;
     969
     970                // handling for opaque type declarations (?)
     971                if ( ! result && widen.second ) {
     972                        if ( const ast::TypeInstType * inst = type2.as< ast::TypeInstType >() ) {
     973                                if ( const ast::NamedTypeDecl * nt = symtab.lookupType( inst->name ) ) {
     974                                        auto type = strict_dynamic_cast< const ast::TypeDecl * >( nt );
     975                                        if ( type->base ) {
     976                                                ast::CV::Qualifiers q1 = type1->qualifiers, q2 = type2->qualifiers;
     977                                                ast::AssertionSet have, need;
     978                                                ast::OpenVarSet newOpen{ open };
     979
     980                                                // force t{1,2} to be cloned if its qualifiers must be stripped, so that
     981                                                // type1 and type->base are left unchanged; calling convention forces
     982                                                // {type1,type->base}->strong_ref >= 1
     983                                                ast::ptr<ast::Type> t1{ type1 }, t2{ type->base };
     984                                                reset_qualifiers( t1 );
     985                                                reset_qualifiers( t2, q1 );
     986
     987                                                if ( unifyExact( t1, t2, env, have, need, newOpen, noWiden(), symtab ) ) {
     988                                                        result = t1;
     989                                                        reset_qualifiers( result, q1 | q2 );
     990                                                }
     991                                        }
     992                                }
     993                        }
     994                }
     995
     996                return result;
     997        }
     998
    385999} // namespace ResolvExpr
    3861000
  • src/ResolvExpr/ConversionCost.cc

    r7951100 rb067d9b  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 07:06:19 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Sep 25 15:43:34 2017
    13 // Update Count     : 10
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Mon Aug 12 10:21:00 2019
     13// Update Count     : 27
    1414//
    1515
     
    2828
    2929namespace ResolvExpr {
    30         const Cost Cost::zero =      Cost(  0,  0,  0,  0 );
    31         const Cost Cost::infinity =  Cost( -1, -1, -1, -1 );
    32         const Cost Cost::unsafe =    Cost(  1,  0,  0,  0 );
    33         const Cost Cost::poly =      Cost(  0,  1,  0,  0 );
    34         const Cost Cost::safe =      Cost(  0,  0,  1,  0 );
    35         const Cost Cost::reference = Cost(  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
    3641
    3742#if 0
     
    4045#define PRINT(x)
    4146#endif
    42         Cost conversionCost( Type *src, Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
    43                 if ( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) {
     47
     48        Cost conversionCost( const Type * src, const Type * dest, bool srcIsLvalue,
     49                        const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
     50                if ( const TypeInstType * destAsTypeInst = dynamic_cast< const TypeInstType * >( dest ) ) {
    4451                        PRINT( std::cerr << "type inst " << destAsTypeInst->name; )
    45                         if ( const EqvClass* eqvClass = env.lookup( destAsTypeInst->name ) ) {
     52                        if ( const EqvClass * eqvClass = env.lookup( destAsTypeInst->name ) ) {
    4653                                if ( eqvClass->type ) {
    47                                         return conversionCost( src, eqvClass->type, indexer, env );
     54                                        return conversionCost( src, eqvClass->type, srcIsLvalue, indexer, env );
    4855                                } else {
    4956                                        return Cost::infinity;
    5057                                }
    51                         } else if ( NamedTypeDecl *namedType = indexer.lookupType( destAsTypeInst->name ) ) {
     58                        } else if ( const NamedTypeDecl * namedType = indexer.lookupType( destAsTypeInst->name ) ) {
    5259                                PRINT( std::cerr << " found" << std::endl; )
    53                                 TypeDecl *type = dynamic_cast< TypeDecl* >( namedType );
     60                                const TypeDecl * type = dynamic_cast< const TypeDecl * >( namedType );
    5461                                // all typedefs should be gone by this point
    5562                                assert( type );
    5663                                if ( type->base ) {
    57                                         return conversionCost( src, type->base, indexer, env ) + Cost::safe;
     64                                        return conversionCost( src, type->base, srcIsLvalue, indexer, env )
     65                                                + Cost::safe;
    5866                                } // if
    5967                        } // if
     
    7179                        PRINT( std::cerr << "compatible!" << std::endl; )
    7280                        return Cost::zero;
    73                 } else if ( dynamic_cast< VoidType* >( dest ) ) {
     81                } else if ( dynamic_cast< const VoidType * >( dest ) ) {
    7482                        return Cost::safe;
    75                 } else if ( ReferenceType * refType = dynamic_cast< ReferenceType * > ( dest ) ) {
     83                } else if ( const ReferenceType * refType = dynamic_cast< const ReferenceType * > ( dest ) ) {
    7684                        PRINT( std::cerr << "conversionCost: dest is reference" << std::endl; )
    77                         return convertToReferenceCost( src, refType, indexer, env, [](Type * t1, Type * t2, const SymTab::Indexer &, const TypeEnvironment & env ){
     85                        return convertToReferenceCost( src, refType, srcIsLvalue, indexer, env, [](const Type * const t1, const Type * t2, const SymTab::Indexer &, const TypeEnvironment & env ){
    7886                                return ptrsAssignable( t1, t2, env );
    7987                        });
    8088                } else {
    81                         PassVisitor<ConversionCost> converter( dest, indexer, env, conversionCost );
     89                        PassVisitor<ConversionCost> converter(
     90                                dest, srcIsLvalue, indexer, env,
     91                                (Cost (*)(const Type *, const Type *, bool, const SymTab::Indexer&, const TypeEnvironment&))
     92                                        conversionCost );
    8293                        src->accept( converter );
    8394                        if ( converter.pass.get_cost() == Cost::infinity ) {
     
    89100        }
    90101
    91         Cost convertToReferenceCost( Type * src, Type * dest, int diff, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) {
     102        static Cost convertToReferenceCost( const Type * src, const Type * dest, bool srcIsLvalue,
     103                        int diff, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) {
    92104                PRINT( std::cerr << "convert to reference cost... diff " << diff << " " << src << " / " << dest << std::endl; )
    93105                if ( diff > 0 ) {
    94106                        // TODO: document this
    95                         Cost cost = convertToReferenceCost( strict_dynamic_cast< ReferenceType * >( src )->base, dest, diff-1, indexer, env, func );
     107                        Cost cost = convertToReferenceCost(
     108                                strict_dynamic_cast< const ReferenceType * >( src )->base, dest, srcIsLvalue,
     109                                diff-1, indexer, env, func );
    96110                        cost.incReference();
    97111                        return cost;
    98112                } else if ( diff < -1 ) {
    99113                        // TODO: document this
    100                         Cost cost = convertToReferenceCost( src, strict_dynamic_cast< ReferenceType * >( dest )->base, diff+1, indexer, env, func );
     114                        Cost cost = convertToReferenceCost(
     115                                src, strict_dynamic_cast< const ReferenceType * >( dest )->base, srcIsLvalue,
     116                                diff+1, indexer, env, func );
    101117                        cost.incReference();
    102118                        return cost;
    103119                } else if ( diff == 0 ) {
    104                         ReferenceType * srcAsRef = dynamic_cast< ReferenceType * >( src );
    105                         ReferenceType * destAsRef = dynamic_cast< ReferenceType * >( dest );
     120                        const ReferenceType * srcAsRef = dynamic_cast< const ReferenceType * >( src );
     121                        const ReferenceType * destAsRef = dynamic_cast< const ReferenceType * >( dest );
    106122                        if ( srcAsRef && destAsRef ) { // pointer-like conversions between references
    107123                                PRINT( std::cerr << "converting between references" << std::endl; )
    108                                 Type::Qualifiers tq1 = srcAsRef->base->get_qualifiers();
    109                                 Type::Qualifiers tq2 = destAsRef->base->get_qualifiers();
     124                                Type::Qualifiers tq1 = srcAsRef->base->tq;
     125                                Type::Qualifiers tq2 = destAsRef->base->tq;
    110126                                if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers( srcAsRef->base, destAsRef->base, indexer, env ) ) {
    111127                                        PRINT( std::cerr << " :: compatible and good qualifiers" << std::endl; )
     
    128144                        } else {
    129145                                PRINT( std::cerr << "reference to rvalue conversion" << std::endl; )
    130                                 PassVisitor<ConversionCost> converter( dest, indexer, env, conversionCost );
     146                                PassVisitor<ConversionCost> converter(
     147                                        dest, srcIsLvalue, indexer, env,
     148                                        (Cost (*)(const Type *, const Type *, bool, const SymTab::Indexer&, const TypeEnvironment&))
     149                                                conversionCost );
    131150                                src->accept( converter );
    132151                                return converter.pass.get_cost();
    133152                        } // if
    134153                } else {
    135                         ReferenceType * destAsRef = dynamic_cast< ReferenceType * >( dest );
     154                        const ReferenceType * destAsRef = dynamic_cast< const ReferenceType * >( dest );
    136155                        assert( diff == -1 && destAsRef );
    137156                        PRINT( std::cerr << "dest is: " << dest << " / src is: " << src << std::endl; )
    138157                        if ( typesCompatibleIgnoreQualifiers( src, destAsRef->base, indexer, env ) ) {
    139158                                PRINT( std::cerr << "converting compatible base type" << std::endl; )
    140                                 if ( src->get_lvalue() ) {
     159                                if ( srcIsLvalue ) {
    141160                                        PRINT(
    142161                                                std::cerr << "lvalue to reference conversion" << std::endl;
     
    144163                                        )
    145164                                        // lvalue-to-reference conversion:  cv lvalue T => cv T &
    146                                         if ( src->get_qualifiers() == destAsRef->base->get_qualifiers() ) {
     165                                        if ( src->tq == destAsRef->base->tq ) {
    147166                                                return Cost::reference; // cost needs to be non-zero to add cast
    148                                         } if ( src->get_qualifiers() < destAsRef->base->get_qualifiers() ) {
     167                                        } if ( src->tq < destAsRef->base->tq ) {
    149168                                                return Cost::safe; // cost needs to be higher than previous cast to differentiate adding qualifiers vs. keeping same
    150169                                        } else {
     
    166185        }
    167186
    168         Cost convertToReferenceCost( Type * src, ReferenceType * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) {
     187        Cost convertToReferenceCost( const Type * src, const ReferenceType * dest, bool srcIsLvalue,
     188                        const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func ) {
    169189                int sdepth = src->referenceDepth(), ddepth = dest->referenceDepth();
    170                 Cost cost = convertToReferenceCost( src, dest, sdepth-ddepth, indexer, env, func );
     190                Cost cost = convertToReferenceCost( src, dest, srcIsLvalue, sdepth-ddepth, indexer, env, func );
    171191                PRINT( std::cerr << "convertToReferenceCost result: " << cost << std::endl; )
    172192                return cost;
    173193        }
    174194
    175         ConversionCost::ConversionCost( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc )
    176                 : dest( dest ), indexer( indexer ), cost( Cost::infinity ), env( env ), costFunc( costFunc ) {
    177         }
    178 
    179 /*
    180             Old
    181             ===
    182            Double
    183              |
    184            Float
    185              |
    186            ULong
    187            /   \
    188         UInt    Long
    189            \   /
    190             Int
    191              |
    192            Ushort
    193              |
    194            Short
    195              |
    196            Uchar
    197            /   \
    198         Schar   Char
    199 
    200                                 New
    201                                 ===
    202                        +-----LongDoubleComplex--+
    203            LongDouble--+          |             +-LongDoubleImag
    204              |         +---DoubleComplex---+         |
    205            Double------+        |          +----DoubleImag
    206              |           +-FloatComplex-+            |
    207            Float---------+              +-------FloatImag
    208              |
    209           ULongLong
    210              |
    211           LongLong
    212              |
    213            ULong
    214            /   \
    215         UInt    Long
    216            \   /
    217             Int
    218              |
    219            Ushort
    220              |
    221            Short
    222              |
    223            Uchar
    224            /   \
    225         Schar   Char
    226            \   /
    227             Bool
    228 */
    229 
    230         static const int costMatrix[][ BasicType::NUMBER_OF_BASIC_TYPES ] = {
    231         /* 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 */
    232                 /* 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},
    233                 /* 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},
    234                 /* 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},
    235                 /* 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},
    236                 /* 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},
    237                 /* 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},
    238                 /* 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},
    239                 /* 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},
    240                 /* 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},
    241                 /* 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},
    242                 /* 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},
    243                 /* 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},
    244 
    245                 /* 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},
    246                 /* 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},
    247                 /* 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},
    248                 /* 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},
    249                 /* 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},
    250                 /* 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},
    251                 /* 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},
    252                 /* 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},
    253                 /* 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},
    254 
    255                 /* 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},
    256                 /* 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},
    257 
    258                 /* 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},
    259                 /* 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},
    260         };
     195        ConversionCost::ConversionCost( const Type * dest, bool srcIsLvalue, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc )
     196                : dest( dest ), srcIsLvalue( srcIsLvalue ), indexer( indexer ), cost( Cost::infinity ), env( env ), costFunc( costFunc ) {
     197        }
     198
     199        // GENERATED START, DO NOT EDIT
     200        // GENERATED BY BasicTypes-gen.cc
     201        /* EXTENDED INTEGRAL RANK HIERARCHY (root to leaves)
     202                                 _Bool
     203        char                signed char         unsigned char
     204                  signed short int         unsigned short int
     205                  signed int               unsigned int
     206                  signed long int          unsigned long int
     207                  signed long long int     unsigned long long int
     208                  __int128                 unsigned __int128
     209                  _Float16                 _Float16 _Complex
     210                  _Float32                 _Float32 _Complex
     211                  float                    float _Complex
     212                  _Float32x                _Float32x _Complex
     213                  _Float64                 _Float64 _Complex
     214                  double                   double _Complex
     215                  _Float64x                _Float64x _Complex
     216                             __float80
     217                  _Float128                _Float128 _Complex
     218                            __float128
     219                  long double              long double _Complex
     220                  _Float128x               _Float128x _Complex
     221        */
     222        // GENERATED END
     223
     224        // GENERATED START, DO NOT EDIT
     225        // GENERATED BY BasicTypes-gen.cc
     226        static const int costMatrix[BasicType::NUMBER_OF_BASIC_TYPES][BasicType::NUMBER_OF_BASIC_TYPES] = { // path length from root to node
     227                /*               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 */
     228                /*      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, },
     229                /*      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, },
     230                /*     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, },
     231                /*     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, },
     232                /*     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, },
     233                /*    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, },
     234                /*      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, },
     235                /*     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, },
     236                /*     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, },
     237                /*    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, },
     238                /*    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, },
     239                /*   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, },
     240                /*     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, },
     241                /*    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, },
     242                /*    _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, },
     243                /*    _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, },
     244                /*     _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, },
     245                /*    _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, },
     246                /*      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, },
     247                /*     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, },
     248                /*    _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, },
     249                /*   _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, },
     250                /*     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, },
     251                /*   _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, },
     252                /*      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, },
     253                /*     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, },
     254                /*   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, },
     255                /*  _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, },
     256                /*    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, },
     257                /*    _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, },
     258                /*  _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, },
     259                /*     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, },
     260                /*     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, },
     261                /*    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, },
     262                /*   _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, },
     263                /* _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, },
     264        }; // costMatrix
     265        static const int maxIntCost = 15;
     266        // GENERATED END
    261267        static_assert(
    262                 sizeof(costMatrix)/sizeof(costMatrix[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES*BasicType::NUMBER_OF_BASIC_TYPES,
    263                 "Each basic type kind should have a corresponding row in the cost matrix"
     268                sizeof(costMatrix)/sizeof(costMatrix[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES * BasicType::NUMBER_OF_BASIC_TYPES,
     269                "Missing row in the cost matrix"
    264270        );
    265271
    266 
    267         void ConversionCost::postvisit( VoidType * ) {
     272        // GENERATED START, DO NOT EDIT
     273        // GENERATED BY BasicTypes-gen.cc
     274        static const int signMatrix[BasicType::NUMBER_OF_BASIC_TYPES][BasicType::NUMBER_OF_BASIC_TYPES] = { // number of sign changes in safe conversion
     275                /*               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 */
     276                /*      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, },
     277                /*      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, },
     278                /*     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, },
     279                /*     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, },
     280                /*     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, },
     281                /*    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, },
     282                /*      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, },
     283                /*     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, },
     284                /*     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, },
     285                /*    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, },
     286                /*    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, },
     287                /*   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, },
     288                /*     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, },
     289                /*    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, },
     290                /*    _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, },
     291                /*    _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, },
     292                /*     _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, },
     293                /*    _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, },
     294                /*      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, },
     295                /*     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, },
     296                /*    _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, },
     297                /*   _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, },
     298                /*     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, },
     299                /*   _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, },
     300                /*      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, },
     301                /*     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, },
     302                /*   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, },
     303                /*  _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, },
     304                /*    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, },
     305                /*    _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, },
     306                /*  _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, },
     307                /*     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, },
     308                /*     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, },
     309                /*    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, },
     310                /*   _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, },
     311                /* _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, },
     312        }; // signMatrix
     313        // GENERATED END
     314        static_assert(
     315                sizeof(signMatrix)/sizeof(signMatrix[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES * BasicType::NUMBER_OF_BASIC_TYPES,
     316                "Missing row in the sign matrix"
     317        );
     318
     319        void ConversionCost::postvisit( const VoidType * ) {
    268320                cost = Cost::infinity;
    269321        }
    270322
    271         void ConversionCost::postvisit(BasicType *basicType) {
    272                 if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {
    273                         int tableResult = costMatrix[ basicType->get_kind() ][ destAsBasic->get_kind() ];
     323        void ConversionCost::postvisit(const BasicType * basicType) {
     324                if ( const BasicType * destAsBasic = dynamic_cast< const BasicType * >( dest ) ) {
     325                        int tableResult = costMatrix[ basicType->kind ][ destAsBasic->kind ];
    274326                        if ( tableResult == -1 ) {
    275327                                cost = Cost::unsafe;
     
    277329                                cost = Cost::zero;
    278330                                cost.incSafe( tableResult );
    279                         } // if
    280                 } else if ( dynamic_cast< EnumInstType *>( dest ) ) {
     331                                cost.incSign( signMatrix[ basicType->kind ][ destAsBasic->kind ] );
     332                        } // if
     333                } else if ( dynamic_cast< const EnumInstType * >( dest ) ) {
    281334                        // xxx - not positive this is correct, but appears to allow casting int => enum
    282335                        cost = Cost::unsafe;
     
    285338        }
    286339
    287         void ConversionCost::postvisit( PointerType * pointerType ) {
    288                 if ( PointerType *destAsPtr = dynamic_cast< PointerType* >( dest ) ) {
     340        void ConversionCost::postvisit( const PointerType * pointerType ) {
     341                if ( const PointerType * destAsPtr = dynamic_cast< const PointerType * >( dest ) ) {
    289342                        PRINT( std::cerr << pointerType << " ===> " << destAsPtr << std::endl; )
    290                         Type::Qualifiers tq1 = pointerType->base->get_qualifiers();
    291                         Type::Qualifiers tq2 = destAsPtr->base->get_qualifiers();
     343                        Type::Qualifiers tq1 = pointerType->base->tq;
     344                        Type::Qualifiers tq2 = destAsPtr->base->tq;
    292345                        if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers( pointerType->base, destAsPtr->base, indexer, env ) ) {
    293346                                PRINT( std::cerr << " :: compatible and good qualifiers" << std::endl; )
     
    298351                                        // types are the same, except otherPointer has more qualifiers
    299352                                        cost = Cost::safe;
    300                                 }
     353                                } // if
    301354                        } else {
    302355                                int assignResult = ptrsAssignable( pointerType->base, destAsPtr->base, env );
     
    318371        }
    319372
    320         void ConversionCost::postvisit( ArrayType * ) {}
    321 
    322         void ConversionCost::postvisit( ReferenceType * refType ) {
     373        void ConversionCost::postvisit( const ArrayType * ) {}
     374
     375        void ConversionCost::postvisit( const ReferenceType * refType ) {
    323376                // Note: dest can never be a reference, since it would have been caught in an earlier check
    324                 assert( ! dynamic_cast< ReferenceType * >( dest ) );
     377                assert( ! dynamic_cast< const ReferenceType * >( dest ) );
    325378                // convert reference to rvalue: cv T1 & => T2
    326379                // recursively compute conversion cost from T1 to T2.
    327380                // cv can be safely dropped because of 'implicit dereference' behavior.
    328                 cost = costFunc( refType->base, dest, indexer, env );
    329                 if ( refType->base->get_qualifiers() == dest->get_qualifiers() ) {
     381                cost = costFunc( refType->base, dest, srcIsLvalue, indexer, env );
     382                if ( refType->base->tq == dest->tq ) {
    330383                        cost.incReference();  // prefer exact qualifiers
    331                 } else if ( refType->base->get_qualifiers() < dest->get_qualifiers() ) {
     384                } else if ( refType->base->tq < dest->tq ) {
    332385                        cost.incSafe(); // then gaining qualifiers
    333386                } else {
     
    337390        }
    338391
    339         void ConversionCost::postvisit( FunctionType * ) {}
    340 
    341         void ConversionCost::postvisit( StructInstType * inst ) {
    342                 if ( StructInstType *destAsInst = dynamic_cast< StructInstType* >( dest ) ) {
     392        void ConversionCost::postvisit( const FunctionType * ) {}
     393
     394        void ConversionCost::postvisit( const StructInstType * inst ) {
     395                if ( const StructInstType * destAsInst = dynamic_cast< const StructInstType * >( dest ) ) {
    343396                        if ( inst->name == destAsInst->name ) {
    344397                                cost = Cost::zero;
     
    347400        }
    348401
    349         void ConversionCost::postvisit( UnionInstType * inst ) {
    350                 if ( UnionInstType *destAsInst = dynamic_cast< UnionInstType* >( dest ) ) {
     402        void ConversionCost::postvisit( const UnionInstType * inst ) {
     403                if ( const UnionInstType * destAsInst = dynamic_cast< const UnionInstType * >( dest ) ) {
    351404                        if ( inst->name == destAsInst->name ) {
    352405                                cost = Cost::zero;
     
    355408        }
    356409
    357         void ConversionCost::postvisit( EnumInstType * ) {
     410        void ConversionCost::postvisit( const EnumInstType * ) {
    358411                static Type::Qualifiers q;
    359412                static BasicType integer( q, BasicType::SignedInt );
    360                 cost = costFunc( &integer, dest, indexer, env );  // safe if dest >= int
     413                cost = costFunc( &integer, dest, srcIsLvalue, indexer, env );  // safe if dest >= int
    361414                if ( cost < Cost::unsafe ) {
    362415                        cost.incSafe();
     
    364417        }
    365418
    366         void ConversionCost::postvisit( TraitInstType * ) {}
    367 
    368         void ConversionCost::postvisit( TypeInstType *inst ) {
    369                 if ( const EqvClass *eqvClass = env.lookup( inst->name ) ) {
    370                         cost = costFunc( eqvClass->type, dest, indexer, env );
    371                 } else if ( TypeInstType *destAsInst = dynamic_cast< TypeInstType* >( dest ) ) {
     419        void ConversionCost::postvisit( const TraitInstType * ) {}
     420
     421        void ConversionCost::postvisit( const TypeInstType * inst ) {
     422                if ( const EqvClass * eqvClass = env.lookup( inst->name ) ) {
     423                        cost = costFunc( eqvClass->type, dest, srcIsLvalue, indexer, env );
     424                } else if ( const TypeInstType * destAsInst = dynamic_cast< const TypeInstType * >( dest ) ) {
    372425                        if ( inst->name == destAsInst->name ) {
    373426                                cost = Cost::zero;
    374427                        }
    375                 } else if ( NamedTypeDecl *namedType = indexer.lookupType( inst->name ) ) {
    376                         TypeDecl *type = dynamic_cast< TypeDecl* >( namedType );
     428                } else if ( const NamedTypeDecl * namedType = indexer.lookupType( inst->name ) ) {
     429                        const TypeDecl * type = dynamic_cast< const TypeDecl * >( namedType );
    377430                        // all typedefs should be gone by this point
    378431                        assert( type );
    379432                        if ( type->base ) {
    380                                 cost = costFunc( type->base, dest, indexer, env ) + Cost::safe;
    381                         } // if
    382                 } // if
    383         }
    384 
    385         void ConversionCost::postvisit( TupleType * tupleType ) {
     433                                cost = costFunc( type->base, dest, srcIsLvalue, indexer, env ) + Cost::safe;
     434                        } // if
     435                } // if
     436        }
     437
     438        void ConversionCost::postvisit( const TupleType * tupleType ) {
    386439                Cost c = Cost::zero;
    387                 if ( TupleType * destAsTuple = dynamic_cast< TupleType * >( dest ) ) {
     440                if ( const TupleType * destAsTuple = dynamic_cast< const TupleType * >( dest ) ) {
    388441                        std::list< Type * >::const_iterator srcIt = tupleType->types.begin();
    389442                        std::list< Type * >::const_iterator destIt = destAsTuple->types.begin();
    390443                        while ( srcIt != tupleType->types.end() && destIt != destAsTuple->types.end() ) {
    391                                 Cost newCost = costFunc( *srcIt++, *destIt++, indexer, env );
     444                                Cost newCost = costFunc( * srcIt++, * destIt++, srcIsLvalue, indexer, env );
    392445                                if ( newCost == Cost::infinity ) {
    393446                                        return;
     
    403456        }
    404457
    405         void ConversionCost::postvisit( VarArgsType * ) {
    406                 if ( dynamic_cast< VarArgsType* >( dest ) ) {
    407                         cost = Cost::zero;
    408                 }
    409         }
    410 
    411         void ConversionCost::postvisit( ZeroType * ) {
    412                 if ( dynamic_cast< ZeroType * >( dest ) ) {
    413                         cost = Cost::zero;
    414                 } else if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {
    415                         // copied from visit(BasicType*) for signed int, but +1 for safe conversions
    416                         int tableResult = costMatrix[ BasicType::SignedInt ][ destAsBasic->get_kind() ];
     458        void ConversionCost::postvisit( const VarArgsType * ) {
     459                if ( dynamic_cast< const VarArgsType * >( dest ) ) {
     460                        cost = Cost::zero;
     461                }
     462        }
     463
     464        void ConversionCost::postvisit( const ZeroType * ) {
     465                if ( dynamic_cast< const ZeroType * >( dest ) ) {
     466                        cost = Cost::zero;
     467                } else if ( const BasicType * destAsBasic = dynamic_cast< const BasicType * >( dest ) ) {
     468                        // copied from visit(BasicType *) for signed int, but +1 for safe conversions
     469                        int tableResult = costMatrix[ BasicType::SignedInt ][ destAsBasic->kind ];
    417470                        if ( tableResult == -1 ) {
    418471                                cost = Cost::unsafe;
     
    420473                                cost = Cost::zero;
    421474                                cost.incSafe( tableResult + 1 );
    422                         }
    423                 } else if ( dynamic_cast< PointerType* >( dest ) ) {
    424                         cost = Cost::safe;
    425                 }
    426         }
    427 
    428         void ConversionCost::postvisit( OneType * ) {
    429                 if ( dynamic_cast< OneType * >( dest ) ) {
    430                         cost = Cost::zero;
    431                 } else if ( BasicType *destAsBasic = dynamic_cast< BasicType* >( dest ) ) {
    432                         // copied from visit(BasicType*) for signed int, but +1 for safe conversions
    433                         int tableResult = costMatrix[ BasicType::SignedInt ][ destAsBasic->get_kind() ];
     475                                cost.incSign( signMatrix[ BasicType::SignedInt ][ destAsBasic->kind ] );
     476                        } // if
     477                } else if ( dynamic_cast< const PointerType * >( dest ) ) {
     478                        cost = Cost::zero;
     479                        cost.incSafe( maxIntCost + 2 ); // +1 for zero_t -> int, +1 for disambiguation
     480                } // if
     481        }
     482
     483        void ConversionCost::postvisit( const OneType * ) {
     484                if ( dynamic_cast< const OneType * >( dest ) ) {
     485                        cost = Cost::zero;
     486                } else if ( const BasicType * destAsBasic = dynamic_cast< const BasicType * >( dest ) ) {
     487                        // copied from visit(BasicType *) for signed int, but +1 for safe conversions
     488                        int tableResult = costMatrix[ BasicType::SignedInt ][ destAsBasic->kind ];
    434489                        if ( tableResult == -1 ) {
    435490                                cost = Cost::unsafe;
     
    437492                                cost = Cost::zero;
    438493                                cost.incSafe( tableResult + 1 );
     494                                cost.incSign( signMatrix[ BasicType::SignedInt ][ destAsBasic->kind ] );
     495                        } // if
     496                } // if
     497        }
     498
     499static int localPtrsAssignable(const ast::Type * t1, const ast::Type * t2,
     500                const ast::SymbolTable &, const ast::TypeEnvironment & env ) {
     501        return ptrsAssignable( t1, t2, env );
     502}
     503
     504// TODO: This is used for overload resolution. It might be able to be dropped once the old system
     505// is removed.
     506static Cost localConversionCost(
     507        const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab,
     508        const ast::TypeEnvironment & env
     509) { return conversionCost( src, dst, symtab, env ); }
     510
     511Cost conversionCost(
     512        const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab,
     513        const ast::TypeEnvironment & env
     514) {
     515        if ( const ast::TypeInstType * inst = dynamic_cast< const ast::TypeInstType * >( dst ) ) {
     516                if ( const ast::EqvClass * eqv = env.lookup( inst->name ) ) {
     517                        if ( eqv->bound ) {
     518                                return conversionCost(src, eqv->bound, symtab, env );
     519                        } else {
     520                                return Cost::infinity;
    439521                        }
    440                 }
    441         }
     522                } else if ( const ast::NamedTypeDecl * named = symtab.lookupType( inst->name ) ) {
     523                        const ast::TypeDecl * type = dynamic_cast< const ast::TypeDecl * >( named );
     524                        assertf( type, "Unexpected typedef." );
     525                        if ( type->base ) {
     526                                return conversionCost( src, type->base, symtab, env ) + Cost::safe;
     527                        }
     528                }
     529        }
     530        if ( typesCompatibleIgnoreQualifiers( src, dst, symtab, env ) ) {
     531                return Cost::zero;
     532        } else if ( dynamic_cast< const ast::VoidType * >( dst ) ) {
     533                return Cost::safe;
     534        } else if ( const ast::ReferenceType * refType =
     535                         dynamic_cast< const ast::ReferenceType * >( dst ) ) {
     536                return convertToReferenceCost( src, refType, symtab, env, localPtrsAssignable );
     537        } else {
     538                ast::Pass<ConversionCost_new> converter( dst, symtab, env, localConversionCost );
     539                src->accept( converter );
     540                return converter.pass.cost;
     541        }
     542}
     543
     544static Cost convertToReferenceCost( const ast::Type * src, const ast::Type * dst,
     545                int diff, const ast::SymbolTable & symtab, const ast::TypeEnvironment & env,
     546                NumCostCalculation func ) {
     547        if ( 0 < diff ) {
     548                Cost cost = convertToReferenceCost(
     549                        strict_dynamic_cast< const ast::ReferenceType * >( src )->base,
     550                        dst, (diff - 1), symtab, env, func );
     551                cost.incReference();
     552                return cost;
     553        } else if ( diff < -1 ) {
     554                Cost cost = convertToReferenceCost(
     555                        src, strict_dynamic_cast< const ast::ReferenceType * >( dst )->base,
     556                        (diff + 1), symtab, env, func );
     557                cost.incReference();
     558                return cost;
     559        } else if ( 0 == diff ) {
     560                const ast::ReferenceType * srcAsRef = dynamic_cast< const ast::ReferenceType * >( src );
     561                const ast::ReferenceType * dstAsRef = dynamic_cast< const ast::ReferenceType * >( dst );
     562                if ( srcAsRef && dstAsRef ) {
     563                        ast::CV::Qualifiers tq1 = srcAsRef->base->qualifiers;
     564                        ast::CV::Qualifiers tq2 = dstAsRef->base->qualifiers;
     565                        if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers(
     566                                        srcAsRef->base, dstAsRef->base, symtab, env ) ) {
     567                                if ( tq1 == tq2 ) {
     568                                        return Cost::zero;
     569                                } else {
     570                                        return Cost::safe;
     571                                }
     572                        } else {
     573                                int assignResult = func( srcAsRef->base, dstAsRef->base, symtab, env );
     574                                if ( 0 < assignResult ) {
     575                                        return Cost::safe;
     576                                } else if ( assignResult < 0 ) {
     577                                        return Cost::unsafe;
     578                                }
     579                        }
     580                } else {
     581                        ast::Pass<ConversionCost_new> converter( dst, symtab, env, localConversionCost );
     582                        src->accept( converter );
     583                        return converter.pass.cost;
     584                }
     585        } else {
     586                assert( -1 == diff );
     587                const ast::ReferenceType * dstAsRef = dynamic_cast< const ast::ReferenceType * >( dst );
     588                assert( dstAsRef );
     589                if ( typesCompatibleIgnoreQualifiers( src, dstAsRef->base, symtab, env ) ) {
     590                        if ( src->is_lvalue() ) {
     591                                if ( src->qualifiers == dstAsRef->base->qualifiers ) {
     592                                        return Cost::reference;
     593                                } else if ( src->qualifiers < dstAsRef->base->qualifiers ) {
     594                                        return Cost::safe;
     595                                } else {
     596                                        return Cost::unsafe;
     597                                }
     598                        } else if ( dstAsRef->base->is_const() ) {
     599                                return Cost::safe;
     600                        } else {
     601                                return Cost::unsafe;
     602                        }
     603                }
     604        }
     605        return Cost::infinity;
     606}
     607
     608Cost convertToReferenceCost( const ast::Type * src, const ast::ReferenceType * dst,
     609            const ast::SymbolTable & symtab, const ast::TypeEnvironment & env,
     610                NumCostCalculation func ) {
     611        int sdepth = src->referenceDepth(), ddepth = dst->referenceDepth();
     612        return convertToReferenceCost( src, dst, sdepth - ddepth, symtab, env, func );
     613}
     614
     615void ConversionCost_new::postvisit( const ast::VoidType * voidType ) {
     616        (void)voidType;
     617        cost = Cost::infinity;
     618}
     619
     620void ConversionCost_new::postvisit( const ast::BasicType * basicType ) {
     621        if ( const ast::BasicType * dstAsBasic = dynamic_cast< const ast::BasicType * >( dst ) ) {
     622                int tableResult = costMatrix[ basicType->kind ][ dstAsBasic->kind ];
     623                if ( tableResult == -1 ) {
     624                        cost = Cost::unsafe;
     625                } else {
     626                        cost = Cost::zero;
     627                        cost.incSafe( tableResult );
     628                        cost.incSign( signMatrix[ basicType->kind ][ dstAsBasic->kind ] );
     629                }
     630        } else if ( dynamic_cast< const ast::EnumInstType * >( dst ) ) {
     631                // xxx - not positive this is correct, but appears to allow casting int => enum
     632                cost = Cost::unsafe;
     633        }
     634}
     635
     636void ConversionCost_new::postvisit( const ast::PointerType * pointerType ) {
     637        if ( const ast::PointerType * dstAsPtr = dynamic_cast< const ast::PointerType * >( dst ) ) {
     638                ast::CV::Qualifiers tq1 = pointerType->base->qualifiers;
     639                ast::CV::Qualifiers tq2 = dstAsPtr->base->qualifiers;
     640                if ( tq1 <= tq2 && typesCompatibleIgnoreQualifiers(
     641                                pointerType->base, dstAsPtr->base, symtab, env ) ) {
     642                        if ( tq1 == tq2 ) {
     643                                cost = Cost::zero;
     644                        } else {
     645                                cost = Cost::safe;
     646                        }
     647                } else {
     648                        int assignResult = ptrsAssignable( pointerType->base, dstAsPtr->base, env );
     649                        if ( 0 < assignResult && tq1 <= tq2 ) {
     650                                if ( tq1 == tq2 ) {
     651                                        cost = Cost::safe;
     652                                } else {
     653                                        cost = Cost::safe + Cost::safe;
     654                                }
     655                        } else if ( assignResult < 0 ) {
     656                                cost = Cost::unsafe;
     657                        } // else Cost::infinity
     658                }
     659        }
     660}
     661
     662void ConversionCost_new::postvisit( const ast::ArrayType * arrayType ) {
     663        (void)arrayType;
     664}
     665
     666void ConversionCost_new::postvisit( const ast::ReferenceType * refType ) {
     667        assert( nullptr == dynamic_cast< const ast::ReferenceType * >( dst ) );
     668
     669        cost = costCalc( refType->base, dst, symtab, env );
     670        if ( refType->base->qualifiers == dst->qualifiers ) {
     671                cost.incReference();
     672        } else if ( refType->base->qualifiers < dst->qualifiers ) {
     673                cost.incSafe();
     674        } else {
     675                cost.incUnsafe();
     676        }
     677}
     678
     679void ConversionCost_new::postvisit( const ast::FunctionType * functionType ) {
     680        (void)functionType;
     681}
     682
     683void ConversionCost_new::postvisit( const ast::StructInstType * structInstType ) {
     684        if ( const ast::StructInstType * dstAsInst =
     685                        dynamic_cast< const ast::StructInstType * >( dst ) ) {
     686                if ( structInstType->name == dstAsInst->name ) {
     687                        cost = Cost::zero;
     688                }
     689        }
     690}
     691
     692void ConversionCost_new::postvisit( const ast::UnionInstType * unionInstType ) {
     693        if ( const ast::UnionInstType * dstAsInst =
     694                        dynamic_cast< const ast::UnionInstType * >( dst ) ) {
     695                if ( unionInstType->name == dstAsInst->name ) {
     696                        cost = Cost::zero;
     697                }
     698        }
     699}
     700
     701void ConversionCost_new::postvisit( const ast::EnumInstType * enumInstType ) {
     702        (void)enumInstType;
     703        static const ast::BasicType integer( ast::BasicType::SignedInt );
     704        cost = costCalc( &integer, dst, symtab, env );
     705        if ( cost < Cost::unsafe ) {
     706                cost.incSafe();
     707        }
     708}
     709
     710void ConversionCost_new::postvisit( const ast::TraitInstType * traitInstType ) {
     711        (void)traitInstType;
     712}
     713
     714void ConversionCost_new::postvisit( const ast::TypeInstType * typeInstType ) {
     715        if ( const ast::EqvClass * eqv = env.lookup( typeInstType->name ) ) {
     716                cost = costCalc( eqv->bound, dst, symtab, env );
     717        } else if ( const ast::TypeInstType * dstAsInst =
     718                        dynamic_cast< const ast::TypeInstType * >( dst ) ) {
     719                if ( typeInstType->name == dstAsInst->name ) {
     720                        cost = Cost::zero;
     721                }
     722        } else if ( const ast::NamedTypeDecl * namedType = symtab.lookupType( typeInstType->name ) ) {
     723                const ast::TypeDecl * type = dynamic_cast< const ast::TypeDecl * >( namedType );
     724                assertf( type, "Unexpected typedef.");
     725                if ( type->base ) {
     726                        cost = costCalc( type->base, dst, symtab, env ) + Cost::safe;
     727                }
     728        }
     729}
     730
     731void ConversionCost_new::postvisit( const ast::TupleType * tupleType ) {
     732        Cost c = Cost::zero;
     733        if ( const ast::TupleType * dstAsTuple = dynamic_cast< const ast::TupleType * >( dst ) ) {
     734                auto srcIt = tupleType->types.begin();
     735                auto dstIt = dstAsTuple->types.begin();
     736                auto srcEnd = tupleType->types.end();
     737                auto dstEnd = dstAsTuple->types.end();
     738                while ( srcIt != srcEnd && dstIt != dstEnd ) {
     739                        Cost newCost = costCalc( * srcIt++, * dstIt++, symtab, env );
     740                        if ( newCost == Cost::infinity ) {
     741                                return;
     742                        }
     743                        c += newCost;
     744                }
     745                if ( dstIt != dstEnd ) {
     746                        cost = Cost::infinity;
     747                } else {
     748                        cost = c;
     749                }
     750        }
     751}
     752
     753void ConversionCost_new::postvisit( const ast::VarArgsType * varArgsType ) {
     754        (void)varArgsType;
     755        if ( dynamic_cast< const ast::VarArgsType * >( dst ) ) {
     756                cost = Cost::zero;
     757        }
     758}
     759
     760void ConversionCost_new::postvisit( const ast::ZeroType * zeroType ) {
     761        (void)zeroType;
     762        if ( dynamic_cast< const ast::ZeroType * >( dst ) ) {
     763                cost = Cost::zero;
     764        } else if ( const ast::BasicType * dstAsBasic =
     765                        dynamic_cast< const ast::BasicType * >( dst ) ) {
     766                int tableResult = costMatrix[ ast::BasicType::SignedInt ][ dstAsBasic->kind ];
     767                if ( -1 == tableResult ) {
     768                        cost = Cost::unsafe;
     769                } else {
     770                        cost = Cost::zero;
     771                        cost.incSafe( tableResult + 1 );
     772                        cost.incSign( signMatrix[ ast::BasicType::SignedInt ][ dstAsBasic->kind ] );
     773                }
     774        }
     775}
     776
     777void ConversionCost_new::postvisit( const ast::OneType * oneType ) {
     778        (void)oneType;
     779        if ( dynamic_cast< const ast::OneType * >( dst ) ) {
     780                cost = Cost::zero;
     781        } else if ( const ast::BasicType * dstAsBasic =
     782                        dynamic_cast< const ast::BasicType * >( dst ) ) {
     783                int tableResult = costMatrix[ ast::BasicType::SignedInt ][ dstAsBasic->kind ];
     784                if ( -1 == tableResult ) {
     785                        cost = Cost::unsafe;
     786                } else {
     787                        cost = Cost::zero;
     788                        cost.incSafe( tableResult + 1 );
     789                        cost.incSign( signMatrix[ ast::BasicType::SignedInt ][ dstAsBasic->kind ] );
     790                }
     791        } else if ( dynamic_cast< const ast::PointerType * >( dst ) ) {
     792                cost = Cost::zero;
     793                cost.incSafe( maxIntCost + 2 );
     794        }
     795}
     796
     797
    442798} // namespace ResolvExpr
    443799
  • src/ResolvExpr/ConversionCost.h

    r7951100 rb067d9b  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 09:37:28 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Jul 22 09:38:24 2017
    13 // Update Count     : 4
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Thu Aug  8 16:13:00 2019
     13// Update Count     : 6
    1414//
    1515
     
    2020#include "Cost.h"             // for Cost
    2121
     22#include "AST/Fwd.hpp"
     23#include "AST/Pass.hpp"       // for WithShortCircuiting
    2224#include "Common/PassVisitor.h"
    2325#include "SynTree/Visitor.h"  // for Visitor
     
    3133        class TypeEnvironment;
    3234
    33         typedef std::function<Cost(Type *, Type *, const SymTab::Indexer &, const TypeEnvironment &)> CostFunction;
     35        typedef std::function<Cost(const Type *, const Type *, bool,
     36                const SymTab::Indexer &, const TypeEnvironment &)> CostFunction;
     37
    3438        struct ConversionCost : public WithShortCircuiting {
    3539          public:
    36                 ConversionCost( Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction );
     40                ConversionCost( const Type * dest, bool srcIsLvalue,
     41                        const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction );
    3742
    3843                Cost get_cost() const { return cost; }
    3944
    40                 void previsit( BaseSyntaxNode * ) { visit_children = false; }
     45                void previsit( const BaseSyntaxNode * ) { visit_children = false; }
    4146
    42                 void postvisit( VoidType * voidType );
    43                 void postvisit( BasicType * basicType );
    44                 void postvisit( PointerType * pointerType );
    45                 void postvisit( ArrayType * arrayType );
    46                 void postvisit( ReferenceType * refType );
    47                 void postvisit( FunctionType * functionType );
    48                 void postvisit( StructInstType * aggregateUseType );
    49                 void postvisit( UnionInstType * aggregateUseType );
    50                 void postvisit( EnumInstType * aggregateUseType );
    51                 void postvisit( TraitInstType * aggregateUseType );
    52                 void postvisit( TypeInstType * aggregateUseType );
    53                 void postvisit( TupleType * tupleType );
    54                 void postvisit( VarArgsType * varArgsType );
    55                 void postvisit( ZeroType * zeroType );
    56                 void postvisit( OneType * oneType );
     47                void postvisit( const VoidType * voidType );
     48                void postvisit( const BasicType * basicType );
     49                void postvisit( const PointerType * pointerType );
     50                void postvisit( const ArrayType * arrayType );
     51                void postvisit( const ReferenceType * refType );
     52                void postvisit( const FunctionType * functionType );
     53                void postvisit( const StructInstType * aggregateUseType );
     54                void postvisit( const UnionInstType * aggregateUseType );
     55                void postvisit( const EnumInstType * aggregateUseType );
     56                void postvisit( const TraitInstType * aggregateUseType );
     57                void postvisit( const TypeInstType * aggregateUseType );
     58                void postvisit( const TupleType * tupleType );
     59                void postvisit( const VarArgsType * varArgsType );
     60                void postvisit( const ZeroType * zeroType );
     61                void postvisit( const OneType * oneType );
    5762          protected:
    58                 Type *dest;
     63                const Type * dest;
     64                bool srcIsLvalue;
    5965                const SymTab::Indexer &indexer;
    6066                Cost cost;
     
    6369        };
    6470
    65         typedef std::function<int(Type *, Type *, const SymTab::Indexer &, const TypeEnvironment &)> PtrsFunction;
    66         Cost convertToReferenceCost( Type * src, ReferenceType * dest, const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func );
     71        typedef std::function<int(const Type *, const Type *, const SymTab::Indexer &, const TypeEnvironment &)> PtrsFunction;
     72        Cost convertToReferenceCost( const Type * src, const ReferenceType * dest, bool srcIsLvalue,
     73                const SymTab::Indexer & indexer, const TypeEnvironment & env, PtrsFunction func );
     74
     75// Some function pointer types, differ in return type.
     76using CostCalculation = std::function<Cost(const ast::Type *, const ast::Type *,
     77        const ast::SymbolTable &, const ast::TypeEnvironment &)>;
     78using NumCostCalculation = std::function<int(const ast::Type *, const ast::Type *,
     79        const ast::SymbolTable &, const ast::TypeEnvironment &)>;
     80
     81#warning when the old ConversionCost is removed, get ride of the _new suffix.
     82class ConversionCost_new : public ast::WithShortCircuiting {
     83protected:
     84        const ast::Type * dst;
     85        const ast::SymbolTable & symtab;
     86        const ast::TypeEnvironment & env;
     87        CostCalculation costCalc;
     88public:
     89        Cost cost;
     90
     91        ConversionCost_new( const ast::Type * dst, const ast::SymbolTable & symtab,
     92                        const ast::TypeEnvironment & env, CostCalculation costCalc ) :
     93                dst( dst ), symtab( symtab ), env( env ), costCalc( costCalc ), cost( Cost::infinity )
     94        {}
     95
     96        void previsit( const ast::Node * ) { visit_children = false; }
     97
     98        void postvisit( const ast::VoidType * voidType );
     99        void postvisit( const ast::BasicType * basicType );
     100        void postvisit( const ast::PointerType * pointerType );
     101        void postvisit( const ast::ArrayType * arrayType );
     102        void postvisit( const ast::ReferenceType * refType );
     103        void postvisit( const ast::FunctionType * functionType );
     104        void postvisit( const ast::StructInstType * structInstType );
     105        void postvisit( const ast::UnionInstType * unionInstType );
     106        void postvisit( const ast::EnumInstType * enumInstType );
     107        void postvisit( const ast::TraitInstType * traitInstType );
     108        void postvisit( const ast::TypeInstType * typeInstType );
     109        void postvisit( const ast::TupleType * tupleType );
     110        void postvisit( const ast::VarArgsType * varArgsType );
     111        void postvisit( const ast::ZeroType * zeroType );
     112        void postvisit( const ast::OneType * oneType );
     113};
     114
     115Cost convertToReferenceCost( const ast::Type * src, const ast::ReferenceType * dest,
     116        const ast::SymbolTable & indexer, const ast::TypeEnvironment & env, NumCostCalculation func );
     117
    67118} // namespace ResolvExpr
    68119
  • src/ResolvExpr/Cost.h

    r7951100 rb067d9b  
    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
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Jul 22 09:35:55 2017
    13 // Update Count     : 5
     12// Last Modified On : Fri Jun 21 11:39:13 2019
     13// Update Count     : 63
    1414//
    1515
     
    1717
    1818#include <iostream>
     19#include <cassert>
     20#include <climits>
    1921
    2022namespace ResolvExpr {
     23        // To maximize performance and space, the 7 resolution costs are packed into a single 64-bit word. However, the
     24        // specialization cost is a negative value so a correction is needed is a few places.
     25
    2126        class Cost {
    22           private:
    23                 Cost( int unsafeCost, int polyCost, int safeCost, int referenceCost );
     27                union {
     28                        struct {
     29                        #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
     30                                // Little-endian => first value is low priority and last is high priority.
     31                                unsigned char padding;                                  ///< unused
     32                                unsigned char referenceCost;                    ///< reference conversions
     33                                unsigned char specCost;                                 ///< Polymorphic type specializations (type assertions), negative cost
     34                                unsigned char varCost;                                  ///< Count of polymorphic type variables
     35                                unsigned char signCost;                                 ///< Count of safe sign conversions
     36                                unsigned char safeCost;                                 ///< Safe (widening) conversions
     37                                unsigned char polyCost;                                 ///< Count of parameters and return values bound to some poly type
     38                                unsigned char unsafeCost;                               ///< Unsafe (narrowing) conversions
     39                        #else
     40                                #error Cost BIG_ENDIAN unsupported
     41                        #endif
     42                        } v;
     43                        uint64_t all;
     44                };
     45                static const unsigned char correctb = 0xff;             // byte correction for negative spec cost
     46                static const uint64_t correctw = 0x00'00'00'00'00'ff'00'00; //' word correction for negative spec cost
     47          public:
     48                // Compiler adjusts constants for correct endian.
     49                enum : uint64_t {
     50                        zero      = 0x00'00'00'00'00'ff'00'00,
     51                        infinity  = 0xff'ff'ff'ff'ff'00'ff'ff,
     52                        unsafe    = 0x01'00'00'00'00'ff'00'00,
     53                        poly      = 0x00'01'00'00'00'ff'00'00,
     54                        safe      = 0x00'00'01'00'00'ff'00'00,
     55                        sign      = 0x00'00'00'01'00'ff'00'00,
     56                        var       = 0x00'00'00'00'01'ff'00'00,
     57                        spec      = 0x00'00'00'00'00'fe'00'00,
     58                        reference = 0x00'00'00'00'00'ff'01'00,
     59                }; //'
    2460
    25           public:
    26                 Cost & incUnsafe( int inc = 1 );
    27                 Cost & incPoly( int inc = 1 );
    28                 Cost & incSafe( int inc = 1 );
    29                 Cost & incReference( int inc = 1 );
     61                Cost( uint64_t all ) { Cost::all = all; }
     62                Cost( int unsafeCost, int polyCost, int safeCost, int signCost, int varCost, int specCost, int referenceCost ) {
     63                        // Assume little-endian => first value is low priority and last is high priority.
     64                        v = {
     65                        #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
     66                                (unsigned char)0,                                               // padding
     67                                (unsigned char)referenceCost,                   // low priority
     68                                (unsigned char)(specCost + correctb),   // correct for signedness
     69                                (unsigned char)varCost,
     70                                (unsigned char)signCost,
     71                                (unsigned char)safeCost,
     72                                (unsigned char)polyCost,
     73                                (unsigned char)unsafeCost,                              // high priority
     74                        #else
     75                                #error Cost BIG_ENDIAN unsupported
     76                        #endif
     77                        };
     78                }
    3079
    31                 int get_unsafeCost() const { return unsafeCost; }
    32                 int get_polyCost() const { return polyCost; }
    33                 int get_safeCost() const { return safeCost; }
    34                 int get_referenceCost() const { return referenceCost; }
     80                int get_unsafeCost() const { return v.unsafeCost; }
     81                int get_polyCost() const { return v.polyCost; }
     82                int get_safeCost() const { return v.safeCost; }
     83                int get_signCost() const { return v.signCost; }
     84                int get_varCost() const { return v.varCost; }
     85                int get_specCost() const { return -(correctb - v.specCost); }
     86                int get_referenceCost() const { return v.referenceCost; }
    3587
    36                 Cost operator+( const Cost &other ) const;
    37                 Cost operator-( const Cost &other ) const;
    38                 Cost &operator+=( const Cost &other );
    39                 bool operator<( const Cost &other ) const;
    40                 bool operator==( const Cost &other ) const;
    41                 bool operator!=( const Cost &other ) const;
    42                 friend std::ostream &operator<<( std::ostream &os, const Cost &cost );
     88                friend bool operator==( const Cost, const Cost );
     89                friend bool operator!=( const Cost lhs, const Cost rhs );
     90                // returns negative for *this < rhs, 0 for *this == rhs, positive for *this > rhs
     91                int compare( const Cost rhs ) const {
     92                        if ( all == infinity ) return 1;
     93                        if ( rhs.all == infinity ) return -1;
     94                        return all > rhs.all ? 1 : all == rhs.all ? 0 : -1;
     95                }
     96                friend bool operator<( const Cost lhs, const Cost rhs );
    4397
    44                 static const Cost zero;
    45                 static const Cost infinity;
     98                friend Cost operator+( const Cost lhs, const Cost rhs );
     99 
     100                Cost operator+=( const Cost rhs ) {
     101                        if ( all == infinity ) return *this;
     102                        if ( rhs.all == infinity ) {
     103                                all = infinity;
     104                                return *this;
     105                        }
     106                        all += rhs.all - correctw;                                      // correct for negative spec cost
     107                        return *this;
     108                }
    46109
    47                 static const Cost unsafe;
    48                 static const Cost poly;
    49                 static const Cost safe;
    50                 static const Cost reference;
    51           private:
    52                 int compare( const Cost &other ) const;
     110                Cost incUnsafe( int inc = 1 ) {
     111                        if ( all != infinity ) { assert( v.unsafeCost + inc <= UCHAR_MAX ); v.unsafeCost += inc; }
     112                        return *this;
     113                }
    53114
    54                 int unsafeCost;
    55                 int polyCost;
    56                 int safeCost;
    57                 int referenceCost;
     115                Cost incPoly( int inc = 1 ) {
     116                        if ( all != infinity ) { assert( v.polyCost + inc <= UCHAR_MAX ); v.polyCost += inc; }
     117                        return *this;
     118                }
     119
     120                Cost incSafe( int inc = 1 ) {
     121                        if ( all != infinity ) { assert( v.safeCost + inc <= UCHAR_MAX ); v.safeCost += inc; }
     122                        return *this;
     123                }
     124
     125                Cost incSign( int inc = 1 ) {
     126                        if ( all != infinity ) { assert( v.signCost + inc <= UCHAR_MAX ); v.signCost += inc; }
     127                        return *this;
     128                }
     129
     130                Cost incVar( int inc = 1 ) {
     131                        if ( all != infinity ) { assert( v.varCost + inc <= UCHAR_MAX ); v.varCost += inc; }
     132                        return *this;
     133                }
     134
     135                Cost decSpec( int dec = 1 ) {
     136                        if ( all != infinity ) { assert( v.specCost - dec >= 0 ); v.specCost -= dec; }
     137                        return *this;
     138                }
     139
     140                Cost incReference( int inc = 1 ) {
     141                        if ( all != infinity ) { assert( v.referenceCost + inc <= UCHAR_MAX ); v.referenceCost += inc; }
     142                        return *this;
     143                }
     144
     145                friend std::ostream & operator<<( std::ostream & os, const Cost cost );
    58146        };
    59147
    60         inline Cost::Cost( int unsafeCost, int polyCost, int safeCost, int referenceCost ) : unsafeCost( unsafeCost ), polyCost( polyCost ), safeCost( safeCost ), referenceCost( referenceCost ) {}
    61 
    62         inline Cost & Cost::incUnsafe( int inc ) {
    63                 if ( *this == infinity ) return *this;
    64                 unsafeCost += inc;
    65                 return *this;
     148        inline bool operator==( const Cost lhs, const Cost rhs ) {
     149                return lhs.all == rhs.all;
    66150        }
    67151
    68         inline Cost & Cost::incPoly( int inc ) {
    69                 if ( *this == infinity ) return *this;
    70                 polyCost += inc;
    71                 return *this;
     152        inline bool operator!=( const Cost lhs, const Cost rhs ) {
     153                return !( lhs.all == rhs.all );
    72154        }
    73155
    74         inline Cost & Cost::incSafe( int inc ) {
    75                 if ( *this == infinity ) return *this;
    76                 safeCost += inc;
    77                 return *this;
     156        inline bool operator<( const Cost lhs, const Cost rhs ) {
     157                if ( lhs.all == Cost::infinity ) return false;
     158                if ( rhs.all == Cost::infinity ) return true;
     159                return lhs.all < rhs.all;
    78160        }
    79161
    80         inline Cost & Cost::incReference( int inc ) {
    81                 if ( *this == infinity ) return *this;
    82                 referenceCost += inc;
    83                 return *this;
     162        inline Cost operator+( const Cost lhs, const Cost rhs ) {
     163                if ( lhs.all == Cost::infinity || rhs.all == Cost::infinity ) return Cost{ Cost::infinity };
     164                return Cost{ lhs.all + rhs.all - Cost::correctw }; // correct for negative spec cost
    84165        }
    85166
    86         inline Cost Cost::operator+( const Cost &other ) const {
    87                 if ( *this == infinity || other == infinity ) return infinity;
    88                 return Cost( unsafeCost + other.unsafeCost, polyCost + other.polyCost, safeCost + other.safeCost, referenceCost + other.referenceCost );
    89         }
    90 
    91         inline Cost Cost::operator-( const Cost &other ) const {
    92                 if ( *this == infinity || other == infinity ) return infinity;
    93                 return Cost( unsafeCost - other.unsafeCost, polyCost - other.polyCost, safeCost - other.safeCost, referenceCost - other.referenceCost );
    94         }
    95 
    96         inline Cost &Cost::operator+=( const Cost &other ) {
    97                 if ( *this == infinity ) return *this;
    98                 if ( other == infinity ) {
    99                         *this = infinity;
    100                         return *this;
    101                 }
    102                 unsafeCost += other.unsafeCost;
    103                 polyCost += other.polyCost;
    104                 safeCost += other.safeCost;
    105                 referenceCost += other.referenceCost;
    106                 return *this;
    107         }
    108 
    109         inline bool Cost::operator<( const Cost &other ) const {
    110                 if ( *this == infinity ) return false;
    111                 if ( other == infinity ) return true;
    112 
    113                 if ( unsafeCost > other.unsafeCost ) {
    114                         return false;
    115                 } else if ( unsafeCost < other.unsafeCost ) {
    116                         return true;
    117                 } else if ( polyCost > other.polyCost ) {
    118                         return false;
    119                 } else if ( polyCost < other.polyCost ) {
    120                         return true;
    121                 } else if ( safeCost > other.safeCost ) {
    122                         return false;
    123                 } else if ( safeCost < other.safeCost ) {
    124                         return true;
    125                 } else if ( referenceCost > other.referenceCost ) {
    126                         return false;
    127                 } else if ( referenceCost < other.referenceCost ) {
    128                         return true;
    129                 } else {
    130                         return false;
    131                 } // if
    132         }
    133 
    134         inline bool Cost::operator==( const Cost &other ) const {
    135                 return unsafeCost == other.unsafeCost
    136                         && polyCost == other.polyCost
    137                         && safeCost == other.safeCost
    138                         && referenceCost == other.referenceCost;
    139         }
    140 
    141         inline bool Cost::operator!=( const Cost &other ) const {
    142                 return !( *this == other );
    143         }
    144 
    145         inline std::ostream &operator<<( std::ostream &os, const Cost &cost ) {
    146                 os << "( " << cost.unsafeCost << ", " << cost.polyCost << ", " << cost.safeCost << ", " << cost.referenceCost << " )";
    147                 return os;
     167        inline std::ostream & operator<<( std::ostream & os, const Cost cost ) {
     168                return os << "( " << cost.get_unsafeCost() << ", " << cost.get_polyCost() << ", " << cost.get_safeCost()
     169                                  << ", " << cost.get_signCost() << ", " << cost.get_varCost() << ", " << cost.get_specCost()
     170                                  << ", " << cost.get_referenceCost() << " )";
    148171        }
    149172} // namespace ResolvExpr
  • src/ResolvExpr/CurrentObject.cc

    r7951100 rb067d9b  
    1616#include <stddef.h>                    // for size_t
    1717#include <cassert>                     // for assertf, assert, safe_dynamic_...
     18#include <deque>
    1819#include <iostream>                    // for ostream, operator<<, basic_ost...
    1920#include <stack>                       // for stack
    2021#include <string>                      // for string, operator<<, allocator
    2122
     23#include "AST/Expr.hpp"                // for InitAlternative
     24#include "AST/GenericSubstitution.hpp" // for genericSubstitution
     25#include "AST/Init.hpp"                // for Designation
     26#include "AST/Node.hpp"                // for readonly
     27#include "AST/Type.hpp"
    2228#include "Common/Indenter.h"           // for Indenter, operator<<
    2329#include "Common/SemanticError.h"      // for SemanticError
     
    139145                ArrayIterator( ArrayType * at ) : array( at ) {
    140146                        PRINT( std::cerr << "Creating array iterator: " << at << std::endl; )
    141                         base = at->get_base();
     147                        base = at->base;
    142148                        memberIter = createMemberIterator( base );
    143                         if ( at->isVarLen ) SemanticError( at, "VLA initialization does not support @=" );
    144                         setSize( at->get_dimension() );
     149                        if ( at->isVarLen ) SemanticError( at, "VLA initialization does not support @=: " );
     150                        setSize( at->dimension );
    145151                }
    146152
     
    150156
    151157        private:
    152                 void setSize( Expression * expr ) {
    153                         if ( ConstantExpr * constExpr = dynamic_cast< ConstantExpr * >( expr ) ) {
    154                                 try {
    155                                         size = constExpr->intValue();
    156                                         PRINT( std::cerr << "array type with size: " << size << std::endl; )
    157                                 } catch ( SemanticErrorException & ) {
    158                                         SemanticError( expr, "Constant expression of non-integral type in array dimension: " );
    159                                 }
    160                         }       else if ( CastExpr * castExpr = dynamic_cast< CastExpr * >( expr ) ) {
    161                                 setSize( castExpr->get_arg() ); // xxx - need to perform the conversion specified by the cast
    162                         } else if ( VariableExpr * varExpr = dynamic_cast< VariableExpr * >( expr ) ) {
    163                                 if ( EnumInstType * inst = dynamic_cast< EnumInstType * > ( varExpr->result ) ) {
    164                                         long long int value;
    165                                         if ( inst->baseEnum->valueOf( varExpr->var, value ) ) {
    166                                                 size = value;
    167                                         }
    168                                 }
     158                void setSize( Expression * expr ) { // replace this logic with an eval call
     159                        auto res = eval(expr);
     160                        if (res.second) {
     161                                size = res.first;
    169162                        } else {
    170                                 assertf( false, "unhandled expression in setSize: %s", toString( expr ).c_str() ); // xxx - if not a constant expression, it's not simple to determine how long the array actually is, which is necessary for initialization to be done correctly -- fix this
     163                                SemanticError( expr->location, toString("Array designator must be a constant expression: ", expr) );
    171164                        }
    172165                }
     
    592585} // namespace ResolvExpr
    593586
     587namespace ast {
     588        /// create a new MemberIterator that traverses a type correctly
     589        MemberIterator * createMemberIterator( const CodeLocation & loc, const Type * type );
     590
     591        /// Iterates "other" types (e.g. basic, pointer) which do not change at list initializer entry
     592        class SimpleIterator final : public MemberIterator {
     593                CodeLocation location;
     594                readonly< Type > type = nullptr;
     595        public:
     596                SimpleIterator( const CodeLocation & loc, const Type * t ) : location( loc ), type( t ) {}
     597
     598                void setPosition(
     599                        std::deque< ptr< Expr > >::const_iterator begin,
     600                        std::deque< ptr< Expr > >::const_iterator end
     601                ) override {
     602                        if ( begin != end ) {
     603                                SemanticError( location, "Un-designated initializer given non-empty designator" );
     604                        }
     605                }
     606
     607                std::deque< InitAlternative > operator* () const override { return first(); }
     608
     609                operator bool() const override { return type; }
     610
     611                SimpleIterator & bigStep() override { return smallStep(); }
     612                SimpleIterator & smallStep() override {
     613                        type = nullptr;  // empty on increment because no members
     614                        return *this;
     615                }
     616
     617                const Type * getType() override { return type; }
     618
     619                const Type * getNext() override { return type; }
     620
     621                std::deque< InitAlternative > first() const override {
     622                        if ( type ) return { InitAlternative{ type, new Designation{ location } } };
     623                        return {};
     624                }
     625        };
     626
     627        /// Iterates array types
     628        class ArrayIterator final : public MemberIterator {
     629                CodeLocation location;
     630                readonly< ArrayType > array = nullptr;
     631                readonly< Type > base = nullptr;
     632                size_t index = 0;
     633                size_t size = 0;
     634                std::unique_ptr< MemberIterator > memberIter;
     635
     636                void setSize( const Expr * expr ) {
     637                        auto res = eval(expr);
     638                        if ( ! res.second ) {
     639                                SemanticError( location,
     640                                        toString("Array designator must be a constant expression: ", expr ) );
     641                        }
     642                        size = res.first;
     643                }
     644
     645        public:
     646                ArrayIterator( const CodeLocation & loc, const ArrayType * at )
     647                : location( loc ), array( at ), base( at->base ) {
     648                        PRINT( std::cerr << "Creating array iterator: " << at << std::endl; )
     649                        memberIter.reset( createMemberIterator( loc, base ) );
     650                        if ( at->isVarLen ) {
     651                                SemanticError( location, at, "VLA initialization does not support @=: " );
     652                        }
     653                        setSize( at->dimension );
     654                }
     655
     656                void setPosition( const Expr * expr ) {
     657                        // need to permit integer-constant-expressions, including: integer constants,
     658                        // enumeration constants, character constants, sizeof expressions, alignof expressions,
     659                        // cast expressions
     660                        if ( auto constExpr = dynamic_cast< const ConstantExpr * >( expr ) ) {
     661                                try {
     662                                        index = constExpr->intValue();
     663                                } catch ( SemanticErrorException & ) {
     664                                        SemanticError( expr,
     665                                                "Constant expression of non-integral type in array designator: " );
     666                                }
     667                        } else if ( auto castExpr = dynamic_cast< const CastExpr * >( expr ) ) {
     668                                setPosition( castExpr->arg );
     669                        } else if (
     670                                dynamic_cast< const SizeofExpr * >( expr )
     671                                || dynamic_cast< const AlignofExpr * >( expr )
     672                        ) {
     673                                index = 0;
     674                        } else {
     675                                assertf( false,
     676                                        "bad designator given to ArrayIterator: %s", toString( expr ).c_str() );
     677                        }
     678                }
     679
     680                void setPosition(
     681                        std::deque< ptr< Expr > >::const_iterator begin,
     682                        std::deque< ptr< Expr > >::const_iterator end
     683                ) override {
     684                        if ( begin == end ) return;
     685
     686                        setPosition( *begin );
     687                        memberIter->setPosition( ++begin, end );
     688                }
     689
     690                std::deque< InitAlternative > operator* () const override { return first(); }
     691
     692                operator bool() const override { return index < size; }
     693
     694                ArrayIterator & bigStep() override {
     695                        PRINT( std::cerr << "bigStep in ArrayIterator (" << index << "/" << size << ")" << std::endl; )
     696                        ++index;
     697                        memberIter.reset( index < size ? createMemberIterator( location, base ) : nullptr );
     698                        return *this;
     699                }
     700
     701                ArrayIterator & smallStep() override {
     702                        PRINT( std::cerr << "smallStep in ArrayIterator (" << index << "/" << size << ")" << std::endl; )
     703                        if ( memberIter ) {
     704                                PRINT( std::cerr << "has member iter: " << *memberIter << std::endl; )
     705                                memberIter->smallStep();
     706                                if ( *memberIter ) {
     707                                        PRINT( std::cerr << "has valid member iter" << std::endl; )
     708                                        return *this;
     709                                }
     710                        }
     711                        return bigStep();
     712                }
     713
     714                const Type * getType() override { return array; }
     715
     716                const Type * getNext() override { return base; }
     717
     718                std::deque< InitAlternative > first() const override {
     719                        PRINT( std::cerr << "first in ArrayIterator (" << index << "/" << size << ")" << std::endl; )
     720                        if ( memberIter && *memberIter ) {
     721                                std::deque< InitAlternative > ret = memberIter->first();
     722                                for ( InitAlternative & alt : ret ) {
     723                                        alt.designation.get_and_mutate()->designators.emplace_front(
     724                                                ConstantExpr::from_ulong( location, index ) );
     725                                }
     726                                return ret;
     727                        }
     728                        return {};
     729                }
     730        };
     731
     732        class AggregateIterator : public MemberIterator {
     733        protected:
     734                using MemberList = std::vector< ptr< Decl > >;
     735
     736                CodeLocation location;
     737                std::string kind;  // for debug
     738                std::string name;
     739                const Type * inst;
     740                const MemberList & members;
     741                MemberList::const_iterator curMember;
     742                bool atbegin = true;  // false at first {small,big}Step
     743                const Type * curType = nullptr;
     744                std::unique_ptr< MemberIterator > memberIter = nullptr;
     745                TypeSubstitution sub;
     746
     747                bool init() {
     748                        PRINT( std::cerr << "--init()--" << members.size() << std::endl; )
     749                        if ( curMember != members.end() ) {
     750                                if ( auto field = curMember->as< ObjectDecl >() ) {
     751                                        PRINT( std::cerr << "incremented to field: " << field << std::endl; )
     752                                        curType = field->get_type();
     753                                        memberIter.reset( createMemberIterator( location, curType ) );
     754                                        return true;
     755                                }
     756                        }
     757                        return false;
     758                }
     759
     760                AggregateIterator(
     761                        const CodeLocation & loc, const std::string k, const std::string & n, const Type * i,
     762                        const MemberList & ms )
     763                : location( loc ), kind( k ), name( n ), inst( i ), members( ms ), curMember( ms.begin() ),
     764                  sub( genericSubstitution( i ) ) {
     765                        PRINT( std::cerr << "Creating " << kind << "(" << name << ")"; )
     766                        init();
     767                }
     768
     769        public:
     770                void setPosition(
     771                        std::deque< ptr< Expr > >::const_iterator begin,
     772                        std::deque< ptr< Expr > >::const_iterator end
     773                ) final {
     774                        if ( begin == end ) return;
     775
     776                        if ( auto varExpr = begin->as< VariableExpr >() ) {
     777                                for ( curMember = members.begin(); curMember != members.end(); ++curMember ) {
     778                                        if ( *curMember != varExpr->var ) continue;
     779
     780                                        ++begin;
     781
     782                                        memberIter.reset( createMemberIterator( location, varExpr->result ) );
     783                                        curType = varExpr->result;
     784                                        atbegin = curMember == members.begin() && begin == end;
     785                                        memberIter->setPosition( begin, end );
     786                                        return;
     787                                }
     788                                assertf( false,
     789                                        "could not find member in %s: %s", kind.c_str(), toString( varExpr ).c_str() );
     790                        } else {
     791                                assertf( false,
     792                                        "bad designator given to %s: %s", kind.c_str(), toString( *begin ).c_str() );
     793                        }
     794                }
     795
     796                std::deque< InitAlternative > operator* () const final {
     797                        if ( memberIter && *memberIter ) {
     798                                std::deque< InitAlternative > ret = memberIter->first();
     799                                PRINT( std::cerr << "sub: " << sub << std::endl; )
     800                                for ( InitAlternative & alt : ret ) {
     801                                        PRINT( std::cerr << "iterating and adding designators" << std::endl; )
     802                                        alt.designation.get_and_mutate()->designators.emplace_front(
     803                                                new VariableExpr{ location, curMember->strict_as< ObjectDecl >() } );
     804                                        // need to substitute for generic types so that casts are to concrete types
     805                                        PRINT( std::cerr << "  type is: " << alt.type; )
     806                                        sub.apply( alt.type ); // also apply to designation??
     807                                        PRINT( std::cerr << " ==> " << alt.type << std::endl; )
     808                                }
     809                                return ret;
     810                        }
     811                        return {};
     812                }
     813
     814                AggregateIterator & smallStep() final {
     815                        PRINT( std::cerr << "smallStep in " << kind << std::endl; )
     816                        atbegin = false;
     817                        if ( memberIter ) {
     818                                PRINT( std::cerr << "has member iter, incrementing..." << std::endl; )
     819                                memberIter->smallStep();
     820                                if ( *memberIter ) {
     821                                        PRINT( std::cerr << "success!" << std::endl; )
     822                                        return *this;
     823                                }
     824                        }
     825                        return bigStep();
     826                }
     827
     828                AggregateIterator & bigStep() override = 0;
     829
     830                const Type * getType() final { return inst; }
     831
     832                const Type * getNext() final {
     833                        return ( memberIter && *memberIter ) ? memberIter->getType() : nullptr;
     834                }
     835
     836                std::deque< InitAlternative > first() const final {
     837                        std::deque< InitAlternative > ret;
     838                        PRINT( std::cerr << "first " << kind << std::endl; )
     839                        if ( memberIter && *memberIter ) {
     840                                PRINT( std::cerr << "adding children" << std::endl; )
     841                                ret = memberIter->first();
     842                                for ( InitAlternative & alt : ret ) {
     843                                        PRINT( std::cerr << "iterating and adding designators" << std::endl; )
     844                                        alt.designation.get_and_mutate()->designators.emplace_front(
     845                                                new VariableExpr{ location, curMember->strict_as< ObjectDecl >() } );
     846                                }
     847                        }
     848                        if ( atbegin ) {
     849                                // only add self if at the very beginning of the structure
     850                                PRINT( std::cerr << "adding self" << std::endl; )
     851                                ret.emplace_front( inst, new Designation{ location } );
     852                        }
     853                        return ret;
     854                }
     855        };
     856
     857        class StructIterator final : public AggregateIterator {
     858        public:
     859                StructIterator( const CodeLocation & loc, const StructInstType * inst )
     860                : AggregateIterator( loc, "StructIterator", inst->name, inst, inst->base->members ) {}
     861
     862                operator bool() const override {
     863                        return curMember != members.end() || (memberIter && *memberIter);
     864                }
     865
     866                StructIterator & bigStep() override {
     867                        PRINT( std::cerr << "bigStep in " << kind << std::endl; )
     868                        atbegin = false;
     869                        memberIter = nullptr;
     870                        curType = nullptr;
     871                        while ( curMember != members.end() ) {
     872                                ++curMember;
     873                                if ( init() ) return *this;
     874                        }
     875                        return *this;
     876                }
     877        };
     878
     879        class UnionIterator final : public AggregateIterator {
     880        public:
     881                UnionIterator( const CodeLocation & loc, const UnionInstType * inst )
     882                : AggregateIterator( loc, "UnionIterator", inst->name, inst, inst->base->members ) {}
     883
     884                operator bool() const override { return memberIter && *memberIter; }
     885
     886                UnionIterator & bigStep() override {
     887                        // unions only initialize one member
     888                        PRINT( std::cerr << "bigStep in " << kind << std::endl; )
     889                        atbegin = false;
     890                        memberIter = nullptr;
     891                        curType = nullptr;
     892                        curMember = members.end();
     893                        return *this;
     894                }
     895        };
     896
     897        class TupleIterator final : public AggregateIterator {
     898        public:
     899                TupleIterator( const CodeLocation & loc, const TupleType * inst )
     900                : AggregateIterator(
     901                        loc, "TupleIterator", toString("Tuple", inst->size()), inst, inst->members
     902                ) {}
     903
     904                operator bool() const override {
     905                        return curMember != members.end() || (memberIter && *memberIter);
     906                }
     907
     908                TupleIterator & bigStep() override {
     909                        PRINT( std::cerr << "bigStep in " << kind << std::endl; )
     910                        atbegin = false;
     911                        memberIter = nullptr;
     912                        curType = nullptr;
     913                        while ( curMember != members.end() ) {
     914                                ++curMember;
     915                                if ( init() ) return *this;
     916                        }
     917                        return *this;
     918                }
     919        };
     920
     921        MemberIterator * createMemberIterator( const CodeLocation & loc, const Type * type ) {
     922                if ( auto aggr = dynamic_cast< const ReferenceToType * >( type ) ) {
     923                        if ( auto sit = dynamic_cast< const StructInstType * >( aggr ) ) {
     924                                return new StructIterator{ loc, sit };
     925                        } else if ( auto uit = dynamic_cast< const UnionInstType * >( aggr ) ) {
     926                                return new UnionIterator{ loc, uit };
     927                        } else {
     928                                assertf(
     929                                        dynamic_cast< const EnumInstType * >( aggr )
     930                                                || dynamic_cast< const TypeInstType * >( aggr ),
     931                                        "Encountered unhandled ReferenceToType in createMemberIterator: %s",
     932                                                toString( type ).c_str() );
     933                                return new SimpleIterator{ loc, type };
     934                        }
     935                } else if ( auto at = dynamic_cast< const ArrayType * >( type ) ) {
     936                        return new ArrayIterator{ loc, at };
     937                } else if ( auto tt = dynamic_cast< const TupleType * >( type ) ) {
     938                        return new TupleIterator{ loc, tt };
     939                } else {
     940                        return new SimpleIterator{ loc, type };
     941                }
     942        }
     943
     944        CurrentObject::CurrentObject( const CodeLocation & loc, const Type * type ) : objStack() {
     945                objStack.emplace_back( new SimpleIterator{ loc, type } );
     946        }
     947
     948        const Designation * CurrentObject::findNext( const Designation * designation ) {
     949                using DesignatorChain = std::deque< ptr< Expr > >;
     950                PRINT( std::cerr << "___findNext" << std::endl; )
     951               
     952                // find all the d's
     953                std::vector< DesignatorChain > desigAlts{ {} }, newDesigAlts;
     954                std::deque< const Type * > curTypes{ objStack.back()->getType() }, newTypes;
     955                for ( const Expr * expr : designation->designators ) {
     956                        PRINT( std::cerr << "____untyped: " << expr << std::endl; )
     957                        auto dit = desigAlts.begin();
     958                        if ( auto nexpr = dynamic_cast< const NameExpr * >( expr ) ) {
     959                                for ( const Type * t : curTypes ) {
     960                                        assert( dit != desigAlts.end() );
     961
     962                                        DesignatorChain & d = *dit;
     963                                        PRINT( std::cerr << "____actual: " << t << std::endl; )
     964                                        if ( auto refType = dynamic_cast< const ReferenceToType * >( t ) ) {
     965                                                // concatenate identical field names
     966                                                for ( const Decl * mem : refType->lookup( nexpr->name ) ) {
     967                                                        if ( auto field = dynamic_cast< const ObjectDecl * >( mem ) ) {
     968                                                                PRINT( std::cerr << "____alt: " << field->type << std::endl; )
     969                                                                DesignatorChain d2 = d;
     970                                                                d2.emplace_back( new VariableExpr{ expr->location, field } );
     971                                                                newDesigAlts.emplace_back( std::move( d2 ) );
     972                                                                newTypes.emplace_back( field->type );
     973                                                        }
     974                                                }
     975                                        }
     976
     977                                        ++dit;
     978                                }
     979                        } else {
     980                                for ( const Type * t : curTypes ) {
     981                                        assert( dit != desigAlts.end() );
     982
     983                                        DesignatorChain & d = *dit;
     984                                        if ( auto at = dynamic_cast< const ArrayType * >( t ) ) {
     985                                                PRINT( std::cerr << "____alt: " << at->get_base() << std::endl; )
     986                                                d.emplace_back( expr );
     987                                                newDesigAlts.emplace_back( d );
     988                                                newTypes.emplace_back( at->base );
     989                                        }
     990                                }
     991                        }
     992
     993                        // reset queue
     994                        desigAlts = std::move( newDesigAlts );
     995                        newDesigAlts.clear();
     996                        curTypes = std::move( newTypes );
     997                        newTypes.clear();
     998                        assertf( desigAlts.size() == curTypes.size(), "Designator alternatives (%zu) and current types (%zu) out of sync", desigAlts.size(), curTypes.size() );
     999                }
     1000
     1001                if ( desigAlts.size() > 1 ) {
     1002                        SemanticError( designation, toString("Too many alternatives (", desigAlts.size(), ") for designation: ") );
     1003                } else if ( desigAlts.empty() ) {
     1004                        SemanticError( designation, "No reasonable alternatives for designation: " );
     1005                }
     1006
     1007                DesignatorChain & d = desigAlts.back();
     1008                PRINT( for ( Expression * expr : d ) {
     1009                        std::cerr << "____desig: " << expr << std::endl;
     1010                } ) // for
     1011                assertf( ! curTypes.empty(), "empty designator chosen");
     1012
     1013                // set new designators
     1014                assertf( ! objStack.empty(), "empty object stack when setting designation" );
     1015                Designation * actualDesignation =
     1016                        new Designation{ designation->location, DesignatorChain{d} };
     1017                objStack.back()->setPosition( d ); // destroys d
     1018                return actualDesignation;
     1019        }
     1020
     1021        void CurrentObject::setNext( const Designation * designation ) {
     1022                PRINT( std::cerr << "____setNext" << designation << std::endl; )
     1023                assertf( ! objStack.empty(), "obj stack empty in setNext" );
     1024                objStack.back()->setPosition( designation->designators );
     1025        }
     1026
     1027        void CurrentObject::increment() {
     1028                PRINT( std::cerr << "____increment" << std::endl; )
     1029                if ( objStack.empty() ) return;
     1030                PRINT( std::cerr << *objStack.back() << std::endl; )
     1031                objStack.back()->smallStep();
     1032        }
     1033
     1034        void CurrentObject::enterListInit( const CodeLocation & loc ) {
     1035                PRINT( std::cerr << "____entering list init" << std::endl; )
     1036                assertf( ! objStack.empty(), "empty obj stack entering list init" );
     1037                const ast::Type * type = objStack.back()->getNext();
     1038                assert( type );
     1039                objStack.emplace_back( createMemberIterator( loc, type ) );
     1040        }
     1041
     1042        void CurrentObject::exitListInit() {
     1043                PRINT( std::cerr << "____exiting list init" << std::endl; )
     1044                assertf( ! objStack.empty(), "objstack empty" );
     1045                objStack.pop_back();
     1046                if ( ! objStack.empty() ) {
     1047                        PRINT( std::cerr << *objStack.back() << std::endl; )
     1048                        objStack.back()->bigStep();
     1049                }
     1050        }
     1051
     1052        std::deque< InitAlternative > CurrentObject::getOptions() {
     1053                PRINT( std::cerr << "____getting current options" << std::endl; )
     1054                assertf( ! objStack.empty(), "objstack empty in getOptions" );
     1055                return **objStack.back();
     1056        }
     1057
     1058        const Type * CurrentObject::getCurrentType() {
     1059                PRINT( std::cerr << "____getting current type" << std::endl; )
     1060                assertf( ! objStack.empty(), "objstack empty in getCurrentType" );
     1061                return objStack.back()->getNext();
     1062        }
     1063}
     1064
    5941065// Local Variables: //
    5951066// tab-width: 4 //
  • src/ResolvExpr/CurrentObject.h

    r7951100 rb067d9b  
    1616#pragma once
    1717
     18#include <deque>
    1819#include <list>   // for list
     20#include <memory> // for unique_ptr
    1921#include <stack>  // for stack
     22#include <vector>
     23
     24#include "AST/Node.hpp"  // for ptr
     25#include "Common/CodeLocation.h"
    2026
    2127class Designation;
     
    5258} // namespace ResolvExpr
    5359
     60namespace ast {
     61        // AST class types
     62        class Designation;
     63        struct InitAlternative;
     64        class Type;
     65
     66        /// Iterates members of a type by initializer
     67        class MemberIterator {
     68        public:
     69                virtual ~MemberIterator() {}
     70
     71                /// Internal set position based on iterator ranges
     72                virtual void setPosition(
     73                        std::deque< ptr< Expr > >::const_iterator it,
     74                        std::deque< ptr< Expr > >::const_iterator end ) = 0;
     75
     76                /// walks the current object using the given designators as a guide
     77                void setPosition( const std::deque< ptr< Expr > > & designators ) {
     78                        setPosition( designators.begin(), designators.end() );
     79                }
     80
     81                /// retrieve the list of possible (Type,Designation) pairs for the current position in the
     82                /// current object
     83                virtual std::deque< InitAlternative > operator* () const = 0;
     84
     85                /// true if the iterator is not currently at the end
     86                virtual operator bool() const = 0;
     87
     88                /// moves the iterator by one member in the current object
     89                virtual MemberIterator & bigStep() = 0;
     90
     91                /// moves the iterator by one member in the current subobject
     92                virtual MemberIterator & smallStep() = 0;
     93
     94                /// the type of the current object
     95                virtual const Type * getType() = 0;
     96
     97                /// the type of the current subobject
     98                virtual const Type * getNext() = 0;
     99       
     100                /// helper for operator*; aggregates must add designator to each init alternative, but
     101                /// adding designators in operator* creates duplicates
     102                virtual std::deque< InitAlternative > first() const = 0;
     103        };
     104
     105        /// Builds initializer lists in resolution
     106        class CurrentObject final {
     107                std::vector< std::shared_ptr<MemberIterator> > objStack;
     108       
     109        public:
     110                CurrentObject() = default;
     111                CurrentObject( const CodeLocation & loc, const Type * type );
     112
     113                /// resolves unresolved designation
     114                const Designation * findNext( const Designation * designation );
     115                /// sets current position using the resolved designation
     116                void setNext( const ast::Designation * designation );
     117                /// steps to next sub-object of current object
     118                void increment();
     119                /// sets new current object for the duration of this brace-enclosed intializer-list
     120                void enterListInit( const CodeLocation & loc );
     121                /// restores previous current object
     122                void exitListInit();
     123                /// produces a list of alternatives (Type *, Designation *) for the current sub-object's
     124                /// initializer.
     125                std::deque< InitAlternative > getOptions();
     126                /// produces the type of the current object but no subobjects
     127                const Type * getCurrentType();
     128        };
     129} // namespace ast
     130
    54131// Local Variables: //
    55132// tab-width: 4 //
  • src/ResolvExpr/ExplodedActual.cc

    r7951100 rb067d9b  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // Alternative.h --
     7// ExplodedActual.cc --
    88//
    99// Author           : Aaron B. Moss
     
    2424        }
    2525}
     26
     27// Local Variables: //
     28// tab-width: 4 //
     29// mode: c++ //
     30// compile-command: "make install" //
     31// End: //
  • src/ResolvExpr/ExplodedActual.h

    r7951100 rb067d9b  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // Alternative.h --
     7// ExplodedActual.h --
    88//
    99// Author           : Aaron B. Moss
     
    3232
    3333                ExplodedActual() : env(), cost(Cost::zero), exprs() {}
    34 
    3534                ExplodedActual( const Alternative& actual, const SymTab::Indexer& indexer );
     35                ExplodedActual(ExplodedActual&&) = default;
     36                ExplodedActual& operator= (ExplodedActual&&) = default;
    3637        };
    3738}
     39
     40// Local Variables: //
     41// tab-width: 4 //
     42// mode: c++ //
     43// compile-command: "make install" //
     44// End: //
  • src/ResolvExpr/FindOpenVars.cc

    r7951100 rb067d9b  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 09:42:48 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun May 17 09:45:25 2015
    13 // Update Count     : 3
     11// Last Modified By : Andrew
     12// Last Modified On : Fri Jul 12 14:18:00 2019
     13// Update Count     : 4
    1414//
    1515
     
    1919#include <map>                    // for map<>::mapped_type
    2020
     21#include "AST/Pass.hpp"
     22#include "AST/Type.hpp"
    2123#include "Common/PassVisitor.h"
    2224#include "SynTree/Declaration.h"  // for TypeDecl, DeclarationWithType (ptr ...
     
    2426
    2527namespace ResolvExpr {
    26         struct FindOpenVars : public WithGuards {
    27                 FindOpenVars( OpenVarSet &openVars, OpenVarSet &closedVars, AssertionSet &needAssertions, AssertionSet &haveAssertions, bool firstIsOpen );
     28        struct FindOpenVars_old : public WithGuards {
     29                FindOpenVars_old( OpenVarSet &openVars, OpenVarSet &closedVars, AssertionSet &needAssertions, AssertionSet &haveAssertions, bool firstIsOpen );
    2830
    29                 void previsit( PointerType * pointerType );
    30                 void previsit( ArrayType * arrayType );
    31                 void previsit( FunctionType * functionType );
    32                 void previsit( TupleType * tupleType );
     31                void previsit( const PointerType * pointerType );
     32                void previsit( const ArrayType * arrayType );
     33                void previsit( const FunctionType * functionType );
     34                void previsit( const TupleType * tupleType );
    3335
    34                 void common_action( Type *type );
     36                void common_action( const Type *type );
    3537
    3638                OpenVarSet &openVars, &closedVars;
     
    3941        };
    4042
    41         void findOpenVars( Type *type, OpenVarSet &openVars, OpenVarSet &closedVars, AssertionSet &needAssertions, AssertionSet &haveAssertions, bool firstIsOpen ) {
    42                 PassVisitor<FindOpenVars> finder( openVars, closedVars, needAssertions, haveAssertions, firstIsOpen );
     43        void findOpenVars( const Type *type, OpenVarSet &openVars, OpenVarSet &closedVars, AssertionSet &needAssertions, AssertionSet &haveAssertions, bool firstIsOpen ) {
     44                PassVisitor<FindOpenVars_old> finder( openVars, closedVars, needAssertions, haveAssertions, firstIsOpen );
    4345                type->accept( finder );
    4446        }
    4547
    46         FindOpenVars::FindOpenVars( OpenVarSet &openVars, OpenVarSet &closedVars, AssertionSet &needAssertions, AssertionSet &haveAssertions, bool firstIsOpen )
     48        FindOpenVars_old::FindOpenVars_old( OpenVarSet &openVars, OpenVarSet &closedVars, AssertionSet &needAssertions, AssertionSet &haveAssertions, bool firstIsOpen )
    4749                : openVars( openVars ), closedVars( closedVars ), needAssertions( needAssertions ), haveAssertions( haveAssertions ), nextIsOpen( firstIsOpen ) {
    4850        }
    4951
    50         void FindOpenVars::common_action( Type *type ) {
     52        void FindOpenVars_old::common_action( const Type * type ) {
    5153                if ( nextIsOpen ) {
    52                         for ( Type::ForallList::const_iterator i = type->get_forall().begin(); i != type->get_forall().end(); ++i ) {
     54                        for ( Type::ForallList::const_iterator i = type->forall.begin(); i != type->forall.end(); ++i ) {
    5355                                openVars[ (*i)->get_name() ] = TypeDecl::Data{ (*i) };
    5456                                for ( std::list< DeclarationWithType* >::const_iterator assert = (*i)->get_assertions().begin(); assert != (*i)->get_assertions().end(); ++assert ) {
     
    5961                        }
    6062                } else {
    61                         for ( Type::ForallList::const_iterator i = type->get_forall().begin(); i != type->get_forall().end(); ++i ) {
     63                        for ( Type::ForallList::const_iterator i = type->forall.begin(); i != type->forall.end(); ++i ) {
    6264                                closedVars[ (*i)->get_name() ] = TypeDecl::Data{ (*i) };
    6365                                for ( std::list< DeclarationWithType* >::const_iterator assert = (*i)->get_assertions().begin(); assert != (*i)->get_assertions().end(); ++assert ) {
     
    7678        }
    7779
    78         void FindOpenVars::previsit(PointerType *pointerType) {
     80        void FindOpenVars_old::previsit(const PointerType * pointerType) {
    7981                common_action( pointerType );
    8082        }
    8183
    82         void FindOpenVars::previsit(ArrayType *arrayType) {
     84        void FindOpenVars_old::previsit(const ArrayType * arrayType) {
    8385                common_action( arrayType );
    8486        }
    8587
    86         void FindOpenVars::previsit(FunctionType *functionType) {
     88        void FindOpenVars_old::previsit(const FunctionType * functionType) {
    8789                common_action( functionType );
    8890                nextIsOpen = ! nextIsOpen;
     
    9092        }
    9193
    92         void FindOpenVars::previsit(TupleType *tupleType) {
     94        void FindOpenVars_old::previsit(const TupleType * tupleType) {
    9395                common_action( tupleType );
     96        }
     97
     98        namespace {
     99                struct FindOpenVars_new final : public ast::WithGuards {
     100                        ast::OpenVarSet & open;
     101                        ast::OpenVarSet & closed;
     102                        ast::AssertionSet & need;
     103                        ast::AssertionSet & have;
     104                        bool nextIsOpen;
     105
     106                        FindOpenVars_new(
     107                                ast::OpenVarSet & o, ast::OpenVarSet & c, ast::AssertionSet & n,
     108                                ast::AssertionSet & h, FirstMode firstIsOpen )
     109                        : open( o ), closed( c ), need( n ), have( h ), nextIsOpen( firstIsOpen ) {}
     110
     111                        void previsit( const ast::FunctionType * type ) {
     112                                // mark open/closed variables
     113                                if ( nextIsOpen ) {
     114                                        for ( const ast::TypeDecl * decl : type->forall ) {
     115                                                open[ decl->name ] = ast::TypeDecl::Data{ decl };
     116                                                for ( const ast::DeclWithType * assert : decl->assertions ) {
     117                                                        need[ assert ].isUsed = false;
     118                                                }
     119                                        }
     120                                } else {
     121                                        for ( const ast::TypeDecl * decl : type->forall ) {
     122                                                closed[ decl->name ] = ast::TypeDecl::Data{ decl };
     123                                                for ( const ast::DeclWithType * assert : decl->assertions ) {
     124                                                        have[ assert ].isUsed = false;
     125                                                }
     126                                        }
     127                                }
     128
     129                                // flip open variables for contained function types
     130                                nextIsOpen = ! nextIsOpen;
     131                                GuardAction( [this](){ nextIsOpen = ! nextIsOpen; } );
     132                        }
     133
     134                };
     135        }
     136
     137        void findOpenVars(
     138                        const ast::Type * type, ast::OpenVarSet & open, ast::OpenVarSet & closed,
     139                        ast::AssertionSet & need, ast::AssertionSet & have, FirstMode firstIsOpen ) {
     140                ast::Pass< FindOpenVars_new > finder{ open, closed, need, have, firstIsOpen };
     141                type->accept( finder );
    94142        }
    95143} // namespace ResolvExpr
  • src/ResolvExpr/FindOpenVars.h

    r7951100 rb067d9b  
    1616#pragma once
    1717
     18#include "AST/TypeEnvironment.hpp"  // for AssertionSet, OpenVarSet
    1819#include "ResolvExpr/TypeEnvironment.h"  // for AssertionSet, OpenVarSet
    1920
    2021class Type;
     22namespace ast {
     23        class Type;
     24}
    2125
    2226namespace ResolvExpr {
    2327        // Updates open and closed variables and their associated assertions
    24         void findOpenVars( Type *type, OpenVarSet &openVars, OpenVarSet &closedVars, AssertionSet &needAssertions, AssertionSet &haveAssertions, bool firstIsOpen );
     28        void findOpenVars( const Type *type, OpenVarSet &openVars, OpenVarSet &closedVars, AssertionSet &needAssertions, AssertionSet &haveAssertions, bool firstIsOpen );
     29
     30        enum FirstMode { FirstClosed, FirstOpen };
     31
     32        // Updates open and closed variables and their associated assertions
     33        void findOpenVars(
     34                const ast::Type * type, ast::OpenVarSet & open, ast::OpenVarSet & closed,
     35                ast::AssertionSet & need, ast::AssertionSet & have, FirstMode firstIsOpen );
    2536} // namespace ResolvExpr
    2637
  • src/ResolvExpr/Occurs.cc

    r7951100 rb067d9b  
    2424        struct Occurs : public WithVisitorRef<Occurs> {
    2525                Occurs( std::string varName, const TypeEnvironment &env );
    26                 void previsit( TypeInstType * typeInst );
     26                void previsit( const TypeInstType * typeInst );
    2727
    2828                bool result;
     
    3131        };
    3232
    33         bool occurs( Type *type, std::string varName, const TypeEnvironment &env ) {
     33        bool occurs( const Type *type, const std::string & varName, const TypeEnvironment &env ) {
    3434                PassVisitor<Occurs> occur( varName, env );
    3535                type->accept( occur );
     
    4545        }
    4646
    47         void Occurs::previsit( TypeInstType * typeInst ) {
     47        void Occurs::previsit( const TypeInstType * typeInst ) {
    4848                ///   std::cerr << "searching for vars: ";
    4949///   std::copy( eqvVars.begin(), eqvVars.end(), std::ostream_iterator< std::string >( std::cerr, " " ) );
  • src/ResolvExpr/PolyCost.cc

    r7951100 rb067d9b  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 09:50:12 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun May 17 09:52:02 2015
    13 // Update Count     : 3
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Wed Jun 19 10:45:00 2019
     13// Update Count     : 4
    1414//
    1515
     16#include "AST/SymbolTable.hpp"
     17#include "AST/Type.hpp"
     18#include "AST/TypeEnvironment.hpp"
    1619#include "Common/PassVisitor.h"
    1720#include "SymTab/Indexer.h"   // for Indexer
     
    5457        }
    5558
     59// TODO: When the old PolyCost is torn out get rid of the _new suffix.
     60struct PolyCost_new {
     61        int result;
     62        const ast::SymbolTable &symtab;
     63        const ast::TypeEnvironment &env_;
     64
     65        PolyCost_new( const ast::SymbolTable & symtab, const ast::TypeEnvironment & env ) :
     66                result( 0 ), symtab( symtab ), env_( env ) {}
     67
     68        void previsit( const ast::TypeInstType * type ) {
     69                if ( const ast::EqvClass * eqv = env_.lookup( type->name ) ) /* && */ if ( eqv->bound ) {
     70                        if ( const ast::TypeInstType * otherType = eqv->bound.as< ast::TypeInstType >() ) {
     71                                if ( symtab.lookupType( otherType->name ) ) {
     72                                        // Bound to opaque type.
     73                                        result += 1;
     74                                }
     75                        } else {
     76                                // Bound to concrete type.
     77                                result += 1;
     78                        }
     79                }
     80        }
     81};
     82
     83int polyCost(
     84        const ast::Type * type, const ast::SymbolTable & symtab, const ast::TypeEnvironment & env
     85) {
     86        ast::Pass<PolyCost_new> costing( symtab, env );
     87        type->accept( costing );
     88        return costing.pass.result;
     89}
     90
    5691} // namespace ResolvExpr
    5792
  • src/ResolvExpr/PtrsAssignable.cc

    r7951100 rb067d9b  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 11:44:11 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Mar  2 17:36:05 2016
    13 // Update Count     : 8
    14 //
    15 
     11// Last Modified By : Andrew
     12// Last Modified On : Mon Jun 24 15:29:00 2019
     13// Update Count     : 9
     14//
     15
     16#include "typeops.h"
     17
     18#include "AST/Pass.hpp"
     19#include "AST/Type.hpp"
     20#include "AST/TypeEnvironment.hpp"
    1621#include "Common/PassVisitor.h"
    1722#include "ResolvExpr/TypeEnvironment.h"  // for EqvClass, TypeEnvironment
     
    2227namespace ResolvExpr {
    2328        struct PtrsAssignable : public WithShortCircuiting {
    24                 PtrsAssignable( Type *dest, const TypeEnvironment &env );
     29                PtrsAssignable( const Type * dest, const TypeEnvironment &env );
    2530
    2631                int get_result() const { return result; }
    2732
    28                 void previsit( Type * ) { visit_children = false; }
    29 
    30                 void postvisit( VoidType * voidType );
    31                 void postvisit( BasicType * basicType );
    32                 void postvisit( PointerType * pointerType );
    33                 void postvisit( ArrayType * arrayType );
    34                 void postvisit( FunctionType * functionType );
    35                 void postvisit( StructInstType * inst );
    36                 void postvisit( UnionInstType * inst );
    37                 void postvisit( EnumInstType * inst );
    38                 void postvisit( TraitInstType * inst );
    39                 void postvisit( TypeInstType * inst );
    40                 void postvisit( TupleType * tupleType );
    41                 void postvisit( VarArgsType * varArgsType );
    42                 void postvisit( ZeroType * zeroType );
    43                 void postvisit( OneType * oneType );
     33                void previsit( const Type * ) { visit_children = false; }
     34
     35                void postvisit( const VoidType * voidType );
     36                void postvisit( const BasicType * basicType );
     37                void postvisit( const PointerType * pointerType );
     38                void postvisit( const ArrayType * arrayType );
     39                void postvisit( const FunctionType * functionType );
     40                void postvisit( const StructInstType * inst );
     41                void postvisit( const UnionInstType * inst );
     42                void postvisit( const EnumInstType * inst );
     43                void postvisit( const TraitInstType * inst );
     44                void postvisit( const TypeInstType * inst );
     45                void postvisit( const TupleType * tupleType );
     46                void postvisit( const VarArgsType * varArgsType );
     47                void postvisit( const ZeroType * zeroType );
     48                void postvisit( const OneType * oneType );
    4449          private:
    45                 Type *dest;
     50                const Type * dest;
    4651                int result;
    4752                const TypeEnvironment &env;
    4853        };
    4954
    50         int ptrsAssignable( Type *src, Type *dest, const TypeEnvironment &env ) {
     55        int ptrsAssignable( const Type *src, const Type * dest, const TypeEnvironment &env ) {
    5156                // std::cerr << "assignable: " << src << " | " << dest << std::endl;
    52                 if ( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) {
    53                         if ( const EqvClass *eqvClass = env.lookup( destAsTypeInst->get_name() ) ) {
     57                if ( const TypeInstType * destAsTypeInst = dynamic_cast< const TypeInstType* >( dest ) ) {
     58                        if ( const EqvClass * eqvClass = env.lookup( destAsTypeInst->get_name() ) ) {
    5459                                return ptrsAssignable( src, eqvClass->type, env );
    5560                        } // if
    5661                } // if
    57                 if ( dynamic_cast< VoidType* >( dest ) ) {
     62                if ( dynamic_cast< const VoidType* >( dest ) ) {
    5863                        // void * = T * for any T is unsafe
    5964                        // xxx - this should be safe, but that currently breaks the build
     
    6671        }
    6772
    68         PtrsAssignable::PtrsAssignable( Type *dest, const TypeEnvironment &env ) : dest( dest ), result( 0 ), env( env ) {}
    69 
    70         void PtrsAssignable::postvisit( VoidType * ) {
     73        PtrsAssignable::PtrsAssignable( const Type * dest, const TypeEnvironment &env ) : dest( dest ), result( 0 ), env( env ) {}
     74
     75        void PtrsAssignable::postvisit( const VoidType * ) {
    7176                // T * = void * is disallowed - this is a change from C, where any
    7277                // void * can be assigned or passed to a non-void pointer without a cast.
    7378        }
    7479
    75         void PtrsAssignable::postvisit( __attribute__((unused)) BasicType *basicType ) {}
    76         void PtrsAssignable::postvisit( __attribute__((unused)) PointerType *pointerType ) {}
    77         void PtrsAssignable::postvisit( __attribute__((unused)) ArrayType *arrayType ) {}
    78         void PtrsAssignable::postvisit( __attribute__((unused)) FunctionType *functionType ) {}
    79 
    80         void PtrsAssignable::postvisit(  __attribute__((unused)) StructInstType *inst ) {}
    81         void PtrsAssignable::postvisit(  __attribute__((unused)) UnionInstType *inst ) {}
    82 
    83         void PtrsAssignable::postvisit( EnumInstType * ) {
    84                 if ( dynamic_cast< BasicType* >( dest ) ) {
     80        void PtrsAssignable::postvisit( const BasicType * ) {}
     81        void PtrsAssignable::postvisit( const PointerType * ) {}
     82        void PtrsAssignable::postvisit( const ArrayType * ) {}
     83        void PtrsAssignable::postvisit( const FunctionType * ) {}
     84
     85        void PtrsAssignable::postvisit( const StructInstType * ) {}
     86        void PtrsAssignable::postvisit( const UnionInstType * ) {}
     87
     88        void PtrsAssignable::postvisit( const EnumInstType * ) {
     89                if ( dynamic_cast< const BasicType* >( dest ) ) {
    8590                        // int * = E *, etc. is safe. This isn't technically correct, as each
    8691                        // enum has one basic type that it is compatible with, an that type can
     
    9297        }
    9398
    94         void PtrsAssignable::postvisit(  __attribute__((unused)) TraitInstType *inst ) {}
    95         void PtrsAssignable::postvisit( TypeInstType *inst ) {
    96                 if ( const EqvClass *eqvClass = env.lookup( inst->get_name() ) ) {
     99        void PtrsAssignable::postvisit(  const TraitInstType * ) {}
     100        void PtrsAssignable::postvisit( const TypeInstType * inst ) {
     101                if ( const EqvClass * eqvClass = env.lookup( inst->name ) ) {
    97102                        if ( eqvClass->type ) {
    98103                                // T * = S * for any S depends on the type bound to T
     
    102107        }
    103108
    104         void PtrsAssignable::postvisit(  __attribute__((unused)) TupleType *tupleType ) {}
    105         void PtrsAssignable::postvisit(  __attribute__((unused)) VarArgsType *varArgsType ) {}
    106         void PtrsAssignable::postvisit(  __attribute__((unused)) ZeroType *zeroType ) {}
    107         void PtrsAssignable::postvisit(  __attribute__((unused)) OneType *oneType ) {}
     109        void PtrsAssignable::postvisit( const TupleType * ) {}
     110        void PtrsAssignable::postvisit( const VarArgsType * ) {}
     111        void PtrsAssignable::postvisit( const ZeroType * ) {}
     112        void PtrsAssignable::postvisit( const OneType * ) {}
     113
     114// TODO: Get rid of the `_new` suffix when the old version is removed.
     115struct PtrsAssignable_new : public ast::WithShortCircuiting {
     116        const ast::Type * dst;
     117        const ast::TypeEnvironment & typeEnv;
     118        int result;
     119
     120        PtrsAssignable_new( const ast::Type * dst, const ast::TypeEnvironment & env ) :
     121                dst( dst ), typeEnv( env ), result( 0 ) {}
     122
     123        void previsit( Type * ) { visit_children = false; }
     124
     125        void postvisit( const ast::EnumInstType * ) {
     126                if ( dynamic_cast< const ast::BasicType * >( dst ) ) {
     127                        // int * = E *, etc. is safe. This isn't technically correct, as each
     128                        // enum has one basic type that it is compatible with, an that type can
     129                        // differ from enum to enum. Without replicating GCC's internal logic,
     130                        // there is no way to know which type this particular enum is compatible
     131                        // with, so punt on this for now.
     132                        result = 1;
     133                }
     134        }
     135        void postvisit( const ast::TypeInstType * inst ) {
     136                if ( const ast::EqvClass * eqv = typeEnv.lookup( inst->name ) ) {
     137                        if ( eqv->bound ) {
     138                                // T * = S * for any S depends on the type bound to T
     139                                result = ptrsAssignable( eqv->bound, dst, typeEnv );
     140                        }
     141                }
     142        }
     143};
     144
     145int ptrsAssignable( const ast::Type * src, const ast::Type * dst,
     146                const ast::TypeEnvironment & env ) {
     147        if ( const ast::TypeInstType * dstAsInst = dynamic_cast< const ast::TypeInstType * >( dst ) ) {
     148                if ( const ast::EqvClass * eqv = env.lookup( dstAsInst->name ) ) {
     149                        return ptrsAssignable( src, eqv->bound, env );
     150                }
     151        }
     152        if ( dynamic_cast< const ast::VoidType * >( dst ) ) {
     153                return -1;
     154        } else {
     155                ast::Pass<PtrsAssignable_new> visitor( dst, env );
     156                src->accept( visitor );
     157                return visitor.pass.result;
     158        }
     159
     160// see ticket #136 (this should be able to replace the visitor).
     161#if 0
     162        if ( const ast::TypeInstType * dstAsTypeInst =
     163                        dynamic_cast< const ast::TypeInstType* >( dst ) ) {
     164                if ( const ast::EqvClass * eqv = env.lookup( dstAsTypeInst->get_name() ) ) {
     165                        return ptrsAssignable( src, eqv->type, env );
     166                } // if
     167        } // if
     168        if ( dynamic_cast< VoidType* >( dst ) ) {
     169                // void * = T * for any T is unsafe
     170                // xxx - this should be safe, but that currently breaks the build
     171                return -1;
     172        } else if ( dynamic_cast< EnumInstType * >( src ) ) {
     173                if ( dynamic_cast< BasicType * >( dst ) ) {
     174                        // int * = E *, etc. is safe. This isn't technically correct, as each
     175                        // enum has one basic type that it is compatible with, an that type can
     176                        // differ from enum to enum. Without replicating GCC's internal logic,
     177                        // there is no way to know which type this particular enum is compatible
     178                        // with, so punt on this for now.
     179                        return 1;
     180                }
     181        } else if ( const ast::TypeInstType * typeInstType =
     182                        dynamic_cast< const ast::TypeInstType * >( src ) ) {
     183                if ( const ast::EqvClass * eqv = env.lookup( typeInstType->name ) ) {
     184                        if ( eqv->bound ) {
     185                                // T * = S * for any S depends on the type bound to T
     186                                return ptrsAssignable( eqv->bound, dst, env );
     187                        }
     188                }
     189        }
     190        return 0;
     191#endif
     192}
    108193
    109194} // namespace ResolvExpr
  • src/ResolvExpr/PtrsCastable.cc

    r7951100 rb067d9b  
    1414//
    1515
     16#include "AST/Decl.hpp"
     17#include "AST/Pass.hpp"
     18#include "AST/Type.hpp"
     19#include "AST/TypeEnvironment.hpp"
    1620#include "Common/PassVisitor.h"
    1721#include "ResolvExpr/TypeEnvironment.h"  // for EqvClass, TypeEnvironment
     
    2327
    2428namespace ResolvExpr {
    25         struct PtrsCastable : public WithShortCircuiting  {
     29        struct PtrsCastable_old : public WithShortCircuiting  {
    2630          public:
    27                 PtrsCastable( Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer );
     31                PtrsCastable_old( const Type * dest, const TypeEnvironment &env, const SymTab::Indexer &indexer );
    2832
    2933                int get_result() const { return result; }
    3034
    31                 void previsit( Type * ) { visit_children = false; }
    32 
    33                 void postvisit( VoidType * voidType );
    34                 void postvisit( BasicType * basicType );
    35                 void postvisit( PointerType * pointerType );
    36                 void postvisit( ArrayType * arrayType );
    37                 void postvisit( FunctionType * functionType );
    38                 void postvisit( StructInstType * inst );
    39                 void postvisit( UnionInstType * inst );
    40                 void postvisit( EnumInstType * inst );
    41                 void postvisit( TraitInstType * inst );
    42                 void postvisit( TypeInstType * inst );
    43                 void postvisit( TupleType * tupleType );
    44                 void postvisit( VarArgsType * varArgsType );
    45                 void postvisit( ZeroType * zeroType );
    46                 void postvisit( OneType * oneType );
     35                void previsit( const Type * ) { visit_children = false; }
     36
     37                void postvisit( const VoidType * voidType );
     38                void postvisit( const BasicType * basicType );
     39                void postvisit( const PointerType * pointerType );
     40                void postvisit( const ArrayType * arrayType );
     41                void postvisit( const FunctionType * functionType );
     42                void postvisit( const StructInstType * inst );
     43                void postvisit( const UnionInstType * inst );
     44                void postvisit( const EnumInstType * inst );
     45                void postvisit( const TraitInstType * inst );
     46                void postvisit( const TypeInstType * inst );
     47                void postvisit( const TupleType * tupleType );
     48                void postvisit( const VarArgsType * varArgsType );
     49                void postvisit( const ZeroType * zeroType );
     50                void postvisit( const OneType * oneType );
    4751          private:
    48                 Type *dest;
     52                const Type * dest;
    4953                int result;
    5054                const TypeEnvironment &env;
     
    5357
    5458        namespace {
    55                 int objectCast( Type *src, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
    56                         if ( dynamic_cast< FunctionType* >( src ) ) {
     59                int objectCast( const Type * src, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
     60                        if ( dynamic_cast< const FunctionType* >( src ) ) {
    5761                                return -1;
    58                         } else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( src ) ) {
    59                                 if ( NamedTypeDecl *ntDecl = indexer.lookupType( typeInst->get_name() ) ) {
    60                                         if ( TypeDecl *tyDecl = dynamic_cast< TypeDecl* >( ntDecl ) ) {
    61                                                 if ( tyDecl->get_kind() == TypeDecl::Ftype ) {
     62                        } else if ( const TypeInstType * typeInst = dynamic_cast< const TypeInstType* >( src ) ) {
     63                                if ( const NamedTypeDecl * ntDecl = indexer.lookupType( typeInst->name ) ) {
     64                                        if ( const TypeDecl * tyDecl = dynamic_cast< const TypeDecl* >( ntDecl ) ) {
     65                                                if ( tyDecl->kind == TypeDecl::Ftype ) {
    6266                                                        return -1;
    6367                                                } // if
    6468                                        } //if
    65                                 } else if ( const EqvClass *eqvClass = env.lookup( typeInst->get_name() ) ) {
     69                                } else if ( const EqvClass * eqvClass = env.lookup( typeInst->get_name() ) ) {
    6670                                        if ( eqvClass->data.kind == TypeDecl::Ftype ) {
    6771                                                return -1;
     
    7175                        return 1;
    7276                }
    73                 int functionCast( Type *src, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
     77                int functionCast( const Type * src, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
    7478                        return -1 * objectCast( src, env, indexer );  // reverse the sense of objectCast
    7579                }
    7680        }
    7781
    78         int ptrsCastable( Type *src, Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
    79                 if ( TypeInstType *destAsTypeInst = dynamic_cast< TypeInstType* >( dest ) ) {
    80                         if ( const EqvClass *eqvClass = env.lookup( destAsTypeInst->get_name() ) ) {
     82        int ptrsCastable( const Type * src, const Type * dest, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
     83                if ( const TypeInstType * destAsTypeInst = dynamic_cast< const TypeInstType* >( dest ) ) {
     84                        if ( const EqvClass * eqvClass = env.lookup( destAsTypeInst->get_name() ) ) {
    8185                                // xxx - should this be ptrsCastable?
    8286                                return ptrsAssignable( src, eqvClass->type, env );
    8387                        } // if
    8488                } // if
    85                 if ( dynamic_cast< VoidType* >( dest ) ) {
     89                if ( dynamic_cast< const VoidType* >( dest ) ) {
    8690                        return objectCast( src, env, indexer );
    8791                } else {
    88                         PassVisitor<PtrsCastable> ptrs( dest, env, indexer );
     92                        PassVisitor<PtrsCastable_old> ptrs( dest, env, indexer );
    8993                        src->accept( ptrs );
    9094                        return ptrs.pass.get_result();
     
    9296        }
    9397
    94         PtrsCastable::PtrsCastable( Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer )
     98        PtrsCastable_old::PtrsCastable_old( const Type * dest, const TypeEnvironment &env, const SymTab::Indexer &indexer )
    9599                : dest( dest ), result( 0 ), env( env ), indexer( indexer )     {
    96100        }
    97101
    98         void PtrsCastable::postvisit( VoidType * ) {
    99                 result = objectCast( dest, env, indexer );
    100         }
    101 
    102         void PtrsCastable::postvisit( BasicType * ) {
    103                 result = objectCast( dest, env, indexer );
    104         }
    105 
    106         void PtrsCastable::postvisit( PointerType * ) {
    107                 result = objectCast( dest, env, indexer );
    108         }
    109 
    110         void PtrsCastable::postvisit( ArrayType * ) {
    111                 result = objectCast( dest, env, indexer );
    112         }
    113 
    114         void PtrsCastable::postvisit( FunctionType * ) {
     102        void PtrsCastable_old::postvisit( const VoidType * ) {
     103                result = objectCast( dest, env, indexer );
     104        }
     105
     106        void PtrsCastable_old::postvisit( const BasicType * ) {
     107                result = objectCast( dest, env, indexer );
     108        }
     109
     110        void PtrsCastable_old::postvisit( const PointerType * ) {
     111                result = objectCast( dest, env, indexer );
     112        }
     113
     114        void PtrsCastable_old::postvisit( const ArrayType * ) {
     115                result = objectCast( dest, env, indexer );
     116        }
     117
     118        void PtrsCastable_old::postvisit( const FunctionType * ) {
    115119                // result = -1;
    116120                result = functionCast( dest, env, indexer );
    117121        }
    118122
    119         void PtrsCastable::postvisit( StructInstType * ) {
    120                 result = objectCast( dest, env, indexer );
    121         }
    122 
    123         void PtrsCastable::postvisit( UnionInstType * ) {
    124                 result = objectCast( dest, env, indexer );
    125         }
    126 
    127         void PtrsCastable::postvisit( EnumInstType * ) {
    128                 if ( dynamic_cast< EnumInstType* >( dest ) ) {
     123        void PtrsCastable_old::postvisit( const StructInstType * ) {
     124                result = objectCast( dest, env, indexer );
     125        }
     126
     127        void PtrsCastable_old::postvisit( const UnionInstType * ) {
     128                result = objectCast( dest, env, indexer );
     129        }
     130
     131        void PtrsCastable_old::postvisit( const EnumInstType * ) {
     132                if ( dynamic_cast< const EnumInstType * >( dest ) ) {
    129133                        result = 1;
    130                 } else if ( BasicType *bt = dynamic_cast< BasicType* >( dest ) ) {
    131                         if ( bt->get_kind() == BasicType::SignedInt ) {
     134                } else if ( const BasicType * bt = dynamic_cast< const BasicType * >( dest ) ) {
     135                        if ( bt->kind == BasicType::SignedInt ) {
    132136                                result = 0;
    133137                        } else {
     
    139143        }
    140144
    141         void PtrsCastable::postvisit( TraitInstType * ) {}
    142 
    143         void PtrsCastable::postvisit(TypeInstType *inst) {
     145        void PtrsCastable_old::postvisit( const TraitInstType * ) {}
     146
     147        void PtrsCastable_old::postvisit( const TypeInstType *inst ) {
    144148                //result = objectCast( inst, env, indexer ) > 0 && objectCast( dest, env, indexer ) > 0 ? 1 : -1;
    145149                result = objectCast( inst, env, indexer ) == objectCast( dest, env, indexer ) ? 1 : -1;
    146150        }
    147151
    148         void PtrsCastable::postvisit( TupleType * ) {
    149                 result = objectCast( dest, env, indexer );
    150         }
    151 
    152         void PtrsCastable::postvisit( VarArgsType * ) {
    153                 result = objectCast( dest, env, indexer );
    154         }
    155 
    156         void PtrsCastable::postvisit( ZeroType * ) {
    157                 result = objectCast( dest, env, indexer );
    158         }
    159 
    160         void PtrsCastable::postvisit( OneType * ) {
    161                 result = objectCast( dest, env, indexer );
    162         }
     152        void PtrsCastable_old::postvisit( const TupleType * ) {
     153                result = objectCast( dest, env, indexer );
     154        }
     155
     156        void PtrsCastable_old::postvisit( const VarArgsType * ) {
     157                result = objectCast( dest, env, indexer );
     158        }
     159
     160        void PtrsCastable_old::postvisit( const ZeroType * ) {
     161                result = objectCast( dest, env, indexer );
     162        }
     163
     164        void PtrsCastable_old::postvisit( const OneType * ) {
     165                result = objectCast( dest, env, indexer );
     166        }
     167
     168namespace {
     169        // can this type be cast to an object (1 for yes, -1 for no)
     170        int objectCast(
     171                const ast::Type * src, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab
     172        ) {
     173                if ( dynamic_cast< const ast::FunctionType * >( src ) ) {
     174                        return -1;
     175                } else if ( auto inst = dynamic_cast< const ast::TypeInstType * >( src ) ) {
     176                        if ( const ast::NamedTypeDecl * named = symtab.lookupType( inst->name ) ) {
     177                                if ( auto tyDecl = dynamic_cast< const ast::TypeDecl * >( named ) ) {
     178                                        if ( tyDecl->kind == ast::TypeVar::Ftype ) {
     179                                                return -1;
     180                                        }
     181                                }
     182                        } else if ( const ast::EqvClass * eqvClass = env.lookup( inst->name ) ) {
     183                                if ( eqvClass->data.kind == ast::TypeVar::Ftype ) {
     184                                        return -1;
     185                                }
     186                        }
     187                }
     188
     189                return 1;
     190        }
     191
     192        // can this type be cast to a function (inverse of objectCast)
     193        int functionCast(
     194                const ast::Type * src, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab
     195        ) {
     196                return -1 * objectCast( src, env, symtab );
     197        }
     198
     199        class PtrsCastable_new : public ast::WithShortCircuiting {
     200                const ast::Type * dst;
     201                const ast::TypeEnvironment & env;
     202                const ast::SymbolTable & symtab;
     203        public:
     204                int result;
     205
     206                PtrsCastable_new(
     207                        const ast::Type * d, const ast::TypeEnvironment & e, const ast::SymbolTable & syms )
     208                : dst( d ), env( e ), symtab( syms ), result( 0 ) {}
     209
     210                void previsit( const ast::Type * ) { visit_children = false; }
     211
     212                void postvisit( const ast::VoidType * ) {
     213                        result = objectCast( dst, env, symtab );
     214                }
     215
     216                void postvisit( const ast::BasicType * ) {
     217                        result = objectCast( dst, env, symtab );
     218                }
     219
     220                void postvisit( const ast::PointerType * ) {
     221                        result = objectCast( dst, env, symtab );
     222                }
     223
     224                void postvisit( const ast::ArrayType * ) {
     225                        result = objectCast( dst, env, symtab );
     226                }
     227
     228                void postvisit( const ast::FunctionType * ) {
     229                        result = functionCast( dst, env, symtab );
     230                }
     231
     232                void postvisit( const ast::StructInstType * ) {
     233                        result = objectCast( dst, env, symtab );
     234                }
     235
     236                void postvisit( const ast::UnionInstType * ) {
     237                        result = objectCast( dst, env, symtab );
     238                }
     239
     240                void postvisit( const ast::EnumInstType * ) {
     241                        if ( dynamic_cast< const ast::EnumInstType * >( dst ) ) {
     242                                result = 1;
     243                        } else if ( auto bt = dynamic_cast< const ast::BasicType * >( dst ) ) {
     244                                if ( bt->kind == ast::BasicType::SignedInt ) {
     245                                        result = 0;
     246                                } else {
     247                                        result = 1;
     248                                }
     249                        } else {
     250                                result = objectCast( dst, env, symtab );
     251                        }
     252                }
     253
     254                void postvisit( const ast::TraitInstType * ) {}
     255
     256                void postvisit( const ast::TypeInstType * inst ) {
     257                        // check trait and destination type are both object or both function
     258                        result = objectCast( inst, env, symtab ) == objectCast( dst, env, symtab ) ? 1 : -1;
     259                }
     260
     261                void postvisit( const ast::TupleType * ) {
     262                        result = objectCast( dst, env, symtab );
     263                }
     264
     265                void postvisit( const ast::VarArgsType * ) {
     266                        result = objectCast( dst, env, symtab );
     267                }
     268
     269                void postvisit( const ast::ZeroType * ) {
     270                        result = objectCast( dst, env, symtab );
     271                }
     272
     273                void postvisit( const ast::OneType * ) {
     274                        result = objectCast( dst, env, symtab );
     275                }
     276
     277        };
     278} // anonymous namespace
     279
     280int ptrsCastable(
     281        const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab,
     282        const ast::TypeEnvironment & env
     283) {
     284        if ( auto inst = dynamic_cast< const ast::TypeInstType * >( dst ) ) {
     285                if ( const ast::EqvClass * eqvClass = env.lookup( inst->name ) ) {
     286                        return ptrsAssignable( src, eqvClass->bound, env );
     287                }
     288        }
     289
     290        if ( dynamic_cast< const ast::VoidType * >( dst ) ) {
     291                return objectCast( src, env, symtab );
     292        } else {
     293                ast::Pass< PtrsCastable_new > ptrs{ dst, env, symtab };
     294                src->accept( ptrs );
     295                return ptrs.pass.result;
     296        }
     297}
     298
    163299} // namespace ResolvExpr
    164300
  • src/ResolvExpr/RenameVars.cc

    r7951100 rb067d9b  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 12:05:18 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Mar  2 17:36:32 2016
    13 // Update Count     : 5
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Thr Jun 20 17:39:00 2019
     13// Update Count     : 8
    1414//
    1515
     
    1919#include <utility>                 // for pair
    2020
     21#include "AST/Pass.hpp"
     22#include "AST/Type.hpp"
    2123#include "Common/PassVisitor.h"
     24#include "Common/ScopedMap.h"
    2225#include "Common/SemanticError.h"  // for SemanticError
    2326#include "RenameVars.h"
     
    2831
    2932namespace ResolvExpr {
    30         namespace {
    31                 struct RenameVars {
    32                         RenameVars();
    33                         void reset();
    3433
    35                         void previsit( TypeInstType * instType );
    36                         void previsit( Type * );
    37                         void postvisit( Type * );
     34namespace {
     35        class RenamingData {
     36                int level = 0;
     37                int resetCount = 0;
     38                ScopedMap< std::string, std::string > nameMap;
    3839
    39                   private:
    40                         int level, resetCount;
    41                         std::list< std::map< std::string, std::string > > mapStack;
    42                 };
    43 
    44                 PassVisitor<RenameVars> global_renamer;
    45         } // namespace
    46 
    47         void renameTyVars( Type * t ) {
    48                 t->accept( global_renamer );
    49         }
    50 
    51         void resetTyVarRenaming() {
    52                 global_renamer.pass.reset();
    53         }
    54 
    55         namespace {
    56                 RenameVars::RenameVars() : level( 0 ), resetCount( 0 ) {
    57                         mapStack.push_front( std::map< std::string, std::string >() );
     40        public:
     41                void reset() {
     42                        level = 0;
     43                        ++resetCount;
    5844                }
    5945
    60                 void RenameVars::reset() {
    61                         level = 0;
    62                         resetCount++;
     46                using mapConstIterator = ScopedMap< std::string, std::string >::const_iterator;
     47
     48                void rename( TypeInstType * type ) {
     49                        mapConstIterator it = nameMap.find( type->name );
     50                        if ( it != nameMap.end() ) {
     51                                type->name = it->second;
     52                        }
    6353                }
    6454
    65                 void RenameVars::previsit( TypeInstType * instType ) {
    66                         previsit( (Type *)instType );
    67                         std::map< std::string, std::string >::const_iterator i = mapStack.front().find( instType->name );
    68                         if ( i != mapStack.front().end() ) {
    69                                 instType->name = i->second;
    70                         } // if
    71                 }
    72 
    73                 void RenameVars::previsit( Type * type ) {
     55                void openLevel( Type * type ) {
    7456                        if ( ! type->forall.empty() ) {
    75                                 // copies current name mapping into new mapping
    76                                 mapStack.push_front( mapStack.front() );
     57                                nameMap.beginScope();
    7758                                // renames all "forall" type names to `_${level}_${name}'
    7859                                for ( auto td : type->forall ) {
     
    8061                                        output << "_" << resetCount << "_" << level << "_" << td->name;
    8162                                        std::string newname( output.str() );
    82                                         mapStack.front()[ td->get_name() ] = newname;
     63                                        nameMap[ td->get_name() ] = newname;
    8364                                        td->name = newname;
    8465                                        // ditto for assertion names, the next level in
     
    8970                }
    9071
    91                 void RenameVars::postvisit( Type * type ) {
    92                         // clears name mapping added by typeBefore()
    93                         if ( ! type->forall.empty() ) {
    94                                 mapStack.pop_front();
    95                         } // if
     72                void closeLevel( Type * type ) {
     73                        if ( !type->forall.empty() ) {
     74                                nameMap.endScope();
     75                        }
    9676                }
    97         } // namespace
     77
     78                const ast::TypeInstType * rename( const ast::TypeInstType * type ) {
     79                        mapConstIterator it = nameMap.find( type->name );
     80                        if ( it != nameMap.end() ) {
     81                                ast::TypeInstType * mutType = ast::mutate( type );
     82                                mutType->name = it->second;
     83                    type = mutType;
     84                        }
     85                        return type;
     86                }
     87
     88                template<typename NodeT>
     89                const NodeT * openLevel( const NodeT * type ) {
     90                        if ( !type->forall.empty() ) {
     91                                nameMap.beginScope();
     92                                // Load new names from this forall clause and perform renaming.
     93                                NodeT * mutType = ast::mutate( type );
     94                                for ( ast::ptr< ast::TypeDecl > & td : mutType->forall ) {
     95                                        std::ostringstream output;
     96                                        output << "_" << resetCount << "_" << level << "_" << td->name;
     97                                        std::string newname( output.str() );
     98                                        nameMap[ td->name ] = newname;
     99                                        ++level;
     100
     101                                        ast::TypeDecl * decl = ast::mutate( td.get() );
     102                                        decl->name = newname;
     103                                        td = decl;
     104                                }
     105                        }
     106                        return type;
     107                }
     108
     109                template<typename NodeT>
     110                const NodeT * closeLevel( const NodeT * type ) {
     111                        if ( !type->forall.empty() ) {
     112                                nameMap.endScope();
     113                        }
     114                        return type;
     115                }
     116        };
     117
     118        // Global State:
     119        RenamingData renaming;
     120
     121        struct RenameVars {
     122                void previsit( TypeInstType * instType ) {
     123                        renaming.openLevel( (Type*)instType );
     124                        renaming.rename( instType );
     125                }
     126                void previsit( Type * type ) {
     127                        renaming.openLevel( type );
     128                }
     129                void postvisit( Type * type ) {
     130                        renaming.closeLevel( type );
     131                }
     132
     133                const ast::FunctionType * previsit( const ast::FunctionType * type ) {
     134                        return renaming.openLevel( type );
     135                }
     136                const ast::StructInstType * previsit( const ast::StructInstType * type ) {
     137                        return renaming.openLevel( type );
     138                }
     139                const ast::UnionInstType * previsit( const ast::UnionInstType * type ) {
     140                        return renaming.openLevel( type );
     141                }
     142                const ast::TraitInstType * previsit( const ast::TraitInstType * type ) {
     143                        return renaming.openLevel( type );
     144                }
     145                const ast::TypeInstType * previsit( const ast::TypeInstType * type ) {
     146                        return renaming.rename( renaming.openLevel( type ) );
     147                }
     148                const ast::ParameterizedType * postvisit( const ast::ParameterizedType * type ) {
     149                        return renaming.closeLevel( type );
     150                }
     151        };
     152
     153} // namespace
     154
     155void renameTyVars( Type * t ) {
     156        PassVisitor<RenameVars> renamer;
     157        t->accept( renamer );
     158}
     159
     160const ast::Type * renameTyVars( const ast::Type * t ) {
     161        ast::Pass<RenameVars> renamer;
     162        return t->accept( renamer );
     163}
     164
     165void resetTyVarRenaming() {
     166        renaming.reset();
     167}
     168
    98169} // namespace ResolvExpr
    99170
  • src/ResolvExpr/RenameVars.h

    r7951100 rb067d9b  
    2323#include "SynTree/Visitor.h"  // for Visitor
    2424
     25namespace ast {
     26        class Type;
     27}
     28
    2529namespace ResolvExpr {
    2630        /// Provides a consistent renaming of forall type names in a hierarchy by prefixing them with a unique "level" ID
    2731        void renameTyVars( Type * );
     32        const ast::Type * renameTyVars( const ast::Type * );
    2833
    2934        /// resets internal state of renamer to avoid overflow
  • src/ResolvExpr/ResolveTypeof.cc

    r7951100 rb067d9b  
    1818#include <cassert>               // for assert
    1919
     20#include "AST/CVQualifiers.hpp"
     21#include "AST/Node.hpp"
     22#include "AST/Pass.hpp"
     23#include "AST/Type.hpp"
     24#include "AST/TypeEnvironment.hpp"
    2025#include "Common/PassVisitor.h"  // for PassVisitor
     26#include "Common/utility.h"      // for copy
    2127#include "Resolver.h"            // for resolveInVoidContext
    2228#include "SynTree/Expression.h"  // for Expression
     
    4248        }
    4349
    44         class ResolveTypeof : public WithShortCircuiting {
     50        class ResolveTypeof_old : public WithShortCircuiting {
    4551          public:
    46                 ResolveTypeof( const SymTab::Indexer &indexer ) : indexer( indexer ) {}
     52                ResolveTypeof_old( const SymTab::Indexer &indexer ) : indexer( indexer ) {}
    4753                void premutate( TypeofType *typeofType );
    4854                Type * postmutate( TypeofType *typeofType );
     
    5359
    5460        Type * resolveTypeof( Type *type, const SymTab::Indexer &indexer ) {
    55                 PassVisitor<ResolveTypeof> mutator( indexer );
     61                PassVisitor<ResolveTypeof_old> mutator( indexer );
    5662                return type->acceptMutator( mutator );
    5763        }
    5864
    59         void ResolveTypeof::premutate( TypeofType * ) {
     65        void ResolveTypeof_old::premutate( TypeofType * ) {
    6066                visit_children = false;
    6167        }
    6268
    63         Type * ResolveTypeof::postmutate( TypeofType *typeofType ) {
     69        Type * ResolveTypeof_old::postmutate( TypeofType *typeofType ) {
    6470#if 0
    6571                std::cerr << "resolving typeof: ";
     
    6773                std::cerr << std::endl;
    6874#endif
    69                 if ( typeofType->expr ) {
     75                // pass on null expression
     76                if ( ! typeofType->expr ) return typeofType;
     77
     78                bool isBasetypeof = typeofType->is_basetypeof;
     79                auto oldQuals = typeofType->get_qualifiers().val;
     80
     81                Type* newType;
     82                if ( TypeExpr* tyExpr = dynamic_cast<TypeExpr*>(typeofType->expr) ) {
     83                        // typeof wrapping type
     84                        newType = tyExpr->type;
     85                        tyExpr->type = nullptr;
     86                        delete tyExpr;
     87                } else {
     88                        // typeof wrapping expression
    7089                        Expression * newExpr = resolveInVoidContext( typeofType->expr, indexer );
    7190                        assert( newExpr->result && ! newExpr->result->isVoid() );
    72                         Type * newType = newExpr->result;
     91                        newType = newExpr->result;
    7392                        newExpr->result = nullptr;
    7493                        delete typeofType;
    7594                        delete newExpr;
     95                }
     96
     97                // clear qualifiers for base, combine with typeoftype quals in any case
     98                if ( isBasetypeof ) {
     99                        // replace basetypeof(<enum>) by int
     100                        if ( dynamic_cast<EnumInstType*>(newType) ) {
     101                                Type* newerType =
     102                                        new BasicType{ newType->get_qualifiers(), BasicType::SignedInt,
     103                                        newType->attributes };
     104                                delete newType;
     105                                newType = newerType;
     106                        }
     107                        newType->get_qualifiers().val
     108                                = ( newType->get_qualifiers().val & ~Type::Qualifiers::Mask ) | oldQuals;
     109                } else {
     110                        newType->get_qualifiers().val |= oldQuals;
     111                }
     112               
     113                return newType;
     114        }
     115
     116namespace {
     117        struct ResolveTypeof_new : public ast::WithShortCircuiting {
     118                const ast::SymbolTable & localSymtab;
     119
     120                ResolveTypeof_new( const ast::SymbolTable & syms ) : localSymtab( syms ) {}
     121
     122                void premutate( const ast::TypeofType * ) { visit_children = false; }
     123
     124                const ast::Type * postmutate( const ast::TypeofType * typeofType ) {
     125                        // pass on null expression
     126                        if ( ! typeofType->expr ) return typeofType;
     127
     128                        ast::ptr< ast::Type > newType;
     129                        if ( auto tyExpr = typeofType->expr.as< ast::TypeExpr >() ) {
     130                                // typeof wrapping type
     131                                newType = tyExpr->type;
     132                        } else {
     133                                // typeof wrapping expression
     134                                ast::TypeEnvironment dummy;
     135                                ast::ptr< ast::Expr > newExpr =
     136                                        resolveInVoidContext( typeofType->expr, localSymtab, dummy );
     137                                assert( newExpr->result && ! newExpr->result->isVoid() );
     138                                newType = newExpr->result;
     139                        }
     140
     141                        // clear qualifiers for base, combine with typeoftype quals regardless
     142                        if ( typeofType->kind == ast::TypeofType::Basetypeof ) {
     143                                // replace basetypeof(<enum>) by int
     144                                if ( newType.as< ast::EnumInstType >() ) {
     145                                        newType = new ast::BasicType{
     146                                                ast::BasicType::SignedInt, newType->qualifiers, copy(newType->attributes) };
     147                                }
     148                                reset_qualifiers(
     149                                        newType,
     150                                        ( newType->qualifiers & ~ast::CV::EquivQualifiers ) | typeofType->qualifiers );
     151                        } else {
     152                                add_qualifiers( newType, typeofType->qualifiers );
     153                        }
     154
    76155                        return newType;
    77                 } // if
    78                 return typeofType;
    79         }
     156                }
     157        };
     158} // anonymous namespace
     159
     160const ast::Type * resolveTypeof( const ast::Type * type , const ast::SymbolTable & symtab ) {
     161        ast::Pass< ResolveTypeof_new > mutator{ symtab };
     162        return type->accept( mutator );
     163}
     164
    80165} // namespace ResolvExpr
    81166
  • src/ResolvExpr/ResolveTypeof.h

    r7951100 rb067d9b  
    2020class Indexer;
    2121}  // namespace SymTab
     22namespace ast {
     23        class Type;
     24        class SymbolTable;
     25}
    2226
    2327namespace ResolvExpr {
    2428        Type *resolveTypeof( Type*, const SymTab::Indexer &indexer );
     29        const ast::Type * resolveTypeof( const ast::Type *, const ast::SymbolTable & );
    2530} // namespace ResolvExpr
    2631
  • src/ResolvExpr/Resolver.cc

    r7951100 rb067d9b  
    77// Resolver.cc --
    88//
    9 // Author           : Richard C. Bilson
     9// Author           : Aaron B. Moss
    1010// Created On       : Sun May 17 12:17:01 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Feb 17 11:19:40 2018
    13 // Update Count     : 213
     11// Last Modified By : Aaron B. Moss
     12// Last Modified On : Wed May 29 11:00:00 2019
     13// Update Count     : 241
    1414//
    1515
    16 #include <stddef.h>                      // for NULL
    1716#include <cassert>                       // for strict_dynamic_cast, assert
    1817#include <memory>                        // for allocator, allocator_traits<...
    1918#include <tuple>                         // for get
    20 #include <vector>
     19#include <vector>                        // for vector
    2120
    2221#include "Alternative.h"                 // for Alternative, AltList
    2322#include "AlternativeFinder.h"           // for AlternativeFinder, resolveIn...
     23#include "Candidate.hpp"
     24#include "CandidateFinder.hpp"
     25#include "CurrentObject.h"               // for CurrentObject
     26#include "RenameVars.h"                  // for RenameVars, global_renamer
     27#include "Resolver.h"
     28#include "ResolvMode.h"                  // for ResolvMode
     29#include "typeops.h"                     // for extractResultType
     30#include "Unify.h"                       // for unify
     31#include "AST/Chain.hpp"
     32#include "AST/Decl.hpp"
     33#include "AST/Init.hpp"
     34#include "AST/Pass.hpp"
     35#include "AST/Print.hpp"
     36#include "AST/SymbolTable.hpp"
     37#include "AST/Type.hpp"
    2438#include "Common/PassVisitor.h"          // for PassVisitor
    2539#include "Common/SemanticError.h"        // for SemanticError
    2640#include "Common/utility.h"              // for ValueGuard, group_iterate
    27 #include "CurrentObject.h"               // for CurrentObject
    2841#include "InitTweak/GenInit.h"
    2942#include "InitTweak/InitTweak.h"         // for isIntrinsicSingleArgCallStmt
    30 #include "RenameVars.h"                  // for RenameVars, global_renamer
    3143#include "ResolvExpr/TypeEnvironment.h"  // for TypeEnvironment
    32 #include "ResolveTypeof.h"               // for resolveTypeof
    33 #include "Resolver.h"
    3444#include "SymTab/Autogen.h"              // for SizeType
    3545#include "SymTab/Indexer.h"              // for Indexer
     
    4252#include "SynTree/Visitor.h"             // for acceptAll, maybeAccept
    4353#include "Tuples/Tuples.h"
    44 #include "typeops.h"                     // for extractResultType
    45 #include "Unify.h"                       // for unify
     54#include "Validate/FindSpecialDecls.h"   // for SizeType
    4655
    4756using namespace std;
    4857
    4958namespace ResolvExpr {
    50         struct Resolver final : public WithIndexer, public WithGuards, public WithVisitorRef<Resolver>, public WithShortCircuiting, public WithStmtsToAdd {
    51                 Resolver() {}
    52                 Resolver( const SymTab::Indexer & other ) {
     59        struct Resolver_old final : public WithIndexer, public WithGuards, public WithVisitorRef<Resolver_old>, public WithShortCircuiting, public WithStmtsToAdd {
     60                Resolver_old() {}
     61                Resolver_old( const SymTab::Indexer & other ) {
    5362                        indexer = other;
    5463                }
    5564
    56                 void previsit( FunctionDecl *functionDecl );
    57                 void postvisit( FunctionDecl *functionDecl );
    58                 void previsit( ObjectDecl *objectDecll );
    59                 void previsit( TypeDecl *typeDecl );
     65                void previsit( FunctionDecl * functionDecl );
     66                void postvisit( FunctionDecl * functionDecl );
     67                void previsit( ObjectDecl * objectDecll );
    6068                void previsit( EnumDecl * enumDecl );
    6169                void previsit( StaticAssertDecl * assertDecl );
     
    6472                void previsit( PointerType * at );
    6573
    66                 void previsit( ExprStmt *exprStmt );
    67                 void previsit( AsmExpr *asmExpr );
    68                 void previsit( AsmStmt *asmStmt );
    69                 void previsit( IfStmt *ifStmt );
    70                 void previsit( WhileStmt *whileStmt );
    71                 void previsit( ForStmt *forStmt );
    72                 void previsit( SwitchStmt *switchStmt );
    73                 void previsit( CaseStmt *caseStmt );
    74                 void previsit( BranchStmt *branchStmt );
    75                 void previsit( ReturnStmt *returnStmt );
    76                 void previsit( ThrowStmt *throwStmt );
    77                 void previsit( CatchStmt *catchStmt );
     74                void previsit( ExprStmt * exprStmt );
     75                void previsit( AsmExpr * asmExpr );
     76                void previsit( AsmStmt * asmStmt );
     77                void previsit( IfStmt * ifStmt );
     78                void previsit( WhileStmt * whileStmt );
     79                void previsit( ForStmt * forStmt );
     80                void previsit( SwitchStmt * switchStmt );
     81                void previsit( CaseStmt * caseStmt );
     82                void previsit( BranchStmt * branchStmt );
     83                void previsit( ReturnStmt * returnStmt );
     84                void previsit( ThrowStmt * throwStmt );
     85                void previsit( CatchStmt * catchStmt );
    7886                void previsit( WaitForStmt * stmt );
    79                 void previsit( WithStmt * withStmt );
    80 
    81                 void previsit( SingleInit *singleInit );
    82                 void previsit( ListInit *listInit );
    83                 void previsit( ConstructorInit *ctorInit );
     87
     88                void previsit( SingleInit * singleInit );
     89                void previsit( ListInit * listInit );
     90                void previsit( ConstructorInit * ctorInit );
    8491          private:
    8592                typedef std::list< Initializer * >::iterator InitIterator;
     
    8895                void handlePtrType( PtrType * type );
    8996
    90                 void resolveWithExprs( std::list< Expression * > & withExprs, std::list< Statement * > & newStmts );
    9197                void fallbackInit( ConstructorInit * ctorInit );
    9298
     
    96102        };
    97103
     104        struct ResolveWithExprs : public WithIndexer, public WithGuards, public WithVisitorRef<ResolveWithExprs>, public WithShortCircuiting, public WithStmtsToAdd {
     105                void previsit( FunctionDecl * );
     106                void previsit( WithStmt * );
     107
     108                void resolveWithExprs( std::list< Expression * > & withExprs, std::list< Statement * > & newStmts );
     109        };
     110
    98111        void resolve( std::list< Declaration * > translationUnit ) {
    99                 PassVisitor<Resolver> resolver;
     112                PassVisitor<Resolver_old> resolver;
    100113                acceptAll( translationUnit, resolver );
    101114        }
    102115
    103         void resolveDecl( Declaration * decl, const SymTab::Indexer &indexer ) {
    104                 PassVisitor<Resolver> resolver( indexer );
     116        void resolveDecl( Declaration * decl, const SymTab::Indexer & indexer ) {
     117                PassVisitor<Resolver_old> resolver( indexer );
    105118                maybeAccept( decl, resolver );
    106119        }
    107120
    108121        namespace {
    109                 struct DeleteFinder : public WithShortCircuiting        {
     122                struct DeleteFinder_old : public WithShortCircuiting    {
    110123                        DeletedExpr * delExpr = nullptr;
    111124                        void previsit( DeletedExpr * expr ) {
     
    121134
    122135        DeletedExpr * findDeletedExpr( Expression * expr ) {
    123                 PassVisitor<DeleteFinder> finder;
     136                PassVisitor<DeleteFinder_old> finder;
    124137                expr->accept( finder );
    125138                return finder.pass.delExpr;
     
    127140
    128141        namespace {
    129                 struct StripCasts {
     142                struct StripCasts_old {
    130143                        Expression * postmutate( CastExpr * castExpr ) {
    131144                                if ( castExpr->isGenerated && ResolvExpr::typesCompatible( castExpr->arg->result, castExpr->result, SymTab::Indexer() ) ) {
     
    140153
    141154                        static void strip( Expression *& expr ) {
    142                                 PassVisitor<StripCasts> stripper;
     155                                PassVisitor<StripCasts_old> stripper;
    143156                                expr = expr->acceptMutator( stripper );
    144157                        }
    145158                };
    146159
    147                 void finishExpr( Expression *&expr, const TypeEnvironment &env, TypeSubstitution * oldenv = nullptr ) {
     160                void finishExpr( Expression *& expr, const TypeEnvironment & env, TypeSubstitution * oldenv = nullptr ) {
    148161                        expr->env = oldenv ? oldenv->clone() : new TypeSubstitution;
    149162                        env.makeSubstitution( *expr->env );
    150                         StripCasts::strip( expr ); // remove unnecessary casts that may be buried in an expression
     163                        StripCasts_old::strip( expr ); // remove unnecessary casts that may be buried in an expression
    151164                }
    152165
    153166                void removeExtraneousCast( Expression *& expr, const SymTab::Indexer & indexer ) {
    154167                        if ( CastExpr * castExpr = dynamic_cast< CastExpr * >( expr ) ) {
    155                                 if ( ResolvExpr::typesCompatible( castExpr->arg->result, castExpr->result, indexer ) ) {
     168                                if ( typesCompatible( castExpr->arg->result, castExpr->result, indexer ) ) {
    156169                                        // cast is to the same type as its argument, so it's unnecessary -- remove it
    157170                                        expr = castExpr->arg;
     
    165178
    166179        namespace {
    167                 void findUnfinishedKindExpression(Expression * untyped, Alternative & alt, const SymTab::Indexer & indexer, const std::string & kindStr, std::function<bool(const Alternative &)> pred, bool adjust = false, bool prune = true, bool failFast = true) {
     180                void findUnfinishedKindExpression(Expression * untyped, Alternative & alt, const SymTab::Indexer & indexer, const std::string & kindStr, std::function<bool(const Alternative &)> pred, ResolvMode mode = ResolvMode{} ) {
    168181                        assertf( untyped, "expected a non-null expression." );
     182
     183                        // xxx - this isn't thread-safe, but should work until we parallelize the resolver
     184                        static unsigned recursion_level = 0;
     185
     186                        ++recursion_level;
    169187                        TypeEnvironment env;
    170188                        AlternativeFinder finder( indexer, env );
    171                         finder.find( untyped, adjust, prune, failFast );
     189                        finder.find( untyped, recursion_level == 1 ? mode.atTopLevel() : mode );
     190                        --recursion_level;
    172191
    173192                        #if 0
     
    182201                        #endif
    183202
     203                        // produce filtered list of alternatives
    184204                        AltList candidates;
    185205                        for ( Alternative & alt : finder.get_alternatives() ) {
     
    189209                        }
    190210
    191                         // xxx - if > 1 alternative with same cost, ignore deleted and pick from remaining
    192                         // choose the lowest cost expression among the candidates
     211                        // produce invalid error if no candidates
     212                        if ( candidates.empty() ) {
     213                                SemanticError( untyped, toString( "No reasonable alternatives for ", kindStr, (kindStr != "" ? " " : ""), "expression: ") );
     214                        }
     215
     216                        // search for cheapest candidate
    193217                        AltList winners;
    194                         findMinCost( candidates.begin(), candidates.end(), back_inserter( winners ) );
    195                         if ( winners.size() == 0 ) {
    196                                 SemanticError( untyped, toString( "No reasonable alternatives for ", kindStr, (kindStr != "" ? " " : ""), "expression: ") );
    197                         } else if ( winners.size() != 1 ) {
     218                        bool seen_undeleted = false;
     219                        for ( unsigned i = 0; i < candidates.size(); ++i ) {
     220                                int c = winners.empty() ? -1 : candidates[i].cost.compare( winners.front().cost );
     221
     222                                if ( c > 0 ) continue; // skip more expensive than winner
     223
     224                                if ( c < 0 ) {
     225                                        // reset on new cheapest
     226                                        seen_undeleted = ! findDeletedExpr( candidates[i].expr );
     227                                        winners.clear();
     228                                } else /* if ( c == 0 ) */ {
     229                                        if ( findDeletedExpr( candidates[i].expr ) ) {
     230                                                // skip deleted expression if already seen one equivalent-cost not
     231                                                if ( seen_undeleted ) continue;
     232                                        } else if ( ! seen_undeleted ) {
     233                                                // replace list of equivalent-cost deleted expressions with one non-deleted
     234                                                winners.clear();
     235                                                seen_undeleted = true;
     236                                        }
     237                                }
     238
     239                                winners.emplace_back( std::move( candidates[i] ) );
     240                        }
     241
     242                        // promote alternative.cvtCost to .cost
     243                        // xxx - I don't know why this is done, but I'm keeping the behaviour from findMinCost
     244                        for ( Alternative& winner : winners ) {
     245                                winner.cost = winner.cvtCost;
     246                        }
     247
     248                        // produce ambiguous errors, if applicable
     249                        if ( winners.size() != 1 ) {
    198250                                std::ostringstream stream;
    199251                                stream << "Cannot choose between " << winners.size() << " alternatives for " << kindStr << (kindStr != "" ? " " : "") << "expression\n";
     
    204256                        }
    205257
    206                         // there is one unambiguous interpretation - move the expression into the with statement
    207                         Alternative & choice = winners.front();
    208                         if ( findDeletedExpr( choice.expr ) ) {
     258                        // single selected choice
     259                        Alternative& choice = winners.front();
     260
     261                        // fail on only expression deleted
     262                        if ( ! seen_undeleted ) {
    209263                                SemanticError( untyped->location, choice.expr, "Unique best alternative includes deleted identifier in " );
    210264                        }
     265
     266                        // xxx - check for ambiguous expressions
     267
     268                        // output selected choice
    211269                        alt = std::move( choice );
    212270                }
    213271
    214272                /// resolve `untyped` to the expression whose alternative satisfies `pred` with the lowest cost; kindStr is used for providing better error messages
    215                 void findKindExpression(Expression *& untyped, const SymTab::Indexer & indexer, const std::string & kindStr, std::function<bool(const Alternative &)> pred, bool adjust = false, bool prune = true, bool failFast = true) {
     273                void findKindExpression(Expression *& untyped, const SymTab::Indexer & indexer, const std::string & kindStr, std::function<bool(const Alternative &)> pred, ResolvMode mode = ResolvMode{}) {
    216274                        if ( ! untyped ) return;
    217275                        Alternative choice;
    218                         findUnfinishedKindExpression( untyped, choice, indexer, kindStr, pred, adjust, prune, failFast );
     276                        findUnfinishedKindExpression( untyped, choice, indexer, kindStr, pred, mode );
    219277                        finishExpr( choice.expr, choice.env, untyped->env );
    220278                        delete untyped;
     
    231289
    232290        // used in resolveTypeof
    233         Expression * resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer ) {
     291        Expression * resolveInVoidContext( Expression * expr, const SymTab::Indexer & indexer ) {
    234292                TypeEnvironment env;
    235293                return resolveInVoidContext( expr, indexer, env );
    236294        }
    237295
    238         Expression * resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer, TypeEnvironment &env ) {
     296        Expression * resolveInVoidContext( Expression * expr, const SymTab::Indexer & indexer, TypeEnvironment & env ) {
    239297                // it's a property of the language that a cast expression has either 1 or 0 interpretations; if it has 0
    240298                // interpretations, an exception has already been thrown.
    241299                assertf( expr, "expected a non-null expression." );
    242300
    243                 static CastExpr untyped( nullptr ); // cast to void
    244                 untyped.location = expr->location;
     301                CastExpr * untyped = new CastExpr( expr ); // cast to void
     302                untyped->location = expr->location;
    245303
    246304                // set up and resolve expression cast to void
    247                 untyped.arg = expr;
    248305                Alternative choice;
    249                 findUnfinishedKindExpression( &untyped, choice, indexer, "", standardAlternativeFilter, true );
     306                findUnfinishedKindExpression( untyped, choice, indexer, "", standardAlternativeFilter, ResolvMode::withAdjustment() );
    250307                CastExpr * castExpr = strict_dynamic_cast< CastExpr * >( choice.expr );
     308                assert( castExpr );
    251309                env = std::move( choice.env );
    252310
     
    256314
    257315                // unlink the arg so that it isn't deleted twice at the end of the program
    258                 untyped.arg = nullptr;
     316                untyped->arg = nullptr;
    259317                return ret;
    260318        }
    261319
    262         void findVoidExpression( Expression *& untyped, const SymTab::Indexer &indexer ) {
     320        void findVoidExpression( Expression *& untyped, const SymTab::Indexer & indexer ) {
    263321                resetTyVarRenaming();
    264322                TypeEnvironment env;
     
    269327        }
    270328
    271         void findSingleExpression( Expression *&untyped, const SymTab::Indexer &indexer ) {
     329        void findSingleExpression( Expression *& untyped, const SymTab::Indexer & indexer ) {
    272330                findKindExpression( untyped, indexer, "", standardAlternativeFilter );
    273331        }
     
    288346                        if ( dynamic_cast< EnumInstType * >( type ) ) {
    289347                                return true;
    290                         } else if ( BasicType *bt = dynamic_cast< BasicType * >( type ) ) {
     348                        } else if ( BasicType * bt = dynamic_cast< BasicType * >( type ) ) {
    291349                                return bt->isInteger();
    292350                        } else if ( dynamic_cast< ZeroType* >( type ) != nullptr || dynamic_cast< OneType* >( type ) != nullptr ) {
     
    297355                }
    298356
    299                 void findIntegralExpression( Expression *& untyped, const SymTab::Indexer &indexer ) {
     357                void findIntegralExpression( Expression *& untyped, const SymTab::Indexer & indexer ) {
    300358                        findKindExpression( untyped, indexer, "condition", isIntegralType );
    301359                }
    302360        }
    303361
    304         void Resolver::previsit( ObjectDecl *objectDecl ) {
    305                 Type *new_type = resolveTypeof( objectDecl->get_type(), indexer );
    306                 objectDecl->set_type( new_type );
    307                 // To handle initialization of routine pointers, e.g., int (*fp)(int) = foo(), means that class-variable
    308                 // initContext is changed multiple time because the LHS is analysed twice. The second analysis changes
    309                 // initContext because of a function type can contain object declarations in the return and parameter types. So
    310                 // each value of initContext is retained, so the type on the first analysis is preserved and used for selecting
    311                 // the RHS.
    312                 GuardValue( currentObject );
    313                 currentObject = CurrentObject( objectDecl->get_type() );
    314                 if ( inEnumDecl && dynamic_cast< EnumInstType * >( objectDecl->get_type() ) ) {
    315                         // enumerator initializers should not use the enum type to initialize, since
    316                         // the enum type is still incomplete at this point. Use signed int instead.
    317                         currentObject = CurrentObject( new BasicType( Type::Qualifiers(), BasicType::SignedInt ) );
    318                 }
    319         }
    320 
    321         template< typename PtrType >
    322         void Resolver::handlePtrType( PtrType * type ) {
    323                 if ( type->get_dimension() ) {
    324                         findSingleExpression( type->dimension, SymTab::SizeType->clone(), indexer );
    325                 }
    326         }
    327 
    328         void Resolver::previsit( ArrayType * at ) {
    329                 handlePtrType( at );
    330         }
    331 
    332         void Resolver::previsit( PointerType * pt ) {
    333                 handlePtrType( pt );
    334         }
    335 
    336         void Resolver::previsit( TypeDecl *typeDecl ) {
    337                 if ( typeDecl->get_base() ) {
    338                         Type *new_type = resolveTypeof( typeDecl->get_base(), indexer );
    339                         typeDecl->set_base( new_type );
    340                 } // if
    341         }
    342 
    343         void Resolver::previsit( FunctionDecl *functionDecl ) {
    344 #if 0
    345                 std::cerr << "resolver visiting functiondecl ";
    346                 functionDecl->print( std::cerr );
    347                 std::cerr << std::endl;
    348 #endif
    349                 Type *new_type = resolveTypeof( functionDecl->type, indexer );
    350                 functionDecl->set_type( new_type );
    351                 GuardValue( functionReturn );
    352                 functionReturn = ResolvExpr::extractResultType( functionDecl->type );
    353 
     362
     363        bool isStructOrUnion( const Alternative & alt ) {
     364                Type * t = alt.expr->result->stripReferences();
     365                return dynamic_cast< StructInstType * >( t ) || dynamic_cast< UnionInstType * >( t );
     366        }
     367
     368        void resolveWithExprs( std::list< Declaration * > & translationUnit ) {
     369                PassVisitor<ResolveWithExprs> resolver;
     370                acceptAll( translationUnit, resolver );
     371        }
     372
     373        void ResolveWithExprs::resolveWithExprs( std::list< Expression * > & withExprs, std::list< Statement * > & newStmts ) {
     374                for ( Expression *& expr : withExprs )  {
     375                        // only struct- and union-typed expressions are viable candidates
     376                        findKindExpression( expr, indexer, "with statement", isStructOrUnion );
     377
     378                        // if with expression might be impure, create a temporary so that it is evaluated once
     379                        if ( Tuples::maybeImpure( expr ) ) {
     380                                static UniqueName tmpNamer( "_with_tmp_" );
     381                                ObjectDecl * tmp = ObjectDecl::newObject( tmpNamer.newName(), expr->result->clone(), new SingleInit( expr ) );
     382                                expr = new VariableExpr( tmp );
     383                                newStmts.push_back( new DeclStmt( tmp ) );
     384                                if ( InitTweak::isConstructable( tmp->type ) ) {
     385                                        // generate ctor/dtor and resolve them
     386                                        tmp->init = InitTweak::genCtorInit( tmp );
     387                                        tmp->accept( *visitor );
     388                                }
     389                        }
     390                }
     391        }
     392
     393        void ResolveWithExprs::previsit( WithStmt * withStmt ) {
     394                resolveWithExprs( withStmt->exprs, stmtsToAddBefore );
     395        }
     396
     397        void ResolveWithExprs::previsit( FunctionDecl * functionDecl ) {
    354398                {
    355399                        // resolve with-exprs with parameters in scope and add any newly generated declarations to the
     
    367411        }
    368412
    369         void Resolver::postvisit( FunctionDecl *functionDecl ) {
    370                 // default value expressions have an environment which shouldn't be there and trips up later passes.
    371                 // xxx - it might be necessary to somehow keep the information from this environment, but I can't currently
    372                 // see how it's useful.
     413        void Resolver_old::previsit( ObjectDecl * objectDecl ) {
     414                // To handle initialization of routine pointers, e.g., int (*fp)(int) = foo(), means that
     415                // class-variable initContext is changed multiple time because the LHS is analysed twice.
     416                // The second analysis changes initContext because of a function type can contain object
     417                // declarations in the return and parameter types. So each value of initContext is
     418                // retained, so the type on the first analysis is preserved and used for selecting the RHS.
     419                GuardValue( currentObject );
     420                currentObject = CurrentObject( objectDecl->get_type() );
     421                if ( inEnumDecl && dynamic_cast< EnumInstType * >( objectDecl->get_type() ) ) {
     422                        // enumerator initializers should not use the enum type to initialize, since
     423                        // the enum type is still incomplete at this point. Use signed int instead.
     424                        currentObject = CurrentObject( new BasicType( Type::Qualifiers(), BasicType::SignedInt ) );
     425                }
     426        }
     427
     428        template< typename PtrType >
     429        void Resolver_old::handlePtrType( PtrType * type ) {
     430                if ( type->get_dimension() ) {
     431                        findSingleExpression( type->dimension, Validate::SizeType->clone(), indexer );
     432                }
     433        }
     434
     435        void Resolver_old::previsit( ArrayType * at ) {
     436                handlePtrType( at );
     437        }
     438
     439        void Resolver_old::previsit( PointerType * pt ) {
     440                handlePtrType( pt );
     441        }
     442
     443        void Resolver_old::previsit( FunctionDecl * functionDecl ) {
     444#if 0
     445                std::cerr << "resolver visiting functiondecl ";
     446                functionDecl->print( std::cerr );
     447                std::cerr << std::endl;
     448#endif
     449                GuardValue( functionReturn );
     450                functionReturn = ResolvExpr::extractResultType( functionDecl->type );
     451        }
     452
     453        void Resolver_old::postvisit( FunctionDecl * functionDecl ) {
     454                // default value expressions have an environment which shouldn't be there and trips up
     455                // later passes.
     456                // xxx - it might be necessary to somehow keep the information from this environment, but I
     457                // can't currently see how it's useful.
    373458                for ( Declaration * d : functionDecl->type->parameters ) {
    374459                        if ( ObjectDecl * obj = dynamic_cast< ObjectDecl * >( d ) ) {
     
    381466        }
    382467
    383         void Resolver::previsit( EnumDecl * ) {
     468        void Resolver_old::previsit( EnumDecl * ) {
    384469                // in case we decide to allow nested enums
    385470                GuardValue( inEnumDecl );
     
    387472        }
    388473
    389         void Resolver::previsit( StaticAssertDecl * assertDecl ) {
     474        void Resolver_old::previsit( StaticAssertDecl * assertDecl ) {
    390475                findIntegralExpression( assertDecl->condition, indexer );
    391476        }
    392477
    393         void Resolver::previsit( ExprStmt *exprStmt ) {
     478        void Resolver_old::previsit( ExprStmt * exprStmt ) {
    394479                visit_children = false;
    395480                assertf( exprStmt->expr, "ExprStmt has null Expression in resolver" );
     
    397482        }
    398483
    399         void Resolver::previsit( AsmExpr *asmExpr ) {
     484        void Resolver_old::previsit( AsmExpr * asmExpr ) {
    400485                visit_children = false;
    401486                findVoidExpression( asmExpr->operand, indexer );
     
    405490        }
    406491
    407         void Resolver::previsit( AsmStmt *asmStmt ) {
     492        void Resolver_old::previsit( AsmStmt * asmStmt ) {
    408493                visit_children = false;
    409494                acceptAll( asmStmt->get_input(), *visitor );
     
    411496        }
    412497
    413         void Resolver::previsit( IfStmt *ifStmt ) {
     498        void Resolver_old::previsit( IfStmt * ifStmt ) {
    414499                findIntegralExpression( ifStmt->condition, indexer );
    415500        }
    416501
    417         void Resolver::previsit( WhileStmt *whileStmt ) {
     502        void Resolver_old::previsit( WhileStmt * whileStmt ) {
    418503                findIntegralExpression( whileStmt->condition, indexer );
    419504        }
    420505
    421         void Resolver::previsit( ForStmt *forStmt ) {
     506        void Resolver_old::previsit( ForStmt * forStmt ) {
    422507                if ( forStmt->condition ) {
    423508                        findIntegralExpression( forStmt->condition, indexer );
     
    429514        }
    430515
    431         void Resolver::previsit( SwitchStmt *switchStmt ) {
     516        void Resolver_old::previsit( SwitchStmt * switchStmt ) {
    432517                GuardValue( currentObject );
    433518                findIntegralExpression( switchStmt->condition, indexer );
     
    436521        }
    437522
    438         void Resolver::previsit( CaseStmt *caseStmt ) {
     523        void Resolver_old::previsit( CaseStmt * caseStmt ) {
    439524                if ( caseStmt->condition ) {
    440525                        std::list< InitAlternative > initAlts = currentObject.getOptions();
     
    455540        }
    456541
    457         void Resolver::previsit( BranchStmt *branchStmt ) {
     542        void Resolver_old::previsit( BranchStmt * branchStmt ) {
    458543                visit_children = false;
    459544                // must resolve the argument for a computed goto
     
    466551        }
    467552
    468         void Resolver::previsit( ReturnStmt *returnStmt ) {
     553        void Resolver_old::previsit( ReturnStmt * returnStmt ) {
    469554                visit_children = false;
    470555                if ( returnStmt->expr ) {
     
    473558        }
    474559
    475         void Resolver::previsit( ThrowStmt *throwStmt ) {
     560        void Resolver_old::previsit( ThrowStmt * throwStmt ) {
    476561                visit_children = false;
    477562                // TODO: Replace *exception type with &exception type.
    478563                if ( throwStmt->get_expr() ) {
    479                         StructDecl * exception_decl =
    480                                 indexer.lookupStruct( "__cfaabi_ehm__base_exception_t" );
     564                        const StructDecl * exception_decl = indexer.lookupStruct( "__cfaabi_ehm__base_exception_t" );
    481565                        assert( exception_decl );
    482                         Type * exceptType = new PointerType( noQualifiers, new StructInstType( noQualifiers, exception_decl ) );
     566                        Type * exceptType = new PointerType( noQualifiers, new StructInstType( noQualifiers, const_cast<StructDecl *>(exception_decl) ) );
    483567                        findSingleExpression( throwStmt->expr, exceptType, indexer );
    484568                }
    485569        }
    486570
    487         void Resolver::previsit( CatchStmt *catchStmt ) {
     571        void Resolver_old::previsit( CatchStmt * catchStmt ) {
    488572                if ( catchStmt->cond ) {
    489573                        findSingleExpression( catchStmt->cond, new BasicType( noQualifiers, BasicType::Bool ), indexer );
     
    500584        }
    501585
    502         void Resolver::previsit( WaitForStmt * stmt ) {
     586        void Resolver_old::previsit( WaitForStmt * stmt ) {
    503587                visit_children = false;
    504588
     
    582666
    583667                                                        // Make sure we don't widen any existing bindings
    584                                                         for ( auto & i : resultEnv ) {
    585                                                                 i.allowWidening = false;
    586                                                         }
     668                                                        resultEnv.forbidWidening();
    587669
    588670                                                        // Find any unbound type variables
     
    592674                                                        auto param_end = function->parameters.end();
    593675
    594                                                         int n_mutex_arg = 0;
     676                                                        int n_mutex_param = 0;
    595677
    596678                                                        // For every arguments of its set, check if it matches one of the parameter
     
    602684                                                                        // We ran out of parameters but still have arguments
    603685                                                                        // this function doesn't match
    604                                                                         SemanticError( function, toString("candidate function not viable: too many mutex arguments, expected ", n_mutex_arg, "\n" ));
     686                                                                        SemanticError( function, toString("candidate function not viable: too many mutex arguments, expected ", n_mutex_param, "\n" ));
    605687                                                                }
    606688
    607                                                                 n_mutex_arg++;
     689                                                                n_mutex_param++;
    608690
    609691                                                                // Check if the argument matches the parameter type in the current scope
     
    628710                                                        // Check if parameters are missing
    629711                                                        if( advance_to_mutex( param, param_end ) ) {
     712                                                                do {
     713                                                                        n_mutex_param++;
     714                                                                        param++;
     715                                                                } while( advance_to_mutex( param, param_end ) );
     716
    630717                                                                // We ran out of arguments but still have parameters left
    631718                                                                // this function doesn't match
    632                                                                 SemanticError( function, toString("candidate function not viable: too few mutex arguments, expected ", n_mutex_arg, "\n" ));
     719                                                                SemanticError( function, toString("candidate function not viable: too few mutex arguments, expected ", n_mutex_param, "\n" ));
    633720                                                        }
    634721
     
    646733
    647734                                                }
    648                                                 catch( SemanticErrorException &e ) {
     735                                                catch( SemanticErrorException & e ) {
    649736                                                        errors.append( e );
    650737                                                }
    651738                                        }
    652739                                }
    653                                 catch( SemanticErrorException &e ) {
     740                                catch( SemanticErrorException & e ) {
    654741                                        errors.append( e );
    655742                                }
     
    694781        }
    695782
    696         bool isStructOrUnion( const Alternative & alt ) {
    697                 Type * t = alt.expr->result->stripReferences();
    698                 return dynamic_cast< StructInstType * >( t ) || dynamic_cast< UnionInstType * >( t );
    699         }
    700 
    701         void Resolver::resolveWithExprs( std::list< Expression * > & withExprs, std::list< Statement * > & newStmts ) {
    702                 for ( Expression *& expr : withExprs )  {
    703                         // only struct- and union-typed expressions are viable candidates
    704                         findKindExpression( expr, indexer, "with statement", isStructOrUnion );
    705 
    706                         // if with expression might be impure, create a temporary so that it is evaluated once
    707                         if ( Tuples::maybeImpure( expr ) ) {
    708                                 static UniqueName tmpNamer( "_with_tmp_" );
    709                                 ObjectDecl * tmp = ObjectDecl::newObject( tmpNamer.newName(), expr->result->clone(), new SingleInit( expr ) );
    710                                 expr = new VariableExpr( tmp );
    711                                 newStmts.push_back( new DeclStmt( tmp ) );
    712                                 if ( InitTweak::isConstructable( tmp->type ) ) {
    713                                         // generate ctor/dtor and resolve them
    714                                         tmp->init = InitTweak::genCtorInit( tmp );
    715                                         tmp->accept( *visitor );
    716                                 }
    717                         }
    718                 }
    719         }
    720 
    721         void Resolver::previsit( WithStmt * withStmt ) {
    722                 resolveWithExprs( withStmt->exprs, stmtsToAddBefore );
    723         }
    724 
    725         template< typename T >
    726         bool isCharType( T t ) {
     783        bool isCharType( Type * t ) {
    727784                if ( BasicType * bt = dynamic_cast< BasicType * >( t ) ) {
    728785                        return bt->get_kind() == BasicType::Char || bt->get_kind() == BasicType::SignedChar ||
     
    732789        }
    733790
    734         void Resolver::previsit( SingleInit *singleInit ) {
     791        void Resolver_old::previsit( SingleInit * singleInit ) {
    735792                visit_children = false;
    736793                // resolve initialization using the possibilities as determined by the currentObject cursor
     
    746803                initExpr->expr = nullptr;
    747804                std::swap( initExpr->env, newExpr->env );
    748                 // InitExpr may have inferParams in the case where the expression specializes a function pointer,
    749                 // and newExpr may already have inferParams of its own, so a simple swap is not sufficient.
     805                // InitExpr may have inferParams in the case where the expression specializes a function
     806                // pointer, and newExpr may already have inferParams of its own, so a simple swap is not
     807                // sufficient.
    750808                newExpr->spliceInferParams( initExpr );
    751809                delete initExpr;
    752810
    753                 // get the actual object's type (may not exactly match what comes back from the resolver due to conversions)
     811                // get the actual object's type (may not exactly match what comes back from the resolver
     812                // due to conversions)
    754813                Type * initContext = currentObject.getCurrentType();
    755814
     
    762821                                if ( PointerType * pt = dynamic_cast< PointerType *>( newExpr->get_result() ) ) {
    763822                                        if ( isCharType( pt->get_base() ) ) {
    764                                                 if ( CastExpr *ce = dynamic_cast< CastExpr * >( newExpr ) ) {
    765                                                         // strip cast if we're initializing a char[] with a char *, e.g.  char x[] = "hello";
     823                                                if ( CastExpr * ce = dynamic_cast< CastExpr * >( newExpr ) ) {
     824                                                        // strip cast if we're initializing a char[] with a char *,
     825                                                        // e.g.  char x[] = "hello";
    766826                                                        newExpr = ce->get_arg();
    767827                                                        ce->set_arg( nullptr );
     
    781841        }
    782842
    783         void Resolver::previsit( ListInit * listInit ) {
     843        void Resolver_old::previsit( ListInit * listInit ) {
    784844                visit_children = false;
    785845                // move cursor into brace-enclosed initializer-list
    786846                currentObject.enterListInit();
    787                 // xxx - fix this so that the list isn't copied, iterator should be used to change current element
     847                // xxx - fix this so that the list isn't copied, iterator should be used to change current
     848                // element
    788849                std::list<Designation *> newDesignations;
    789850                for ( auto p : group_iterate(listInit->get_designations(), listInit->get_initializers()) ) {
    790                         // iterate designations and initializers in pairs, moving the cursor to the current designated object and resolving
    791                         // the initializer against that object.
     851                        // iterate designations and initializers in pairs, moving the cursor to the current
     852                        // designated object and resolving the initializer against that object.
    792853                        Designation * des = std::get<0>(p);
    793854                        Initializer * init = std::get<1>(p);
     
    815876
    816877        // ConstructorInit - fall back on C-style initializer
    817         void Resolver::fallbackInit( ConstructorInit * ctorInit ) {
     878        void Resolver_old::fallbackInit( ConstructorInit * ctorInit ) {
    818879                // could not find valid constructor, or found an intrinsic constructor
    819880                // fall back on C-style initializer
    820881                delete ctorInit->get_ctor();
    821                 ctorInit->set_ctor( NULL );
     882                ctorInit->set_ctor( nullptr );
    822883                delete ctorInit->get_dtor();
    823                 ctorInit->set_dtor( NULL );
     884                ctorInit->set_dtor( nullptr );
    824885                maybeAccept( ctorInit->get_init(), *visitor );
    825886        }
     
    828889        void resolveCtorInit( ConstructorInit * ctorInit, const SymTab::Indexer & indexer ) {
    829890                assert( ctorInit );
    830                 PassVisitor<Resolver> resolver( indexer );
     891                PassVisitor<Resolver_old> resolver( indexer );
    831892                ctorInit->accept( resolver );
    832893        }
     
    834895        void resolveStmtExpr( StmtExpr * stmtExpr, const SymTab::Indexer & indexer ) {
    835896                assert( stmtExpr );
    836                 PassVisitor<Resolver> resolver( indexer );
     897                PassVisitor<Resolver_old> resolver( indexer );
    837898                stmtExpr->accept( resolver );
    838899                stmtExpr->computeResult();
     
    840901        }
    841902
    842         void Resolver::previsit( ConstructorInit *ctorInit ) {
     903        void Resolver_old::previsit( ConstructorInit * ctorInit ) {
    843904                visit_children = false;
    844905                // xxx - fallback init has been removed => remove fallbackInit function and remove complexity from FixInit and remove C-init from ConstructorInit
     
    864925
    865926                // xxx - todo -- what about arrays?
    866                 // if ( dtor == NULL && InitTweak::isIntrinsicCallStmt( ctorInit->get_ctor() ) ) {
     927                // if ( dtor == nullptr && InitTweak::isIntrinsicCallStmt( ctorInit->get_ctor() ) ) {
    867928                //      // can reduce the constructor down to a SingleInit using the
    868929                //      // second argument from the ctor call, since
    869930                //      delete ctorInit->get_ctor();
    870                 //      ctorInit->set_ctor( NULL );
     931                //      ctorInit->set_ctor( nullptr );
    871932
    872933                //      Expression * arg =
     
    874935                // }
    875936        }
     937
     938        ///////////////////////////////////////////////////////////////////////////
     939        //
     940        // *** NEW RESOLVER ***
     941        //
     942        ///////////////////////////////////////////////////////////////////////////
     943
     944        namespace {
     945                /// Finds deleted expressions in an expression tree
     946                struct DeleteFinder_new final : public ast::WithShortCircuiting {
     947                        const ast::DeletedExpr * delExpr = nullptr;
     948
     949                        void previsit( const ast::DeletedExpr * expr ) {
     950                                if ( delExpr ) { visit_children = false; }
     951                                else { delExpr = expr; }
     952                        }
     953
     954                        void previsit( const ast::Expr * ) {
     955                                if ( delExpr ) { visit_children = false; }
     956                        }
     957                };
     958        } // anonymous namespace
     959
     960        /// Check if this expression is or includes a deleted expression
     961        const ast::DeletedExpr * findDeletedExpr( const ast::Expr * expr ) {
     962                ast::Pass<DeleteFinder_new> finder;
     963                expr->accept( finder );
     964                return finder.pass.delExpr;
     965        }
     966
     967        namespace {
     968                /// always-accept candidate filter
     969                bool anyCandidate( const Candidate & ) { return true; }
     970
     971                /// Calls the CandidateFinder and finds the single best candidate
     972                CandidateRef findUnfinishedKindExpression(
     973                        const ast::Expr * untyped, const ast::SymbolTable & symtab, const std::string & kind,
     974                        std::function<bool(const Candidate &)> pred = anyCandidate, ResolvMode mode = {}
     975                ) {
     976                        if ( ! untyped ) return nullptr;
     977
     978                        // xxx - this isn't thread-safe, but should work until we parallelize the resolver
     979                        static unsigned recursion_level = 0;
     980
     981                        ++recursion_level;
     982                        ast::TypeEnvironment env;
     983                        CandidateFinder finder{ symtab, env };
     984                        finder.find( untyped, recursion_level == 1 ? mode.atTopLevel() : mode );
     985                        --recursion_level;
     986
     987                        // produce a filtered list of candidates
     988                        CandidateList candidates;
     989                        for ( auto & cand : finder.candidates ) {
     990                                if ( pred( *cand ) ) { candidates.emplace_back( cand ); }
     991                        }
     992
     993                        // produce invalid error if no candidates
     994                        if ( candidates.empty() ) {
     995                                SemanticError( untyped,
     996                                        toString( "No reasonable alternatives for ", kind, (kind != "" ? " " : ""),
     997                                        "expression: ") );
     998                        }
     999
     1000                        // search for cheapest candidate
     1001                        CandidateList winners;
     1002                        bool seen_undeleted = false;
     1003                        for ( CandidateRef & cand : candidates ) {
     1004                                int c = winners.empty() ? -1 : cand->cost.compare( winners.front()->cost );
     1005
     1006                                if ( c > 0 ) continue;  // skip more expensive than winner
     1007
     1008                                if ( c < 0 ) {
     1009                                        // reset on new cheapest
     1010                                        seen_undeleted = ! findDeletedExpr( cand->expr );
     1011                                        winners.clear();
     1012                                } else /* if ( c == 0 ) */ {
     1013                                        if ( findDeletedExpr( cand->expr ) ) {
     1014                                                // skip deleted expression if already seen one equivalent-cost not
     1015                                                if ( seen_undeleted ) continue;
     1016                                        } else if ( ! seen_undeleted ) {
     1017                                                // replace list of equivalent-cost deleted expressions with one non-deleted
     1018                                                winners.clear();
     1019                                                seen_undeleted = true;
     1020                                        }
     1021                                }
     1022
     1023                                winners.emplace_back( std::move( cand ) );
     1024                        }
     1025
     1026                        // promote candidate.cvtCost to .cost
     1027                        promoteCvtCost( winners );
     1028
     1029                        // produce ambiguous errors, if applicable
     1030                        if ( winners.size() != 1 ) {
     1031                                std::ostringstream stream;
     1032                                stream << "Cannot choose between " << winners.size() << " alternatives for "
     1033                                        << kind << (kind != "" ? " " : "") << "expression\n";
     1034                                ast::print( stream, untyped );
     1035                                stream << " Alternatives are:\n";
     1036                                print( stream, winners, 1 );
     1037                                SemanticError( untyped->location, stream.str() );
     1038                        }
     1039
     1040                        // single selected choice
     1041                        CandidateRef & choice = winners.front();
     1042
     1043                        // fail on only expression deleted
     1044                        if ( ! seen_undeleted ) {
     1045                                SemanticError( untyped->location, choice->expr.get(), "Unique best alternative "
     1046                                "includes deleted identifier in " );
     1047                        }
     1048
     1049                        return std::move( choice );
     1050                }
     1051
     1052                /// Strips extraneous casts out of an expression
     1053                struct StripCasts_new final {
     1054                        const ast::Expr * postmutate( const ast::CastExpr * castExpr ) {
     1055                                if (
     1056                                        castExpr->isGenerated
     1057                                        && typesCompatible( castExpr->arg->result, castExpr->result )
     1058                                ) {
     1059                                        // generated cast is the same type as its argument, remove it after keeping env
     1060                                        return ast::mutate_field(
     1061                                                castExpr->arg.get(), &ast::Expr::env, castExpr->env );
     1062                                }
     1063                                return castExpr;
     1064                        }
     1065
     1066                        static void strip( ast::ptr< ast::Expr > & expr ) {
     1067                                ast::Pass< StripCasts_new > stripper;
     1068                                expr = expr->accept( stripper );
     1069                        }
     1070                };
     1071
     1072                /// Swaps argument into expression pointer, saving original environment
     1073                void swap_and_save_env( ast::ptr< ast::Expr > & expr, const ast::Expr * newExpr ) {
     1074                        ast::ptr< ast::TypeSubstitution > env = expr->env;
     1075                        expr.set_and_mutate( newExpr )->env = env;
     1076                }
     1077
     1078                /// Removes cast to type of argument (unlike StripCasts, also handles non-generated casts)
     1079                void removeExtraneousCast( ast::ptr<ast::Expr> & expr, const ast::SymbolTable & symtab ) {
     1080                        if ( const ast::CastExpr * castExpr = expr.as< ast::CastExpr >() ) {
     1081                                if ( typesCompatible( castExpr->arg->result, castExpr->result, symtab ) ) {
     1082                                        // cast is to the same type as its argument, remove it
     1083                                        swap_and_save_env( expr, castExpr->arg );
     1084                                }
     1085                        }
     1086                }
     1087
     1088                /// Establish post-resolver invariants for expressions
     1089                void finishExpr(
     1090                        ast::ptr< ast::Expr > & expr, const ast::TypeEnvironment & env,
     1091                        const ast::TypeSubstitution * oldenv = nullptr
     1092                ) {
     1093                        // set up new type substitution for expression
     1094                        ast::ptr< ast::TypeSubstitution > newenv =
     1095                                 oldenv ? oldenv : new ast::TypeSubstitution{};
     1096                        env.writeToSubstitution( *newenv.get_and_mutate() );
     1097                        expr.get_and_mutate()->env = std::move( newenv );
     1098                        // remove unncecessary casts
     1099                        StripCasts_new::strip( expr );
     1100                }
     1101        } // anonymous namespace
     1102
     1103
     1104        ast::ptr< ast::Expr > resolveInVoidContext(
     1105                const ast::Expr * expr, const ast::SymbolTable & symtab, ast::TypeEnvironment & env
     1106        ) {
     1107                assertf( expr, "expected a non-null expression" );
     1108
     1109                // set up and resolve expression cast to void
     1110                ast::CastExpr * untyped = new ast::CastExpr{ expr };
     1111                CandidateRef choice = findUnfinishedKindExpression(
     1112                        untyped, symtab, "", anyCandidate, ResolvMode::withAdjustment() );
     1113
     1114                // a cast expression has either 0 or 1 interpretations (by language rules);
     1115                // if 0, an exception has already been thrown, and this code will not run
     1116                const ast::CastExpr * castExpr = choice->expr.strict_as< ast::CastExpr >();
     1117                env = std::move( choice->env );
     1118
     1119                return castExpr->arg;
     1120        }
     1121
     1122        namespace {
     1123                /// Resolve `untyped` to the expression whose candidate is the best match for a `void`
     1124                /// context.
     1125                ast::ptr< ast::Expr > findVoidExpression(
     1126                        const ast::Expr * untyped, const ast::SymbolTable & symtab
     1127                ) {
     1128                        resetTyVarRenaming();
     1129                        ast::TypeEnvironment env;
     1130                        ast::ptr< ast::Expr > newExpr = resolveInVoidContext( untyped, symtab, env );
     1131                        finishExpr( newExpr, env, untyped->env );
     1132                        return newExpr;
     1133                }
     1134
     1135                /// resolve `untyped` to the expression whose candidate satisfies `pred` with the
     1136                /// lowest cost, returning the resolved version
     1137                ast::ptr< ast::Expr > findKindExpression(
     1138                        const ast::Expr * untyped, const ast::SymbolTable & symtab,
     1139                        std::function<bool(const Candidate &)> pred = anyCandidate,
     1140                        const std::string & kind = "", ResolvMode mode = {}
     1141                ) {
     1142                        if ( ! untyped ) return {};
     1143                        CandidateRef choice =
     1144                                findUnfinishedKindExpression( untyped, symtab, kind, pred, mode );
     1145                        finishExpr( choice->expr, choice->env, untyped->env );
     1146                        return std::move( choice->expr );
     1147                }
     1148
     1149                /// Resolve `untyped` to the single expression whose candidate is the best match
     1150                ast::ptr< ast::Expr > findSingleExpression(
     1151                        const ast::Expr * untyped, const ast::SymbolTable & symtab
     1152                ) {
     1153                        return findKindExpression( untyped, symtab );
     1154                }
     1155        } // anonymous namespace
     1156
     1157                ast::ptr< ast::Expr > findSingleExpression(
     1158                        const ast::Expr * untyped, const ast::Type * type, const ast::SymbolTable & symtab
     1159                ) {
     1160                        assert( untyped && type );
     1161                        ast::ptr< ast::Expr > castExpr = new ast::CastExpr{ untyped, type };
     1162                        ast::ptr< ast::Expr > newExpr = findSingleExpression( castExpr, symtab );
     1163                        removeExtraneousCast( newExpr, symtab );
     1164                        return newExpr;
     1165                }
     1166
     1167        namespace {
     1168                /// Predicate for "Candidate has integral type"
     1169                bool hasIntegralType( const Candidate & i ) {
     1170                        const ast::Type * type = i.expr->result;
     1171
     1172                        if ( auto bt = dynamic_cast< const ast::BasicType * >( type ) ) {
     1173                                return bt->isInteger();
     1174                        } else if (
     1175                                dynamic_cast< const ast::EnumInstType * >( type )
     1176                                || dynamic_cast< const ast::ZeroType * >( type )
     1177                                || dynamic_cast< const ast::OneType * >( type )
     1178                        ) {
     1179                                return true;
     1180                        } else return false;
     1181                }
     1182
     1183                /// Resolve `untyped` as an integral expression, returning the resolved version
     1184                ast::ptr< ast::Expr > findIntegralExpression(
     1185                        const ast::Expr * untyped, const ast::SymbolTable & symtab
     1186                ) {
     1187                        return findKindExpression( untyped, symtab, hasIntegralType, "condition" );
     1188                }
     1189
     1190                /// check if a type is a character type
     1191                bool isCharType( const ast::Type * t ) {
     1192                        if ( auto bt = dynamic_cast< const ast::BasicType * >( t ) ) {
     1193                                return bt->kind == ast::BasicType::Char
     1194                                        || bt->kind == ast::BasicType::SignedChar
     1195                                        || bt->kind == ast::BasicType::UnsignedChar;
     1196                        }
     1197                        return false;
     1198                }
     1199
     1200                /// Advance a type itertor to the next mutex parameter
     1201                template<typename Iter>
     1202                inline bool nextMutex( Iter & it, const Iter & end ) {
     1203                        while ( it != end && ! (*it)->get_type()->is_mutex() ) { ++it; }
     1204                        return it != end;
     1205                }
     1206        }
     1207
     1208        class Resolver_new final
     1209        : public ast::WithSymbolTable, public ast::WithGuards,
     1210          public ast::WithVisitorRef<Resolver_new>, public ast::WithShortCircuiting,
     1211          public ast::WithStmtsToAdd<> {
     1212
     1213                ast::ptr< ast::Type > functionReturn = nullptr;
     1214                ast::CurrentObject currentObject;
     1215                bool inEnumDecl = false;
     1216
     1217        public:
     1218                Resolver_new() = default;
     1219                Resolver_new( const ast::SymbolTable & syms ) { symtab = syms; }
     1220
     1221                void previsit( const ast::FunctionDecl * );
     1222                const ast::FunctionDecl * postvisit( const ast::FunctionDecl * );
     1223                void previsit( const ast::ObjectDecl * );
     1224                void previsit( const ast::EnumDecl * );
     1225                const ast::StaticAssertDecl * previsit( const ast::StaticAssertDecl * );
     1226
     1227                const ast::ArrayType * previsit( const ast::ArrayType * );
     1228                const ast::PointerType * previsit( const ast::PointerType * );
     1229
     1230                const ast::ExprStmt *        previsit( const ast::ExprStmt * );
     1231                const ast::AsmExpr *         previsit( const ast::AsmExpr * );
     1232                const ast::AsmStmt *         previsit( const ast::AsmStmt * );
     1233                const ast::IfStmt *          previsit( const ast::IfStmt * );
     1234                const ast::WhileStmt *       previsit( const ast::WhileStmt * );
     1235                const ast::ForStmt *         previsit( const ast::ForStmt * );
     1236                const ast::SwitchStmt *      previsit( const ast::SwitchStmt * );
     1237                const ast::CaseStmt *        previsit( const ast::CaseStmt * );
     1238                const ast::BranchStmt *      previsit( const ast::BranchStmt * );
     1239                const ast::ReturnStmt *      previsit( const ast::ReturnStmt * );
     1240                const ast::ThrowStmt *       previsit( const ast::ThrowStmt * );
     1241                const ast::CatchStmt *       previsit( const ast::CatchStmt * );
     1242                const ast::WaitForStmt *     previsit( const ast::WaitForStmt * );
     1243
     1244                const ast::SingleInit *      previsit( const ast::SingleInit * );
     1245                const ast::ListInit *        previsit( const ast::ListInit * );
     1246                const ast::ConstructorInit * previsit( const ast::ConstructorInit * );
     1247        };
     1248
     1249        void resolve( std::list< ast::ptr<ast::Decl> >& translationUnit ) {
     1250                ast::Pass< Resolver_new > resolver;
     1251                accept_all( translationUnit, resolver );
     1252        }
     1253
     1254        ast::ptr< ast::Init > resolveCtorInit(
     1255                const ast::ConstructorInit * ctorInit, const ast::SymbolTable & symtab
     1256        ) {
     1257                assert( ctorInit );
     1258                ast::Pass< Resolver_new > resolver{ symtab };
     1259                return ctorInit->accept( resolver );
     1260        }
     1261
     1262        ast::ptr< ast::Expr > resolveStmtExpr(
     1263                const ast::StmtExpr * stmtExpr, const ast::SymbolTable & symtab
     1264        ) {
     1265                assert( stmtExpr );
     1266                ast::Pass< Resolver_new > resolver{ symtab };
     1267                ast::ptr< ast::Expr > ret = stmtExpr;
     1268                ret = ret->accept( resolver );
     1269                strict_dynamic_cast< ast::StmtExpr * >( ret.get_and_mutate() )->computeResult();
     1270                return ret;
     1271        }
     1272
     1273        void Resolver_new::previsit( const ast::FunctionDecl * functionDecl ) {
     1274                GuardValue( functionReturn );
     1275                functionReturn = extractResultType( functionDecl->type );
     1276        }
     1277
     1278        const ast::FunctionDecl * Resolver_new::postvisit( const ast::FunctionDecl * functionDecl ) {
     1279                // default value expressions have an environment which shouldn't be there and trips up
     1280                // later passes.
     1281                ast::ptr< ast::FunctionDecl > ret = functionDecl;
     1282                for ( unsigned i = 0; i < functionDecl->type->params.size(); ++i ) {
     1283                        const ast::ptr<ast::DeclWithType> & d = functionDecl->type->params[i];
     1284
     1285                        if ( const ast::ObjectDecl * obj = d.as< ast::ObjectDecl >() ) {
     1286                                if ( const ast::SingleInit * init = obj->init.as< ast::SingleInit >() ) {
     1287                                        if ( init->value->env == nullptr ) continue;
     1288                                        // clone initializer minus the initializer environment
     1289                                        ast::chain_mutate( ret )
     1290                                                ( &ast::FunctionDecl::type )
     1291                                                        ( &ast::FunctionType::params )[i]
     1292                                                                ( &ast::ObjectDecl::init )
     1293                                                                        ( &ast::SingleInit::value )->env = nullptr;
     1294
     1295                                        assert( functionDecl != ret.get() || functionDecl->unique() );
     1296                                        assert( ! ret->type->params[i].strict_as< ast::ObjectDecl >()->init.strict_as< ast::SingleInit >()->value->env );
     1297                                }
     1298                        }
     1299                }
     1300                return ret.get();
     1301        }
     1302
     1303        void Resolver_new::previsit( const ast::ObjectDecl * objectDecl ) {
     1304                // To handle initialization of routine pointers [e.g. int (*fp)(int) = foo()],
     1305                // class-variable `initContext` is changed multiple times because the LHS is analyzed
     1306                // twice. The second analysis changes `initContext` because a function type can contain
     1307                // object declarations in the return and parameter types. Therefore each value of
     1308                // `initContext` is retained so the type on the first analysis is preserved and used for
     1309                // selecting the RHS.
     1310                GuardValue( currentObject );
     1311                currentObject = ast::CurrentObject{ objectDecl->location, objectDecl->get_type() };
     1312                if ( inEnumDecl && dynamic_cast< const ast::EnumInstType * >( objectDecl->get_type() ) ) {
     1313                        // enumerator initializers should not use the enum type to initialize, since the
     1314                        // enum type is still incomplete at this point. Use `int` instead.
     1315                        currentObject = ast::CurrentObject{
     1316                                objectDecl->location, new ast::BasicType{ ast::BasicType::SignedInt } };
     1317                }
     1318        }
     1319
     1320        void Resolver_new::previsit( const ast::EnumDecl * ) {
     1321                // in case we decide to allow nested enums
     1322                GuardValue( inEnumDecl );
     1323                inEnumDecl = false;
     1324        }
     1325
     1326        const ast::StaticAssertDecl * Resolver_new::previsit(
     1327                const ast::StaticAssertDecl * assertDecl
     1328        ) {
     1329                return ast::mutate_field(
     1330                        assertDecl, &ast::StaticAssertDecl::cond,
     1331                        findIntegralExpression( assertDecl->cond, symtab ) );
     1332        }
     1333
     1334        template< typename PtrType >
     1335        const PtrType * handlePtrType( const PtrType * type, const ast::SymbolTable & symtab ) {
     1336                if ( type->dimension ) {
     1337                        #warning should use new equivalent to Validate::SizeType rather than sizeType here
     1338                        ast::ptr< ast::Type > sizeType = new ast::BasicType{ ast::BasicType::LongUnsignedInt };
     1339                        ast::mutate_field(
     1340                                type, &PtrType::dimension,
     1341                                findSingleExpression( type->dimension, sizeType, symtab ) );
     1342                }
     1343                return type;
     1344        }
     1345
     1346        const ast::ArrayType * Resolver_new::previsit( const ast::ArrayType * at ) {
     1347                return handlePtrType( at, symtab );
     1348        }
     1349
     1350        const ast::PointerType * Resolver_new::previsit( const ast::PointerType * pt ) {
     1351                return handlePtrType( pt, symtab );
     1352        }
     1353
     1354        const ast::ExprStmt * Resolver_new::previsit( const ast::ExprStmt * exprStmt ) {
     1355                visit_children = false;
     1356                assertf( exprStmt->expr, "ExprStmt has null expression in resolver" );
     1357
     1358                return ast::mutate_field(
     1359                        exprStmt, &ast::ExprStmt::expr, findVoidExpression( exprStmt->expr, symtab ) );
     1360        }
     1361
     1362        const ast::AsmExpr * Resolver_new::previsit( const ast::AsmExpr * asmExpr ) {
     1363                visit_children = false;
     1364
     1365                asmExpr = ast::mutate_field(
     1366                        asmExpr, &ast::AsmExpr::operand, findVoidExpression( asmExpr->operand, symtab ) );
     1367
     1368                if ( asmExpr->inout ) {
     1369                        asmExpr = ast::mutate_field(
     1370                                asmExpr, &ast::AsmExpr::inout, findVoidExpression( asmExpr->inout, symtab ) );
     1371                }
     1372
     1373                return asmExpr;
     1374        }
     1375
     1376        const ast::AsmStmt * Resolver_new::previsit( const ast::AsmStmt * asmStmt ) {
     1377                visitor->maybe_accept( asmStmt, &ast::AsmStmt::input );
     1378                visitor->maybe_accept( asmStmt, &ast::AsmStmt::output );
     1379                visit_children = false;
     1380                return asmStmt;
     1381        }
     1382
     1383        const ast::IfStmt * Resolver_new::previsit( const ast::IfStmt * ifStmt ) {
     1384                return ast::mutate_field(
     1385                        ifStmt, &ast::IfStmt::cond, findIntegralExpression( ifStmt->cond, symtab ) );
     1386        }
     1387
     1388        const ast::WhileStmt * Resolver_new::previsit( const ast::WhileStmt * whileStmt ) {
     1389                return ast::mutate_field(
     1390                        whileStmt, &ast::WhileStmt::cond, findIntegralExpression( whileStmt->cond, symtab ) );
     1391        }
     1392
     1393        const ast::ForStmt * Resolver_new::previsit( const ast::ForStmt * forStmt ) {
     1394                if ( forStmt->cond ) {
     1395                        forStmt = ast::mutate_field(
     1396                                forStmt, &ast::ForStmt::cond, findIntegralExpression( forStmt->cond, symtab ) );
     1397                }
     1398
     1399                if ( forStmt->inc ) {
     1400                        forStmt = ast::mutate_field(
     1401                                forStmt, &ast::ForStmt::inc, findVoidExpression( forStmt->inc, symtab ) );
     1402                }
     1403
     1404                return forStmt;
     1405        }
     1406
     1407        const ast::SwitchStmt * Resolver_new::previsit( const ast::SwitchStmt * switchStmt ) {
     1408                GuardValue( currentObject );
     1409                switchStmt = ast::mutate_field(
     1410                        switchStmt, &ast::SwitchStmt::cond,
     1411                        findIntegralExpression( switchStmt->cond, symtab ) );
     1412                currentObject = ast::CurrentObject{ switchStmt->location, switchStmt->cond->result };
     1413                return switchStmt;
     1414        }
     1415
     1416        const ast::CaseStmt * Resolver_new::previsit( const ast::CaseStmt * caseStmt ) {
     1417                if ( caseStmt->cond ) {
     1418                        std::deque< ast::InitAlternative > initAlts = currentObject.getOptions();
     1419                        assertf( initAlts.size() == 1, "SwitchStmt did not correctly resolve an integral "
     1420                                "expression." );
     1421
     1422                        ast::ptr< ast::Expr > untyped =
     1423                                new ast::CastExpr{ caseStmt->location, caseStmt->cond, initAlts.front().type };
     1424                        ast::ptr< ast::Expr > newExpr = findSingleExpression( untyped, symtab );
     1425
     1426                        // case condition cannot have a cast in C, so it must be removed here, regardless of
     1427                        // whether it would perform a conversion.
     1428                        if ( const ast::CastExpr * castExpr = newExpr.as< ast::CastExpr >() ) {
     1429                                swap_and_save_env( newExpr, castExpr->arg );
     1430                        }
     1431
     1432                        caseStmt = ast::mutate_field( caseStmt, &ast::CaseStmt::cond, newExpr );
     1433                }
     1434                return caseStmt;
     1435        }
     1436
     1437        const ast::BranchStmt * Resolver_new::previsit( const ast::BranchStmt * branchStmt ) {
     1438                visit_children = false;
     1439                // must resolve the argument of a computed goto
     1440                if ( branchStmt->kind == ast::BranchStmt::Goto && branchStmt->computedTarget ) {
     1441                        // computed goto argument is void*
     1442                        ast::ptr< ast::Type > target = new ast::PointerType{ new ast::VoidType{} };
     1443                        branchStmt = ast::mutate_field(
     1444                                branchStmt, &ast::BranchStmt::computedTarget,
     1445                                findSingleExpression( branchStmt->computedTarget, target, symtab ) );
     1446                }
     1447                return branchStmt;
     1448        }
     1449
     1450        const ast::ReturnStmt * Resolver_new::previsit( const ast::ReturnStmt * returnStmt ) {
     1451                visit_children = false;
     1452                if ( returnStmt->expr ) {
     1453                        returnStmt = ast::mutate_field(
     1454                                returnStmt, &ast::ReturnStmt::expr,
     1455                                findSingleExpression( returnStmt->expr, functionReturn, symtab ) );
     1456                }
     1457                return returnStmt;
     1458        }
     1459
     1460        const ast::ThrowStmt * Resolver_new::previsit( const ast::ThrowStmt * throwStmt ) {
     1461                visit_children = false;
     1462                if ( throwStmt->expr ) {
     1463                        const ast::StructDecl * exceptionDecl =
     1464                                symtab.lookupStruct( "__cfaabi_ehm__base_exception_t" );
     1465                        assert( exceptionDecl );
     1466                        ast::ptr< ast::Type > exceptType =
     1467                                new ast::PointerType{ new ast::StructInstType{ exceptionDecl } };
     1468                        throwStmt = ast::mutate_field(
     1469                                throwStmt, &ast::ThrowStmt::expr,
     1470                                findSingleExpression( throwStmt->expr, exceptType, symtab ) );
     1471                }
     1472                return throwStmt;
     1473        }
     1474
     1475        const ast::CatchStmt * Resolver_new::previsit( const ast::CatchStmt * catchStmt ) {
     1476                if ( catchStmt->cond ) {
     1477                        ast::ptr< ast::Type > boolType = new ast::BasicType{ ast::BasicType::Bool };
     1478                        catchStmt = ast::mutate_field(
     1479                                catchStmt, &ast::CatchStmt::cond,
     1480                                findSingleExpression( catchStmt->cond, boolType, symtab ) );
     1481                }
     1482                return catchStmt;
     1483        }
     1484
     1485        const ast::WaitForStmt * Resolver_new::previsit( const ast::WaitForStmt * stmt ) {
     1486                visit_children = false;
     1487
     1488                // Resolve all clauses first
     1489                for ( unsigned i = 0; i < stmt->clauses.size(); ++i ) {
     1490                        const ast::WaitForStmt::Clause & clause = stmt->clauses[i];
     1491
     1492                        ast::TypeEnvironment env;
     1493                        CandidateFinder funcFinder{ symtab, env };
     1494
     1495                        // Find all candidates for a function in canonical form
     1496                        funcFinder.find( clause.target.func, ResolvMode::withAdjustment() );
     1497
     1498                        if ( funcFinder.candidates.empty() ) {
     1499                                stringstream ss;
     1500                                ss << "Use of undeclared indentifier '";
     1501                                ss << clause.target.func.strict_as< ast::NameExpr >()->name;
     1502                                ss << "' in call to waitfor";
     1503                                SemanticError( stmt->location, ss.str() );
     1504                        }
     1505
     1506                        if ( clause.target.args.empty() ) {
     1507                                SemanticError( stmt->location,
     1508                                        "Waitfor clause must have at least one mutex parameter");
     1509                        }
     1510
     1511                        // Find all alternatives for all arguments in canonical form
     1512                        std::vector< CandidateFinder > argFinders =
     1513                                funcFinder.findSubExprs( clause.target.args );
     1514
     1515                        // List all combinations of arguments
     1516                        std::vector< CandidateList > possibilities;
     1517                        combos( argFinders.begin(), argFinders.end(), back_inserter( possibilities ) );
     1518
     1519                        // For every possible function:
     1520                        // * try matching the arguments to the parameters, not the other way around because
     1521                        //   more arguments than parameters
     1522                        CandidateList funcCandidates;
     1523                        std::vector< CandidateList > argsCandidates;
     1524                        SemanticErrorException errors;
     1525                        for ( CandidateRef & func : funcFinder.candidates ) {
     1526                                try {
     1527                                        auto pointerType = dynamic_cast< const ast::PointerType * >(
     1528                                                func->expr->result->stripReferences() );
     1529                                        if ( ! pointerType ) {
     1530                                                SemanticError( stmt->location, func->expr->result.get(),
     1531                                                        "candidate not viable: not a pointer type\n" );
     1532                                        }
     1533
     1534                                        auto funcType = pointerType->base.as< ast::FunctionType >();
     1535                                        if ( ! funcType ) {
     1536                                                SemanticError( stmt->location, func->expr->result.get(),
     1537                                                        "candidate not viable: not a function type\n" );
     1538                                        }
     1539
     1540                                        {
     1541                                                auto param    = funcType->params.begin();
     1542                                                auto paramEnd = funcType->params.end();
     1543
     1544                                                if( ! nextMutex( param, paramEnd ) ) {
     1545                                                        SemanticError( stmt->location, funcType,
     1546                                                                "candidate function not viable: no mutex parameters\n");
     1547                                                }
     1548                                        }
     1549
     1550                                        CandidateRef func2{ new Candidate{ *func } };
     1551                                        // strip reference from function
     1552                                        func2->expr = referenceToRvalueConversion( func->expr, func2->cost );
     1553
     1554                                        // Each argument must be matched with a parameter of the current candidate
     1555                                        for ( auto & argsList : possibilities ) {
     1556                                                try {
     1557                                                        // Declare data structures needed for resolution
     1558                                                        ast::OpenVarSet open;
     1559                                                        ast::AssertionSet need, have;
     1560                                                        ast::TypeEnvironment resultEnv{ func->env };
     1561                                                        // Add all type variables as open so that those not used in the
     1562                                                        // parameter list are still considered open
     1563                                                        resultEnv.add( funcType->forall );
     1564
     1565                                                        // load type variables from arguments into one shared space
     1566                                                        for ( auto & arg : argsList ) {
     1567                                                                resultEnv.simpleCombine( arg->env );
     1568                                                        }
     1569
     1570                                                        // Make sure we don't widen any existing bindings
     1571                                                        resultEnv.forbidWidening();
     1572
     1573                                                        // Find any unbound type variables
     1574                                                        resultEnv.extractOpenVars( open );
     1575
     1576                                                        auto param = funcType->params.begin();
     1577                                                        auto paramEnd = funcType->params.end();
     1578
     1579                                                        unsigned n_mutex_param = 0;
     1580
     1581                                                        // For every argument of its set, check if it matches one of the
     1582                                                        // parameters. The order is important
     1583                                                        for ( auto & arg : argsList ) {
     1584                                                                // Ignore non-mutex arguments
     1585                                                                if ( ! nextMutex( param, paramEnd ) ) {
     1586                                                                        // We ran out of parameters but still have arguments.
     1587                                                                        // This function doesn't match
     1588                                                                        SemanticError( stmt->location, funcType,
     1589                                                                                toString("candidate function not viable: too many mutex "
     1590                                                                                "arguments, expected ", n_mutex_param, "\n" ) );
     1591                                                                }
     1592
     1593                                                                ++n_mutex_param;
     1594
     1595                                                                // Check if the argument matches the parameter type in the current
     1596                                                                // scope
     1597                                                                ast::ptr< ast::Type > paramType = (*param)->get_type();
     1598                                                                if (
     1599                                                                        ! unify(
     1600                                                                                arg->expr->result, paramType, resultEnv, need, have, open,
     1601                                                                                symtab )
     1602                                                                ) {
     1603                                                                        // Type doesn't match
     1604                                                                        stringstream ss;
     1605                                                                        ss << "candidate function not viable: no known conversion "
     1606                                                                                "from '";
     1607                                                                        ast::print( ss, (*param)->get_type() );
     1608                                                                        ss << "' to '";
     1609                                                                        ast::print( ss, arg->expr->result );
     1610                                                                        ss << "' with env '";
     1611                                                                        ast::print( ss, resultEnv );
     1612                                                                        ss << "'\n";
     1613                                                                        SemanticError( stmt->location, funcType, ss.str() );
     1614                                                                }
     1615
     1616                                                                ++param;
     1617                                                        }
     1618
     1619                                                        // All arguments match!
     1620
     1621                                                        // Check if parameters are missing
     1622                                                        if ( nextMutex( param, paramEnd ) ) {
     1623                                                                do {
     1624                                                                        ++n_mutex_param;
     1625                                                                        ++param;
     1626                                                                } while ( nextMutex( param, paramEnd ) );
     1627
     1628                                                                // We ran out of arguments but still have parameters left; this
     1629                                                                // function doesn't match
     1630                                                                SemanticError( stmt->location, funcType,
     1631                                                                        toString( "candidate function not viable: too few mutex "
     1632                                                                        "arguments, expected ", n_mutex_param, "\n" ) );
     1633                                                        }
     1634
     1635                                                        // All parameters match!
     1636
     1637                                                        // Finish the expressions to tie in proper environments
     1638                                                        finishExpr( func2->expr, resultEnv );
     1639                                                        for ( CandidateRef & arg : argsList ) {
     1640                                                                finishExpr( arg->expr, resultEnv );
     1641                                                        }
     1642
     1643                                                        // This is a match, store it and save it for later
     1644                                                        funcCandidates.emplace_back( std::move( func2 ) );
     1645                                                        argsCandidates.emplace_back( std::move( argsList ) );
     1646
     1647                                                } catch ( SemanticErrorException & e ) {
     1648                                                        errors.append( e );
     1649                                                }
     1650                                        }
     1651                                } catch ( SemanticErrorException & e ) {
     1652                                        errors.append( e );
     1653                                }
     1654                        }
     1655
     1656                        // Make sure correct number of arguments
     1657                        if( funcCandidates.empty() ) {
     1658                                SemanticErrorException top( stmt->location,
     1659                                        "No alternatives for function in call to waitfor" );
     1660                                top.append( errors );
     1661                                throw top;
     1662                        }
     1663
     1664                        if( argsCandidates.empty() ) {
     1665                                SemanticErrorException top( stmt->location,
     1666                                        "No alternatives for arguments in call to waitfor" );
     1667                                top.append( errors );
     1668                                throw top;
     1669                        }
     1670
     1671                        if( funcCandidates.size() > 1 ) {
     1672                                SemanticErrorException top( stmt->location,
     1673                                        "Ambiguous function in call to waitfor" );
     1674                                top.append( errors );
     1675                                throw top;
     1676                        }
     1677                        if( argsCandidates.size() > 1 ) {
     1678                                SemanticErrorException top( stmt->location,
     1679                                        "Ambiguous arguments in call to waitfor" );
     1680                                top.append( errors );
     1681                                throw top;
     1682                        }
     1683                        // TODO: need to use findDeletedExpr to ensure no deleted identifiers are used.
     1684
     1685                        // build new clause
     1686                        ast::WaitForStmt::Clause clause2;
     1687
     1688                        clause2.target.func = funcCandidates.front()->expr;
     1689
     1690                        clause2.target.args.reserve( clause.target.args.size() );
     1691                        for ( auto arg : argsCandidates.front() ) {
     1692                                clause2.target.args.emplace_back( std::move( arg->expr ) );
     1693                        }
     1694
     1695                        // Resolve the conditions as if it were an IfStmt, statements normally
     1696                        clause2.cond = findSingleExpression( clause.cond, symtab );
     1697                        clause2.stmt = clause.stmt->accept( *visitor );
     1698
     1699                        // set results into stmt
     1700                        auto n = mutate( stmt );
     1701                        n->clauses[i] = std::move( clause2 );
     1702                        stmt = n;
     1703                }
     1704
     1705                if ( stmt->timeout.stmt ) {
     1706                        // resolve the timeout as a size_t, the conditions like IfStmt, and stmts normally
     1707                        ast::WaitForStmt::Timeout timeout2;
     1708
     1709                        ast::ptr< ast::Type > target =
     1710                                new ast::BasicType{ ast::BasicType::LongLongUnsignedInt };
     1711                        timeout2.time = findSingleExpression( stmt->timeout.time, target, symtab );
     1712                        timeout2.cond = findSingleExpression( stmt->timeout.cond, symtab );
     1713                        timeout2.stmt = stmt->timeout.stmt->accept( *visitor );
     1714
     1715                        // set results into stmt
     1716                        auto n = mutate( stmt );
     1717                        n->timeout = std::move( timeout2 );
     1718                        stmt = n;
     1719                }
     1720
     1721                if ( stmt->orElse.stmt ) {
     1722                        // resolve the condition like IfStmt, stmts normally
     1723                        ast::WaitForStmt::OrElse orElse2;
     1724
     1725                        orElse2.cond = findSingleExpression( stmt->orElse.cond, symtab );
     1726                        orElse2.stmt = stmt->orElse.stmt->accept( *visitor );
     1727
     1728                        // set results into stmt
     1729                        auto n = mutate( stmt );
     1730                        n->orElse = std::move( orElse2 );
     1731                        stmt = n;
     1732                }
     1733
     1734                return stmt;
     1735        }
     1736
     1737
     1738
     1739        const ast::SingleInit * Resolver_new::previsit( const ast::SingleInit * singleInit ) {
     1740                visit_children = false;
     1741                // resolve initialization using the possibilities as determined by the `currentObject`
     1742                // cursor.
     1743                ast::ptr< ast::Expr > untyped = new ast::UntypedInitExpr{
     1744                        singleInit->location, singleInit->value, currentObject.getOptions() };
     1745                ast::ptr<ast::Expr> newExpr = findSingleExpression( untyped, symtab );
     1746                const ast::InitExpr * initExpr = newExpr.strict_as< ast::InitExpr >();
     1747
     1748                // move cursor to the object that is actually initialized
     1749                currentObject.setNext( initExpr->designation );
     1750
     1751                // discard InitExpr wrapper and retain relevant pieces.
     1752                // `initExpr` may have inferred params in the case where the expression specialized a
     1753                // function pointer, and newExpr may already have inferParams of its own, so a simple
     1754                // swap is not sufficient
     1755                ast::Expr::InferUnion inferred = initExpr->inferred;
     1756                swap_and_save_env( newExpr, initExpr->expr );
     1757                newExpr.get_and_mutate()->inferred.splice( std::move(inferred) );
     1758
     1759                // get the actual object's type (may not exactly match what comes back from the resolver
     1760                // due to conversions)
     1761                const ast::Type * initContext = currentObject.getCurrentType();
     1762
     1763                removeExtraneousCast( newExpr, symtab );
     1764
     1765                // check if actual object's type is char[]
     1766                if ( auto at = dynamic_cast< const ast::ArrayType * >( initContext ) ) {
     1767                        if ( isCharType( at->base ) ) {
     1768                                // check if the resolved type is char*
     1769                                if ( auto pt = newExpr->result.as< ast::PointerType >() ) {
     1770                                        if ( isCharType( pt->base ) ) {
     1771                                                // strip cast if we're initializing a char[] with a char*
     1772                                                // e.g. char x[] = "hello"
     1773                                                if ( auto ce = newExpr.as< ast::CastExpr >() ) {
     1774                                                        swap_and_save_env( newExpr, ce->arg );
     1775                                                }
     1776                                        }
     1777                                }
     1778                        }
     1779                }
     1780
     1781                // move cursor to next object in preparation for next initializer
     1782                currentObject.increment();
     1783
     1784                // set initializer expression to resolved expression
     1785                return ast::mutate_field( singleInit, &ast::SingleInit::value, std::move(newExpr) );
     1786        }
     1787
     1788        const ast::ListInit * Resolver_new::previsit( const ast::ListInit * listInit ) {
     1789                // move cursor into brace-enclosed initializer-list
     1790                currentObject.enterListInit( listInit->location );
     1791
     1792                assert( listInit->designations.size() == listInit->initializers.size() );
     1793                for ( unsigned i = 0; i < listInit->designations.size(); ++i ) {
     1794                        // iterate designations and initializers in pairs, moving the cursor to the current
     1795                        // designated object and resolving the initializer against that object
     1796                        listInit = ast::mutate_field_index(
     1797                                listInit, &ast::ListInit::designations, i,
     1798                                currentObject.findNext( listInit->designations[i] ) );
     1799                        listInit = ast::mutate_field_index(
     1800                                listInit, &ast::ListInit::initializers, i,
     1801                                listInit->initializers[i]->accept( *visitor ) );
     1802                }
     1803
     1804                // move cursor out of brace-enclosed initializer-list
     1805                currentObject.exitListInit();
     1806
     1807                visit_children = false;
     1808                return listInit;
     1809        }
     1810
     1811        const ast::ConstructorInit * Resolver_new::previsit( const ast::ConstructorInit * ctorInit ) {
     1812                visitor->maybe_accept( ctorInit, &ast::ConstructorInit::ctor );
     1813                visitor->maybe_accept( ctorInit, &ast::ConstructorInit::dtor );
     1814
     1815                // found a constructor - can get rid of C-style initializer
     1816                // xxx - Rob suggests this field is dead code
     1817                ctorInit = ast::mutate_field( ctorInit, &ast::ConstructorInit::init, nullptr );
     1818
     1819                // intrinsic single-parameter constructors and destructors do nothing. Since this was
     1820                // implicitly generated, there's no way for it to have side effects, so get rid of it to
     1821                // clean up generated code
     1822                if ( InitTweak::isIntrinsicSingleArgCallStmt( ctorInit->ctor ) ) {
     1823                        ctorInit = ast::mutate_field( ctorInit, &ast::ConstructorInit::ctor, nullptr );
     1824                }
     1825                if ( InitTweak::isIntrinsicSingleArgCallStmt( ctorInit->dtor ) ) {
     1826                        ctorInit = ast::mutate_field( ctorInit, &ast::ConstructorInit::dtor, nullptr );
     1827                }
     1828
     1829                return ctorInit;
     1830        }
     1831
    8761832} // namespace ResolvExpr
    8771833
  • src/ResolvExpr/Resolver.h

    r7951100 rb067d9b  
    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
    1616#pragma once
    1717
    18 #include <list>  // for list
     18#include <list>          // for list
     19
     20#include "AST/Node.hpp"  // for ptr
    1921
    2022class ConstructorInit;
     
    2325class StmtExpr;
    2426namespace SymTab {
    25 class Indexer;
    26 }  // namespace SymTab
     27        class Indexer;
     28} // namespace SymTab
     29
     30namespace ast {
     31        class ConstructorInit;
     32        class Decl;
     33        class DeletedExpr;
     34        class Init;
     35        class StmtExpr;
     36        class SymbolTable;
     37        class Type;
     38        class TypeEnvironment;
     39} // namespace ast
    2740
    2841namespace ResolvExpr {
    2942        /// Checks types and binds syntactic constructs to typed representations
    3043        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 );
     44        void resolveDecl( Declaration *, const SymTab::Indexer & indexer );
     45        Expression *resolveInVoidContext( Expression * expr, const SymTab::Indexer & indexer );
     46        void findVoidExpression( Expression *& untyped, const SymTab::Indexer & indexer );
     47        void findSingleExpression( Expression *& untyped, const SymTab::Indexer & indexer );
     48        void findSingleExpression( Expression *& untyped, Type * type, const SymTab::Indexer & indexer );
    3649        void resolveCtorInit( ConstructorInit * ctorInit, const SymTab::Indexer & indexer );
    3750        void resolveStmtExpr( StmtExpr * stmtExpr, const SymTab::Indexer & indexer );
     51        /// Searches expr and returns the first DeletedExpr found, otherwise nullptr
     52        DeletedExpr * findDeletedExpr( Expression * expr );
     53        /// Resolves with-stmts and with-clauses on functions
     54        void resolveWithExprs( std::list< Declaration * > & translationUnit );
     55
     56        /// Checks types and binds syntactic constructs to typed representations
     57        void resolve( std::list< ast::ptr<ast::Decl> >& translationUnit );
     58        /// Searches expr and returns the first DeletedExpr found, otherwise nullptr
     59        const ast::DeletedExpr * findDeletedExpr( const ast::Expr * expr );
     60        /// Find the expression candidate that is the unique best match for `untyped` in a `void`
     61        /// context.
     62        ast::ptr< ast::Expr > resolveInVoidContext(
     63                const ast::Expr * expr, const ast::SymbolTable & symtab, ast::TypeEnvironment & env );
     64        /// Resolve `untyped` to the single expression whose candidate is the best match for the
     65        /// given type.
     66        ast::ptr< ast::Expr > findSingleExpression(
     67                const ast::Expr * untyped, const ast::Type * type, const ast::SymbolTable & symtab );
     68        /// Resolves a constructor init expression
     69        ast::ptr< ast::Init > resolveCtorInit(
     70                const ast::ConstructorInit * ctorInit, const ast::SymbolTable & symtab );
     71        /// Resolves a statement expression
     72        ast::ptr< ast::Expr > resolveStmtExpr(
     73                const ast::StmtExpr * stmtExpr, const ast::SymbolTable & symtab );
    3874} // namespace ResolvExpr
    3975
  • src/ResolvExpr/TypeEnvironment.cc

    r7951100 rb067d9b  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 12:19:47 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun May 17 12:23:36 2015
    13 // Update Count     : 3
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Fri Jun 18 14:27:00 2019
     13// Update Count     : 5
    1414//
    1515
     
    1717#include <algorithm>                   // for copy, set_intersection
    1818#include <iterator>                    // for ostream_iterator, insert_iterator
     19#include <memory>                      // for unique_ptr
    1920#include <utility>                     // for pair, move
    2021
     
    2223#include "SynTree/Type.h"              // for Type, FunctionType, Type::Fora...
    2324#include "SynTree/TypeSubstitution.h"  // for TypeSubstitution
     25#include "Tuples/Tuples.h"             // for isTtype
    2426#include "TypeEnvironment.h"
     27#include "typeops.h"                   // for occurs
     28#include "Unify.h"                     // for unifyInexact
    2529
    2630namespace ResolvExpr {
     
    6569        }
    6670
     71        EqvClass::EqvClass( EqvClass &&other )
     72        : vars{std::move(other.vars)}, type{other.type},
     73          allowWidening{std::move(other.allowWidening)}, data{std::move(other.data)} {
     74                  other.type = nullptr;
     75        }
     76
    6777        EqvClass &EqvClass::operator=( const EqvClass &other ) {
    6878                if ( this == &other ) return *this;
     
    7282        }
    7383
     84        EqvClass &EqvClass::operator=( EqvClass &&other ) {
     85                if ( this == &other ) return *this;
     86                delete type;
     87
     88                vars = std::move(other.vars);
     89                type = other.type;
     90                other.type = nullptr;
     91                allowWidening = std::move(other.allowWidening);
     92                data = std::move(other.data);
     93
     94                return *this;
     95        }
     96
    7497        EqvClass::~EqvClass() {
    7598                delete type;
     99        }
     100
     101        void EqvClass::set_type( Type* ty ) {
     102                if ( ty == type ) return;
     103                delete type;
     104                type = ty;
    76105        }
    77106
     
    91120
    92121        const EqvClass* TypeEnvironment::lookup( const std::string &var ) const {
    93                 for ( std::list< EqvClass >::const_iterator i = env.begin(); i != env.end(); ++i ) {
    94                         if ( i->vars.find( var ) != i->vars.end() ) {
    95 ///       std::cout << var << " is in class ";
    96 ///       i->print( std::cout );
    97                                 return &*i;
    98                         }
    99 ///     std::cout << var << " is not in class ";
    100 ///     i->print( std::cout );
     122                for ( ClassList::const_iterator i = env.begin(); i != env.end(); ++i ) {
     123                        if ( i->vars.find( var ) != i->vars.end() ) return &*i;
    101124                } // for
    102125                return nullptr;
     
    109132                        ++next;
    110133                        std::set<std::string> intersection;
    111                         std::set_intersection( i->vars.begin(), i->vars.end(), eqvClass.vars.begin(), eqvClass.vars.end(), 
     134                        std::set_intersection( i->vars.begin(), i->vars.end(), eqvClass.vars.begin(), eqvClass.vars.end(),
    112135                                std::inserter( intersection, intersection.begin() ) );
    113136                        if ( ! intersection.empty() ) { env.erase( i ); }
    114137                        i = next;
    115138                }
    116         }
    117 
    118         void TypeEnvironment::add( const EqvClass &eqvClass ) {
    119                 filterOverlappingClasses( env, eqvClass );
    120                 env.push_back( eqvClass );
    121139        }
    122140
     
    131149                        newClass.vars.insert( (*i)->get_name() );
    132150                        newClass.data = TypeDecl::Data{ (*i) };
    133                         env.push_back( newClass );
     151                        env.push_back( std::move(newClass) );
    134152                } // for
    135153        }
     
    145163                        // transition to TypeSubstitution
    146164                        newClass.data = TypeDecl::Data{ TypeDecl::Dtype, false };
    147                         add( newClass );
     165                        add( std::move(newClass) );
    148166                }
    149167        }
    150168
    151169        void TypeEnvironment::makeSubstitution( TypeSubstitution &sub ) const {
    152                 for ( std::list< EqvClass >::const_iterator theClass = env.begin(); theClass != env.end(); ++theClass ) {
     170                for ( ClassList::const_iterator theClass = env.begin(); theClass != env.end(); ++theClass ) {
    153171                        for ( std::set< std::string >::const_iterator theVar = theClass->vars.begin(); theVar != theClass->vars.end(); ++theVar ) {
    154 ///       std::cerr << "adding " << *theVar;
    155172                                if ( theClass->type ) {
    156 ///         std::cerr << " bound to ";
    157 ///         theClass->type->print( std::cerr );
    158 ///         std::cerr << std::endl;
    159173                                        sub.add( *theVar, theClass->type );
    160174                                } else if ( theVar != theClass->vars.begin() ) {
    161175                                        TypeInstType *newTypeInst = new TypeInstType( Type::Qualifiers(), *theClass->vars.begin(), theClass->data.kind == TypeDecl::Ftype );
    162 ///         std::cerr << " bound to variable " << *theClass->vars.begin() << std::endl;
    163176                                        sub.add( *theVar, newTypeInst );
    164177                                        delete newTypeInst;
     
    166179                        } // for
    167180                } // for
    168 ///   std::cerr << "input env is:" << std::endl;
    169 ///   print( std::cerr, 8 );
    170 ///   std::cerr << "sub is:" << std::endl;
    171 ///   sub.print( std::cerr, 8 );
    172181                sub.normalize();
    173182        }
     
    179188        }
    180189
    181         std::list< EqvClass >::iterator TypeEnvironment::internal_lookup( const std::string &var ) {
    182                 for ( std::list< EqvClass >::iterator i = env.begin(); i != env.end(); ++i ) {
    183                         if ( i->vars.find( var ) == i->vars.end() ) {
    184                                 return i;
    185                         } // if
     190        TypeEnvironment::ClassList::iterator TypeEnvironment::internal_lookup( const std::string &var ) {
     191                for ( ClassList::iterator i = env.begin(); i != env.end(); ++i ) {
     192                        if ( i->vars.count( var ) ) return i;
    186193                } // for
    187194                return env.end();
     
    192199        }
    193200
    194         void TypeEnvironment::combine( const TypeEnvironment &second, Type *(*combineFunc)( Type*, Type* ) ) {
    195                 TypeEnvironment secondCopy( second );
    196                 for ( std::list< EqvClass >::iterator firstClass = env.begin(); firstClass != env.end(); ++firstClass ) {
    197                         EqvClass &newClass = *firstClass;
    198                         std::set< std::string > newVars;
    199                         for ( std::set< std::string >::const_iterator var = firstClass->vars.begin(); var != firstClass->vars.end(); ++var ) {
    200                                 std::list< EqvClass >::iterator secondClass = secondCopy.internal_lookup( *var );
    201                                 if ( secondClass != secondCopy.env.end() ) {
    202                                         newVars.insert( secondClass->vars.begin(), secondClass->vars.end() );
    203                                         if ( secondClass->type ) {
    204                                                 if ( newClass.type ) {
    205                                                         Type *newType = combineFunc( newClass.type, secondClass->type );
    206                                                         delete newClass.type;
    207                                                         newClass.type = newType;
    208                                                         newClass.allowWidening = newClass.allowWidening && secondClass->allowWidening;
    209                                                 } else {
    210                                                         newClass.type = secondClass->type->clone();
    211                                                         newClass.allowWidening = secondClass->allowWidening;
    212                                                 } // if
    213                                         } // if
    214                                         secondCopy.env.erase( secondClass );
    215                                 } // if
    216                         } // for
    217                         newClass.vars.insert( newVars.begin(), newVars.end() );
    218                 } // for
    219                 for ( std::list< EqvClass >::iterator secondClass = secondCopy.env.begin(); secondClass != secondCopy.env.end(); ++secondClass ) {
    220                         env.push_back( *secondClass );
    221                 } // for
     201        // xxx -- this should maybe be worrying about iterator invalidation (see resolv-proto)
     202        bool TypeEnvironment::mergeBound( EqvClass& to, const EqvClass& from, OpenVarSet& openVars, const SymTab::Indexer& indexer ) {
     203                if ( from.type ) {
     204                        if ( to.type ) {
     205                                // attempt to unify bound types
     206                                std::unique_ptr<Type> toType{ to.type->clone() }, fromType{ from.type->clone() };
     207                                WidenMode widen{ to.allowWidening, from.allowWidening };
     208                                Type* common = nullptr;
     209                                AssertionSet need, have;
     210                                if ( unifyInexact( toType.get(), fromType.get(), *this, need, have, openVars, widen, indexer, common ) ) {
     211                                        // unifies, set common type if necessary
     212                                        if ( common ) {
     213                                                common->get_qualifiers() = Type::Qualifiers{};
     214                                                to.set_type( common );
     215                                        }
     216                                } else return false; // cannot unify
     217                        } else {
     218                                to.type = from.type->clone();
     219                        }
     220                }
     221
     222                // unify widening if matches
     223                to.allowWidening &= from.allowWidening;
     224                return true;
     225        }
     226
     227        // xxx -- this should maybe be worrying about iterator invalidation (see resolv-proto)
     228        bool TypeEnvironment::mergeClasses( TypeEnvironment::ClassList::iterator to, TypeEnvironment::ClassList::iterator from, OpenVarSet& openVars, const SymTab::Indexer& indexer ) {
     229                EqvClass& r = *to;
     230                EqvClass& s = *from;
     231
     232                // ensure bounds match
     233                if ( ! mergeBound( r, s, openVars, indexer ) ) return false;
     234
     235                // check safely bindable
     236                if ( r.type && occursIn( r.type, s.vars.begin(), s.vars.end(), *this ) ) return false;
     237               
     238                // merge classes in
     239                r.vars.insert( s.vars.begin(), s.vars.end() );
     240                r.allowWidening &= s.allowWidening;
     241                env.erase( from );
     242
     243                return true;
     244        }
     245
     246        bool TypeEnvironment::combine( const TypeEnvironment& o, OpenVarSet& openVars, const SymTab::Indexer& indexer ) {
     247                // short-circuit easy cases
     248                if ( o.isEmpty() ) return true;
     249                if ( isEmpty() ) {
     250                        simpleCombine( o );
     251                        return true;
     252                }
     253
     254                // merge classes
     255                for ( auto ct = o.env.begin(); ct != o.env.end(); ++ct ) {
     256                        const EqvClass& c = *ct;
     257
     258                        // typeclass in local environment bound to c
     259                        auto rt = env.end();
     260
     261                        // look for first existing bound variable
     262                        auto vt = c.vars.begin();
     263                        for ( ; vt != c.vars.end(); ++vt ) {
     264                                rt = internal_lookup( *vt );
     265                                if ( rt != env.end() ) break;
     266                        }
     267
     268                        if ( rt != env.end() ) {  // c needs to be merged into *rt
     269                                EqvClass& r = *rt;
     270                                // merge bindings
     271                                if ( ! mergeBound( r, c, openVars, indexer ) ) return false;
     272                                // merge previous unbound variables into this class, checking occurs if needed
     273                                if ( r.type ) for ( auto ut = c.vars.begin(); ut != vt; ++ut ) {
     274                                        if ( occurs( r.type, *ut, *this ) ) return false;
     275                                        r.vars.insert( *ut );
     276                                } else { r.vars.insert( c.vars.begin(), vt ); }
     277                                // merge subsequent variables into this class (skipping *vt, already there)
     278                                while ( ++vt != c.vars.end() ) {
     279                                        auto st = internal_lookup( *vt );
     280                                        if ( st == env.end() ) {
     281                                                // unbound, safe to add if passes occurs
     282                                                if ( r.type && occurs( r.type, *vt, *this ) ) return false;
     283                                                r.vars.insert( *vt );
     284                                        } else if ( st != rt ) {
     285                                                // bound, but not to the same class
     286                                                if ( ! mergeClasses( rt, st, openVars, indexer ) ) return false;
     287                                        }   // ignore bound into the same class
     288                                }
     289                        } else {  // no variables in c bound; just copy up
     290                                env.push_back( c );
     291                        }
     292                }
     293
     294                // merged all classes
     295                return true;
    222296        }
    223297
    224298        void TypeEnvironment::extractOpenVars( OpenVarSet &openVars ) const {
    225                 for ( std::list< EqvClass >::const_iterator eqvClass = env.begin(); eqvClass != env.end(); ++eqvClass ) {
     299                for ( ClassList::const_iterator eqvClass = env.begin(); eqvClass != env.end(); ++eqvClass ) {
    226300                        for ( std::set< std::string >::const_iterator var = eqvClass->vars.begin(); var != eqvClass->vars.end(); ++var ) {
    227301                                openVars[ *var ] = eqvClass->data;
     
    241315        }
    242316
     317        bool isFtype( const Type * type ) {
     318                if ( dynamic_cast< const FunctionType * >( type ) ) {
     319                        return true;
     320                } else if ( const TypeInstType *typeInst = dynamic_cast< const TypeInstType * >( type ) ) {
     321                        return typeInst->get_isFtype();
     322                } // if
     323                return false;
     324        }
     325
     326        bool tyVarCompatible( const TypeDecl::Data & data, const Type * type ) {
     327                switch ( data.kind ) {
     328                  case TypeDecl::Dtype:
     329                        // to bind to an object type variable, the type must not be a function type.
     330                        // if the type variable is specified to be a complete type then the incoming
     331                        // type must also be complete
     332                        // xxx - should this also check that type is not a tuple type and that it's not a ttype?
     333                        return ! isFtype( type ) && (! data.isComplete || type->isComplete() );
     334                  case TypeDecl::Ftype:
     335                        return isFtype( type );
     336                  case TypeDecl::Ttype:
     337                        // ttype unifies with any tuple type
     338                        return dynamic_cast< const TupleType * >( type ) || Tuples::isTtype( type );
     339                  default:
     340                        assertf(false, "Unhandled tyvar kind: %d", data.kind);
     341                } // switch
     342                return false;
     343        }
     344
     345        bool TypeEnvironment::bindVar( const TypeInstType *typeInst, Type *bindTo, const TypeDecl::Data & data, AssertionSet &need, AssertionSet &have, const OpenVarSet &openVars, WidenMode widen, const SymTab::Indexer &indexer ) {
     346
     347                // remove references from other, so that type variables can only bind to value types
     348                bindTo = bindTo->stripReferences();
     349                OpenVarSet::const_iterator tyvar = openVars.find( typeInst->get_name() );
     350                assert( tyvar != openVars.end() );
     351                if ( ! tyVarCompatible( tyvar->second, bindTo ) ) {
     352                        return false;
     353                } // if
     354                if ( occurs( bindTo, typeInst->get_name(), *this ) ) {
     355                        return false;
     356                } // if
     357                auto curClass = internal_lookup( typeInst->get_name() );
     358                if ( curClass != env.end() ) {
     359                        if ( curClass->type ) {
     360                                Type *common = 0;
     361                                // attempt to unify equivalence class type (which has qualifiers stripped, so they must be restored) with the type to bind to
     362                                std::unique_ptr< Type > newType( curClass->type->clone() );
     363                                newType->tq = typeInst->tq;
     364                                if ( unifyInexact( newType.get(), bindTo, *this, need, have, openVars, widen & WidenMode( curClass->allowWidening, true ), indexer, common ) ) {
     365                                        if ( common ) {
     366                                                common->get_qualifiers() = Type::Qualifiers{};
     367                                                curClass->set_type( common );
     368                                        } // if
     369                                } else return false;
     370                        } else {
     371                                Type* newType = bindTo->clone();
     372                                newType->get_qualifiers() = Type::Qualifiers{};
     373                                curClass->set_type( newType );
     374                                curClass->allowWidening = widen.first && widen.second;
     375                        } // if
     376                } else {
     377                        EqvClass newClass;
     378                        newClass.vars.insert( typeInst->get_name() );
     379                        newClass.type = bindTo->clone();
     380                        newClass.type->get_qualifiers() = Type::Qualifiers();
     381                        newClass.allowWidening = widen.first && widen.second;
     382                        newClass.data = data;
     383                        env.push_back( std::move(newClass) );
     384                } // if
     385                return true;
     386        }
     387
     388        bool TypeEnvironment::bindVarToVar( const TypeInstType * var1, const TypeInstType * var2,
     389                        TypeDecl::Data && data, AssertionSet &need, AssertionSet &have,
     390                        const OpenVarSet &openVars, WidenMode widen, const SymTab::Indexer &indexer ) {
     391
     392                auto class1 = internal_lookup( var1->get_name() );
     393                auto class2 = internal_lookup( var2->get_name() );
     394
     395                // exit early if variables already bound together
     396                if ( class1 != env.end() && class1 == class2 ) {
     397                        class1->allowWidening &= widen;
     398                        return true;
     399                }
     400
     401                bool widen1 = false, widen2 = false;
     402                const Type *type1 = nullptr, *type2 = nullptr;
     403
     404                // check for existing bindings, perform occurs check
     405                if ( class1 != env.end() ) {
     406                        if ( class1->type ) {
     407                                if ( occurs( class1->type, var2->get_name(), *this ) ) return false;
     408                                type1 = class1->type;
     409                        } // if
     410                        widen1 = widen.first && class1->allowWidening;
     411                } // if
     412                if ( class2 != env.end() ) {
     413                        if ( class2->type ) {
     414                                if ( occurs( class2->type, var1->get_name(), *this ) ) return false;
     415                                type2 = class2->type;
     416                        } // if
     417                        widen2 = widen.second && class2->allowWidening;
     418                } // if
     419
     420                if ( type1 && type2 ) {
     421                        // both classes bound, merge if bound types can be unified
     422                        std::unique_ptr<Type> newType1{ type1->clone() }, newType2{ type2->clone() };
     423                        WidenMode newWidenMode{ widen1, widen2 };
     424                        Type *common = 0;
     425                        if ( unifyInexact( newType1.get(), newType2.get(), *this, need, have, openVars, newWidenMode, indexer, common ) ) {
     426                                class1->vars.insert( class2->vars.begin(), class2->vars.end() );
     427                                class1->allowWidening = widen1 && widen2;
     428                                if ( common ) {
     429                                        common->get_qualifiers() = Type::Qualifiers{};
     430                                        class1->set_type( common );
     431                                }
     432                                class1->data.isComplete |= data.isComplete;
     433                                env.erase( class2 );
     434                        } else return false;
     435                } else if ( class1 != env.end() && class2 != env.end() ) {
     436                        // both classes exist, at least one unbound, merge unconditionally
     437                        if ( type1 ) {
     438                                class1->vars.insert( class2->vars.begin(), class2->vars.end() );
     439                                class1->allowWidening = widen1;
     440                                class1->data.isComplete |= data.isComplete;
     441                                env.erase( class2 );
     442                        } else {
     443                                class2->vars.insert( class1->vars.begin(), class1->vars.end() );
     444                                class2->allowWidening = widen2;
     445                                class2->data.isComplete |= data.isComplete;
     446                                env.erase( class1 );
     447                        } // if
     448                } else if ( class1 != env.end() ) {
     449                        // var2 unbound, add to class1
     450                        class1->vars.insert( var2->get_name() );
     451                        class1->allowWidening = widen1;
     452                        class1->data.isComplete |= data.isComplete;
     453                } else if ( class2 != env.end() ) {
     454                        // var1 unbound, add to class2
     455                        class2->vars.insert( var1->get_name() );
     456                        class2->allowWidening = widen2;
     457                        class2->data.isComplete |= data.isComplete;
     458                } else {
     459                        // neither var bound, create new class
     460                        EqvClass newClass;
     461                        newClass.vars.insert( var1->get_name() );
     462                        newClass.vars.insert( var2->get_name() );
     463                        newClass.allowWidening = widen1 && widen2;
     464                        newClass.data = data;
     465                        env.push_back( std::move(newClass) );
     466                } // if
     467                return true;
     468        }
     469
     470        void TypeEnvironment::forbidWidening() {
     471                for ( EqvClass& c : env ) c.allowWidening = false;
     472        }
     473
    243474        std::ostream & operator<<( std::ostream & out, const TypeEnvironment & env ) {
    244475                env.print( out );
  • src/ResolvExpr/TypeEnvironment.h

    r7951100 rb067d9b  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 12:24:58 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Jul 22 09:35:45 2017
    13 // Update Count     : 3
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Fri Jul 19 17:00:10 2019
     13// Update Count     : 10
    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
     24#include <utility>                     // for move, swap
     25
     26#include "WidenMode.h"                 // for WidenMode
    2327
    2428#include "SynTree/Declaration.h"       // for TypeDecl::Data, DeclarationWit...
     
    3640        // declarations.
    3741        //
    38         // I've seen a TU go from 54 minutes to 1 minute 34 seconds with the addition of this comparator.
     42        // I've seen a TU go from 54 minutes to 1 minute 34 seconds with the addition of this
     43        // comparator.
    3944        //
    4045        // Note: since this compares pointers for position, minor changes in the source file that affect
    4146        // memory layout can alter compilation time in unpredictable ways. For example, the placement
    4247        // of a line directive can reorder type pointers with respect to each other so that assertions
    43         // are seen in different orders, causing a potentially different number of unification calls when
    44         // resolving assertions. I've seen a TU go from 36 seconds to 27 seconds by reordering line directives
    45         // alone, so it would be nice to fix this comparison so that assertions compare more consistently.
    46         // I've tried to modify this to compare on mangle name instead of type as the second comparator, but
    47         // this causes some assertions to never be recorded. More investigation is needed.
     48        // are seen in different orders, causing a potentially different number of unification calls
     49        // when resolving assertions. I've seen a TU go from 36 seconds to 27 seconds by reordering
     50        // line directives alone, so it would be nice to fix this comparison so that assertions compare
     51        // more consistently. I've tried to modify this to compare on mangle name instead of type as
     52        // the second comparator, but this causes some assertions to never be recorded. More
     53        // investigation is needed.
    4854        struct AssertCompare {
    49                 bool operator()( DeclarationWithType * d1, DeclarationWithType * d2 ) const {
     55                bool operator()( const DeclarationWithType * d1, const DeclarationWithType * d2 ) const {
    5056                        int cmp = d1->get_name().compare( d2->get_name() );
    5157                        return cmp < 0 ||
     
    5460        };
    5561        struct AssertionSetValue {
    56                 bool isUsed;
    57                 // chain of Unique IDs of the assertion declarations. The first ID in the chain is the ID of an assertion on the current type,
    58                 // with each successive ID being the ID of an assertion pulled in by the previous ID. The last ID in the chain is
    59                 // the ID of the assertion that pulled in the current assertion.
    60                 std::list< UniqueId > idChain;
     62                bool isUsed;        ///< True if assertion needs to be resolved
     63                UniqueId resnSlot;  ///< ID of slot assertion belongs to
     64
     65                AssertionSetValue() : isUsed(false), resnSlot(0) {}
    6166        };
    62         typedef std::map< DeclarationWithType*, AssertionSetValue, AssertCompare > AssertionSet;
    63         typedef std::map< std::string, TypeDecl::Data > OpenVarSet;
     67        typedef std::map< const DeclarationWithType *, AssertionSetValue, AssertCompare > AssertionSet;
     68        typedef std::unordered_map< std::string, TypeDecl::Data > OpenVarSet;
     69
     70        /// merges one set of open vars into another
     71        static inline void mergeOpenVars( OpenVarSet& dst, const OpenVarSet& src ) {
     72                for ( const auto& entry : src ) { dst[ entry.first ] = entry.second; }
     73        }
    6474
    6575        void printAssertionSet( const AssertionSet &, std::ostream &, int indent = 0 );
     
    6878        struct EqvClass {
    6979                std::set< std::string > vars;
    70                 Type *type;
     80                Type * type;
    7181                bool allowWidening;
    7282                TypeDecl::Data data;
     
    7787                EqvClass( const EqvClass &other );
    7888                EqvClass( const EqvClass &other, const Type *ty );
     89                EqvClass( EqvClass &&other );
    7990                EqvClass &operator=( const EqvClass &other );
     91                EqvClass &operator=( EqvClass &&other );
    8092                ~EqvClass();
    8193                void print( std::ostream &os, Indenter indent = {} ) const;
     94
     95                /// Takes ownership of `ty`, freeing old `type`
     96                void set_type(Type* ty);
    8297        };
    8398
    8499        class TypeEnvironment {
     100                using ClassList = std::list< EqvClass >;
    85101          public:
    86102                const EqvClass* lookup( const std::string &var ) const;
    87                 void add( const EqvClass &eqvClass );
     103          private:
    88104                void add( EqvClass &&eqvClass  );
     105          public:
    89106                void add( const Type::ForallList &tyDecls );
    90107                void add( const TypeSubstitution & sub );
     
    94111                bool isEmpty() const { return env.empty(); }
    95112                void print( std::ostream &os, Indenter indent = {} ) const;
    96                 void combine( const TypeEnvironment &second, Type *(*combineFunc)( Type*, Type* ) );
     113
     114                /// Simply concatenate the second environment onto this one; no safety checks performed
    97115                void simpleCombine( const TypeEnvironment &second );
     116
     117          private:
     118                /// Unifies the type bound of to with the type bound of from, returning false if fails
     119                bool mergeBound( EqvClass& to, const EqvClass& from, OpenVarSet& openVars, const SymTab::Indexer& indexer );
     120
     121                /// Merges two type classes from local environment, returning false if fails
     122                bool mergeClasses( ClassList::iterator to, ClassList::iterator from, OpenVarSet& openVars, const SymTab::Indexer& indexer );
     123
     124          public:
     125                /// Merges the second environment with this one, checking compatibility.
     126                /// Returns false if fails, but does NOT roll back partial changes.
     127                bool combine( const TypeEnvironment& second, OpenVarSet& openVars, const SymTab::Indexer& indexer );
     128
    98129                void extractOpenVars( OpenVarSet &openVars ) const;
    99130                TypeEnvironment *clone() const { return new TypeEnvironment( *this ); }
     
    103134                void addActual( const TypeEnvironment& actualEnv, OpenVarSet& openVars );
    104135
    105                 typedef std::list< EqvClass >::iterator iterator;
    106                 iterator begin() { return env.begin(); }
    107                 iterator end() { return env.end(); }
    108                 typedef std::list< EqvClass >::const_iterator const_iterator;
    109                 const_iterator begin() const { return env.begin(); }
    110                 const_iterator end() const { return env.end(); }
     136                /// Binds the type class represented by `typeInst` to the type `bindTo`; will add
     137                /// the class if needed. Returns false on failure.
     138                bool bindVar( const TypeInstType * typeInst, Type * bindTo, const TypeDecl::Data & data, AssertionSet &need, AssertionSet &have, const OpenVarSet &openVars, WidenMode widen, const SymTab::Indexer &indexer );
     139
     140                /// Binds the type classes represented by `var1` and `var2` together; will add
     141                /// one or both classes if needed. Returns false on failure.
     142                bool bindVarToVar( const TypeInstType * var1, const TypeInstType * var2, TypeDecl::Data && data, AssertionSet &need, AssertionSet &have, const OpenVarSet &openVars, WidenMode widen, const SymTab::Indexer &indexer );
     143
     144                /// Disallows widening for all bindings in the environment
     145                void forbidWidening();
     146
     147                using iterator = ClassList::const_iterator;
     148                iterator begin() const { return env.begin(); }
     149                iterator end() const { return env.end(); }
     150
    111151          private:
    112                 std::list< EqvClass > env;
    113                 std::list< EqvClass >::iterator internal_lookup( const std::string &var );
     152                ClassList env;
     153
     154                ClassList::iterator internal_lookup( const std::string &var );
    114155        };
    115156
  • src/ResolvExpr/Unify.cc

    r7951100 rb067d9b  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 12:27:10 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Mar 16 16:22:54 2017
    13 // Update Count     : 42
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Wed Sep  4 10:00:00 2019
     13// Update Count     : 44
    1414//
    1515
    16 #include <cassert>                // for assertf, assert
    17 #include <iterator>               // for back_insert_iterator, back_inserter
    18 #include <map>                    // for _Rb_tree_const_iterator, _Rb_tree_i...
    19 #include <memory>                 // for unique_ptr
    20 #include <set>                    // for set
    21 #include <string>                 // for string, operator==, operator!=, bas...
    22 #include <utility>                // for pair, move
    23 
    24 #include "Common/PassVisitor.h"   // for PassVisitor
    25 #include "FindOpenVars.h"         // for findOpenVars
    26 #include "Parser/LinkageSpec.h"   // for C
    27 #include "SynTree/Constant.h"     // for Constant
    28 #include "SynTree/Declaration.h"  // for TypeDecl, TypeDecl::Data, Declarati...
    29 #include "SynTree/Expression.h"   // for TypeExpr, Expression, ConstantExpr
    30 #include "SynTree/Mutator.h"      // for Mutator
    31 #include "SynTree/Type.h"         // for Type, TypeInstType, FunctionType
    32 #include "SynTree/Visitor.h"      // for Visitor
    33 #include "Tuples/Tuples.h"        // for isTtype
    34 #include "TypeEnvironment.h"      // for EqvClass, AssertionSet, OpenVarSet
    3516#include "Unify.h"
    36 #include "typeops.h"              // for flatten, occurs, commonType
     17
     18#include <cassert>                  // for assertf, assert
     19#include <iterator>                 // for back_insert_iterator, back_inserter
     20#include <map>                      // for _Rb_tree_const_iterator, _Rb_tree_i...
     21#include <memory>                   // for unique_ptr
     22#include <set>                      // for set
     23#include <string>                   // for string, operator==, operator!=, bas...
     24#include <utility>                  // for pair, move
     25#include <vector>
     26
     27#include "AST/Decl.hpp"
     28#include "AST/Node.hpp"
     29#include "AST/Pass.hpp"
     30#include "AST/Type.hpp"
     31#include "AST/TypeEnvironment.hpp"
     32#include "Common/PassVisitor.h"     // for PassVisitor
     33#include "FindOpenVars.h"           // for findOpenVars
     34#include "Parser/LinkageSpec.h"     // for C
     35#include "SynTree/Constant.h"       // for Constant
     36#include "SynTree/Declaration.h"    // for TypeDecl, TypeDecl::Data, Declarati...
     37#include "SynTree/Expression.h"     // for TypeExpr, Expression, ConstantExpr
     38#include "SynTree/Mutator.h"        // for Mutator
     39#include "SynTree/Type.h"           // for Type, TypeInstType, FunctionType
     40#include "SynTree/Visitor.h"        // for Visitor
     41#include "Tuples/Tuples.h"          // for isTtype
     42#include "TypeEnvironment.h"        // for EqvClass, AssertionSet, OpenVarSet
     43#include "typeops.h"                // for flatten, occurs, commonType
     44
     45namespace ast {
     46        class SymbolTable;
     47}
    3748
    3849namespace SymTab {
     
    4455namespace ResolvExpr {
    4556
    46         struct Unify : public WithShortCircuiting {
    47                 Unify( Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer );
     57        struct Unify_old : public WithShortCircuiting {
     58                Unify_old( Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widen, const SymTab::Indexer &indexer );
    4859
    4960                bool get_result() const { return result; }
     
    7788                AssertionSet &haveAssertions;
    7889                const OpenVarSet &openVars;
    79                 WidenMode widenMode;
     90                WidenMode widen;
    8091                const SymTab::Indexer &indexer;
    8192        };
     
    8394        /// Attempts an inexact unification of type1 and type2.
    8495        /// Returns false if no such unification; if the types can be unified, sets common (unless they unify exactly and have identical type qualifiers)
    85         bool unifyInexact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer, Type *&common );
    86         bool unifyExact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer );
    87 
    88         bool typesCompatible( Type *first, Type *second, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
     96        bool unifyInexact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widen, const SymTab::Indexer &indexer, Type *&common );
     97        bool unifyExact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widen, const SymTab::Indexer &indexer );
     98
     99        bool unifyExact(
     100                const ast::Type * type1, const ast::Type * type2, ast::TypeEnvironment & env,
     101                ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open,
     102                WidenMode widen, const ast::SymbolTable & symtab );
     103
     104        bool typesCompatible( const Type * first, const Type * second, const SymTab::Indexer & indexer, const TypeEnvironment & env ) {
    89105                TypeEnvironment newEnv;
    90106                OpenVarSet openVars, closedVars; // added closedVars
    91107                AssertionSet needAssertions, haveAssertions;
    92                 Type *newFirst = first->clone(), *newSecond = second->clone();
     108                Type * newFirst = first->clone(), * newSecond = second->clone();
    93109                env.apply( newFirst );
    94110                env.apply( newSecond );
     
    105121        }
    106122
    107         bool typesCompatibleIgnoreQualifiers( Type *first, Type *second, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
     123        bool typesCompatible(
     124                        const ast::Type * first, const ast::Type * second, const ast::SymbolTable & symtab,
     125                        const ast::TypeEnvironment & env ) {
     126                ast::TypeEnvironment newEnv;
     127                ast::OpenVarSet open, closed;
     128                ast::AssertionSet need, have;
     129
     130                ast::ptr<ast::Type> newFirst{ first }, newSecond{ second };
     131                env.apply( newFirst );
     132                env.apply( newSecond );
     133
     134                findOpenVars( newFirst, open, closed, need, have, FirstClosed );
     135                findOpenVars( newSecond, open, closed, need, have, FirstOpen );
     136
     137                return unifyExact(
     138                        newFirst, newSecond, newEnv, need, have, open, noWiden(), symtab );
     139        }
     140
     141        bool typesCompatibleIgnoreQualifiers( const Type * first, const Type * second, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {
    108142                TypeEnvironment newEnv;
    109143                OpenVarSet openVars;
     
    129163        }
    130164
    131         bool isFtype( Type *type ) {
    132                 if ( dynamic_cast< FunctionType* >( type ) ) {
    133                         return true;
    134                 } else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( type ) ) {
    135                         return typeInst->get_isFtype();
    136                 } // if
    137                 return false;
    138         }
    139 
    140         bool tyVarCompatible( const TypeDecl::Data & data, Type *type ) {
    141                 switch ( data.kind ) {
    142                   case TypeDecl::Dtype:
    143                         // to bind to an object type variable, the type must not be a function type.
    144                         // if the type variable is specified to be a complete type then the incoming
    145                         // type must also be complete
    146                         // xxx - should this also check that type is not a tuple type and that it's not a ttype?
    147                         return ! isFtype( type ) && (! data.isComplete || type->isComplete() );
    148                   case TypeDecl::Ftype:
    149                         return isFtype( type );
    150                   case TypeDecl::Ttype:
    151                         // ttype unifies with any tuple type
    152                         return dynamic_cast< TupleType * >( type ) || Tuples::isTtype( type );
    153                 } // switch
    154                 return false;
    155         }
    156 
    157         bool bindVar( TypeInstType *typeInst, Type *other, const TypeDecl::Data & data, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer ) {
    158                 // remove references from other, so that type variables can only bind to value types
    159                 other = other->stripReferences();
    160                 OpenVarSet::const_iterator tyvar = openVars.find( typeInst->get_name() );
    161                 assert( tyvar != openVars.end() );
    162                 if ( ! tyVarCompatible( tyvar->second, other ) ) {
    163                         return false;
    164                 } // if
    165                 if ( occurs( other, typeInst->get_name(), env ) ) {
    166                         return false;
    167                 } // if
    168                 if ( const EqvClass *curClass = env.lookup( typeInst->get_name() ) ) {
    169                         if ( curClass->type ) {
    170                                 Type *common = 0;
    171                                 // attempt to unify equivalence class type (which has qualifiers stripped, so they must be restored) with the type to bind to
    172                                 std::unique_ptr< Type > newType( curClass->type->clone() );
    173                                 newType->get_qualifiers() = typeInst->get_qualifiers();
    174                                 if ( unifyInexact( newType.get(), other, env, needAssertions, haveAssertions, openVars, widenMode & WidenMode( curClass->allowWidening, true ), indexer, common ) ) {
    175                                         if ( common ) {
    176                                                 common->get_qualifiers() = Type::Qualifiers();
    177                                                 env.add( EqvClass{ *curClass, common } );
    178                                         } // if
    179                                         return true;
    180                                 } else {
    181                                         return false;
    182                                 } // if
    183                         } else {
    184                                 EqvClass newClass { *curClass, other };
    185                                 newClass.type->get_qualifiers() = Type::Qualifiers();
    186                                 newClass.allowWidening = widenMode.widenFirst && widenMode.widenSecond;
    187                                 env.add( std::move(newClass) );
    188                         } // if
    189                 } else {
    190                         EqvClass newClass;
    191                         newClass.vars.insert( typeInst->get_name() );
    192                         newClass.type = other->clone();
    193                         newClass.type->get_qualifiers() = Type::Qualifiers();
    194                         newClass.allowWidening = widenMode.widenFirst && widenMode.widenSecond;
    195                         newClass.data = data;
    196                         env.add( newClass );
    197                 } // if
    198                 return true;
    199         }
    200 
    201         bool bindVarToVar( TypeInstType *var1, TypeInstType *var2, const TypeDecl::Data & data, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer ) {
    202                 bool result = true;
    203                 const EqvClass *class1 = env.lookup( var1->get_name() );
    204                 const EqvClass *class2 = env.lookup( var2->get_name() );
    205                 bool widen1 = false, widen2 = false;
    206                 Type *type1 = nullptr, *type2 = nullptr;
    207 
    208                 if ( class1 ) {
    209                         if ( class1->type ) {
    210                                 if ( occurs( class1->type, var2->get_name(), env ) ) {
    211                                         return false;
    212                                 } // if
    213                                 type1 = class1->type->clone();
    214                         } // if
    215                         widen1 = widenMode.widenFirst && class1->allowWidening;
    216                 } // if
    217                 if ( class2 ) {
    218                         if ( class2->type ) {
    219                                 if ( occurs( class2->type, var1->get_name(), env ) ) {
    220                                         return false;
    221                                 } // if
    222                                 type2 = class2->type->clone();
    223                         } // if
    224                         widen2 = widenMode.widenSecond && class2->allowWidening;
    225                 } // if
    226 
    227                 if ( type1 && type2 ) {
    228 //    std::cerr << "has type1 && type2" << std::endl;
    229                         WidenMode newWidenMode ( widen1, widen2 );
    230                         Type *common = 0;
    231                         if ( unifyInexact( type1, type2, env, needAssertions, haveAssertions, openVars, newWidenMode, indexer, common ) ) {
    232                                 EqvClass newClass1 = *class1;
    233                                 newClass1.vars.insert( class2->vars.begin(), class2->vars.end() );
    234                                 newClass1.allowWidening = widen1 && widen2;
    235                                 if ( common ) {
    236                                         common->get_qualifiers() = Type::Qualifiers();
    237                                         delete newClass1.type;
    238                                         newClass1.type = common;
    239                                 } // if
    240                                 env.add( std::move(newClass1) );
    241                         } else {
    242                                 result = false;
    243                         } // if
    244                 } else if ( class1 && class2 ) {
    245                         if ( type1 ) {
    246                                 EqvClass newClass1 = *class1;
    247                                 newClass1.vars.insert( class2->vars.begin(), class2->vars.end() );
    248                                 newClass1.allowWidening = widen1;
    249                                 env.add( std::move(newClass1) );
    250                         } else {
    251                                 EqvClass newClass2 = *class2;
    252                                 newClass2.vars.insert( class1->vars.begin(), class1->vars.end() );
    253                                 newClass2.allowWidening = widen2;
    254                                 env.add( std::move(newClass2) );
    255                         } // if
    256                 } else if ( class1 ) {
    257                         EqvClass newClass1 = *class1;
    258                         newClass1.vars.insert( var2->get_name() );
    259                         newClass1.allowWidening = widen1;
    260                         env.add( std::move(newClass1) );
    261                 } else if ( class2 ) {
    262                         EqvClass newClass2 = *class2;
    263                         newClass2.vars.insert( var1->get_name() );
    264                         newClass2.allowWidening = widen2;
    265                         env.add( std::move(newClass2) );
    266                 } else {
    267                         EqvClass newClass;
    268                         newClass.vars.insert( var1->get_name() );
    269                         newClass.vars.insert( var2->get_name() );
    270                         newClass.allowWidening = widen1 && widen2;
    271                         newClass.data = data;
    272                         env.add( newClass );
    273                 } // if
    274                 delete type1;
    275                 delete type2;
    276                 return result;
     165        bool typesCompatibleIgnoreQualifiers(
     166                        const ast::Type * first, const ast::Type * second, const ast::SymbolTable & symtab,
     167                        const ast::TypeEnvironment & env ) {
     168                ast::TypeEnvironment newEnv;
     169                ast::OpenVarSet open;
     170                ast::AssertionSet need, have;
     171
     172                ast::ptr<ast::Type> newFirst{ first }, newSecond{ second };
     173                env.apply( newFirst );
     174                env.apply( newSecond );
     175                reset_qualifiers( newFirst );
     176                reset_qualifiers( newSecond );
     177
     178                return unifyExact(
     179                        newFirst, newSecond, newEnv, need, have, open, noWiden(), symtab );
    277180        }
    278181
     
    299202        }
    300203
    301         bool unifyExact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer ) {
     204        bool unifyExact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widen, const SymTab::Indexer &indexer ) {
    302205#ifdef DEBUG
    303206                TypeEnvironment debugEnv( env );
     
    320223                bool isopen2 = var2 && ( entry2 != openVars.end() );
    321224
    322                 if ( isopen1 && isopen2 && entry1->second == entry2->second ) {
    323                         result = bindVarToVar( var1, var2, entry1->second, env, needAssertions, haveAssertions, openVars, widenMode, indexer );
     225                if ( isopen1 && isopen2 ) {
     226                        if ( entry1->second.kind != entry2->second.kind ) {
     227                                result = false;
     228                        } else {
     229                                result = env.bindVarToVar(
     230                                        var1, var2, TypeDecl::Data{ entry1->second, entry2->second }, needAssertions,
     231                                        haveAssertions, openVars, widen, indexer );
     232                        }
    324233                } else if ( isopen1 ) {
    325                         result = bindVar( var1, type2, entry1->second, env, needAssertions, haveAssertions, openVars, widenMode, indexer );
    326                 } else if ( isopen2 ) { // TODO: swap widenMode values in call, since type positions are flipped?
    327                         result = bindVar( var2, type1, entry2->second, env, needAssertions, haveAssertions, openVars, widenMode, indexer );
     234                        result = env.bindVar( var1, type2, entry1->second, needAssertions, haveAssertions, openVars, widen, indexer );
     235                } else if ( isopen2 ) { // TODO: swap widen values in call, since type positions are flipped?
     236                        result = env.bindVar( var2, type1, entry2->second, needAssertions, haveAssertions, openVars, widen, indexer );
    328237                } else {
    329                         PassVisitor<Unify> comparator( type2, env, needAssertions, haveAssertions, openVars, widenMode, indexer );
     238                        PassVisitor<Unify_old> comparator( type2, env, needAssertions, haveAssertions, openVars, widen, indexer );
    330239                        type1->accept( comparator );
    331240                        result = comparator.pass.get_result();
     
    352261        }
    353262
    354         bool unifyInexact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer, Type *&common ) {
     263        bool unifyInexact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widen, const SymTab::Indexer &indexer, Type *&common ) {
    355264                Type::Qualifiers tq1 = type1->get_qualifiers(), tq2 = type2->get_qualifiers();
    356265                type1->get_qualifiers() = Type::Qualifiers();
     
    364273                std::cerr << std::endl;
    365274#endif
    366                 if ( ! unifyExact( type1, type2, env, needAssertions, haveAssertions, openVars, widenMode, indexer ) ) {
     275                if ( ! unifyExact( type1, type2, env, needAssertions, haveAssertions, openVars, widen, indexer ) ) {
    367276#ifdef DEBUG
    368277                        std::cerr << "unifyInexact: no exact unification found" << std::endl;
    369278#endif
    370                         if ( ( common = commonType( type1, type2, widenMode.widenFirst, widenMode.widenSecond, indexer, env, openVars ) ) ) {
    371                                 common->get_qualifiers() = tq1 | tq2;
     279                        if ( ( common = commonType( type1, type2, widen.first, widen.second, indexer, env, openVars ) ) ) {
     280                                common->tq = tq1.unify( tq2 );
    372281#ifdef DEBUG
    373282                                std::cerr << "unifyInexact: common type is ";
     
    384293                } else {
    385294                        if ( tq1 != tq2 ) {
    386                                 if ( ( tq1 > tq2 || widenMode.widenFirst ) && ( tq2 > tq1 || widenMode.widenSecond ) ) {
     295                                if ( ( tq1 > tq2 || widen.first ) && ( tq2 > tq1 || widen.second ) ) {
    387296                                        common = type1->clone();
    388                                         common->get_qualifiers() = tq1 | tq2;
     297                                        common->tq = tq1.unify( tq2 );
    389298                                        result = true;
    390299                                } else {
     
    393302                        } else {
    394303                                common = type1->clone();
    395                                 common->get_qualifiers() = tq1 | tq2;
     304                                common->tq = tq1.unify( tq2 );
    396305                                result = true;
    397306                        } // if
     
    402311        }
    403312
    404         Unify::Unify( Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer )
    405                 : result( false ), type2( type2 ), env( env ), needAssertions( needAssertions ), haveAssertions( haveAssertions ), openVars( openVars ), widenMode( widenMode ), indexer( indexer ) {
    406         }
    407 
    408         void Unify::postvisit( __attribute__((unused)) VoidType *voidType) {
     313        Unify_old::Unify_old( Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widen, const SymTab::Indexer &indexer )
     314                : result( false ), type2( type2 ), env( env ), needAssertions( needAssertions ), haveAssertions( haveAssertions ), openVars( openVars ), widen( widen ), indexer( indexer ) {
     315        }
     316
     317        void Unify_old::postvisit( __attribute__((unused)) VoidType *voidType) {
    409318                result = dynamic_cast< VoidType* >( type2 );
    410319        }
    411320
    412         void Unify::postvisit(BasicType *basicType) {
     321        void Unify_old::postvisit(BasicType *basicType) {
    413322                if ( BasicType *otherBasic = dynamic_cast< BasicType* >( type2 ) ) {
    414323                        result = basicType->get_kind() == otherBasic->get_kind();
     
    438347        }
    439348
    440         void Unify::postvisit(PointerType *pointerType) {
     349        void Unify_old::postvisit(PointerType *pointerType) {
    441350                if ( PointerType *otherPointer = dynamic_cast< PointerType* >( type2 ) ) {
    442351                        result = unifyExact( pointerType->get_base(), otherPointer->get_base(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
     
    446355        }
    447356
    448         void Unify::postvisit(ReferenceType *refType) {
     357        void Unify_old::postvisit(ReferenceType *refType) {
    449358                if ( ReferenceType *otherRef = dynamic_cast< ReferenceType* >( type2 ) ) {
    450359                        result = unifyExact( refType->get_base(), otherRef->get_base(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
     
    454363        }
    455364
    456         void Unify::postvisit(ArrayType *arrayType) {
     365        void Unify_old::postvisit(ArrayType *arrayType) {
    457366                ArrayType *otherArray = dynamic_cast< ArrayType* >( type2 );
    458367                // to unify, array types must both be VLA or both not VLA
     
    534443        /// If this isn't done then argument lists can have wildly different
    535444        /// size and structure, when they should be compatible.
    536         struct TtypeExpander : public WithShortCircuiting {
     445        struct TtypeExpander_old : public WithShortCircuiting {
    537446                TypeEnvironment & tenv;
    538                 TtypeExpander( TypeEnvironment & tenv ) : tenv( tenv ) {}
     447                TtypeExpander_old( TypeEnvironment & tenv ) : tenv( tenv ) {}
    539448                void premutate( TypeInstType * ) { visit_children = false; }
    540449                Type * postmutate( TypeInstType * typeInst ) {
     
    555464                dst.clear();
    556465                for ( DeclarationWithType * dcl : src ) {
    557                         PassVisitor<TtypeExpander> expander( env );
     466                        PassVisitor<TtypeExpander_old> expander( env );
    558467                        dcl->acceptMutator( expander );
    559468                        std::list< Type * > types;
     
    570479        }
    571480
    572         void Unify::postvisit(FunctionType *functionType) {
     481        void Unify_old::postvisit(FunctionType *functionType) {
    573482                FunctionType *otherFunction = dynamic_cast< FunctionType* >( type2 );
    574483                if ( otherFunction && functionType->get_isVarArgs() == otherFunction->get_isVarArgs() ) {
     
    581490
    582491                        // sizes don't have to match if ttypes are involved; need to be more precise wrt where the ttype is to prevent errors
    583                         if ( (flatFunc->parameters.size() == flatOther->parameters.size() && flatFunc->returnVals.size() == flatOther->returnVals.size()) || flatFunc->isTtype() || flatOther->isTtype() ) {
     492                        if (
     493                                        (flatFunc->parameters.size() == flatOther->parameters.size() &&
     494                                                flatFunc->returnVals.size() == flatOther->returnVals.size())
     495                                        || flatFunc->isTtype()
     496                                        || flatOther->isTtype()
     497                        ) {
    584498                                if ( unifyDeclList( flatFunc->parameters.begin(), flatFunc->parameters.end(), flatOther->parameters.begin(), flatOther->parameters.end(), env, needAssertions, haveAssertions, openVars, indexer ) ) {
    585499                                        if ( unifyDeclList( flatFunc->returnVals.begin(), flatFunc->returnVals.end(), flatOther->returnVals.begin(), flatOther->returnVals.end(), env, needAssertions, haveAssertions, openVars, indexer ) ) {
     
    597511
    598512        template< typename RefType >
    599         void Unify::handleRefType( RefType *inst, Type *other ) {
     513        void Unify_old::handleRefType( RefType *inst, Type *other ) {
    600514                // check that other type is compatible and named the same
    601515                RefType *otherStruct = dynamic_cast< RefType* >( other );
     
    604518
    605519        template< typename RefType >
    606         void Unify::handleGenericRefType( RefType *inst, Type *other ) {
     520        void Unify_old::handleGenericRefType( RefType *inst, Type *other ) {
    607521                // Check that other type is compatible and named the same
    608522                handleRefType( inst, other );
     
    672586        }
    673587
    674         void Unify::postvisit(StructInstType *structInst) {
     588        void Unify_old::postvisit(StructInstType *structInst) {
    675589                handleGenericRefType( structInst, type2 );
    676590        }
    677591
    678         void Unify::postvisit(UnionInstType *unionInst) {
     592        void Unify_old::postvisit(UnionInstType *unionInst) {
    679593                handleGenericRefType( unionInst, type2 );
    680594        }
    681595
    682         void Unify::postvisit(EnumInstType *enumInst) {
     596        void Unify_old::postvisit(EnumInstType *enumInst) {
    683597                handleRefType( enumInst, type2 );
    684598        }
    685599
    686         void Unify::postvisit(TraitInstType *contextInst) {
     600        void Unify_old::postvisit(TraitInstType *contextInst) {
    687601                handleRefType( contextInst, type2 );
    688602        }
    689603
    690         void Unify::postvisit(TypeInstType *typeInst) {
     604        void Unify_old::postvisit(TypeInstType *typeInst) {
    691605                assert( openVars.find( typeInst->get_name() ) == openVars.end() );
    692606                TypeInstType *otherInst = dynamic_cast< TypeInstType* >( type2 );
     
    743657        }
    744658
    745         void Unify::postvisit(TupleType *tupleType) {
     659        void Unify_old::postvisit(TupleType *tupleType) {
    746660                if ( TupleType *otherTuple = dynamic_cast< TupleType* >( type2 ) ) {
    747661                        std::unique_ptr<TupleType> flat1( tupleType->clone() );
     
    749663                        std::list<Type *> types1, types2;
    750664
    751                         PassVisitor<TtypeExpander> expander( env );
     665                        PassVisitor<TtypeExpander_old> expander( env );
    752666                        flat1->acceptMutator( expander );
    753667                        flat2->acceptMutator( expander );
     
    760674        }
    761675
    762         void Unify::postvisit( __attribute__((unused)) VarArgsType *varArgsType ) {
     676        void Unify_old::postvisit( __attribute__((unused)) VarArgsType *varArgsType ) {
    763677                result = dynamic_cast< VarArgsType* >( type2 );
    764678        }
    765679
    766         void Unify::postvisit( __attribute__((unused)) ZeroType *zeroType ) {
     680        void Unify_old::postvisit( __attribute__((unused)) ZeroType *zeroType ) {
    767681                result = dynamic_cast< ZeroType* >( type2 );
    768682        }
    769683
    770         void Unify::postvisit( __attribute__((unused)) OneType *oneType ) {
     684        void Unify_old::postvisit( __attribute__((unused)) OneType *oneType ) {
    771685                result = dynamic_cast< OneType* >( type2 );
    772686        }
    773687
    774         // xxx - compute once and store in the FunctionType?
    775688        Type * extractResultType( FunctionType * function ) {
    776689                if ( function->get_returnVals().size() == 0 ) {
     
    786699                }
    787700        }
     701
     702        class Unify_new final : public ast::WithShortCircuiting {
     703                const ast::Type * type2;
     704                ast::TypeEnvironment & tenv;
     705                ast::AssertionSet & need;
     706                ast::AssertionSet & have;
     707                const ast::OpenVarSet & open;
     708                WidenMode widen;
     709                const ast::SymbolTable & symtab;
     710        public:
     711                bool result;
     712
     713                Unify_new(
     714                        const ast::Type * type2, ast::TypeEnvironment & env, ast::AssertionSet & need,
     715                        ast::AssertionSet & have, const ast::OpenVarSet & open, WidenMode widen,
     716                        const ast::SymbolTable & symtab )
     717                : type2(type2), tenv(env), need(need), have(have), open(open), widen(widen),
     718                  symtab(symtab), result(false) {}
     719
     720                void previsit( const ast::Node * ) { visit_children = false; }
     721
     722                void postvisit( const ast::VoidType * ) {
     723                        result = dynamic_cast< const ast::VoidType * >( type2 );
     724                }
     725
     726                void postvisit( const ast::BasicType * basic ) {
     727                        if ( auto basic2 = dynamic_cast< const ast::BasicType * >( type2 ) ) {
     728                                result = basic->kind == basic2->kind;
     729                        }
     730                }
     731
     732                void postvisit( const ast::PointerType * pointer ) {
     733                        if ( auto pointer2 = dynamic_cast< const ast::PointerType * >( type2 ) ) {
     734                                result = unifyExact(
     735                                        pointer->base, pointer2->base, tenv, need, have, open,
     736                                        noWiden(), symtab );
     737                        }
     738                }
     739
     740                void postvisit( const ast::ArrayType * array ) {
     741                        auto array2 = dynamic_cast< const ast::ArrayType * >( type2 );
     742                        if ( ! array2 ) return;
     743
     744                        // to unify, array types must both be VLA or both not VLA and both must have a
     745                        // dimension expression or not have a dimension
     746                        if ( array->isVarLen != array2->isVarLen ) return;
     747                        if ( ! array->isVarLen && ! array2->isVarLen
     748                                        && array->dimension && array2->dimension ) {
     749                                auto ce1 = array->dimension.as< ast::ConstantExpr >();
     750                                auto ce2 = array2->dimension.as< ast::ConstantExpr >();
     751
     752                                // see C11 Reference Manual 6.7.6.2.6
     753                                // two array types with size specifiers that are integer constant expressions are
     754                                // compatible if both size specifiers have the same constant value
     755                                if ( ce1 && ce2 && ce1->intValue() != ce2->intValue() ) return;
     756                        }
     757
     758                        result = unifyExact(
     759                                array->base, array2->base, tenv, need, have, open, noWiden(),
     760                                symtab );
     761                }
     762
     763                void postvisit( const ast::ReferenceType * ref ) {
     764                        if ( auto ref2 = dynamic_cast< const ast::ReferenceType * >( type2 ) ) {
     765                                result = unifyExact(
     766                                        ref->base, ref2->base, tenv, need, have, open, noWiden(),
     767                                        symtab );
     768                        }
     769                }
     770
     771        private:
     772                /// Replaces ttype variables with their bound types.
     773                /// If this isn't done when satifying ttype assertions, then argument lists can have
     774                /// different size and structure when they should be compatible.
     775                struct TtypeExpander_new : public ast::WithShortCircuiting {
     776                        ast::TypeEnvironment & tenv;
     777
     778                        TtypeExpander_new( ast::TypeEnvironment & env ) : tenv( env ) {}
     779
     780                        const ast::Type * postvisit( const ast::TypeInstType * typeInst ) {
     781                                if ( const ast::EqvClass * clz = tenv.lookup( typeInst->name ) ) {
     782                                        // expand ttype parameter into its actual type
     783                                        if ( clz->data.kind == ast::TypeVar::Ttype && clz->bound ) {
     784                                                return clz->bound;
     785                                        }
     786                                }
     787                                return typeInst;
     788                        }
     789                };
     790
     791                /// returns flattened version of `src`
     792                static std::vector< ast::ptr< ast::DeclWithType > > flattenList(
     793                        const std::vector< ast::ptr< ast::DeclWithType > > & src, ast::TypeEnvironment & env
     794                ) {
     795                        std::vector< ast::ptr< ast::DeclWithType > > dst;
     796                        dst.reserve( src.size() );
     797                        for ( const ast::DeclWithType * d : src ) {
     798                                ast::Pass<TtypeExpander_new> expander{ env };
     799                                d = d->accept( expander );
     800                                auto types = flatten( d->get_type() );
     801                                for ( ast::ptr< ast::Type > & t : types ) {
     802                                        // outermost const, volatile, _Atomic qualifiers in parameters should not play
     803                                        // a role in the unification of function types, since they do not determine
     804                                        // whether a function is callable.
     805                                        // NOTE: **must** consider at least mutex qualifier, since functions can be
     806                                        // overloaded on outermost mutex and a mutex function has different
     807                                        // requirements than a non-mutex function
     808                                        remove_qualifiers( t, ast::CV::Const | ast::CV::Volatile | ast::CV::Atomic );
     809                                        dst.emplace_back( new ast::ObjectDecl{ d->location, "", t } );
     810                                }
     811                        }
     812                        return dst;
     813                }
     814
     815                /// Creates a tuple type based on a list of DeclWithType
     816                template< typename Iter >
     817                static ast::ptr< ast::Type > tupleFromDecls( Iter crnt, Iter end ) {
     818                        std::vector< ast::ptr< ast::Type > > types;
     819                        while ( crnt != end ) {
     820                                // it is guaranteed that a ttype variable will be bound to a flat tuple, so ensure
     821                                // that this results in a flat tuple
     822                                flatten( (*crnt)->get_type(), types );
     823
     824                                ++crnt;
     825                        }
     826
     827                        return { new ast::TupleType{ std::move(types) } };
     828                }
     829
     830                template< typename Iter >
     831                static bool unifyDeclList(
     832                        Iter crnt1, Iter end1, Iter crnt2, Iter end2, ast::TypeEnvironment & env,
     833                        ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open,
     834                        const ast::SymbolTable & symtab
     835                ) {
     836                        while ( crnt1 != end1 && crnt2 != end2 ) {
     837                                const ast::Type * t1 = (*crnt1)->get_type();
     838                                const ast::Type * t2 = (*crnt2)->get_type();
     839                                bool isTuple1 = Tuples::isTtype( t1 );
     840                                bool isTuple2 = Tuples::isTtype( t2 );
     841
     842                                // assumes here that ttype *must* be last parameter
     843                                if ( isTuple1 && ! isTuple2 ) {
     844                                        // combine remainder of list2, then unify
     845                                        return unifyExact(
     846                                                t1, tupleFromDecls( crnt2, end2 ), env, need, have, open,
     847                                                noWiden(), symtab );
     848                                } else if ( ! isTuple1 && isTuple2 ) {
     849                                        // combine remainder of list1, then unify
     850                                        return unifyExact(
     851                                                tupleFromDecls( crnt1, end1 ), t2, env, need, have, open,
     852                                                noWiden(), symtab );
     853                                }
     854
     855                                if ( ! unifyExact(
     856                                        t1, t2, env, need, have, open, noWiden(), symtab )
     857                                ) return false;
     858
     859                                ++crnt1; ++crnt2;
     860                        }
     861
     862                        // May get to the end of one argument list before the other. This is only okay if the
     863                        // other is a ttype
     864                        if ( crnt1 != end1 ) {
     865                                // try unifying empty tuple with ttype
     866                                const ast::Type * t1 = (*crnt1)->get_type();
     867                                if ( ! Tuples::isTtype( t1 ) ) return false;
     868                                return unifyExact(
     869                                        t1, tupleFromDecls( crnt2, end2 ), env, need, have, open,
     870                                        noWiden(), symtab );
     871                        } else if ( crnt2 != end2 ) {
     872                                // try unifying empty tuple with ttype
     873                                const ast::Type * t2 = (*crnt2)->get_type();
     874                                if ( ! Tuples::isTtype( t2 ) ) return false;
     875                                return unifyExact(
     876                                        tupleFromDecls( crnt1, end1 ), t2, env, need, have, open,
     877                                        noWiden(), symtab );
     878                        }
     879
     880                        return true;
     881                }
     882
     883                static bool unifyDeclList(
     884                        const std::vector< ast::ptr< ast::DeclWithType > > & list1,
     885                        const std::vector< ast::ptr< ast::DeclWithType > > & list2,
     886                        ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
     887                        const ast::OpenVarSet & open, const ast::SymbolTable & symtab
     888                ) {
     889                        return unifyDeclList(
     890                                list1.begin(), list1.end(), list2.begin(), list2.end(), env, need, have, open,
     891                                symtab );
     892                }
     893
     894                static void markAssertionSet( ast::AssertionSet & assns, const ast::DeclWithType * assn ) {
     895                        auto i = assns.find( assn );
     896                        if ( i != assns.end() ) {
     897                                i->second.isUsed = true;
     898                        }
     899                }
     900
     901                /// mark all assertions in `type` used in both `assn1` and `assn2`
     902                static void markAssertions(
     903                        ast::AssertionSet & assn1, ast::AssertionSet & assn2,
     904                        const ast::ParameterizedType * type
     905                ) {
     906                        for ( const auto & tyvar : type->forall ) {
     907                                for ( const ast::DeclWithType * assert : tyvar->assertions ) {
     908                                        markAssertionSet( assn1, assert );
     909                                        markAssertionSet( assn2, assert );
     910                                }
     911                        }
     912                }
     913
     914        public:
     915                void postvisit( const ast::FunctionType * func ) {
     916                        auto func2 = dynamic_cast< const ast::FunctionType * >( type2 );
     917                        if ( ! func2 ) return;
     918
     919                        if ( func->isVarArgs != func2->isVarArgs ) return;
     920
     921                        // Flatten the parameter lists for both functions so that tuple structure does not
     922                        // affect unification. Does not actually mutate function parameters.
     923                        auto params = flattenList( func->params, tenv );
     924                        auto params2 = flattenList( func2->params, tenv );
     925
     926                        // sizes don't have to match if ttypes are involved; need to be more precise w.r.t.
     927                        // where the ttype is to prevent errors
     928                        if (
     929                                ( params.size() != params2.size() || func->returns.size() != func2->returns.size() )
     930                                && ! func->isTtype()
     931                                && ! func2->isTtype()
     932                        ) return;
     933
     934                        if ( ! unifyDeclList( params, params2, tenv, need, have, open, symtab ) ) return;
     935                        if ( ! unifyDeclList(
     936                                func->returns, func2->returns, tenv, need, have, open, symtab ) ) return;
     937
     938                        markAssertions( have, need, func );
     939                        markAssertions( have, need, func2 );
     940
     941                        result = true;
     942                }
     943
     944        private:
     945                template< typename RefType >
     946                const RefType * handleRefType( const RefType * inst, const ast::Type * other ) {
     947                        // check that the other type is compatible and named the same
     948                        auto otherInst = dynamic_cast< const RefType * >( other );
     949                        result = otherInst && inst->name == otherInst->name;
     950                        return otherInst;
     951                }
     952
     953                /// Creates a tuple type based on a list of TypeExpr
     954                template< typename Iter >
     955                static const ast::Type * tupleFromExprs(
     956                        const ast::TypeExpr * param, Iter & crnt, Iter end, ast::CV::Qualifiers qs
     957                ) {
     958                        std::vector< ast::ptr< ast::Type > > types;
     959                        do {
     960                                types.emplace_back( param->type );
     961
     962                                ++crnt;
     963                                if ( crnt == end ) break;
     964                                param = strict_dynamic_cast< const ast::TypeExpr * >( crnt->get() );
     965                        } while(true);
     966
     967                        return new ast::TupleType{ std::move(types), qs };
     968                }
     969
     970                template< typename RefType >
     971                void handleGenericRefType( const RefType * inst, const ast::Type * other ) {
     972                        // check that other type is compatible and named the same
     973                        const RefType * inst2 = handleRefType( inst, other );
     974                        if ( ! inst2 ) return;
     975
     976                        // check that parameters of types unify, if any
     977                        const std::vector< ast::ptr< ast::Expr > > & params = inst->params;
     978                        const std::vector< ast::ptr< ast::Expr > > & params2 = inst2->params;
     979
     980                        auto it = params.begin();
     981                        auto jt = params2.begin();
     982                        for ( ; it != params.end() && jt != params2.end(); ++it, ++jt ) {
     983                                auto param = strict_dynamic_cast< const ast::TypeExpr * >( it->get() );
     984                                auto param2 = strict_dynamic_cast< const ast::TypeExpr * >( jt->get() );
     985
     986                                ast::ptr< ast::Type > pty = param->type;
     987                                ast::ptr< ast::Type > pty2 = param2->type;
     988
     989                                bool isTuple = Tuples::isTtype( pty );
     990                                bool isTuple2 = Tuples::isTtype( pty2 );
     991
     992                                if ( isTuple && isTuple2 ) {
     993                                        ++it; ++jt;  // skip ttype parameters before break
     994                                } else if ( isTuple ) {
     995                                        // bundle remaining params into tuple
     996                                        pty2 = tupleFromExprs( param2, jt, params2.end(), pty->qualifiers );
     997                                        ++it;  // skip ttype parameter for break
     998                                } else if ( isTuple2 ) {
     999                                        // bundle remaining params into tuple
     1000                                        pty = tupleFromExprs( param, it, params.end(), pty2->qualifiers );
     1001                                        ++jt;  // skip ttype parameter for break
     1002                                }
     1003
     1004                                if ( ! unifyExact(
     1005                                                pty, pty2, tenv, need, have, open, noWiden(), symtab ) ) {
     1006                                        result = false;
     1007                                        return;
     1008                                }
     1009
     1010                                // ttype parameter should be last
     1011                                if ( isTuple || isTuple2 ) break;
     1012                        }
     1013                        result = it == params.end() && jt == params2.end();
     1014                }
     1015
     1016        public:
     1017                void postvisit( const ast::StructInstType * aggrType ) {
     1018                        handleGenericRefType( aggrType, type2 );
     1019                }
     1020
     1021                void postvisit( const ast::UnionInstType * aggrType ) {
     1022                        handleGenericRefType( aggrType, type2 );
     1023                }
     1024
     1025                void postvisit( const ast::EnumInstType * aggrType ) {
     1026                        handleRefType( aggrType, type2 );
     1027                }
     1028
     1029                void postvisit( const ast::TraitInstType * aggrType ) {
     1030                        handleRefType( aggrType, type2 );
     1031                }
     1032
     1033                void postvisit( const ast::TypeInstType * typeInst ) {
     1034                        assert( open.find( typeInst->name ) == open.end() );
     1035                        handleRefType( typeInst, type2 );
     1036                }
     1037
     1038        private:
     1039                /// Creates a tuple type based on a list of Type
     1040                static ast::ptr< ast::Type > tupleFromTypes(
     1041                        const std::vector< ast::ptr< ast::Type > > & tys
     1042                ) {
     1043                        std::vector< ast::ptr< ast::Type > > out;
     1044                        for ( const ast::Type * ty : tys ) {
     1045                                // it is guaranteed that a ttype variable will be bound to a flat tuple, so ensure
     1046                                // that this results in a flat tuple
     1047                                flatten( ty, out );
     1048                        }
     1049
     1050                        return { new ast::TupleType{ std::move(out) } };
     1051                }
     1052
     1053                static bool unifyList(
     1054                        const std::vector< ast::ptr< ast::Type > > & list1,
     1055                        const std::vector< ast::ptr< ast::Type > > & list2, ast::TypeEnvironment & env,
     1056                        ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open,
     1057                        const ast::SymbolTable & symtab
     1058                ) {
     1059                        auto crnt1 = list1.begin();
     1060                        auto crnt2 = list2.begin();
     1061                        while ( crnt1 != list1.end() && crnt2 != list2.end() ) {
     1062                                const ast::Type * t1 = *crnt1;
     1063                                const ast::Type * t2 = *crnt2;
     1064                                bool isTuple1 = Tuples::isTtype( t1 );
     1065                                bool isTuple2 = Tuples::isTtype( t2 );
     1066
     1067                                // assumes ttype must be last parameter
     1068                                if ( isTuple1 && ! isTuple2 ) {
     1069                                        // combine entirety of list2, then unify
     1070                                        return unifyExact(
     1071                                                t1, tupleFromTypes( list2 ), env, need, have, open,
     1072                                                noWiden(), symtab );
     1073                                } else if ( ! isTuple1 && isTuple2 ) {
     1074                                        // combine entirety of list1, then unify
     1075                                        return unifyExact(
     1076                                                tupleFromTypes( list1 ), t2, env, need, have, open,
     1077                                                noWiden(), symtab );
     1078                                }
     1079
     1080                                if ( ! unifyExact(
     1081                                        t1, t2, env, need, have, open, noWiden(), symtab )
     1082                                ) return false;
     1083
     1084                                ++crnt1; ++crnt2;
     1085                        }
     1086
     1087                        if ( crnt1 != list1.end() ) {
     1088                                // try unifying empty tuple type with ttype
     1089                                const ast::Type * t1 = *crnt1;
     1090                                if ( ! Tuples::isTtype( t1 ) ) return false;
     1091                                // xxx - this doesn't generate an empty tuple, contrary to comment; both ported
     1092                                // from Rob's code
     1093                                return unifyExact(
     1094                                                t1, tupleFromTypes( list2 ), env, need, have, open,
     1095                                                noWiden(), symtab );
     1096                        } else if ( crnt2 != list2.end() ) {
     1097                                // try unifying empty tuple with ttype
     1098                                const ast::Type * t2 = *crnt2;
     1099                                if ( ! Tuples::isTtype( t2 ) ) return false;
     1100                                // xxx - this doesn't generate an empty tuple, contrary to comment; both ported
     1101                                // from Rob's code
     1102                                return unifyExact(
     1103                                                tupleFromTypes( list1 ), t2, env, need, have, open,
     1104                                                noWiden(), symtab );
     1105                        }
     1106
     1107                        return true;
     1108                }
     1109
     1110        public:
     1111                void postvisit( const ast::TupleType * tuple ) {
     1112                        auto tuple2 = dynamic_cast< const ast::TupleType * >( type2 );
     1113                        if ( ! tuple2 ) return;
     1114
     1115                        ast::Pass<TtypeExpander_new> expander{ tenv };
     1116                        const ast::Type * flat = tuple->accept( expander );
     1117                        const ast::Type * flat2 = tuple2->accept( expander );
     1118
     1119                        auto types = flatten( flat );
     1120                        auto types2 = flatten( flat2 );
     1121
     1122                        result = unifyList( types, types2, tenv, need, have, open, symtab );
     1123                }
     1124
     1125                void postvisit( const ast::VarArgsType * ) {
     1126                        result = dynamic_cast< const ast::VarArgsType * >( type2 );
     1127                }
     1128
     1129                void postvisit( const ast::ZeroType * ) {
     1130                        result = dynamic_cast< const ast::ZeroType * >( type2 );
     1131                }
     1132
     1133                void postvisit( const ast::OneType * ) {
     1134                        result = dynamic_cast< const ast::OneType * >( type2 );
     1135                }
     1136
     1137          private:
     1138                template< typename RefType > void handleRefType( RefType *inst, Type *other );
     1139                template< typename RefType > void handleGenericRefType( RefType *inst, Type *other );
     1140        };
     1141
     1142        bool unify(
     1143                        const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2,
     1144                        ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
     1145                        ast::OpenVarSet & open, const ast::SymbolTable & symtab
     1146        ) {
     1147                ast::ptr<ast::Type> common;
     1148                return unify( type1, type2, env, need, have, open, symtab, common );
     1149        }
     1150
     1151        bool unify(
     1152                        const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2,
     1153                        ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
     1154                        ast::OpenVarSet & open, const ast::SymbolTable & symtab, ast::ptr<ast::Type> & common
     1155        ) {
     1156                ast::OpenVarSet closed;
     1157                findOpenVars( type1, open, closed, need, have, FirstClosed );
     1158                findOpenVars( type2, open, closed, need, have, FirstOpen );
     1159                return unifyInexact(
     1160                        type1, type2, env, need, have, open, WidenMode{ true, true }, symtab, common );
     1161        }
     1162
     1163        bool unifyExact(
     1164                        const ast::Type * type1, const ast::Type * type2, ast::TypeEnvironment & env,
     1165                        ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open,
     1166                        WidenMode widen, const ast::SymbolTable & symtab
     1167        ) {
     1168                if ( type1->qualifiers != type2->qualifiers ) return false;
     1169
     1170                auto var1 = dynamic_cast< const ast::TypeInstType * >( type1 );
     1171                auto var2 = dynamic_cast< const ast::TypeInstType * >( type2 );
     1172                ast::OpenVarSet::const_iterator
     1173                        entry1 = var1 ? open.find( var1->name ) : open.end(),
     1174                        entry2 = var2 ? open.find( var2->name ) : open.end();
     1175                bool isopen1 = entry1 != open.end();
     1176                bool isopen2 = entry2 != open.end();
     1177
     1178                if ( isopen1 && isopen2 ) {
     1179                        if ( entry1->second.kind != entry2->second.kind ) return false;
     1180                        return env.bindVarToVar(
     1181                                var1, var2, ast::TypeDecl::Data{ entry1->second, entry2->second }, need, have,
     1182                                open, widen, symtab );
     1183                } else if ( isopen1 ) {
     1184                        return env.bindVar( var1, type2, entry1->second, need, have, open, widen, symtab );
     1185                } else if ( isopen2 ) {
     1186                        return env.bindVar( var2, type1, entry2->second, need, have, open, widen, symtab );
     1187                } else {
     1188                        ast::Pass<Unify_new> comparator{ type2, env, need, have, open, widen, symtab };
     1189                        type1->accept( comparator );
     1190                        return comparator.pass.result;
     1191                }
     1192        }
     1193
     1194        bool unifyInexact(
     1195                        const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2,
     1196                        ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
     1197                        const ast::OpenVarSet & open, WidenMode widen, const ast::SymbolTable & symtab,
     1198                        ast::ptr<ast::Type> & common
     1199        ) {
     1200                ast::CV::Qualifiers q1 = type1->qualifiers, q2 = type2->qualifiers;
     1201
     1202                // force t1 and t2 to be cloned if their qualifiers must be stripped, so that type1 and
     1203                // type2 are left unchanged; calling convention forces type{1,2}->strong_ref >= 1
     1204                ast::ptr<ast::Type> t1{ type1 }, t2{ type2 };
     1205                reset_qualifiers( t1 );
     1206                reset_qualifiers( t2 );
     1207
     1208                if ( unifyExact( t1, t2, env, need, have, open, widen, symtab ) ) {
     1209                        t1 = nullptr; t2 = nullptr; // release t1, t2 to avoid spurious clones
     1210
     1211                        // if exact unification on unqualified types, try to merge qualifiers
     1212                        if ( q1 == q2 || ( ( q1 > q2 || widen.first ) && ( q2 > q1 || widen.second ) ) ) {
     1213                                common = type1;
     1214                                reset_qualifiers( common, q1 | q2 );
     1215                                return true;
     1216                        } else {
     1217                                return false;
     1218                        }
     1219
     1220                } else if (( common = commonType( t1, t2, widen, symtab, env, open ) )) {
     1221                        t1 = nullptr; t2 = nullptr; // release t1, t2 to avoid spurious clones
     1222
     1223                        // no exact unification, but common type
     1224                        reset_qualifiers( common, q1 | q2 );
     1225                        return true;
     1226                } else {
     1227                        return false;
     1228                }
     1229        }
     1230
     1231        ast::ptr<ast::Type> extractResultType( const ast::FunctionType * func ) {
     1232                if ( func->returns.empty() ) return new ast::VoidType{};
     1233                if ( func->returns.size() == 1 ) return func->returns[0]->get_type();
     1234
     1235                std::vector<ast::ptr<ast::Type>> tys;
     1236                for ( const ast::DeclWithType * decl : func->returns ) {
     1237                        tys.emplace_back( decl->get_type() );
     1238                }
     1239                return new ast::TupleType{ std::move(tys) };
     1240        }
    7881241} // namespace ResolvExpr
    7891242
  • src/ResolvExpr/Unify.h

    r7951100 rb067d9b  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 13:09:04 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Jul 21 23:09:34 2017
    13 // Update Count     : 3
     11// Last Modified By : Aaron B. Moss
     12// Last Modified On : Mon Jun 18 11:58:00 2018
     13// Update Count     : 4
    1414//
    1515
     
    1818#include <list>                   // for list
    1919
     20#include "AST/Node.hpp"             // for ptr
     21#include "AST/TypeEnvironment.hpp"  // for TypeEnvironment, AssertionSet, OpenVarSet
    2022#include "Common/utility.h"       // for deleteAll
    2123#include "SynTree/Declaration.h"  // for TypeDecl, TypeDecl::Data
    2224#include "TypeEnvironment.h"      // for AssertionSet, OpenVarSet
     25#include "WidenMode.h"              // for WidenMode
    2326
    2427class Type;
    2528class TypeInstType;
    2629namespace SymTab {
    27 class Indexer;
    28 }  // namespace SymTab
     30        class Indexer;
     31}
     32
     33namespace ast {
     34        class SymbolTable;
     35        class Type;
     36}
    2937
    3038namespace ResolvExpr {
    31         struct WidenMode {
    32                 WidenMode( bool widenFirst, bool widenSecond ): widenFirst( widenFirst ), widenSecond( widenSecond ) {}
    33                 WidenMode &operator|=( const WidenMode &other ) { widenFirst |= other.widenFirst; widenSecond |= other.widenSecond; return *this; }
    34                 WidenMode &operator&=( const WidenMode &other ) { widenFirst &= other.widenFirst; widenSecond &= other.widenSecond; return *this; }
    35                 WidenMode operator|( const WidenMode &other ) { WidenMode newWM( *this ); newWM |= other; return newWM; }
    36                 WidenMode operator&( const WidenMode &other ) { WidenMode newWM( *this ); newWM &= other; return newWM; }
    37                 operator bool() { return widenFirst && widenSecond; }
    38 
    39                 bool widenFirst : 1, widenSecond : 1;
    40         };
    41 
    42         bool bindVar( TypeInstType *typeInst, Type *other, const TypeDecl::Data & data, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer );
    4339        bool unify( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer );
    4440        bool unify( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer, Type *&commonType );
    4541        bool unifyExact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, OpenVarSet &openVars, const SymTab::Indexer &indexer );
     42        bool unifyInexact( Type *type1, Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widen, const SymTab::Indexer &indexer, Type *&common );
    4643
    4744        template< typename Iterator1, typename Iterator2 >
     
    7269        }
    7370
     71        bool unify(
     72                const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2,
     73                ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
     74                ast::OpenVarSet & open, const ast::SymbolTable & symtab );
     75
     76        bool unify(
     77                const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2,
     78                ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
     79                ast::OpenVarSet & open, const ast::SymbolTable & symtab, ast::ptr<ast::Type> & common );
     80
     81        bool unifyExact(
     82                const ast::Type * type1, const ast::Type * type2, ast::TypeEnvironment & env,
     83                ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open,
     84                WidenMode widen, const ast::SymbolTable & symtab );
     85
     86        bool unifyInexact(
     87                const ast::ptr<ast::Type> & type1, const ast::ptr<ast::Type> & type2,
     88                ast::TypeEnvironment & env, ast::AssertionSet & need, ast::AssertionSet & have,
     89                const ast::OpenVarSet & open, WidenMode widen, const ast::SymbolTable & symtab,
     90                ast::ptr<ast::Type> & common );
     91
    7492} // namespace ResolvExpr
    7593
  • src/ResolvExpr/module.mk

    r7951100 rb067d9b  
    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
     17SRC_RESOLVEXPR = \
     18      ResolvExpr/AdjustExprType.cc \
     19      ResolvExpr/Alternative.cc \
     20      ResolvExpr/AlternativeFinder.cc \
     21      ResolvExpr/Candidate.cpp \
     22      ResolvExpr/CandidateFinder.cpp \
     23      ResolvExpr/CastCost.cc \
     24      ResolvExpr/CommonType.cc \
     25      ResolvExpr/ConversionCost.cc \
     26      ResolvExpr/CurrentObject.cc \
     27      ResolvExpr/ExplodedActual.cc \
     28      ResolvExpr/ExplodedArg.cpp \
     29      ResolvExpr/FindOpenVars.cc \
     30      ResolvExpr/Occurs.cc \
     31      ResolvExpr/PolyCost.cc \
     32      ResolvExpr/PtrsAssignable.cc \
     33      ResolvExpr/PtrsCastable.cc \
     34      ResolvExpr/RenameVars.cc \
     35      ResolvExpr/ResolveAssertions.cc \
     36      ResolvExpr/Resolver.cc \
     37      ResolvExpr/ResolveTypeof.cc \
     38      ResolvExpr/SatisfyAssertions.cpp \
     39      ResolvExpr/SpecCost.cc \
     40      ResolvExpr/TypeEnvironment.cc \
     41      ResolvExpr/Unify.cc
     42
     43SRC += $(SRC_RESOLVEXPR) ResolvExpr/AlternativePrinter.cc
     44SRCDEMANGLE += $(SRC_RESOLVEXPR)
  • src/ResolvExpr/typeops.h

    r7951100 rb067d9b  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 07:28:22 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Jul 22 09:36:18 2017
    13 // Update Count     : 3
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Thu Aug  8 16:36:00 2019
     13// Update Count     : 5
    1414//
    1515
     
    1818#include <vector>
    1919
     20#include "Cost.h"
     21#include "TypeEnvironment.h"
     22#include "WidenMode.h"
     23#include "AST/Fwd.hpp"
     24#include "AST/Node.hpp"
     25#include "AST/SymbolTable.hpp"
     26#include "AST/Type.hpp"
     27#include "AST/TypeEnvironment.hpp"
    2028#include "SynTree/SynTree.h"
    2129#include "SynTree/Type.h"
    22 #include "SymTab/Indexer.h"
    23 #include "Cost.h"
    24 #include "TypeEnvironment.h"
     30
     31namespace SymTab {
     32        class Indexer;
     33}
    2534
    2635namespace ResolvExpr {
     
    5463        // in AdjustExprType.cc
    5564        /// Replaces array types with the equivalent pointer, and function types with a pointer-to-function
    56         void adjustExprType( Type *&type, const TypeEnvironment &env, const SymTab::Indexer &indexer );
     65        void adjustExprType( Type *& type, const TypeEnvironment & env, const SymTab::Indexer & indexer );
    5766
    5867        /// Replaces array types with the equivalent pointer, and function types with a pointer-to-function using empty TypeEnvironment and Indexer
     
    6069
    6170        template< typename ForwardIterator >
    62         void adjustExprTypeList( ForwardIterator begin, ForwardIterator end, const TypeEnvironment &env, const SymTab::Indexer &indexer ) {
     71        void adjustExprTypeList( ForwardIterator begin, ForwardIterator end, const TypeEnvironment & env, const SymTab::Indexer & indexer ) {
    6372                while ( begin != end ) {
    6473                        adjustExprType( *begin++, env, indexer );
     
    6675        }
    6776
     77        /// Replaces array types with equivalent pointer, and function types with a pointer-to-function
     78        const ast::Type * adjustExprType(
     79                const ast::Type * type, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab );
     80
    6881        // in CastCost.cc
    69         Cost castCost( Type *src, Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env );
     82        Cost castCost( const Type * src, const Type * dest, bool srcIsLvalue,
     83                const SymTab::Indexer & indexer, const TypeEnvironment & env );
     84        Cost castCost(
     85                const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab,
     86                const ast::TypeEnvironment & env );
    7087
    7188        // in ConversionCost.cc
    72         Cost conversionCost( Type *src, Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env );
     89        Cost conversionCost( const Type * src, const Type * dest, bool srcIsLvalue,
     90                const SymTab::Indexer & indexer, const TypeEnvironment & env );
     91        Cost conversionCost(
     92                const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab,
     93                const ast::TypeEnvironment & env );
     94
     95        // in AlternativeFinder.cc
     96        Cost computeConversionCost( Type * actualType, Type * formalType, bool actualIsLvalue,
     97                const SymTab::Indexer & indexer, const TypeEnvironment & env );
    7398
    7499        // in PtrsAssignable.cc
    75         int ptrsAssignable( Type *src, Type *dest, const TypeEnvironment &env );
     100        int ptrsAssignable( const Type * src, const Type * dest, const TypeEnvironment & env );
     101        int ptrsAssignable( const ast::Type * src, const ast::Type * dst,
     102                const ast::TypeEnvironment & env );
    76103
    77104        // in PtrsCastable.cc
    78         int ptrsCastable( Type *src, Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer );
     105        int ptrsCastable( const Type * src, const Type * dest, const TypeEnvironment & env, const SymTab::Indexer & indexer );
     106        int ptrsCastable(
     107                const ast::Type * src, const ast::Type * dst, const ast::SymbolTable & symtab,
     108                const ast::TypeEnvironment & env );
    79109
    80110        // in Unify.cc
    81         bool isFtype( Type *type );
    82         bool typesCompatible( Type *, Type *, const SymTab::Indexer &indexer, const TypeEnvironment &env );
    83         bool typesCompatibleIgnoreQualifiers( Type *, Type *, const SymTab::Indexer &indexer, const TypeEnvironment &env );
    84 
    85         inline bool typesCompatible( Type *t1, Type *t2, const SymTab::Indexer &indexer ) {
     111        bool typesCompatible( const Type *, const Type *, const SymTab::Indexer & indexer, const TypeEnvironment & env );
     112        bool typesCompatibleIgnoreQualifiers( const Type *, const Type *, const SymTab::Indexer & indexer, const TypeEnvironment & env );
     113
     114        inline bool typesCompatible( const Type * t1, const Type * t2, const SymTab::Indexer & indexer ) {
    86115                TypeEnvironment env;
    87116                return typesCompatible( t1, t2, indexer, env );
    88117        }
    89118
    90         inline bool typesCompatibleIgnoreQualifiers( Type *t1, Type *t2, const SymTab::Indexer &indexer ) {
     119        inline bool typesCompatibleIgnoreQualifiers( const Type * t1, const Type * t2, const SymTab::Indexer & indexer ) {
    91120                TypeEnvironment env;
    92121                return typesCompatibleIgnoreQualifiers( t1, t2, indexer, env );
    93122        }
    94123
     124        bool typesCompatible(
     125                const ast::Type *, const ast::Type *, const ast::SymbolTable & symtab = {},
     126                const ast::TypeEnvironment & env = {} );
     127
     128        bool typesCompatibleIgnoreQualifiers(
     129                const ast::Type *, const ast::Type *, const ast::SymbolTable &,
     130                const ast::TypeEnvironment & env = {} );
     131
    95132        /// creates the type represented by the list of returnVals in a FunctionType. The caller owns the return value.
    96133        Type * extractResultType( FunctionType * functionType );
     134        /// Creates or extracts the type represented by the list of returns in a `FunctionType`.
     135        ast::ptr<ast::Type> extractResultType( const ast::FunctionType * func );
    97136
    98137        // in CommonType.cc
    99         Type *commonType( Type *type1, Type *type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars );
     138        Type * commonType( Type * type1, Type * type2, bool widenFirst, bool widenSecond, const SymTab::Indexer & indexer, TypeEnvironment & env, const OpenVarSet & openVars );
     139        ast::ptr< ast::Type > commonType(
     140                const ast::ptr< ast::Type > & type1, const ast::ptr< ast::Type > & type2, WidenMode widen,
     141                const ast::SymbolTable & symtab, ast::TypeEnvironment & env, const ast::OpenVarSet & open );
    100142
    101143        // in PolyCost.cc
    102         int polyCost( Type *type, const TypeEnvironment &env, const SymTab::Indexer &indexer );
     144        int polyCost( Type * type, const TypeEnvironment & env, const SymTab::Indexer & indexer );
     145        int polyCost(
     146                const ast::Type * type, const ast::SymbolTable & symtab, const ast::TypeEnvironment & env );
     147
     148        // in SpecCost.cc
     149        int specCost( Type * type );
     150        int specCost( const ast::Type * type );
    103151
    104152        // in Occurs.cc
    105         bool occurs( Type *type, std::string varName, const TypeEnvironment &env );
     153        bool occurs( const Type * type, const std::string & varName, const TypeEnvironment & env );
     154        // new AST version in TypeEnvironment.cpp (only place it was used in old AST)
     155
     156        template<typename Iter>
     157        bool occursIn( Type* ty, Iter begin, Iter end, const TypeEnvironment & env ) {
     158                while ( begin != end ) {
     159                        if ( occurs( ty, *begin, env ) ) return true;
     160                        ++begin;
     161                }
     162                return false;
     163        }
    106164
    107165        // in AlternativeFinder.cc
    108166        void referenceToRvalueConversion( Expression *& expr, Cost & cost );
    109 
    110         // flatten tuple type into list of types
     167        // in CandidateFinder.cpp
     168        const ast::Expr * referenceToRvalueConversion( const ast::Expr * expr, Cost & cost );
     169
     170        /// flatten tuple type into list of types
    111171        template< typename OutputIterator >
    112172        void flatten( Type * type, OutputIterator out ) {
     
    119179                }
    120180        }
     181
     182        /// flatten tuple type into existing list of types
     183        static inline void flatten(
     184                const ast::Type * type, std::vector< ast::ptr< ast::Type > > & out
     185        ) {
     186                if ( auto tupleType = dynamic_cast< const ast::TupleType * >( type ) ) {
     187                        for ( const ast::Type * t : tupleType->types ) {
     188                                flatten( t, out );
     189                        }
     190                } else {
     191                        out.emplace_back( type );
     192                }
     193        }
     194
     195        /// flatten tuple type into list of types
     196        static inline std::vector< ast::ptr< ast::Type > > flatten( const ast::Type * type ) {
     197                std::vector< ast::ptr< ast::Type > > out;
     198                out.reserve( type->size() );
     199                flatten( type, out );
     200                return out;
     201        }
     202
     203        // in TypeEnvironment.cc
     204        bool isFtype( const Type * type );
    121205} // namespace ResolvExpr
     206
     207namespace ast {
     208        // in TypeEnvironment.cpp
     209        bool isFtype( const ast::Type * type );
     210} // namespace ast
    122211
    123212// Local Variables: //
  • src/SymTab/Autogen.cc

    r7951100 rb067d9b  
    2424#include <vector>                  // for vector
    2525
     26#include "AST/Decl.hpp"
    2627#include "CodeGen/OperatorTable.h" // for isCtorDtor, isCtorDtorAssign
    2728#include "Common/PassVisitor.h"    // for PassVisitor
     
    4142
    4243namespace SymTab {
    43         Type * SizeType = 0;
    44 
    4544        /// Data used to generate functions generically. Specifically, the name of the generated function and a function which generates the routine protoype
    4645        struct FuncData {
    47                 typedef FunctionType * (*TypeGen)( Type * );
     46                typedef FunctionType * (*TypeGen)( Type *, bool );
    4847                FuncData( const std::string & fname, const TypeGen & genType ) : fname( fname ), genType( genType ) {}
    4948                std::string fname;
     
    211210        }
    212211
     212        bool isUnnamedBitfield( const ast::ObjectDecl * obj ) {
     213                return obj && obj->name.empty() && obj->bitfieldWidth;
     214        }
     215
    213216        /// inserts a forward declaration for functionDecl into declsToAdd
    214217        void addForwardDecl( FunctionDecl * functionDecl, std::list< Declaration * > & declsToAdd ) {
     
    231234
    232235        /// given type T, generate type of default ctor/dtor, i.e. function type void (*) (T *)
    233         FunctionType * genDefaultType( Type * paramType ) {
    234                 const auto & typeParams = getGenericParams( paramType );
     236        FunctionType * genDefaultType( Type * paramType, bool maybePolymorphic ) {
    235237                FunctionType *ftype = new FunctionType( Type::Qualifiers(), false );
    236                 cloneAll( typeParams, ftype->forall );
     238                if ( maybePolymorphic ) {
     239                        // only copy in
     240                        const auto & typeParams = getGenericParams( paramType );
     241                        cloneAll( typeParams, ftype->forall );
     242                }
    237243                ObjectDecl *dstParam = new ObjectDecl( "_dst", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new ReferenceType( Type::Qualifiers(), paramType->clone() ), nullptr );
    238244                ftype->parameters.push_back( dstParam );
     
    241247
    242248        /// given type T, generate type of copy ctor, i.e. function type void (*) (T *, T)
    243         FunctionType * genCopyType( Type * paramType ) {
    244                 FunctionType *ftype = genDefaultType( paramType );
     249        FunctionType * genCopyType( Type * paramType, bool maybePolymorphic ) {
     250                FunctionType *ftype = genDefaultType( paramType, maybePolymorphic );
    245251                ObjectDecl *srcParam = new ObjectDecl( "_src", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, paramType->clone(), nullptr );
    246252                ftype->parameters.push_back( srcParam );
     
    249255
    250256        /// given type T, generate type of assignment, i.e. function type T (*) (T *, T)
    251         FunctionType * genAssignType( Type * paramType ) {
    252                 FunctionType *ftype = genCopyType( paramType );
     257        FunctionType * genAssignType( Type * paramType, bool maybePolymorphic ) {
     258                FunctionType *ftype = genCopyType( paramType, maybePolymorphic );
    253259                ObjectDecl *returnVal = new ObjectDecl( "_ret", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, paramType->clone(), nullptr );
    254260                ftype->returnVals.push_back( returnVal );
     
    308314                for ( const FuncData & d : data ) {
    309315                        // generate a function (?{}, ?=?, ^?{}) based on the current FuncData.
    310                         FunctionType * ftype = d.genType( type );
     316                        FunctionType * ftype = d.genType( type, true );
    311317
    312318                        // destructor for concurrent type must be mutex
     
    387393
    388394        void StructFuncGenerator::makeMemberOp( ObjectDecl * dstParam, Expression * src, DeclarationWithType * field, FunctionDecl * func, bool forward ) {
    389                 InitTweak::InitExpander srcParam( src );
     395                InitTweak::InitExpander_old srcParam( src );
    390396
    391397                // assign to destination
  • src/SymTab/Autogen.h

    r7951100 rb067d9b  
    1717
    1818#include <cassert>                // for assert
     19#include <iterator>               // for back_inserter
    1920#include <string>                 // for string
    2021
     22#include "AST/Decl.hpp"
     23#include "AST/Expr.hpp"
     24#include "AST/Init.hpp"
     25#include "AST/Node.hpp"
     26#include "AST/Stmt.hpp"
     27#include "AST/Type.hpp"
    2128#include "CodeGen/OperatorTable.h"
    2229#include "Common/UniqueName.h"    // for UniqueName
     30#include "Common/utility.h"       // for splice
    2331#include "InitTweak/InitTweak.h"  // for InitExpander
    2432#include "SynTree/Constant.h"     // for Constant
     
    3644        /// returns true if obj's name is the empty string and it has a bitfield width
    3745        bool isUnnamedBitfield( ObjectDecl * obj );
    38 
    39         /// size_t type - set when size_t typedef is seen. Useful in a few places,
    40         /// such as in determining array dimension type
    41         extern Type * SizeType;
    42 
    43         /// intrinsic dereference operator for unqualified types - set when *? function is seen in FindSpecialDeclarations.
    44         /// Useful for creating dereference ApplicationExprs without a full resolver pass.
    45         extern FunctionDecl * dereferenceOperator;
    46 
    47         // generate the type of an assignment function for paramType
    48         FunctionType * genAssignType( Type * paramType );
    49 
    50         // generate the type of a default constructor or destructor for paramType
    51         FunctionType * genDefaultType( Type * paramType );
    52 
    53         // generate the type of a copy constructor for paramType
    54         FunctionType * genCopyType( Type * paramType );
     46        bool isUnnamedBitfield( const ast::ObjectDecl * obj );
     47
     48        /// generate the type of an assignment function for paramType.
     49        /// maybePolymorphic is true if the resulting FunctionType is allowed to be polymorphic
     50        FunctionType * genAssignType( Type * paramType, bool maybePolymorphic = true );
     51
     52        /// generate the type of a default constructor or destructor for paramType.
     53        /// maybePolymorphic is true if the resulting FunctionType is allowed to be polymorphic
     54        FunctionType * genDefaultType( Type * paramType, bool maybePolymorphic = true );
     55
     56        /// generate the type of a copy constructor for paramType.
     57        /// maybePolymorphic is true if the resulting FunctionType is allowed to be polymorphic
     58        FunctionType * genCopyType( Type * paramType, bool maybePolymorphic = true );
     59
     60        /// Enum for loop direction
     61        enum LoopDirection { LoopBackward, LoopForward };
    5562
    5663        /// inserts into out a generated call expression to function fname with arguments dstParam and srcParam. Intended to be used with generated ?=?, ?{}, and ^?{} calls.
    5764        template< typename OutputIterator >
    58         Statement * genCall( InitTweak::InitExpander & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, Type * addCast = nullptr, bool forward = true );
     65        Statement * genCall( InitTweak::InitExpander_old & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, Type * addCast = nullptr, bool forward = true );
     66
     67        template< typename OutIter >
     68        ast::ptr< ast::Stmt > genCall(
     69                InitTweak::InitExpander_new & srcParam, const ast::Expr * dstParam,
     70                const CodeLocation & loc, const std::string & fname, OutIter && out,
     71                const ast::Type * type, const ast::Type * addCast, LoopDirection forward = LoopForward );
    5972
    6073        /// inserts into out a generated call expression to function fname with arguments dstParam and srcParam. Should only be called with non-array types.
    6174        /// optionally returns a statement which must be inserted prior to the containing loop, if there is one
    6275        template< typename OutputIterator >
    63         Statement * genScalarCall( InitTweak::InitExpander & srcParam, Expression * dstParam, std::string fname, OutputIterator out, Type * type, Type * addCast = nullptr ) {
     76        Statement * genScalarCall( InitTweak::InitExpander_old & srcParam, Expression * dstParam, std::string fname, OutputIterator out, Type * type, Type * addCast = nullptr ) {
    6477                bool isReferenceCtorDtor = false;
    6578                if ( dynamic_cast< ReferenceType * >( type ) && CodeGen::isCtorDtor( fname ) ) {
     
    8497                        //   type->get_qualifiers() = Type::Qualifiers();
    8598                        Type * castType = addCast->clone();
    86                         castType->get_qualifiers() -= Type::Qualifiers( Type::Lvalue | Type::Const | Type::Volatile | Type::Restrict | Type::Atomic );
     99                        castType->get_qualifiers() -= Type::Qualifiers( Type::Const | Type::Volatile | Type::Restrict | Type::Atomic );
    87100                        // castType->set_lvalue( true ); // xxx - might not need this
    88101                        dstParam = new CastExpr( dstParam, new ReferenceType( Type::Qualifiers(), castType ) );
     
    111124        }
    112125
     126        /// inserts into out a generated call expression to function fname with arguments dstParam and
     127        /// srcParam. Should only be called with non-array types.
     128        /// optionally returns a statement which must be inserted prior to the containing loop, if
     129        /// there is one
     130        template< typename OutIter >
     131        ast::ptr< ast::Stmt > genScalarCall(
     132                InitTweak::InitExpander_new & srcParam, const ast::Expr * dstParam,
     133                const CodeLocation & loc, std::string fname, OutIter && out, const ast::Type * type,
     134                const ast::Type * addCast = nullptr
     135        ) {
     136                bool isReferenceCtorDtor = false;
     137                if ( dynamic_cast< const ast::ReferenceType * >( type ) && CodeGen::isCtorDtor( fname ) ) {
     138                        // reference constructors are essentially application of the rebind operator.
     139                        // apply & to both arguments, do not need a cast
     140                        fname = "?=?";
     141                        dstParam = new ast::AddressExpr{ dstParam };
     142                        addCast = nullptr;
     143                        isReferenceCtorDtor = true;
     144                }
     145
     146                // want to be able to generate assignment, ctor, and dtor generically, so fname is one of
     147                // "?=?", "?{}", or "^?{}"
     148                ast::UntypedExpr * fExpr = new ast::UntypedExpr{ loc, new ast::NameExpr{ loc, fname } };
     149
     150                if ( addCast ) {
     151                        // cast to T& with qualifiers removed, so that qualified objects can be constructed and
     152                        // destructed with the same functions as non-qualified objects. Unfortunately, lvalue
     153                        // is considered a qualifier - for AddressExpr to resolve, its argument must have an
     154                        // lvalue-qualified type, so remove all qualifiers except lvalue.
     155                        // xxx -- old code actually removed lvalue too...
     156                        ast::ptr< ast::Type > guard = addCast;  // prevent castType from mutating addCast
     157                        ast::ptr< ast::Type > castType = addCast;
     158                        ast::remove_qualifiers(
     159                                castType,
     160                                ast::CV::Const | ast::CV::Volatile | ast::CV::Restrict | ast::CV::Atomic );
     161                        dstParam = new ast::CastExpr{ dstParam, new ast::ReferenceType{ castType } };
     162                }
     163                fExpr->args.emplace_back( dstParam );
     164
     165                const ast::Stmt * listInit = srcParam.buildListInit( fExpr );
     166
     167                // fetch next set of arguments
     168                ++srcParam;
     169
     170                // return if adding reference fails -- will happen on default ctor and dtor
     171                if ( isReferenceCtorDtor && ! srcParam.addReference() ) return listInit;
     172
     173                std::vector< ast::ptr< ast::Expr > > args = *srcParam;
     174                splice( fExpr->args, args );
     175
     176                *out++ = new ast::ExprStmt{ loc, fExpr };
     177
     178                srcParam.clearArrayIndices();
     179               
     180                return listInit;
     181        }
     182
    113183        /// Store in out a loop which calls fname on each element of the array with srcParam and dstParam as arguments.
    114184        /// If forward is true, loop goes from 0 to N-1, else N-1 to 0
    115185        template< typename OutputIterator >
    116         void genArrayCall( InitTweak::InitExpander & srcParam, Expression *dstParam, const std::string & fname, OutputIterator out, ArrayType *array, Type * addCast = nullptr, bool forward = true ) {
     186        void genArrayCall( InitTweak::InitExpander_old & srcParam, Expression *dstParam, const std::string & fname, OutputIterator out, ArrayType *array, Type * addCast = nullptr, bool forward = true ) {
    117187                static UniqueName indexName( "_index" );
    118188
     
    175245        }
    176246
     247        /// Store in out a loop which calls fname on each element of the array with srcParam and
     248        /// dstParam as arguments. If forward is true, loop goes from 0 to N-1, else N-1 to 0
     249        template< typename OutIter >
     250        void genArrayCall(
     251                InitTweak::InitExpander_new & srcParam, const ast::Expr * dstParam,
     252                const CodeLocation & loc, const std::string & fname, OutIter && out,
     253                const ast::ArrayType * array, const ast::Type * addCast = nullptr,
     254                LoopDirection forward = LoopForward
     255        ) {
     256                static UniqueName indexName( "_index" );
     257
     258                // for a flexible array member nothing is done -- user must define own assignment
     259                if ( ! array->dimension ) return;
     260
     261                if ( addCast ) {
     262                        // peel off array layer from cast
     263                        addCast = strict_dynamic_cast< const ast::ArrayType * >( addCast )->base;
     264                }
     265
     266                ast::ptr< ast::Expr > begin, end, cmp, update;
     267
     268                if ( forward ) {
     269                        // generate: for ( int i = 0; i < N; ++i )
     270                        begin = ast::ConstantExpr::from_int( loc, 0 );
     271                        end = array->dimension;
     272                        cmp = new ast::NameExpr{ loc, "?<?" };
     273                        update = new ast::NameExpr{ loc, "++?" };
     274                } else {
     275                        // generate: for ( int i = N-1; i >= 0; --i )
     276                        begin = new ast::UntypedExpr{
     277                                loc, new ast::NameExpr{ loc, "?-?" },
     278                                { array->dimension, ast::ConstantExpr::from_int( loc, 1 ) } };
     279                        end = ast::ConstantExpr::from_int( loc, 0 );
     280                        cmp = new ast::NameExpr{ loc, "?>=?" };
     281                        update = new ast::NameExpr{ loc, "--?" };
     282                }
     283
     284                ast::ptr< ast::DeclWithType > index = new ast::ObjectDecl{
     285                        loc, indexName.newName(), new ast::BasicType{ ast::BasicType::SignedInt },
     286                        new ast::SingleInit{ loc, begin } };
     287               
     288                ast::ptr< ast::Expr > cond = new ast::UntypedExpr{
     289                        loc, cmp, { new ast::VariableExpr{ loc, index }, end } };
     290               
     291                ast::ptr< ast::Expr > inc = new ast::UntypedExpr{
     292                        loc, update, { new ast::VariableExpr{ loc, index } } };
     293               
     294                ast::ptr< ast::Expr > dstIndex = new ast::UntypedExpr{
     295                        loc, new ast::NameExpr{ loc, "?[?]" },
     296                        { dstParam, new ast::VariableExpr{ loc, index } } };
     297               
     298                // srcParam must keep track of the array indices to build the source parameter and/or
     299                // array list initializer
     300                srcParam.addArrayIndex( new ast::VariableExpr{ loc, index }, array->dimension );
     301
     302                // for stmt's body, eventually containing call
     303                ast::CompoundStmt * body = new ast::CompoundStmt{ loc };
     304                ast::ptr< ast::Stmt > listInit = genCall(
     305                        srcParam, dstIndex, loc, fname, std::back_inserter( body->kids ), array->base, addCast,
     306                        forward );
     307               
     308                // block containing the stmt and index variable
     309                ast::CompoundStmt * block = new ast::CompoundStmt{ loc };
     310                block->push_back( new ast::DeclStmt{ loc, index } );
     311                if ( listInit ) { block->push_back( listInit ); }
     312                block->push_back( new ast::ForStmt{ loc, {}, cond, inc, body } );
     313
     314                *out++ = block;
     315        }
     316
    177317        template< typename OutputIterator >
    178         Statement * genCall( InitTweak::InitExpander & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, Type * addCast, bool forward ) {
     318        Statement * genCall( InitTweak::InitExpander_old & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, Type * addCast, bool forward ) {
    179319                if ( ArrayType * at = dynamic_cast< ArrayType * >( type ) ) {
    180320                        genArrayCall( srcParam, dstParam, fname, out, at, addCast, forward );
     
    185325        }
    186326
     327        template< typename OutIter >
     328        ast::ptr< ast::Stmt > genCall(
     329                InitTweak::InitExpander_new & srcParam, const ast::Expr * dstParam,
     330                const CodeLocation & loc, const std::string & fname, OutIter && out,
     331                const ast::Type * type, const ast::Type * addCast, LoopDirection forward
     332        ) {
     333                if ( auto at = dynamic_cast< const ast::ArrayType * >( type ) ) {
     334                        genArrayCall(
     335                                srcParam, dstParam, loc, fname, std::forward< OutIter >(out), at, addCast,
     336                                forward );
     337                        return {};
     338                } else {
     339                        return genScalarCall(
     340                                srcParam, dstParam, loc, fname, std::forward< OutIter >( out ), type, addCast );
     341                }
     342        }
     343
    187344        /// inserts into out a generated call expression to function fname with arguments dstParam
    188345        /// and srcParam. Intended to be used with generated ?=?, ?{}, and ^?{} calls. decl is the
     
    190347        /// ImplicitCtorDtorStmt node.
    191348        template< typename OutputIterator >
    192         void genImplicitCall( InitTweak::InitExpander & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, DeclarationWithType * decl, bool forward = true ) {
     349        void genImplicitCall( InitTweak::InitExpander_old & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, DeclarationWithType * decl, bool forward = true ) {
    193350                ObjectDecl *obj = dynamic_cast<ObjectDecl *>( decl );
    194351                assert( obj );
     
    218375                }
    219376        }
     377
     378        static inline ast::ptr< ast::Stmt > genImplicitCall(
     379                InitTweak::InitExpander_new & srcParam, const ast::Expr * dstParam,
     380                const CodeLocation & loc, const std::string & fname, const ast::ObjectDecl * obj,
     381                LoopDirection forward = LoopForward
     382        ) {
     383                // unnamed bit fields are not copied as they cannot be accessed
     384                if ( isUnnamedBitfield( obj ) ) return {};
     385
     386                ast::ptr< ast::Type > addCast = nullptr;
     387                if ( (fname == "?{}" || fname == "^?{}") && ( ! obj || ( obj && ! obj->bitfieldWidth ) ) ) {
     388                        assert( dstParam->result );
     389                        addCast = dstParam->result;
     390                }
     391
     392                std::vector< ast::ptr< ast::Stmt > > stmts;
     393                genCall(
     394                        srcParam, dstParam, loc, fname, back_inserter( stmts ), obj->type, addCast, forward );
     395
     396                if ( stmts.empty() ) {
     397                        return {};
     398                } else if ( stmts.size() == 1 ) {
     399                        const ast::Stmt * callStmt = stmts.front();
     400                        if ( addCast ) {
     401                                // implicitly generated ctor/dtor calls should be wrapped so that later passes are
     402                                // aware they were generated.
     403                                callStmt = new ast::ImplicitCtorDtorStmt{ callStmt->location, callStmt };
     404                        }
     405                        return callStmt;
     406                } else {
     407                        assert( false );
     408                        return {};
     409                }
     410        }
    220411} // namespace SymTab
    221412
  • src/SymTab/FixFunction.cc

    r7951100 rb067d9b  
    1818#include <list>                   // for list
    1919
    20 #include "Common/utility.h"       // for maybeClone
     20#include "AST/Decl.hpp"
     21#include "AST/Pass.hpp"
     22#include "AST/Type.hpp"
     23#include "Common/utility.h"       // for maybeClone, copy
    2124#include "SynTree/Declaration.h"  // for FunctionDecl, ObjectDecl, Declarati...
    2225#include "SynTree/Expression.h"   // for Expression
     
    2427
    2528namespace SymTab {
    26         FixFunction::FixFunction() : isVoid( false ) {}
     29        class FixFunction_old : public WithShortCircuiting {
     30                typedef Mutator Parent;
     31          public:
     32                FixFunction_old() : isVoid( false ) {}
    2733
     34                void premutate(FunctionDecl *functionDecl);
     35                DeclarationWithType* postmutate(FunctionDecl *functionDecl);
    2836
    29         DeclarationWithType * FixFunction::postmutate(FunctionDecl *functionDecl) {
     37                Type * postmutate(ArrayType * arrayType);
     38
     39                void premutate(ArrayType * arrayType);
     40                void premutate(VoidType * voidType);
     41                void premutate(BasicType * basicType);
     42                void premutate(PointerType * pointerType);
     43                void premutate(StructInstType * aggregateUseType);
     44                void premutate(UnionInstType * aggregateUseType);
     45                void premutate(EnumInstType * aggregateUseType);
     46                void premutate(TraitInstType * aggregateUseType);
     47                void premutate(TypeInstType * aggregateUseType);
     48                void premutate(TupleType * tupleType);
     49                void premutate(VarArgsType * varArgsType);
     50                void premutate(ZeroType * zeroType);
     51                void premutate(OneType * oneType);
     52
     53                bool isVoid;
     54        };
     55
     56        DeclarationWithType * FixFunction_old::postmutate(FunctionDecl *functionDecl) {
    3057                // can't delete function type because it may contain assertions, so transfer ownership to new object
    3158                ObjectDecl *pointer = new ObjectDecl( functionDecl->name, functionDecl->get_storageClasses(), functionDecl->linkage, nullptr, new PointerType( Type::Qualifiers(), functionDecl->type ), nullptr, functionDecl->attributes );
     59                pointer->location = functionDecl->location;
    3260                functionDecl->attributes.clear();
    3361                functionDecl->type = nullptr;
     
    4068        // does not cause an error
    4169
    42         Type * FixFunction::postmutate(ArrayType *arrayType) {
     70        Type * FixFunction_old::postmutate(ArrayType *arrayType) {
    4371                // need to recursively mutate the base type in order for multi-dimensional arrays to work.
    4472                PointerType *pointerType = new PointerType( arrayType->get_qualifiers(), arrayType->base, arrayType->dimension, arrayType->isVarLen, arrayType->isStatic );
     73                pointerType->location = arrayType->location;
    4574                arrayType->base = nullptr;
    4675                arrayType->dimension = nullptr;
     
    4978        }
    5079
    51         void FixFunction::premutate(VoidType *) {
     80        void FixFunction_old::premutate(VoidType *) {
    5281                isVoid = true;
    5382        }
    5483
    55         void FixFunction::premutate(FunctionDecl *) { visit_children = false; }
    56         void FixFunction::premutate(ArrayType *) { visit_children = false; }
    57         void FixFunction::premutate(BasicType *) { visit_children = false; }
    58         void FixFunction::premutate(PointerType *) { visit_children = false; }
    59         void FixFunction::premutate(StructInstType *) { visit_children = false; }
    60         void FixFunction::premutate(UnionInstType *) { visit_children = false; }
    61         void FixFunction::premutate(EnumInstType *) { visit_children = false; }
    62         void FixFunction::premutate(TraitInstType *) { visit_children = false; }
    63         void FixFunction::premutate(TypeInstType *) { visit_children = false; }
    64         void FixFunction::premutate(TupleType *) { visit_children = false; }
    65         void FixFunction::premutate(VarArgsType *) { visit_children = false; }
    66         void FixFunction::premutate(ZeroType *) { visit_children = false; }
    67         void FixFunction::premutate(OneType *) { visit_children = false; }
     84        void FixFunction_old::premutate(FunctionDecl *) { visit_children = false; }
     85        void FixFunction_old::premutate(ArrayType *) { visit_children = false; }
     86        void FixFunction_old::premutate(BasicType *) { visit_children = false; }
     87        void FixFunction_old::premutate(PointerType *) { visit_children = false; }
     88        void FixFunction_old::premutate(StructInstType *) { visit_children = false; }
     89        void FixFunction_old::premutate(UnionInstType *) { visit_children = false; }
     90        void FixFunction_old::premutate(EnumInstType *) { visit_children = false; }
     91        void FixFunction_old::premutate(TraitInstType *) { visit_children = false; }
     92        void FixFunction_old::premutate(TypeInstType *) { visit_children = false; }
     93        void FixFunction_old::premutate(TupleType *) { visit_children = false; }
     94        void FixFunction_old::premutate(VarArgsType *) { visit_children = false; }
     95        void FixFunction_old::premutate(ZeroType *) { visit_children = false; }
     96        void FixFunction_old::premutate(OneType *) { visit_children = false; }
    6897
    6998        bool fixFunction( DeclarationWithType *& dwt ) {
    70                 PassVisitor<FixFunction> fixer;
     99                PassVisitor<FixFunction_old> fixer;
    71100                dwt = dwt->acceptMutator( fixer );
    72101                return fixer.pass.isVoid;
    73102        }
     103
     104namespace {
     105        struct FixFunction_new final : public ast::WithShortCircuiting {
     106                bool isVoid = false;
     107
     108                void premutate( const ast::FunctionDecl * ) { visit_children = false; }
     109
     110                const ast::DeclWithType * postmutate( const ast::FunctionDecl * func ) {
     111                        return new ast::ObjectDecl{
     112                                func->location, func->name, new ast::PointerType{ func->type }, nullptr,
     113                                func->storage, func->linkage, nullptr, copy( func->attributes ) };
     114                }
     115
     116                void premutate( const ast::ArrayType * ) { visit_children = false; }
     117
     118                const ast::Type * postmutate( const ast::ArrayType * array ) {
     119                        return new ast::PointerType{
     120                                array->base, array->dimension, array->isVarLen, array->isStatic,
     121                                array->qualifiers };
     122                }
     123
     124                void premutate( const ast::VoidType * ) { isVoid = true; }
     125
     126                void premutate( const ast::BasicType * ) { visit_children = false; }
     127                void premutate( const ast::PointerType * ) { visit_children = false; }
     128                void premutate( const ast::StructInstType * ) { visit_children = false; }
     129                void premutate( const ast::UnionInstType * ) { visit_children = false; }
     130                void premutate( const ast::EnumInstType * ) { visit_children = false; }
     131                void premutate( const ast::TraitInstType * ) { visit_children = false; }
     132                void premutate( const ast::TypeInstType * ) { visit_children = false; }
     133                void premutate( const ast::TupleType * ) { visit_children = false; }
     134                void premutate( const ast::VarArgsType * ) { visit_children = false; }
     135                void premutate( const ast::ZeroType * ) { visit_children = false; }
     136                void premutate( const ast::OneType * ) { visit_children = false; }
     137        };
     138} // anonymous namespace
     139
     140const ast::DeclWithType * fixFunction( const ast::DeclWithType * dwt, bool & isVoid ) {
     141        ast::Pass< FixFunction_new > fixer;
     142        dwt = dwt->accept( fixer );
     143        isVoid |= fixer.pass.isVoid;
     144        return dwt;
     145}
     146
    74147} // namespace SymTab
    75148
  • src/SymTab/FixFunction.h

    r7951100 rb067d9b  
    1919#include "SynTree/SynTree.h"    // for Types
    2020
     21namespace ast {
     22        class DeclWithType;
     23}
     24
    2125namespace SymTab {
    22         /// Replaces function and array types by equivalent pointer types.
    23         class FixFunction : public WithShortCircuiting {
    24                 typedef Mutator Parent;
    25           public:
    26                 FixFunction();
     26        /// Replaces function and array types by equivalent pointer types. Returns true if type is
     27        /// void
     28        bool fixFunction( DeclarationWithType *& );
    2729
    28                 void premutate(FunctionDecl *functionDecl);
    29                 DeclarationWithType* postmutate(FunctionDecl *functionDecl);
    30 
    31                 Type * postmutate(ArrayType * arrayType);
    32 
    33                 void premutate(ArrayType * arrayType);
    34                 void premutate(VoidType * voidType);
    35                 void premutate(BasicType * basicType);
    36                 void premutate(PointerType * pointerType);
    37                 void premutate(StructInstType * aggregateUseType);
    38                 void premutate(UnionInstType * aggregateUseType);
    39                 void premutate(EnumInstType * aggregateUseType);
    40                 void premutate(TraitInstType * aggregateUseType);
    41                 void premutate(TypeInstType * aggregateUseType);
    42                 void premutate(TupleType * tupleType);
    43                 void premutate(VarArgsType * varArgsType);
    44                 void premutate(ZeroType * zeroType);
    45                 void premutate(OneType * oneType);
    46 
    47                 bool isVoid;
    48         };
    49 
    50         bool fixFunction( DeclarationWithType *& );
     30        /// Returns declaration with function and array types replaced by equivalent pointer types.
     31        /// Sets isVoid to true if type is void
     32        const ast::DeclWithType * fixFunction( const ast::DeclWithType * dwt, bool & isVoid );
    5133} // namespace SymTab
    5234
  • src/SymTab/Indexer.cc

    r7951100 rb067d9b  
    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 && ! data.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                                 // only implicitly delete non-user defined functions that are  not intrinsic, and are
    169                                 // not copy functions (assignment or copy constructor), unless a user-defined copy function exists.
    170                                 // deleteStmt will be non-null only if a user-defined function is found.
    171                                 if (isNotUserDefinedFunc && (! isCopyFunc || existsUserDefinedCopyFunc)) {
    172                                         ball.decl.deleteStmt = val.deleteStmt;
    173                                 }
    174                                 out.push_back( ball.decl );
    175                         }
    176                 }
    177         }
    178 
    179         void Indexer::makeWritable() {
    180                 if ( ! tables ) {
    181                         // create indexer if not yet set
    182                         tables = new Indexer::Impl( scope );
    183                 } else if ( tables->refCount > 1 || tables->scope != scope ) {
    184                         // make this indexer the base of a fresh indexer at the current scope
    185                         tables = new Indexer::Impl( scope, std::move( *this ) );
    186                 }
    187         }
    188 
    189         Indexer::Indexer() : tables( 0 ), scope( 0 ) {}
    190 
    191         Indexer::Indexer( const Indexer &that ) : doDebug( that.doDebug ), tables( newRef( that.tables ) ), scope( that.scope ) {}
    192 
    193         Indexer::Indexer( Indexer &&that ) : doDebug( that.doDebug ), tables( that.tables ), scope( that.scope ) {
    194                 that.tables = 0;
    195         }
     72                        return ret;
     73                }
     74        }
     75
     76        Indexer::Indexer()
     77        : idTable(), typeTable(), structTable(), enumTable(), unionTable(), traitTable(),
     78          prevScope(), scope( 0 ), repScope( 0 ) { ++* stats().count; }
    19679
    19780        Indexer::~Indexer() {
    198                 deleteRef( tables );
    199         }
    200 
    201         Indexer& Indexer::operator= ( const Indexer &that ) {
    202                 deleteRef( tables );
    203 
    204                 tables = newRef( that.tables );
    205                 scope = that.scope;
    206                 doDebug = that.doDebug;
    207 
    208                 return *this;
    209         }
    210 
    211         Indexer& Indexer::operator= ( Indexer &&that ) {
    212                 deleteRef( tables );
    213 
    214                 tables = that.tables;
    215                 scope = that.scope;
    216                 doDebug = that.doDebug;
    217 
    218                 that.tables = 0;
    219 
    220                 return *this;
    221         }
    222 
    223         void Indexer::lookupId( const std::string &id, std::list< IdData > &out ) const {
    224                 std::unordered_set< std::string > foundMangleNames;
    225 
    226                 Indexer::Impl *searchTables = tables;
    227                 while ( searchTables ) {
    228 
    229                         IdTable::const_iterator decls = searchTables->idTable.find( id );
    230                         if ( decls != searchTables->idTable.end() ) {
    231                                 const MangleTable &mangleTable = decls->second;
    232                                 for ( MangleTable::const_iterator decl = mangleTable.begin(); decl != mangleTable.end(); ++decl ) {
    233                                         // mark the mangled name as found, skipping this insertion if a declaration for that name has already been found
    234                                         if ( foundMangleNames.insert( decl->first ).second == false ) continue;
    235 
    236                                         out.push_back( decl->second );
    237                                 }
    238                         }
    239 
    240                         // get declarations from base indexers
    241                         searchTables = searchTables->base.tables;
    242                 }
    243 
    244                 // some special functions, e.g. constructors and destructors
    245                 // remove autogenerated functions when they are defined so that
    246                 // they can never be matched
    247                 removeSpecialOverrides( id, out );
    248         }
    249 
    250         NamedTypeDecl *Indexer::lookupType( const std::string &id ) const {
    251                 if ( ! tables ) return 0;
    252 
    253                 TypeTable::const_iterator ret = tables->typeTable.find( id );
    254                 return ret != tables->typeTable.end() ? ret->second : tables->base.lookupType( id );
    255         }
    256 
    257         StructDecl *Indexer::lookupStruct( const std::string &id ) const {
    258                 if ( ! tables ) return 0;
    259 
    260                 StructTable::const_iterator ret = tables->structTable.find( id );
    261                 return ret != tables->structTable.end() ? ret->second : tables->base.lookupStruct( id );
    262         }
    263 
    264         EnumDecl *Indexer::lookupEnum( const std::string &id ) const {
    265                 if ( ! tables ) return 0;
    266 
    267                 EnumTable::const_iterator ret = tables->enumTable.find( id );
    268                 return ret != tables->enumTable.end() ? ret->second : tables->base.lookupEnum( id );
    269         }
    270 
    271         UnionDecl *Indexer::lookupUnion( const std::string &id ) const {
    272                 if ( ! tables ) return 0;
    273 
    274                 UnionTable::const_iterator ret = tables->unionTable.find( id );
    275                 return ret != tables->unionTable.end() ? ret->second : tables->base.lookupUnion( id );
    276         }
    277 
    278         TraitDecl *Indexer::lookupTrait( const std::string &id ) const {
    279                 if ( ! tables ) return 0;
    280 
    281                 TraitTable::const_iterator ret = tables->traitTable.find( id );
    282                 return ret != tables->traitTable.end() ? ret->second : tables->base.lookupTrait( id );
    283         }
    284 
    285         const Indexer::IdData * Indexer::lookupIdAtScope( const std::string &id, const std::string &mangleName, unsigned long scope ) const {
    286                 if ( ! tables ) return nullptr;
    287                 if ( tables->scope < scope ) return nullptr;
    288 
    289                 IdTable::const_iterator decls = tables->idTable.find( id );
    290                 if ( decls != tables->idTable.end() ) {
    291                         const MangleTable &mangleTable = decls->second;
    292                         MangleTable::const_iterator decl = mangleTable.find( mangleName );
    293                         if ( decl != mangleTable.end() ) return &decl->second;
    294                 }
    295 
    296                 return tables->base.lookupIdAtScope( id, mangleName, scope );
    297         }
    298 
    299         Indexer::IdData * Indexer::lookupIdAtScope( const std::string &id, const std::string &mangleName, unsigned long scope ) {
    300                 return const_cast<IdData *>(const_cast<const Indexer *>(this)->lookupIdAtScope( id, mangleName, scope ));
    301         }
    302 
    303         bool Indexer::hasIncompatibleCDecl( const std::string &id, const std::string &mangleName, unsigned long scope ) const {
    304                 if ( ! tables ) return false;
    305                 if ( tables->scope < scope ) return false;
    306 
    307                 IdTable::const_iterator decls = tables->idTable.find( id );
    308                 if ( decls != tables->idTable.end() ) {
    309                         const MangleTable &mangleTable = decls->second;
    310                         for ( MangleTable::const_iterator decl = mangleTable.begin(); decl != mangleTable.end(); ++decl ) {
    311                                 // check for C decls with the same name, skipping those with a compatible type (by mangleName)
    312                                 if ( ! LinkageSpec::isMangled( decl->second.id->get_linkage() ) && decl->first != mangleName ) return true;
    313                         }
    314                 }
    315 
    316                 return tables->base.hasIncompatibleCDecl( id, mangleName, scope );
    317         }
    318 
    319         bool Indexer::hasCompatibleCDecl( const std::string &id, const std::string &mangleName, unsigned long scope ) const {
    320                 if ( ! tables ) return false;
    321                 if ( tables->scope < scope ) return false;
    322 
    323                 IdTable::const_iterator decls = tables->idTable.find( id );
    324                 if ( decls != tables->idTable.end() ) {
    325                         const MangleTable &mangleTable = decls->second;
    326                         for ( MangleTable::const_iterator decl = mangleTable.begin(); decl != mangleTable.end(); ++decl ) {
    327                                 // check for C decls with the same name, skipping
    328                                 // those with an incompatible type (by mangleName)
    329                                 if ( ! LinkageSpec::isMangled( decl->second.id->get_linkage() ) && decl->first == mangleName ) return true;
    330                         }
    331                 }
    332 
    333                 return tables->base.hasCompatibleCDecl( id, mangleName, scope );
    334         }
    335 
    336         NamedTypeDecl *Indexer::lookupTypeAtScope( const std::string &id, unsigned long scope ) const {
    337                 if ( ! tables ) return 0;
    338                 if ( tables->scope < scope ) return 0;
    339 
    340                 TypeTable::const_iterator ret = tables->typeTable.find( id );
    341                 return ret != tables->typeTable.end() ? ret->second : tables->base.lookupTypeAtScope( id, scope );
    342         }
    343 
    344         StructDecl *Indexer::lookupStructAtScope( const std::string &id, unsigned long scope ) const {
    345                 if ( ! tables ) return 0;
    346                 if ( tables->scope < scope ) return 0;
    347 
    348                 StructTable::const_iterator ret = tables->structTable.find( id );
    349                 return ret != tables->structTable.end() ? ret->second : tables->base.lookupStructAtScope( id, scope );
    350         }
    351 
    352         EnumDecl *Indexer::lookupEnumAtScope( const std::string &id, unsigned long scope ) const {
    353                 if ( ! tables ) return 0;
    354                 if ( tables->scope < scope ) return 0;
    355 
    356                 EnumTable::const_iterator ret = tables->enumTable.find( id );
    357                 return ret != tables->enumTable.end() ? ret->second : tables->base.lookupEnumAtScope( id, scope );
    358         }
    359 
    360         UnionDecl *Indexer::lookupUnionAtScope( const std::string &id, unsigned long scope ) const {
    361                 if ( ! tables ) return 0;
    362                 if ( tables->scope < scope ) return 0;
    363 
    364                 UnionTable::const_iterator ret = tables->unionTable.find( id );
    365                 return ret != tables->unionTable.end() ? ret->second : tables->base.lookupUnionAtScope( id, scope );
    366         }
    367 
    368         TraitDecl *Indexer::lookupTraitAtScope( const std::string &id, unsigned long scope ) const {
    369                 if ( ! tables ) return 0;
    370                 if ( tables->scope < scope ) return 0;
    371 
    372                 TraitTable::const_iterator ret = tables->traitTable.find( id );
    373                 return ret != tables->traitTable.end() ? ret->second : tables->base.lookupTraitAtScope( id, scope );
    374         }
    375 
    376         bool isFunction( DeclarationWithType * decl ) {
     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;
     109        }
     110
     111        void Indexer::lookupId( const std::string & id, std::list< IdData > &out ) const {
     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                }
     122        }
     123
     124        const NamedTypeDecl * Indexer::lookupType( const std::string & id ) const {
     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;
     130        }
     131
     132        const StructDecl * Indexer::lookupStruct( const std::string & id ) const {
     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        const 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        const 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        const 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;
     172        }
     173
     174        const NamedTypeDecl * Indexer::globalLookupType( const std::string & id ) const {
     175                return atScope( 0 )->lookupType( id );
     176        }
     177
     178        const StructDecl * Indexer::globalLookupStruct( const std::string & id ) const {
     179                return atScope( 0 )->lookupStruct( id );
     180        }
     181
     182        const UnionDecl * Indexer::globalLookupUnion( const std::string & id ) const {
     183                return atScope( 0 )->lookupUnion( id );
     184        }
     185
     186        const EnumDecl * Indexer::globalLookupEnum( const std::string & id ) const {
     187                return atScope( 0 )->lookupEnum( id );
     188        }
     189
     190        bool isFunction( const DeclarationWithType * decl ) {
    377191                return GenPoly::getFunctionType( decl->get_type() );
    378192        }
    379193
    380         bool isObject( DeclarationWithType * decl ) {
     194        bool isObject( const DeclarationWithType * decl ) {
    381195                return ! isFunction( decl );
    382196        }
    383197
    384         bool isDefinition( DeclarationWithType * decl ) {
    385                 if ( FunctionDecl * func = dynamic_cast< FunctionDecl * >( decl ) ) {
     198        bool isDefinition( const DeclarationWithType * decl ) {
     199                if ( const FunctionDecl * func = dynamic_cast< const FunctionDecl * >( decl ) ) {
    386200                        // a function is a definition if it has a body
    387201                        return func->statements;
     
    393207        }
    394208
    395         bool addedIdConflicts( Indexer::IdData & existing, DeclarationWithType *added, BaseSyntaxNode * deleteStmt, Indexer::ConflictFunction handleConflicts ) {
    396                 // 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, const DeclarationWithType * added,
     212                        Indexer::OnConflict handleConflicts, const Declaration * deleteStmt ) {
     213                // if we're giving the same name mangling to things of different types then there is
     214                // something wrong
    397215                assert( (isObject( added ) && isObject( existing.id ) )
    398216                        || ( isFunction( added ) && isFunction( existing.id ) ) );
    399217
    400                 if ( LinkageSpec::isOverridable( existing.id->get_linkage() ) ) {
     218                if ( LinkageSpec::isOverridable( existing.id->linkage ) ) {
    401219                        // new definition shadows the autogenerated one, even at the same scope
    402220                        return false;
    403                 } 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() ) ) {
    404224
    405225                        // it is a conflict if one declaration is deleted and the other is not
    406226                        if ( deleteStmt && ! existing.deleteStmt ) {
    407                                 return handleConflicts( existing, "deletion of defined identifier " );
     227                                if ( handleConflicts.mode == OnConflict::Error ) {
     228                                        SemanticError( added, "deletion of defined identifier " );
     229                                }
     230                                return true;
    408231                        } else if ( ! deleteStmt && existing.deleteStmt ) {
    409                                 return handleConflicts( existing, "definition of deleted identifier " );
     232                                if ( handleConflicts.mode == OnConflict::Error ) {
     233                                        SemanticError( added, "definition of deleted identifier " );
     234                                }
     235                                return true;
    410236                        }
    411237
    412238                        if ( isDefinition( added ) && isDefinition( existing.id ) ) {
    413                                 if ( isFunction( added ) ) {
    414                                         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(const std::string & id, const std::string &mangleName ) const {
     277                if ( ! idTable ) return false;
     278
     279                ++* stats().map_lookups;
     280                auto decls = idTable->find( id );
     281                if ( decls == idTable->end() ) return false;
     282
     283                for ( auto decl : *(decls->second) ) {
     284                        // skip other scopes (hidden by this decl)
     285                        if ( decl.second.scope != scope ) continue;
     286                        // check for C decl with incompatible type (by manglename)
     287                        if ( ! LinkageSpec::isMangled( decl.second.id->linkage ) && decl.first != mangleName ) {
     288                                return true;
     289                        }
     290                }
     291
     292                return false;
     293        }
     294
     295        /// gets the base type of the first parameter; decl must be a ctor/dtor/assignment function
     296        std::string getOtypeKey( const FunctionDecl * function ) {
     297                auto& params = function->type->parameters;
     298                assert( ! params.empty() );
     299                // use base type of pointer, so that qualifiers on the pointer type aren't considered.
     300                Type * base = InitTweak::getPointerBase( params.front()->get_type() );
     301                assert( base );
     302                return Mangler::mangle( base );
     303        }
     304
     305        /// gets the declaration for the function acting on a type specified by otype key,
     306        /// nullptr if none such
     307        const FunctionDecl * getFunctionForOtype( const DeclarationWithType * decl, const std::string& otypeKey ) {
     308                const FunctionDecl * func = dynamic_cast< const FunctionDecl * >( decl );
     309                if ( ! func || otypeKey != getOtypeKey( func ) ) return nullptr;
     310                return func;
     311        }
     312
     313        bool Indexer::removeSpecialOverrides(Indexer::IdData& data, Indexer::MangleTable::Ptr& mangleTable ) {
     314                // if a type contains user defined ctor/dtor/assign, then special rules trigger, which
     315                // determinethe set of ctor/dtor/assign that can be used  by the requester. In particular,
     316                // if the user defines a default ctor, then the generated default ctor is unavailable,
     317                // likewise for copy ctor and dtor. If the user defines any ctor/dtor, then no generated
     318                // field ctors are available. If the user defines any ctor then the generated default ctor
     319                // is unavailable (intrinsic default ctor must be overridden exactly). If the user defines
     320                // anything that looks like a copy constructor, then the generated copy constructor is
     321                // unavailable, and likewise for the assignment operator.
     322
     323                // only relevant on function declarations
     324                const FunctionDecl * function = dynamic_cast< const FunctionDecl * >( data.id );
     325                if ( ! function ) return true;
     326                // only need to perform this check for constructors, destructors, and assignment functions
     327                if ( ! CodeGen::isCtorDtorAssign( data.id->name ) ) return true;
     328
     329                // set up information for this type
     330                bool dataIsUserDefinedFunc = ! LinkageSpec::isOverridable( function->linkage );
     331                bool dataIsCopyFunc = InitTweak::isCopyFunction( function, function->name );
     332                std::string dataOtypeKey = getOtypeKey( function );
     333
     334                if ( dataIsUserDefinedFunc && dataIsCopyFunc ) {
     335                        // this is a user-defined copy function
     336                        // if this is the first such, delete/remove non-user-defined overloads as needed
     337                        std::vector< std::string > removed;
     338                        std::vector< MangleTable::value_type > deleted;
     339                        bool alreadyUserDefinedFunc = false;
     340
     341                        for ( const auto& entry : * mangleTable ) {
     342                                // skip decls that aren't functions or are for the wrong type
     343                                const FunctionDecl * decl = getFunctionForOtype( entry.second.id, dataOtypeKey );
     344                                if ( ! decl ) continue;
     345
     346                                bool isCopyFunc = InitTweak::isCopyFunction( decl, decl->name );
     347                                if ( ! LinkageSpec::isOverridable( decl->linkage ) ) {
     348                                        // matching user-defined function
     349                                        if ( isCopyFunc ) {
     350                                                // mutation already performed, return early
     351                                                return true;
     352                                        } else {
     353                                                // note that non-copy deletions already performed
     354                                                alreadyUserDefinedFunc = true;
     355                                        }
    415356                                } else {
    416                                         return handleConflicts( existing, "duplicate object definition for " );
    417                                 } // if
    418                         } // if
    419                 } else {
    420                         return handleConflicts( existing, "duplicate definition for " );
    421                 } // if
    422 
     357                                        // non-user-defined function; mark for deletion/removal as appropriate
     358                                        if ( isCopyFunc ) {
     359                                                removed.push_back( entry.first );
     360                                        } else if ( ! alreadyUserDefinedFunc ) {
     361                                                deleted.push_back( entry );
     362                                        }
     363                                }
     364                        }
     365
     366                        // perform removals from mangle table, and deletions if necessary
     367                        for ( const auto& key : removed ) {
     368                                ++* stats().map_mutations;
     369                                mangleTable = mangleTable->erase( key );
     370                        }
     371                        if ( ! alreadyUserDefinedFunc ) for ( const auto& entry : deleted ) {
     372                                ++* stats().map_mutations;
     373                                mangleTable = mangleTable->set( entry.first, IdData{ entry.second, function } );
     374                        }
     375                } else if ( dataIsUserDefinedFunc ) {
     376                        // this is a user-defined non-copy function
     377                        // if this is the first user-defined function, delete non-user-defined overloads
     378                        std::vector< MangleTable::value_type > deleted;
     379
     380                        for ( const auto& entry : * mangleTable ) {
     381                                // skip decls that aren't functions or are for the wrong type
     382                                const FunctionDecl * decl = getFunctionForOtype( entry.second.id, dataOtypeKey );
     383                                if ( ! decl ) continue;
     384
     385                                // exit early if already a matching user-defined function;
     386                                // earlier function will have mutated table
     387                                if ( ! LinkageSpec::isOverridable( decl->linkage ) ) return true;
     388
     389                                // skip mutating intrinsic functions
     390                                if ( decl->linkage == LinkageSpec::Intrinsic ) continue;
     391
     392                                // user-defined non-copy functions do not override copy functions
     393                                if ( InitTweak::isCopyFunction( decl, decl->name ) ) continue;
     394
     395                                // this function to be deleted after mangleTable iteration is complete
     396                                deleted.push_back( entry );
     397                        }
     398
     399                        // mark deletions to update mangle table
     400                        // this needs to be a separate loop because of iterator invalidation
     401                        for ( const auto& entry : deleted ) {
     402                                ++* stats().map_mutations;
     403                                mangleTable = mangleTable->set( entry.first, IdData{ entry.second, function } );
     404                        }
     405                } else if ( function->linkage != LinkageSpec::Intrinsic ) {
     406                        // this is an overridable generated function
     407                        // if there already exists a matching user-defined function, delete this appropriately
     408                        for ( const auto& entry : * mangleTable ) {
     409                                // skip decls that aren't functions or are for the wrong type
     410                                const FunctionDecl * decl = getFunctionForOtype( entry.second.id, dataOtypeKey );
     411                                if ( ! decl ) continue;
     412
     413                                // skip non-user-defined functions
     414                                if ( LinkageSpec::isOverridable( decl->linkage ) ) continue;
     415
     416                                if ( dataIsCopyFunc ) {
     417                                        // remove current function if exists a user-defined copy function
     418                                        // since the signatures for copy functions don't need to match exactly, using
     419                                        // a delete statement is the wrong approach
     420                                        if ( InitTweak::isCopyFunction( decl, decl->name ) ) return false;
     421                                } else {
     422                                        // mark current function deleted by first user-defined function found
     423                                        data.deleteStmt = decl;
     424                                        return true;
     425                                }
     426                        }
     427                }
     428
     429                // nothing (more) to fix, return true
    423430                return true;
    424431        }
    425432
    426         void Indexer::addId( DeclarationWithType *decl, ConflictFunction handleConflicts, Expression * baseExpr, BaseSyntaxNode * deleteStmt ) {
    427                 if ( decl->name == "" ) return;
    428                 debugPrint( "Adding Id " << decl->name << std::endl );
    429                 makeWritable();
    430 
     433        void Indexer::addId(const DeclarationWithType * decl, OnConflict handleConflicts, const Expression * baseExpr,
     434                        const Declaration * deleteStmt ) {
     435                ++* stats().add_calls;
    431436                const std::string &name = decl->name;
     437                if ( name == "" ) return;
     438
    432439                std::string mangleName;
    433440                if ( LinkageSpec::isOverridable( decl->linkage ) ) {
    434                         // mangle the name without including the appropriate suffix, so overridable routines are placed into the
    435                         // same "bucket" as their user defined versions.
     441                        // mangle the name without including the appropriate suffix, so overridable routines
     442                        // are placed into the same "bucket" as their user defined versions.
    436443                        mangleName = Mangler::mangle( decl, false );
    437444                } else {
     
    439446                } // if
    440447
    441                 // this ensures that no two declarations with the same unmangled name at the same scope both have C linkage
    442                 if ( ! LinkageSpec::isMangled( decl->linkage ) ) {
    443                         // NOTE this is broken in Richard's original code in such a way that it never triggers (it
    444                         // doesn't check decls that have the same manglename, and all C-linkage decls are defined to
    445                         // have their name as their manglename, hence the error can never trigger).
    446                         // The code here is closer to correct, but name mangling would have to be completely
    447                         // isomorphic to C type-compatibility, which it may not be.
    448                         if ( hasIncompatibleCDecl( name, mangleName, scope ) ) {
     448                // this ensures that no two declarations with the same unmangled name at the same scope
     449                // both have C linkage
     450                if ( LinkageSpec::isMangled( decl->linkage ) ) {
     451                        // Check that a Cforall declaration doesn't override any C declaration
     452                        if ( hasCompatibleCDecl( name, mangleName ) ) {
     453                                SemanticError( decl, "Cforall declaration hides C function " );
     454                        }
     455                } else {
     456                        // NOTE: only correct if name mangling is completely isomorphic to C
     457                        // type-compatibility, which it may not be.
     458                        if ( hasIncompatibleCDecl( name, mangleName ) ) {
    449459                                SemanticError( decl, "conflicting overload of C function " );
    450460                        }
    451                 } else {
    452                         // Check that a Cforall declaration doesn't override any C declaration
    453                         if ( hasCompatibleCDecl( name, mangleName, scope ) ) {
    454                                 SemanticError( decl, "Cforall declaration hides C function " );
    455                         }
    456                 }
    457 
    458                 // Skip repeat declarations of the same identifier
    459                 IdData * existing = lookupIdAtScope( name, mangleName, scope );
    460                 if ( existing && existing->id && addedIdConflicts( *existing, decl, deleteStmt, handleConflicts ) ) return;
    461 
    462                 // add to indexer
    463                 tables->idTable[ name ][ mangleName ] = IdData{ decl, baseExpr, deleteStmt };
    464                 ++tables->size;
    465         }
    466 
    467         void Indexer::addId( DeclarationWithType * decl, Expression * baseExpr ) {
     461                }
     462
     463                // ensure tables exist and add identifier
     464                MangleTable::Ptr mangleTable;
     465                if ( ! idTable ) {
     466                        idTable = IdTable::new_ptr();
     467                        mangleTable = MangleTable::new_ptr();
     468                } else {
     469                        ++* stats().map_lookups;
     470                        auto decls = idTable->find( name );
     471                        if ( decls == idTable->end() ) {
     472                                mangleTable = MangleTable::new_ptr();
     473                        } else {
     474                                mangleTable = decls->second;
     475                                // skip in-scope repeat declarations of same identifier
     476                                ++* stats().map_lookups;
     477                                auto existing = mangleTable->find( mangleName );
     478                                if ( existing != mangleTable->end()
     479                                                && existing->second.scope == scope
     480                                                && existing->second.id ) {
     481                                        if ( addedIdConflicts( existing->second, decl, handleConflicts, deleteStmt ) ) {
     482                                                if ( handleConflicts.mode == OnConflict::Delete ) {
     483                                                        // set delete expression for conflicting identifier
     484                                                        lazyInitScope();
     485                                                        * stats().map_mutations += 2;
     486                                                        idTable = idTable->set(
     487                                                                name,
     488                                                                mangleTable->set(
     489                                                                        mangleName,
     490                                                                        IdData{ existing->second, handleConflicts.deleteStmt } ) );
     491                                                }
     492                                                return;
     493                                        }
     494                                }
     495                        }
     496                }
     497
     498                // add/overwrite with new identifier
     499                lazyInitScope();
     500                IdData data{ decl, baseExpr, deleteStmt, scope };
     501                // Ensure that auto-generated ctor/dtor/assignment are deleted if necessary
     502                if ( ! removeSpecialOverrides( data, mangleTable ) ) return;
     503                * stats().map_mutations += 2;
     504                idTable = idTable->set( name, mangleTable->set( mangleName, std::move(data) ) );
     505        }
     506
     507        void Indexer::addId( const DeclarationWithType * decl, const Expression * baseExpr ) {
    468508                // default handling of conflicts is to raise an error
    469                 addId( decl, [decl](IdData &, const std::string & msg) { SemanticError( decl, msg ); return true; }, baseExpr, decl->isDeleted ? decl : nullptr );
    470         }
    471 
    472         void Indexer::addDeletedId( DeclarationWithType * decl, BaseSyntaxNode * deleteStmt ) {
     509                addId( decl, OnConflict::error(), baseExpr, decl->isDeleted ? decl : nullptr );
     510        }
     511
     512        void Indexer::addDeletedId( const DeclarationWithType * decl, const Declaration * deleteStmt ) {
    473513                // default handling of conflicts is to raise an error
    474                 addId( decl, [decl](IdData &, const std::string & msg) { SemanticError( decl, msg ); return true; }, nullptr, deleteStmt );
    475         }
    476 
    477         bool addedTypeConflicts( NamedTypeDecl *existing, NamedTypeDecl *added ) {
    478                 if ( existing->get_base() == 0 ) {
     514                addId( decl, OnConflict::error(), nullptr, deleteStmt );
     515        }
     516
     517        bool addedTypeConflicts( const NamedTypeDecl * existing, const NamedTypeDecl * added ) {
     518                if ( existing->base == nullptr ) {
    479519                        return false;
    480                 } else if ( added->get_base() == 0 ) {
     520                } else if ( added->base == nullptr ) {
    481521                        return true;
    482522                } else {
    483                         SemanticError( added, "redeclaration of " );
    484                 }
    485         }
    486 
    487         void Indexer::addType( NamedTypeDecl *decl ) {
    488                 debugPrint( "Adding type " << decl->name << std::endl );
    489                 makeWritable();
    490 
    491                 const std::string &id = decl->get_name();
    492                 TypeTable::iterator existing = tables->typeTable.find( id );
    493                 if ( existing == tables->typeTable.end() ) {
    494                         NamedTypeDecl *parent = tables->base.lookupTypeAtScope( id, scope );
    495                         if ( ! parent || ! addedTypeConflicts( parent, decl ) ) {
    496                                 tables->typeTable.insert( existing, std::make_pair( id, decl ) );
    497                                 ++tables->size;
    498                         }
    499                 } else {
    500                         if ( ! addedTypeConflicts( existing->second, decl ) ) {
    501                                 existing->second = decl;
    502                         }
    503                 }
    504         }
    505 
    506         bool addedDeclConflicts( AggregateDecl *existing, AggregateDecl *added ) {
     523                        assert( existing->base && added->base );
     524                        // typedef redeclarations are errors only if types are different
     525                        if ( ! ResolvExpr::typesCompatible( existing->base, added->base, Indexer() ) ) {
     526                                SemanticError( added->location, "redeclaration of " + added->name );
     527                        }
     528                }
     529                // does not need to be added to the table if both existing and added have a base that are
     530                // the same
     531                return true;
     532        }
     533
     534        void Indexer::addType( const NamedTypeDecl * decl ) {
     535                ++* stats().add_calls;
     536                const std::string & id = decl->name;
     537
     538                if ( ! typeTable ) {
     539                        typeTable = TypeTable::new_ptr();
     540                } else {
     541                        ++* stats().map_lookups;
     542                        auto existing = typeTable->find( id );
     543                        if ( existing != typeTable->end()
     544                                && existing->second.scope == scope
     545                                && addedTypeConflicts( existing->second.decl, decl ) ) return;
     546                }
     547
     548                lazyInitScope();
     549                ++* stats().map_mutations;
     550                typeTable = typeTable->set( id, Scoped<NamedTypeDecl>{ decl, scope } );
     551        }
     552
     553        bool addedDeclConflicts( const AggregateDecl * existing, const AggregateDecl * added ) {
    507554                if ( ! existing->body ) {
    508555                        return false;
     
    513560        }
    514561
    515         void Indexer::addStruct( const std::string &id ) {
    516                 debugPrint( "Adding fwd decl for struct " << id << std::endl );
     562        void Indexer::addStruct( const std::string & id ) {
    517563                addStruct( new StructDecl( id ) );
    518564        }
    519565
    520         void Indexer::addStruct( StructDecl *decl ) {
    521                 debugPrint( "Adding struct " << decl->name << std::endl );
    522                 makeWritable();
    523 
    524                 const std::string &id = decl->get_name();
    525                 StructTable::iterator existing = tables->structTable.find( id );
    526                 if ( existing == tables->structTable.end() ) {
    527                         StructDecl *parent = tables->base.lookupStructAtScope( id, scope );
    528                         if ( ! parent || ! addedDeclConflicts( parent, decl ) ) {
    529                                 tables->structTable.insert( existing, std::make_pair( id, decl ) );
    530                                 ++tables->size;
    531                         }
    532                 } else {
    533                         if ( ! addedDeclConflicts( existing->second, decl ) ) {
    534                                 existing->second = decl;
    535                         }
    536                 }
    537         }
    538 
    539         void Indexer::addEnum( EnumDecl *decl ) {
    540                 debugPrint( "Adding enum " << decl->name << std::endl );
    541                 makeWritable();
    542 
    543                 const std::string &id = decl->get_name();
    544                 EnumTable::iterator existing = tables->enumTable.find( id );
    545                 if ( existing == tables->enumTable.end() ) {
    546                         EnumDecl *parent = tables->base.lookupEnumAtScope( id, scope );
    547                         if ( ! parent || ! addedDeclConflicts( parent, decl ) ) {
    548                                 tables->enumTable.insert( existing, std::make_pair( id, decl ) );
    549                                 ++tables->size;
    550                         }
    551                 } else {
    552                         if ( ! addedDeclConflicts( existing->second, decl ) ) {
    553                                 existing->second = decl;
    554                         }
    555                 }
    556         }
    557 
    558         void Indexer::addUnion( const std::string &id ) {
    559                 debugPrint( "Adding fwd decl for union " << id << std::endl );
     566        void Indexer::addStruct( const StructDecl * decl ) {
     567                ++* stats().add_calls;
     568                const std::string & id = decl->name;
     569
     570                if ( ! structTable ) {
     571                        structTable = StructTable::new_ptr();
     572                } else {
     573                        ++* stats().map_lookups;
     574                        auto existing = structTable->find( id );
     575                        if ( existing != structTable->end()
     576                                && existing->second.scope == scope
     577                                && addedDeclConflicts( existing->second.decl, decl ) ) return;
     578                }
     579
     580                lazyInitScope();
     581                ++* stats().map_mutations;
     582                structTable = structTable->set( id, Scoped<StructDecl>{ decl, scope } );
     583        }
     584
     585        void Indexer::addEnum( const EnumDecl * decl ) {
     586                ++* stats().add_calls;
     587                const std::string & id = decl->name;
     588
     589                if ( ! enumTable ) {
     590                        enumTable = EnumTable::new_ptr();
     591                } else {
     592                        ++* stats().map_lookups;
     593                        auto existing = enumTable->find( id );
     594                        if ( existing != enumTable->end()
     595                                && existing->second.scope == scope
     596                                && addedDeclConflicts( existing->second.decl, decl ) ) return;
     597                }
     598
     599                lazyInitScope();
     600                ++* stats().map_mutations;
     601                enumTable = enumTable->set( id, Scoped<EnumDecl>{ decl, scope } );
     602        }
     603
     604        void Indexer::addUnion( const std::string & id ) {
    560605                addUnion( new UnionDecl( id ) );
    561606        }
    562607
    563         void Indexer::addUnion( UnionDecl *decl ) {
    564                 debugPrint( "Adding union " << decl->name << std::endl );
    565                 makeWritable();
    566 
    567                 const std::string &id = decl->get_name();
    568                 UnionTable::iterator existing = tables->unionTable.find( id );
    569                 if ( existing == tables->unionTable.end() ) {
    570                         UnionDecl *parent = tables->base.lookupUnionAtScope( id, scope );
    571                         if ( ! parent || ! addedDeclConflicts( parent, decl ) ) {
    572                                 tables->unionTable.insert( existing, std::make_pair( id, decl ) );
    573                                 ++tables->size;
    574                         }
    575                 } else {
    576                         if ( ! addedDeclConflicts( existing->second, decl ) ) {
    577                                 existing->second = decl;
    578                         }
    579                 }
    580         }
    581 
    582         void Indexer::addTrait( TraitDecl *decl ) {
    583                 debugPrint( "Adding trait " << decl->name << std::endl );
    584                 makeWritable();
    585 
    586                 const std::string &id = decl->get_name();
    587                 TraitTable::iterator existing = tables->traitTable.find( id );
    588                 if ( existing == tables->traitTable.end() ) {
    589                         TraitDecl *parent = tables->base.lookupTraitAtScope( id, scope );
    590                         if ( ! parent || ! addedDeclConflicts( parent, decl ) ) {
    591                                 tables->traitTable.insert( existing, std::make_pair( id, decl ) );
    592                                 ++tables->size;
    593                         }
    594                 } else {
    595                         if ( ! addedDeclConflicts( existing->second, decl ) ) {
    596                                 existing->second = decl;
    597                         }
    598                 }
    599         }
    600 
    601         void Indexer::addMembers( AggregateDecl * aggr, Expression * expr, ConflictFunction handleConflicts ) {
     608        void Indexer::addUnion( const UnionDecl * decl ) {
     609                ++* stats().add_calls;
     610                const std::string & id = decl->name;
     611
     612                if ( ! unionTable ) {
     613                        unionTable = UnionTable::new_ptr();
     614                } else {
     615                        ++* stats().map_lookups;
     616                        auto existing = unionTable->find( id );
     617                        if ( existing != unionTable->end()
     618                                && existing->second.scope == scope
     619                                && addedDeclConflicts( existing->second.decl, decl ) ) return;
     620                }
     621
     622                lazyInitScope();
     623                ++* stats().map_mutations;
     624                unionTable = unionTable->set( id, Scoped<UnionDecl>{ decl, scope } );
     625        }
     626
     627        void Indexer::addTrait( const TraitDecl * decl ) {
     628                ++* stats().add_calls;
     629                const std::string & id = decl->name;
     630
     631                if ( ! traitTable ) {
     632                        traitTable = TraitTable::new_ptr();
     633                } else {
     634                        ++* stats().map_lookups;
     635                        auto existing = traitTable->find( id );
     636                        if ( existing != traitTable->end()
     637                                && existing->second.scope == scope
     638                                && addedDeclConflicts( existing->second.decl, decl ) ) return;
     639                }
     640
     641                lazyInitScope();
     642                ++* stats().map_mutations;
     643                traitTable = traitTable->set( id, Scoped<TraitDecl>{ decl, scope } );
     644        }
     645
     646        void Indexer::addMembers( const AggregateDecl * aggr, const Expression * expr, OnConflict handleConflicts ) {
    602647                for ( Declaration * decl : aggr->members ) {
    603648                        if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType * >( decl ) ) {
    604649                                addId( dwt, handleConflicts, expr );
    605650                                if ( dwt->name == "" ) {
    606                                         Type * t = dwt->get_type()->stripReferences();
    607                                         if ( dynamic_cast< StructInstType * >( t ) || dynamic_cast< UnionInstType * >( t ) ) {
     651                                        const Type * t = dwt->get_type()->stripReferences();
     652                                        if ( dynamic_cast<const StructInstType *>( t ) || dynamic_cast<const UnionInstType *>( t ) ) {
    608653                                                Expression * base = expr->clone();
    609654                                                ResolvExpr::Cost cost = ResolvExpr::Cost::zero; // xxx - carry this cost into the indexer as a base cost?
     
    616661        }
    617662
    618         void Indexer::addWith( std::list< Expression * > & withExprs, BaseSyntaxNode * withStmt ) {
    619                 for ( Expression * expr : withExprs ) {
     663        void Indexer::addWith( const std::list< Expression * > & withExprs, const Declaration * withStmt ) {
     664                for ( const Expression * expr : withExprs ) {
    620665                        if ( expr->result ) {
    621666                                AggregateDecl * aggr = expr->result->stripReferences()->getAggr();
    622667                                assertf( aggr, "WithStmt expr has non-aggregate type: %s", toString( expr->result ).c_str() );
    623668
    624                                 addMembers( aggr, expr, [withStmt](IdData & existing, const std::string &) {
    625                                         // on conflict, delete the identifier
    626                                         existing.deleteStmt = withStmt;
    627                                         return true;
    628                                 });
     669                                addMembers( aggr, expr, OnConflict::deleteWith( withStmt ) );
    629670                        }
    630671                }
     
    644685        }
    645686
    646         void Indexer::addFunctionType( FunctionType * ftype ) {
     687        void Indexer::addFunctionType( const FunctionType * ftype ) {
    647688                addTypes( ftype->forall );
    648689                addIds( ftype->returnVals );
    649690                addIds( ftype->parameters );
    650         }
    651 
    652         void Indexer::enterScope() {
    653                 ++scope;
    654 
    655                 if ( doDebug ) {
    656                         std::cerr << "--- Entering scope " << scope << std::endl;
    657                 }
    658         }
    659 
    660         void Indexer::leaveScope() {
    661                 using std::cerr;
    662 
    663                 assert( scope > 0 && "cannot leave initial scope" );
    664                 if ( doDebug ) {
    665                         cerr << "--- Leaving scope " << scope << " containing" << std::endl;
    666                 }
    667                 --scope;
    668 
    669                 while ( tables && tables->scope > scope ) {
    670                         if ( doDebug ) {
    671                                 dump( tables->idTable, cerr );
    672                                 dump( tables->typeTable, cerr );
    673                                 dump( tables->structTable, cerr );
    674                                 dump( tables->enumTable, cerr );
    675                                 dump( tables->unionTable, cerr );
    676                                 dump( tables->traitTable, cerr );
    677                         }
    678 
    679                         // swap tables for base table until we find one at an appropriate scope
    680                         Indexer::Impl *base = newRef( tables->base.tables );
    681                         deleteRef( tables );
    682                         tables = base;
    683                 }
    684         }
    685 
    686         void Indexer::print( std::ostream &os, int indent ) const {
    687                 using std::cerr;
    688 
    689                 if ( tables ) {
    690                         os << "--- scope " << tables->scope << " ---" << std::endl;
    691 
    692                         os << "===idTable===" << std::endl;
    693                         dump( tables->idTable, os );
    694                         os << "===typeTable===" << std::endl;
    695                         dump( tables->typeTable, os );
    696                         os << "===structTable===" << std::endl;
    697                         dump( tables->structTable, os );
    698                         os << "===enumTable===" << std::endl;
    699                         dump( tables->enumTable, os );
    700                         os << "===unionTable===" << std::endl;
    701                         dump( tables->unionTable, os );
    702                         os << "===contextTable===" << std::endl;
    703                         dump( tables->traitTable, os );
    704 
    705                         tables->base.print( os, indent );
    706                 } else {
    707                         os << "--- end ---" << std::endl;
    708                 }
    709 
    710691        }
    711692
     
    715696                        Expression * base = baseExpr->clone();
    716697                        ResolvExpr::referenceToRvalueConversion( base, cost );
    717                         ret = new MemberExpr( id, base );
     698                        ret = new MemberExpr( const_cast<DeclarationWithType *>(id), base );
    718699                        // xxx - this introduces hidden environments, for now remove them.
    719700                        // std::swap( base->env, ret->env );
     
    721702                        base->env = nullptr;
    722703                } else {
    723                         ret = new VariableExpr( id );
    724                 }
    725                 if ( deleteStmt ) ret = new DeletedExpr( ret, deleteStmt );
     704                        ret = new VariableExpr( const_cast<DeclarationWithType *>(id) );
     705                }
     706                if ( deleteStmt ) ret = new DeletedExpr( ret, const_cast<Declaration *>(deleteStmt) );
    726707                return ret;
    727708        }
  • src/SymTab/Indexer.h

    r7951100 rb067d9b  
    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();
    4540
    4641                struct IdData {
    47                         DeclarationWithType * id = nullptr;
    48                         Expression * baseExpr = nullptr; // WithExpr
     42                        const DeclarationWithType * id = nullptr;
     43                        const Expression * baseExpr = nullptr; // WithExpr
    4944
    5045                        /// non-null if this declaration is deleted
    51                         BaseSyntaxNode * deleteStmt = nullptr;
     46                        const Declaration * 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                                const DeclarationWithType * id, const Expression * baseExpr, const Declaration * deleteStmt,
     54                                unsigned long scope )
     55                                : id( id ), baseExpr( baseExpr ), deleteStmt( deleteStmt ), scope( scope ) {}
     56                        IdData( const IdData& o, const Declaration * deleteStmt )
     57                                : id( o.id ), baseExpr( o.baseExpr ), deleteStmt( deleteStmt ), scope( o.scope ) {}
    5658
    5759                        Expression * combine( ResolvExpr::Cost & cost ) const;
     
    5961
    6062                /// Gets all declarations with the given ID
    61                 void lookupId( const std::string &id, std::list< IdData > &out ) const;
     63                void lookupId( const std::string & id, std::list< IdData > &out ) const;
    6264                /// Gets the top-most type declaration with the given ID
    63                 NamedTypeDecl *lookupType( const std::string &id ) const;
     65                const NamedTypeDecl * lookupType( const std::string & id ) const;
    6466                /// Gets the top-most struct declaration with the given ID
    65                 StructDecl *lookupStruct( const std::string &id ) const;
     67                const StructDecl * lookupStruct( const std::string & id ) const;
    6668                /// Gets the top-most enum declaration with the given ID
    67                 EnumDecl *lookupEnum( const std::string &id ) const;
     69                const EnumDecl * lookupEnum( const std::string & id ) const;
    6870                /// Gets the top-most union declaration with the given ID
    69                 UnionDecl *lookupUnion( const std::string &id ) const;
     71                const UnionDecl * lookupUnion( const std::string & id ) const;
    7072                /// Gets the top-most trait declaration with the given ID
    71                 TraitDecl *lookupTrait( const std::string &id ) const;
     73                const TraitDecl * lookupTrait( const std::string & id ) const;
    7274
    73                 void print( std::ostream &os, int indent = 0 ) const;
     75                /// Gets the type declaration with the given ID at global scope
     76                const NamedTypeDecl * globalLookupType( const std::string & id ) const;
     77                /// Gets the struct declaration with the given ID at global scope
     78                const StructDecl * globalLookupStruct( const std::string & id ) const;
     79                /// Gets the union declaration with the given ID at global scope
     80                const UnionDecl * globalLookupUnion( const std::string & id ) const;
     81                /// Gets the enum declaration with the given ID at global scope
     82                const EnumDecl * globalLookupEnum( const std::string & id ) const;
    7483
    75                 /// looks up a specific mangled ID at the given scope
    76                 IdData * lookupIdAtScope( const std::string &id, const std::string &mangleName, unsigned long scope );
    77                 const IdData * lookupIdAtScope( const std::string &id, const std::string &mangleName, unsigned long scope ) const;
    78                 /// returns true if there exists a declaration with C linkage and the given name with a different mangled name
    79                 bool hasIncompatibleCDecl( const std::string &id, const std::string &mangleName, unsigned long scope ) const;
    80                 /// returns true if there exists a declaration with C linkage and the given name with the same mangled name
    81                 bool hasCompatibleCDecl( const std::string &id, const std::string &mangleName, unsigned long scope ) const;
    82                 // equivalents to lookup functions that only look at tables at scope `scope` (which should be >= tables->scope)
    83                 NamedTypeDecl *lookupTypeAtScope( const std::string &id, unsigned long scope ) const;
    84                 StructDecl *lookupStructAtScope( const std::string &id, unsigned long scope ) const;
    85                 EnumDecl *lookupEnumAtScope( const std::string &id, unsigned long scope ) const;
    86                 UnionDecl *lookupUnionAtScope( const std::string &id, unsigned long scope ) const;
    87                 TraitDecl *lookupTraitAtScope( const std::string &id, unsigned long scope ) const;
     84                void addId( const DeclarationWithType * decl, const Expression * baseExpr = nullptr );
     85                void addDeletedId( const DeclarationWithType * decl, const Declaration * deleteStmt );
    8886
    89                 typedef std::function<bool(IdData &, const std::string &)> ConflictFunction;
    90 
    91                 void addId( DeclarationWithType * decl, Expression * baseExpr = nullptr );
    92                 void addDeletedId( DeclarationWithType * decl, BaseSyntaxNode * deleteStmt );
    93 
    94                 void addType( NamedTypeDecl *decl );
    95                 void addStruct( const std::string &id );
    96                 void addStruct( StructDecl *decl );
    97                 void addEnum( EnumDecl *decl );
    98                 void addUnion( const std::string &id );
    99                 void addUnion( UnionDecl *decl );
    100                 void addTrait( TraitDecl *decl );
     87                void addType( const NamedTypeDecl * decl );
     88                void addStruct( const std::string & id );
     89                void addStruct( const StructDecl * decl );
     90                void addEnum( const EnumDecl * decl );
     91                void addUnion( const std::string & id );
     92                void addUnion( const UnionDecl * decl );
     93                void addTrait( const TraitDecl * decl );
    10194
    10295                /// adds all of the IDs from WithStmt exprs
    103                 void addWith( std::list< Expression * > & withExprs, BaseSyntaxNode * withStmt );
    104 
    105                 /// adds all of the members of the Aggregate (addWith helper)
    106                 void addMembers( AggregateDecl * aggr, Expression * expr, ConflictFunction );
     96                void addWith( const std::list< Expression * > & withExprs, const Declaration * withStmt );
    10797
    10898                /// convenience function for adding a list of Ids to the indexer
     
    113103
    114104                /// convenience function for adding all of the declarations in a function type to the indexer
    115                 void addFunctionType( FunctionType * ftype );
     105                void addFunctionType( const FunctionType * ftype );
    116106
    117                 bool doDebug = false; ///< Display debugging trace?
    118107          private:
    119                 struct Impl;
     108                /// Wraps a Decl * with a scope
     109                template<typename Decl>
     110                struct Scoped {
     111                        const Decl * decl;           ///< declaration
     112                        unsigned long scope;  ///< scope of this declaration
    120113
    121                 Impl *tables;         ///< Copy-on-write instance of table data structure
    122                 unsigned long scope;  ///< Scope index of this pointer
     114                        Scoped(const Decl * d, unsigned long s) : decl(d), scope(s) {}
     115                };
    123116
    124                 /// Takes a new ref to a table (returns null if null)
    125                 static Impl *newRef( Impl *toClone );
    126                 /// Clears a ref to a table (does nothing if null)
    127                 static void deleteRef( Impl *toFree );
     117                using Ptr = std::shared_ptr<const Indexer>;
    128118
    129                 // Removes matching autogenerated constructors and destructors
    130                 // so that they will not be selected
    131                 // void removeSpecialOverrides( FunctionDecl *decl );
    132                 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> >;
    133126
    134                 /// Ensures that tables variable is writable (i.e. allocated, uniquely owned by this Indexer, and at the current scope)
    135                 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                        const Declaration * deleteStmt;  ///< Statement that deletes this expression
     155
     156                private:
     157                        OnConflict() : mode(Error), deleteStmt(nullptr) {}
     158                        OnConflict( const Declaration * d ) : mode(Delete), deleteStmt(d) {}
     159                public:
     160                        OnConflict( const OnConflict& ) = default;
     161
     162                        static OnConflict error() { return {}; }
     163                        static OnConflict deleteWith( const Declaration * d ) { return { d }; }
     164                };
     165
     166                /// true if the existing identifier conflicts with the added identifier
     167                bool addedIdConflicts(
     168                        const IdData & existing, const DeclarationWithType * added, OnConflict handleConflicts,
     169                        const Declaration * deleteStmt );
    136170
    137171                /// common code for addId, addDeletedId, etc.
    138                 void addId( DeclarationWithType * decl, ConflictFunction, Expression * baseExpr = nullptr, BaseSyntaxNode * deleteStmt = nullptr );
     172                void addId(const DeclarationWithType * decl, OnConflict handleConflicts,
     173                        const Expression * baseExpr = nullptr, const Declaration * deleteStmt = nullptr );
     174
     175                /// adds all of the members of the Aggregate (addWith helper)
     176                void addMembers( const AggregateDecl * aggr, const Expression * expr, OnConflict handleConflicts );
     177
     178                /// returns true if there exists a declaration with C linkage and the given name with the same mangled name
     179                bool hasCompatibleCDecl( const std::string & id, const std::string & mangleName ) const;
     180                /// returns true if there exists a declaration with C linkage and the given name with a different mangled name
     181                bool hasIncompatibleCDecl( const std::string & id, const std::string & mangleName ) const;
    139182        };
    140183} // namespace SymTab
  • src/SymTab/Mangler.cc

    r7951100 rb067d9b  
    1010// Created On       : Sun May 17 21:40:29 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Sep 25 15:49:26 2017
    13 // Update Count     : 23
     12// Last Modified On : Tue Jul 30 13:46:10 2019
     13// Update Count     : 26
    1414//
    1515#include "Mangler.h"
    1616
    17 #include <algorithm>                // for copy, transform
    18 #include <cassert>                  // for assert, assertf
    19 #include <functional>               // for const_mem_fun_t, mem_fun
    20 #include <iterator>                 // for ostream_iterator, back_insert_ite...
    21 #include <list>                     // for _List_iterator, list, _List_const...
    22 #include <string>                   // for string, char_traits, operator<<
    23 
    24 #include "CodeGen/OperatorTable.h"  // for OperatorInfo, operatorLookup
     17#include <algorithm>                     // for copy, transform
     18#include <cassert>                       // for assert, assertf
     19#include <functional>                    // for const_mem_fun_t, mem_fun
     20#include <iterator>                      // for ostream_iterator, back_insert_ite...
     21#include <list>                          // for _List_iterator, list, _List_const...
     22#include <string>                        // for string, char_traits, operator<<
     23
     24#include "CodeGen/OperatorTable.h"       // for OperatorInfo, operatorLookup
    2525#include "Common/PassVisitor.h"
    26 #include "Common/SemanticError.h"   // for SemanticError
    27 #include "Common/utility.h"         // for toString
    28 #include "Parser/LinkageSpec.h"     // for Spec, isOverridable, AutoGen, Int...
    29 #include "SynTree/Declaration.h"    // for TypeDecl, DeclarationWithType
    30 #include "SynTree/Expression.h"     // for TypeExpr, Expression, operator<<
    31 #include "SynTree/Type.h"           // for Type, ReferenceToType, Type::Fora...
     26#include "Common/SemanticError.h"        // for SemanticError
     27#include "Common/utility.h"              // for toString
     28#include "Parser/LinkageSpec.h"          // for Spec, isOverridable, AutoGen, Int...
     29#include "ResolvExpr/TypeEnvironment.h"  // for TypeEnvironment
     30#include "SynTree/Declaration.h"         // for TypeDecl, DeclarationWithType
     31#include "SynTree/Expression.h"          // for TypeExpr, Expression, operator<<
     32#include "SynTree/Type.h"                // for Type, ReferenceToType, Type::Fora...
     33
     34#include "AST/Pass.hpp"
    3235
    3336namespace SymTab {
     
    3538                namespace {
    3639                        /// Mangles names to a unique C identifier
    37                         struct Mangler : public WithShortCircuiting, public WithVisitorRef<Mangler>, public WithGuards {
    38                                 Mangler( bool mangleOverridable, bool typeMode, bool mangleGenericParams );
    39                                 Mangler( const Mangler & ) = delete;
    40 
    41                                 void previsit( BaseSyntaxNode * ) { visit_children = false; }
    42 
    43                                 void postvisit( ObjectDecl * declaration );
    44                                 void postvisit( FunctionDecl * declaration );
    45                                 void postvisit( TypeDecl * declaration );
    46 
    47                                 void postvisit( VoidType * voidType );
    48                                 void postvisit( BasicType * basicType );
    49                                 void postvisit( PointerType * pointerType );
    50                                 void postvisit( ArrayType * arrayType );
    51                                 void postvisit( ReferenceType * refType );
    52                                 void postvisit( FunctionType * functionType );
    53                                 void postvisit( StructInstType * aggregateUseType );
    54                                 void postvisit( UnionInstType * aggregateUseType );
    55                                 void postvisit( EnumInstType * aggregateUseType );
    56                                 void postvisit( TypeInstType * aggregateUseType );
    57                                 void postvisit( TraitInstType * inst );
    58                                 void postvisit( TupleType * tupleType );
    59                                 void postvisit( VarArgsType * varArgsType );
    60                                 void postvisit( ZeroType * zeroType );
    61                                 void postvisit( OneType * oneType );
     40                        struct Mangler_old : public WithShortCircuiting, public WithVisitorRef<Mangler_old>, public WithGuards {
     41                                Mangler_old( bool mangleOverridable, bool typeMode, bool mangleGenericParams );
     42                                Mangler_old( const Mangler_old & ) = delete;
     43
     44                                void previsit( const BaseSyntaxNode * ) { visit_children = false; }
     45
     46                                void postvisit( const ObjectDecl * declaration );
     47                                void postvisit( const FunctionDecl * declaration );
     48                                void postvisit( const TypeDecl * declaration );
     49
     50                                void postvisit( const VoidType * voidType );
     51                                void postvisit( const BasicType * basicType );
     52                                void postvisit( const PointerType * pointerType );
     53                                void postvisit( const ArrayType * arrayType );
     54                                void postvisit( const ReferenceType * refType );
     55                                void postvisit( const FunctionType * functionType );
     56                                void postvisit( const StructInstType * aggregateUseType );
     57                                void postvisit( const UnionInstType * aggregateUseType );
     58                                void postvisit( const EnumInstType * aggregateUseType );
     59                                void postvisit( const TypeInstType * aggregateUseType );
     60                                void postvisit( const TraitInstType * inst );
     61                                void postvisit( const TupleType * tupleType );
     62                                void postvisit( const VarArgsType * varArgsType );
     63                                void postvisit( const ZeroType * zeroType );
     64                                void postvisit( const OneType * oneType );
     65                                void postvisit( const QualifiedType * qualType );
    6266
    6367                                std::string get_mangleName() { return mangleName.str(); }
     
    7276                                bool mangleGenericParams;       ///< Include generic parameters in name mangling if true
    7377                                bool inFunctionType = false;    ///< Include type qualifiers if false.
    74 
    75                                 void mangleDecl( DeclarationWithType *declaration );
    76                                 void mangleRef( ReferenceToType *refType, std::string prefix );
    77 
    78                                 void printQualifiers( Type *type );
    79                         }; // Mangler
     78                                bool inQualifiedType = false;   ///< Add start/end delimiters around qualified type
     79
     80                          public:
     81                                Mangler_old( bool mangleOverridable, bool typeMode, bool mangleGenericParams,
     82                                        int nextVarNum, const VarMapType& varNums );
     83
     84                          private:
     85                                void mangleDecl( const DeclarationWithType * declaration );
     86                                void mangleRef( const ReferenceToType * refType, std::string prefix );
     87
     88                                void printQualifiers( const Type *type );
     89                        }; // Mangler_old
    8090                } // namespace
    8191
    82                 std::string mangle( BaseSyntaxNode * decl, bool mangleOverridable, bool typeMode, bool mangleGenericParams ) {
    83                         PassVisitor<Mangler> mangler( mangleOverridable, typeMode, mangleGenericParams );
     92                std::string mangle( const BaseSyntaxNode * decl, bool mangleOverridable, bool typeMode, bool mangleGenericParams ) {
     93                        PassVisitor<Mangler_old> mangler( mangleOverridable, typeMode, mangleGenericParams );
    8494                        maybeAccept( decl, mangler );
    8595                        return mangler.pass.get_mangleName();
    8696                }
    8797
    88                 std::string mangleType( Type * ty ) {
    89                         PassVisitor<Mangler> mangler( false, true, true );
     98                std::string mangleType( const Type * ty ) {
     99                        PassVisitor<Mangler_old> mangler( false, true, true );
    90100                        maybeAccept( ty, mangler );
    91101                        return mangler.pass.get_mangleName();
    92102                }
    93103
    94                 std::string mangleConcrete( Type * ty ) {
    95                         PassVisitor<Mangler> mangler( false, false, false );
     104                std::string mangleConcrete( const Type * ty ) {
     105                        PassVisitor<Mangler_old> mangler( false, false, false );
    96106                        maybeAccept( ty, mangler );
    97107                        return mangler.pass.get_mangleName();
     
    99109
    100110                namespace {
    101                         Mangler::Mangler( bool mangleOverridable, bool typeMode, bool mangleGenericParams )
    102                                 : nextVarNum( 0 ), isTopLevel( true ), mangleOverridable( mangleOverridable ), typeMode( typeMode ), mangleGenericParams( mangleGenericParams ) {}
    103 
    104                         void Mangler::mangleDecl( DeclarationWithType * declaration ) {
     111                        Mangler_old::Mangler_old( bool mangleOverridable, bool typeMode, bool mangleGenericParams )
     112                                : nextVarNum( 0 ), isTopLevel( true ),
     113                                mangleOverridable( mangleOverridable ), typeMode( typeMode ),
     114                                mangleGenericParams( mangleGenericParams ) {}
     115
     116                        Mangler_old::Mangler_old( bool mangleOverridable, bool typeMode, bool mangleGenericParams,
     117                                int nextVarNum, const VarMapType& varNums )
     118                                : varNums( varNums ), nextVarNum( nextVarNum ), isTopLevel( false ),
     119                                mangleOverridable( mangleOverridable ), typeMode( typeMode ),
     120                                mangleGenericParams( mangleGenericParams ) {}
     121
     122                        void Mangler_old::mangleDecl( const DeclarationWithType * declaration ) {
    105123                                bool wasTopLevel = isTopLevel;
    106124                                if ( isTopLevel ) {
     
    109127                                        isTopLevel = false;
    110128                                } // if
    111                                 mangleName << "__";
     129                                mangleName << Encoding::manglePrefix;
    112130                                CodeGen::OperatorInfo opInfo;
    113131                                if ( operatorLookup( declaration->get_name(), opInfo ) ) {
    114                                         mangleName << opInfo.outputName;
     132                                        mangleName << opInfo.outputName.size() << opInfo.outputName;
    115133                                } else {
    116                                         mangleName << declaration->get_name();
    117                                 } // if
    118                                 mangleName << "__";
     134                                        mangleName << declaration->name.size() << declaration->name;
     135                                } // if
    119136                                maybeAccept( declaration->get_type(), *visitor );
    120137                                if ( mangleOverridable && LinkageSpec::isOverridable( declaration->get_linkage() ) ) {
     
    122139                                        // so they need a different name mangling
    123140                                        if ( declaration->get_linkage() == LinkageSpec::AutoGen ) {
    124                                                 mangleName << "autogen__";
     141                                                mangleName << Encoding::autogen;
    125142                                        } else if ( declaration->get_linkage() == LinkageSpec::Intrinsic ) {
    126                                                 mangleName << "intrinsic__";
     143                                                mangleName << Encoding::intrinsic;
    127144                                        } else {
    128145                                                // if we add another kind of overridable function, this has to change
     
    133150                        }
    134151
    135                         void Mangler::postvisit( ObjectDecl * declaration ) {
     152                        void Mangler_old::postvisit( const ObjectDecl * declaration ) {
    136153                                mangleDecl( declaration );
    137154                        }
    138155
    139                         void Mangler::postvisit( FunctionDecl * declaration ) {
     156                        void Mangler_old::postvisit( const FunctionDecl * declaration ) {
    140157                                mangleDecl( declaration );
    141158                        }
    142159
    143                         void Mangler::postvisit( VoidType * voidType ) {
     160                        void Mangler_old::postvisit( const VoidType * voidType ) {
    144161                                printQualifiers( voidType );
    145                                 mangleName << "v";
    146                         }
    147 
    148                         void Mangler::postvisit( BasicType * basicType ) {
    149                                 static const char *btLetter[] = {
    150                                         "b",    // Bool
    151                                         "c",    // Char
    152                                         "Sc",   // SignedChar
    153                                         "Uc",   // UnsignedChar
    154                                         "s",    // ShortSignedInt
    155                                         "Us",   // ShortUnsignedInt
    156                                         "i",    // SignedInt
    157                                         "Ui",   // UnsignedInt
    158                                         "l",    // LongSignedInt
    159                                         "Ul",   // LongUnsignedInt
    160                                         "q",    // LongLongSignedInt
    161                                         "Uq",   // LongLongUnsignedInt
    162                                         "f",    // Float
    163                                         "d",    // Double
    164                                         "r",    // LongDouble
    165                                         "Xf",   // FloatComplex
    166                                         "Xd",   // DoubleComplex
    167                                         "Xr",   // LongDoubleComplex
    168                                         "If",   // FloatImaginary
    169                                         "Id",   // DoubleImaginary
    170                                         "Ir",   // LongDoubleImaginary
    171                                         "w",    // SignedInt128
    172                                         "Uw",   // UnsignedInt128
    173                                         "x",   // Float80
    174                                         "y",   // Float128
    175                                 };
    176                                 static_assert(
    177                                         sizeof(btLetter)/sizeof(btLetter[0]) == BasicType::NUMBER_OF_BASIC_TYPES,
    178                                         "Each basic type kind should have a corresponding mangler letter"
    179                                 );
    180 
     162                                mangleName << Encoding::void_t;
     163                        }
     164
     165                        void Mangler_old::postvisit( const BasicType * basicType ) {
    181166                                printQualifiers( basicType );
    182                                 assert( basicType->get_kind() < sizeof(btLetter)/sizeof(btLetter[0]) );
    183                                 mangleName << btLetter[ basicType->get_kind() ];
    184                         }
    185 
    186                         void Mangler::postvisit( PointerType * pointerType ) {
     167                                assertf( basicType->kind < BasicType::NUMBER_OF_BASIC_TYPES, "Unhandled basic type: %d", basicType->kind );
     168                                mangleName << Encoding::basicTypes[ basicType->kind ];
     169                        }
     170
     171                        void Mangler_old::postvisit( const PointerType * pointerType ) {
    187172                                printQualifiers( pointerType );
    188173                                // mangle void (*f)() and void f() to the same name to prevent overloading on functions and function pointers
    189                                 if ( ! dynamic_cast<FunctionType *>( pointerType->base ) ) mangleName << "P";
     174                                if ( ! dynamic_cast<FunctionType *>( pointerType->base ) ) mangleName << Encoding::pointer;
    190175                                maybeAccept( pointerType->base, *visitor );
    191176                        }
    192177
    193                         void Mangler::postvisit( ArrayType * arrayType ) {
     178                        void Mangler_old::postvisit( const ArrayType * arrayType ) {
    194179                                // TODO: encode dimension
    195180                                printQualifiers( arrayType );
    196                                 mangleName << "A0";
     181                                mangleName << Encoding::array << "0";
    197182                                maybeAccept( arrayType->base, *visitor );
    198183                        }
    199184
    200                         void Mangler::postvisit( ReferenceType * refType ) {
     185                        void Mangler_old::postvisit( const ReferenceType * refType ) {
    201186                                // don't print prefix (e.g. 'R') for reference types so that references and non-references do not overload.
    202187                                // Further, do not print the qualifiers for a reference type (but do run printQualifers because of TypeDecls, etc.),
     
    217202                        }
    218203
    219                         void Mangler::postvisit( FunctionType * functionType ) {
     204                        void Mangler_old::postvisit( const FunctionType * functionType ) {
    220205                                printQualifiers( functionType );
    221                                 mangleName << "F";
     206                                mangleName << Encoding::function;
    222207                                // turn on inFunctionType so that printQualifiers does not print most qualifiers for function parameters,
    223208                                // since qualifiers on outermost parameter type do not differentiate function types, e.g.,
     
    226211                                inFunctionType = true;
    227212                                std::list< Type* > returnTypes = getTypes( functionType->returnVals );
    228                                 acceptAll( returnTypes, *visitor );
     213                                if (returnTypes.empty()) mangleName << Encoding::void_t;
     214                                else acceptAll( returnTypes, *visitor );
    229215                                mangleName << "_";
    230216                                std::list< Type* > paramTypes = getTypes( functionType->parameters );
     
    233219                        }
    234220
    235                         void Mangler::mangleRef( ReferenceToType * refType, std::string prefix ) {
     221                        void Mangler_old::mangleRef( const ReferenceToType * refType, std::string prefix ) {
    236222                                printQualifiers( refType );
    237223
    238                                 mangleName << ( refType->name.length() + prefix.length() ) << prefix << refType->name;
     224                                mangleName << prefix << refType->name.length() << refType->name;
    239225
    240226                                if ( mangleGenericParams ) {
    241                                         std::list< Expression* >& params = refType->parameters;
     227                                        const std::list< Expression* > & params = refType->parameters;
    242228                                        if ( ! params.empty() ) {
    243229                                                mangleName << "_";
    244                                                 for ( std::list< Expression* >::const_iterator param = params.begin(); param != params.end(); ++param ) {
    245                                                         TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param );
    246                                                         assertf(paramType, "Aggregate parameters should be type expressions: %s", toCString(*param));
     230                                                for ( const Expression * param : params ) {
     231                                                        const TypeExpr * paramType = dynamic_cast< const TypeExpr * >( param );
     232                                                        assertf(paramType, "Aggregate parameters should be type expressions: %s", toCString(param));
    247233                                                        maybeAccept( paramType->type, *visitor );
    248234                                                }
     
    252238                        }
    253239
    254                         void Mangler::postvisit( StructInstType * aggregateUseType ) {
    255                                 mangleRef( aggregateUseType, "s" );
    256                         }
    257 
    258                         void Mangler::postvisit( UnionInstType * aggregateUseType ) {
    259                                 mangleRef( aggregateUseType, "u" );
    260                         }
    261 
    262                         void Mangler::postvisit( EnumInstType * aggregateUseType ) {
    263                                 mangleRef( aggregateUseType, "e" );
    264                         }
    265 
    266                         void Mangler::postvisit( TypeInstType * typeInst ) {
     240                        void Mangler_old::postvisit( const StructInstType * aggregateUseType ) {
     241                                mangleRef( aggregateUseType, Encoding::struct_t );
     242                        }
     243
     244                        void Mangler_old::postvisit( const UnionInstType * aggregateUseType ) {
     245                                mangleRef( aggregateUseType, Encoding::union_t );
     246                        }
     247
     248                        void Mangler_old::postvisit( const EnumInstType * aggregateUseType ) {
     249                                mangleRef( aggregateUseType, Encoding::enum_t );
     250                        }
     251
     252                        void Mangler_old::postvisit( const TypeInstType * typeInst ) {
    267253                                VarMapType::iterator varNum = varNums.find( typeInst->get_name() );
    268254                                if ( varNum == varNums.end() ) {
    269                                         mangleRef( typeInst, "t" );
     255                                        mangleRef( typeInst, Encoding::type );
    270256                                } else {
    271257                                        printQualifiers( typeInst );
    272                                         std::ostringstream numStream;
    273                                         numStream << varNum->second.first;
    274                                         switch ( (TypeDecl::Kind )varNum->second.second ) {
    275                                           case TypeDecl::Dtype:
    276                                                 mangleName << "d";
    277                                                 break;
    278                                           case TypeDecl::Ftype:
    279                                                 mangleName << "f";
    280                                                 break;
    281                                                 case TypeDecl::Ttype:
    282                                                 mangleName << "tVARGS";
    283                                                 break;
    284                                                 default:
    285                                                 assert( false );
    286                                         } // switch
    287                                         mangleName << numStream.str();
    288                                 } // if
    289                         }
    290 
    291                         void Mangler::postvisit( TraitInstType * inst ) {
     258                                        // Note: Can't use name here, since type variable names do not actually disambiguate a function, e.g.
     259                                        //   forall(dtype T) void f(T);
     260                                        //   forall(dtype S) void f(S);
     261                                        // are equivalent and should mangle the same way. This is accomplished by numbering the type variables when they
     262                                        // are first found and prefixing with the appropriate encoding for the type class.
     263                                        assertf( varNum->second.second < TypeDecl::NUMBER_OF_KINDS, "Unhandled type variable kind: %d", varNum->second.second );
     264                                        mangleName << Encoding::typeVariables[varNum->second.second] << varNum->second.first;
     265                                } // if
     266                        }
     267
     268                        void Mangler_old::postvisit( const TraitInstType * inst ) {
    292269                                printQualifiers( inst );
    293                                 mangleName << "_Y" << inst->name << "_";
    294                         }
    295 
    296                         void Mangler::postvisit( TupleType * tupleType ) {
     270                                mangleName << inst->name.size() << inst->name;
     271                        }
     272
     273                        void Mangler_old::postvisit( const TupleType * tupleType ) {
    297274                                printQualifiers( tupleType );
    298                                 mangleName << "T";
     275                                mangleName << Encoding::tuple << tupleType->types.size();
    299276                                acceptAll( tupleType->types, *visitor );
    300                                 mangleName << "_";
    301                         }
    302 
    303                         void Mangler::postvisit( VarArgsType * varArgsType ) {
     277                        }
     278
     279                        void Mangler_old::postvisit( const VarArgsType * varArgsType ) {
    304280                                printQualifiers( varArgsType );
    305                                 mangleName << "VARGS";
    306                         }
    307 
    308                         void Mangler::postvisit( ZeroType * ) {
    309                                 mangleName << "Z";
    310                         }
    311 
    312                         void Mangler::postvisit( OneType * ) {
    313                                 mangleName << "O";
    314                         }
    315 
    316                         void Mangler::postvisit( TypeDecl * decl ) {
    317                                 static const char *typePrefix[] = { "BT", "BD", "BF" };
    318                                 mangleName << typePrefix[ decl->get_kind() ] << ( decl->name.length() + 1 ) << decl->name;
     281                                static const std::string vargs = "__builtin_va_list";
     282                                mangleName << Encoding::type << vargs.size() << vargs;
     283                        }
     284
     285                        void Mangler_old::postvisit( const ZeroType * ) {
     286                                mangleName << Encoding::zero;
     287                        }
     288
     289                        void Mangler_old::postvisit( const OneType * ) {
     290                                mangleName << Encoding::one;
     291                        }
     292
     293                        void Mangler_old::postvisit( const QualifiedType * qualType ) {
     294                                bool inqual = inQualifiedType;
     295                                if (! inqual ) {
     296                                        // N marks the start of a qualified type
     297                                        inQualifiedType = true;
     298                                        mangleName << Encoding::qualifiedTypeStart;
     299                                }
     300                                maybeAccept( qualType->parent, *visitor );
     301                                maybeAccept( qualType->child, *visitor );
     302                                if ( ! inqual ) {
     303                                        // E marks the end of a qualified type
     304                                        inQualifiedType = false;
     305                                        mangleName << Encoding::qualifiedTypeEnd;
     306                                }
     307                        }
     308
     309                        void Mangler_old::postvisit( const TypeDecl * decl ) {
     310                                // TODO: is there any case where mangling a TypeDecl makes sense? If so, this code needs to be
     311                                // fixed to ensure that two TypeDecls mangle to the same name when they are the same type and vice versa.
     312                                // Note: The current scheme may already work correctly for this case, I have not thought about this deeply
     313                                // and the case has not yet come up in practice. Alternatively, if not then this code can be removed
     314                                // aside from the assert false.
     315                                assertf(false, "Mangler_old should not visit typedecl: %s", toCString(decl));
     316                                assertf( decl->kind < TypeDecl::NUMBER_OF_KINDS, "Unhandled type variable kind: %d", decl->kind );
     317                                mangleName << Encoding::typeVariables[ decl->kind ] << ( decl->name.length() ) << decl->name;
    319318                        }
    320319
     
    325324                        }
    326325
    327                         void Mangler::printQualifiers( Type * type ) {
     326                        void Mangler_old::printQualifiers( const Type * type ) {
    328327                                // skip if not including qualifiers
    329328                                if ( typeMode ) return;
    330                                 if ( ! type->get_forall().empty() ) {
     329                                if ( ! type->forall.empty() ) {
    331330                                        std::list< std::string > assertionNames;
    332                                         int tcount = 0, dcount = 0, fcount = 0, vcount = 0;
    333                                         mangleName << "A";
    334                                         for ( Type::ForallList::iterator i = type->forall.begin(); i != type->forall.end(); ++i ) {
    335                                                 switch ( (*i)->get_kind() ) {
     331                                        int dcount = 0, fcount = 0, vcount = 0, acount = 0;
     332                                        mangleName << Encoding::forall;
     333                                        for ( const TypeDecl * i : type->forall ) {
     334                                                switch ( i->kind ) {
    336335                                                  case TypeDecl::Dtype:
    337336                                                        dcount++;
     
    346345                                                        assert( false );
    347346                                                } // switch
    348                                                 varNums[ (*i)->name ] = std::pair< int, int >( nextVarNum++, (int)(*i)->get_kind() );
    349                                                 for ( std::list< DeclarationWithType* >::iterator assert = (*i)->assertions.begin(); assert != (*i)->assertions.end(); ++assert ) {
    350                                                         PassVisitor<Mangler> sub_mangler( mangleOverridable, typeMode, mangleGenericParams );
    351                                                         sub_mangler.pass.nextVarNum = nextVarNum;
    352                                                         sub_mangler.pass.isTopLevel = false;
    353                                                         sub_mangler.pass.varNums = varNums;
    354                                                         (*assert)->accept( sub_mangler );
    355                                                         assertionNames.push_back( sub_mangler.pass.mangleName.str() );
     347                                                varNums[ i->name ] = std::make_pair( nextVarNum, (int)i->kind );
     348                                                for ( const DeclarationWithType * assert : i->assertions ) {
     349                                                        PassVisitor<Mangler_old> sub_mangler(
     350                                                                mangleOverridable, typeMode, mangleGenericParams, nextVarNum, varNums );
     351                                                        assert->accept( sub_mangler );
     352                                                        assertionNames.push_back( sub_mangler.pass.get_mangleName() );
     353                                                        acount++;
    356354                                                } // for
    357355                                        } // for
    358                                         mangleName << tcount << "_" << dcount << "_" << fcount << "_" << vcount << "_";
     356                                        mangleName << dcount << "_" << fcount << "_" << vcount << "_" << acount << "_";
    359357                                        std::copy( assertionNames.begin(), assertionNames.end(), std::ostream_iterator< std::string >( mangleName, "" ) );
    360358                                        mangleName << "_";
     
    363361                                        // these qualifiers do not distinguish the outermost type of a function parameter
    364362                                        if ( type->get_const() ) {
    365                                                 mangleName << "C";
     363                                                mangleName << Encoding::qualifiers.at(Type::Const);
    366364                                        } // if
    367365                                        if ( type->get_volatile() ) {
    368                                                 mangleName << "V";
     366                                                mangleName << Encoding::qualifiers.at(Type::Volatile);
    369367                                        } // if
    370368                                        // Removed due to restrict not affecting function compatibility in GCC
     
    373371                                        // } // if
    374372                                        if ( type->get_atomic() ) {
    375                                                 mangleName << "A";
     373                                                mangleName << Encoding::qualifiers.at(Type::Atomic);
    376374                                        } // if
    377375                                }
    378376                                if ( type->get_mutex() ) {
    379                                         mangleName << "M";
    380                                 } // if
    381                                 if ( type->get_lvalue() ) {
    382                                         // mangle based on whether the type is lvalue, so that the resolver can differentiate lvalues and rvalues
    383                                         mangleName << "L";
    384                                 }
    385 
     377                                        mangleName << Encoding::qualifiers.at(Type::Mutex);
     378                                } // if
    386379                                if ( inFunctionType ) {
    387380                                        // turn off inFunctionType so that types can be differentiated for nested qualifiers
     
    394387} // namespace SymTab
    395388
     389namespace Mangle {
     390        namespace {
     391                /// Mangles names to a unique C identifier
     392                struct Mangler_new : public ast::WithShortCircuiting, public ast::WithVisitorRef<Mangler_new>, public ast::WithGuards {
     393                        Mangler_new( Mangle::Mode mode );
     394                        Mangler_new( const Mangler_new & ) = delete;
     395
     396                        void previsit( const ast::Node * ) { visit_children = false; }
     397
     398                        void postvisit( const ast::ObjectDecl * declaration );
     399                        void postvisit( const ast::FunctionDecl * declaration );
     400                        void postvisit( const ast::TypeDecl * declaration );
     401
     402                        void postvisit( const ast::VoidType * voidType );
     403                        void postvisit( const ast::BasicType * basicType );
     404                        void postvisit( const ast::PointerType * pointerType );
     405                        void postvisit( const ast::ArrayType * arrayType );
     406                        void postvisit( const ast::ReferenceType * refType );
     407                        void postvisit( const ast::FunctionType * functionType );
     408                        void postvisit( const ast::StructInstType * aggregateUseType );
     409                        void postvisit( const ast::UnionInstType * aggregateUseType );
     410                        void postvisit( const ast::EnumInstType * aggregateUseType );
     411                        void postvisit( const ast::TypeInstType * aggregateUseType );
     412                        void postvisit( const ast::TraitInstType * inst );
     413                        void postvisit( const ast::TupleType * tupleType );
     414                        void postvisit( const ast::VarArgsType * varArgsType );
     415                        void postvisit( const ast::ZeroType * zeroType );
     416                        void postvisit( const ast::OneType * oneType );
     417                        void postvisit( const ast::QualifiedType * qualType );
     418
     419                        std::string get_mangleName() { return mangleName.str(); }
     420                  private:
     421                        std::ostringstream mangleName;  ///< Mangled name being constructed
     422                        typedef std::map< std::string, std::pair< int, int > > VarMapType;
     423                        VarMapType varNums;             ///< Map of type variables to indices
     424                        int nextVarNum;                 ///< Next type variable index
     425                        bool isTopLevel;                ///< Is the Mangler at the top level
     426                        bool mangleOverridable;         ///< Specially mangle overridable built-in methods
     427                        bool typeMode;                  ///< Produce a unique mangled name for a type
     428                        bool mangleGenericParams;       ///< Include generic parameters in name mangling if true
     429                        bool inFunctionType = false;    ///< Include type qualifiers if false.
     430                        bool inQualifiedType = false;   ///< Add start/end delimiters around qualified type
     431
     432                  private:
     433                        Mangler_new( bool mangleOverridable, bool typeMode, bool mangleGenericParams,
     434                                int nextVarNum, const VarMapType& varNums );
     435                        friend class ast::Pass<Mangler_new>;
     436
     437                  private:
     438                        void mangleDecl( const ast::DeclWithType *declaration );
     439                        void mangleRef( const ast::ReferenceToType *refType, std::string prefix );
     440
     441                        void printQualifiers( const ast::Type *type );
     442                }; // Mangler_new
     443        } // namespace
     444
     445
     446        std::string mangle( const ast::Node * decl, Mangle::Mode mode ) {
     447                ast::Pass<Mangler_new> mangler( mode );
     448                maybeAccept( decl, mangler );
     449                return mangler.pass.get_mangleName();
     450        }
     451
     452        namespace {
     453                Mangler_new::Mangler_new( Mangle::Mode mode )
     454                        : nextVarNum( 0 ), isTopLevel( true ),
     455                        mangleOverridable  ( ! mode.no_overrideable   ),
     456                        typeMode           (   mode.type              ),
     457                        mangleGenericParams( ! mode.no_generic_params ) {}
     458
     459                Mangler_new::Mangler_new( bool mangleOverridable, bool typeMode, bool mangleGenericParams,
     460                        int nextVarNum, const VarMapType& varNums )
     461                        : varNums( varNums ), nextVarNum( nextVarNum ), isTopLevel( false ),
     462                        mangleOverridable( mangleOverridable ), typeMode( typeMode ),
     463                        mangleGenericParams( mangleGenericParams ) {}
     464
     465                void Mangler_new::mangleDecl( const ast::DeclWithType * decl ) {
     466                        bool wasTopLevel = isTopLevel;
     467                        if ( isTopLevel ) {
     468                                varNums.clear();
     469                                nextVarNum = 0;
     470                                isTopLevel = false;
     471                        } // if
     472                        mangleName << Encoding::manglePrefix;
     473                        CodeGen::OperatorInfo opInfo;
     474                        if ( operatorLookup( decl->name, opInfo ) ) {
     475                                mangleName << opInfo.outputName.size() << opInfo.outputName;
     476                        } else {
     477                                mangleName << decl->name.size() << decl->name;
     478                        } // if
     479                        maybeAccept( decl->get_type(), *visitor );
     480                        if ( mangleOverridable && decl->linkage.is_overrideable ) {
     481                                // want to be able to override autogenerated and intrinsic routines,
     482                                // so they need a different name mangling
     483                                if ( decl->linkage == ast::Linkage::AutoGen ) {
     484                                        mangleName << Encoding::autogen;
     485                                } else if ( decl->linkage == ast::Linkage::Intrinsic ) {
     486                                        mangleName << Encoding::intrinsic;
     487                                } else {
     488                                        // if we add another kind of overridable function, this has to change
     489                                        assert( false && "unknown overrideable linkage" );
     490                                } // if
     491                        }
     492                        isTopLevel = wasTopLevel;
     493                }
     494
     495                void Mangler_new::postvisit( const ast::ObjectDecl * decl ) {
     496                        mangleDecl( decl );
     497                }
     498
     499                void Mangler_new::postvisit( const ast::FunctionDecl * decl ) {
     500                        mangleDecl( decl );
     501                }
     502
     503                void Mangler_new::postvisit( const ast::VoidType * voidType ) {
     504                        printQualifiers( voidType );
     505                        mangleName << Encoding::void_t;
     506                }
     507
     508                void Mangler_new::postvisit( const ast::BasicType * basicType ) {
     509                        printQualifiers( basicType );
     510                        assertf( basicType->kind < ast::BasicType::NUMBER_OF_BASIC_TYPES, "Unhandled basic type: %d", basicType->kind );
     511                        mangleName << Encoding::basicTypes[ basicType->kind ];
     512                }
     513
     514                void Mangler_new::postvisit( const ast::PointerType * pointerType ) {
     515                        printQualifiers( pointerType );
     516                        // mangle void (*f)() and void f() to the same name to prevent overloading on functions and function pointers
     517                        if ( ! pointerType->base.as<ast::FunctionType>() ) mangleName << Encoding::pointer;
     518                        maybe_accept( pointerType->base.get(), *visitor );
     519                }
     520
     521                void Mangler_new::postvisit( const ast::ArrayType * arrayType ) {
     522                        // TODO: encode dimension
     523                        printQualifiers( arrayType );
     524                        mangleName << Encoding::array << "0";
     525                        maybeAccept( arrayType->base.get(), *visitor );
     526                }
     527
     528                void Mangler_new::postvisit( const ast::ReferenceType * refType ) {
     529                        // don't print prefix (e.g. 'R') for reference types so that references and non-references do not overload.
     530                        // Further, do not print the qualifiers for a reference type (but do run printQualifers because of TypeDecls, etc.),
     531                        // by pretending every reference type is a function parameter.
     532                        GuardValue( inFunctionType );
     533                        inFunctionType = true;
     534                        printQualifiers( refType );
     535                        maybeAccept( refType->base.get(), *visitor );
     536                }
     537
     538                inline std::vector< ast::ptr< ast::Type > > getTypes( const std::vector< ast::ptr< ast::DeclWithType > > & decls ) {
     539                        std::vector< ast::ptr< ast::Type > > ret;
     540                        std::transform( decls.begin(), decls.end(), std::back_inserter( ret ),
     541                                                        std::mem_fun( &ast::DeclWithType::get_type ) );
     542                        return ret;
     543                }
     544
     545                void Mangler_new::postvisit( const ast::FunctionType * functionType ) {
     546                        printQualifiers( functionType );
     547                        mangleName << Encoding::function;
     548                        // turn on inFunctionType so that printQualifiers does not print most qualifiers for function parameters,
     549                        // since qualifiers on outermost parameter type do not differentiate function types, e.g.,
     550                        // void (*)(const int) and void (*)(int) are the same type, but void (*)(const int *) and void (*)(int *) are different
     551                        GuardValue( inFunctionType );
     552                        inFunctionType = true;
     553                        std::vector< ast::ptr< ast::Type > > returnTypes = getTypes( functionType->returns );
     554                        if (returnTypes.empty()) mangleName << Encoding::void_t;
     555                        else accept_each( returnTypes, *visitor );
     556                        mangleName << "_";
     557                        std::vector< ast::ptr< ast::Type > > paramTypes = getTypes( functionType->params );
     558                        accept_each( paramTypes, *visitor );
     559                        mangleName << "_";
     560                }
     561
     562                void Mangler_new::mangleRef( const ast::ReferenceToType * refType, std::string prefix ) {
     563                        printQualifiers( refType );
     564
     565                        mangleName << prefix << refType->name.length() << refType->name;
     566
     567                        if ( mangleGenericParams ) {
     568                                if ( ! refType->params.empty() ) {
     569                                        mangleName << "_";
     570                                        for ( const ast::Expr * param : refType->params ) {
     571                                                auto paramType = dynamic_cast< const ast::TypeExpr * >( param );
     572                                                assertf(paramType, "Aggregate parameters should be type expressions: %s", toCString(param));
     573                                                maybeAccept( paramType->type.get(), *visitor );
     574                                        }
     575                                        mangleName << "_";
     576                                }
     577                        }
     578                }
     579
     580                void Mangler_new::postvisit( const ast::StructInstType * aggregateUseType ) {
     581                        mangleRef( aggregateUseType, Encoding::struct_t );
     582                }
     583
     584                void Mangler_new::postvisit( const ast::UnionInstType * aggregateUseType ) {
     585                        mangleRef( aggregateUseType, Encoding::union_t );
     586                }
     587
     588                void Mangler_new::postvisit( const ast::EnumInstType * aggregateUseType ) {
     589                        mangleRef( aggregateUseType, Encoding::enum_t );
     590                }
     591
     592                void Mangler_new::postvisit( const ast::TypeInstType * typeInst ) {
     593                        VarMapType::iterator varNum = varNums.find( typeInst->name );
     594                        if ( varNum == varNums.end() ) {
     595                                mangleRef( typeInst, Encoding::type );
     596                        } else {
     597                                printQualifiers( typeInst );
     598                                // Note: Can't use name here, since type variable names do not actually disambiguate a function, e.g.
     599                                //   forall(dtype T) void f(T);
     600                                //   forall(dtype S) void f(S);
     601                                // are equivalent and should mangle the same way. This is accomplished by numbering the type variables when they
     602                                // are first found and prefixing with the appropriate encoding for the type class.
     603                                assertf( varNum->second.second < TypeDecl::NUMBER_OF_KINDS, "Unhandled type variable kind: %d", varNum->second.second );
     604                                mangleName << Encoding::typeVariables[varNum->second.second] << varNum->second.first;
     605                        } // if
     606                }
     607
     608                void Mangler_new::postvisit( const ast::TraitInstType * inst ) {
     609                        printQualifiers( inst );
     610                        mangleName << inst->name.size() << inst->name;
     611                }
     612
     613                void Mangler_new::postvisit( const ast::TupleType * tupleType ) {
     614                        printQualifiers( tupleType );
     615                        mangleName << Encoding::tuple << tupleType->types.size();
     616                        accept_each( tupleType->types, *visitor );
     617                }
     618
     619                void Mangler_new::postvisit( const ast::VarArgsType * varArgsType ) {
     620                        printQualifiers( varArgsType );
     621                        static const std::string vargs = "__builtin_va_list";
     622                        mangleName << Encoding::type << vargs.size() << vargs;
     623                }
     624
     625                void Mangler_new::postvisit( const ast::ZeroType * ) {
     626                        mangleName << Encoding::zero;
     627                }
     628
     629                void Mangler_new::postvisit( const ast::OneType * ) {
     630                        mangleName << Encoding::one;
     631                }
     632
     633                void Mangler_new::postvisit( const ast::QualifiedType * qualType ) {
     634                        bool inqual = inQualifiedType;
     635                        if (! inqual ) {
     636                                // N marks the start of a qualified type
     637                                inQualifiedType = true;
     638                                mangleName << Encoding::qualifiedTypeStart;
     639                        }
     640                        maybeAccept( qualType->parent.get(), *visitor );
     641                        maybeAccept( qualType->child.get(), *visitor );
     642                        if ( ! inqual ) {
     643                                // E marks the end of a qualified type
     644                                inQualifiedType = false;
     645                                mangleName << Encoding::qualifiedTypeEnd;
     646                        }
     647                }
     648
     649                void Mangler_new::postvisit( const ast::TypeDecl * decl ) {
     650                        // TODO: is there any case where mangling a TypeDecl makes sense? If so, this code needs to be
     651                        // fixed to ensure that two TypeDecls mangle to the same name when they are the same type and vice versa.
     652                        // Note: The current scheme may already work correctly for this case, I have not thought about this deeply
     653                        // and the case has not yet come up in practice. Alternatively, if not then this code can be removed
     654                        // aside from the assert false.
     655                        assertf(false, "Mangler_new should not visit typedecl: %s", toCString(decl));
     656                        assertf( decl->kind < ast::TypeVar::Kind::NUMBER_OF_KINDS, "Unhandled type variable kind: %d", decl->kind );
     657                        mangleName << Encoding::typeVariables[ decl->kind ] << ( decl->name.length() ) << decl->name;
     658                }
     659
     660                __attribute__((unused)) void printVarMap( const std::map< std::string, std::pair< int, int > > &varMap, std::ostream &os ) {
     661                        for ( std::map< std::string, std::pair< int, int > >::const_iterator i = varMap.begin(); i != varMap.end(); ++i ) {
     662                                os << i->first << "(" << i->second.first << "/" << i->second.second << ")" << std::endl;
     663                        } // for
     664                }
     665
     666                void Mangler_new::printQualifiers( const ast::Type * type ) {
     667                        // skip if not including qualifiers
     668                        if ( typeMode ) return;
     669                        if ( auto ptype = dynamic_cast< const ast::ParameterizedType * >(type) ) {
     670                                if ( ! ptype->forall.empty() ) {
     671                                        std::list< std::string > assertionNames;
     672                                        int dcount = 0, fcount = 0, vcount = 0, acount = 0;
     673                                        mangleName << Encoding::forall;
     674                                        for ( const ast::TypeDecl * decl : ptype->forall ) {
     675                                                switch ( decl->kind ) {
     676                                                case ast::TypeVar::Kind::Dtype:
     677                                                        dcount++;
     678                                                        break;
     679                                                case ast::TypeVar::Kind::Ftype:
     680                                                        fcount++;
     681                                                        break;
     682                                                case ast::TypeVar::Kind::Ttype:
     683                                                        vcount++;
     684                                                        break;
     685                                                default:
     686                                                        assert( false );
     687                                                } // switch
     688                                                varNums[ decl->name ] = std::make_pair( nextVarNum, (int)decl->kind );
     689                                                for ( const ast::DeclWithType * assert : decl->assertions ) {
     690                                                        ast::Pass<Mangler_new> sub_mangler(
     691                                                                mangleOverridable, typeMode, mangleGenericParams, nextVarNum, varNums );
     692                                                        assert->accept( sub_mangler );
     693                                                        assertionNames.push_back( sub_mangler.pass.get_mangleName() );
     694                                                        acount++;
     695                                                } // for
     696                                        } // for
     697                                        mangleName << dcount << "_" << fcount << "_" << vcount << "_" << acount << "_";
     698                                        std::copy( assertionNames.begin(), assertionNames.end(), std::ostream_iterator< std::string >( mangleName, "" ) );
     699                                        mangleName << "_";
     700                                } // if
     701                        } // if
     702                        if ( ! inFunctionType ) {
     703                                // these qualifiers do not distinguish the outermost type of a function parameter
     704                                if ( type->is_const() ) {
     705                                        mangleName << Encoding::qualifiers.at(Type::Const);
     706                                } // if
     707                                if ( type->is_volatile() ) {
     708                                        mangleName << Encoding::qualifiers.at(Type::Volatile);
     709                                } // if
     710                                // Removed due to restrict not affecting function compatibility in GCC
     711                                // if ( type->get_isRestrict() ) {
     712                                //      mangleName << "E";
     713                                // } // if
     714                                if ( type->is_atomic() ) {
     715                                        mangleName << Encoding::qualifiers.at(Type::Atomic);
     716                                } // if
     717                        }
     718                        if ( type->is_mutex() ) {
     719                                mangleName << Encoding::qualifiers.at(Type::Mutex);
     720                        } // if
     721                        if ( inFunctionType ) {
     722                                // turn off inFunctionType so that types can be differentiated for nested qualifiers
     723                                GuardValue( inFunctionType );
     724                                inFunctionType = false;
     725                        }
     726                }
     727        }       // namespace
     728} // namespace Mangle
     729
    396730// Local Variables: //
    397731// tab-width: 4 //
  • src/SymTab/Mangler.h

    r7951100 rb067d9b  
    2121#include <utility>            // for pair
    2222
     23#include "AST/Bitfield.hpp"
     24#include "AST/Fwd.hpp"
    2325#include "SynTree/SynTree.h"  // for Types
    2426#include "SynTree/Visitor.h"  // for Visitor, maybeAccept
     27
     28// https://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangling
     29// The CFA name mangling scheme is based closely on the itanium C++ name mangling scheme, with the following key differences:
     30// * Variable names are also mangled to include type information, not just functions
     31// * CFA does not have template expansion, so the rules for function specialization do not apply.
     32// * CFA instead has to handle type parameters and assertion parameters.
     33// * Currently name compression is not implemented.
     34
     35namespace ResolvExpr {
     36        class TypeEnvironment;
     37}
    2538
    2639namespace SymTab {
    2740        namespace Mangler {
    2841                /// Mangle syntax tree object; primary interface to clients
    29                 std::string mangle( BaseSyntaxNode * decl, bool mangleOverridable = true, bool typeMode = false, bool mangleGenericParams = true );
     42                std::string mangle( const BaseSyntaxNode * decl, bool mangleOverridable = true, bool typeMode = false, bool mangleGenericParams = true );
    3043
    3144                /// Mangle a type name; secondary interface
    32                 std::string mangleType( Type* ty );
     45                std::string mangleType( const Type * ty );
    3346                /// Mangle ignoring generic type parameters
    34                 std::string mangleConcrete( Type* ty );
     47                std::string mangleConcrete( const Type * ty );
     48
     49                namespace Encoding {
     50                        extern const std::string manglePrefix;
     51                        extern const std::string basicTypes[];
     52                        extern const std::map<int, std::string> qualifiers;
     53
     54                        extern const std::string void_t;
     55                        extern const std::string zero;
     56                        extern const std::string one;
     57
     58                        extern const std::string function;
     59                        extern const std::string tuple;
     60                        extern const std::string pointer;
     61                        extern const std::string array;
     62                        extern const std::string qualifiedTypeStart;
     63                        extern const std::string qualifiedTypeEnd;
     64
     65                        extern const std::string forall;
     66                        extern const std::string typeVariables[];
     67
     68                        extern const std::string struct_t;
     69                        extern const std::string union_t;
     70                        extern const std::string enum_t;
     71                        extern const std::string type;
     72
     73                        extern const std::string autogen;
     74                        extern const std::string intrinsic;
     75                };
    3576        } // Mangler
    3677} // SymTab
     78
     79namespace Mangle {
     80        /// Bitflags for mangle modes
     81        enum {
     82                NoOverrideable  = 1 << 0,
     83                Type            = 1 << 1,
     84                NoGenericParams = 1 << 2
     85        };
     86
     87        /// Bitflag type for mangler modes
     88        struct mangle_flags {
     89                union {
     90                        unsigned int val;
     91                        struct {
     92                                bool no_overrideable   : 1;
     93                                bool type              : 1;
     94                                bool no_generic_params : 1;
     95                        };
     96                };
     97
     98                constexpr mangle_flags( unsigned int val ) : val(val) {}
     99        };
     100
     101        using Mode = bitfield<mangle_flags>;
     102
     103        static inline Mode typeMode() { return NoOverrideable | Type; }
     104
     105        /// Mangle declaration name
     106        std::string mangle( const ast::Node * decl, Mode mode = {} );
     107
     108        namespace Encoding {
     109                using namespace SymTab::Mangler::Encoding;
     110        };
     111}
     112
     113extern "C" {
     114        char * cforall_demangle(const char *, int);
     115}
    37116
    38117// Local Variables: //
  • src/SymTab/Validate.cc

    r7951100 rb067d9b  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 21:50:04 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Aug 28 13:47:23 2017
    13 // Update Count     : 359
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Wed Aug  7 6:42:00 2019
     13// Update Count     : 360
    1414//
    1515
     
    4444#include <list>                        // for list
    4545#include <string>                      // for string
     46#include <unordered_map>               // for unordered_map
    4647#include <utility>                     // for pair
    4748
     49#include "AST/Chain.hpp"
     50#include "AST/Decl.hpp"
     51#include "AST/Node.hpp"
     52#include "AST/Pass.hpp"
     53#include "AST/SymbolTable.hpp"
     54#include "AST/Type.hpp"
     55#include "AST/TypeSubstitution.hpp"
    4856#include "CodeGen/CodeGenerator.h"     // for genName
    4957#include "CodeGen/OperatorTable.h"     // for isCtorDtor, isCtorDtorAssign
    5058#include "ControlStruct/Mutate.h"      // for ForExprMutator
     59#include "Common/CodeLocation.h"       // for CodeLocation
     60#include "Common/Stats.h"              // for Stats::Heap
    5161#include "Common/PassVisitor.h"        // for PassVisitor, WithDeclsToAdd
    5262#include "Common/ScopedMap.h"          // for ScopedMap
     
    6171#include "Parser/LinkageSpec.h"        // for C
    6272#include "ResolvExpr/typeops.h"        // for typesCompatible
     73#include "ResolvExpr/Resolver.h"       // for findSingleExpression
     74#include "ResolvExpr/ResolveTypeof.h"  // for resolveTypeof
    6375#include "SymTab/Autogen.h"            // for SizeType
    6476#include "SynTree/Attribute.h"         // for noAttributes, Attribute
     
    7284#include "SynTree/TypeSubstitution.h"  // for TypeSubstitution
    7385#include "SynTree/Visitor.h"           // for Visitor
     86#include "Validate/HandleAttributes.h" // for handleAttributes
     87#include "Validate/FindSpecialDecls.h" // for FindSpecialDecls
    7488
    7589class CompoundStmt;
     
    7791class SwitchStmt;
    7892
    79 #define debugPrint( x ) if ( doDebug ) { std::cout << x; }
     93#define debugPrint( x ) if ( doDebug ) x
    8094
    8195namespace SymTab {
     96        /// hoists declarations that are difficult to hoist while parsing
     97        struct HoistTypeDecls final : public WithDeclsToAdd {
     98                void previsit( SizeofExpr * );
     99                void previsit( AlignofExpr * );
     100                void previsit( UntypedOffsetofExpr * );
     101                void previsit( CompoundLiteralExpr * );
     102                void handleType( Type * );
     103        };
     104
     105        struct FixQualifiedTypes final : public WithIndexer {
     106                Type * postmutate( QualifiedType * );
     107        };
     108
    82109        struct HoistStruct final : public WithDeclsToAdd, public WithGuards {
    83110                /// Flattens nested struct types
    84111                static void hoistStruct( std::list< Declaration * > &translationUnit );
    85112
    86                 void previsit( EnumInstType * enumInstType );
    87                 void previsit( StructInstType * structInstType );
    88                 void previsit( UnionInstType * unionInstType );
    89113                void previsit( StructDecl * aggregateDecl );
    90114                void previsit( UnionDecl * aggregateDecl );
    91115                void previsit( StaticAssertDecl * assertDecl );
     116                void previsit( StructInstType * type );
     117                void previsit( UnionInstType * type );
     118                void previsit( EnumInstType * type );
    92119
    93120          private:
    94                 template< typename AggDecl > void handleAggregate( AggDecl *aggregateDecl );
     121                template< typename AggDecl > void handleAggregate( AggDecl * aggregateDecl );
    95122
    96123                AggregateDecl * parentAggr = nullptr;
     
    106133
    107134        /// Replaces enum types by int, and function or array types in function parameter and return lists by appropriate pointers.
    108         struct EnumAndPointerDecay {
    109                 void previsit( EnumDecl *aggregateDecl );
    110                 void previsit( FunctionType *func );
     135        struct EnumAndPointerDecay_old {
     136                void previsit( EnumDecl * aggregateDecl );
     137                void previsit( FunctionType * func );
    111138        };
    112139
    113140        /// Associates forward declarations of aggregates with their definitions
    114         struct LinkReferenceToTypes final : public WithIndexer, public WithGuards {
    115                 LinkReferenceToTypes( const Indexer *indexer );
    116                 void postvisit( TypeInstType *typeInst );
    117 
    118                 void postvisit( EnumInstType *enumInst );
    119                 void postvisit( StructInstType *structInst );
    120                 void postvisit( UnionInstType *unionInst );
    121                 void postvisit( TraitInstType *traitInst );
    122 
    123                 void postvisit( EnumDecl *enumDecl );
    124                 void postvisit( StructDecl *structDecl );
    125                 void postvisit( UnionDecl *unionDecl );
     141        struct LinkReferenceToTypes_old final : public WithIndexer, public WithGuards, public WithVisitorRef<LinkReferenceToTypes_old>, public WithShortCircuiting {
     142                LinkReferenceToTypes_old( const Indexer * indexer );
     143                void postvisit( TypeInstType * typeInst );
     144
     145                void postvisit( EnumInstType * enumInst );
     146                void postvisit( StructInstType * structInst );
     147                void postvisit( UnionInstType * unionInst );
     148                void postvisit( TraitInstType * traitInst );
     149                void previsit( QualifiedType * qualType );
     150                void postvisit( QualifiedType * qualType );
     151
     152                void postvisit( EnumDecl * enumDecl );
     153                void postvisit( StructDecl * structDecl );
     154                void postvisit( UnionDecl * unionDecl );
    126155                void postvisit( TraitDecl * traitDecl );
    127156
    128                 void previsit( StructDecl *structDecl );
    129                 void previsit( UnionDecl *unionDecl );
     157                void previsit( StructDecl * structDecl );
     158                void previsit( UnionDecl * unionDecl );
    130159
    131160                void renameGenericParams( std::list< TypeDecl * > & params );
    132161
    133162          private:
    134                 const Indexer *local_indexer;
     163                const Indexer * local_indexer;
    135164
    136165                typedef std::map< std::string, std::list< EnumInstType * > > ForwardEnumsType;
     
    145174
    146175        /// Replaces array and function types in forall lists by appropriate pointer type and assigns each Object and Function declaration a unique ID.
    147         struct ForallPointerDecay final {
     176        struct ForallPointerDecay_old final {
    148177                void previsit( ObjectDecl * object );
    149178                void previsit( FunctionDecl * func );
     
    165194        };
    166195
    167         struct EliminateTypedef final : public WithVisitorRef<EliminateTypedef>, public WithGuards {
    168                 EliminateTypedef() : scopeLevel( 0 ) {}
     196        struct ReplaceTypedef final : public WithVisitorRef<ReplaceTypedef>, public WithGuards, public WithShortCircuiting, public WithDeclsToAdd {
     197                ReplaceTypedef() : scopeLevel( 0 ) {}
    169198                /// Replaces typedefs by forward declarations
    170                 static void eliminateTypedef( std::list< Declaration * > &translationUnit );
    171 
     199                static void replaceTypedef( std::list< Declaration * > &translationUnit );
     200
     201                void premutate( QualifiedType * );
     202                Type * postmutate( QualifiedType * qualType );
    172203                Type * postmutate( TypeInstType * aggregateUseType );
    173204                Declaration * postmutate( TypedefDecl * typeDecl );
     
    180211
    181212                void premutate( CompoundStmt * compoundStmt );
    182                 CompoundStmt * postmutate( CompoundStmt * compoundStmt );
    183213
    184214                void premutate( StructDecl * structDecl );
    185                 Declaration * postmutate( StructDecl * structDecl );
    186215                void premutate( UnionDecl * unionDecl );
    187                 Declaration * postmutate( UnionDecl * unionDecl );
    188216                void premutate( EnumDecl * enumDecl );
    189                 Declaration * postmutate( EnumDecl * enumDecl );
    190                 Declaration * postmutate( TraitDecl * contextDecl );
     217                void premutate( TraitDecl * );
    191218
    192219                void premutate( FunctionType * ftype );
     
    194221          private:
    195222                template<typename AggDecl>
    196                 AggDecl *handleAggregate( AggDecl * aggDecl );
    197 
    198                 template<typename AggDecl>
    199223                void addImplicitTypedef( AggDecl * aggDecl );
     224                template< typename AggDecl >
     225                void handleAggregate( AggDecl * aggr );
    200226
    201227                typedef std::unique_ptr<TypedefDecl> TypedefDeclPtr;
    202228                typedef ScopedMap< std::string, std::pair< TypedefDeclPtr, int > > TypedefMap;
    203                 typedef std::map< std::string, TypeDecl * > TypeDeclMap;
     229                typedef ScopedMap< std::string, TypeDecl * > TypeDeclMap;
    204230                TypedefMap typedefNames;
    205231                TypeDeclMap typedeclNames;
    206232                int scopeLevel;
    207233                bool inFunctionType = false;
     234        };
     235
     236        struct EliminateTypedef {
     237                /// removes TypedefDecls from the AST
     238                static void eliminateTypedef( std::list< Declaration * > &translationUnit );
     239
     240                template<typename AggDecl>
     241                void handleAggregate( AggDecl * aggregateDecl );
     242
     243                void previsit( StructDecl * aggregateDecl );
     244                void previsit( UnionDecl * aggregateDecl );
     245                void previsit( CompoundStmt * compoundStmt );
    208246        };
    209247
     
    214252                static void verify( std::list< Declaration * > &translationUnit );
    215253
    216                 void previsit( FunctionDecl *funcDecl );
     254                void previsit( FunctionDecl * funcDecl );
    217255        };
    218256
     
    223261        };
    224262
    225         struct ArrayLength {
     263        struct FixObjectType : public WithIndexer {
     264                /// resolves typeof type in object, function, and type declarations
     265                static void fix( std::list< Declaration * > & translationUnit );
     266
     267                void previsit( ObjectDecl * );
     268                void previsit( FunctionDecl * );
     269                void previsit( TypeDecl * );
     270        };
     271
     272        struct ArrayLength : public WithIndexer {
    226273                /// for array types without an explicit length, compute the length and store it so that it
    227274                /// is known to the rest of the phases. For example,
     
    234281
    235282                void previsit( ObjectDecl * objDecl );
     283                void previsit( ArrayType * arrayType );
    236284        };
    237285
     
    239287                Type::StorageClasses storageClasses;
    240288
    241                 void premutate( ObjectDecl *objectDecl );
    242                 Expression * postmutate( CompoundLiteralExpr *compLitExpr );
     289                void premutate( ObjectDecl * objectDecl );
     290                Expression * postmutate( CompoundLiteralExpr * compLitExpr );
    243291        };
    244292
     
    250298        };
    251299
    252         FunctionDecl * dereferenceOperator = nullptr;
    253         struct FindSpecialDeclarations final {
    254                 void previsit( FunctionDecl * funcDecl );
    255         };
    256 
    257300        void validate( std::list< Declaration * > &translationUnit, __attribute__((unused)) bool doDebug ) {
    258                 PassVisitor<EnumAndPointerDecay> epc;
    259                 PassVisitor<LinkReferenceToTypes> lrt( nullptr );
    260                 PassVisitor<ForallPointerDecay> fpd;
     301                PassVisitor<EnumAndPointerDecay_old> epc;
     302                PassVisitor<LinkReferenceToTypes_old> lrt( nullptr );
     303                PassVisitor<ForallPointerDecay_old> fpd;
    261304                PassVisitor<CompoundLiteral> compoundliteral;
    262305                PassVisitor<ValidateGenericParameters> genericParams;
    263                 PassVisitor<FindSpecialDeclarations> finder;
    264306                PassVisitor<LabelAddressFixer> labelAddrFixer;
    265 
    266                 EliminateTypedef::eliminateTypedef( translationUnit );
    267                 HoistStruct::hoistStruct( translationUnit ); // must happen after EliminateTypedef, so that aggregate typedefs occur in the correct order
    268                 ReturnTypeFixer::fix( translationUnit ); // must happen before autogen
    269                 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
    270                 acceptAll( translationUnit, lrt ); // must happen before autogen, because sized flag needs to propagate to generated functions
    271                 acceptAll( translationUnit, genericParams );  // check as early as possible - can't happen before LinkReferenceToTypes
    272                 VerifyCtorDtorAssign::verify( translationUnit );  // must happen before autogen, because autogen examines existing ctor/dtors
    273                 ReturnChecker::checkFunctionReturns( translationUnit );
    274                 InitTweak::fixReturnStatements( translationUnit ); // must happen before autogen
    275                 Concurrency::applyKeywords( translationUnit );
    276                 acceptAll( translationUnit, fpd ); // must happen before autogenerateRoutines, after Concurrency::applyKeywords because uniqueIds must be set on declaration before resolution
    277                 ControlStruct::hoistControlDecls( translationUnit );  // hoist initialization out of for statements; must happen before autogenerateRoutines
    278                 autogenerateRoutines( translationUnit ); // moved up, used to be below compoundLiteral - currently needs EnumAndPointerDecay
    279                 Concurrency::implementMutexFuncs( translationUnit );
    280                 Concurrency::implementThreadStarter( translationUnit );
    281                 mutateAll( translationUnit, compoundliteral );
    282                 ArrayLength::computeLength( translationUnit );
    283                 acceptAll( translationUnit, finder ); // xxx - remove this pass soon
    284                 mutateAll( translationUnit, labelAddrFixer );
    285         }
    286 
    287         void validateType( Type *type, const Indexer *indexer ) {
    288                 PassVisitor<EnumAndPointerDecay> epc;
    289                 PassVisitor<LinkReferenceToTypes> lrt( indexer );
    290                 PassVisitor<ForallPointerDecay> fpd;
     307                PassVisitor<HoistTypeDecls> hoistDecls;
     308                PassVisitor<FixQualifiedTypes> fixQual;
     309
     310                {
     311                        Stats::Heap::newPass("validate-A");
     312                        Stats::Time::BlockGuard guard("validate-A");
     313                        acceptAll( translationUnit, hoistDecls );
     314                        ReplaceTypedef::replaceTypedef( translationUnit );
     315                        ReturnTypeFixer::fix( translationUnit ); // must happen before autogen
     316                        acceptAll( translationUnit, epc ); // must happen before VerifyCtorDtorAssign, because void return objects should not exist; before LinkReferenceToTypes_old because it is an indexer and needs correct types for mangling
     317                }
     318                {
     319                        Stats::Heap::newPass("validate-B");
     320                        Stats::Time::BlockGuard guard("validate-B");
     321                        Stats::Time::TimeBlock("Link Reference To Types", [&]() {
     322                                acceptAll( translationUnit, lrt ); // must happen before autogen, because sized flag needs to propagate to generated functions
     323                        });
     324                        Stats::Time::TimeBlock("Fix Qualified Types", [&]() {
     325                                mutateAll( translationUnit, fixQual ); // must happen after LinkReferenceToTypes_old, because aggregate members are accessed
     326                        });
     327                        Stats::Time::TimeBlock("Hoist Structs", [&]() {
     328                                HoistStruct::hoistStruct( translationUnit ); // must happen after EliminateTypedef, so that aggregate typedefs occur in the correct order
     329                        });
     330                        Stats::Time::TimeBlock("Eliminate Typedefs", [&]() {
     331                                EliminateTypedef::eliminateTypedef( translationUnit ); //
     332                        });
     333                }
     334                {
     335                        Stats::Heap::newPass("validate-C");
     336                        Stats::Time::BlockGuard guard("validate-C");
     337                        acceptAll( translationUnit, genericParams );  // check as early as possible - can't happen before LinkReferenceToTypes_old
     338                        VerifyCtorDtorAssign::verify( translationUnit );  // must happen before autogen, because autogen examines existing ctor/dtors
     339                        ReturnChecker::checkFunctionReturns( translationUnit );
     340                        InitTweak::fixReturnStatements( translationUnit ); // must happen before autogen
     341                }
     342                {
     343                        Stats::Heap::newPass("validate-D");
     344                        Stats::Time::BlockGuard guard("validate-D");
     345                        Stats::Time::TimeBlock("Apply Concurrent Keywords", [&]() {
     346                                Concurrency::applyKeywords( translationUnit );
     347                        });
     348                        Stats::Time::TimeBlock("Forall Pointer Decay", [&]() {
     349                                acceptAll( translationUnit, fpd ); // must happen before autogenerateRoutines, after Concurrency::applyKeywords because uniqueIds must be set on declaration before resolution
     350                        });
     351                        Stats::Time::TimeBlock("Hoist Control Declarations", [&]() {
     352                                ControlStruct::hoistControlDecls( translationUnit );  // hoist initialization out of for statements; must happen before autogenerateRoutines
     353                        });
     354                        Stats::Time::TimeBlock("Generate Autogen routines", [&]() {
     355                                autogenerateRoutines( translationUnit ); // moved up, used to be below compoundLiteral - currently needs EnumAndPointerDecay_old
     356                        });
     357                }
     358                {
     359                        Stats::Heap::newPass("validate-E");
     360                        Stats::Time::BlockGuard guard("validate-E");
     361                        Stats::Time::TimeBlock("Implement Mutex Func", [&]() {
     362                                Concurrency::implementMutexFuncs( translationUnit );
     363                        });
     364                        Stats::Time::TimeBlock("Implement Thread Start", [&]() {
     365                                Concurrency::implementThreadStarter( translationUnit );
     366                        });
     367                        Stats::Time::TimeBlock("Compound Literal", [&]() {
     368                                mutateAll( translationUnit, compoundliteral );
     369                        });
     370                        Stats::Time::TimeBlock("Resolve With Expressions", [&]() {
     371                                ResolvExpr::resolveWithExprs( translationUnit ); // must happen before FixObjectType because user-code is resolved and may contain with variables
     372                        });
     373                }
     374                {
     375                        Stats::Heap::newPass("validate-F");
     376                        Stats::Time::BlockGuard guard("validate-F");
     377                        Stats::Time::TimeBlock("Fix Object Type", [&]() {
     378                                FixObjectType::fix( translationUnit );
     379                        });
     380                        Stats::Time::TimeBlock("Array Length", [&]() {
     381                                ArrayLength::computeLength( translationUnit );
     382                        });
     383                        Stats::Time::TimeBlock("Find Special Declarations", [&]() {
     384                                Validate::findSpecialDecls( translationUnit );
     385                        });
     386                        Stats::Time::TimeBlock("Fix Label Address", [&]() {
     387                                mutateAll( translationUnit, labelAddrFixer );
     388                        });
     389                        Stats::Time::TimeBlock("Handle Attributes", [&]() {
     390                                Validate::handleAttributes( translationUnit );
     391                        });
     392                }
     393        }
     394
     395        void validateType( Type * type, const Indexer * indexer ) {
     396                PassVisitor<EnumAndPointerDecay_old> epc;
     397                PassVisitor<LinkReferenceToTypes_old> lrt( indexer );
     398                PassVisitor<ForallPointerDecay_old> fpd;
    291399                type->accept( epc );
    292400                type->accept( lrt );
     
    294402        }
    295403
     404
     405        void HoistTypeDecls::handleType( Type * type ) {
     406                // some type declarations are buried in expressions and not easy to hoist during parsing; hoist them here
     407                AggregateDecl * aggr = nullptr;
     408                if ( StructInstType * inst = dynamic_cast< StructInstType * >( type ) ) {
     409                        aggr = inst->baseStruct;
     410                } else if ( UnionInstType * inst = dynamic_cast< UnionInstType * >( type ) ) {
     411                        aggr = inst->baseUnion;
     412                } else if ( EnumInstType * inst = dynamic_cast< EnumInstType * >( type ) ) {
     413                        aggr = inst->baseEnum;
     414                }
     415                if ( aggr && aggr->body ) {
     416                        declsToAddBefore.push_front( aggr );
     417                }
     418        }
     419
     420        void HoistTypeDecls::previsit( SizeofExpr * expr ) {
     421                handleType( expr->type );
     422        }
     423
     424        void HoistTypeDecls::previsit( AlignofExpr * expr ) {
     425                handleType( expr->type );
     426        }
     427
     428        void HoistTypeDecls::previsit( UntypedOffsetofExpr * expr ) {
     429                handleType( expr->type );
     430        }
     431
     432        void HoistTypeDecls::previsit( CompoundLiteralExpr * expr ) {
     433                handleType( expr->result );
     434        }
     435
     436
     437        Type * FixQualifiedTypes::postmutate( QualifiedType * qualType ) {
     438                Type * parent = qualType->parent;
     439                Type * child = qualType->child;
     440                if ( dynamic_cast< GlobalScopeType * >( qualType->parent ) ) {
     441                        // .T => lookup T at global scope
     442                        if ( TypeInstType * inst = dynamic_cast< TypeInstType * >( child ) ) {
     443                                auto td = indexer.globalLookupType( inst->name );
     444                                if ( ! td ) {
     445                                        SemanticError( qualType->location, toString("Use of undefined global type ", inst->name) );
     446                                }
     447                                auto base = td->base;
     448                                assert( base );
     449                                Type * ret = base->clone();
     450                                ret->get_qualifiers() = qualType->get_qualifiers();
     451                                return ret;
     452                        } else {
     453                                // .T => T is not a type name
     454                                assertf( false, "unhandled global qualified child type: %s", toCString(child) );
     455                        }
     456                } else {
     457                        // S.T => S must be an aggregate type, find the declaration for T in S.
     458                        AggregateDecl * aggr = nullptr;
     459                        if ( StructInstType * inst = dynamic_cast< StructInstType * >( parent ) ) {
     460                                aggr = inst->baseStruct;
     461                        } else if ( UnionInstType * inst = dynamic_cast< UnionInstType * > ( parent ) ) {
     462                                aggr = inst->baseUnion;
     463                        } else {
     464                                SemanticError( qualType->location, toString("Qualified type requires an aggregate on the left, but has: ", parent) );
     465                        }
     466                        assert( aggr ); // TODO: need to handle forward declarations
     467                        for ( Declaration * member : aggr->members ) {
     468                                if ( TypeInstType * inst = dynamic_cast< TypeInstType * >( child ) ) {
     469                                        // name on the right is a typedef
     470                                        if ( NamedTypeDecl * aggr = dynamic_cast< NamedTypeDecl * > ( member ) ) {
     471                                                if ( aggr->name == inst->name ) {
     472                                                        assert( aggr->base );
     473                                                        Type * ret = aggr->base->clone();
     474                                                        ret->get_qualifiers() = qualType->get_qualifiers();
     475                                                        TypeSubstitution sub = parent->genericSubstitution();
     476                                                        sub.apply(ret);
     477                                                        return ret;
     478                                                }
     479                                        }
     480                                } else {
     481                                        // S.T - S is not an aggregate => error
     482                                        assertf( false, "unhandled qualified child type: %s", toCString(qualType) );
     483                                }
     484                        }
     485                        // failed to find a satisfying definition of type
     486                        SemanticError( qualType->location, toString("Undefined type in qualified type: ", qualType) );
     487                }
     488
     489                // ... may want to link canonical SUE definition to each forward decl so that it becomes easier to lookup?
     490        }
     491
     492
    296493        void HoistStruct::hoistStruct( std::list< Declaration * > &translationUnit ) {
    297494                PassVisitor<HoistStruct> hoister;
     
    299496        }
    300497
    301         bool shouldHoist( Declaration *decl ) {
     498        bool shouldHoist( Declaration * decl ) {
    302499                return dynamic_cast< StructDecl * >( decl ) || dynamic_cast< UnionDecl * >( decl ) || dynamic_cast< StaticAssertDecl * >( decl );
    303500        }
    304501
     502        namespace {
     503                void qualifiedName( AggregateDecl * aggr, std::ostringstream & ss ) {
     504                        if ( aggr->parent ) qualifiedName( aggr->parent, ss );
     505                        ss << "__" << aggr->name;
     506                }
     507
     508                // mangle nested type names using entire parent chain
     509                std::string qualifiedName( AggregateDecl * aggr ) {
     510                        std::ostringstream ss;
     511                        qualifiedName( aggr, ss );
     512                        return ss.str();
     513                }
     514        }
     515
    305516        template< typename AggDecl >
    306         void HoistStruct::handleAggregate( AggDecl *aggregateDecl ) {
     517        void HoistStruct::handleAggregate( AggDecl * aggregateDecl ) {
    307518                if ( parentAggr ) {
     519                        aggregateDecl->parent = parentAggr;
     520                        aggregateDecl->name = qualifiedName( aggregateDecl );
    308521                        // Add elements in stack order corresponding to nesting structure.
    309522                        declsToAddBefore.push_front( aggregateDecl );
     
    316529        }
    317530
    318         void HoistStruct::previsit( EnumInstType * inst ) {
    319                 if ( inst->baseEnum && inst->baseEnum->body ) {
    320                         declsToAddBefore.push_front( inst->baseEnum );
    321                 }
    322         }
    323 
    324         void HoistStruct::previsit( StructInstType * inst ) {
    325                 if ( inst->baseStruct && inst->baseStruct->body ) {
    326                         declsToAddBefore.push_front( inst->baseStruct );
    327                 }
    328         }
    329 
    330         void HoistStruct::previsit( UnionInstType * inst ) {
    331                 if ( inst->baseUnion && inst->baseUnion->body ) {
    332                         declsToAddBefore.push_front( inst->baseUnion );
    333                 }
    334         }
    335 
    336531        void HoistStruct::previsit( StaticAssertDecl * assertDecl ) {
    337532                if ( parentAggr ) {
     
    348543        }
    349544
    350         void EnumAndPointerDecay::previsit( EnumDecl *enumDecl ) {
     545        void HoistStruct::previsit( StructInstType * type ) {
     546                // need to reset type name after expanding to qualified name
     547                assert( type->baseStruct );
     548                type->name = type->baseStruct->name;
     549        }
     550
     551        void HoistStruct::previsit( UnionInstType * type ) {
     552                assert( type->baseUnion );
     553                type->name = type->baseUnion->name;
     554        }
     555
     556        void HoistStruct::previsit( EnumInstType * type ) {
     557                assert( type->baseEnum );
     558                type->name = type->baseEnum->name;
     559        }
     560
     561
     562        bool isTypedef( Declaration * decl ) {
     563                return dynamic_cast< TypedefDecl * >( decl );
     564        }
     565
     566        void EliminateTypedef::eliminateTypedef( std::list< Declaration * > &translationUnit ) {
     567                PassVisitor<EliminateTypedef> eliminator;
     568                acceptAll( translationUnit, eliminator );
     569                filter( translationUnit, isTypedef, true );
     570        }
     571
     572        template< typename AggDecl >
     573        void EliminateTypedef::handleAggregate( AggDecl * aggregateDecl ) {
     574                filter( aggregateDecl->members, isTypedef, true );
     575        }
     576
     577        void EliminateTypedef::previsit( StructDecl * aggregateDecl ) {
     578                handleAggregate( aggregateDecl );
     579        }
     580
     581        void EliminateTypedef::previsit( UnionDecl * aggregateDecl ) {
     582                handleAggregate( aggregateDecl );
     583        }
     584
     585        void EliminateTypedef::previsit( CompoundStmt * compoundStmt ) {
     586                // remove and delete decl stmts
     587                filter( compoundStmt->kids, [](Statement * stmt) {
     588                        if ( DeclStmt * declStmt = dynamic_cast< DeclStmt * >( stmt ) ) {
     589                                if ( dynamic_cast< TypedefDecl * >( declStmt->decl ) ) {
     590                                        return true;
     591                                } // if
     592                        } // if
     593                        return false;
     594                }, true);
     595        }
     596
     597        void EnumAndPointerDecay_old::previsit( EnumDecl * enumDecl ) {
    351598                // Set the type of each member of the enumeration to be EnumConstant
    352                 for ( std::list< Declaration * >::iterator i = enumDecl->get_members().begin(); i != enumDecl->get_members().end(); ++i ) {
    353                         ObjectDecl * obj = dynamic_cast< ObjectDecl * >( *i );
     599                for ( std::list< Declaration * >::iterator i = enumDecl->members.begin(); i != enumDecl->members.end(); ++i ) {
     600                        ObjectDecl * obj = dynamic_cast< ObjectDecl * >( * i );
    354601                        assert( obj );
    355                         obj->set_type( new EnumInstType( Type::Qualifiers( Type::Const ), enumDecl->get_name() ) );
     602                        obj->set_type( new EnumInstType( Type::Qualifiers( Type::Const ), enumDecl->name ) );
    356603                } // for
    357604        }
     
    380627        }
    381628
    382         void EnumAndPointerDecay::previsit( FunctionType *func ) {
     629        void EnumAndPointerDecay_old::previsit( FunctionType * func ) {
    383630                // Fix up parameters and return types
    384631                fixFunctionList( func->parameters, func->isVarArgs, func );
     
    386633        }
    387634
    388         LinkReferenceToTypes::LinkReferenceToTypes( const Indexer *other_indexer ) {
     635        LinkReferenceToTypes_old::LinkReferenceToTypes_old( const Indexer * other_indexer ) {
    389636                if ( other_indexer ) {
    390637                        local_indexer = other_indexer;
     
    394641        }
    395642
    396         void LinkReferenceToTypes::postvisit( EnumInstType *enumInst ) {
    397                 EnumDecl *st = local_indexer->lookupEnum( enumInst->get_name() );
     643        void LinkReferenceToTypes_old::postvisit( EnumInstType * enumInst ) {
     644                const EnumDecl * st = local_indexer->lookupEnum( enumInst->name );
    398645                // it's not a semantic error if the enum is not found, just an implicit forward declaration
    399646                if ( st ) {
    400                         //assert( ! enumInst->get_baseEnum() || enumInst->get_baseEnum()->get_members().empty() || ! st->get_members().empty() );
    401                         enumInst->set_baseEnum( st );
    402                 } // if
    403                 if ( ! st || st->get_members().empty() ) {
     647                        enumInst->baseEnum = const_cast<EnumDecl *>(st); // Just linking in the node
     648                } // if
     649                if ( ! st || ! st->body ) {
    404650                        // use of forward declaration
    405                         forwardEnums[ enumInst->get_name() ].push_back( enumInst );
     651                        forwardEnums[ enumInst->name ].push_back( enumInst );
    406652                } // if
    407653        }
     
    415661        }
    416662
    417         void LinkReferenceToTypes::postvisit( StructInstType *structInst ) {
    418                 StructDecl *st = local_indexer->lookupStruct( structInst->get_name() );
     663        void LinkReferenceToTypes_old::postvisit( StructInstType * structInst ) {
     664                const StructDecl * st = local_indexer->lookupStruct( structInst->name );
    419665                // it's not a semantic error if the struct is not found, just an implicit forward declaration
    420666                if ( st ) {
    421                         //assert( ! structInst->get_baseStruct() || structInst->get_baseStruct()->get_members().empty() || ! st->get_members().empty() );
    422                         structInst->set_baseStruct( st );
    423                 } // if
    424                 if ( ! st || st->get_members().empty() ) {
     667                        structInst->baseStruct = const_cast<StructDecl *>(st); // Just linking in the node
     668                } // if
     669                if ( ! st || ! st->body ) {
    425670                        // use of forward declaration
    426                         forwardStructs[ structInst->get_name() ].push_back( structInst );
     671                        forwardStructs[ structInst->name ].push_back( structInst );
    427672                } // if
    428673                checkGenericParameters( structInst );
    429674        }
    430675
    431         void LinkReferenceToTypes::postvisit( UnionInstType *unionInst ) {
    432                 UnionDecl *un = local_indexer->lookupUnion( unionInst->get_name() );
     676        void LinkReferenceToTypes_old::postvisit( UnionInstType * unionInst ) {
     677                const UnionDecl * un = local_indexer->lookupUnion( unionInst->name );
    433678                // it's not a semantic error if the union is not found, just an implicit forward declaration
    434679                if ( un ) {
    435                         unionInst->set_baseUnion( un );
    436                 } // if
    437                 if ( ! un || un->get_members().empty() ) {
     680                        unionInst->baseUnion = const_cast<UnionDecl *>(un); // Just linking in the node
     681                } // if
     682                if ( ! un || ! un->body ) {
    438683                        // use of forward declaration
    439                         forwardUnions[ unionInst->get_name() ].push_back( unionInst );
     684                        forwardUnions[ unionInst->name ].push_back( unionInst );
    440685                } // if
    441686                checkGenericParameters( unionInst );
     687        }
     688
     689        void LinkReferenceToTypes_old::previsit( QualifiedType * ) {
     690                visit_children = false;
     691        }
     692
     693        void LinkReferenceToTypes_old::postvisit( QualifiedType * qualType ) {
     694                // linking only makes sense for the 'oldest ancestor' of the qualified type
     695                qualType->parent->accept( * visitor );
    442696        }
    443697
     
    450704                        DeclarationWithType * dwt2 = dynamic_cast<DeclarationWithType *>( d2 );
    451705                        if ( dwt1 && dwt2 ) {
    452                                 if ( dwt1->get_name() == dwt2->get_name() && ResolvExpr::typesCompatible( dwt1->get_type(), dwt2->get_type(), SymTab::Indexer() ) ) {
     706                                if ( dwt1->name == dwt2->name && ResolvExpr::typesCompatible( dwt1->get_type(), dwt2->get_type(), SymTab::Indexer() ) ) {
    453707                                        // std::cerr << "=========== equal:" << std::endl;
    454708                                        // std::cerr << "d1: " << d1 << std::endl;
     
    475729        template< typename Iterator >
    476730        void expandAssertions( TraitInstType * inst, Iterator out ) {
    477                 assertf( inst->baseTrait, "Trait instance not linked to base trait: %s", toString( inst ).c_str() );
     731                assertf( inst->baseTrait, "Trait instance not linked to base trait: %s", toCString( inst ) );
    478732                std::list< DeclarationWithType * > asserts;
    479733                for ( Declaration * decl : inst->baseTrait->members ) {
     
    484738        }
    485739
    486         void LinkReferenceToTypes::postvisit( TraitDecl * traitDecl ) {
     740        void LinkReferenceToTypes_old::postvisit( TraitDecl * traitDecl ) {
    487741                if ( traitDecl->name == "sized" ) {
    488742                        // "sized" is a special trait - flick the sized status on for the type variable
     
    506760        }
    507761
    508         void LinkReferenceToTypes::postvisit( TraitInstType * traitInst ) {
     762        void LinkReferenceToTypes_old::postvisit( TraitInstType * traitInst ) {
    509763                // handle other traits
    510                 TraitDecl *traitDecl = local_indexer->lookupTrait( traitInst->name );
     764                const TraitDecl * traitDecl = local_indexer->lookupTrait( traitInst->name );
    511765                if ( ! traitDecl ) {
    512766                        SemanticError( traitInst->location, "use of undeclared trait " + traitInst->name );
    513767                } // if
    514                 if ( traitDecl->get_parameters().size() != traitInst->get_parameters().size() ) {
     768                if ( traitDecl->parameters.size() != traitInst->parameters.size() ) {
    515769                        SemanticError( traitInst, "incorrect number of trait parameters: " );
    516770                } // if
    517                 traitInst->baseTrait = traitDecl;
     771                traitInst->baseTrait = const_cast<TraitDecl *>(traitDecl); // Just linking in the node
    518772
    519773                // need to carry over the 'sized' status of each decl in the instance
    520                 for ( auto p : group_iterate( traitDecl->get_parameters(), traitInst->get_parameters() ) ) {
     774                for ( auto p : group_iterate( traitDecl->parameters, traitInst->parameters ) ) {
    521775                        TypeExpr * expr = dynamic_cast< TypeExpr * >( std::get<1>(p) );
    522776                        if ( ! expr ) {
     
    525779                        if ( TypeInstType * inst = dynamic_cast< TypeInstType * >( expr->get_type() ) ) {
    526780                                TypeDecl * formalDecl = std::get<0>(p);
    527                                 TypeDecl * instDecl = inst->get_baseType();
     781                                TypeDecl * instDecl = inst->baseType;
    528782                                if ( formalDecl->get_sized() ) instDecl->set_sized( true );
    529783                        }
     
    532786        }
    533787
    534         void LinkReferenceToTypes::postvisit( EnumDecl *enumDecl ) {
     788        void LinkReferenceToTypes_old::postvisit( EnumDecl * enumDecl ) {
    535789                // visit enum members first so that the types of self-referencing members are updated properly
    536                 if ( ! enumDecl->get_members().empty() ) {
    537                         ForwardEnumsType::iterator fwds = forwardEnums.find( enumDecl->get_name() );
     790                if ( enumDecl->body ) {
     791                        ForwardEnumsType::iterator fwds = forwardEnums.find( enumDecl->name );
    538792                        if ( fwds != forwardEnums.end() ) {
    539793                                for ( std::list< EnumInstType * >::iterator inst = fwds->second.begin(); inst != fwds->second.end(); ++inst ) {
    540                                         (*inst )->set_baseEnum( enumDecl );
     794                                        (* inst)->baseEnum = enumDecl;
    541795                                } // for
    542796                                forwardEnums.erase( fwds );
    543797                        } // if
    544                 } // if
    545         }
    546 
    547         void LinkReferenceToTypes::renameGenericParams( std::list< TypeDecl * > & params ) {
     798
     799                        for ( Declaration * member : enumDecl->members ) {
     800                                ObjectDecl * field = strict_dynamic_cast<ObjectDecl *>( member );
     801                                if ( field->init ) {
     802                                        // need to resolve enumerator initializers early so that other passes that determine if an expression is constexpr have the appropriate information.
     803                                        SingleInit * init = strict_dynamic_cast<SingleInit *>( field->init );
     804                                        ResolvExpr::findSingleExpression( init->value, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), indexer );
     805                                }
     806                        }
     807                } // if
     808        }
     809
     810        void LinkReferenceToTypes_old::renameGenericParams( std::list< TypeDecl * > & params ) {
    548811                // rename generic type parameters uniquely so that they do not conflict with user-defined function forall parameters, e.g.
    549812                //   forall(otype T)
     
    563826        }
    564827
    565         void LinkReferenceToTypes::previsit( StructDecl * structDecl ) {
     828        void LinkReferenceToTypes_old::previsit( StructDecl * structDecl ) {
    566829                renameGenericParams( structDecl->parameters );
    567830        }
    568831
    569         void LinkReferenceToTypes::previsit( UnionDecl * unionDecl ) {
     832        void LinkReferenceToTypes_old::previsit( UnionDecl * unionDecl ) {
    570833                renameGenericParams( unionDecl->parameters );
    571834        }
    572835
    573         void LinkReferenceToTypes::postvisit( StructDecl *structDecl ) {
     836        void LinkReferenceToTypes_old::postvisit( StructDecl * structDecl ) {
    574837                // visit struct members first so that the types of self-referencing members are updated properly
    575838                // xxx - need to ensure that type parameters match up between forward declarations and definition (most importantly, number of type parameters and their defaults)
    576                 if ( ! structDecl->get_members().empty() ) {
    577                         ForwardStructsType::iterator fwds = forwardStructs.find( structDecl->get_name() );
     839                if ( structDecl->body ) {
     840                        ForwardStructsType::iterator fwds = forwardStructs.find( structDecl->name );
    578841                        if ( fwds != forwardStructs.end() ) {
    579842                                for ( std::list< StructInstType * >::iterator inst = fwds->second.begin(); inst != fwds->second.end(); ++inst ) {
    580                                         (*inst )->set_baseStruct( structDecl );
     843                                        (* inst)->baseStruct = structDecl;
    581844                                } // for
    582845                                forwardStructs.erase( fwds );
     
    585848        }
    586849
    587         void LinkReferenceToTypes::postvisit( UnionDecl *unionDecl ) {
    588                 if ( ! unionDecl->get_members().empty() ) {
    589                         ForwardUnionsType::iterator fwds = forwardUnions.find( unionDecl->get_name() );
     850        void LinkReferenceToTypes_old::postvisit( UnionDecl * unionDecl ) {
     851                if ( unionDecl->body ) {
     852                        ForwardUnionsType::iterator fwds = forwardUnions.find( unionDecl->name );
    590853                        if ( fwds != forwardUnions.end() ) {
    591854                                for ( std::list< UnionInstType * >::iterator inst = fwds->second.begin(); inst != fwds->second.end(); ++inst ) {
    592                                         (*inst )->set_baseUnion( unionDecl );
     855                                        (* inst)->baseUnion = unionDecl;
    593856                                } // for
    594857                                forwardUnions.erase( fwds );
     
    597860        }
    598861
    599         void LinkReferenceToTypes::postvisit( TypeInstType *typeInst ) {
     862        void LinkReferenceToTypes_old::postvisit( TypeInstType * typeInst ) {
    600863                // ensure generic parameter instances are renamed like the base type
    601864                if ( inGeneric && typeInst->baseType ) typeInst->name = typeInst->baseType->name;
    602                 if ( NamedTypeDecl *namedTypeDecl = local_indexer->lookupType( typeInst->get_name() ) ) {
    603                         if ( TypeDecl *typeDecl = dynamic_cast< TypeDecl * >( namedTypeDecl ) ) {
    604                                 typeInst->set_isFtype( typeDecl->get_kind() == TypeDecl::Ftype );
     865                if ( const NamedTypeDecl * namedTypeDecl = local_indexer->lookupType( typeInst->name ) ) {
     866                        if ( const TypeDecl * typeDecl = dynamic_cast< const TypeDecl * >( namedTypeDecl ) ) {
     867                                typeInst->set_isFtype( typeDecl->kind == TypeDecl::Ftype );
    605868                        } // if
    606869                } // if
     
    614877                        // expand trait instances into their members
    615878                        for ( DeclarationWithType * assertion : asserts ) {
    616                                 if ( TraitInstType *traitInst = dynamic_cast< TraitInstType * >( assertion->get_type() ) ) {
     879                                if ( TraitInstType * traitInst = dynamic_cast< TraitInstType * >( assertion->get_type() ) ) {
    617880                                        // expand trait instance into all of its members
    618881                                        expandAssertions( traitInst, back_inserter( type->assertions ) );
     
    634897        }
    635898
    636         void ForallPointerDecay::previsit( ObjectDecl *object ) {
     899        void ForallPointerDecay_old::previsit( ObjectDecl * object ) {
    637900                // ensure that operator names only apply to functions or function pointers
    638901                if ( CodeGen::isOperator( object->name ) && ! dynamic_cast< FunctionType * >( object->type->stripDeclarator() ) ) {
     
    642905        }
    643906
    644         void ForallPointerDecay::previsit( FunctionDecl *func ) {
     907        void ForallPointerDecay_old::previsit( FunctionDecl * func ) {
    645908                func->fixUniqueId();
    646909        }
    647910
    648         void ForallPointerDecay::previsit( FunctionType * ftype ) {
     911        void ForallPointerDecay_old::previsit( FunctionType * ftype ) {
    649912                forallFixer( ftype->forall, ftype );
    650913        }
    651914
    652         void ForallPointerDecay::previsit( StructDecl * aggrDecl ) {
     915        void ForallPointerDecay_old::previsit( StructDecl * aggrDecl ) {
    653916                forallFixer( aggrDecl->parameters, aggrDecl );
    654917        }
    655918
    656         void ForallPointerDecay::previsit( UnionDecl * aggrDecl ) {
     919        void ForallPointerDecay_old::previsit( UnionDecl * aggrDecl ) {
    657920                forallFixer( aggrDecl->parameters, aggrDecl );
    658921        }
     
    679942
    680943
    681         bool isTypedef( Declaration *decl ) {
    682                 return dynamic_cast< TypedefDecl * >( decl );
    683         }
    684 
    685         void EliminateTypedef::eliminateTypedef( std::list< Declaration * > &translationUnit ) {
    686                 PassVisitor<EliminateTypedef> eliminator;
     944        void ReplaceTypedef::replaceTypedef( std::list< Declaration * > &translationUnit ) {
     945                PassVisitor<ReplaceTypedef> eliminator;
    687946                mutateAll( translationUnit, eliminator );
    688947                if ( eliminator.pass.typedefNames.count( "size_t" ) ) {
    689948                        // grab and remember declaration of size_t
    690                         SizeType = eliminator.pass.typedefNames["size_t"].first->get_base()->clone();
     949                        Validate::SizeType = eliminator.pass.typedefNames["size_t"].first->base->clone();
    691950                } else {
    692951                        // xxx - missing global typedef for size_t - default to long unsigned int, even though that may be wrong
    693952                        // eventually should have a warning for this case.
    694                         SizeType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );
    695                 }
    696                 filter( translationUnit, isTypedef, true );
    697         }
    698 
    699         Type * EliminateTypedef::postmutate( TypeInstType * typeInst ) {
     953                        Validate::SizeType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );
     954                }
     955        }
     956
     957        void ReplaceTypedef::premutate( QualifiedType * ) {
     958                visit_children = false;
     959        }
     960
     961        Type * ReplaceTypedef::postmutate( QualifiedType * qualType ) {
     962                // replacing typedefs only makes sense for the 'oldest ancestor' of the qualified type
     963                qualType->parent = qualType->parent->acceptMutator( * visitor );
     964                return qualType;
     965        }
     966
     967        Type * ReplaceTypedef::postmutate( TypeInstType * typeInst ) {
    700968                // instances of typedef types will come here. If it is an instance
    701969                // of a typdef type, link the instance to its actual type.
    702                 TypedefMap::const_iterator def = typedefNames.find( typeInst->get_name() );
     970                TypedefMap::const_iterator def = typedefNames.find( typeInst->name );
    703971                if ( def != typedefNames.end() ) {
    704                         Type *ret = def->second.first->base->clone();
     972                        Type * ret = def->second.first->base->clone();
     973                        ret->location = typeInst->location;
    705974                        ret->get_qualifiers() |= typeInst->get_qualifiers();
    706975                        // attributes are not carried over from typedef to function parameters/return values
     
    713982                        // place instance parameters on the typedef'd type
    714983                        if ( ! typeInst->parameters.empty() ) {
    715                                 ReferenceToType *rtt = dynamic_cast<ReferenceToType*>(ret);
     984                                ReferenceToType * rtt = dynamic_cast<ReferenceToType *>(ret);
    716985                                if ( ! rtt ) {
    717986                                        SemanticError( typeInst->location, "Cannot apply type parameters to base type of " + typeInst->name );
    718987                                }
    719                                 rtt->get_parameters().clear();
     988                                rtt->parameters.clear();
    720989                                cloneAll( typeInst->parameters, rtt->parameters );
    721                                 mutateAll( rtt->parameters, *visitor );  // recursively fix typedefs on parameters
     990                                mutateAll( rtt->parameters, * visitor );  // recursively fix typedefs on parameters
    722991                        } // if
    723992                        delete typeInst;
    724993                        return ret;
    725994                } else {
    726                         TypeDeclMap::const_iterator base = typedeclNames.find( typeInst->get_name() );
    727                         assertf( base != typedeclNames.end(), "Cannot find typedecl name %s", typeInst->name.c_str() );
     995                        TypeDeclMap::const_iterator base = typedeclNames.find( typeInst->name );
     996                        if ( base == typedeclNames.end() ) {
     997                                SemanticError( typeInst->location, toString("Use of undefined type ", typeInst->name) );
     998                        }
    728999                        typeInst->set_baseType( base->second );
    729                 } // if
    730                 return typeInst;
     1000                        return typeInst;
     1001                } // if
     1002                assert( false );
    7311003        }
    7321004
     
    7451017        }
    7461018
    747         Declaration *EliminateTypedef::postmutate( TypedefDecl * tyDecl ) {
    748                 if ( typedefNames.count( tyDecl->get_name() ) == 1 && typedefNames[ tyDecl->get_name() ].second == scopeLevel ) {
     1019        Declaration * ReplaceTypedef::postmutate( TypedefDecl * tyDecl ) {
     1020                if ( typedefNames.count( tyDecl->name ) == 1 && typedefNames[ tyDecl->name ].second == scopeLevel ) {
    7491021                        // typedef to the same name from the same scope
    7501022                        // must be from the same type
    7511023
    752                         Type * t1 = tyDecl->get_base();
    753                         Type * t2 = typedefNames[ tyDecl->get_name() ].first->get_base();
     1024                        Type * t1 = tyDecl->base;
     1025                        Type * t2 = typedefNames[ tyDecl->name ].first->base;
    7541026                        if ( ! ResolvExpr::typesCompatible( t1, t2, Indexer() ) ) {
    7551027                                SemanticError( tyDecl->location, "Cannot redefine typedef: " + tyDecl->name );
     
    7631035                        }
    7641036                } else {
    765                         typedefNames[ tyDecl->get_name() ] = std::make_pair( TypedefDeclPtr( tyDecl ), scopeLevel );
     1037                        typedefNames[ tyDecl->name ] = std::make_pair( TypedefDeclPtr( tyDecl ), scopeLevel );
    7661038                } // if
    7671039
     
    7711043                //    struct screen;
    7721044                // because the expansion of the typedef is:
    773                 //    void rtn( SCREEN *p ) => void rtn( struct screen *p )
     1045                //    void rtn( SCREEN * p ) => void rtn( struct screen * p )
    7741046                // hence the type-name "screen" must be defined.
    7751047                // Note, qualifiers on the typedef are superfluous for the forward declaration.
    7761048
    777                 Type *designatorType = tyDecl->get_base()->stripDeclarator();
    778                 if ( StructInstType *aggDecl = dynamic_cast< StructInstType * >( designatorType ) ) {
    779                         return new StructDecl( aggDecl->get_name(), DeclarationNode::Struct, noAttributes, tyDecl->get_linkage() );
    780                 } else if ( UnionInstType *aggDecl = dynamic_cast< UnionInstType * >( designatorType ) ) {
    781                         return new UnionDecl( aggDecl->get_name(), noAttributes, tyDecl->get_linkage() );
    782                 } else if ( EnumInstType *enumDecl = dynamic_cast< EnumInstType * >( designatorType ) ) {
    783                         return new EnumDecl( enumDecl->get_name(), noAttributes, tyDecl->get_linkage() );
    784                 } else {
    785                         return tyDecl->clone();
    786                 } // if
    787         }
    788 
    789         void EliminateTypedef::premutate( TypeDecl * typeDecl ) {
    790                 TypedefMap::iterator i = typedefNames.find( typeDecl->get_name() );
     1049                Type * designatorType = tyDecl->base->stripDeclarator();
     1050                if ( StructInstType * aggDecl = dynamic_cast< StructInstType * >( designatorType ) ) {
     1051                        declsToAddBefore.push_back( new StructDecl( aggDecl->name, DeclarationNode::Struct, noAttributes, tyDecl->linkage ) );
     1052                } else if ( UnionInstType * aggDecl = dynamic_cast< UnionInstType * >( designatorType ) ) {
     1053                        declsToAddBefore.push_back( new UnionDecl( aggDecl->name, noAttributes, tyDecl->linkage ) );
     1054                } else if ( EnumInstType * enumDecl = dynamic_cast< EnumInstType * >( designatorType ) ) {
     1055                        declsToAddBefore.push_back( new EnumDecl( enumDecl->name, noAttributes, tyDecl->linkage ) );
     1056                } // if
     1057                return tyDecl->clone();
     1058        }
     1059
     1060        void ReplaceTypedef::premutate( TypeDecl * typeDecl ) {
     1061                TypedefMap::iterator i = typedefNames.find( typeDecl->name );
    7911062                if ( i != typedefNames.end() ) {
    7921063                        typedefNames.erase( i ) ;
    7931064                } // if
    7941065
    795                 typedeclNames[ typeDecl->get_name() ] = typeDecl;
    796         }
    797 
    798         void EliminateTypedef::premutate( FunctionDecl * ) {
     1066                typedeclNames.insert( typeDecl->name, typeDecl );
     1067        }
     1068
     1069        void ReplaceTypedef::premutate( FunctionDecl * ) {
    7991070                GuardScope( typedefNames );
    800         }
    801 
    802         void EliminateTypedef::premutate( ObjectDecl * ) {
     1071                GuardScope( typedeclNames );
     1072        }
     1073
     1074        void ReplaceTypedef::premutate( ObjectDecl * ) {
    8031075                GuardScope( typedefNames );
    804         }
    805 
    806         DeclarationWithType *EliminateTypedef::postmutate( ObjectDecl * objDecl ) {
    807                 if ( FunctionType *funtype = dynamic_cast<FunctionType *>( objDecl->get_type() ) ) { // function type?
     1076                GuardScope( typedeclNames );
     1077        }
     1078
     1079        DeclarationWithType * ReplaceTypedef::postmutate( ObjectDecl * objDecl ) {
     1080                if ( FunctionType * funtype = dynamic_cast<FunctionType *>( objDecl->type ) ) { // function type?
    8081081                        // replace the current object declaration with a function declaration
    809                         FunctionDecl * newDecl = new FunctionDecl( objDecl->get_name(), objDecl->get_storageClasses(), objDecl->get_linkage(), funtype, 0, objDecl->get_attributes(), objDecl->get_funcSpec() );
    810                         objDecl->get_attributes().clear();
     1082                        FunctionDecl * newDecl = new FunctionDecl( objDecl->name, objDecl->get_storageClasses(), objDecl->linkage, funtype, 0, objDecl->attributes, objDecl->get_funcSpec() );
     1083                        objDecl->attributes.clear();
    8111084                        objDecl->set_type( nullptr );
    8121085                        delete objDecl;
     
    8161089        }
    8171090
    818         void EliminateTypedef::premutate( CastExpr * ) {
     1091        void ReplaceTypedef::premutate( CastExpr * ) {
    8191092                GuardScope( typedefNames );
    820         }
    821 
    822         void EliminateTypedef::premutate( CompoundStmt * ) {
     1093                GuardScope( typedeclNames );
     1094        }
     1095
     1096        void ReplaceTypedef::premutate( CompoundStmt * ) {
    8231097                GuardScope( typedefNames );
     1098                GuardScope( typedeclNames );
    8241099                scopeLevel += 1;
    8251100                GuardAction( [this](){ scopeLevel -= 1; } );
    8261101        }
    8271102
    828         CompoundStmt *EliminateTypedef::postmutate( CompoundStmt * compoundStmt ) {
    829                 // remove and delete decl stmts
    830                 filter( compoundStmt->kids, [](Statement * stmt) {
    831                         if ( DeclStmt *declStmt = dynamic_cast< DeclStmt * >( stmt ) ) {
    832                                 if ( dynamic_cast< TypedefDecl * >( declStmt->get_decl() ) ) {
    833                                         return true;
    834                                 } // if
    835                         } // if
    836                         return false;
    837                 }, true);
    838                 return compoundStmt;
    839         }
    840 
    841         // there may be typedefs nested within aggregates. in order for everything to work properly, these should be removed
    842         // as well
    8431103        template<typename AggDecl>
    844         AggDecl *EliminateTypedef::handleAggregate( AggDecl * aggDecl ) {
    845                 filter( aggDecl->members, isTypedef, true );
    846                 return aggDecl;
    847         }
    848 
    849         template<typename AggDecl>
    850         void EliminateTypedef::addImplicitTypedef( AggDecl * aggDecl ) {
     1104        void ReplaceTypedef::addImplicitTypedef( AggDecl * aggDecl ) {
    8511105                if ( typedefNames.count( aggDecl->get_name() ) == 0 ) {
    852                         Type *type = nullptr;
     1106                        Type * type = nullptr;
    8531107                        if ( StructDecl * newDeclStructDecl = dynamic_cast< StructDecl * >( aggDecl ) ) {
    8541108                                type = new StructInstType( Type::Qualifiers(), newDeclStructDecl->get_name() );
     
    8601114                        TypedefDeclPtr tyDecl( new TypedefDecl( aggDecl->get_name(), aggDecl->location, Type::StorageClasses(), type, aggDecl->get_linkage() ) );
    8611115                        typedefNames[ aggDecl->get_name() ] = std::make_pair( std::move( tyDecl ), scopeLevel );
    862                 } // if
    863         }
    864 
    865         void EliminateTypedef::premutate( StructDecl * structDecl ) {
     1116                        // add the implicit typedef to the AST
     1117                        declsToAddBefore.push_back( new TypedefDecl( aggDecl->get_name(), aggDecl->location, Type::StorageClasses(), type->clone(), aggDecl->get_linkage() ) );
     1118                } // if
     1119        }
     1120
     1121        template< typename AggDecl >
     1122        void ReplaceTypedef::handleAggregate( AggDecl * aggr ) {
     1123                SemanticErrorException errors;
     1124
     1125                ValueGuard< std::list<Declaration * > > oldBeforeDecls( declsToAddBefore );
     1126                ValueGuard< std::list<Declaration * > > oldAfterDecls ( declsToAddAfter  );
     1127                declsToAddBefore.clear();
     1128                declsToAddAfter.clear();
     1129
     1130                GuardScope( typedefNames );
     1131                GuardScope( typedeclNames );
     1132                mutateAll( aggr->parameters, * visitor );
     1133
     1134                // unroll mutateAll for aggr->members so that implicit typedefs for nested types are added to the aggregate body.
     1135                for ( std::list< Declaration * >::iterator i = aggr->members.begin(); i != aggr->members.end(); ++i ) {
     1136                        if ( !declsToAddAfter.empty() ) { aggr->members.splice( i, declsToAddAfter ); }
     1137
     1138                        try {
     1139                                * i = maybeMutate( * i, * visitor );
     1140                        } catch ( SemanticErrorException &e ) {
     1141                                errors.append( e );
     1142                        }
     1143
     1144                        if ( !declsToAddBefore.empty() ) { aggr->members.splice( i, declsToAddBefore ); }
     1145                }
     1146
     1147                if ( !declsToAddAfter.empty() ) { aggr->members.splice( aggr->members.end(), declsToAddAfter ); }
     1148                if ( !errors.isEmpty() ) { throw errors; }
     1149        }
     1150
     1151        void ReplaceTypedef::premutate( StructDecl * structDecl ) {
     1152                visit_children = false;
    8661153                addImplicitTypedef( structDecl );
    867         }
    868 
    869 
    870         Declaration *EliminateTypedef::postmutate( StructDecl * structDecl ) {
    871                 return handleAggregate( structDecl );
    872         }
    873 
    874         void EliminateTypedef::premutate( UnionDecl * unionDecl ) {
     1154                handleAggregate( structDecl );
     1155        }
     1156
     1157        void ReplaceTypedef::premutate( UnionDecl * unionDecl ) {
     1158                visit_children = false;
    8751159                addImplicitTypedef( unionDecl );
    876         }
    877 
    878         Declaration *EliminateTypedef::postmutate( UnionDecl * unionDecl ) {
    879                 return handleAggregate( unionDecl );
    880         }
    881 
    882         void EliminateTypedef::premutate( EnumDecl * enumDecl ) {
     1160                handleAggregate( unionDecl );
     1161        }
     1162
     1163        void ReplaceTypedef::premutate( EnumDecl * enumDecl ) {
    8831164                addImplicitTypedef( enumDecl );
    8841165        }
    8851166
    886         Declaration *EliminateTypedef::postmutate( EnumDecl * enumDecl ) {
    887                 return handleAggregate( enumDecl );
    888         }
    889 
    890         Declaration *EliminateTypedef::postmutate( TraitDecl * traitDecl ) {
    891                 return handleAggregate( traitDecl );
    892         }
    893 
    894         void EliminateTypedef::premutate( FunctionType * ) {
     1167        void ReplaceTypedef::premutate( FunctionType * ) {
    8951168                GuardValue( inFunctionType );
    8961169                inFunctionType = true;
     1170        }
     1171
     1172        void ReplaceTypedef::premutate( TraitDecl * ) {
     1173                GuardScope( typedefNames );
     1174                GuardScope( typedeclNames);
    8971175        }
    8981176
     
    9391217                        for ( size_t i = 0; paramIter != params->end(); ++paramIter, ++i ) {
    9401218                                if ( i < args.size() ) {
    941                                         TypeExpr * expr = strict_dynamic_cast< TypeExpr * >( *std::next( args.begin(), i ) );
    942                                         sub.add( (*paramIter)->get_name(), expr->get_type()->clone() );
     1219                                        TypeExpr * expr = strict_dynamic_cast< TypeExpr * >( * std::next( args.begin(), i ) );
     1220                                        sub.add( (* paramIter)->get_name(), expr->get_type()->clone() );
    9431221                                } else if ( i == args.size() ) {
    944                                         Type * defaultType = (*paramIter)->get_init();
     1222                                        Type * defaultType = (* paramIter)->get_init();
    9451223                                        if ( defaultType ) {
    9461224                                                args.push_back( new TypeExpr( defaultType->clone() ) );
    947                                                 sub.add( (*paramIter)->get_name(), defaultType->clone() );
     1225                                                sub.add( (* paramIter)->get_name(), defaultType->clone() );
    9481226                                        }
    9491227                                }
     
    9641242        }
    9651243
    966         void CompoundLiteral::premutate( ObjectDecl *objectDecl ) {
     1244        void CompoundLiteral::premutate( ObjectDecl * objectDecl ) {
    9671245                storageClasses = objectDecl->get_storageClasses();
    9681246        }
    9691247
    970         Expression *CompoundLiteral::postmutate( CompoundLiteralExpr *compLitExpr ) {
     1248        Expression * CompoundLiteral::postmutate( CompoundLiteralExpr * compLitExpr ) {
    9711249                // transform [storage_class] ... (struct S){ 3, ... };
    9721250                // into [storage_class] struct S temp =  { 3, ... };
    9731251                static UniqueName indexName( "_compLit" );
    9741252
    975                 ObjectDecl *tempvar = new ObjectDecl( indexName.newName(), storageClasses, LinkageSpec::C, nullptr, compLitExpr->get_result(), compLitExpr->get_initializer() );
     1253                ObjectDecl * tempvar = new ObjectDecl( indexName.newName(), storageClasses, LinkageSpec::C, nullptr, compLitExpr->get_result(), compLitExpr->get_initializer() );
    9761254                compLitExpr->set_result( nullptr );
    9771255                compLitExpr->set_initializer( nullptr );
     
    10111289                        TupleType * tupleType = strict_dynamic_cast< TupleType * >( ResolvExpr::extractResultType( ftype ) );
    10121290                        // ensure return value is not destructed by explicitly creating an empty ListInit node wherein maybeConstruct is false.
    1013                         ObjectDecl * newRet = new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, 0, tupleType, new ListInit( std::list<Initializer*>(), noDesignators, false ) );
     1291                        ObjectDecl * newRet = new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, 0, tupleType, new ListInit( std::list<Initializer *>(), noDesignators, false ) );
    10141292                        deleteAll( retVals );
    10151293                        retVals.clear();
     
    10181296        }
    10191297
     1298        void FixObjectType::fix( std::list< Declaration * > & translationUnit ) {
     1299                PassVisitor<FixObjectType> fixer;
     1300                acceptAll( translationUnit, fixer );
     1301        }
     1302
     1303        void FixObjectType::previsit( ObjectDecl * objDecl ) {
     1304                Type * new_type = ResolvExpr::resolveTypeof( objDecl->get_type(), indexer );
     1305                objDecl->set_type( new_type );
     1306        }
     1307
     1308        void FixObjectType::previsit( FunctionDecl * funcDecl ) {
     1309                Type * new_type = ResolvExpr::resolveTypeof( funcDecl->type, indexer );
     1310                funcDecl->set_type( new_type );
     1311        }
     1312
     1313        void FixObjectType::previsit( TypeDecl * typeDecl ) {
     1314                if ( typeDecl->get_base() ) {
     1315                        Type * new_type = ResolvExpr::resolveTypeof( typeDecl->get_base(), indexer );
     1316                        typeDecl->set_base( new_type );
     1317                } // if
     1318        }
     1319
    10201320        void ArrayLength::computeLength( std::list< Declaration * > & translationUnit ) {
    10211321                PassVisitor<ArrayLength> len;
     
    10241324
    10251325        void ArrayLength::previsit( ObjectDecl * objDecl ) {
    1026                 if ( ArrayType * at = dynamic_cast< ArrayType * >( objDecl->get_type() ) ) {
    1027                         if ( at->get_dimension() ) return;
    1028                         if ( ListInit * init = dynamic_cast< ListInit * >( objDecl->get_init() ) ) {
    1029                                 at->set_dimension( new ConstantExpr( Constant::from_ulong( init->get_initializers().size() ) ) );
    1030                         }
     1326                if ( ArrayType * at = dynamic_cast< ArrayType * >( objDecl->type ) ) {
     1327                        if ( at->dimension ) return;
     1328                        if ( ListInit * init = dynamic_cast< ListInit * >( objDecl->init ) ) {
     1329                                at->dimension = new ConstantExpr( Constant::from_ulong( init->initializers.size() ) );
     1330                        }
     1331                }
     1332        }
     1333
     1334        void ArrayLength::previsit( ArrayType * type ) {
     1335                if ( type->dimension ) {
     1336                        // need to resolve array dimensions early so that constructor code can correctly determine
     1337                        // if a type is a VLA (and hence whether its elements need to be constructed)
     1338                        ResolvExpr::findSingleExpression( type->dimension, Validate::SizeType->clone(), indexer );
     1339
     1340                        // must re-evaluate whether a type is a VLA, now that more information is available
     1341                        // (e.g. the dimension may have been an enumerator, which was unknown prior to this step)
     1342                        type->isVarLen = ! InitTweak::isConstExpr( type->dimension );
    10311343                }
    10321344        }
     
    10621374        }
    10631375
    1064         void FindSpecialDeclarations::previsit( FunctionDecl * funcDecl ) {
    1065                 if ( ! dereferenceOperator ) {
    1066                         if ( funcDecl->get_name() == "*?" && funcDecl->get_linkage() == LinkageSpec::Intrinsic ) {
    1067                                 FunctionType * ftype = funcDecl->get_functionType();
    1068                                 if ( ftype->get_parameters().size() == 1 && ftype->get_parameters().front()->get_type()->get_qualifiers() == Type::Qualifiers() ) {
    1069                                         dereferenceOperator = funcDecl;
     1376namespace {
     1377        /// Replaces enum types by int, and function/array types in function parameter and return
     1378        /// lists by appropriate pointers
     1379        struct EnumAndPointerDecay_new {
     1380                const ast::EnumDecl * previsit( const ast::EnumDecl * enumDecl ) {
     1381                        // set the type of each member of the enumeration to be EnumConstant
     1382                        for ( unsigned i = 0; i < enumDecl->members.size(); ++i ) {
     1383                                // build new version of object with EnumConstant
     1384                                ast::ptr< ast::ObjectDecl > obj =
     1385                                        enumDecl->members[i].strict_as< ast::ObjectDecl >();
     1386                                obj.get_and_mutate()->type =
     1387                                        new ast::EnumInstType{ enumDecl->name, ast::CV::Const };
     1388
     1389                                // set into decl
     1390                                ast::EnumDecl * mut = mutate( enumDecl );
     1391                                mut->members[i] = obj.get();
     1392                                enumDecl = mut;
     1393                        }
     1394                        return enumDecl;
     1395                }
     1396
     1397                static const ast::FunctionType * fixFunctionList(
     1398                        const ast::FunctionType * func,
     1399                        std::vector< ast::ptr< ast::DeclWithType > > ast::FunctionType::* field,
     1400                        ast::ArgumentFlag isVarArgs = ast::FixedArgs
     1401                ) {
     1402                        const auto & dwts = func->* field;
     1403                        unsigned nvals = dwts.size();
     1404                        bool hasVoid = false;
     1405                        for ( unsigned i = 0; i < nvals; ++i ) {
     1406                                func = ast::mutate_field_index( func, field, i, fixFunction( dwts[i], hasVoid ) );
     1407                        }
     1408
     1409                        // the only case in which "void" is valid is where it is the only one in the list
     1410                        if ( hasVoid && ( nvals > 1 || isVarArgs ) ) {
     1411                                SemanticError(
     1412                                        dwts.front()->location, func, "invalid type void in function type" );
     1413                        }
     1414
     1415                        // one void is the only thing in the list, remove it
     1416                        if ( hasVoid ) {
     1417                                func = ast::mutate_field(
     1418                                        func, field, std::vector< ast::ptr< ast::DeclWithType > >{} );
     1419                        }
     1420
     1421                        return func;
     1422                }
     1423
     1424                const ast::FunctionType * previsit( const ast::FunctionType * func ) {
     1425                        func = fixFunctionList( func, &ast::FunctionType::params, func->isVarArgs );
     1426                        return fixFunctionList( func, &ast::FunctionType::returns );
     1427                }
     1428        };
     1429
     1430        /// expand assertions from a trait instance, performing appropriate type variable substitutions
     1431        void expandAssertions(
     1432                const ast::TraitInstType * inst, std::vector< ast::ptr< ast::DeclWithType > > & out
     1433        ) {
     1434                assertf( inst->base, "Trait instance not linked to base trait: %s", toCString( inst ) );
     1435
     1436                // build list of trait members, substituting trait decl parameters for instance parameters
     1437                ast::TypeSubstitution sub{
     1438                        inst->base->params.begin(), inst->base->params.end(), inst->params.begin() };
     1439                // deliberately take ast::ptr by-value to ensure this does not mutate inst->base
     1440                for ( ast::ptr< ast::Decl > decl : inst->base->members ) {
     1441                        auto member = decl.strict_as< ast::DeclWithType >();
     1442                        sub.apply( member );
     1443                        out.emplace_back( member );
     1444                }
     1445        }
     1446
     1447        /// Associates forward declarations of aggregates with their definitions
     1448        class LinkReferenceToTypes_new final
     1449        : public ast::WithSymbolTable, public ast::WithGuards, public
     1450          ast::WithVisitorRef<LinkReferenceToTypes_new>, public ast::WithShortCircuiting {
     1451
     1452                // these maps of uses of forward declarations of types need to have the actual type
     1453                // declaration switched in * after * they have been traversed. To enable this in the
     1454                // ast::Pass framework, any node that needs to be so mutated has mutate() called on it
     1455                // before it is placed in the map, properly updating its parents in the usual traversal,
     1456                // then can have the actual mutation applied later
     1457                using ForwardEnumsType = std::unordered_multimap< std::string, ast::EnumInstType * >;
     1458                using ForwardStructsType = std::unordered_multimap< std::string, ast::StructInstType * >;
     1459                using ForwardUnionsType = std::unordered_multimap< std::string, ast::UnionInstType * >;
     1460
     1461                const CodeLocation & location;
     1462                const ast::SymbolTable * localSymtab;
     1463
     1464                ForwardEnumsType forwardEnums;
     1465                ForwardStructsType forwardStructs;
     1466                ForwardUnionsType forwardUnions;
     1467
     1468                /// true if currently in a generic type body, so that type parameter instances can be
     1469                /// renamed appropriately
     1470                bool inGeneric = false;
     1471
     1472        public:
     1473                /// contstruct using running symbol table
     1474                LinkReferenceToTypes_new( const CodeLocation & loc )
     1475                : location( loc ), localSymtab( &symtab ) {}
     1476
     1477                /// construct using provided symbol table
     1478                LinkReferenceToTypes_new( const CodeLocation & loc, const ast::SymbolTable & syms )
     1479                : location( loc ), localSymtab( &syms ) {}
     1480
     1481                const ast::Type * postvisit( const ast::TypeInstType * typeInst ) {
     1482                        // ensure generic parameter instances are renamed like the base type
     1483                        if ( inGeneric && typeInst->base ) {
     1484                                typeInst = ast::mutate_field(
     1485                                        typeInst, &ast::TypeInstType::name, typeInst->base->name );
     1486                        }
     1487
     1488                        if (
     1489                                auto typeDecl = dynamic_cast< const ast::TypeDecl * >(
     1490                                        localSymtab->lookupType( typeInst->name ) )
     1491                        ) {
     1492                                typeInst = ast::mutate_field( typeInst, &ast::TypeInstType::kind, typeDecl->kind );
     1493                        }
     1494
     1495                        return typeInst;
     1496                }
     1497
     1498                const ast::Type * postvisit( const ast::EnumInstType * inst ) {
     1499                        const ast::EnumDecl * decl = localSymtab->lookupEnum( inst->name );
     1500                        // not a semantic error if the enum is not found, just an implicit forward declaration
     1501                        if ( decl ) {
     1502                                inst = ast::mutate_field( inst, &ast::EnumInstType::base, decl );
     1503                        }
     1504                        if ( ! decl || ! decl->body ) {
     1505                                // forward declaration
     1506                                auto mut = mutate( inst );
     1507                                forwardEnums.emplace( inst->name, mut );
     1508                                inst = mut;
     1509                        }
     1510                        return inst;
     1511                }
     1512
     1513                void checkGenericParameters( const ast::ReferenceToType * inst ) {
     1514                        for ( const ast::Expr * param : inst->params ) {
     1515                                if ( ! dynamic_cast< const ast::TypeExpr * >( param ) ) {
     1516                                        SemanticError(
     1517                                                location, inst, "Expression parameters for generic types are currently "
     1518                                                "unsupported: " );
    10701519                                }
    10711520                        }
    10721521                }
    1073         }
     1522
     1523                const ast::StructInstType * postvisit( const ast::StructInstType * inst ) {
     1524                        const ast::StructDecl * decl = localSymtab->lookupStruct( inst->name );
     1525                        // not a semantic error if the struct is not found, just an implicit forward declaration
     1526                        if ( decl ) {
     1527                                inst = ast::mutate_field( inst, &ast::StructInstType::base, decl );
     1528                        }
     1529                        if ( ! decl || ! decl->body ) {
     1530                                // forward declaration
     1531                                auto mut = mutate( inst );
     1532                                forwardStructs.emplace( inst->name, mut );
     1533                                inst = mut;
     1534                        }
     1535                        checkGenericParameters( inst );
     1536                        return inst;
     1537                }
     1538
     1539                const ast::UnionInstType * postvisit( const ast::UnionInstType * inst ) {
     1540                        const ast::UnionDecl * decl = localSymtab->lookupUnion( inst->name );
     1541                        // not a semantic error if the struct is not found, just an implicit forward declaration
     1542                        if ( decl ) {
     1543                                inst = ast::mutate_field( inst, &ast::UnionInstType::base, decl );
     1544                        }
     1545                        if ( ! decl || ! decl->body ) {
     1546                                // forward declaration
     1547                                auto mut = mutate( inst );
     1548                                forwardUnions.emplace( inst->name, mut );
     1549                                inst = mut;
     1550                        }
     1551                        checkGenericParameters( inst );
     1552                        return inst;
     1553                }
     1554
     1555                const ast::Type * postvisit( const ast::TraitInstType * traitInst ) {
     1556                        // handle other traits
     1557                        const ast::TraitDecl * traitDecl = localSymtab->lookupTrait( traitInst->name );
     1558                        if ( ! traitDecl )       {
     1559                                SemanticError( location, "use of undeclared trait " + traitInst->name );
     1560                        }
     1561                        if ( traitDecl->params.size() != traitInst->params.size() ) {
     1562                                SemanticError( location, traitInst, "incorrect number of trait parameters: " );
     1563                        }
     1564                        traitInst = ast::mutate_field( traitInst, &ast::TraitInstType::base, traitDecl );
     1565
     1566                        // need to carry over the "sized" status of each decl in the instance
     1567                        for ( unsigned i = 0; i < traitDecl->params.size(); ++i ) {
     1568                                auto expr = traitInst->params[i].as< ast::TypeExpr >();
     1569                                if ( ! expr ) {
     1570                                        SemanticError(
     1571                                                traitInst->params[i].get(), "Expression parameters for trait instances "
     1572                                                "are currently unsupported: " );
     1573                                }
     1574
     1575                                if ( auto inst = expr->type.as< ast::TypeInstType >() ) {
     1576                                        if ( traitDecl->params[i]->sized && ! inst->base->sized ) {
     1577                                                // traitInst = ast::mutate_field_index(
     1578                                                //      traitInst, &ast::TraitInstType::params, i,
     1579                                                //      ...
     1580                                                // );
     1581                                                ast::TraitInstType * mut = ast::mutate( traitInst );
     1582                                                ast::chain_mutate( mut->params[i] )
     1583                                                        ( &ast::TypeExpr::type )
     1584                                                                ( &ast::TypeInstType::base )->sized = true;
     1585                                                traitInst = mut;
     1586                                        }
     1587                                }
     1588                        }
     1589
     1590                        return traitInst;
     1591                }
     1592
     1593                void previsit( const ast::QualifiedType * ) { visit_children = false; }
     1594
     1595                const ast::Type * postvisit( const ast::QualifiedType * qualType ) {
     1596                        // linking only makes sense for the "oldest ancestor" of the qualified type
     1597                        return ast::mutate_field(
     1598                                qualType, &ast::QualifiedType::parent, qualType->parent->accept( * visitor ) );
     1599                }
     1600
     1601                const ast::Decl * postvisit( const ast::EnumDecl * enumDecl ) {
     1602                        // visit enum members first so that the types of self-referencing members are updated
     1603                        // properly
     1604                        if ( ! enumDecl->body ) return enumDecl;
     1605
     1606                        // update forward declarations to point here
     1607                        auto fwds = forwardEnums.equal_range( enumDecl->name );
     1608                        if ( fwds.first != fwds.second ) {
     1609                                auto inst = fwds.first;
     1610                                do {
     1611                                        // forward decl is stored * mutably * in map, can thus be updated
     1612                                        inst->second->base = enumDecl;
     1613                                } while ( ++inst != fwds.second );
     1614                                forwardEnums.erase( fwds.first, fwds.second );
     1615                        }
     1616
     1617                        // ensure that enumerator initializers are properly set
     1618                        for ( unsigned i = 0; i < enumDecl->members.size(); ++i ) {
     1619                                auto field = enumDecl->members[i].strict_as< ast::ObjectDecl >();
     1620                                if ( field->init ) {
     1621                                        // need to resolve enumerator initializers early so that other passes that
     1622                                        // determine if an expression is constexpr have appropriate information
     1623                                        auto init = field->init.strict_as< ast::SingleInit >();
     1624
     1625                                        enumDecl = ast::mutate_field_index(
     1626                                                enumDecl, &ast::EnumDecl::members, i,
     1627                                                ast::mutate_field( field, &ast::ObjectDecl::init,
     1628                                                        ast::mutate_field( init, &ast::SingleInit::value,
     1629                                                                ResolvExpr::findSingleExpression(
     1630                                                                        init->value, new ast::BasicType{ ast::BasicType::SignedInt },
     1631                                                                        symtab ) ) ) );
     1632                                }
     1633                        }
     1634
     1635                        return enumDecl;
     1636                }
     1637
     1638                /// rename generic type parameters uniquely so that they do not conflict with user defined
     1639                /// function forall parameters, e.g. the T in Box and the T in f, below
     1640                ///   forall(otype T)
     1641                ///   struct Box {
     1642                ///     T x;
     1643                ///   };
     1644                ///   forall(otype T)
     1645                ///   void f(Box(T) b) {
     1646                ///     ...
     1647                ///   }
     1648                template< typename AggrDecl >
     1649                const AggrDecl * renameGenericParams( const AggrDecl * aggr ) {
     1650                        GuardValue( inGeneric );
     1651                        inGeneric = ! aggr->params.empty();
     1652
     1653                        for ( unsigned i = 0; i < aggr->params.size(); ++i ) {
     1654                                const ast::TypeDecl * td = aggr->params[i];
     1655
     1656                                aggr = ast::mutate_field_index(
     1657                                        aggr, &AggrDecl::params, i,
     1658                                        ast::mutate_field( td, &ast::TypeDecl::name, "__" + td->name + "_generic_" ) );
     1659                        }
     1660                        return aggr;
     1661                }
     1662
     1663                const ast::StructDecl * previsit( const ast::StructDecl * structDecl ) {
     1664                        return renameGenericParams( structDecl );
     1665                }
     1666
     1667                void postvisit( const ast::StructDecl * structDecl ) {
     1668                        // visit struct members first so that the types of self-referencing members are
     1669                        // updated properly
     1670                        if ( ! structDecl->body ) return;
     1671
     1672                        // update forward declarations to point here
     1673                        auto fwds = forwardStructs.equal_range( structDecl->name );
     1674                        if ( fwds.first != fwds.second ) {
     1675                                auto inst = fwds.first;
     1676                                do {
     1677                                        // forward decl is stored * mutably * in map, can thus be updated
     1678                                        inst->second->base = structDecl;
     1679                                } while ( ++inst != fwds.second );
     1680                                forwardStructs.erase( fwds.first, fwds.second );
     1681                        }
     1682                }
     1683
     1684                const ast::UnionDecl * previsit( const ast::UnionDecl * unionDecl ) {
     1685                        return renameGenericParams( unionDecl );
     1686                }
     1687
     1688                void postvisit( const ast::UnionDecl * unionDecl ) {
     1689                        // visit union members first so that the types of self-referencing members are updated
     1690                        // properly
     1691                        if ( ! unionDecl->body ) return;
     1692
     1693                        // update forward declarations to point here
     1694                        auto fwds = forwardUnions.equal_range( unionDecl->name );
     1695                        if ( fwds.first != fwds.second ) {
     1696                                auto inst = fwds.first;
     1697                                do {
     1698                                        // forward decl is stored * mutably * in map, can thus be updated
     1699                                        inst->second->base = unionDecl;
     1700                                } while ( ++inst != fwds.second );
     1701                                forwardUnions.erase( fwds.first, fwds.second );
     1702                        }
     1703                }
     1704
     1705                const ast::Decl * postvisit( const ast::TraitDecl * traitDecl ) {
     1706                        // set the "sized" status for the special "sized" trait
     1707                        if ( traitDecl->name == "sized" ) {
     1708                                assertf( traitDecl->params.size() == 1, "Built-in trait 'sized' has incorrect "
     1709                                        "number of parameters: %zd", traitDecl->params.size() );
     1710
     1711                                traitDecl = ast::mutate_field_index(
     1712                                        traitDecl, &ast::TraitDecl::params, 0,
     1713                                        ast::mutate_field(
     1714                                                traitDecl->params.front().get(), &ast::TypeDecl::sized, true ) );
     1715                        }
     1716
     1717                        // move assertions from type parameters into the body of the trait
     1718                        std::vector< ast::ptr< ast::DeclWithType > > added;
     1719                        for ( const ast::TypeDecl * td : traitDecl->params ) {
     1720                                for ( const ast::DeclWithType * assn : td->assertions ) {
     1721                                        auto inst = dynamic_cast< const ast::TraitInstType * >( assn->get_type() );
     1722                                        if ( inst ) {
     1723                                                expandAssertions( inst, added );
     1724                                        } else {
     1725                                                added.emplace_back( assn );
     1726                                        }
     1727                                }
     1728                        }
     1729                        if ( ! added.empty() ) {
     1730                                auto mut = mutate( traitDecl );
     1731                                for ( const ast::DeclWithType * decl : added ) {
     1732                                        mut->members.emplace_back( decl );
     1733                                }
     1734                                traitDecl = mut;
     1735                        }
     1736
     1737                        return traitDecl;
     1738                }
     1739        };
     1740
     1741        /// Replaces array and function types in forall lists by appropriate pointer type and assigns
     1742        /// each object and function declaration a unique ID
     1743        class ForallPointerDecay_new {
     1744                const CodeLocation & location;
     1745        public:
     1746                ForallPointerDecay_new( const CodeLocation & loc ) : location( loc ) {}
     1747
     1748                const ast::ObjectDecl * previsit( const ast::ObjectDecl * obj ) {
     1749                        // ensure that operator names only apply to functions or function pointers
     1750                        if (
     1751                                CodeGen::isOperator( obj->name )
     1752                                && ! dynamic_cast< const ast::FunctionType * >( obj->type->stripDeclarator() )
     1753                        ) {
     1754                                SemanticError( obj->location, toCString( "operator ", obj->name.c_str(), " is not "
     1755                                        "a function or function pointer." )  );
     1756                        }
     1757
     1758                        // ensure object has unique ID
     1759                        if ( obj->uniqueId ) return obj;
     1760                        auto mut = mutate( obj );
     1761                        mut->fixUniqueId();
     1762                        return mut;
     1763                }
     1764
     1765                const ast::FunctionDecl * previsit( const ast::FunctionDecl * func ) {
     1766                        // ensure function has unique ID
     1767                        if ( func->uniqueId ) return func;
     1768                        auto mut = mutate( func );
     1769                        mut->fixUniqueId();
     1770                        return mut;
     1771                }
     1772
     1773                /// Fix up assertions -- flattens assertion lists, removing all trait instances
     1774                template< typename node_t, typename parent_t >
     1775                static const node_t * forallFixer(
     1776                        const CodeLocation & loc, const node_t * node,
     1777                        ast::ParameterizedType::ForallList parent_t::* forallField
     1778                ) {
     1779                        for ( unsigned i = 0; i < (node->* forallField).size(); ++i ) {
     1780                                const ast::TypeDecl * type = (node->* forallField)[i];
     1781                                if ( type->assertions.empty() ) continue;
     1782
     1783                                std::vector< ast::ptr< ast::DeclWithType > > asserts;
     1784                                asserts.reserve( type->assertions.size() );
     1785
     1786                                // expand trait instances into their members
     1787                                for ( const ast::DeclWithType * assn : type->assertions ) {
     1788                                        auto traitInst =
     1789                                                dynamic_cast< const ast::TraitInstType * >( assn->get_type() );
     1790                                        if ( traitInst ) {
     1791                                                // expand trait instance to all its members
     1792                                                expandAssertions( traitInst, asserts );
     1793                                        } else {
     1794                                                // pass other assertions through
     1795                                                asserts.emplace_back( assn );
     1796                                        }
     1797                                }
     1798
     1799                                // apply FixFunction to every assertion to check for invalid void type
     1800                                for ( ast::ptr< ast::DeclWithType > & assn : asserts ) {
     1801                                        bool isVoid = false;
     1802                                        assn = fixFunction( assn, isVoid );
     1803                                        if ( isVoid ) {
     1804                                                SemanticError( loc, node, "invalid type void in assertion of function " );
     1805                                        }
     1806                                }
     1807
     1808                                // place mutated assertion list in node
     1809                                auto mut = mutate( type );
     1810                                mut->assertions = move( asserts );
     1811                                node = ast::mutate_field_index( node, forallField, i, mut );
     1812                        }
     1813                        return node;
     1814                }
     1815
     1816                const ast::FunctionType * previsit( const ast::FunctionType * ftype ) {
     1817                        return forallFixer( location, ftype, &ast::FunctionType::forall );
     1818                }
     1819
     1820                const ast::StructDecl * previsit( const ast::StructDecl * aggrDecl ) {
     1821                        return forallFixer( aggrDecl->location, aggrDecl, &ast::StructDecl::params );
     1822                }
     1823
     1824                const ast::UnionDecl * previsit( const ast::UnionDecl * aggrDecl ) {
     1825                        return forallFixer( aggrDecl->location, aggrDecl, &ast::UnionDecl::params );
     1826                }
     1827        };
     1828} // anonymous namespace
     1829
     1830const ast::Type * validateType(
     1831                const CodeLocation & loc, const ast::Type * type, const ast::SymbolTable & symtab ) {
     1832        ast::Pass< EnumAndPointerDecay_new > epc;
     1833        ast::Pass< LinkReferenceToTypes_new > lrt{ loc, symtab };
     1834        ast::Pass< ForallPointerDecay_new > fpd{ loc };
     1835
     1836        return type->accept( epc )->accept( lrt )->accept( fpd );
     1837}
     1838
    10741839} // namespace SymTab
    10751840
  • src/SymTab/Validate.h

    r7951100 rb067d9b  
    1919#include <list>  // for list
    2020
    21 class Declaration;
    22 class Type;
     21struct CodeLocation;
     22class  Declaration;
     23class  Type;
     24
     25namespace ast {
     26        class Type;
     27        class SymbolTable;
     28}
    2329
    2430namespace SymTab {
     
    2834        void validate( std::list< Declaration * > &translationUnit, bool doDebug = false );
    2935        void validateType( Type *type, const Indexer *indexer );
     36
     37        const ast::Type * validateType(
     38                const CodeLocation & loc, const ast::Type * type, const ast::SymbolTable & symtab );
    3039} // namespace SymTab
    3140
  • src/SymTab/module.mk

    r7951100 rb067d9b  
    1515###############################################################################
    1616
    17 SRC += SymTab/Indexer.cc \
    18        SymTab/Mangler.cc \
    19        SymTab/Validate.cc \
    20        SymTab/FixFunction.cc \
    21        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

    r7951100 rb067d9b  
    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
     
    4242AddressExpr::AddressExpr( Expression *arg ) : Expression(), arg( arg ) {
    4343        if ( arg->result ) {
    44                 if ( arg->result->get_lvalue() ) {
     44                if ( arg->get_lvalue() ) {
    4545                        // lvalue, retains all layers of reference and gains a pointer inside the references
    4646                        set_result( addrType( arg->result ) );
    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                }
    52                 // result of & is never an lvalue
    53                 get_result()->set_lvalue( false );
    5455        }
    5556}
  • src/SynTree/AggregateDecl.cc

    r7951100 rb067d9b  
    8686std::string TraitDecl::typeString() const { return "trait"; }
    8787
    88 namespace {
    89         long long int getConstValue( Expression * expr ) {
    90                 if ( CastExpr * castExpr = dynamic_cast< CastExpr * > ( expr ) ) {
    91                         return getConstValue( castExpr->arg );
    92                 } else if ( ConstantExpr * constExpr = dynamic_cast< ConstantExpr * >( expr ) ) {
    93                         return constExpr->intValue();
    94                 // can be -1, +1, etc.
    95                 // } else if ( UntypedExpr * untypedExpr = dynamic_cast< UntypedExpr * >( expr ) ) {
    96                 //      if ( untypedExpr-> )
    97                 } else {
    98                         assertf( false, "Unhandled expression type in getConstValue for enumerators: %s", toString( expr ).c_str() );
    99                 }
    100         }
    101 }
    102 
    10388bool EnumDecl::valueOf( Declaration * enumerator, long long int & value ) {
    10489        if ( enumValues.empty() ) {
     
    10893                        if ( field->init ) {
    10994                                SingleInit * init = strict_dynamic_cast< SingleInit * >( field->init );
    110                                 currentValue = getConstValue( init->value );
     95                                auto result = eval( init->value );
     96                                if ( ! result.second ) SemanticError( init->location, toString( "Non-constexpr in initialization of enumerator: ", field ) );
     97                                currentValue = result.first;
    11198                        }
    11299                        assertf( enumValues.count( field->name ) == 0, "Enum %s has multiple members with the name %s", name.c_str(), field->name.c_str() );
  • src/SynTree/ApplicationExpr.cc

    r7951100 rb067d9b  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Rob Schluntz
    12 // Last Modified On : Tue Apr 26 12:41:06 2016
    13 // Update Count     : 4
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Mon Aug 12 14:28:00 2019
     13// Update Count     : 5
    1414//
    1515
     
    2525#include "Declaration.h"         // for Declaration
    2626#include "Expression.h"          // for ParamEntry, ApplicationExpr, Expression
     27#include "InitTweak/InitTweak.h" // for getFunction
    2728#include "ResolvExpr/typeops.h"  // for extractResultType
    2829#include "Type.h"                // for Type, PointerType, FunctionType
    2930
     31ParamEntry::ParamEntry( UniqueId decl, Declaration * declptr, Type * actualType, Type * formalType, Expression* expr )
     32                : decl( decl ), declptr( declptr ), actualType( actualType ), formalType( formalType ), expr( expr ) {
     33        }
     34
    3035ParamEntry::ParamEntry( const ParamEntry &other ) :
    31                 decl( other.decl ), actualType( maybeClone( other.actualType ) ), formalType( maybeClone( other.formalType ) ), expr( maybeClone( other.expr ) ), inferParams( new InferredParams( *other.inferParams ) ) {
    32 }
    33 
    34 ParamEntry &ParamEntry::operator=( const ParamEntry &other ) {
    35         if ( &other == this ) return *this;
    36         decl = other.decl;
    37         // xxx - this looks like a memory leak
    38         actualType = maybeClone( other.actualType );
    39         formalType = maybeClone( other.formalType );
    40         expr = maybeClone( other.expr );
    41         *inferParams = *other.inferParams;
    42         return *this;
     36                decl( other.decl ), declptr( maybeClone( other.declptr ) ), actualType( maybeClone( other.actualType ) ), formalType( maybeClone( other.formalType ) ), expr( maybeClone( other.expr ) ) {
    4337}
    4438
    4539ParamEntry::~ParamEntry() {
     40        delete declptr;
    4641        delete actualType;
    4742        delete formalType;
     
    5045
    5146ParamEntry::ParamEntry( ParamEntry && other ) :
    52                 decl( other.decl ), actualType( other.actualType ), formalType( other.formalType ), expr( other.expr ), inferParams( std::move( other.inferParams ) ) {
    53         other.actualType = nullptr;
    54         other.formalType = nullptr;
    55         other.expr = nullptr;
     47                decl( other.decl ), declptr( other.declptr ), actualType( other.actualType ), formalType( other.formalType ), expr( other.expr ) {
     48        new (&other) ParamEntry();
    5649}
    5750
    5851ParamEntry & ParamEntry::operator=( ParamEntry && other ) {
    5952        if ( &other == this ) return *this;
    60         delete actualType;
    61         delete formalType;
    62         delete expr;
    63         decl = other.decl;
    64         actualType = other.actualType;
    65         formalType = other.formalType;
    66         expr = other.expr;
    67         other.actualType = nullptr;
    68         other.formalType = nullptr;
    69         other.expr = nullptr;
    70         inferParams = std::move( other.inferParams );
     53        this->~ParamEntry();
     54        new (this) ParamEntry(other.decl, other.declptr, other.actualType, other.formalType, other.expr);
     55        new (&other) ParamEntry();
     56
    7157        return *this;
    7258}
     
    9177}
    9278
     79bool ApplicationExpr::get_lvalue() const {
     80        // from src/GenPoly/Lvalue.cc: isIntrinsicReference
     81        static std::set<std::string> lvalueFunctions = { "*?", "?[?]" };
     82        if ( const DeclarationWithType * func = InitTweak::getFunction( this ) ) {
     83                return func->linkage == LinkageSpec::Intrinsic && lvalueFunctions.count(func->name);
     84        }
     85        return false;
     86}
     87
    9388void ApplicationExpr::print( std::ostream &os, Indenter indent ) const {
    9489        os << "Application of" << std::endl << indent+1;
  • src/SynTree/ArrayType.cc

    r7951100 rb067d9b  
    2626ArrayType::ArrayType( const Type::Qualifiers &tq, Type *base, Expression *dimension, bool isVarLen, bool isStatic, const std::list< Attribute * > & attributes )
    2727        : Type( tq, attributes ), base( base ), dimension( dimension ), isVarLen( isVarLen ), isStatic( isStatic ) {
    28         base->set_lvalue( false );
    2928}
    3029
  • src/SynTree/Attribute.cc

    r7951100 rb067d9b  
    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/Attribute.h

    r7951100 rb067d9b  
    5050        Attribute * clone() const override { return new Attribute( *this ); }
    5151        virtual void accept( Visitor & v ) override { v.visit( this ); }
     52        virtual void accept( Visitor & v ) const override { v.visit( this ); }
    5253        virtual Attribute * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    5354        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
  • src/SynTree/BaseSyntaxNode.h

    r7951100 rb067d9b  
    99// Author           : Thierry Delisle
    1010// Created On       : Tue Feb 14 07:44:20 2017
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Thr Aug 17 13:44:00
    13 // Update Count     : 1
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Wed Jul 10 16:13:49 2019
     13// Update Count     : 4
    1414//
    1515
     
    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; }
     33        BaseSyntaxNode & operator=( const BaseSyntaxNode & ) = default;
    2634
    2735        virtual ~BaseSyntaxNode() {}
     
    2937        virtual BaseSyntaxNode * clone() const = 0;
    3038        virtual void accept( Visitor & v ) = 0;
     39        virtual void accept( Visitor & v ) const = 0;
    3140        virtual BaseSyntaxNode * acceptMutator( Mutator & m ) = 0;
    32   /// Notes:
    33   /// * each node is responsible for indenting its children.
    34   /// * Expressions should not finish with a newline, since the expression's parent has better information.
     41        /// Notes:
     42        /// * each node is responsible for indenting its children.
     43        /// * Expressions should not finish with a newline, since the expression's parent has better information.
    3544        virtual void print( std::ostream & os, Indenter indent = {} ) const = 0;
    36   void print( std::ostream & os, unsigned int indent ) {
    37     print( os, Indenter{ Indenter::tabsize, indent });
    38   }
    3945};
    4046
  • src/SynTree/BasicType.cc

    r7951100 rb067d9b  
    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 : Sun Aug  4 21:07:44 2019
     13// Update Count     : 13
    1414//
    1515
     
    3030
    3131bool BasicType::isInteger() const {
    32         switch ( kind ) {
    33           case Bool:
    34           case Char:
    35           case SignedChar:
    36           case UnsignedChar:
    37           case ShortSignedInt:
    38           case ShortUnsignedInt:
    39           case SignedInt:
    40           case UnsignedInt:
    41           case LongSignedInt:
    42           case LongUnsignedInt:
    43           case LongLongSignedInt:
    44           case LongLongUnsignedInt:
    45           case SignedInt128:
    46           case UnsignedInt128:
    47                 return true;
    48           case Float:
    49           case Double:
    50           case LongDouble:
    51           case FloatComplex:
    52           case DoubleComplex:
    53           case LongDoubleComplex:
    54           case FloatImaginary:
    55           case DoubleImaginary:
    56           case LongDoubleImaginary:
    57           case Float80:
    58           case Float128:
    59                 return false;
    60           case NUMBER_OF_BASIC_TYPES:
    61                 assert( false );
    62         } // switch
    63         assert( false );
    64         return false;
     32        return kind <= UnsignedInt128;
    6533}
    6634
  • src/SynTree/CommaExpr.cc

    r7951100 rb067d9b  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Rob Schluntz
    12 // Last Modified On : Mon May 02 15:19:44 2016
    13 // Update Count     : 1
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Mon Arg 12 16:11:00 2016
     13// Update Count     : 2
    1414//
    1515
     
    2323CommaExpr::CommaExpr( Expression *arg1, Expression *arg2 )
    2424                : Expression(), arg1( arg1 ), arg2( arg2 ) {
    25         // xxx - result of a comma expression is never an lvalue, so should set lvalue
    26         // to false on all result types. Actually doing this causes some strange things
    27         // to happen in later passes (particularly, Specialize, Lvalue, and Box). This needs to be looked into.
    2825        set_result( maybeClone( arg2->get_result() ) );
    29         // get_type->set_isLvalue( false );
    3026}
    3127
     
    3733        delete arg1;
    3834        delete arg2;
     35}
     36
     37bool CommaExpr::get_lvalue() const {
     38        // This is wrong by C, but the current implementation uses it.
     39        // (ex: Specialize, Lvalue and Box)
     40        return arg2->get_lvalue();
    3941}
    4042
  • src/SynTree/Constant.cc

    r7951100 rb067d9b  
    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 Jul 14 14:50:00 2017
    13 // Update Count     : 29
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Wed Feb 13 18:11:22 2019
     13// Update Count     : 32
    1414//
    1515
     
    1919
    2020#include "Constant.h"
     21#include "Expression.h" // for ConstantExpr
    2122#include "Type.h"    // for BasicType, Type, Type::Qualifiers, PointerType
    2223
    23 Constant::Constant( Type * type, std::string rep, unsigned long long val ) : type( type ), rep( rep ), val( val ) {}
    24 Constant::Constant( Type * type, std::string rep, double val ) : type( type ), rep( rep ), val( val ) {}
     24Constant::Constant( Type * type, std::string rep, std::optional<unsigned long long> ival ) : type( type ), rep( rep ), ival( ival ) {}
    2525
    26 Constant::Constant( const Constant &other ) : rep( other.rep ), val( other.val ) {
     26Constant::Constant( const Constant &other ) : BaseSyntaxNode( other ), rep( other.rep ), ival( other.ival ) {
    2727        type = other.type->clone();
    2828}
     
    3434}
    3535
    36 Constant Constant::from_char( char c ) {
    37         return Constant( new BasicType( Type::Qualifiers(), BasicType::Char ), std::to_string( c ), (unsigned long long int)c );
    38 }
    39 
    4036Constant Constant::from_int( int i ) {
    4137        return Constant( new BasicType( Type::Qualifiers(), BasicType::SignedInt ), std::to_string( i ), (unsigned long long int)i );
     
    4440Constant Constant::from_ulong( unsigned long i ) {
    4541        return Constant( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), std::to_string( i ), (unsigned long long int)i );
    46 }
    47 
    48 Constant Constant::from_double( double d ) {
    49         return Constant( new BasicType( Type::Qualifiers(), BasicType::Double ), std::to_string( d ), d );
    5042}
    5143
     
    6355unsigned long long Constant::get_ival() const {
    6456        assertf( strict_dynamic_cast<BasicType*>(type)->isInteger(), "Attempt to retrieve ival from non-integer constant." );
    65         return val.ival;
    66 }
    67 
    68 double Constant::get_dval() const {
    69         assertf( ! strict_dynamic_cast<BasicType*>(type)->isInteger(), "Attempt to retrieve dval from integer constant." );
    70         return val.dval;
     57        return ival.value();
    7158}
    7259
    7360void Constant::print( std::ostream &os, Indenter ) const {
    74         os << "(" << rep << " " << val.ival;
     61        os << "(" << rep << " " << (ival ? toString(ival.value()) : "") ;
    7562        if ( type ) {
    7663                os << ": ";
  • src/SynTree/Constant.h

    r7951100 rb067d9b  
    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:54:46 2017
    13 // Update Count     : 17
     12// Last Modified On : Wed Jul 10 15:57:38 2019
     13// Update Count     : 19
    1414//
    1515
     
    1818#include <iosfwd>     // for ostream
    1919#include <string>     // for string
     20#include <optional>   // for optional
    2021
    2122#include "BaseSyntaxNode.h"
     
    2728class Constant : public BaseSyntaxNode {
    2829  public:
    29         Constant( Type * type, std::string rep, unsigned long long val );
    30         Constant( Type * type, std::string rep, double val );
     30        Constant( Type * type, std::string rep, std::optional<unsigned long long> i );
    3131        Constant( const Constant & other );
     32        Constant & operator=( const Constant & ) = default;
    3233        virtual ~Constant();
    3334
    34         virtual Constant * clone() const { return new Constant( *this ); }
     35        virtual Constant * clone() const override { return new Constant( *this ); }
    3536
    3637        Type * get_type() { return type; }
     
    3940        void set_value( std::string newValue ) { rep = newValue; }
    4041        unsigned long long get_ival() const;
    41         double get_dval() const;
    4242
    4343        /// generates a boolean constant of the given bool
    4444        static Constant from_bool( bool b );
    45         /// generates a char constant of the given char
    46         static Constant from_char( char c );
    4745        /// generates an integer constant of the given int
    4846        static Constant from_int( int i );
    4947        /// generates an integer constant of the given unsigned long int
    5048        static Constant from_ulong( unsigned long i );
    51         /// generates a floating point constant of the given double
    52         static Constant from_double( double d );
    5349
    5450        /// generates a null pointer value for the given type. void * if omitted.
    5551        static Constant null( Type * ptrtype = nullptr );
    5652
    57         virtual void accept( Visitor & v ) { v.visit( this ); }
    58         virtual Constant * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    59         virtual void print( std::ostream & os, Indenter indent = 0 ) const;
    60   private:
     53        virtual void accept( Visitor & v ) override { v.visit( this ); }
     54        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     55        virtual Constant * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
     56        virtual void print( std::ostream & os, Indenter indent = 0 ) const override;
     57
    6158        Type * type;
    6259        std::string rep;
    63         union Val {
    64                 unsigned long long ival;
    65                 double dval;
    66                 Val( unsigned long long ival ) : ival( ival ) {}
    67                 Val( double dval ) : dval( dval ) {}
    68         } val;
     60        std::optional<unsigned long long> ival;
    6961};
    7062
  • src/SynTree/DeclReplacer.cc

    r7951100 rb067d9b  
    3030                        bool debug;
    3131                public:
     32                        size_t replaced;
     33
     34                public:
    3235                        DeclReplacer( const DeclMap & declMap, const TypeMap & typeMap, bool debug = false );
    3336
     
    3841                        void previsit( TypeInstType * inst );
    3942                };
     43
     44                /// Mutator that replaces uses of declarations with arbitrary expressions, according to the supplied mapping
     45                struct ExprDeclReplacer {
     46                private:
     47                        const ExprMap & exprMap;
     48                        bool debug;
     49                public:
     50                        size_t replaced;
     51
     52                public:
     53                        ExprDeclReplacer( const ExprMap & exprMap, bool debug = false );
     54
     55                        // replace variable with new node from expr map
     56                        Expression * postmutate( VariableExpr * varExpr );
     57                };
    4058        }
    4159
    42         void replace( BaseSyntaxNode * node, const DeclMap & declMap, const TypeMap & typeMap, bool debug ) {
     60        size_t replace( BaseSyntaxNode * node, const DeclMap & declMap, const TypeMap & typeMap, bool debug ) {
    4361                PassVisitor<DeclReplacer> replacer( declMap, typeMap, debug );
    4462                maybeAccept( node, replacer );
     63                return replacer.pass.replaced;
    4564        }
    4665
    47         void replace( BaseSyntaxNode * node, const DeclMap & declMap, bool debug ) {
     66        size_t replace( BaseSyntaxNode * node, const DeclMap & declMap, bool debug ) {
    4867                TypeMap typeMap;
    49                 replace( node, declMap, typeMap, debug );
     68                return replace( node, declMap, typeMap, debug );
    5069        }
    5170
    52         void replace( BaseSyntaxNode * node, const TypeMap & typeMap, bool debug ) {
     71        size_t replace( BaseSyntaxNode * node, const TypeMap & typeMap, bool debug ) {
    5372                DeclMap declMap;
    54                 replace( node, declMap, typeMap, debug );
     73                return replace( node, declMap, typeMap, debug );
     74        }
     75
     76        size_t replace( BaseSyntaxNode *& node, const ExprMap & exprMap, bool debug ) {
     77                PassVisitor<ExprDeclReplacer> replacer( exprMap, debug );
     78                node = maybeMutate( node, replacer );
     79                return replacer.pass.replaced;
    5580        }
    5681
    5782        namespace {
    58                 DeclReplacer::DeclReplacer( const DeclMap & declMap, const TypeMap & typeMap, bool debug ) : declMap( declMap ), typeMap( typeMap ) , debug( debug ) {}
     83                DeclReplacer::DeclReplacer( const DeclMap & declMap, const TypeMap & typeMap, bool debug ) : declMap( declMap ), typeMap( typeMap ) , debug( debug ), replaced( 0 ) {}
    5984
    6085                // replace variable with new node from decl map
     
    6287                        // xxx - assertions and parameters aren't accounted for in this... (i.e. they aren't inserted into the map when it's made, only DeclStmts are)
    6388                        if ( declMap.count( varExpr->var ) ) {
     89                                replaced++;
    6490                                auto replacement = declMap.at( varExpr->var );
    6591                                if ( debug ) {
     
    7298                void DeclReplacer::previsit( TypeInstType * inst ) {
    7399                        if ( typeMap.count( inst->baseType ) ) {
     100                                replaced++;
    74101                                auto replacement = typeMap.at( inst->baseType );
    75102                                if ( debug ) {
     
    79106                        }
    80107                }
     108
     109                ExprDeclReplacer::ExprDeclReplacer( const ExprMap & exprMap, bool debug ) : exprMap( exprMap ), debug( debug ), replaced( 0 ) {}
     110
     111                Expression * ExprDeclReplacer::postmutate( VariableExpr * varExpr ) {
     112                        if ( exprMap.count( varExpr->var ) ) {
     113                                replaced++;
     114                                Expression * replacement = exprMap.at( varExpr->var )->clone();
     115                                if ( debug ) {
     116                                        std::cerr << "replacing variable reference: " << (void*)varExpr->var << " " << varExpr->var << " with " << (void*)replacement << " " << replacement << std::endl;
     117                                }
     118                                std::swap( varExpr->env, replacement->env );
     119                                delete varExpr;
     120                                return replacement;
     121                        }
     122                        return varExpr;
     123                }
    81124        }
    82125} // namespace VarExprReplacer
  • src/SynTree/DeclReplacer.h

    r7951100 rb067d9b  
    2626        typedef std::map< DeclarationWithType *, DeclarationWithType * > DeclMap;
    2727        typedef std::map< TypeDecl *, TypeDecl * > TypeMap;
     28        typedef std::map< DeclarationWithType *, Expression * > ExprMap;
    2829
    29         void replace( BaseSyntaxNode * node, const DeclMap & declMap, bool debug = false );
    30         void replace( BaseSyntaxNode * node, const TypeMap & typeMap, bool debug = false );
    31         void replace( BaseSyntaxNode * node, const DeclMap & declMap, const TypeMap & typeMap, bool debug = false );
     30        size_t replace( BaseSyntaxNode * node, const DeclMap & declMap, bool debug = false );
     31        size_t replace( BaseSyntaxNode * node, const TypeMap & typeMap, bool debug = false );
     32        size_t replace( BaseSyntaxNode * node, const DeclMap & declMap, const TypeMap & typeMap, bool debug = false );
     33
     34        size_t replace( BaseSyntaxNode *& node, const ExprMap & exprMap, bool debug = false);
     35
     36        template<typename T>
     37        size_t replace( T *& node, const ExprMap & exprMap, bool debug = false ) {
     38                if ( ! node ) return 0ul;
     39                BaseSyntaxNode * arg = node;
     40                size_t replaced = replace( arg, exprMap, debug );
     41                node = dynamic_cast<T *>( arg );
     42                assertf( node, "DeclReplacer fundamentally changed the type of its argument." );
     43                return replaced;
     44        }
    3245}
    3346
  • src/SynTree/Declaration.cc

    r7951100 rb067d9b  
    2727
    2828static UniqueId lastUniqueId = 0;
    29 typedef std::map< UniqueId, Declaration* > IdMapType;
    30 static IdMapType idMap;
    3129
    3230Declaration::Declaration( const std::string &name, Type::StorageClasses scs, LinkageSpec::Spec linkage )
    33                 : name( name ), linkage( linkage ), storageClasses( scs ), uniqueId( 0 ) {
     31                : name( name ), linkage( linkage ), uniqueId( 0 ), storageClasses( scs ) {
    3432}
    3533
    3634Declaration::Declaration( const Declaration &other )
    37         : BaseSyntaxNode( other ), name( other.name ), linkage( other.linkage ), extension( other.extension ), storageClasses( other.storageClasses ), uniqueId( other.uniqueId ) {
     35        : BaseSyntaxNode( other ), name( other.name ), linkage( other.linkage ), extension( other.extension ), uniqueId( other.uniqueId ), storageClasses( other.storageClasses ) {
    3836}
    3937
     
    4543        if ( uniqueId ) return;
    4644        uniqueId = ++lastUniqueId;
    47         idMap[ uniqueId ] = this;
    4845}
    49 
    50 Declaration *Declaration::declFromId( UniqueId id ) {
    51         IdMapType::const_iterator i = idMap.find( id );
    52         return i != idMap.end() ? i->second : 0;
    53 }
    54 
    55 void Declaration::dumpIds( std::ostream &os ) {
    56         for ( IdMapType::const_iterator i = idMap.begin(); i != idMap.end(); ++i ) {
    57                 os << i->first << " -> ";
    58                 i->second->printShort( os );
    59                 os << std::endl;
    60         } // for
    61 }
    62 
    6346
    6447AsmDecl::AsmDecl( AsmStmt *stmt ) : Declaration( "", Type::StorageClasses(), LinkageSpec::C ), stmt( stmt ) {
  • src/SynTree/Declaration.h

    r7951100 rb067d9b  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : 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
     
    6263        void fixUniqueId( void );
    6364        virtual Declaration *clone() const override = 0;
    64         virtual void accept( Visitor &v ) override = 0;
     65        virtual void accept( Visitor & v ) override = 0;
     66        virtual void accept( Visitor & v ) const override = 0;
    6567        virtual Declaration *acceptMutator( Mutator &m ) override = 0;
    6668        virtual void print( std::ostream &os, Indenter indent = {} ) const override = 0;
    6769        virtual void printShort( std::ostream &os, Indenter indent = {} ) const = 0;
    6870
    69         static void dumpIds( std::ostream &os );
    70         static Declaration *declFromId( UniqueId id );
    71 
    72   private:
     71        UniqueId uniqueId;
    7372        Type::StorageClasses storageClasses;
    74         UniqueId uniqueId;
     73  private:
    7574};
    7675
     
    141140
    142141        virtual ObjectDecl *clone() const override { return new ObjectDecl( *this ); }
    143         virtual void accept( Visitor &v ) override { v.visit( this ); }
     142        virtual void accept( Visitor & v ) override { v.visit( this ); }
     143        virtual void accept( Visitor & v ) const override { v.visit( this ); }
    144144        virtual DeclarationWithType *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    145145        virtual void print( std::ostream &os, Indenter indent = {} ) const override;
     
    166166        CompoundStmt *get_statements() const { return statements; }
    167167        void set_statements( CompoundStmt *newValue ) { statements = newValue; }
     168        bool has_body() const { return NULL != statements; }
    168169
    169170        static FunctionDecl * newFunction( const std::string & name, FunctionType * type, CompoundStmt * statements );
    170171
    171172        virtual FunctionDecl *clone() const override { return new FunctionDecl( *this ); }
    172         virtual void accept( Visitor &v ) override { v.visit( this ); }
     173        virtual void accept( Visitor & v ) override { v.visit( this ); }
     174        virtual void accept( Visitor & v ) const override { v.visit( this ); }
    173175        virtual DeclarationWithType *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    174176        virtual void print( std::ostream &os, Indenter indent = {} ) const override;
     
    202204        typedef NamedTypeDecl Parent;
    203205  public:
    204         enum Kind { Dtype, Ftype, Ttype };
     206        enum Kind { Dtype, Ftype, Ttype, NUMBER_OF_KINDS };
    205207
    206208        Type * init;
     
    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);}
     
    235241
    236242        virtual TypeDecl *clone() const override { return new TypeDecl( *this ); }
    237         virtual void accept( Visitor &v ) override { v.visit( this ); }
    238         virtual Declaration *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    239         virtual void print( std::ostream &os, Indenter indent = {} ) const override;
    240 
    241   private:
     243        virtual void accept( Visitor & v ) override { v.visit( this ); }
     244        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     245        virtual Declaration *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
     246        virtual void print( std::ostream &os, Indenter indent = {} ) const override;
     247
    242248        Kind kind;
    243249};
     
    254260
    255261        virtual TypedefDecl *clone() const override { return new TypedefDecl( *this ); }
    256         virtual void accept( Visitor &v ) override { v.visit( this ); }
     262        virtual void accept( Visitor & v ) override { v.visit( this ); }
     263        virtual void accept( Visitor & v ) const override { v.visit( this ); }
    257264        virtual Declaration *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    258265  private:
     
    266273        bool body;
    267274        std::list< Attribute * > attributes;
     275        AggregateDecl * parent = nullptr;
    268276
    269277        AggregateDecl( const std::string &name, const std::list< Attribute * > & attributes = std::list< class Attribute * >(), LinkageSpec::Spec linkage = LinkageSpec::Cforall );
     
    280288        AggregateDecl * set_body( bool body ) { AggregateDecl::body = body; return this; }
    281289
    282         virtual void print( std::ostream &os, Indenter indent = {} ) const override;
     290        virtual void print( std::ostream &os, Indenter indent = {} ) const override final;
    283291        virtual void printShort( std::ostream &os, Indenter indent = {} ) const override;
    284292  protected:
     
    297305
    298306        virtual StructDecl *clone() const override { return new StructDecl( *this ); }
    299         virtual void accept( Visitor &v ) override { v.visit( this ); }
    300         virtual Declaration *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    301   private:
     307        virtual void accept( Visitor & v ) override { v.visit( this ); }
     308        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     309        virtual Declaration *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    302310        DeclarationNode::Aggregate kind;
     311  private:
    303312        virtual std::string typeString() const override;
    304313};
     
    311320
    312321        virtual UnionDecl *clone() const override { return new UnionDecl( *this ); }
    313         virtual void accept( Visitor &v ) override { v.visit( this ); }
     322        virtual void accept( Visitor & v ) override { v.visit( this ); }
     323        virtual void accept( Visitor & v ) const override { v.visit( this ); }
    314324        virtual Declaration *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    315325  private:
     
    326336
    327337        virtual EnumDecl *clone() const override { return new EnumDecl( *this ); }
    328         virtual void accept( Visitor &v ) override { v.visit( this ); }
    329         virtual Declaration *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    330   private:
    331         std::map< std::string, long long int > enumValues;
     338        virtual void accept( Visitor & v ) override { v.visit( this ); }
     339        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     340        virtual Declaration *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
     341  private:
     342        std::unordered_map< std::string, long long int > enumValues;
    332343        virtual std::string typeString() const override;
    333344};
     
    342353
    343354        virtual TraitDecl *clone() const override { return new TraitDecl( *this ); }
    344         virtual void accept( Visitor &v ) override { v.visit( this ); }
    345         virtual Declaration *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    346   private:
    347         virtual std::string typeString() const override;
     355        virtual void accept( Visitor & v ) override { v.visit( this ); }
     356        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     357        virtual Declaration *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
     358  private:
     359        virtual std::string typeString() const override;
     360};
     361
     362class WithStmt : public Declaration {
     363public:
     364        std::list< Expression * > exprs;
     365        Statement * stmt;
     366
     367        WithStmt( const std::list< Expression * > & exprs, Statement * stmt );
     368        WithStmt( const WithStmt & other );
     369        virtual ~WithStmt();
     370
     371        virtual WithStmt * clone() const override { return new WithStmt( *this ); }
     372        virtual void accept( Visitor & v ) override { v.visit( this ); }
     373        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     374        virtual Declaration * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
     375        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     376        virtual void printShort( std::ostream & os, Indenter indent = {} ) const override { print(os, indent); }
    348377};
    349378
     
    360389
    361390        virtual AsmDecl *clone() const override { return new AsmDecl( *this ); }
    362         virtual void accept( Visitor &v ) override { v.visit( this ); }
     391        virtual void accept( Visitor & v ) override { v.visit( this ); }
     392        virtual void accept( Visitor & v ) const override { v.visit( this ); }
    363393        virtual AsmDecl *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    364394        virtual void print( std::ostream &os, Indenter indent = {} ) const override;
     
    376406
    377407        virtual StaticAssertDecl * clone() const override { return new StaticAssertDecl( *this ); }
    378         virtual void accept( Visitor &v ) override { v.visit( this ); }
     408        virtual void accept( Visitor & v ) override { v.visit( this ); }
     409        virtual void accept( Visitor & v ) const override { v.visit( this ); }
    379410        virtual StaticAssertDecl * acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    380411        virtual void print( std::ostream &os, Indenter indent = {} ) const override;
  • src/SynTree/Expression.cc

    r7951100 rb067d9b  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Jul 25 14:15:47 2017
    13 // Update Count     : 54
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Thr Aug 15 13:43:00 2019
     13// Update Count     : 64
    1414//
    1515
     
    1919#include <iostream>                  // for ostream, operator<<, basic_ostream
    2020#include <list>                      // for list, _List_iterator, list<>::co...
     21#include <set>                       // for set
    2122
    2223#include "Common/utility.h"          // for maybeClone, cloneAll, deleteAll
     
    3334#include "GenPoly/Lvalue.h"
    3435
    35 void printInferParams( const InferredParams & inferParams, std::ostream &os, Indenter indent, int level ) {
     36void printInferParams( const InferredParams & inferParams, std::ostream & os, Indenter indent, int level ) {
    3637        if ( ! inferParams.empty() ) {
    3738                os << indent << "with inferred parameters " << level << ":" << std::endl;
    3839                for ( InferredParams::const_iterator i = inferParams.begin(); i != inferParams.end(); ++i ) {
    3940                        os << indent+1;
    40                         Declaration::declFromId( i->second.decl )->printShort( os, indent+1 );
     41                        assert(i->second.declptr);
     42                        i->second.declptr->printShort( os, indent+1 );
    4143                        os << std::endl;
    42                         printInferParams( *i->second.inferParams, os, indent+1, level+1 );
     44                        printInferParams( i->second.expr->inferParams, os, indent+1, level+1 );
    4345                } // for
    4446        } // if
     
    4749Expression::Expression() : result( 0 ), env( 0 ) {}
    4850
    49 Expression::Expression( const Expression &other ) : BaseSyntaxNode( other ), result( maybeClone( other.result ) ), env( maybeClone( other.env ) ), extension( other.extension ), inferParams( other.inferParams ) {
    50 }
     51Expression::Expression( const Expression & other ) : BaseSyntaxNode( other ), result( maybeClone( other.result ) ), env( maybeClone( other.env ) ), extension( other.extension ), inferParams( other.inferParams ), resnSlots( other.resnSlots ) {}
    5152
    5253void Expression::spliceInferParams( Expression * other ) {
     
    5556                inferParams[p.first] = std::move( p.second );
    5657        }
     58        resnSlots.insert( resnSlots.end(), other->resnSlots.begin(), other->resnSlots.end() );
    5759}
    5860
     
    6264}
    6365
    64 void Expression::print( std::ostream &os, Indenter indent ) const {
     66bool Expression::get_lvalue() const {
     67        return false;
     68}
     69
     70void Expression::print( std::ostream & os, Indenter indent ) const {
    6571        printInferParams( inferParams, os, indent+1, 0 );
    6672
     
    7985}
    8086
    81 ConstantExpr::ConstantExpr( const ConstantExpr &other) : Expression( other ), constant( other.constant ) {
     87ConstantExpr::ConstantExpr( const ConstantExpr & other) : Expression( other ), constant( other.constant ) {
    8288}
    8389
    8490ConstantExpr::~ConstantExpr() {}
    8591
    86 void ConstantExpr::print( std::ostream &os, Indenter indent ) const {
     92void ConstantExpr::print( std::ostream & os, Indenter indent ) const {
    8793        os << "constant expression " ;
    8894        constant.print( os );
     
    103109}
    104110
     111VariableExpr::VariableExpr() : Expression(), var( nullptr ) {}
     112
    105113VariableExpr::VariableExpr( DeclarationWithType *_var ) : Expression(), var( _var ) {
    106114        assert( var );
    107115        assert( var->get_type() );
    108116        Type * type = var->get_type()->clone();
    109         type->set_lvalue( true );
    110117
    111118        // xxx - doesn't quite work yet - get different alternatives with the same cost
     
    117124        //      long long int value;
    118125        //      if ( decl->valueOf( var, value ) ) {
    119         //              type->set_lvalue( false );
     126        //              type->set_lvalue( false ); // Would have to move to get_lvalue.
    120127        //      }
    121128        // }
     
    124131}
    125132
    126 VariableExpr::VariableExpr( const VariableExpr &other ) : Expression( other ), var( other.var ) {
     133VariableExpr::VariableExpr( const VariableExpr & other ) : Expression( other ), var( other.var ) {
    127134}
    128135
    129136VariableExpr::~VariableExpr() {
    130137        // don't delete the declaration, since it points somewhere else in the tree
     138}
     139
     140bool VariableExpr::get_lvalue() const {
     141        // It isn't always an lvalue, but it is never an rvalue.
     142        return true;
    131143}
    132144
     
    137149}
    138150
    139 void VariableExpr::print( std::ostream &os, Indenter indent ) const {
     151void VariableExpr::print( std::ostream & os, Indenter indent ) const {
    140152        os << "Variable Expression: ";
    141153        var->printShort(os, indent);
     
    143155}
    144156
    145 SizeofExpr::SizeofExpr( Expression *expr_ ) :
     157SizeofExpr::SizeofExpr( Expression * expr_ ) :
    146158                Expression(), expr(expr_), type(0), isType(false) {
    147159        set_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );
    148160}
    149161
    150 SizeofExpr::SizeofExpr( Type *type_ ) :
     162SizeofExpr::SizeofExpr( Type * type_ ) :
    151163                Expression(), expr(0), type(type_), isType(true) {
    152164        set_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );
    153165}
    154166
    155 SizeofExpr::SizeofExpr( const SizeofExpr &other ) :
     167SizeofExpr::SizeofExpr( const SizeofExpr & other ) :
    156168        Expression( other ), expr( maybeClone( other.expr ) ), type( maybeClone( other.type ) ), isType( other.isType ) {
    157169}
     
    162174}
    163175
    164 void SizeofExpr::print( std::ostream &os, Indenter indent) const {
     176void SizeofExpr::print( std::ostream & os, Indenter indent) const {
    165177        os << "Sizeof Expression on: ";
    166178        if (isType) type->print(os, indent+1);
     
    169181}
    170182
    171 AlignofExpr::AlignofExpr( Expression *expr_ ) :
     183AlignofExpr::AlignofExpr( Expression * expr_ ) :
    172184                Expression(), expr(expr_), type(0), isType(false) {
    173185        set_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );
    174186}
    175187
    176 AlignofExpr::AlignofExpr( Type *type_ ) :
     188AlignofExpr::AlignofExpr( Type * type_ ) :
    177189                Expression(), expr(0), type(type_), isType(true) {
    178190        set_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );
    179191}
    180192
    181 AlignofExpr::AlignofExpr( const AlignofExpr &other ) :
     193AlignofExpr::AlignofExpr( const AlignofExpr & other ) :
    182194        Expression( other ), expr( maybeClone( other.expr ) ), type( maybeClone( other.type ) ), isType( other.isType ) {
    183195}
     
    188200}
    189201
    190 void AlignofExpr::print( std::ostream &os, Indenter indent) const {
     202void AlignofExpr::print( std::ostream & os, Indenter indent) const {
    191203        os << "Alignof Expression on: ";
    192204        if (isType) type->print(os, indent+1);
     
    195207}
    196208
    197 UntypedOffsetofExpr::UntypedOffsetofExpr( Type *type, const std::string &member ) :
     209UntypedOffsetofExpr::UntypedOffsetofExpr( Type * type, const std::string & member ) :
    198210                Expression(), type(type), member(member) {
    199211        assert( type );
     
    201213}
    202214
    203 UntypedOffsetofExpr::UntypedOffsetofExpr( const UntypedOffsetofExpr &other ) :
     215UntypedOffsetofExpr::UntypedOffsetofExpr( const UntypedOffsetofExpr & other ) :
    204216        Expression( other ), type( maybeClone( other.type ) ), member( other.member ) {}
    205217
     
    208220}
    209221
    210 void UntypedOffsetofExpr::print( std::ostream &os, Indenter indent) const {
     222void UntypedOffsetofExpr::print( std::ostream & os, Indenter indent) const {
    211223        os << "Untyped Offsetof Expression on member " << member << " of ";
    212224        type->print(os, indent+1);
     
    214226}
    215227
    216 OffsetofExpr::OffsetofExpr( Type *type, DeclarationWithType *member ) :
     228OffsetofExpr::OffsetofExpr( Type * type, DeclarationWithType * member ) :
    217229                Expression(), type(type), member(member) {
    218230        assert( member );
     
    221233}
    222234
    223 OffsetofExpr::OffsetofExpr( const OffsetofExpr &other ) :
     235OffsetofExpr::OffsetofExpr( const OffsetofExpr & other ) :
    224236        Expression( other ), type( maybeClone( other.type ) ), member( other.member ) {}
    225237
     
    228240}
    229241
    230 void OffsetofExpr::print( std::ostream &os, Indenter indent) const {
     242void OffsetofExpr::print( std::ostream & os, Indenter indent) const {
    231243        os << "Offsetof Expression on member " << member->name << " of ";
    232244        type->print(os, indent+1);
     
    234246}
    235247
    236 OffsetPackExpr::OffsetPackExpr( StructInstType *type ) : Expression(), type( type ) {
     248OffsetPackExpr::OffsetPackExpr( StructInstType * type ) : Expression(), type( type ) {
    237249        assert( type );
    238250        set_result( new ArrayType( Type::Qualifiers(), new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), 0, false, false ) );
    239251}
    240252
    241 OffsetPackExpr::OffsetPackExpr( const OffsetPackExpr &other ) : Expression( other ), type( maybeClone( other.type ) ) {}
     253OffsetPackExpr::OffsetPackExpr( const OffsetPackExpr & other ) : Expression( other ), type( maybeClone( other.type ) ) {}
    242254
    243255OffsetPackExpr::~OffsetPackExpr() { delete type; }
    244256
    245 void OffsetPackExpr::print( std::ostream &os, Indenter indent ) const {
     257void OffsetPackExpr::print( std::ostream & os, Indenter indent ) const {
    246258        os << "Offset pack expression on ";
    247259        type->print(os, indent+1);
     
    249261}
    250262
    251 AttrExpr::AttrExpr( Expression *attr, Expression *expr_ ) :
    252                 Expression(), attr( attr ), expr(expr_), type(0), isType(false) {
    253 }
    254 
    255 AttrExpr::AttrExpr( Expression *attr, Type *type_ ) :
    256                 Expression(), attr( attr ), expr(0), type(type_), isType(true) {
    257 }
    258 
    259 AttrExpr::AttrExpr( const AttrExpr &other ) :
    260                 Expression( other ), attr( maybeClone( other.attr ) ), expr( maybeClone( other.expr ) ), type( maybeClone( other.type ) ), isType( other.isType ) {
    261 }
    262 
    263 AttrExpr::~AttrExpr() {
    264         delete attr;
    265         delete expr;
    266         delete type;
    267 }
    268 
    269 void AttrExpr::print( std::ostream &os, Indenter indent) const {
    270         os << "Attr ";
    271         attr->print( os, indent+1);
    272         if ( isType || expr ) {
    273                 os << "applied to: ";
    274                 if (isType) type->print(os, indent+1);
    275                 else expr->print(os, indent+1);
    276         } // if
    277         Expression::print( os, indent );
    278 }
    279 
    280 CastExpr::CastExpr( Expression *arg, Type *toType, bool isGenerated ) : Expression(), arg(arg), isGenerated( isGenerated ) {
     263CastExpr::CastExpr( Expression * arg, Type * toType, bool isGenerated ) : arg(arg), isGenerated( isGenerated ) {
    281264        set_result(toType);
    282265}
    283266
    284 CastExpr::CastExpr( Expression *arg, bool isGenerated ) : Expression(), arg(arg), isGenerated( isGenerated ) {
     267CastExpr::CastExpr( Expression * arg, bool isGenerated ) : arg(arg), isGenerated( isGenerated ) {
    285268        set_result( new VoidType( Type::Qualifiers() ) );
    286269}
    287270
    288 CastExpr::CastExpr( const CastExpr &other ) : Expression( other ), arg( maybeClone( other.arg ) ), isGenerated( other.isGenerated ) {
     271CastExpr::CastExpr( const CastExpr & other ) : Expression( other ), arg( maybeClone( other.arg ) ), isGenerated( other.isGenerated ) {
    289272}
    290273
     
    293276}
    294277
    295 void CastExpr::print( std::ostream &os, Indenter indent ) const {
    296         os << "Cast of:" << std::endl << indent+1;
     278bool CastExpr::get_lvalue() const {
     279        // This is actually wrong by C, but it works with our current set-up.
     280        return arg->get_lvalue();
     281}
     282
     283void CastExpr::print( std::ostream & os, Indenter indent ) const {
     284        os << (isGenerated ? "Generated " : "Explicit ") << "Cast of:" << std::endl << indent+1;
    297285        arg->print(os, indent+1);
    298286        os << std::endl << indent << "... to:";
     
    306294}
    307295
    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 ) {
     296KeywordCastExpr::KeywordCastExpr( Expression * arg, Target target ) : Expression(), arg(arg), target( target ) {
     297}
     298
     299KeywordCastExpr::KeywordCastExpr( const KeywordCastExpr & other ) : Expression( other ), arg( maybeClone( other.arg ) ), target( other.target ) {
    312300}
    313301
     
    327315}
    328316
    329 void KeywordCastExpr::print( std::ostream &os, Indenter indent ) const {
     317void KeywordCastExpr::print( std::ostream & os, Indenter indent ) const {
    330318        os << "Keyword Cast of:" << std::endl << indent+1;
    331319        arg->print(os, indent+1);
     
    335323}
    336324
    337 VirtualCastExpr::VirtualCastExpr( Expression *arg_, Type *toType ) : Expression(), arg(arg_) {
     325VirtualCastExpr::VirtualCastExpr( Expression * arg_, Type * toType ) : Expression(), arg(arg_) {
    338326        set_result(toType);
    339327}
    340328
    341 VirtualCastExpr::VirtualCastExpr( const VirtualCastExpr &other ) : Expression( other ), arg( maybeClone( other.arg ) ) {
     329VirtualCastExpr::VirtualCastExpr( const VirtualCastExpr & other ) : Expression( other ), arg( maybeClone( other.arg ) ) {
    342330}
    343331
     
    346334}
    347335
    348 void VirtualCastExpr::print( std::ostream &os, Indenter indent ) const {
     336void VirtualCastExpr::print( std::ostream & os, Indenter indent ) const {
    349337        os << "Virtual Cast of:" << std::endl << indent+1;
    350338        arg->print(os, indent+1);
     
    359347}
    360348
    361 UntypedMemberExpr::UntypedMemberExpr( Expression * member, Expression *aggregate ) :
     349UntypedMemberExpr::UntypedMemberExpr( Expression * member, Expression * aggregate ) :
    362350                Expression(), member(member), aggregate(aggregate) {
    363351        assert( aggregate );
    364352}
    365353
    366 UntypedMemberExpr::UntypedMemberExpr( const UntypedMemberExpr &other ) :
     354UntypedMemberExpr::UntypedMemberExpr( const UntypedMemberExpr & other ) :
    367355                Expression( other ), member( maybeClone( other.member ) ), aggregate( maybeClone( other.aggregate ) ) {
    368356}
     
    373361}
    374362
    375 void UntypedMemberExpr::print( std::ostream &os, Indenter indent ) const {
     363bool UntypedMemberExpr::get_lvalue() const {
     364        return aggregate->get_lvalue();
     365}
     366
     367void UntypedMemberExpr::print( std::ostream & os, Indenter indent ) const {
    376368        os << "Untyped Member Expression, with field: " << std::endl << indent+1;
    377369        member->print(os, indent+1 );
    378         os << indent << "... from aggregate: " << std::endl << indent+1;
     370        os << indent << "... from aggregate:" << std::endl << indent+1;
    379371        aggregate->print(os, indent+1);
    380372        Expression::print( os, indent );
    381373}
    382374
    383 MemberExpr::MemberExpr( DeclarationWithType *member, Expression *aggregate ) :
     375MemberExpr::MemberExpr( DeclarationWithType * member, Expression * aggregate ) :
    384376                Expression(), member(member), aggregate(aggregate) {
    385377        assert( member );
     
    391383        sub.apply( res );
    392384        result = res;
    393         result->set_lvalue( true );
    394385        result->get_qualifiers() |= aggregate->result->get_qualifiers();
    395386}
    396387
    397 MemberExpr::MemberExpr( const MemberExpr &other ) :
     388MemberExpr::MemberExpr( const MemberExpr & other ) :
    398389                Expression( other ), member( other.member ), aggregate( maybeClone( other.aggregate ) ) {
    399390}
     
    404395}
    405396
    406 void MemberExpr::print( std::ostream &os, Indenter indent ) const {
    407         os << "Member Expression, with field: " << std::endl;
     397bool MemberExpr::get_lvalue() const {
     398        // This is actually wrong by C, but it works with our current set-up.
     399        return true;
     400}
     401
     402void MemberExpr::print( std::ostream & os, Indenter indent ) const {
     403        os << "Member Expression, with field:" << std::endl;
    408404        os << indent+1;
    409405        member->print( os, indent+1 );
    410         os << std::endl << indent << "... from aggregate: " << std::endl << indent+1;
     406        os << std::endl << indent << "... from aggregate:" << std::endl << indent+1;
    411407        aggregate->print(os, indent + 1);
    412408        Expression::print( os, indent );
    413409}
    414410
    415 UntypedExpr::UntypedExpr( Expression *function, const std::list<Expression *> &args ) :
     411UntypedExpr::UntypedExpr( Expression * function, const std::list<Expression *> & args ) :
    416412                Expression(), function(function), args(args) {}
    417413
    418 UntypedExpr::UntypedExpr( const UntypedExpr &other ) :
     414UntypedExpr::UntypedExpr( const UntypedExpr & other ) :
    419415                Expression( other ), function( maybeClone( other.function ) ) {
    420416        cloneAll( other.args, args );
     
    435431                        // if references are still allowed in the AST, dereference returns a reference
    436432                        ret->set_result( new ReferenceType( Type::Qualifiers(), ret->get_result() ) );
    437                 } else {
    438                         // references have been removed, in which case dereference returns an lvalue of the base type.
    439                         ret->result->set_lvalue( true );
    440433                }
    441434        }
     
    454447}
    455448
    456 
    457 void UntypedExpr::print( std::ostream &os, Indenter indent ) const {
    458         os << "Applying untyped: " << std::endl;
     449bool UntypedExpr::get_lvalue() const {
     450        // from src/GenPoly/Lvalue.cc: isIntrinsicReference
     451        static std::set<std::string> lvalueFunctions = { "*?", "?[?]" };
     452        std::string fname = InitTweak::getFunctionName( const_cast< UntypedExpr * >( this ) );
     453        return lvalueFunctions.count(fname);
     454}
     455
     456void UntypedExpr::print( std::ostream & os, Indenter indent ) const {
     457        os << "Applying untyped:" << std::endl;
    459458        os << indent+1;
    460459        function->print(os, indent+1);
    461         os << std::endl << indent << "...to: " << std::endl;
     460        os << std::endl << indent << "...to:" << std::endl;
    462461        printAll(args, os, indent+1);
    463462        Expression::print( os, indent );
     
    469468}
    470469
    471 NameExpr::NameExpr( const NameExpr &other ) : Expression( other ), name( other.name ) {
     470NameExpr::NameExpr( const NameExpr & other ) : Expression( other ), name( other.name ) {
    472471}
    473472
    474473NameExpr::~NameExpr() {}
    475474
    476 void NameExpr::print( std::ostream &os, Indenter indent ) const {
     475void NameExpr::print( std::ostream & os, Indenter indent ) const {
    477476        os << "Name: " << get_name();
    478477        Expression::print( os, indent );
    479478}
    480479
    481 LogicalExpr::LogicalExpr( Expression *arg1_, Expression *arg2_, bool andp ) :
     480LogicalExpr::LogicalExpr( Expression * arg1_, Expression * arg2_, bool andp ) :
    482481                Expression(), arg1(arg1_), arg2(arg2_), isAnd(andp) {
    483482        set_result( new BasicType( Type::Qualifiers(), BasicType::SignedInt ) );
    484483}
    485484
    486 LogicalExpr::LogicalExpr( const LogicalExpr &other ) :
     485LogicalExpr::LogicalExpr( const LogicalExpr & other ) :
    487486                Expression( other ), arg1( maybeClone( other.arg1 ) ), arg2( maybeClone( other.arg2 ) ), isAnd( other.isAnd ) {
    488487}
     
    493492}
    494493
    495 void LogicalExpr::print( std::ostream &os, Indenter indent )const {
     494void LogicalExpr::print( std::ostream & os, Indenter indent )const {
    496495        os << "Short-circuited operation (" << (isAnd ? "and" : "or") << ") on: ";
    497496        arg1->print(os);
     
    504503                Expression(), arg1(arg1), arg2(arg2), arg3(arg3) {}
    505504
    506 ConditionalExpr::ConditionalExpr( const ConditionalExpr &other ) :
     505ConditionalExpr::ConditionalExpr( const ConditionalExpr & other ) :
    507506                Expression( other ), arg1( maybeClone( other.arg1 ) ), arg2( maybeClone( other.arg2 ) ), arg3( maybeClone( other.arg3 ) ) {
    508507}
     
    514513}
    515514
    516 void ConditionalExpr::print( std::ostream &os, Indenter indent ) const {
     515bool ConditionalExpr::get_lvalue() const {
     516        return false;
     517}
     518
     519void ConditionalExpr::print( std::ostream & os, Indenter indent ) const {
    517520        os << "Conditional expression on: " << std::endl << indent+1;
    518521        arg1->print( os, indent+1 );
     
    527530
    528531
    529 void AsmExpr::print( std::ostream &os, Indenter indent ) const {
     532void AsmExpr::print( std::ostream & os, Indenter indent ) const {
    530533        os << "Asm Expression: " << std::endl;
    531534        if ( inout ) inout->print( os, indent+1 );
     
    538541        assert( callExpr );
    539542        assert( callExpr->result );
    540         set_result( callExpr->get_result()->clone() );
     543        set_result( callExpr->result->clone() );
    541544}
    542545
    543546ImplicitCopyCtorExpr::ImplicitCopyCtorExpr( const ImplicitCopyCtorExpr & other ) : Expression( other ), callExpr( maybeClone( other.callExpr ) ) {
    544         cloneAll( other.tempDecls, tempDecls );
    545         cloneAll( other.returnDecls, returnDecls );
    546         cloneAll( other.dtors, dtors );
    547547}
    548548
     
    550550        set_env( nullptr ); // ImplicitCopyCtorExpr does not take ownership of an environment
    551551        delete callExpr;
    552         deleteAll( tempDecls );
    553         deleteAll( returnDecls );
    554         deleteAll( dtors );
    555 }
    556 
    557 void ImplicitCopyCtorExpr::print( std::ostream &os, Indenter indent ) const {
     552}
     553
     554void ImplicitCopyCtorExpr::print( std::ostream & os, Indenter indent ) const {
    558555        os <<  "Implicit Copy Constructor Expression: " << std::endl << indent+1;
    559556        callExpr->print( os, indent+1 );
    560         os << std::endl << indent << "... with temporaries:" << std::endl;
    561         printAll( tempDecls, os, indent+1 );
    562         os << std::endl << indent << "... with return temporaries:" << std::endl;
    563         printAll( returnDecls, os, indent+1 );
    564         Expression::print( os, indent );
    565557}
    566558
     
    581573}
    582574
    583 void ConstructorExpr::print( std::ostream &os, Indenter indent ) const {
     575bool ConstructorExpr::get_lvalue() const {
     576        return false;
     577}
     578
     579void ConstructorExpr::print( std::ostream & os, Indenter indent ) const {
    584580        os <<  "Constructor Expression: " << std::endl << indent+1;
    585581        callExpr->print( os, indent + 2 );
     
    590586CompoundLiteralExpr::CompoundLiteralExpr( Type * type, Initializer * initializer ) : initializer( initializer ) {
    591587        assert( type && initializer );
    592         type->set_lvalue( true );
    593588        set_result( type );
    594589}
    595590
    596 CompoundLiteralExpr::CompoundLiteralExpr( const CompoundLiteralExpr &other ) : Expression( other ), initializer( other.initializer->clone() ) {}
     591CompoundLiteralExpr::CompoundLiteralExpr( const CompoundLiteralExpr & other ) : Expression( other ), initializer( other.initializer->clone() ) {}
    597592
    598593CompoundLiteralExpr::~CompoundLiteralExpr() {
     
    600595}
    601596
    602 void CompoundLiteralExpr::print( std::ostream &os, Indenter indent ) const {
     597bool CompoundLiteralExpr::get_lvalue() const {
     598        return true;
     599}
     600
     601void CompoundLiteralExpr::print( std::ostream & os, Indenter indent ) const {
    603602        os << "Compound Literal Expression: " << std::endl << indent+1;
    604603        result->print( os, indent+1 );
     
    608607}
    609608
    610 RangeExpr::RangeExpr( Expression *low, Expression *high ) : low( low ), high( high ) {}
    611 RangeExpr::RangeExpr( const RangeExpr &other ) : Expression( other ), low( other.low->clone() ), high( other.high->clone() ) {}
    612 void RangeExpr::print( std::ostream &os, Indenter indent ) const {
     609RangeExpr::RangeExpr( Expression * low, Expression * high ) : low( low ), high( high ) {}
     610RangeExpr::RangeExpr( const RangeExpr & other ) : Expression( other ), low( other.low->clone() ), high( other.high->clone() ) {}
     611void RangeExpr::print( std::ostream & os, Indenter indent ) const {
    613612        os << "Range Expression: ";
    614613        low->print( os, indent );
     
    618617}
    619618
    620 StmtExpr::StmtExpr( CompoundStmt *statements ) : statements( statements ) {
     619StmtExpr::StmtExpr( CompoundStmt * statements ) : statements( statements ) {
    621620        computeResult();
    622621}
    623 StmtExpr::StmtExpr( const StmtExpr &other ) : Expression( other ), statements( other.statements->clone() ) {
     622StmtExpr::StmtExpr( const StmtExpr & other ) : Expression( other ), statements( other.statements->clone() ), resultExpr( other.resultExpr ) {
    624623        cloneAll( other.returnDecls, returnDecls );
    625624        cloneAll( other.dtors, dtors );
     
    650649        }
    651650}
    652 void StmtExpr::print( std::ostream &os, Indenter indent ) const {
     651bool StmtExpr::get_lvalue() const {
     652        return false;
     653}
     654void StmtExpr::print( std::ostream & os, Indenter indent ) const {
    653655        os << "Statement Expression: " << std::endl << indent+1;
    654656        statements->print( os, indent+1 );
     
    666668
    667669long long UniqueExpr::count = 0;
    668 UniqueExpr::UniqueExpr( Expression *expr, long long idVal ) : expr( expr ), object( nullptr ), var( nullptr ), id( idVal ) {
     670UniqueExpr::UniqueExpr( Expression * expr, long long idVal ) : expr( expr ), object( nullptr ), var( nullptr ), id( idVal ) {
    669671        assert( expr );
    670672        assert( count != -1 );
     
    674676        }
    675677}
    676 UniqueExpr::UniqueExpr( const UniqueExpr &other ) : Expression( other ), expr( maybeClone( other.expr ) ), object( maybeClone( other.object ) ), var( maybeClone( other.var ) ), id( other.id ) {
     678UniqueExpr::UniqueExpr( const UniqueExpr & other ) : Expression( other ), expr( maybeClone( other.expr ) ), object( maybeClone( other.object ) ), var( maybeClone( other.var ) ), id( other.id ) {
    677679}
    678680UniqueExpr::~UniqueExpr() {
     
    681683        delete var;
    682684}
    683 void UniqueExpr::print( std::ostream &os, Indenter indent ) const {
     685void UniqueExpr::print( std::ostream & os, Indenter indent ) const {
    684686        os << "Unique Expression with id:" << id << std::endl << indent+1;
    685687        expr->print( os, indent+1 );
     
    732734}
    733735
    734 DeletedExpr::DeletedExpr( Expression * expr, BaseSyntaxNode * deleteStmt ) : expr( expr ), deleteStmt( deleteStmt ) {
     736DeletedExpr::DeletedExpr( Expression * expr, Declaration * deleteStmt ) : expr( expr ), deleteStmt( deleteStmt ) {
    735737        assert( expr->result );
    736738        result = expr->result->clone();
     
    746748        os << std::endl << indent+1 << "... deleted by: ";
    747749        deleteStmt->print( os, indent+1 );
     750}
     751
     752
     753DefaultArgExpr::DefaultArgExpr( Expression * expr ) : expr( expr ) {
     754        assert( expr->result );
     755        result = expr->result->clone();
     756}
     757DefaultArgExpr::DefaultArgExpr( const DefaultArgExpr & other ) : Expression( other ), expr( maybeClone( other.expr ) ) {}
     758DefaultArgExpr::~DefaultArgExpr() {
     759        delete expr;
     760}
     761
     762void DefaultArgExpr::print( std::ostream & os, Indenter indent ) const {
     763        os << "Default Argument Expression" << std::endl << indent+1;
     764        expr->print( os, indent+1 );
    748765}
    749766
  • src/SynTree/Expression.h

    r7951100 rb067d9b  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Sep  3 19:23:46 2017
    13 // Update Count     : 48
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Thr Aug 15 13:46:00 2019
     13// Update Count     : 54
    1414//
    1515
     
    2121#include <memory>                 // for allocator, unique_ptr
    2222#include <string>                 // for string
     23#include <vector>                 // for vector
    2324
    2425#include "BaseSyntaxNode.h"       // for BaseSyntaxNode
     
    3839/// but subject to decay-to-pointer and type parameter renaming
    3940struct ParamEntry {
    40         ParamEntry(): decl( 0 ), actualType( 0 ), formalType( 0 ), expr( 0 ), inferParams( new InferredParams ) {}
    41         ParamEntry( UniqueId decl, Type * actualType, Type * formalType, Expression* expr ): decl( decl ), actualType( actualType ), formalType( formalType ), expr( expr ), inferParams( new InferredParams ) {}
     41        ParamEntry(): decl( 0 ), declptr( nullptr ), actualType( nullptr ), formalType( nullptr ), expr( nullptr ) {}
     42        ParamEntry( UniqueId decl, Declaration * declptr, Type * actualType, Type * formalType, Expression* expr );
    4243        ParamEntry( const ParamEntry & other );
    4344        ParamEntry( ParamEntry && other );
    4445        ~ParamEntry();
    45         ParamEntry & operator=( const ParamEntry & other );
    4646        ParamEntry & operator=( ParamEntry && other );
    4747
    48         UniqueId decl;
    49         Type * actualType;
    50         Type * formalType;
     48        UniqueId const decl;
     49        Declaration * const declptr;
     50        Type * const actualType;
     51        Type * const formalType;
    5152        Expression * expr;
    52         std::unique_ptr< InferredParams > inferParams;
    5353};
    5454
     
    5959        TypeSubstitution * env;
    6060        bool extension = false;
    61         InferredParams inferParams;
     61        InferredParams inferParams;       ///< Post-resolution inferred parameter slots
     62        std::vector<UniqueId> resnSlots;  ///< Pre-resolution inferred parameter slots
     63
     64        // xxx - should turn inferParams+resnSlots into a union to save some memory
    6265
    6366        Expression();
     
    6871        const Type * get_result() const { return result; }
    6972        void set_result( Type * newValue ) { result = newValue; }
     73        virtual bool get_lvalue() const;
    7074
    7175        TypeSubstitution * get_env() const { return env; }
     
    7478        Expression * set_extension( bool exten ) { extension = exten; return this; }
    7579
    76         InferredParams & get_inferParams() { return inferParams; }
    77 
    7880        // move other's inferParams to this
    7981        void spliceInferParams( Expression * other );
     
    8183        virtual Expression * clone() const override = 0;
    8284        virtual void accept( Visitor & v ) override = 0;
     85        virtual void accept( Visitor & v ) const override = 0;
    8386        virtual Expression * acceptMutator( Mutator & m ) override = 0;
    8487        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     
    9699        virtual ~ApplicationExpr();
    97100
     101        bool get_lvalue() const final;
     102
    98103        Expression * get_function() const { return function; }
    99104        void set_function( Expression * newValue ) { function = newValue; }
    100105        std::list<Expression *>& get_args() { return args; }
    101106
    102         virtual ApplicationExpr * clone() const { return new ApplicationExpr( * this ); }
    103         virtual void accept( Visitor & v ) { v.visit( this ); }
    104         virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    105         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     107        virtual ApplicationExpr * clone() const override { return new ApplicationExpr( * this ); }
     108        virtual void accept( Visitor & v ) override { v.visit( this ); }
     109        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     110        virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
     111        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    106112};
    107113
     
    118124        virtual ~UntypedExpr();
    119125
     126        bool get_lvalue() const final;
     127
    120128        Expression * get_function() const { return function; }
    121129        void set_function( Expression * newValue ) { function = newValue; }
     
    128136        static UntypedExpr * createAssign( Expression * arg1, Expression * arg2 );
    129137
    130         virtual UntypedExpr * clone() const { return new UntypedExpr( * this ); }
    131         virtual void accept( Visitor & v ) { v.visit( this ); }
    132         virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    133         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     138        virtual UntypedExpr * clone() const override { return new UntypedExpr( * this ); }
     139        virtual void accept( Visitor & v ) override { v.visit( this ); }
     140        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     141        virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
     142        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    134143};
    135144
     
    146155        void set_name( std::string newValue ) { name = newValue; }
    147156
    148         virtual NameExpr * clone() const { return new NameExpr( * this ); }
    149         virtual void accept( Visitor & v ) { v.visit( this ); }
    150         virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    151         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     157        virtual NameExpr * clone() const override { return new NameExpr( * this ); }
     158        virtual void accept( Visitor & v ) override { v.visit( this ); }
     159        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     160        virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
     161        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    152162};
    153163
     
    167177        void set_arg(Expression * newValue ) { arg = newValue; }
    168178
    169         virtual AddressExpr * clone() const { return new AddressExpr( * this ); }
    170         virtual void accept( Visitor & v ) { v.visit( this ); }
    171         virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    172         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     179        virtual AddressExpr * clone() const override { return new AddressExpr( * this ); }
     180        virtual void accept( Visitor & v ) override { v.visit( this ); }
     181        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     182        virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
     183        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    173184};
    174185
     
    183194        virtual ~LabelAddressExpr();
    184195
    185         virtual LabelAddressExpr * clone() const { return new LabelAddressExpr( * this ); }
    186         virtual void accept( Visitor & v ) { v.visit( this ); }
    187         virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    188         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     196        virtual LabelAddressExpr * clone() const override { return new LabelAddressExpr( * this ); }
     197        virtual void accept( Visitor & v ) override { v.visit( this ); }
     198        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     199        virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
     200        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    189201};
    190202
     
    193205  public:
    194206        Expression * arg;
    195         bool isGenerated = true; // whether this cast appeared in the source program
     207        bool isGenerated = true; // cast generated implicitly by code generation or explicit in program
    196208
    197209        CastExpr( Expression * arg, bool isGenerated = true );
     
    201213        virtual ~CastExpr();
    202214
     215        bool get_lvalue() const final;
     216
    203217        Expression * get_arg() const { return arg; }
    204218        void set_arg( Expression * newValue ) { arg = newValue; }
    205219
    206         virtual CastExpr * clone() const { return new CastExpr( * this ); }
    207         virtual void accept( Visitor & v ) { v.visit( this ); }
    208         virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    209         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     220        virtual CastExpr * clone() const override { return new CastExpr( * this ); }
     221        virtual void accept( Visitor & v ) override { v.visit( this ); }
     222        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     223        virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
     224        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    210225};
    211226
     
    224239        const std::string & targetString() const;
    225240
    226         virtual KeywordCastExpr * clone() const { return new KeywordCastExpr( * this ); }
    227         virtual void accept( Visitor & v ) { v.visit( this ); }
    228         virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    229         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     241        virtual KeywordCastExpr * clone() const override { return new KeywordCastExpr( * this ); }
     242        virtual void accept( Visitor & v ) override { v.visit( this ); }
     243        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     244        virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
     245        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    230246};
    231247
     
    242258        void set_arg( Expression * newValue ) { arg = newValue; }
    243259
    244         virtual VirtualCastExpr * clone() const { return new VirtualCastExpr( * this ); }
    245         virtual void accept( Visitor & v ) { v.visit( this ); }
    246         virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    247         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     260        virtual VirtualCastExpr * clone() const override { return new VirtualCastExpr( * this ); }
     261        virtual void accept( Visitor & v ) override { v.visit( this ); }
     262        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     263        virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
     264        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    248265};
    249266
     
    257274        UntypedMemberExpr( const UntypedMemberExpr & other );
    258275        virtual ~UntypedMemberExpr();
     276
     277        bool get_lvalue() const final;
    259278
    260279        Expression * get_member() const { return member; }
     
    263282        void set_aggregate( Expression * newValue ) { aggregate = newValue; }
    264283
    265         virtual UntypedMemberExpr * clone() const { return new UntypedMemberExpr( * this ); }
    266         virtual void accept( Visitor & v ) { v.visit( this ); }
    267         virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    268         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     284        virtual UntypedMemberExpr * clone() const override { return new UntypedMemberExpr( * this ); }
     285        virtual void accept( Visitor & v ) override { v.visit( this ); }
     286        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     287        virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
     288        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    269289};
    270290
     
    279299        MemberExpr( const MemberExpr & other );
    280300        virtual ~MemberExpr();
     301
     302        bool get_lvalue() const final;
    281303
    282304        DeclarationWithType * get_member() const { return member; }
     
    285307        void set_aggregate( Expression * newValue ) { aggregate = newValue; }
    286308
    287         virtual MemberExpr * clone() const { return new MemberExpr( * this ); }
    288         virtual void accept( Visitor & v ) { v.visit( this ); }
    289         virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    290         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     309        virtual MemberExpr * clone() const override { return new MemberExpr( * this ); }
     310        virtual void accept( Visitor & v ) override { v.visit( this ); }
     311        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     312        virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
     313        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    291314};
    292315
     
    297320        DeclarationWithType * var;
    298321
     322        VariableExpr();
    299323        VariableExpr( DeclarationWithType * var );
    300324        VariableExpr( const VariableExpr & other );
    301325        virtual ~VariableExpr();
    302326
     327        bool get_lvalue() const final;
     328
    303329        DeclarationWithType * get_var() const { return var; }
    304330        void set_var( DeclarationWithType * newValue ) { var = newValue; }
     
    306332        static VariableExpr * functionPointer( FunctionDecl * decl );
    307333
    308         virtual VariableExpr * clone() const { return new VariableExpr( * this ); }
    309         virtual void accept( Visitor & v ) { v.visit( this ); }
    310         virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    311         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     334        virtual VariableExpr * clone() const override { return new VariableExpr( * this ); }
     335        virtual void accept( Visitor & v ) override { v.visit( this ); }
     336        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     337        virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
     338        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    312339};
    313340
     
    327354        long long int intValue() const;
    328355
    329         virtual ConstantExpr * clone() const { return new ConstantExpr( * this ); }
    330         virtual void accept( Visitor & v ) { v.visit( this ); }
    331         virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    332         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     356        virtual ConstantExpr * clone() const override { return new ConstantExpr( * this ); }
     357        virtual void accept( Visitor & v ) override { v.visit( this ); }
     358        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     359        virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
     360        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    333361};
    334362
     
    352380        void set_isType( bool newValue ) { isType = newValue; }
    353381
    354         virtual SizeofExpr * clone() const { return new SizeofExpr( * this ); }
    355         virtual void accept( Visitor & v ) { v.visit( this ); }
    356         virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    357         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     382        virtual SizeofExpr * clone() const override { return new SizeofExpr( * this ); }
     383        virtual void accept( Visitor & v ) override { v.visit( this ); }
     384        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     385        virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
     386        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    358387};
    359388
     
    377406        void set_isType( bool newValue ) { isType = newValue; }
    378407
    379         virtual AlignofExpr * clone() const { return new AlignofExpr( * this ); }
    380         virtual void accept( Visitor & v ) { v.visit( this ); }
    381         virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    382         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     408        virtual AlignofExpr * clone() const override { return new AlignofExpr( * this ); }
     409        virtual void accept( Visitor & v ) override { v.visit( this ); }
     410        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     411        virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
     412        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    383413};
    384414
     
    398428        void set_type( Type * newValue ) { type = newValue; }
    399429
    400         virtual UntypedOffsetofExpr * clone() const { return new UntypedOffsetofExpr( * this ); }
    401         virtual void accept( Visitor & v ) { v.visit( this ); }
    402         virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    403         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     430        virtual UntypedOffsetofExpr * clone() const override { return new UntypedOffsetofExpr( * this ); }
     431        virtual void accept( Visitor & v ) override { v.visit( this ); }
     432        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     433        virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
     434        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    404435};
    405436
     
    419450        void set_member( DeclarationWithType * newValue ) { member = newValue; }
    420451
    421         virtual OffsetofExpr * clone() const { return new OffsetofExpr( * this ); }
    422         virtual void accept( Visitor & v ) { v.visit( this ); }
    423         virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    424         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     452        virtual OffsetofExpr * clone() const override { return new OffsetofExpr( * this ); }
     453        virtual void accept( Visitor & v ) override { v.visit( this ); }
     454        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     455        virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
     456        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    425457};
    426458
     
    437469        void set_type( StructInstType * newValue ) { type = newValue; }
    438470
    439         virtual OffsetPackExpr * clone() const { return new OffsetPackExpr( * this ); }
    440         virtual void accept( Visitor & v ) { v.visit( this ); }
    441         virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    442         virtual void print( std::ostream & os, Indenter indent = {} ) const;
    443 };
    444 
    445 /// AttrExpr represents an @attribute expression (like sizeof, but user-defined)
    446 class AttrExpr : public Expression {
    447   public:
    448         Expression * attr;
    449         Expression * expr;
    450         Type * type;
    451         bool isType;
    452 
    453         AttrExpr(Expression * attr, Expression * expr );
    454         AttrExpr( const AttrExpr & other );
    455         AttrExpr( Expression * attr, Type * type );
    456         virtual ~AttrExpr();
    457 
    458         Expression * get_attr() const { return attr; }
    459         void set_attr( Expression * newValue ) { attr = newValue; }
    460         Expression * get_expr() const { return expr; }
    461         void set_expr( Expression * newValue ) { expr = newValue; }
    462         Type * get_type() const { return type; }
    463         void set_type( Type * newValue ) { type = newValue; }
    464         bool get_isType() const { return isType; }
    465         void set_isType( bool newValue ) { isType = newValue; }
    466 
    467         virtual AttrExpr * clone() const { return new AttrExpr( * this ); }
    468         virtual void accept( Visitor & v ) { v.visit( this ); }
    469         virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    470         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     471        virtual OffsetPackExpr * clone() const override { return new OffsetPackExpr( * this ); }
     472        virtual void accept( Visitor & v ) override { v.visit( this ); }
     473        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     474        virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
     475        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    471476};
    472477
     
    487492        void set_arg2( Expression * newValue ) { arg2 = newValue; }
    488493
    489         virtual LogicalExpr * clone() const { return new LogicalExpr( * this ); }
    490         virtual void accept( Visitor & v ) { v.visit( this ); }
    491         virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    492         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     494        virtual LogicalExpr * clone() const override { return new LogicalExpr( * this ); }
     495        virtual void accept( Visitor & v ) override { v.visit( this ); }
     496        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     497        virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
     498        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    493499
    494500  private:
     
    506512        ConditionalExpr( const ConditionalExpr & other );
    507513        virtual ~ConditionalExpr();
     514
     515        bool get_lvalue() const final;
    508516
    509517        Expression * get_arg1() const { return arg1; }
     
    514522        void set_arg3( Expression * newValue ) { arg3 = newValue; }
    515523
    516         virtual ConditionalExpr * clone() const { return new ConditionalExpr( * this ); }
    517         virtual void accept( Visitor & v ) { v.visit( this ); }
    518         virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    519         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     524        virtual ConditionalExpr * clone() const override { return new ConditionalExpr( * this ); }
     525        virtual void accept( Visitor & v ) override { v.visit( this ); }
     526        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     527        virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
     528        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    520529};
    521530
     
    529538        CommaExpr( const CommaExpr & other );
    530539        virtual ~CommaExpr();
     540
     541        bool get_lvalue() const final;
    531542
    532543        Expression * get_arg1() const { return arg1; }
     
    535546        void set_arg2( Expression * newValue ) { arg2 = newValue; }
    536547
    537         virtual CommaExpr * clone() const { return new CommaExpr( * this ); }
    538         virtual void accept( Visitor & v ) { v.visit( this ); }
    539         virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    540         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     548        virtual CommaExpr * clone() const override { return new CommaExpr( * this ); }
     549        virtual void accept( Visitor & v ) override { v.visit( this ); }
     550        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     551        virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
     552        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    541553};
    542554
     
    553565        void set_type( Type * newValue ) { type = newValue; }
    554566
    555         virtual TypeExpr * clone() const { return new TypeExpr( * this ); }
    556         virtual void accept( Visitor & v ) { v.visit( this ); }
    557         virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    558         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     567        virtual TypeExpr * clone() const override { return new TypeExpr( * this ); }
     568        virtual void accept( Visitor & v ) override { v.visit( this ); }
     569        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     570        virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
     571        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    559572};
    560573
     
    579592        void set_operand( Expression * newValue ) { operand = newValue; }
    580593
    581         virtual AsmExpr * clone() const { return new AsmExpr( * this ); }
    582         virtual void accept( Visitor & v ) { v.visit( this ); }
    583         virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    584         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     594        virtual AsmExpr * clone() const override { return new AsmExpr( * this ); }
     595        virtual void accept( Visitor & v ) override { v.visit( this ); }
     596        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     597        virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
     598        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    585599
    586600        // https://gcc.gnu.org/onlinedocs/gcc-4.7.1/gcc/Machine-Constraints.html#Machine-Constraints
     
    591605class ImplicitCopyCtorExpr : public Expression {
    592606public:
    593         ApplicationExpr * callExpr;
    594         std::list< ObjectDecl * > tempDecls;
    595         std::list< ObjectDecl * > returnDecls;
    596         std::list< Expression * > dtors;
     607        ApplicationExpr * callExpr = nullptr;
    597608
    598609        ImplicitCopyCtorExpr( ApplicationExpr * callExpr );
     
    600611        virtual ~ImplicitCopyCtorExpr();
    601612
    602         ApplicationExpr * get_callExpr() const { return callExpr; }
    603         void set_callExpr( ApplicationExpr * newValue ) { callExpr = newValue; }
    604 
    605         std::list< ObjectDecl * > & get_tempDecls() { return tempDecls; }
    606         std::list< ObjectDecl * > & get_returnDecls() { return returnDecls; }
    607         std::list< Expression * > & get_dtors() { return dtors; }
    608 
    609         virtual ImplicitCopyCtorExpr * clone() const { return new ImplicitCopyCtorExpr( * this ); }
    610         virtual void accept( Visitor & v ) { v.visit( this ); }
    611         virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    612         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     613        virtual ImplicitCopyCtorExpr * clone() const override { return new ImplicitCopyCtorExpr( * this ); }
     614        virtual void accept( Visitor & v ) override { v.visit( this ); }
     615        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     616        virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
     617        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    613618};
    614619
     
    622627        ~ConstructorExpr();
    623628
     629        bool get_lvalue() const final;
     630
    624631        Expression * get_callExpr() const { return callExpr; }
    625632        void set_callExpr( Expression * newValue ) { callExpr = newValue; }
    626633
    627         virtual ConstructorExpr * clone() const { return new ConstructorExpr( * this ); }
    628         virtual void accept( Visitor & v ) { v.visit( this ); }
    629         virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    630         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     634        virtual ConstructorExpr * clone() const override { return new ConstructorExpr( * this ); }
     635        virtual void accept( Visitor & v ) override { v.visit( this ); }
     636        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     637        virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
     638        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    631639};
    632640
     
    640648        virtual ~CompoundLiteralExpr();
    641649
     650        bool get_lvalue() const final;
     651
    642652        Initializer * get_initializer() const { return initializer; }
    643653        void set_initializer( Initializer * i ) { initializer = i; }
    644654
    645         virtual CompoundLiteralExpr * clone() const { return new CompoundLiteralExpr( * this ); }
    646         virtual void accept( Visitor & v ) { v.visit( this ); }
    647         virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    648         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     655        virtual CompoundLiteralExpr * clone() const override { return new CompoundLiteralExpr( * this ); }
     656        virtual void accept( Visitor & v ) override { v.visit( this ); }
     657        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     658        virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
     659        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    649660};
    650661
     
    662673        RangeExpr * set_high( Expression * high ) { RangeExpr::high = high; return this; }
    663674
    664         virtual RangeExpr * clone() const { return new RangeExpr( * this ); }
    665         virtual void accept( Visitor & v ) { v.visit( this ); }
    666         virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    667         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     675        virtual RangeExpr * clone() const override { return new RangeExpr( * this ); }
     676        virtual void accept( Visitor & v ) override { v.visit( this ); }
     677        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     678        virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
     679        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    668680};
    669681
     
    679691        std::list<Expression*>& get_exprs() { return exprs; }
    680692
    681         virtual UntypedTupleExpr * clone() const { return new UntypedTupleExpr( * this ); }
    682         virtual void accept( Visitor & v ) { v.visit( this ); }
    683         virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    684         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     693        virtual UntypedTupleExpr * clone() const override { return new UntypedTupleExpr( * this ); }
     694        virtual void accept( Visitor & v ) override { v.visit( this ); }
     695        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     696        virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
     697        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    685698};
    686699
     
    694707        virtual ~TupleExpr();
    695708
     709        bool get_lvalue() const final;
     710
    696711        std::list<Expression*>& get_exprs() { return exprs; }
    697712
    698         virtual TupleExpr * clone() const { return new TupleExpr( * this ); }
    699         virtual void accept( Visitor & v ) { v.visit( this ); }
    700         virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    701         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     713        virtual TupleExpr * clone() const override { return new TupleExpr( * this ); }
     714        virtual void accept( Visitor & v ) override { v.visit( this ); }
     715        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     716        virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
     717        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    702718};
    703719
     
    711727        TupleIndexExpr( const TupleIndexExpr & other );
    712728        virtual ~TupleIndexExpr();
     729
     730        bool get_lvalue() const final;
    713731
    714732        Expression * get_tuple() const { return tuple; }
     
    717735        TupleIndexExpr * set_index( unsigned int newValue ) { index = newValue; return this; }
    718736
    719         virtual TupleIndexExpr * clone() const { return new TupleIndexExpr( * this ); }
    720         virtual void accept( Visitor & v ) { v.visit( this ); }
    721         virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    722         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     737        virtual TupleIndexExpr * clone() const override { return new TupleIndexExpr( * this ); }
     738        virtual void accept( Visitor & v ) override { v.visit( this ); }
     739        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     740        virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
     741        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    723742};
    724743
     
    735754        StmtExpr * get_stmtExpr() const { return stmtExpr; }
    736755
    737         virtual TupleAssignExpr * clone() const { return new TupleAssignExpr( * this ); }
    738         virtual void accept( Visitor & v ) { v.visit( this ); }
    739         virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    740         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     756        virtual TupleAssignExpr * clone() const override { return new TupleAssignExpr( * this ); }
     757        virtual void accept( Visitor & v ) override { v.visit( this ); }
     758        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     759        virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
     760        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     761
     762        friend class ConverterNewToOld;
     763  private:
     764    TupleAssignExpr( StmtExpr * stmts );
    741765};
    742766
     
    748772        std::list< Expression * > dtors; // destructor(s) for return variable(s)
    749773
     774        // readonly
     775        ExprStmt * resultExpr = nullptr;
     776
    750777        StmtExpr( CompoundStmt * statements );
    751778        StmtExpr( const StmtExpr & other );
    752779        virtual ~StmtExpr();
    753780
     781        bool get_lvalue() const final;
     782
    754783        CompoundStmt * get_statements() const { return statements; }
    755784        StmtExpr * set_statements( CompoundStmt * newValue ) { statements = newValue; return this; }
     
    761790        std::list< Expression * > & get_dtors() { return dtors; }
    762791
    763         virtual StmtExpr * clone() const { return new StmtExpr( * this ); }
    764         virtual void accept( Visitor & v ) { v.visit( this ); }
    765         virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    766         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     792        virtual StmtExpr * clone() const override { return new StmtExpr( * this ); }
     793        virtual void accept( Visitor & v ) override { v.visit( this ); }
     794        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     795        virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
     796        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    767797};
    768798
     
    788818        int get_id() const { return id; }
    789819
    790         virtual UniqueExpr * clone() const { return new UniqueExpr( * this ); }
    791         virtual void accept( Visitor & v ) { v.visit( this ); }
    792         virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    793         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     820        virtual UniqueExpr * clone() const override { return new UniqueExpr( * this ); }
     821        virtual void accept( Visitor & v ) override { v.visit( this ); }
     822        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     823        virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
     824        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    794825
    795826private:
     
    822853        std::list<InitAlternative> & get_initAlts() { return initAlts; }
    823854
    824         virtual UntypedInitExpr * clone() const { return new UntypedInitExpr( * this ); }
    825         virtual void accept( Visitor & v ) { v.visit( this ); }
    826         virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    827         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     855        virtual UntypedInitExpr * clone() const override { return new UntypedInitExpr( * this ); }
     856        virtual void accept( Visitor & v ) override { v.visit( this ); }
     857        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     858        virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
     859        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    828860};
    829861
     
    843875        InitExpr * set_designation( Designation * newValue ) { designation = newValue; return this; }
    844876
    845         virtual InitExpr * clone() const { return new InitExpr( * this ); }
    846         virtual void accept( Visitor & v ) { v.visit( this ); }
    847         virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    848         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     877        virtual InitExpr * clone() const override { return new InitExpr( * this ); }
     878        virtual void accept( Visitor & v ) override { v.visit( this ); }
     879        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     880        virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
     881        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    849882};
    850883
     
    853886public:
    854887        Expression * expr;
    855         BaseSyntaxNode * deleteStmt;
    856 
    857         DeletedExpr( Expression * expr, BaseSyntaxNode * deleteStmt );
     888        Declaration * deleteStmt;
     889
     890        DeletedExpr( Expression * expr, Declaration * deleteStmt );
    858891        DeletedExpr( const DeletedExpr & other );
    859892        ~DeletedExpr();
    860893
    861         virtual DeletedExpr * clone() const { return new DeletedExpr( * this ); }
    862         virtual void accept( Visitor & v ) { v.visit( this ); }
    863         virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    864         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     894        virtual DeletedExpr * clone() const override { return new DeletedExpr( * this ); }
     895        virtual void accept( Visitor & v ) override { v.visit( this ); }
     896        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     897        virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
     898        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     899};
     900
     901/// expression wrapping the use of a default argument - should never make it past the resolver.
     902class DefaultArgExpr : public Expression {
     903public:
     904        Expression * expr;
     905
     906        DefaultArgExpr( Expression * expr );
     907        DefaultArgExpr( const DefaultArgExpr & other );
     908        ~DefaultArgExpr();
     909
     910        virtual DefaultArgExpr * clone() const override { return new DefaultArgExpr( * this ); }
     911        virtual void accept( Visitor & v ) override { v.visit( this ); }
     912        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     913        virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
     914        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    865915};
    866916
     
    887937        virtual ~GenericExpr();
    888938
    889         virtual GenericExpr * clone() const { return new GenericExpr( * this ); }
    890         virtual void accept( Visitor & v ) { v.visit( this ); }
    891         virtual Expression * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    892         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     939        virtual GenericExpr * clone() const override { return new GenericExpr( * this ); }
     940        virtual void accept( Visitor & v ) override { v.visit( this ); }
     941        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     942        virtual Expression * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
     943        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    893944};
    894945
  • src/SynTree/FunctionDecl.cc

    r7951100 rb067d9b  
    8787
    8888        if ( statements ) {
    89                 os << indent << "... with body " << endl << indent+1;
     89                os << indent << "... with body" << endl << indent+1;
    9090                statements->print( os, indent+1 );
    9191        } // if
  • src/SynTree/FunctionType.cc

    r7951100 rb067d9b  
    6666                os << indent+1 << "accepting unspecified arguments" << endl;
    6767        } // if
    68         os << indent << "... returning ";
     68        os << indent << "... returning";
    6969        if ( returnVals.empty() ) {
    70                 os << "nothing " << endl;
     70                os << " nothing" << endl;
    7171        } else {
    7272                os << endl;
  • src/SynTree/Initializer.h

    r7951100 rb067d9b  
    3838
    3939        virtual Designation * clone() const override { return new Designation( *this ); };
    40         virtual void accept( Visitor &v ) override { v.visit( this ); }
     40        virtual void accept( Visitor & v ) override { v.visit( this ); }
     41        virtual void accept( Visitor & v ) const override { v.visit( this ); }
    4142        virtual Designation * acceptMutator( Mutator &m ) override { return m.mutate( this ); }
    4243        virtual void print( std::ostream &os, Indenter indent = {} ) const override;
     
    5253        virtual ~Initializer();
    5354
    54         bool get_maybeConstructed() { return maybeConstructed; }
     55        bool get_maybeConstructed() const { return maybeConstructed; }
    5556
    5657        virtual Initializer *clone() const override = 0;
    57         virtual void accept( Visitor &v ) override = 0;
     58        virtual void accept( Visitor & v ) override = 0;
     59        virtual void accept( Visitor & v ) const override = 0;
    5860        virtual Initializer *acceptMutator( Mutator &m ) override = 0;
    5961        virtual void print( std::ostream &os, Indenter indent = {} ) const override = 0;
     
    7678
    7779        virtual SingleInit *clone() const override { return new SingleInit( *this); }
    78         virtual void accept( Visitor &v ) override { v.visit( this ); }
     80        virtual void accept( Visitor & v ) override { v.visit( this ); }
     81        virtual void accept( Visitor & v ) const override { v.visit( this ); }
    7982        virtual Initializer *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    8083        virtual void print( std::ostream &os, Indenter indent = {} ) const override;
     
    104107
    105108        virtual ListInit *clone() const override { return new ListInit( *this ); }
    106         virtual void accept( Visitor &v ) override { v.visit( this ); }
     109        virtual void accept( Visitor & v ) override { v.visit( this ); }
     110        virtual void accept( Visitor & v ) const override { v.visit( this ); }
    107111        virtual Initializer *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    108112        virtual void print( std::ostream &os, Indenter indent = {} ) const override;
     
    133137
    134138        ConstructorInit *clone() const override { return new ConstructorInit( *this ); }
    135         virtual void accept( Visitor &v ) override { v.visit( this ); }
     139        virtual void accept( Visitor & v ) override { v.visit( this ); }
     140        virtual void accept( Visitor & v ) const override { v.visit( this ); }
    136141        virtual Initializer *acceptMutator( Mutator &m )  override { return m.mutate( this ); }
    137142        virtual void print( std::ostream &os, Indenter indent = {} ) const override;
  • src/SynTree/Label.h

    r7951100 rb067d9b  
    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

    r7951100 rb067d9b  
    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 : Mon Jul 24 16:31:00 2017
    13 // Update Count     : 16
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Thu Jul 25 22:37:46 2019
     13// Update Count     : 17
    1414//
    1515#pragma once
     
    5252        virtual Statement * mutate( FinallyStmt * catchStmt ) = 0;
    5353        virtual Statement * mutate( WaitForStmt * waitforStmt ) = 0;
    54         virtual Statement * mutate( WithStmt * withStmt ) = 0;
     54        virtual Declaration * mutate( WithStmt * withStmt ) = 0;
    5555        virtual NullStmt * mutate( NullStmt * nullStmt ) = 0;
    5656        virtual Statement * mutate( DeclStmt * declStmt ) = 0;
     
    7474        virtual Expression * mutate( OffsetofExpr * offsetofExpr ) = 0;
    7575        virtual Expression * mutate( OffsetPackExpr * offsetPackExpr ) = 0;
    76         virtual Expression * mutate( AttrExpr * attrExpr ) = 0;
    7776        virtual Expression * mutate( LogicalExpr * logicalExpr ) = 0;
    7877        virtual Expression * mutate( ConditionalExpr * conditionalExpr ) = 0;
     
    9392        virtual Expression * mutate( InitExpr  * initExpr ) = 0;
    9493        virtual Expression * mutate( DeletedExpr * delExpr ) = 0;
     94        virtual Expression * mutate( DefaultArgExpr * argExpr ) = 0;
    9595        virtual Expression * mutate( GenericExpr * genExpr ) = 0;
    9696
     
    100100        virtual Type * mutate( ArrayType * arrayType ) = 0;
    101101        virtual Type * mutate( ReferenceType * refType ) = 0;
     102        virtual Type * mutate( QualifiedType * qualType ) = 0;
    102103        virtual Type * mutate( FunctionType * functionType ) = 0;
    103104        virtual Type * mutate( StructInstType * aggregateUseType ) = 0;
     
    112113        virtual Type * mutate( ZeroType * zeroType ) = 0;
    113114        virtual Type * mutate( OneType * oneType ) = 0;
     115        virtual Type * mutate( GlobalScopeType * globalType ) = 0;
    114116
    115117        virtual Designation * mutate( Designation * designation ) = 0 ;
     
    117119        virtual Initializer * mutate( ListInit * listInit ) = 0 ;
    118120        virtual Initializer * mutate( ConstructorInit * ctorInit ) = 0 ;
    119 
    120         virtual Subrange * mutate( Subrange * subrange ) = 0;
    121121
    122122        virtual Constant * mutate( Constant * constant ) = 0;
  • src/SynTree/ObjectDecl.cc

    r7951100 rb067d9b  
    6666
    6767        if ( ! attributes.empty() ) {
    68                 os << std::endl << indent << "... with attributes: " << std::endl;
     68                os << std::endl << indent << "... with attributes:" << std::endl;
    6969                printAll( attributes, os, indent+1 );
    7070        }
  • src/SynTree/ReferenceToType.cc

    r7951100 rb067d9b  
    7676bool StructInstType::isComplete() const { return baseStruct ? baseStruct->has_body() : false; }
    7777
    78 AggregateDecl * StructInstType::getAggr() { return baseStruct; }
     78AggregateDecl * StructInstType::getAggr() const { return baseStruct; }
    7979
    8080TypeSubstitution StructInstType::genericSubstitution() const {
     
    9393        else {
    9494                Type::print( os, indent );
    95                 os << "instance of " << typeString() << " " << name << " with body " << baseStruct->has_body() << " ";
     95                os << "instance of " << typeString() << " " << name << " with body " << baseStruct->has_body();
    9696                if ( ! parameters.empty() ) {
    9797                        os << endl << indent << "... with parameters" << endl;
     
    119119bool UnionInstType::isComplete() const { return baseUnion ? baseUnion->has_body() : false; }
    120120
    121 AggregateDecl * UnionInstType::getAggr() { return baseUnion; }
     121AggregateDecl * UnionInstType::getAggr() const { return baseUnion; }
    122122
    123123TypeSubstitution UnionInstType::genericSubstitution() const {
     
    136136        else {
    137137                Type::print( os, indent );
    138                 os << "instance of " << typeString() << " " << name << " with body " << baseUnion->has_body() << " ";
     138                os << "instance of " << typeString() << " " << name << " with body " << baseUnion->has_body();
    139139                if ( ! parameters.empty() ) {
    140140                        os << endl << indent << "... with parameters" << endl;
     
    152152bool EnumInstType::isComplete() const { return baseEnum ? baseEnum->has_body() : false; }
    153153
     154AggregateDecl * EnumInstType::getAggr() const { return baseEnum; }
     155
    154156void EnumInstType::print( std::ostream &os, Indenter indent ) const {
    155157        using std::endl;
     
    158160        else {
    159161                Type::print( os, indent );
    160                 os << "instance of " << typeString() << " " << name << " with body " << baseEnum->has_body() << " ";
     162                os << "instance of " << typeString() << " " << name << " with body " << baseEnum->has_body();
    161163        } // if
    162164}
     
    203205
    204206        Type::print( os, indent );
    205         os << "instance of " << typeString() << " " << get_name() << " (" << ( isFtype ? "" : "not" ) << " function type) ";
     207        os << "instance of " << typeString() << " " << get_name() << " (" << ( isFtype ? "" : "not" ) << " function type)";
    206208        if ( ! parameters.empty() ) {
    207209                os << endl << indent << "... with parameters" << endl;
  • src/SynTree/Statement.cc

    r7951100 rb067d9b  
    493493
    494494
    495 WithStmt::WithStmt( const std::list< Expression * > & exprs, Statement * stmt ) : Statement(), exprs( exprs ), stmt( stmt ) {}
    496 WithStmt::WithStmt( const WithStmt & other ) : Statement( other ), stmt( maybeClone( other.stmt ) ) {
     495WithStmt::WithStmt( const std::list< Expression * > & exprs, Statement * stmt ) : Declaration("", noStorageClasses, LinkageSpec::Cforall), exprs( exprs ), stmt( stmt ) {}
     496WithStmt::WithStmt( const WithStmt & other ) : Declaration( other ), stmt( maybeClone( other.stmt ) ) {
    497497        cloneAll( other.exprs, exprs );
    498498}
  • src/SynTree/Statement.h

    r7951100 rb067d9b  
    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 void accept( Visitor & v ) const override = 0;
     48        virtual Statement * acceptMutator( Mutator & m ) override = 0;
     49        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    4950};
    5051
     
    5556        CompoundStmt();
    5657        CompoundStmt( std::list<Statement *> stmts );
    57         CompoundStmt( const CompoundStmt &other );
     58        CompoundStmt( const CompoundStmt & other );
    5859        virtual ~CompoundStmt();
    5960
     
    6263        void push_front( Statement * stmt ) { kids.push_front( stmt ); }
    6364
    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;
     65        virtual CompoundStmt * clone() const override { return new CompoundStmt( *this ); }
     66        virtual void accept( Visitor & v ) override { v.visit( this ); }
     67        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     68        virtual CompoundStmt * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
     69        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    6870};
    6971
     
    7274        NullStmt( const std::list<Label> & labels = {} );
    7375
    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;
     76        virtual NullStmt * clone() const override { return new NullStmt( *this ); }
     77        virtual void accept( Visitor & v ) override { v.visit( this ); }
     78        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     79        virtual NullStmt * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
     80        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    7881};
    7982
    8083class ExprStmt : public Statement {
    8184  public:
    82         Expression *expr;
    83 
    84         ExprStmt( Expression *expr );
    85         ExprStmt( const ExprStmt &other );
     85        Expression * expr;
     86
     87        ExprStmt( Expression * expr );
     88        ExprStmt( const ExprStmt & other );
    8689        virtual ~ExprStmt();
    8790
    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;
     91        Expression * get_expr() { return expr; }
     92        void set_expr( Expression * newValue ) { expr = newValue; }
     93
     94        virtual ExprStmt * clone() const override { return new ExprStmt( *this ); }
     95        virtual void accept( Visitor & v ) override { v.visit( this ); }
     96        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     97        virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
     98        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    9599};
    96100
     
    98102  public:
    99103        bool voltile;
    100         Expression *instruction;
     104        Expression * instruction;
    101105        std::list<Expression *> output, input;
    102106        std::list<ConstantExpr *> clobber;
    103107        std::list<Label> gotolabels;
    104108
    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 );
     109        AsmStmt( bool voltile, Expression * instruction, std::list<Expression *> output, std::list<Expression *> input, std::list<ConstantExpr *> clobber, std::list<Label> gotolabels );
     110        AsmStmt( const AsmStmt & other );
    107111        virtual ~AsmStmt();
    108112
     
    114118        void set_output( const std::list<Expression *> & newValue ) { output = newValue; }
    115119        std::list<Expression *> & get_input() { return input; }
    116         void set_input( const std::list<Expression *> &newValue ) { input = newValue; }
     120        void set_input( const std::list<Expression *> & newValue ) { input = newValue; }
    117121        std::list<ConstantExpr *> & get_clobber() { return clobber; }
    118         void set_clobber( const std::list<ConstantExpr *> &newValue ) { clobber = newValue; }
     122        void set_clobber( const std::list<ConstantExpr *> & newValue ) { clobber = newValue; }
    119123        std::list<Label> & get_gotolabels() { return gotolabels; }
    120         void set_gotolabels( const std::list<Label> &newValue ) { gotolabels = newValue; }
    121 
    122         virtual AsmStmt * clone() const { return new AsmStmt( *this ); }
    123         virtual void accept( Visitor & v ) { v.visit( this ); }
    124         virtual Statement * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    125         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     124        void set_gotolabels( const std::list<Label> & newValue ) { gotolabels = newValue; }
     125
     126        virtual AsmStmt * clone() const override { return new AsmStmt( *this ); }
     127        virtual void accept( Visitor & v ) override { v.visit( this ); }
     128        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     129        virtual Statement * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
     130        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    126131};
    127132
     
    133138        virtual ~DirectiveStmt(){}
    134139
    135         virtual DirectiveStmt * clone() const { return new DirectiveStmt( *this ); }
    136         virtual void accept( Visitor & v ) { v.visit( this ); }
    137         virtual Statement * acceptMutator( Mutator & m ) { return m.mutate( this ); }
    138         virtual void print( std::ostream & os, Indenter indent = {} ) const;
     140        virtual DirectiveStmt * clone() const override { return new DirectiveStmt( *this ); }
     141        virtual void accept( Visitor & v ) override { v.visit( this ); }
     142        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     143        virtual Statement * acceptMutator( Mutator & m ) override { return m.mutate( this ); }
     144        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    139145};
    140146
    141147class IfStmt : public Statement {
    142148  public:
    143         Expression *condition;
    144         Statement *thenPart;
    145         Statement *elsePart;
     149        Expression * condition;
     150        Statement * thenPart;
     151        Statement * elsePart;
    146152        std::list<Statement *> initialization;
    147153
    148         IfStmt( Expression *condition, Statement *thenPart, Statement *elsePart,
     154        IfStmt( Expression * condition, Statement * thenPart, Statement * elsePart,
    149155                        std::list<Statement *> initialization = std::list<Statement *>() );
    150         IfStmt( const IfStmt &other );
     156        IfStmt( const IfStmt & other );
    151157        virtual ~IfStmt();
    152158
    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;
     159        std::list<Statement *> & get_initialization() { return initialization; }
     160        Expression * get_condition() { return condition; }
     161        void set_condition( Expression * newValue ) { condition = newValue; }
     162        Statement * get_thenPart() { return thenPart; }
     163        void set_thenPart( Statement * newValue ) { thenPart = newValue; }
     164        Statement * get_elsePart() { return elsePart; }
     165        void set_elsePart( Statement * newValue ) { elsePart = newValue; }
     166
     167        virtual IfStmt * clone() const override { return new IfStmt( *this ); }
     168        virtual void accept( Visitor & v ) override { v.visit( this ); }
     169        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     170        virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
     171        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    165172};
    166173
     
    170177        std::list<Statement *> statements;
    171178
    172         SwitchStmt( Expression *condition, const std::list<Statement *> &statements );
    173         SwitchStmt( const SwitchStmt &other );
     179        SwitchStmt( Expression * condition, const std::list<Statement *> & statements );
     180        SwitchStmt( const SwitchStmt & other );
    174181        virtual ~SwitchStmt();
    175182
    176         Expression *get_condition() { return condition; }
    177         void set_condition( Expression *newValue ) { condition = newValue; }
     183        Expression * get_condition() { return condition; }
     184        void set_condition( Expression * newValue ) { condition = newValue; }
    178185
    179186        std::list<Statement *> & get_statements() { return statements; }
    180187
    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;
     188        virtual void accept( Visitor & v ) override { v.visit( this ); }
     189        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     190        virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
     191
     192        virtual SwitchStmt * clone() const override { return new SwitchStmt( *this ); }
     193        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    186194
    187195};
     
    192200        std::list<Statement *> stmts;
    193201
    194         CaseStmt( Expression *conditions, const std::list<Statement *> &stmts, bool isdef = false ) throw (SemanticErrorException);
    195         CaseStmt( const CaseStmt &other );
     202        CaseStmt( Expression * conditions, const std::list<Statement *> & stmts, bool isdef = false ) throw (SemanticErrorException);
     203        CaseStmt( const CaseStmt & other );
    196204        virtual ~CaseStmt();
    197205
     
    201209        void set_default(bool b) { _isDefault = b; }
    202210
    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;
     211        Expression * & get_condition() { return condition; }
     212        void set_condition( Expression * newValue ) { condition = newValue; }
     213
     214        std::list<Statement *> & get_statements() { return stmts; }
     215        void set_statements( std::list<Statement *> & newValue ) { stmts = newValue; }
     216
     217        virtual void accept( Visitor & v ) override { v.visit( this ); }
     218        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     219        virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
     220
     221        virtual CaseStmt * clone() const override { return new CaseStmt( *this ); }
     222        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    214223  private:
    215224        bool _isDefault;
     
    218227class WhileStmt : public Statement {
    219228  public:
    220         Expression *condition;
    221         Statement *body;
     229        Expression * condition;
     230        Statement * body;
    222231        std::list<Statement *> initialization;
    223232        bool isDoWhile;
    224233
    225         WhileStmt( Expression *condition,
    226                Statement *body, std::list<Statement *> & initialization, bool isDoWhile = false );
    227         WhileStmt( const WhileStmt &other );
     234        WhileStmt( Expression * condition, Statement * body, std::list<Statement *> & initialization, bool isDoWhile = false );
     235        WhileStmt( const WhileStmt & other );
    228236        virtual ~WhileStmt();
    229237
    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; }
     238        Expression * get_condition() { return condition; }
     239        void set_condition( Expression * newValue ) { condition = newValue; }
     240        Statement * get_body() { return body; }
     241        void set_body( Statement * newValue ) { body = newValue; }
    234242        bool get_isDoWhile() { return isDoWhile; }
    235243        void set_isDoWhile( bool newValue ) { isDoWhile = newValue; }
    236244
    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;
     245        virtual WhileStmt * clone() const override { return new WhileStmt( *this ); }
     246        virtual void accept( Visitor & v ) override { v.visit( this ); }
     247        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     248        virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
     249        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    241250};
    242251
     
    244253  public:
    245254        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 );
     255        Expression * condition;
     256        Expression * increment;
     257        Statement * body;
     258
     259        ForStmt( std::list<Statement *> initialization, Expression * condition = 0, Expression * increment = 0, Statement * body = 0 );
     260        ForStmt( const ForStmt & other );
    253261        virtual ~ForStmt();
    254262
    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;
     263        std::list<Statement *> & get_initialization() { return initialization; }
     264        Expression * get_condition() { return condition; }
     265        void set_condition( Expression * newValue ) { condition = newValue; }
     266        Expression * get_increment() { return increment; }
     267        void set_increment( Expression * newValue ) { increment = newValue; }
     268        Statement * get_body() { return body; }
     269        void set_body( Statement * newValue ) { body = newValue; }
     270
     271        virtual ForStmt * clone() const override { return new ForStmt( *this ); }
     272        virtual void accept( Visitor & v ) override { v.visit( this ); }
     273        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     274        virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
     275        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    267276};
    268277
     
    274283        const Label originalTarget;
    275284        Label target;
    276         Expression *computedTarget;
     285        Expression * computedTarget;
    277286        Type type;
    278287
    279288        BranchStmt( Label target, Type ) throw (SemanticErrorException);
    280         BranchStmt( Expression *computedTarget, Type ) throw (SemanticErrorException);
     289        BranchStmt( Expression * computedTarget, Type ) throw (SemanticErrorException);
    281290
    282291        Label get_originalTarget() { return originalTarget; }
     
    284293        void set_target( Label newValue ) { target = newValue; }
    285294
    286         Expression *get_computedTarget() { return computedTarget; }
     295        Expression * get_computedTarget() { return computedTarget; }
    287296        void set_target( Expression * newValue ) { computedTarget = newValue; }
    288297
    289298        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;
     299        const char * get_typename() { return brType[ type ]; }
     300
     301        virtual BranchStmt * clone() const override { return new BranchStmt( *this ); }
     302        virtual void accept( Visitor & v ) override { v.visit( this ); }
     303        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     304        virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
     305        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    296306  private:
    297         static const char *brType[];
     307        static const char * brType[];
    298308};
    299309
    300310class ReturnStmt : public Statement {
    301311  public:
    302         Expression *expr;
    303 
    304         ReturnStmt( Expression *expr );
    305         ReturnStmt( const ReturnStmt &other );
     312        Expression * expr;
     313
     314        ReturnStmt( Expression * expr );
     315        ReturnStmt( const ReturnStmt & other );
    306316        virtual ~ReturnStmt();
    307317
    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;
     318        Expression * get_expr() { return expr; }
     319        void set_expr( Expression * newValue ) { expr = newValue; }
     320
     321        virtual ReturnStmt * clone() const override { return new ReturnStmt( *this ); }
     322        virtual void accept( Visitor & v ) override { v.visit( this ); }
     323        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     324        virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
     325        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    315326};
    316327
     
    324335
    325336        ThrowStmt( Kind kind, Expression * expr, Expression * target = nullptr );
    326         ThrowStmt( const ThrowStmt &other );
     337        ThrowStmt( const ThrowStmt & other );
    327338        virtual ~ThrowStmt();
    328339
     
    333344        void set_target( Expression * newTarget ) { target = newTarget; }
    334345
    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;
     346        virtual ThrowStmt * clone() const override { return new ThrowStmt( *this ); }
     347        virtual void accept( Visitor & v ) override { v.visit( this ); }
     348        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     349        virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
     350        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    339351};
    340352
     
    345357        FinallyStmt * finallyBlock;
    346358
    347         TryStmt( CompoundStmt *tryBlock, std::list<CatchStmt *> &handlers, FinallyStmt *finallyBlock = 0 );
    348         TryStmt( const TryStmt &other );
     359        TryStmt( CompoundStmt * tryBlock, std::list<CatchStmt *> & handlers, FinallyStmt * finallyBlock = 0 );
     360        TryStmt( const TryStmt & other );
    349361        virtual ~TryStmt();
    350362
    351         CompoundStmt *get_block() const { return block; }
    352         void set_block( CompoundStmt *newValue ) { block = newValue; }
     363        CompoundStmt * get_block() const { return block; }
     364        void set_block( CompoundStmt * newValue ) { block = newValue; }
    353365        std::list<CatchStmt *>& get_catchers() { return handlers; }
    354366
    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;
     367        FinallyStmt * get_finally() const { return finallyBlock; }
     368        void set_finally( FinallyStmt * newValue ) { finallyBlock = newValue; }
     369
     370        virtual TryStmt * clone() const override { return new TryStmt( *this ); }
     371        virtual void accept( Visitor & v ) override { v.visit( this ); }
     372        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     373        virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
     374        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    362375};
    363376
     
    367380
    368381        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 );
     382        Declaration * decl;
     383        Expression * cond;
     384        Statement * body;
     385
     386        CatchStmt( Kind kind, Declaration * decl,
     387                   Expression * cond, Statement * body );
     388        CatchStmt( const CatchStmt & other );
    376389        virtual ~CatchStmt();
    377390
    378391        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;
     392        Declaration * get_decl() { return decl; }
     393        void set_decl( Declaration * newValue ) { decl = newValue; }
     394        Expression * get_cond() { return cond; }
     395        void set_cond( Expression * newCond ) { cond = newCond; }
     396        Statement * get_body() { return body; }
     397        void set_body( Statement * newValue ) { body = newValue; }
     398
     399        virtual CatchStmt * clone() const override { return new CatchStmt( *this ); }
     400        virtual void accept( Visitor & v ) override { v.visit( this ); }
     401        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     402        virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
     403        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    390404};
    391405
    392406class FinallyStmt : public Statement {
    393407  public:
    394         CompoundStmt *block;
    395 
    396         FinallyStmt( CompoundStmt *block );
    397         FinallyStmt( const FinallyStmt &other );
     408        CompoundStmt * block;
     409
     410        FinallyStmt( CompoundStmt * block );
     411        FinallyStmt( const FinallyStmt & other );
    398412        virtual ~FinallyStmt();
    399413
    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;
     414        CompoundStmt * get_block() const { return block; }
     415        void set_block( CompoundStmt * newValue ) { block = newValue; }
     416
     417        virtual FinallyStmt * clone() const override { return new FinallyStmt( *this ); }
     418        virtual void accept( Visitor & v ) override { v.visit( this ); }
     419        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     420        virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
     421        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    407422};
    408423
     
    438453        } orelse;
    439454
    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;
    444 
    445 };
    446 
    447 class WithStmt : public Statement {
    448 public:
    449         std::list< Expression * > exprs;
    450         Statement * stmt;
    451 
    452         WithStmt( const std::list< Expression * > & exprs, Statement * stmt );
    453         WithStmt( const WithStmt & other );
    454         virtual ~WithStmt();
    455 
    456         virtual WithStmt * clone() const override { return new WithStmt( *this ); }
    457         virtual void accept( Visitor & v ) override { v.visit( this ); }
    458         virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
    459         virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    460 };
     455        virtual WaitForStmt * clone() const override { return new WaitForStmt( *this ); }
     456        virtual void accept( Visitor & v ) override { v.visit( this ); }
     457        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     458        virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
     459        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     460
     461};
     462
     463// class WithStmt : public Statement {
     464// public:
     465//      std::list< Expression * > exprs;
     466//      Statement * stmt;
     467
     468//      WithStmt( const std::list< Expression * > & exprs, Statement * stmt );
     469//      WithStmt( const WithStmt & other );
     470//      virtual ~WithStmt();
     471
     472//      virtual WithStmt * clone() const override { return new WithStmt( *this ); }
     473//      virtual void accept( Visitor & v ) override { v.visit( this ); }
     474//      virtual void accept( Visitor & v ) const 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// };
    461478
    462479
     
    464481class DeclStmt : public Statement {
    465482  public:
    466         Declaration *decl;
    467 
    468         DeclStmt( Declaration *decl );
    469         DeclStmt( const DeclStmt &other );
     483        Declaration * decl;
     484
     485        DeclStmt( Declaration * decl );
     486        DeclStmt( const DeclStmt & other );
    470487        virtual ~DeclStmt();
    471488
    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.
     489        Declaration * get_decl() const { return decl; }
     490        void set_decl( Declaration * newValue ) { decl = newValue; }
     491
     492        virtual DeclStmt * clone() const override { return new DeclStmt( *this ); }
     493        virtual void accept( Visitor & v ) override { v.visit( this ); }
     494        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     495        virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
     496        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     497};
     498
     499
     500/// represents an implicit application of a constructor or destructor. Qualifiers are replaced immediately before and
     501/// after the call so that qualified objects can be constructed with the same functions as unqualified objects.
    485502class ImplicitCtorDtorStmt : public Statement {
    486503  public:
     
    492509        virtual ~ImplicitCtorDtorStmt();
    493510
    494         Statement *get_callStmt() const { return callStmt; }
     511        Statement * get_callStmt() const { return callStmt; }
    495512        void set_callStmt( Statement * newValue ) { callStmt = newValue; }
    496513
    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;
     514        virtual ImplicitCtorDtorStmt * clone() const override { return new ImplicitCtorDtorStmt( *this ); }
     515        virtual void accept( Visitor & v ) override { v.visit( this ); }
     516        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     517        virtual Statement * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
     518        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
    501519};
    502520
  • src/SynTree/SynTree.h

    r7951100 rb067d9b  
    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 : Mon Jul 24 16:54:00 2017
    13 // Update Count     : 11
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Thu Jul 25 22:37:45 2019
     13// Update Count     : 12
    1414//
    1515
     
    3434class NamedTypeDecl;
    3535class TypeDecl;
    36 class FtypeDecl;
    37 class DtypeDecl;
    3836class TypedefDecl;
    3937class AsmDecl;
     
    8179class OffsetofExpr;
    8280class OffsetPackExpr;
    83 class AttrExpr;
    8481class LogicalExpr;
    8582class ConditionalExpr;
     
    9087class ConstructorExpr;
    9188class CompoundLiteralExpr;
    92 class UntypedValofExpr;
    9389class RangeExpr;
    9490class UntypedTupleExpr;
     
    10197class InitExpr;
    10298class DeletedExpr;
     99class DefaultArgExpr;
    103100class GenericExpr;
    104101
     
    109106class ArrayType;
    110107class ReferenceType;
     108class QualifiedType;
    111109class FunctionType;
    112110class ReferenceToType;
     
    122120class ZeroType;
    123121class OneType;
     122class GlobalScopeType;
    124123
    125124class Designation;
     
    128127class ListInit;
    129128class ConstructorInit;
    130 
    131 class Subrange;
    132129
    133130//template <class T>    // emulate a union with templates?
  • src/SynTree/TupleExpr.cc

    r7951100 rb067d9b  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Mar 17 09:42:29 2017
    13 // Update Count     : 3
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Wed Aug 14 14:34:00 2019
     13// Update Count     : 5
    1414//
    1515
     
    5757}
    5858
     59bool TupleExpr::get_lvalue() const {
     60        return false;
     61}
     62
    5963void TupleExpr::print( std::ostream &os, Indenter indent ) const {
    6064        os << "Tuple:" << std::endl;
     
    6771        assertf( type->size() > index, "TupleIndexExpr index out of bounds: tuple size %d, requested index %d in expr %s", type->size(), index, toString( tuple ).c_str() );
    6872        set_result( (*std::next( type->get_types().begin(), index ))->clone() );
    69         // like MemberExpr, TupleIndexExpr is always an lvalue
    70         get_result()->set_lvalue( true );
    7173}
    7274
     
    7678TupleIndexExpr::~TupleIndexExpr() {
    7779        delete tuple;
     80}
     81
     82bool TupleIndexExpr::get_lvalue() const {
     83        return tuple->get_lvalue();
    7884}
    7985
     
    105111}
    106112
     113TupleAssignExpr::TupleAssignExpr(
     114        StmtExpr * s )
     115: Expression(), stmtExpr(s) {
     116}
     117
     118
    107119TupleAssignExpr::~TupleAssignExpr() {
    108120        delete stmtExpr;
  • src/SynTree/Type.cc

    r7951100 rb067d9b  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Sep 25 15:16:32 2017
    13 // Update Count     : 38
     12// Last Modified On : Sun Aug  4 21:05:07 2019
     13// Update Count     : 45
    1414//
    1515#include "Type.h"
     
    2424using namespace std;
    2525
    26 const char *BasicType::typeNames[] = {
     26const char * BasicType::typeNames[] = {
    2727        "_Bool",
    2828        "char",
     
    3737        "signed long long int",
    3838        "unsigned long long int",
    39         "float",
    40         "double",
    41         "long double",
    42         "float _Complex",
    43         "double _Complex",
    44         "long double _Complex",
    45         "float _Imaginary",
    46         "double _Imaginary",
    47         "long double _Imaginary",
    4839        "__int128",
    4940        "unsigned __int128",
     41        "_Float16",
     42        "_Float16 _Complex",
     43        "_Float32",
     44        "_Float32 _Complex",
     45        "float",
     46        "float _Complex",
     47        //"float _Imaginary",
     48        "_Float32x",
     49        "_Float32x _Complex",
     50        "_Float64",
     51        "_Float64 _Complex",
     52        "double",
     53        "double _Complex",
     54        //"double _Imaginary",
     55        "_Float64x",
     56        "_Float64x _Complex",
    5057        "__float80",
    51         "__float128"
     58        "_Float128",
     59        "_Float128 _Complex",
     60        "__float128",
     61        "long double",
     62        "long double _Complex",
     63        //"long double _Imaginary",
     64        "_Float128x",
     65        "_Float128x _Complex",
    5266};
    5367static_assert(
    54         sizeof(BasicType::typeNames)/sizeof(BasicType::typeNames[0]) == BasicType::NUMBER_OF_BASIC_TYPES,
     68        sizeof(BasicType::typeNames) / sizeof(BasicType::typeNames[0]) == BasicType::NUMBER_OF_BASIC_TYPES,
    5569        "Each basic type name should have a corresponding kind enum value"
    5670);
     
    6983
    7084// These must remain in the same order as the corresponding bit fields.
    71 const char * Type::FuncSpecifiersNames[] = { "inline", "fortran", "_Noreturn" };
     85const char * Type::FuncSpecifiersNames[] = { "inline", "_Noreturn", "fortran" };
    7286const char * Type::StorageClassesNames[] = { "extern", "static", "auto", "register", "_Thread_local" };
    73 const char * Type::QualifiersNames[] = { "const", "restrict", "volatile", "lvalue", "mutex", "_Atomic" };
     87const char * Type::QualifiersNames[] = { "const", "restrict", "volatile", "mutex", "_Atomic" };
    7488
    7589Type * Type::stripDeclarator() {
     
    86100}
    87101
     102const Type * Type::stripReferences() const {
     103        const Type * type;
     104        const ReferenceType * ref;
     105        for ( type = this; (ref = dynamic_cast<const ReferenceType *>( type )); type = ref->base );
     106        return type;
     107}
     108
    88109int Type::referenceDepth() const { return 0; }
    89110
    90111TypeSubstitution Type::genericSubstitution() const { assertf( false, "Non-aggregate type: %s", toCString( this ) ); }
    91112
    92 void Type::print( std::ostream &os, Indenter indent ) const {
     113void Type::print( std::ostream & os, Indenter indent ) const {
    93114        if ( ! forall.empty() ) {
    94115                os << "forall" << std::endl;
     
    105126}
    106127
     128
     129QualifiedType::QualifiedType( const Type::Qualifiers & tq, Type * parent, Type * child ) : Type( tq, {} ), parent( parent ), child( child ) {
     130}
     131
     132QualifiedType::QualifiedType( const QualifiedType & other ) : Type( other ), parent( maybeClone( other.parent ) ), child( maybeClone( other.child ) ) {
     133}
     134
     135QualifiedType::~QualifiedType() {
     136        delete parent;
     137        delete child;
     138}
     139
     140void QualifiedType::print( std::ostream & os, Indenter indent ) const {
     141        os << "Qualified Type:" << endl;
     142        os << indent+1;
     143        parent->print( os, indent+1 );
     144        os << endl << indent+1;
     145        child->print( os, indent+1 );
     146        os << endl;
     147        Type::print( os, indent+1 );
     148}
     149
     150GlobalScopeType::GlobalScopeType() : Type( Type::Qualifiers(), {} ) {}
     151
     152void GlobalScopeType::print( std::ostream & os, Indenter ) const {
     153        os << "Global Scope Type" << endl;
     154}
     155
     156
    107157// Empty Variable declarations:
    108158const Type::FuncSpecifiers noFuncSpecifiers;
  • src/SynTree/Type.h

    r7951100 rb067d9b  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Sep 25 14:14:01 2017
    13 // Update Count     : 154
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Wed Sep  4 09:58:00 2019
     13// Update Count     : 170
    1414//
    1515
     
    102102        }; // StorageClasses
    103103
    104         enum { Const = 1 << 0, Restrict = 1 << 1, Volatile = 1 << 2, Lvalue = 1 << 3, Mutex = 1 << 4, Atomic = 1 << 5, NumTypeQualifier = 6 };
     104        enum { Const = 1 << 0, Restrict = 1 << 1, Volatile = 1 << 2, Mutex = 1 << 3, Atomic = 1 << 4, NumTypeQualifier = 5 };
    105105        static const char * QualifiersNames[];
    106106        union Qualifiers {
    107                 enum { Mask = ~(Restrict | Lvalue) };
     107                enum { Mask = ~Restrict };
    108108                unsigned int val;
    109109                struct {
     
    111111                        bool is_restrict : 1;
    112112                        bool is_volatile : 1;
    113                         bool is_lvalue : 1;
    114113                        bool is_mutex : 1;
    115114                        bool is_atomic : 1;
     
    131130                bool operator>( Qualifiers other ) const { return *this != other && *this >= other; }
    132131                BFCommon( Qualifiers, NumTypeQualifier )
     132
     133                Qualifiers unify( Qualifiers const & other ) const {
     134                        int or_flags = Mask & (val | other.val);
     135                        int and_flags = val & other.val;
     136                        return Qualifiers( or_flags | and_flags );
     137                }
    133138        }; // Qualifiers
    134139
     
    144149
    145150        Qualifiers & get_qualifiers() { return tq; }
    146         bool get_const() { return tq.is_const; }
    147         bool get_volatile() { return tq.is_volatile; }
    148         bool get_restrict() { return tq.is_restrict; }
    149         bool get_lvalue() { return tq.is_lvalue; }
    150         bool get_mutex() { return tq.is_mutex; }
    151         bool get_atomic() { return tq.is_atomic; }
     151        bool get_const() const { return tq.is_const; }
     152        bool get_volatile() const { return tq.is_volatile; }
     153        bool get_restrict() const { return tq.is_restrict; }
     154        bool get_mutex() const { return tq.is_mutex; }
     155        bool get_atomic() const { return tq.is_atomic; }
    152156        void set_const( bool newValue ) { tq.is_const = newValue; }
    153157        void set_volatile( bool newValue ) { tq.is_volatile = newValue; }
    154158        void set_restrict( bool newValue ) { tq.is_restrict = newValue; }
    155         void set_lvalue( bool newValue ) { tq.is_lvalue = newValue; }
    156159        void set_mutex( bool newValue ) { tq.is_mutex = newValue; }
    157160        void set_atomic( bool newValue ) { tq.is_atomic = newValue; }
     
    172175        /// return type without outer references
    173176        Type * stripReferences();
     177        const Type * stripReferences() const;
    174178
    175179        /// return the number of references occuring consecutively on the outermost layer of this type (i.e. do not count references nested within other types)
     
    178182        virtual bool isComplete() const { return true; }
    179183
    180         virtual AggregateDecl * getAggr() { assertf( false, "Non-aggregate type: %s", toCString( this ) ); }
     184        virtual AggregateDecl * getAggr() const { assertf( false, "Non-aggregate type: %s", toCString( this ) ); }
    181185
    182186        virtual TypeSubstitution genericSubstitution() const;
     
    184188        virtual Type *clone() const = 0;
    185189        virtual void accept( Visitor & v ) = 0;
     190        virtual void accept( Visitor & v ) const = 0;
    186191        virtual Type *acceptMutator( Mutator & m ) = 0;
    187192        virtual void print( std::ostream & os, Indenter indent = {} ) const;
     
    201206        virtual VoidType *clone() const override { return new VoidType( *this ); }
    202207        virtual void accept( Visitor & v ) override { v.visit( this ); }
     208        virtual void accept( Visitor & v ) const override { v.visit( this ); }
    203209        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    204210        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     
    207213class BasicType : public Type {
    208214  public:
     215        // GENERATED START, DO NOT EDIT
     216        // GENERATED BY BasicTypes-gen.cc
    209217        enum Kind {
    210218                Bool,
     
    220228                LongLongSignedInt,
    221229                LongLongUnsignedInt,
    222                 Float,
    223                 Double,
    224                 LongDouble,
    225                 FloatComplex,
    226                 DoubleComplex,
    227                 LongDoubleComplex,
    228                 FloatImaginary,
    229                 DoubleImaginary,
    230                 LongDoubleImaginary,
    231230                SignedInt128,
    232231                UnsignedInt128,
    233                 Float80,
    234                 Float128,
     232                uFloat16,
     233                uFloat16Complex,
     234                uFloat32,
     235                uFloat32Complex,
     236                Float,
     237                FloatComplex,
     238                uFloat32x,
     239                uFloat32xComplex,
     240                uFloat64,
     241                uFloat64Complex,
     242                Double,
     243                DoubleComplex,
     244                uFloat64x,
     245                uFloat64xComplex,
     246                uuFloat80,
     247                uFloat128,
     248                uFloat128Complex,
     249                uuFloat128,
     250                LongDouble,
     251                LongDoubleComplex,
     252                uFloat128x,
     253                uFloat128xComplex,
    235254                NUMBER_OF_BASIC_TYPES
    236255        } kind;
     256        // GENERATED END
    237257
    238258        static const char *typeNames[];                                         // string names for basic types, MUST MATCH with Kind
     
    240260        BasicType( const Type::Qualifiers & tq, Kind bt, const std::list< Attribute * > & attributes = std::list< Attribute * >() );
    241261
    242         Kind get_kind() { return kind; }
     262        Kind get_kind() const { return kind; }
    243263        void set_kind( Kind newValue ) { kind = newValue; }
    244264
    245265        virtual BasicType *clone() const override { return new BasicType( *this ); }
    246266        virtual void accept( Visitor & v ) override { v.visit( this ); }
     267        virtual void accept( Visitor & v ) const override { v.visit( this ); }
    247268        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    248269        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     
    280301        virtual PointerType *clone() const override { return new PointerType( *this ); }
    281302        virtual void accept( Visitor & v ) override { v.visit( this ); }
     303        virtual void accept( Visitor & v ) const override { v.visit( this ); }
    282304        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    283305        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     
    311333        virtual ArrayType *clone() const override { return new ArrayType( *this ); }
    312334        virtual void accept( Visitor & v ) override { v.visit( this ); }
     335        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     336        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
     337        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     338};
     339
     340class QualifiedType : public Type {
     341public:
     342        Type * parent;
     343        Type * child;
     344
     345        QualifiedType( const Type::Qualifiers & tq, Type * parent, Type * child );
     346        QualifiedType( const QualifiedType & tq );
     347        virtual ~QualifiedType();
     348
     349        virtual QualifiedType *clone() const override { return new QualifiedType( *this ); }
     350        virtual void accept( Visitor & v ) override { v.visit( this ); }
     351        virtual void accept( Visitor & v ) const override { v.visit( this ); }
    313352        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    314353        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     
    337376        virtual ReferenceType *clone() const override { return new ReferenceType( *this ); }
    338377        virtual void accept( Visitor & v ) override { v.visit( this ); }
     378        virtual void accept( Visitor & v ) const override { v.visit( this ); }
    339379        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    340380        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     
    366406        virtual FunctionType *clone() const override { return new FunctionType( *this ); }
    367407        virtual void accept( Visitor & v ) override { v.visit( this ); }
     408        virtual void accept( Visitor & v ) const override { v.visit( this ); }
    368409        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    369410        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     
    416457        virtual bool isComplete() const override;
    417458
    418         virtual AggregateDecl * getAggr() override;
     459        virtual AggregateDecl * getAggr() const override;
    419460
    420461        virtual TypeSubstitution genericSubstitution() const override;
     
    426467        virtual StructInstType *clone() const override { return new StructInstType( *this ); }
    427468        virtual void accept( Visitor & v ) override { v.visit( this ); }
     469        virtual void accept( Visitor & v ) const override { v.visit( this ); }
    428470        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    429471
     
    453495        virtual bool isComplete() const override;
    454496
    455         virtual AggregateDecl * getAggr() override;
     497        virtual AggregateDecl * getAggr() const override;
    456498
    457499        virtual TypeSubstitution genericSubstitution() const override;
     
    463505        virtual UnionInstType *clone() const override { return new UnionInstType( *this ); }
    464506        virtual void accept( Visitor & v ) override { v.visit( this ); }
     507        virtual void accept( Visitor & v ) const override { v.visit( this ); }
    465508        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    466509
     
    486529        virtual bool isComplete() const override;
    487530
     531        virtual AggregateDecl * getAggr() const override;
     532
    488533        virtual EnumInstType *clone() const override { return new EnumInstType( *this ); }
    489534        virtual void accept( Visitor & v ) override { v.visit( this ); }
     535        virtual void accept( Visitor & v ) const override { v.visit( this ); }
    490536        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    491537
     
    511557        virtual TraitInstType *clone() const override { return new TraitInstType( *this ); }
    512558        virtual void accept( Visitor & v ) override { v.visit( this ); }
     559        virtual void accept( Visitor & v ) const override { v.visit( this ); }
    513560        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    514561  private:
     
    538585        virtual TypeInstType *clone() const override { return new TypeInstType( *this ); }
    539586        virtual void accept( Visitor & v ) override { v.visit( this ); }
     587        virtual void accept( Visitor & v ) const override { v.visit( this ); }
    540588        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    541589        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     
    575623        virtual TupleType *clone() const override { return new TupleType( *this ); }
    576624        virtual void accept( Visitor & v ) override { v.visit( this ); }
     625        virtual void accept( Visitor & v ) const override { v.visit( this ); }
    577626        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    578627        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     
    581630class TypeofType : public Type {
    582631  public:
    583         Expression *expr;
    584 
    585         TypeofType( const Type::Qualifiers & tq, Expression *expr, const std::list< Attribute * > & attributes = std::list< Attribute * >()  );
     632        Expression *expr;    ///< expression to take the type of
     633        bool is_basetypeof;  ///< true iff is basetypeof type
     634
     635        TypeofType( const Type::Qualifiers & tq, Expression *expr, const std::list< Attribute * > & attributes = std::list< Attribute * >() );
     636        TypeofType( const Type::Qualifiers & tq, Expression *expr, bool is_basetypeof,
     637                const std::list< Attribute * > & attributes = std::list< Attribute * >() );
    586638        TypeofType( const TypeofType& );
    587639        virtual ~TypeofType();
     
    594646        virtual TypeofType *clone() const override { return new TypeofType( *this ); }
    595647        virtual void accept( Visitor & v ) override { v.visit( this ); }
     648        virtual void accept( Visitor & v ) const override { v.visit( this ); }
    596649        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    597650        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     
    623676        virtual AttrType *clone() const override { return new AttrType( *this ); }
    624677        virtual void accept( Visitor & v ) override { v.visit( this ); }
     678        virtual void accept( Visitor & v ) const override { v.visit( this ); }
    625679        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    626680        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     
    637691        virtual VarArgsType *clone() const override { return new VarArgsType( *this ); }
    638692        virtual void accept( Visitor & v ) override { v.visit( this ); }
     693        virtual void accept( Visitor & v ) const override { v.visit( this ); }
    639694        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    640695        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     
    649704        virtual ZeroType *clone() const override { return new ZeroType( *this ); }
    650705        virtual void accept( Visitor & v ) override { v.visit( this ); }
     706        virtual void accept( Visitor & v ) const override { v.visit( this ); }
    651707        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    652708        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     
    661717        virtual OneType *clone() const override { return new OneType( *this ); }
    662718        virtual void accept( Visitor & v ) override { v.visit( this ); }
     719        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     720        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
     721        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     722};
     723
     724class GlobalScopeType : public Type {
     725  public:
     726        GlobalScopeType();
     727
     728        virtual GlobalScopeType *clone() const override { return new GlobalScopeType( *this ); }
     729        virtual void accept( Visitor & v ) override { v.visit( this ); }
     730        virtual void accept( Visitor & v ) const override { v.visit( this ); }
    663731        virtual Type *acceptMutator( Mutator & m ) override { return m.mutate( this ); }
    664732        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
  • src/SynTree/TypeSubstitution.cc

    r7951100 rb067d9b  
    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

    r7951100 rb067d9b  
    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/TypeofType.cc

    r7951100 rb067d9b  
    2323class Attribute;
    2424
    25 TypeofType::TypeofType( const Type::Qualifiers &tq, Expression *expr, const std::list< Attribute * > & attributes ) : Type( tq, attributes ), expr( expr ) {
    26 }
     25TypeofType::TypeofType( const Type::Qualifiers &tq, Expression *expr,
     26        const std::list< Attribute * > & attributes )
     27: Type( tq, attributes ), expr( expr ), is_basetypeof(false) {}
    2728
    28 TypeofType::TypeofType( const TypeofType &other ) : Type( other ), expr( maybeClone( other.expr ) ) {
    29 }
     29TypeofType::TypeofType( const Type::Qualifiers &tq, Expression *expr, bool is_basetypeof,
     30        const std::list< Attribute * > & attributes )
     31: Type( tq, attributes ), expr( expr ), is_basetypeof( is_basetypeof ) {}
     32
     33TypeofType::TypeofType( const TypeofType &other )
     34: Type( other ), expr( maybeClone( other.expr ) ), is_basetypeof( other.is_basetypeof ) {}
    3035
    3136TypeofType::~TypeofType() {
     
    3540void TypeofType::print( std::ostream &os, Indenter indent ) const {
    3641        Type::print( os, indent );
     42        if ( is_basetypeof ) { os << "base-"; }
    3743        os << "type-of expression ";
    3844        if ( expr ) {
  • src/SynTree/Visitor.h

    r7951100 rb067d9b  
    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 : Mon Jul 24 16:28:00 2017
    13 // Update Count     : 13
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Thu Jul 25 22:21:49 2019
     13// Update Count     : 14
    1414//
    1515
     
    2727        // of the given syntax node, but performs no other action.
    2828
    29         virtual void visit( ObjectDecl * objectDecl ) = 0;
    30         virtual void visit( FunctionDecl * functionDecl ) = 0;
    31         virtual void visit( StructDecl * aggregateDecl ) = 0;
    32         virtual void visit( UnionDecl * aggregateDecl ) = 0;
    33         virtual void visit( EnumDecl * aggregateDecl ) = 0;
    34         virtual void visit( TraitDecl * aggregateDecl ) = 0;
    35         virtual void visit( TypeDecl * typeDecl ) = 0;
    36         virtual void visit( TypedefDecl * typeDecl ) = 0;
    37         virtual void visit( AsmDecl * asmDecl ) = 0;
    38         virtual void visit( StaticAssertDecl * assertDecl ) = 0;
    39 
    40         virtual void visit( CompoundStmt * compoundStmt ) = 0;
    41         virtual void visit( ExprStmt * exprStmt ) = 0;
    42         virtual void visit( AsmStmt * asmStmt ) = 0;
    43         virtual void visit( DirectiveStmt * directiveStmt ) = 0;
    44         virtual void visit( IfStmt * ifStmt ) = 0;
    45         virtual void visit( WhileStmt * whileStmt ) = 0;
    46         virtual void visit( ForStmt * forStmt ) = 0;
    47         virtual void visit( SwitchStmt * switchStmt ) = 0;
    48         virtual void visit( CaseStmt * caseStmt ) = 0;
    49         virtual void visit( BranchStmt * branchStmt ) = 0;
    50         virtual void visit( ReturnStmt * returnStmt ) = 0;
    51         virtual void visit( ThrowStmt * throwStmt ) = 0;
    52         virtual void visit( TryStmt * tryStmt ) = 0;
    53         virtual void visit( CatchStmt * catchStmt ) = 0;
    54         virtual void visit( FinallyStmt * finallyStmt ) = 0;
    55         virtual void visit( WaitForStmt * waitforStmt ) = 0;
    56         virtual void visit( WithStmt * withStmt ) = 0;
    57         virtual void visit( NullStmt * nullStmt ) = 0;
    58         virtual void visit( DeclStmt * declStmt ) = 0;
    59         virtual void visit( ImplicitCtorDtorStmt * impCtorDtorStmt ) = 0;
    60 
    61         virtual void visit( ApplicationExpr * applicationExpr ) = 0;
    62         virtual void visit( UntypedExpr * untypedExpr ) = 0;
    63         virtual void visit( NameExpr * nameExpr ) = 0;
    64         virtual void visit( CastExpr * castExpr ) = 0;
    65         virtual void visit( KeywordCastExpr * castExpr ) = 0;
    66         virtual void visit( VirtualCastExpr * castExpr ) = 0;
    67         virtual void visit( AddressExpr * addressExpr ) = 0;
    68         virtual void visit( LabelAddressExpr * labAddressExpr ) = 0;
    69         virtual void visit( UntypedMemberExpr * memberExpr ) = 0;
    70         virtual void visit( MemberExpr * memberExpr ) = 0;
    71         virtual void visit( VariableExpr * variableExpr ) = 0;
    72         virtual void visit( ConstantExpr * constantExpr ) = 0;
    73         virtual void visit( SizeofExpr * sizeofExpr ) = 0;
    74         virtual void visit( AlignofExpr * alignofExpr ) = 0;
    75         virtual void visit( UntypedOffsetofExpr * offsetofExpr ) = 0;
    76         virtual void visit( OffsetofExpr * offsetofExpr ) = 0;
    77         virtual void visit( OffsetPackExpr * offsetPackExpr ) = 0;
    78         virtual void visit( AttrExpr * attrExpr ) = 0;
    79         virtual void visit( LogicalExpr * logicalExpr ) = 0;
    80         virtual void visit( ConditionalExpr * conditionalExpr ) = 0;
    81         virtual void visit( CommaExpr * commaExpr ) = 0;
    82         virtual void visit( TypeExpr * typeExpr ) = 0;
    83         virtual void visit( AsmExpr * asmExpr ) = 0;
    84         virtual void visit( ImplicitCopyCtorExpr * impCpCtorExpr ) = 0;
    85         virtual void visit( ConstructorExpr *  ctorExpr ) = 0;
    86         virtual void visit( CompoundLiteralExpr * compLitExpr ) = 0;
    87         virtual void visit( RangeExpr * rangeExpr ) = 0;
    88         virtual void visit( UntypedTupleExpr * tupleExpr ) = 0;
    89         virtual void visit( TupleExpr * tupleExpr ) = 0;
    90         virtual void visit( TupleIndexExpr * tupleExpr ) = 0;
    91         virtual void visit( TupleAssignExpr * assignExpr ) = 0;
    92         virtual void visit( StmtExpr *  stmtExpr ) = 0;
    93         virtual void visit( UniqueExpr *  uniqueExpr ) = 0;
    94         virtual void visit( UntypedInitExpr *  initExpr ) = 0;
    95         virtual void visit( InitExpr *  initExpr ) = 0;
    96         virtual void visit( DeletedExpr * delExpr ) = 0;
    97         virtual void visit( GenericExpr * genExpr ) = 0;
    98 
    99         virtual void visit( VoidType * basicType ) = 0;
    100         virtual void visit( BasicType * basicType ) = 0;
    101         virtual void visit( PointerType * pointerType ) = 0;
    102         virtual void visit( ArrayType * arrayType ) = 0;
    103         virtual void visit( ReferenceType * refType ) = 0;
    104         virtual void visit( FunctionType * functionType ) = 0;
    105         virtual void visit( StructInstType * aggregateUseType ) = 0;
    106         virtual void visit( UnionInstType * aggregateUseType ) = 0;
    107         virtual void visit( EnumInstType * aggregateUseType ) = 0;
    108         virtual void visit( TraitInstType * aggregateUseType ) = 0;
    109         virtual void visit( TypeInstType * aggregateUseType ) = 0;
    110         virtual void visit( TupleType * tupleType ) = 0;
    111         virtual void visit( TypeofType * typeofType ) = 0;
    112         virtual void visit( AttrType * attrType ) = 0;
    113         virtual void visit( VarArgsType * varArgsType ) = 0;
    114         virtual void visit( ZeroType * zeroType ) = 0;
    115         virtual void visit( OneType * oneType ) = 0;
    116 
    117         virtual void visit( Designation * designation ) = 0;
    118         virtual void visit( SingleInit * singleInit ) = 0;
    119         virtual void visit( ListInit * listInit ) = 0;
    120         virtual void visit( ConstructorInit * ctorInit ) = 0;
    121 
    122         virtual void visit( Subrange * subrange ) = 0;
    123 
    124         virtual void visit( Constant * constant ) = 0;
    125 
    126         virtual void visit( Attribute * attribute ) = 0;
     29        virtual void visit( ObjectDecl * node ) { visit( const_cast<const ObjectDecl *>(node) ); }
     30        virtual void visit( const ObjectDecl * objectDecl ) = 0;
     31        virtual void visit( FunctionDecl * node ) { visit( const_cast<const FunctionDecl *>(node) ); }
     32        virtual void visit( const FunctionDecl * functionDecl ) = 0;
     33        virtual void visit( StructDecl * node ) { visit( const_cast<const StructDecl *>(node) ); }
     34        virtual void visit( const StructDecl * aggregateDecl ) = 0;
     35        virtual void visit( UnionDecl * node ) { visit( const_cast<const UnionDecl *>(node) ); }
     36        virtual void visit( const UnionDecl * aggregateDecl ) = 0;
     37        virtual void visit( EnumDecl * node ) { visit( const_cast<const EnumDecl *>(node) ); }
     38        virtual void visit( const EnumDecl * aggregateDecl ) = 0;
     39        virtual void visit( TraitDecl * node ) { visit( const_cast<const TraitDecl *>(node) ); }
     40        virtual void visit( const TraitDecl * aggregateDecl ) = 0;
     41        virtual void visit( TypeDecl * node ) { visit( const_cast<const TypeDecl *>(node) ); }
     42        virtual void visit( const TypeDecl * typeDecl ) = 0;
     43        virtual void visit( TypedefDecl * node ) { visit( const_cast<const TypedefDecl *>(node) ); }
     44        virtual void visit( const TypedefDecl * typeDecl ) = 0;
     45        virtual void visit( AsmDecl * node ) { visit( const_cast<const AsmDecl *>(node) ); }
     46        virtual void visit( const AsmDecl * asmDecl ) = 0;
     47        virtual void visit( StaticAssertDecl * node ) { visit( const_cast<const StaticAssertDecl *>(node) ); }
     48        virtual void visit( const StaticAssertDecl * assertDecl ) = 0;
     49
     50        virtual void visit( CompoundStmt * node ) { visit( const_cast<const CompoundStmt *>(node) ); }
     51        virtual void visit( const CompoundStmt * compoundStmt ) = 0;
     52        virtual void visit( ExprStmt * node ) { visit( const_cast<const ExprStmt *>(node) ); }
     53        virtual void visit( const ExprStmt * exprStmt ) = 0;
     54        virtual void visit( AsmStmt * node ) { visit( const_cast<const AsmStmt *>(node) ); }
     55        virtual void visit( const AsmStmt * asmStmt ) = 0;
     56        virtual void visit( DirectiveStmt * node ) { visit( const_cast<const DirectiveStmt *>(node) ); }
     57        virtual void visit( const DirectiveStmt * directiveStmt ) = 0;
     58        virtual void visit( IfStmt * node ) { visit( const_cast<const IfStmt *>(node) ); }
     59        virtual void visit( const IfStmt * ifStmt ) = 0;
     60        virtual void visit( WhileStmt * node ) { visit( const_cast<const WhileStmt *>(node) ); }
     61        virtual void visit( const WhileStmt * whileStmt ) = 0;
     62        virtual void visit( ForStmt * node ) { visit( const_cast<const ForStmt *>(node) ); }
     63        virtual void visit( const ForStmt * forStmt ) = 0;
     64        virtual void visit( SwitchStmt * node ) { visit( const_cast<const SwitchStmt *>(node) ); }
     65        virtual void visit( const SwitchStmt * switchStmt ) = 0;
     66        virtual void visit( CaseStmt * node ) { visit( const_cast<const CaseStmt *>(node) ); }
     67        virtual void visit( const CaseStmt * caseStmt ) = 0;
     68        virtual void visit( BranchStmt * node ) { visit( const_cast<const BranchStmt *>(node) ); }
     69        virtual void visit( const BranchStmt * branchStmt ) = 0;
     70        virtual void visit( ReturnStmt * node ) { visit( const_cast<const ReturnStmt *>(node) ); }
     71        virtual void visit( const ReturnStmt * returnStmt ) = 0;
     72        virtual void visit( ThrowStmt * node ) { visit( const_cast<const ThrowStmt *>(node) ); }
     73        virtual void visit( const ThrowStmt * throwStmt ) = 0;
     74        virtual void visit( TryStmt * node ) { visit( const_cast<const TryStmt *>(node) ); }
     75        virtual void visit( const TryStmt * tryStmt ) = 0;
     76        virtual void visit( CatchStmt * node ) { visit( const_cast<const CatchStmt *>(node) ); }
     77        virtual void visit( const CatchStmt * catchStmt ) = 0;
     78        virtual void visit( FinallyStmt * node ) { visit( const_cast<const FinallyStmt *>(node) ); }
     79        virtual void visit( const FinallyStmt * finallyStmt ) = 0;
     80        virtual void visit( WaitForStmt * node ) { visit( const_cast<const WaitForStmt *>(node) ); }
     81        virtual void visit( const WaitForStmt * waitforStmt ) = 0;
     82        virtual void visit( WithStmt * node ) { visit( const_cast<const WithStmt *>(node) ); }
     83        virtual void visit( const WithStmt * withStmt ) = 0;
     84        virtual void visit( NullStmt * node ) { visit( const_cast<const NullStmt *>(node) ); }
     85        virtual void visit( const NullStmt * nullStmt ) = 0;
     86        virtual void visit( DeclStmt * node ) { visit( const_cast<const DeclStmt *>(node) ); }
     87        virtual void visit( const DeclStmt * declStmt ) = 0;
     88        virtual void visit( ImplicitCtorDtorStmt * node ) { visit( const_cast<const ImplicitCtorDtorStmt *>(node) ); }
     89        virtual void visit( const ImplicitCtorDtorStmt * impCtorDtorStmt ) = 0;
     90
     91        virtual void visit( ApplicationExpr * node ) { visit( const_cast<const ApplicationExpr *>(node) ); }
     92        virtual void visit( const ApplicationExpr * applicationExpr ) = 0;
     93        virtual void visit( UntypedExpr * node ) { visit( const_cast<const UntypedExpr *>(node) ); }
     94        virtual void visit( const UntypedExpr * untypedExpr ) = 0;
     95        virtual void visit( NameExpr * node ) { visit( const_cast<const NameExpr *>(node) ); }
     96        virtual void visit( const NameExpr * nameExpr ) = 0;
     97        virtual void visit( CastExpr * node ) { visit( const_cast<const CastExpr *>(node) ); }
     98        virtual void visit( const CastExpr * castExpr ) = 0;
     99        virtual void visit( KeywordCastExpr * node ) { visit( const_cast<const KeywordCastExpr *>(node) ); }
     100        virtual void visit( const KeywordCastExpr * castExpr ) = 0;
     101        virtual void visit( VirtualCastExpr * node ) { visit( const_cast<const VirtualCastExpr *>(node) ); }
     102        virtual void visit( const VirtualCastExpr * castExpr ) = 0;
     103        virtual void visit( AddressExpr * node ) { visit( const_cast<const AddressExpr *>(node) ); }
     104        virtual void visit( const AddressExpr * addressExpr ) = 0;
     105        virtual void visit( LabelAddressExpr * node ) { visit( const_cast<const LabelAddressExpr *>(node) ); }
     106        virtual void visit( const LabelAddressExpr * labAddressExpr ) = 0;
     107        virtual void visit( UntypedMemberExpr * node ) { visit( const_cast<const UntypedMemberExpr *>(node) ); }
     108        virtual void visit( const UntypedMemberExpr * memberExpr ) = 0;
     109        virtual void visit( MemberExpr * node ) { visit( const_cast<const MemberExpr *>(node) ); }
     110        virtual void visit( const MemberExpr * memberExpr ) = 0;
     111        virtual void visit( VariableExpr * node ) { visit( const_cast<const VariableExpr *>(node) ); }
     112        virtual void visit( const VariableExpr * variableExpr ) = 0;
     113        virtual void visit( ConstantExpr * node ) { visit( const_cast<const ConstantExpr *>(node) ); }
     114        virtual void visit( const ConstantExpr * constantExpr ) = 0;
     115        virtual void visit( SizeofExpr * node ) { visit( const_cast<const SizeofExpr *>(node) ); }
     116        virtual void visit( const SizeofExpr * sizeofExpr ) = 0;
     117        virtual void visit( AlignofExpr * node ) { visit( const_cast<const AlignofExpr *>(node) ); }
     118        virtual void visit( const AlignofExpr * alignofExpr ) = 0;
     119        virtual void visit( UntypedOffsetofExpr * node ) { visit( const_cast<const UntypedOffsetofExpr *>(node) ); }
     120        virtual void visit( const UntypedOffsetofExpr * offsetofExpr ) = 0;
     121        virtual void visit( OffsetofExpr * node ) { visit( const_cast<const OffsetofExpr *>(node) ); }
     122        virtual void visit( const OffsetofExpr * offsetofExpr ) = 0;
     123        virtual void visit( OffsetPackExpr * node ) { visit( const_cast<const OffsetPackExpr *>(node) ); }
     124        virtual void visit( const OffsetPackExpr * offsetPackExpr ) = 0;
     125        virtual void visit( LogicalExpr * node ) { visit( const_cast<const LogicalExpr *>(node) ); }
     126        virtual void visit( const LogicalExpr * logicalExpr ) = 0;
     127        virtual void visit( ConditionalExpr * node ) { visit( const_cast<const ConditionalExpr *>(node) ); }
     128        virtual void visit( const ConditionalExpr * conditionalExpr ) = 0;
     129        virtual void visit( CommaExpr * node ) { visit( const_cast<const CommaExpr *>(node) ); }
     130        virtual void visit( const CommaExpr * commaExpr ) = 0;
     131        virtual void visit( TypeExpr * node ) { visit( const_cast<const TypeExpr *>(node) ); }
     132        virtual void visit( const TypeExpr * typeExpr ) = 0;
     133        virtual void visit( AsmExpr * node ) { visit( const_cast<const AsmExpr *>(node) ); }
     134        virtual void visit( const AsmExpr * asmExpr ) = 0;
     135        virtual void visit( ImplicitCopyCtorExpr * node ) { visit( const_cast<const ImplicitCopyCtorExpr *>(node) ); }
     136        virtual void visit( const ImplicitCopyCtorExpr * impCpCtorExpr ) = 0;
     137        virtual void visit( ConstructorExpr * node ) { visit( const_cast<const ConstructorExpr *>(node) ); }
     138        virtual void visit( const ConstructorExpr *  ctorExpr ) = 0;
     139        virtual void visit( CompoundLiteralExpr * node ) { visit( const_cast<const CompoundLiteralExpr *>(node) ); }
     140        virtual void visit( const CompoundLiteralExpr * compLitExpr ) = 0;
     141        virtual void visit( RangeExpr * node ) { visit( const_cast<const RangeExpr *>(node) ); }
     142        virtual void visit( const RangeExpr * rangeExpr ) = 0;
     143        virtual void visit( UntypedTupleExpr * node ) { visit( const_cast<const UntypedTupleExpr *>(node) ); }
     144        virtual void visit( const UntypedTupleExpr * tupleExpr ) = 0;
     145        virtual void visit( TupleExpr * node ) { visit( const_cast<const TupleExpr *>(node) ); }
     146        virtual void visit( const TupleExpr * tupleExpr ) = 0;
     147        virtual void visit( TupleIndexExpr * node ) { visit( const_cast<const TupleIndexExpr *>(node) ); }
     148        virtual void visit( const TupleIndexExpr * tupleExpr ) = 0;
     149        virtual void visit( TupleAssignExpr * node ) { visit( const_cast<const TupleAssignExpr *>(node) ); }
     150        virtual void visit( const TupleAssignExpr * assignExpr ) = 0;
     151        virtual void visit( StmtExpr * node ) { visit( const_cast<const StmtExpr *>(node) ); }
     152        virtual void visit( const StmtExpr *  stmtExpr ) = 0;
     153        virtual void visit( UniqueExpr * node ) { visit( const_cast<const UniqueExpr *>(node) ); }
     154        virtual void visit( const UniqueExpr *  uniqueExpr ) = 0;
     155        virtual void visit( UntypedInitExpr * node ) { visit( const_cast<const UntypedInitExpr *>(node) ); }
     156        virtual void visit( const UntypedInitExpr *  initExpr ) = 0;
     157        virtual void visit( InitExpr * node ) { visit( const_cast<const InitExpr *>(node) ); }
     158        virtual void visit( const InitExpr *  initExpr ) = 0;
     159        virtual void visit( DeletedExpr * node ) { visit( const_cast<const DeletedExpr *>(node) ); }
     160        virtual void visit( const DeletedExpr * delExpr ) = 0;
     161        virtual void visit( DefaultArgExpr * node ) { visit( const_cast<const DefaultArgExpr *>(node) ); }
     162        virtual void visit( const DefaultArgExpr * argExpr ) = 0;
     163        virtual void visit( GenericExpr * node ) { visit( const_cast<const GenericExpr *>(node) ); }
     164        virtual void visit( const GenericExpr * genExpr ) = 0;
     165
     166        virtual void visit( VoidType * node ) { visit( const_cast<const VoidType *>(node) ); }
     167        virtual void visit( const VoidType * basicType ) = 0;
     168        virtual void visit( BasicType * node ) { visit( const_cast<const BasicType *>(node) ); }
     169        virtual void visit( const BasicType * basicType ) = 0;
     170        virtual void visit( PointerType * node ) { visit( const_cast<const PointerType *>(node) ); }
     171        virtual void visit( const PointerType * pointerType ) = 0;
     172        virtual void visit( ArrayType * node ) { visit( const_cast<const ArrayType *>(node) ); }
     173        virtual void visit( const ArrayType * arrayType ) = 0;
     174        virtual void visit( ReferenceType * node ) { visit( const_cast<const ReferenceType *>(node) ); }
     175        virtual void visit( const ReferenceType * refType ) = 0;
     176        virtual void visit( QualifiedType * node ) { visit( const_cast<const QualifiedType *>(node) ); }
     177        virtual void visit( const QualifiedType * qualType ) = 0;
     178        virtual void visit( FunctionType * node ) { visit( const_cast<const FunctionType *>(node) ); }
     179        virtual void visit( const FunctionType * functionType ) = 0;
     180        virtual void visit( StructInstType * node ) { visit( const_cast<const StructInstType *>(node) ); }
     181        virtual void visit( const StructInstType * aggregateUseType ) = 0;
     182        virtual void visit( UnionInstType * node ) { visit( const_cast<const UnionInstType *>(node) ); }
     183        virtual void visit( const UnionInstType * aggregateUseType ) = 0;
     184        virtual void visit( EnumInstType * node ) { visit( const_cast<const EnumInstType *>(node) ); }
     185        virtual void visit( const EnumInstType * aggregateUseType ) = 0;
     186        virtual void visit( TraitInstType * node ) { visit( const_cast<const TraitInstType *>(node) ); }
     187        virtual void visit( const TraitInstType * aggregateUseType ) = 0;
     188        virtual void visit( TypeInstType * node ) { visit( const_cast<const TypeInstType *>(node) ); }
     189        virtual void visit( const TypeInstType * aggregateUseType ) = 0;
     190        virtual void visit( TupleType * node ) { visit( const_cast<const TupleType *>(node) ); }
     191        virtual void visit( const TupleType * tupleType ) = 0;
     192        virtual void visit( TypeofType * node ) { visit( const_cast<const TypeofType *>(node) ); }
     193        virtual void visit( const TypeofType * typeofType ) = 0;
     194        virtual void visit( AttrType * node ) { visit( const_cast<const AttrType *>(node) ); }
     195        virtual void visit( const AttrType * attrType ) = 0;
     196        virtual void visit( VarArgsType * node ) { visit( const_cast<const VarArgsType *>(node) ); }
     197        virtual void visit( const VarArgsType * varArgsType ) = 0;
     198        virtual void visit( ZeroType * node ) { visit( const_cast<const ZeroType *>(node) ); }
     199        virtual void visit( const ZeroType * zeroType ) = 0;
     200        virtual void visit( OneType * node ) { visit( const_cast<const OneType *>(node) ); }
     201        virtual void visit( const OneType * oneType ) = 0;
     202        virtual void visit( GlobalScopeType * node ) { visit( const_cast<const GlobalScopeType *>(node) ); }
     203        virtual void visit( const GlobalScopeType * globalType ) = 0;
     204
     205        virtual void visit( Designation * node ) { visit( const_cast<const Designation *>(node) ); }
     206        virtual void visit( const Designation * designation ) = 0;
     207        virtual void visit( SingleInit * node ) { visit( const_cast<const SingleInit *>(node) ); }
     208        virtual void visit( const SingleInit * singleInit ) = 0;
     209        virtual void visit( ListInit * node ) { visit( const_cast<const ListInit *>(node) ); }
     210        virtual void visit( const ListInit * listInit ) = 0;
     211        virtual void visit( ConstructorInit * node ) { visit( const_cast<const ConstructorInit *>(node) ); }
     212        virtual void visit( const ConstructorInit * ctorInit ) = 0;
     213
     214        virtual void visit( Constant * node ) { visit( const_cast<const Constant *>(node) ); }
     215        virtual void visit( const Constant * constant ) = 0;
     216
     217        virtual void visit( Attribute * node ) { visit( const_cast<const Attribute *>(node) ); }
     218        virtual void visit( const Attribute * attribute ) = 0;
    127219};
    128220
    129221template< typename TreeType, typename VisitorType >
    130 inline void maybeAccept( TreeType *tree, VisitorType &visitor ) {
     222inline void maybeAccept( TreeType * tree, VisitorType & visitor ) {
    131223        if ( tree ) {
    132224                tree->accept( visitor );
     
    134226}
    135227
     228template< typename TreeType, typename VisitorType >
     229inline void maybeAccept( const TreeType * tree, VisitorType & visitor ) {
     230        if ( tree ) {
     231                tree->accept( visitor );
     232        }
     233}
     234
    136235template< typename Container, typename VisitorType >
    137 inline void acceptAll( Container &container, VisitorType &visitor ) {
     236inline void acceptAll( Container & container, VisitorType & visitor ) {
    138237        SemanticErrorException errors;
    139         for ( typename Container::iterator i = container.begin(); i != container.end(); ++i ) {
     238        for ( auto * i : container ) {
    140239                try {
    141                         if ( *i ) {
    142                                 (*i)->accept( visitor );
     240                        if ( i ) {
     241                                i->accept( visitor );
     242                        }
     243                } catch( SemanticErrorException & e ) {
     244                        errors.append( e );
     245                }
     246        }
     247        if ( ! errors.isEmpty() ) {
     248                throw errors;
     249        }
     250}
     251
     252template< typename Container, typename VisitorType >
     253inline void acceptAll( const Container & container, VisitorType & visitor ) {
     254        SemanticErrorException errors;
     255        for ( const auto * i : container ) {
     256                try {
     257                        if ( i ) {
     258                                i->accept( visitor );
    143259                        }
    144260                } catch( SemanticErrorException &e ) {
  • src/SynTree/module.mk

    r7951100 rb067d9b  
    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/Explode.cc

    r7951100 rb067d9b  
    99// Author           : Rob Schluntz
    1010// Created On       : Wed Nov 9 13:12:24 2016
    11 // Last Modified By : Rob Schluntz
    12 // Last Modified On : Wed Nov 9 13:20:24 2016
    13 // Update Count     : 2
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Wed Jun 12 16:40:00 2016
     13// Update Count     : 3
    1414//
    1515
     
    106106                return expr;
    107107        }
     108
     109namespace {
     110
     111// Remove one level of reference from a reference type.
     112const ast::Type * getReferenceBase( const ast::Type * t ) {
     113        if ( const ast::ReferenceType * ref = dynamic_cast< const ast::ReferenceType * >( t ) ) {
     114                return ref->base;
     115        } else {
     116                assertf( false, "getReferenceBase for non-ref: %s", toString( t ).c_str() );
     117                return nullptr;
     118        }
     119}
     120
     121struct CastExploderCore {
     122        bool castAdded = false;
     123        bool foundUniqueExpr = false;
     124        const ast::Expr * applyCast( const ast::Expr * expr, bool first = true ) {
     125                // On tuple push the cast down.
     126                if ( const ast::TupleExpr * tupleExpr = dynamic_cast< const ast::TupleExpr * >( expr ) ) {
     127                        foundUniqueExpr = true;
     128                        std::vector< ast::ptr< ast::Expr > > exprs;
     129                        for ( const ast::Expr * expr : tupleExpr->exprs ) {
     130                                exprs.emplace_back( applyCast( expr, false ) );
     131                                //exprs.emplace_back( ast::ptr< ast::Expr >( applyCast( expr, false ) ) );
     132                        }
     133                        if ( first ) {
     134                                castAdded = true;
     135                                const ast::Expr * tuple = new ast::TupleExpr{
     136                                        tupleExpr->location, std::move( exprs ) };
     137                                return new ast::CastExpr{ tuple, new ast::ReferenceType{ tuple->result } };
     138                        } else {
     139                                return new ast::TupleExpr( tupleExpr->location, std::move( exprs ) );
     140                        }
     141                }
     142                if ( dynamic_cast< const ast::ReferenceType * >( expr->result.get() ) ) {
     143                        return expr;
     144                } else {
     145                        castAdded = true;
     146                        return new ast::CastExpr{ expr, new ast::ReferenceType{ expr->result } };
     147                }
     148        }
     149
     150        const ast::Expr * postmutate( const ast::UniqueExpr * node ) {
     151                // move cast into unique expr so that the unique expr has type T& rather than
     152                // type T. In particular, this transformation helps with generating the
     153                // correct code for reference-cast member tuple expressions, since the result
     154                // should now be a tuple of references rather than a reference to a tuple.
     155                // Still, this code is a bit awkward, and could use some improvement.
     156                const ast::UniqueExpr * newNode = new ast::UniqueExpr( node->location,
     157                                applyCast( node->expr ), node->id );
     158                if ( castAdded ) {
     159                        // if a cast was added by applyCast, then unique expr now has one more layer of reference
     160                        // than it had coming into this function. To ensure types still match correctly, need to cast
     161                        //  to reference base so that outer expressions are still correct.
     162                        castAdded = false;
     163                        const ast::Type * newType = getReferenceBase( newNode->result );
     164                        return new ast::CastExpr{ newNode->location, node, newType };
     165                }
     166                return newNode;
     167        }
     168
     169        const ast::Expr * postmutate( const ast::TupleIndexExpr * tupleExpr ) {
     170                // tuple index expr needs to be rebuilt to ensure that the type of the
     171                // field is consistent with the type of the tuple expr, since the field
     172                // may have changed from type T to T&.
     173                return new ast::TupleIndexExpr( tupleExpr->location, tupleExpr->tuple, tupleExpr->index );
     174        }
     175};
     176
     177} // namespace
     178
     179const ast::Expr * distributeReference( const ast::Expr * expr ) {
     180        ast::Pass<CastExploderCore> exploder;
     181        expr = expr->accept( exploder );
     182        if ( ! exploder.pass.foundUniqueExpr ) {
     183                expr = new ast::CastExpr{ expr, new ast::ReferenceType{ expr->result } };
     184        }
     185        return expr;
     186}
     187
    108188} // namespace Tuples
    109189
  • src/Tuples/Explode.h

    r7951100 rb067d9b  
    99// Author           : Rob Schluntz
    1010// Created On       : Wed Nov 9 13:12:24 2016
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Jul 22 09:55:16 2017
    13 // Update Count     : 3
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Mon Jun 17 14:36:00 2019
     13// Update Count     : 4
    1414//
    1515
     
    1919#include <utility>                      // for forward
    2020
     21#include "AST/Expr.hpp"
    2122#include "ResolvExpr/Alternative.h"     // for Alternative, AltList
     23#include "ResolvExpr/Candidate.hpp"     // for Candidate, CandidateList
    2224#include "ResolvExpr/ExplodedActual.h"  // for ExplodedActual
     25#include "ResolvExpr/ExplodedArg.hpp"   // for ExplodedArg
    2326#include "SynTree/Expression.h"         // for Expression, UniqueExpr, AddressExpr
    2427#include "SynTree/Type.h"               // for TupleType, Type
    2528#include "Tuples.h"                     // for maybeImpure
     29
     30namespace ast {
     31        class SymbolTable;
     32}
    2633
    2734namespace SymTab {
     
    4451        template<typename OutputIterator>
    4552        void append( OutputIterator out, Expression* expr, const ResolvExpr::TypeEnvironment& env,
     53                        const ResolvExpr::OpenVarSet& openVars, const ResolvExpr::AssertionList& need,
    4654                        const ResolvExpr::Cost& cost, const ResolvExpr::Cost& cvtCost ) {
    47                 *out++ = ResolvExpr::Alternative{ expr, env, cost, cvtCost };
     55                *out++ = ResolvExpr::Alternative{ expr, env, openVars, need, cost, cvtCost };
    4856        }
    4957
    5058        /// Append alternative to an ExplodedActual
    5159        static inline void append( ResolvExpr::ExplodedActual& ea, Expression* expr,
    52                         const ResolvExpr::TypeEnvironment&, const ResolvExpr::Cost&, const ResolvExpr::Cost& ) {
     60                        const ResolvExpr::TypeEnvironment&, const ResolvExpr::OpenVarSet&,
     61                        const ResolvExpr::AssertionList&, const ResolvExpr::Cost&, const ResolvExpr::Cost& ) {
    5362                ea.exprs.emplace_back( expr );
    54                 /// xxx -- merge environment, cost?
     63                /// xxx -- merge environment, openVars, need, cost?
    5564        }
    5665
     
    6877                                        // distribute reference cast over all components
    6978                                        append( std::forward<Output>(out), distributeReference( alt.release_expr() ),
    70                                                 alt.env, alt.cost, alt.cvtCost );
     79                                                alt.env, alt.openVars, alt.need, alt.cost, alt.cvtCost );
    7180                                }
    7281                                // in tuple assignment, still need to handle the other cases, but only if not already handled here (don't want to output too many alternatives)
     
    102111                } else {
    103112                        // atomic (non-tuple) type - output a clone of the expression in a new alternative
    104                         append( std::forward<Output>(out), expr->clone(), alt.env, alt.cost, alt.cvtCost );
     113                        append( std::forward<Output>(out), expr->clone(), alt.env, alt.openVars, alt.need,
     114                                alt.cost, alt.cvtCost );
    105115                }
    106116        }
     
    127137                explode( alts.begin(), alts.end(), indexer, std::forward<Output>(out), isTupleAssign );
    128138        }
     139
     140const ast::Expr * distributeReference( const ast::Expr * );
     141
     142/// Append candidate to an OutputIterator of Candidates.
     143template<typename OutputIterator>
     144void append( OutputIterator out, const ast::Expr * expr, const ast::TypeEnvironment & env,
     145                const ast::OpenVarSet & open, const ast::AssertionList & need,
     146                const ResolvExpr::Cost & cost, const ResolvExpr::Cost & cvtCost ) {
     147        ast::TypeEnvironment copyEnv = env;
     148        ast::OpenVarSet copyOpen = open;
     149        ast::AssertionSet set;
     150        mergeAssertionSet( set, need );
     151        *out++ = std::make_shared<ResolvExpr::Candidate>( expr, std::move( copyEnv ),
     152                std::move( copyOpen ), std::move( set ), cost, cvtCost );
     153}
     154
     155/// Append candidate to an ExplodedArg.
     156static inline void append( ResolvExpr::ExplodedArg& ea, const ast::Expr * expr,
     157                const ast::TypeEnvironment&, const ast::OpenVarSet&,
     158                const ast::AssertionList&, const ResolvExpr::Cost&, const ResolvExpr::Cost& ) {
     159        // I'm not sure why most of the arguments are unused. But they were in the old version.
     160        ea.exprs.emplace_back( expr );
     161}
     162
     163/// Check if the expression is a cast to a reference type, return it if it is.
     164static inline const ast::CastExpr * isReferenceCast( const ast::Expr * expr ) {
     165        if ( const ast::CastExpr * cast = dynamic_cast< const ast::CastExpr * >( expr ) ) {
     166                if ( dynamic_cast< const ast::ReferenceType * >( cast->result.get() ) ) {
     167                        return cast;
     168                }
     169        }
     170        return nullptr;
     171}
     172
     173/// helper function (indirectely) used by explode
     174template< typename Output >
     175void explodeRecursive(
     176        const ast::CastExpr *, const ResolvExpr::Candidate &,
     177        const ast::SymbolTable &, Output &&
     178) {
     179}
     180
     181/// helper function used by explode
     182template< typename Output >
     183void explodeUnique(
     184        const ast::ptr< ast::Expr > & expr, const ResolvExpr::Candidate & arg,
     185        const ast::SymbolTable & symtab, Output && out, bool isTupleAssign
     186) {
     187        // Tuple assignment can use a faster method if it is cast. Uses recursive exploding.
     188        if ( isTupleAssign ) if ( const ast::CastExpr * castExpr = isReferenceCast( expr ) ) {
     189                ResolvExpr::CandidateList candidates;
     190                explodeUnique( castExpr->arg, arg, symtab, back_inserter( candidates ), true );
     191                for ( ResolvExpr::CandidateRef & cand : candidates ) {
     192                        // Distribute the reference cast over all components of the candidate.
     193                        append( std::forward<Output>(out), distributeReference( cand->expr ), cand->env,
     194                                cand->open, cand->need, cand->cost, cand->cvtCost );
     195                }
     196                return;
     197        }
     198        const ast::Type * res = expr->result->stripReferences();
     199        if ( const ast::TupleType * tupleType = dynamic_cast< const ast::TupleType * >( res ) ) {
     200                if ( const ast::ptr< ast::TupleExpr > & tupleExpr = expr.as< ast::TupleExpr >() ) {
     201                        // Open the tuple expr and continue on its components.
     202                        for ( const ast::Expr * expr : tupleExpr->exprs ) {
     203                                explodeUnique( expr, arg, symtab, std::forward<Output>(out), isTupleAssign );
     204                        }
     205                } else {
     206                        ast::ptr< ast::Expr > local = expr;
     207                        // Expressions which may have side effects require a single unique instance.
     208                        if ( Tuples::maybeImpureIgnoreUnique( local ) ) {
     209                                local = new ast::UniqueExpr( local->location, local );
     210                        }
     211                        // Cast a reference away to a value-type to allow further explosion.
     212                        if ( dynamic_cast< const ast::ReferenceType *>( local->result.get() ) ) {
     213                                local = new ast::CastExpr{ local, tupleType };
     214                        }
     215                        // Now we have to go across the tuple via indexing.
     216                        for ( unsigned int i = 0 ; i < tupleType->size() ; ++i ) {
     217                                ast::TupleIndexExpr * idx = new ast::TupleIndexExpr( local->location, local, i );
     218                                explodeUnique( idx, arg, symtab, std::forward<Output>(out), isTupleAssign );
     219                                // TODO: We need more input to figure out the exact lifetimes of these types.
     220                                // delete idx;
     221                        }
     222                        // delete local;
     223                }
     224        } else {
     225                // For atomic/non-tuple types, no explosion is used.
     226                append( std::forward<Output>(out), expr, arg.env, arg.open, arg.need, arg.cost,
     227                        arg.cvtCost );
     228        }
     229}
     230
     231/// expands a tuple-valued candidate into multiple candidates, each with a non-tuple type
     232template< typename Output >
     233void explode(
     234        const ResolvExpr::Candidate & arg, const ast::SymbolTable & symtab, Output && out,
     235        bool isTupleAssign = false
     236) {
     237        explodeUnique( arg.expr, arg, symtab, std::forward< Output >( out ), isTupleAssign );
     238}
     239
     240/// explode list of candidates into flattened list of candidates
     241template< typename Output >
     242void explode(
     243        const ResolvExpr::CandidateList & cands, const ast::SymbolTable & symtab, Output && out,
     244        bool isTupleAssign = false
     245) {
     246        for ( const ResolvExpr::CandidateRef & cand : cands ) {
     247                explode( *cand, symtab, std::forward< Output >( out ), isTupleAssign );
     248        }
     249}
     250
    129251} // namespace Tuples
    130252
  • src/Tuples/TupleAssignment.cc

    r7951100 rb067d9b  
    2222#include <vector>
    2323
     24#include "AST/Decl.hpp"
     25#include "AST/Init.hpp"
     26#include "AST/Pass.hpp"
     27#include "AST/Stmt.hpp"
     28#include "AST/TypeEnvironment.hpp"
    2429#include "CodeGen/OperatorTable.h"
    2530#include "Common/PassVisitor.h"
    2631#include "Common/UniqueName.h"             // for UniqueName
    27 #include "Common/utility.h"                // for zipWith
     32#include "Common/utility.h"                // for splice, zipWith
    2833#include "Explode.h"                       // for explode
    2934#include "InitTweak/GenInit.h"             // for genCtorInit
     
    5156
    5257namespace Tuples {
    53         class TupleAssignSpotter {
     58        class TupleAssignSpotter_old {
    5459          public:
    5560                // dispatcher for Tuple (multiple and mass) assignment operations
    56                 TupleAssignSpotter( ResolvExpr::AlternativeFinder & );
     61                TupleAssignSpotter_old( ResolvExpr::AlternativeFinder & );
    5762                void spot( UntypedExpr * expr, std::vector<ResolvExpr::AlternativeFinder> &args );
    5863
     
    6267                struct Matcher {
    6368                  public:
    64                         Matcher( TupleAssignSpotter &spotter, const ResolvExpr::AltList& lhs, const
    65                                 ResolvExpr::AltList& rhs );
     69                        Matcher( TupleAssignSpotter_old &spotter, const ResolvExpr::AltList& lhs,
     70                                const ResolvExpr::AltList& rhs );
    6671                        virtual ~Matcher() {}
     72
    6773                        virtual void match( std::list< Expression * > &out ) = 0;
    6874                        ObjectDecl * newObject( UniqueName & namer, Expression * expr );
     75
     76                        void combineState( const ResolvExpr::Alternative& alt ) {
     77                                compositeEnv.simpleCombine( alt.env );
     78                                ResolvExpr::mergeOpenVars( openVars, alt.openVars );
     79                                cloneAll( alt.need, need );
     80                        }
     81
     82                        void combineState( const ResolvExpr::AltList& alts ) {
     83                                for ( const ResolvExpr::Alternative& alt : alts ) { combineState( alt ); }
     84                        }
     85
    6986                        ResolvExpr::AltList lhs, rhs;
    70                         TupleAssignSpotter &spotter;
     87                        TupleAssignSpotter_old &spotter;
    7188                        ResolvExpr::Cost baseCost;
    7289                        std::list< ObjectDecl * > tmpDecls;
    7390                        ResolvExpr::TypeEnvironment compositeEnv;
     91                        ResolvExpr::OpenVarSet openVars;
     92                        ResolvExpr::AssertionSet need;
    7493                };
    7594
    7695                struct MassAssignMatcher : public Matcher {
    7796                  public:
    78                         MassAssignMatcher( TupleAssignSpotter &spotter, const ResolvExpr::AltList& lhs,
     97                        MassAssignMatcher( TupleAssignSpotter_old &spotter, const ResolvExpr::AltList& lhs,
    7998                                const ResolvExpr::AltList& rhs ) : Matcher(spotter, lhs, rhs) {}
    8099                        virtual void match( std::list< Expression * > &out );
     
    83102                struct MultipleAssignMatcher : public Matcher {
    84103                  public:
    85                         MultipleAssignMatcher( TupleAssignSpotter &spotter, const ResolvExpr::AltList& lhs,
     104                        MultipleAssignMatcher( TupleAssignSpotter_old &spotter, const ResolvExpr::AltList& lhs,
    86105                                const ResolvExpr::AltList& rhs ) : Matcher(spotter, lhs, rhs) {}
    87106                        virtual void match( std::list< Expression * > &out );
     
    122141        void handleTupleAssignment( ResolvExpr::AlternativeFinder & currentFinder, UntypedExpr * expr,
    123142                                std::vector<ResolvExpr::AlternativeFinder> &args ) {
    124                 TupleAssignSpotter spotter( currentFinder );
     143                TupleAssignSpotter_old spotter( currentFinder );
    125144                spotter.spot( expr, args );
    126145        }
    127146
    128         TupleAssignSpotter::TupleAssignSpotter( ResolvExpr::AlternativeFinder &f )
     147        TupleAssignSpotter_old::TupleAssignSpotter_old( ResolvExpr::AlternativeFinder &f )
    129148                : currentFinder(f) {}
    130149
    131         void TupleAssignSpotter::spot( UntypedExpr * expr,
     150        void TupleAssignSpotter_old::spot( UntypedExpr * expr,
    132151                        std::vector<ResolvExpr::AlternativeFinder> &args ) {
    133152                if (  NameExpr *op = dynamic_cast< NameExpr * >(expr->get_function()) ) {
     
    210229        }
    211230
    212         void TupleAssignSpotter::match() {
     231        void TupleAssignSpotter_old::match() {
    213232                assert ( matcher != 0 );
    214233
     
    245264                }
    246265
    247                 // extract expressions from the assignment alternatives to produce a list of assignments that
    248                 // together form a single alternative
     266                // extract expressions from the assignment alternatives to produce a list of assignments
     267                // that together form a single alternative
    249268                std::list< Expression *> solved_assigns;
    250269                for ( ResolvExpr::Alternative & alt : current ) {
    251270                        solved_assigns.push_back( alt.expr->clone() );
    252                 }
    253                 // combine assignment environments into combined expression environment
    254                 simpleCombineEnvironments( current.begin(), current.end(), matcher->compositeEnv );
     271                        matcher->combineState( alt );
     272                }
     273
    255274                // xxx -- was push_front
    256                 currentFinder.get_alternatives().push_back( ResolvExpr::Alternative(
    257                         new TupleAssignExpr(solved_assigns, matcher->tmpDecls), matcher->compositeEnv,
    258                         ResolvExpr::sumCost( current ) + matcher->baseCost ) );
    259         }
    260 
    261         TupleAssignSpotter::Matcher::Matcher( TupleAssignSpotter &spotter,
     275                currentFinder.get_alternatives().push_back( ResolvExpr::Alternative{
     276                        new TupleAssignExpr{ solved_assigns, matcher->tmpDecls }, matcher->compositeEnv,
     277                        matcher->openVars,
     278                        ResolvExpr::AssertionList( matcher->need.begin(), matcher->need.end() ),
     279                        ResolvExpr::sumCost( current ) + matcher->baseCost } );
     280        }
     281
     282        TupleAssignSpotter_old::Matcher::Matcher( TupleAssignSpotter_old &spotter,
    262283                const ResolvExpr::AltList &lhs, const ResolvExpr::AltList &rhs )
    263284        : lhs(lhs), rhs(rhs), spotter(spotter),
    264285          baseCost( ResolvExpr::sumCost( lhs ) + ResolvExpr::sumCost( rhs ) ) {
    265                 simpleCombineEnvironments( lhs.begin(), lhs.end(), compositeEnv );
    266                 simpleCombineEnvironments( rhs.begin(), rhs.end(), compositeEnv );
     286                combineState( lhs );
     287                combineState( rhs );
    267288        }
    268289
     
    297318        };
    298319
    299         ObjectDecl * TupleAssignSpotter::Matcher::newObject( UniqueName & namer, Expression * expr ) {
     320        ObjectDecl * TupleAssignSpotter_old::Matcher::newObject( UniqueName & namer, Expression * expr ) {
    300321                assert( expr->result && ! expr->get_result()->isVoid() );
    301322                ObjectDecl * ret = new ObjectDecl( namer.newName(), Type::StorageClasses(), LinkageSpec::Cforall, nullptr, expr->result->clone(), new SingleInit( expr->clone() ) );
     
    313334        }
    314335
    315         void TupleAssignSpotter::MassAssignMatcher::match( std::list< Expression * > &out ) {
     336        void TupleAssignSpotter_old::MassAssignMatcher::match( std::list< Expression * > &out ) {
    316337                static UniqueName lhsNamer( "__massassign_L" );
    317338                static UniqueName rhsNamer( "__massassign_R" );
     
    331352        }
    332353
    333         void TupleAssignSpotter::MultipleAssignMatcher::match( std::list< Expression * > &out ) {
     354        void TupleAssignSpotter_old::MultipleAssignMatcher::match( std::list< Expression * > &out ) {
    334355                static UniqueName lhsNamer( "__multassign_L" );
    335356                static UniqueName rhsNamer( "__multassign_R" );
     
    361382                }
    362383        }
     384
     385namespace {
     386        /// true if `expr` is of tuple type
     387        bool isTuple( const ast::Expr * expr ) {
     388                if ( ! expr ) return false;
     389                assert( expr->result );
     390                return dynamic_cast< const ast::TupleType * >( expr->result->stripReferences() );
     391        }
     392
     393        /// true if `expr` is of tuple type or a reference to one
     394        bool refToTuple( const ast::Expr * expr ) {
     395                assert( expr->result );
     396                // check for function returning tuple of reference types
     397                if ( auto castExpr = dynamic_cast< const ast::CastExpr * >( expr ) ) {
     398                        return refToTuple( castExpr->arg );
     399                } else {
     400                        return isTuple( expr );
     401                }
     402        }
     403
     404        /// Dispatcher for tuple (multiple and mass) assignment operations
     405        class TupleAssignSpotter_new final {
     406                /// Actually finds tuple assignment operations, by subclass
     407                struct Matcher {
     408                        ResolvExpr::CandidateList lhs, rhs;
     409                        TupleAssignSpotter_new & spotter;
     410                        CodeLocation location;
     411                        ResolvExpr::Cost baseCost;
     412                        std::vector< ast::ptr< ast::ObjectDecl > > tmpDecls;
     413                        ast::TypeEnvironment env;
     414                        ast::OpenVarSet open;
     415                        ast::AssertionSet need;
     416
     417                        void combineState( const ResolvExpr::Candidate & cand ) {
     418                                env.simpleCombine( cand.env );
     419                                ast::mergeOpenVars( open, cand.open );
     420                                need.insert( cand.need.begin(), cand.need.end() );
     421                        }
     422
     423                        Matcher(
     424                                TupleAssignSpotter_new & s, const CodeLocation & loc,
     425                                const ResolvExpr::CandidateList & l, const ResolvExpr::CandidateList & r )
     426                        : lhs( l ), rhs( r ), spotter( s ), location( loc ),
     427                          baseCost( ResolvExpr::sumCost( lhs ) + ResolvExpr::sumCost( rhs ) ), tmpDecls(),
     428                          env(), open(), need() {
     429                                for ( auto & cand : lhs ) combineState( *cand );
     430                                for ( auto & cand : rhs ) combineState( *cand );
     431                        }
     432                        virtual ~Matcher() = default;
     433
     434                        virtual std::vector< ast::ptr< ast::Expr > > match() = 0;
     435
     436                        /// removes environments from subexpressions within statement expressions, which could
     437                        /// throw off later passes like those in Box which rely on PolyMutator, and adds the
     438                        /// bindings to the env
     439                        struct EnvRemover {
     440                                /// environment to hoist ExprStmt environments to
     441                                ast::TypeEnvironment & tenv;
     442
     443                                EnvRemover( ast::TypeEnvironment & e ) : tenv( e ) {}
     444
     445                                const ast::ExprStmt * previsit( const ast::ExprStmt * stmt ) {
     446                                        if ( stmt->expr->env ) {
     447                                                tenv.add( *stmt->expr->env );
     448                                                ast::ExprStmt * mut = mutate( stmt );
     449                                                mut->expr.get_and_mutate()->env = nullptr;
     450                                                return mut;
     451                                        }
     452                                        return stmt;
     453                                }
     454                        };
     455
     456                        ast::ObjectDecl * newObject( UniqueName & namer, const ast::Expr * expr ) {
     457                                assert( expr->result && ! expr->result->isVoid() );
     458
     459                                ast::ObjectDecl * ret = new ast::ObjectDecl{
     460                                        location, namer.newName(), expr->result, new ast::SingleInit{ location, expr },
     461                                        ast::Storage::Classes{}, ast::Linkage::Cforall };
     462
     463                                // if expression type is a reference, just need an initializer, otherwise construct
     464                                if ( ! expr->result.as< ast::ReferenceType >() ) {
     465                                        // resolve ctor/dtor for the new object
     466                                        ast::ptr< ast::Init > ctorInit = ResolvExpr::resolveCtorInit(
     467                                                        InitTweak::genCtorInit( location, ret ), spotter.crntFinder.symtab );
     468                                        // remove environments from subexpressions of stmtExpr
     469                                        ast::Pass< EnvRemover > rm{ env };
     470                                        ret->init = ctorInit->accept( rm );
     471                                }
     472
     473                                PRINT( std::cerr << "new object: " << ret << std::endl; )
     474                                return ret;
     475                        }
     476
     477                        ast::UntypedExpr * createFunc(
     478                                const std::string & fname, const ast::ObjectDecl * left,
     479                                const ast::ObjectDecl * right
     480                        ) {
     481                                assert( left );
     482                                std::vector< ast::ptr< ast::Expr > > args;
     483                                args.emplace_back( new ast::VariableExpr{ location, left } );
     484                                if ( right ) { args.emplace_back( new ast::VariableExpr{ location, right } ); }
     485
     486                                if ( left->type->referenceDepth() > 1 && CodeGen::isConstructor( fname ) ) {
     487                                        args.front() = new ast::AddressExpr{ location, args.front() };
     488                                        if ( right ) { args.back() = new ast::AddressExpr{ location, args.back() }; }
     489                                        return new ast::UntypedExpr{
     490                                                location, new ast::NameExpr{ location, "?=?" }, std::move(args) };
     491                                } else {
     492                                        return new ast::UntypedExpr{
     493                                                location, new ast::NameExpr{ location, fname }, std::move(args) };
     494                                }
     495                        }
     496                };
     497
     498                /// Finds mass-assignment operations
     499                struct MassAssignMatcher final : public Matcher {
     500                        MassAssignMatcher(
     501                                TupleAssignSpotter_new & s, const CodeLocation & loc,
     502                                const ResolvExpr::CandidateList & l, const ResolvExpr::CandidateList & r )
     503                        : Matcher( s, loc, l, r ) {}
     504
     505                        std::vector< ast::ptr< ast::Expr > > match() override {
     506                                static UniqueName lhsNamer( "__massassign_L" );
     507                                static UniqueName rhsNamer( "__massassign_R" );
     508                                // empty tuple case falls into this matcher
     509                                assert( lhs.empty() ? rhs.empty() : rhs.size() <= 1 );
     510
     511                                ast::ptr< ast::ObjectDecl > rtmp =
     512                                        rhs.size() == 1 ? newObject( rhsNamer, rhs.front()->expr ) : nullptr;
     513
     514                                std::vector< ast::ptr< ast::Expr > > out;
     515                                for ( ResolvExpr::CandidateRef & lhsCand : lhs ) {
     516                                        // create a temporary object for each value in the LHS and create a call
     517                                        // involving the RHS
     518                                        ast::ptr< ast::ObjectDecl > ltmp = newObject( lhsNamer, lhsCand->expr );
     519                                        out.emplace_back( createFunc( spotter.fname, ltmp, rtmp ) );
     520                                        tmpDecls.emplace_back( std::move( ltmp ) );
     521                                }
     522                                if ( rtmp ) tmpDecls.emplace_back( std::move( rtmp ) );
     523
     524                                return out;
     525                        }
     526                };
     527
     528                /// Finds multiple-assignment operations
     529                struct MultipleAssignMatcher final : public Matcher {
     530                        MultipleAssignMatcher(
     531                                TupleAssignSpotter_new & s, const CodeLocation & loc,
     532                                const ResolvExpr::CandidateList & l, const ResolvExpr::CandidateList & r )
     533                        : Matcher( s, loc, l, r ) {}
     534
     535                        std::vector< ast::ptr< ast::Expr > > match() override {
     536                                static UniqueName lhsNamer( "__multassign_L" );
     537                                static UniqueName rhsNamer( "__multassign_R" );
     538
     539                                if ( lhs.size() != rhs.size() ) return {};
     540
     541                                // produce a new temporary object for each value in the LHS and RHS and pairwise
     542                                // create the calls
     543                                std::vector< ast::ptr< ast::ObjectDecl > > ltmp, rtmp;
     544
     545                                std::vector< ast::ptr< ast::Expr > > out;
     546                                for ( unsigned i = 0; i < lhs.size(); ++i ) {
     547                                        ResolvExpr::CandidateRef & lhsCand = lhs[i];
     548                                        ResolvExpr::CandidateRef & rhsCand = rhs[i];
     549
     550                                        // convert RHS to LHS type minus one reference -- important for case where LHS
     551                                        // is && and RHS is lvalue
     552                                        auto lhsType = lhsCand->expr->result.strict_as< ast::ReferenceType >();
     553                                        rhsCand->expr = new ast::CastExpr{ rhsCand->expr, lhsType->base };
     554                                        ast::ptr< ast::ObjectDecl > lobj = newObject( lhsNamer, lhsCand->expr );
     555                                        ast::ptr< ast::ObjectDecl > robj = newObject( rhsNamer, rhsCand->expr );
     556                                        out.emplace_back( createFunc( spotter.fname, lobj, robj ) );
     557                                        ltmp.emplace_back( std::move( lobj ) );
     558                                        rtmp.emplace_back( std::move( robj ) );
     559
     560                                        // resolve the cast expression so that rhsCand return type is bound by the cast
     561                                        // type as needed, and transfer the resulting environment
     562                                        ResolvExpr::CandidateFinder finder{ spotter.crntFinder.symtab, env };
     563                                        finder.find( rhsCand->expr, ResolvExpr::ResolvMode::withAdjustment() );
     564                                        assert( finder.candidates.size() == 1 );
     565                                        env = std::move( finder.candidates.front()->env );
     566                                }
     567
     568                                splice( tmpDecls, ltmp );
     569                                splice( tmpDecls, rtmp );
     570
     571                                return out;
     572                        }
     573                };
     574
     575                ResolvExpr::CandidateFinder & crntFinder;
     576                std::string fname;
     577                std::unique_ptr< Matcher > matcher;
     578
     579        public:
     580                TupleAssignSpotter_new( ResolvExpr::CandidateFinder & f )
     581                : crntFinder( f ), fname(), matcher() {}
     582
     583                // find left- and right-hand-sides for mass or multiple assignment
     584                void spot(
     585                        const ast::UntypedExpr * expr, std::vector< ResolvExpr::CandidateFinder > & args
     586                ) {
     587                        if ( auto op = expr->func.as< ast::NameExpr >() ) {
     588                                // skip non-assignment functions
     589                                if ( ! CodeGen::isCtorDtorAssign( op->name ) ) return;
     590                                fname = op->name;
     591
     592                                // handled by CandidateFinder if applicable (both odd cases)
     593                                if ( args.empty() || ( args.size() == 1 && CodeGen::isAssignment( fname ) ) ) {
     594                                        return;
     595                                }
     596
     597                                // look over all possible left-hand-side
     598                                for ( ResolvExpr::CandidateRef & lhsCand : args[0] ) {
     599                                        // skip non-tuple LHS
     600                                        if ( ! refToTuple( lhsCand->expr ) ) continue;
     601
     602                                        // explode is aware of casts - ensure every LHS is sent into explode with a
     603                                        // reference cast
     604                                        if ( ! lhsCand->expr.as< ast::CastExpr >() ) {
     605                                                lhsCand->expr = new ast::CastExpr{
     606                                                        lhsCand->expr, new ast::ReferenceType{ lhsCand->expr->result } };
     607                                        }
     608
     609                                        // explode the LHS so that each field of a tuple-valued expr is assigned
     610                                        ResolvExpr::CandidateList lhs;
     611                                        explode( *lhsCand, crntFinder.symtab, back_inserter(lhs), true );
     612                                        for ( ResolvExpr::CandidateRef & cand : lhs ) {
     613                                                // each LHS value must be a reference - some come in with a cast, if not
     614                                                // just cast to reference here
     615                                                if ( ! cand->expr->result.as< ast::ReferenceType >() ) {
     616                                                        cand->expr = new ast::CastExpr{
     617                                                                cand->expr, new ast::ReferenceType{ cand->expr->result } };
     618                                                }
     619                                        }
     620
     621                                        if ( args.size() == 1 ) {
     622                                                // mass default-initialization/destruction
     623                                                ResolvExpr::CandidateList rhs{};
     624                                                matcher.reset( new MassAssignMatcher{ *this, expr->location, lhs, rhs } );
     625                                                match();
     626                                        } else if ( args.size() == 2 ) {
     627                                                for ( const ResolvExpr::CandidateRef & rhsCand : args[1] ) {
     628                                                        ResolvExpr::CandidateList rhs;
     629                                                        if ( isTuple( rhsCand->expr ) ) {
     630                                                                // multiple assignment
     631                                                                explode( *rhsCand, crntFinder.symtab, back_inserter(rhs), true );
     632                                                                matcher.reset(
     633                                                                        new MultipleAssignMatcher{ *this, expr->location, lhs, rhs } );
     634                                                        } else {
     635                                                                // mass assignment
     636                                                                rhs.emplace_back( rhsCand );
     637                                                                matcher.reset(
     638                                                                        new MassAssignMatcher{ *this, expr->location, lhs, rhs } );
     639                                                        }
     640                                                        match();
     641                                                }
     642                                        } else {
     643                                                // expand all possible RHS possibilities
     644                                                std::vector< ResolvExpr::CandidateList > rhsCands;
     645                                                combos(
     646                                                        std::next( args.begin(), 1 ), args.end(), back_inserter( rhsCands ) );
     647                                                for ( const ResolvExpr::CandidateList & rhsCand : rhsCands ) {
     648                                                        // multiple assignment
     649                                                        ResolvExpr::CandidateList rhs;
     650                                                        explode( rhsCand, crntFinder.symtab, back_inserter(rhs), true );
     651                                                        matcher.reset(
     652                                                                new MultipleAssignMatcher{ *this, expr->location, lhs, rhs } );
     653                                                        match();
     654                                                }
     655                                        }
     656                                }
     657                        }
     658                }
     659
     660                void match() {
     661                        assert( matcher );
     662
     663                        std::vector< ast::ptr< ast::Expr > > newAssigns = matcher->match();
     664
     665                        if ( ! ( matcher->lhs.empty() && matcher->rhs.empty() ) ) {
     666                                // if both LHS and RHS are empty than this is the empty tuple case, wherein it's
     667                                // okay for newAssigns to be empty. Otherwise, return early so that no new
     668                                // candidates are generated
     669                                if ( newAssigns.empty() ) return;
     670                        }
     671
     672                        ResolvExpr::CandidateList crnt;
     673                        // now resolve new assignments
     674                        for ( const ast::Expr * expr : newAssigns ) {
     675                                PRINT(
     676                                        std::cerr << "== resolving tuple assign ==" << std::endl;
     677                                        std::cerr << expr << std::endl;
     678                                )
     679
     680                                ResolvExpr::CandidateFinder finder{ crntFinder.symtab, matcher->env };
     681
     682                                try {
     683                                        finder.find( expr, ResolvExpr::ResolvMode::withAdjustment() );
     684                                } catch (...) {
     685                                        // no match is not failure, just that this tuple assignment is invalid
     686                                        return;
     687                                }
     688
     689                                ResolvExpr::CandidateList & cands = finder.candidates;
     690                                assert( cands.size() == 1 );
     691                                assert( cands.front()->expr );
     692                                crnt.emplace_back( std::move( cands.front() ) );
     693                        }
     694
     695                        // extract expressions from the assignment candidates to produce a list of assignments
     696                        // that together form a sigle candidate
     697                        std::vector< ast::ptr< ast::Expr > > solved;
     698                        for ( ResolvExpr::CandidateRef & cand : crnt ) {
     699                                solved.emplace_back( cand->expr );
     700                                matcher->combineState( *cand );
     701                        }
     702
     703                        crntFinder.candidates.emplace_back( std::make_shared< ResolvExpr::Candidate >(
     704                                new ast::TupleAssignExpr{
     705                                        matcher->location, std::move( solved ), std::move( matcher->tmpDecls ) },
     706                                std::move( matcher->env ), std::move( matcher->open ), std::move( matcher->need ),
     707                                ResolvExpr::sumCost( crnt ) + matcher->baseCost ) );
     708                }
     709        };
     710} // anonymous namespace
     711
     712void handleTupleAssignment(
     713        ResolvExpr::CandidateFinder & finder, const ast::UntypedExpr * assign,
     714        std::vector< ResolvExpr::CandidateFinder > & args
     715) {
     716        TupleAssignSpotter_new spotter{ finder };
     717        spotter.spot( assign, args );
     718}
     719
    363720} // namespace Tuples
    364721
  • src/Tuples/TupleExpansion.cc

    r7951100 rb067d9b  
    99// Author           : Rodolfo G. Esteves
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Jun 21 17:35:04 2017
    13 // Update Count     : 19
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Fri Jul 19 14:39:00 2019
     13// Update Count     : 22
    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
     
    299304                // produce the TupleType which aggregates the types of the exprs
    300305                std::list< Type * > types;
    301                 Type::Qualifiers qualifiers( Type::Const | Type::Volatile | Type::Restrict | Type::Lvalue | Type::Atomic | Type::Mutex );
     306                Type::Qualifiers qualifiers( Type::Const | Type::Volatile | Type::Restrict | Type::Atomic | Type::Mutex );
    302307                for ( Expression * expr : exprs ) {
    303308                        assert( expr->get_result() );
     
    314319                return new TupleType( qualifiers, types );
    315320        }
     321        const ast::Type * makeTupleType( const std::vector<ast::ptr<ast::Expr>> & exprs ) {
     322                // produce the TupleType which aggregates the types of the exprs
     323                std::vector<ast::ptr<ast::Type>> types;
     324                ast::CV::Qualifiers quals{
     325                        ast::CV::Const | ast::CV::Volatile | ast::CV::Restrict | ast::CV::Lvalue |
     326                        ast::CV::Atomic | ast::CV::Mutex };
     327
     328                for ( const ast::Expr * expr : exprs ) {
     329                        assert( expr->result );
     330                        // if the type of any expr is void, the type of the entire tuple is void
     331                        if ( expr->result->isVoid() ) return new ast::VoidType{};
     332
     333                        // qualifiers on the tuple type are the qualifiers that exist on all components
     334                        quals &= expr->result->qualifiers;
     335
     336                        types.emplace_back( expr->result );
     337                }
     338
     339                if ( exprs.empty() ) { quals = ast::CV::Qualifiers{}; }
     340                return new ast::TupleType{ std::move(types), quals };
     341        }
    316342
    317343        TypeInstType * isTtype( Type * type ) {
     
    324350        }
    325351
     352        const TypeInstType * isTtype( const Type * type ) {
     353                if ( const TypeInstType * inst = dynamic_cast< const TypeInstType * >( type ) ) {
     354                        if ( inst->baseType && inst->baseType->kind == TypeDecl::Ttype ) {
     355                                return inst;
     356                        }
     357                }
     358                return nullptr;
     359        }
     360
     361        const ast::TypeInstType * isTtype( const ast::Type * type ) {
     362                if ( const ast::TypeInstType * inst = dynamic_cast< const ast::TypeInstType * >( type ) ) {
     363                        if ( inst->base && inst->base->kind == ast::TypeVar::Ttype ) {
     364                                return inst;
     365                        }
     366                }
     367                return nullptr;
     368        }
     369
    326370        namespace {
    327371                /// determines if impurity (read: side-effects) may exist in a piece of code. Currently gives a very crude approximation, wherein any function call expression means the code may be impure
     
    329373                        ImpurityDetector( bool ignoreUnique ) : ignoreUnique( ignoreUnique ) {}
    330374
    331                         void previsit( ApplicationExpr * appExpr ) {
     375                        void previsit( const ApplicationExpr * appExpr ) {
    332376                                visit_children = false;
    333                                 if ( DeclarationWithType * function = InitTweak::getFunction( appExpr ) ) {
    334                                         if ( function->get_linkage() == LinkageSpec::Intrinsic ) {
    335                                                 if ( function->get_name() == "*?" || function->get_name() == "?[?]" ) {
     377                                if ( const DeclarationWithType * function = InitTweak::getFunction( appExpr ) ) {
     378                                        if ( function->linkage == LinkageSpec::Intrinsic ) {
     379                                                if ( function->name == "*?" || function->name == "?[?]" ) {
    336380                                                        // intrinsic dereference, subscript are pure, but need to recursively look for impurity
    337381                                                        visit_children = true;
     
    342386                                maybeImpure = true;
    343387                        }
    344                         void previsit( UntypedExpr * ) { maybeImpure = true; visit_children = false; }
    345                         void previsit( UniqueExpr * ) {
     388                        void previsit( const UntypedExpr * ) { maybeImpure = true; visit_children = false; }
     389                        void previsit( const UniqueExpr * ) {
    346390                                if ( ignoreUnique ) {
    347391                                        // bottom out at unique expression.
     
    358402        } // namespace
    359403
    360         bool maybeImpure( Expression * expr ) {
     404        bool maybeImpure( const Expression * expr ) {
    361405                PassVisitor<ImpurityDetector> detector( false );
    362406                expr->accept( detector );
     
    364408        }
    365409
    366         bool maybeImpureIgnoreUnique( Expression * expr ) {
     410        bool maybeImpureIgnoreUnique( const Expression * expr ) {
    367411                PassVisitor<ImpurityDetector> detector( true );
    368412                expr->accept( detector );
  • src/Tuples/Tuples.h

    r7951100 rb067d9b  
    99// Author           : Rodolfo G. Esteves
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Jul 22 09:55:00 2017
    13 // Update Count     : 16
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Tue Jun 18 09:36:00 2019
     13// Update Count     : 18
    1414//
    1515
     
    1919#include <vector>
    2020
     21#include "AST/Fwd.hpp"
     22#include "AST/Node.hpp"
    2123#include "SynTree/Expression.h"
    2224#include "SynTree/Declaration.h"
     
    2426
    2527#include "ResolvExpr/AlternativeFinder.h"
     28#include "ResolvExpr/CandidateFinder.hpp"
    2629
    2730namespace Tuples {
    2831        // TupleAssignment.cc
    29         void handleTupleAssignment( ResolvExpr::AlternativeFinder & currentFinder, UntypedExpr * assign, 
     32        void handleTupleAssignment( ResolvExpr::AlternativeFinder & currentFinder, UntypedExpr * assign,
    3033                std::vector< ResolvExpr::AlternativeFinder >& args );
    31        
     34        void handleTupleAssignment(
     35                ResolvExpr::CandidateFinder & finder, const ast::UntypedExpr * assign,
     36                std::vector< ResolvExpr::CandidateFinder > & args );
     37
    3238        // TupleExpansion.cc
    3339        /// expands z.[a, b.[x, y], c] into [z.a, z.b.x, z.b.y, z.c], inserting UniqueExprs as appropriate
     
    4248        /// returns VoidType if any of the expressions have Voidtype, otherwise TupleType of the Expression result types
    4349        Type * makeTupleType( const std::list< Expression * > & exprs );
     50        const ast::Type * makeTupleType( const std::vector<ast::ptr<ast::Expr>> & exprs );
    4451
    4552        /// returns a TypeInstType if `type` is a ttype, nullptr otherwise
    4653        TypeInstType * isTtype( Type * type );
     54        const TypeInstType * isTtype( const Type * type );
     55        const ast::TypeInstType * isTtype( const ast::Type * type );
    4756
    4857        /// returns true if the expression may contain side-effects.
    49         bool maybeImpure( Expression * expr );
     58        bool maybeImpure( const Expression * expr );
     59        bool maybeImpure( const ast::Expr * expr );
    5060
    51         /// returns true if the expression may contain side-effect, ignoring the presence of unique expressions.
    52         bool maybeImpureIgnoreUnique( Expression * expr );
     61        /// Returns true if the expression may contain side-effect,
     62        /// ignoring the presence of unique expressions.
     63        bool maybeImpureIgnoreUnique( const Expression * expr );
     64        bool maybeImpureIgnoreUnique( const ast::Expr * expr );
    5365} // namespace Tuples
    5466
  • src/Tuples/module.mk

    r7951100 rb067d9b  
    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 \
     18        Tuples/Tuples.cc
     19SRCDEMANGLE += Tuples/TupleAssignment.cc Tuples/TupleExpansion.cc Tuples/Explode.cc \
     20        Tuples/Tuples.cc
  • src/Virtual/ExpandCasts.cc

    r7951100 rb067d9b  
    147147                                //              )
    148148                                //      ),
    149                         new UntypedExpr( new NameExpr( "__cfa__virtual_cast" ), {
     149                        new ApplicationExpr( VariableExpr::functionPointer( vcast_decl ), {
    150150                                        new CastExpr(
    151151                                                new AddressExpr( new VariableExpr( table ) ),
    152152                                                pointer_to_pvt(1)
    153                                                 ),
     153                                        ),
    154154                                        new CastExpr(
    155155                                                castExpr->get_arg(),
    156156                                                pointer_to_pvt(2)
    157                                                 )
    158                                 } ),
     157                                        )
     158                        } ),
    159159                        castExpr->get_result()->clone()
    160                         );
     160                );
    161161
    162162                castExpr->set_arg( nullptr );
  • src/include/cassert

    r7951100 rb067d9b  
    99// Author           : Peter A. Buhr
    1010// Created On       : Thu Aug 18 13:19:26 2016
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Aug  1 11:56:01 2017
    13 // Update Count     : 16
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Mon Jun  3 13:11:00 2017
     13// Update Count     : 18
    1414//
    1515
     
    1919
    2020#include_next <cassert>
     21
     22#include <string>
     23
     24template < typename ... Params >
     25std::string toString( const Params & ... params );
    2126
    2227#ifdef NDEBUG
     
    4045template<typename T, typename U>
    4146static inline T strict_dynamic_cast( const U & src ) {
     47        assert(src);
    4248        T ret = dynamic_cast<T>(src);
    4349        assertf(ret, "%s", toString(src).c_str());
     
    4551}
    4652
     53template<typename T, decltype(nullptr) null, typename U>
     54static inline T strict_dynamic_cast( const U & src ) {
     55        return src ? strict_dynamic_cast<T, U>( src ) : nullptr;
     56}
     57
     58extern void abort(const char *fmt, ...  ) noexcept __attribute__((noreturn, format(printf, 1, 2)));
    4759// Local Variables: //
    4860// tab-width: 4 //
  • src/main.cc

    r7951100 rb067d9b  
    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 Jun  6 15:51:47 2018
    13 // Update Count     : 498
     12// Last Modified On : Fri Aug 23 06:50:08 2019
     13// Update Count     : 607
    1414//
    1515
     
    1717#include <execinfo.h>                       // for backtrace, backtrace_symbols
    1818#include <getopt.h>                         // for no_argument, optind, geto...
    19 #include <signal.h>                         // for signal, SIGABRT, SIGSEGV
    2019#include <cassert>                          // for assertf
    2120#include <cstdio>                           // for fopen, FILE, fclose, stdin
    2221#include <cstdlib>                          // for exit, free, abort, EXIT_F...
     22#include <csignal>                         // for signal, SIGABRT, SIGSEGV
    2323#include <cstring>                          // for index
    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
    2829#include <string>                           // for char_traits, operator<<
    2930
     31#include "CompilationState.h"
    3032#include "../config.h"                      // for CFA_LIBDIR
    3133#include "CodeGen/FixMain.h"                // for FixMain
     
    3335#include "CodeGen/Generate.h"               // for generate
    3436#include "CodeTools/DeclStats.h"            // for printDeclStats
     37#include "CodeTools/ResolvProtoDump.h"      // for dumpAsResolvProto
    3538#include "CodeTools/TrackLoc.h"             // for fillLocations
    3639#include "Common/CompilerError.h"           // for CompilerError
    37 #include "Common/Heap.h"
     40#include "Common/Stats.h"
    3841#include "Common/PassVisitor.h"
    3942#include "Common/SemanticError.h"           // for SemanticError
     
    6164#include "Virtual/ExpandCasts.h"            // for expandCasts
    6265
     66
    6367using namespace std;
    6468
    65 #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 )                  \
    6687        if ( errorp ) { cerr << name << endl; } \
    67         HeapStats::newPass(name);               \
    68         pass;
     88        NewPass(name);                          \
     89        Stats::Time::StartBlock(name);          \
     90        pass;                                   \
     91        Stats::Time::StopBlock();
    6992
    7093LinkageSpec::Spec linkage = LinkageSpec::Cforall;
     
    7295DeclarationNode * parseTree = nullptr;                                  // program parse tree
    7396
    74 extern int yydebug;                                                                             // set for -g flag (Grammar)
    75 bool
    76         astp = false,
    77         bresolvep = false,
    78         bboxp = false,
    79         bcodegenp = false,
    80         ctorinitp = false,
    81         declstatsp = false,
    82         exprp = false,
    83         expraltp = false,
    84         genericsp = false,
    85         libcfap = false,
    86         nopreludep = false,
    87         noprotop = false,
    88         nomainp = false,
    89         parsep = false,
    90         resolvep = false,                                                                       // used in AlternativeFinder
    91         symtabp = false,
    92         treep = false,
    93         tuplep = false,
    94         validp = false,
    95         errorp = false,
    96         codegenp = false,
    97         prettycodegenp = false,
    98         linemarks = false;
    99 
    100 static void parse_cmdline( int argc, char *argv[], const char *& filename );
     97static bool waiting_for_gdb = false;                                    // flag to set cfa-cpp to wait for gdb on start
     98
     99static std::string PreludeDirector = "";
     100
     101static void parse_cmdline( int argc, char *argv[] );
    101102static void parse( FILE * input, LinkageSpec::Spec linkage, bool shouldExit = false );
    102103static void dump( list< Declaration * > & translationUnit, ostream & out = cout );
     
    152153} // backtrace
    153154
    154 void sigSegvBusHandler( int sig_num ) {
     155static void sigSegvBusHandler( int sig_num ) {
    155156        cerr << "*CFA runtime error* program cfa-cpp terminated with "
    156157                 <<     (sig_num == SIGSEGV ? "segment fault" : "bus error")
     
    158159        backtrace( 2 );                                                                         // skip first 2 stack frames
    159160        //_exit( EXIT_FAILURE );
    160         abort();
     161        abort();                                                                                        // cause core dump for debugging
    161162} // sigSegvBusHandler
    162163
    163 void sigAbortHandler( __attribute__((unused)) int sig_num ) {
     164static void sigAbortHandler( __attribute__((unused)) int sig_num ) {
    164165        backtrace( 6 );                                                                         // skip first 6 stack frames
    165166        signal( SIGABRT, SIG_DFL);                                                      // reset default signal handler
    166     raise( SIGABRT );                                                                   // reraise SIGABRT
     167        raise( SIGABRT );                                                                       // reraise SIGABRT
    167168} // sigAbortHandler
    168 
    169169
    170170int main( int argc, char * argv[] ) {
    171171        FILE * input;                                                                           // use FILE rather than istream because yyin is FILE
    172         ostream *output = & cout;
    173         const char *filename = nullptr;
     172        ostream * output = & cout;
    174173        list< Declaration * > translationUnit;
    175174
     
    183182        // } // for
    184183
    185         parse_cmdline( argc, argv, filename );                          // process command-line arguments
     184        parse_cmdline( argc, argv );                                            // process command-line arguments
    186185        CodeGen::FixMain::setReplaceMain( !nomainp );
     186
     187        if ( waiting_for_gdb ) {
     188                std::cerr << "Waiting for gdb" << std::endl;
     189                std::cerr << "run :" << std::endl;
     190                std::cerr << "  gdb attach " << getpid() << std::endl;
     191                raise(SIGSTOP);
     192        } // if
    187193
    188194        try {
     
    190196                if ( optind < argc ) {                                                  // any commands after the flags ? => input file name
    191197                        input = fopen( argv[ optind ], "r" );
    192                         assertf( input, "cannot open %s\n", argv[ optind ] );
    193                         // if running cfa-cpp directly, might forget to pass -F option (and really shouldn't have to)
    194                         if ( filename == nullptr ) filename = argv[ optind ];
    195                         // prelude filename comes in differently
    196                         if ( libcfap ) filename = "prelude.cf";
     198                        assertf( input, "cannot open %s because %s\n", argv[ optind ], strerror( errno ) );
    197199                        optind += 1;
    198200                } else {                                                                                // no input file name
    199201                        input = stdin;
    200                         // if running cfa-cpp directly, might forget to pass -F option. Since this takes from stdin, pass
    201                         // a fake name along
    202                         if ( filename == nullptr ) filename = "stdin";
    203                 } // if
     202                } // if
     203
     204                Stats::Time::StartGlobal();
     205                NewPass("Parse");
     206                Stats::Time::StartBlock("Parse");
    204207
    205208                // read in the builtins, extras, and the prelude
     
    207210                        // -l is for initial build ONLY and builtins.cf is not in the lib directory so access it here.
    208211
     212                        assertf( !PreludeDirector.empty(), "Can't find prelude without option --prelude-dir must be used." );
     213
    209214                        // Read to gcc builtins, if not generating the cfa library
    210                         FILE * gcc_builtins = fopen( libcfap | treep ? "../prelude/gcc-builtins.cf" : CFA_LIBDIR "/gcc-builtins.cf", "r" );
     215                        FILE * gcc_builtins = fopen( (PreludeDirector + "/gcc-builtins.cf").c_str(), "r" );
    211216                        assertf( gcc_builtins, "cannot open gcc-builtins.cf\n" );
    212217                        parse( gcc_builtins, LinkageSpec::Compiler );
    213218
    214219                        // read the extra prelude in, if not generating the cfa library
    215                         FILE * extras = fopen( libcfap | treep ? "../prelude/extras.cf" : CFA_LIBDIR "/extras.cf", "r" );
     220                        FILE * extras = fopen( (PreludeDirector + "/extras.cf").c_str(), "r" );
    216221                        assertf( extras, "cannot open extras.cf\n" );
    217222                        parse( extras, LinkageSpec::BuiltinC );
     
    219224                        if ( ! libcfap ) {
    220225                                // read the prelude in, if not generating the cfa library
    221                                 FILE * prelude = fopen( treep ? "../prelude/prelude.cf" : CFA_LIBDIR "/prelude.cf", "r" );
    222                                 assertf( prelude, "cannot open prelude.cf\n" );
     226                                FILE * prelude = fopen( (PreludeDirector + "/prelude.cfa").c_str(), "r" );
     227                                assertf( prelude, "cannot open prelude.cfa\n" );
    223228                                parse( prelude, LinkageSpec::Intrinsic );
    224229
    225230                                // Read to cfa builtins, if not generating the cfa library
    226                                 FILE * builtins = fopen( libcfap | treep ? "../prelude/builtins.cf" : CFA_LIBDIR "/builtins.cf", "r" );
     231                                FILE * builtins = fopen( (PreludeDirector + "/builtins.cf").c_str(), "r" );
    227232                                assertf( builtins, "cannot open builtins.cf\n" );
    228233                                parse( builtins, LinkageSpec::BuiltinCFA );
     
    235240                        parseTree->printList( cout );
    236241                        delete parseTree;
    237                         return 0;
     242                        return EXIT_SUCCESS;
    238243                } // if
    239244
     
    244249                if ( astp ) {
    245250                        dump( translationUnit );
    246                         return 0;
    247                 } // if
     251                        return EXIT_SUCCESS;
     252                } // if
     253
     254                // Temporary: fill locations after parsing so that every node has a location, for early error messages.
     255                // Eventually we should pass the locations from the parser to every node, but this quick and dirty solution
     256                // works okay for now.
     257                CodeTools::fillLocations( translationUnit );
     258                Stats::Time::StopBlock();
    248259
    249260                // add the assignment statement after the initialization of a type parameter
    250                 PASS( "validate", SymTab::validate( translationUnit, symtabp ) );
     261                PASS( "Validate", SymTab::validate( translationUnit, symtabp ) );
    251262                if ( symtabp ) {
    252263                        deleteAll( translationUnit );
    253                         return 0;
     264                        return EXIT_SUCCESS;
    254265                } // if
    255266
     
    257268                        PassVisitor<ResolvExpr::AlternativePrinter> printer( cout );
    258269                        acceptAll( translationUnit, printer );
    259                         return 0;
     270                        return EXIT_SUCCESS;
    260271                } // if
    261272
    262273                if ( validp ) {
    263274                        dump( translationUnit );
    264                         return 0;
    265                 } // if
    266 
    267                 PASS( "fixLabels", ControlStruct::fixLabels( translationUnit ) );
    268                 PASS( "fixNames", CodeGen::fixNames( translationUnit ) );
    269                 PASS( "genInit", InitTweak::genInit( translationUnit ) );
    270                 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 ) );
    271282                if ( libcfap ) {
    272283                        // generate the bodies of cfa library functions
     
    277288                        CodeTools::printDeclStats( translationUnit );
    278289                        deleteAll( translationUnit );
    279                         return 0;
    280                 }
     290                        return EXIT_SUCCESS;
     291                } // if
    281292
    282293                if ( bresolvep ) {
    283294                        dump( translationUnit );
    284                         return 0;
     295                        return EXIT_SUCCESS;
    285296                } // if
    286297
    287298                CodeTools::fillLocations( translationUnit );
    288299
    289                 PASS( "resolve", ResolvExpr::resolve( translationUnit ) );
     300                if ( resolvprotop ) {
     301                        CodeTools::dumpAsResolvProto( translationUnit );
     302                        return EXIT_SUCCESS;
     303                } // if
     304
     305                PASS( "Resolve", ResolvExpr::resolve( translationUnit ) );
    290306                if ( exprp ) {
    291307                        dump( translationUnit );
    292                         return 0;
     308                        return EXIT_SUCCESS;
    293309                } // if
    294310
    295311                // fix ObjectDecl - replaces ConstructorInit nodes
    296                 PASS( "fixInit", InitTweak::fix( translationUnit, filename, libcfap || treep ) );
     312                PASS( "Fix Init", InitTweak::fix( translationUnit, buildingLibrary() ) );
    297313                if ( ctorinitp ) {
    298314                        dump ( translationUnit );
    299                         return 0;
    300                 } // if
    301 
    302                 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
    303 
    304                 PASS( "translateEHM" , ControlStruct::translateEHM( translationUnit ) );
    305 
    306                 PASS( "generateWaitfor" , Concurrency::generateWaitFor( translationUnit ) );
    307 
    308                 PASS( "convertSpecializations",  GenPoly::convertSpecializations( translationUnit ) ); // needs to happen before tuple types are expanded
    309 
    310                 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?
    311327
    312328                if ( tuplep ) {
    313329                        dump( translationUnit );
    314                         return 0;
    315                 }
    316 
    317                 PASS( "virtual expandCasts", Virtual::expandCasts( translationUnit ) ); // Must come after translateEHM
    318 
    319                 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 ) );
    320336                if ( genericsp ) {
    321337                        dump( translationUnit );
    322                         return 0;
    323                 }
    324                 PASS( "convertLvalue", GenPoly::convertLvalue( translationUnit ) );
    325 
     338                        return EXIT_SUCCESS;
     339                } // if
     340
     341                PASS( "Convert L-Value", GenPoly::convertLvalue( translationUnit ) );
    326342
    327343                if ( bboxp ) {
    328344                        dump( translationUnit );
    329                         return 0;
    330                 } // if
    331                 PASS( "box", GenPoly::box( translationUnit ) );
     345                        return EXIT_SUCCESS;
     346                } // if
     347                PASS( "Box", GenPoly::box( translationUnit ) );
    332348
    333349                if ( bcodegenp ) {
    334350                        dump( translationUnit );
    335                         return 0;
    336                 }
     351                        return EXIT_SUCCESS;
     352                } // if
    337353
    338354                if ( optind < argc ) {                                                  // any commands after the flags and input file ? => output file name
     
    341357
    342358                CodeTools::fillLocations( translationUnit );
    343                 PASS( "codegen", CodeGen::generate( translationUnit, *output, ! noprotop, prettycodegenp, true, linemarks ) );
    344 
    345                 CodeGen::FixMain::fix( *output, treep ? "../prelude/bootloader.c" : CFA_LIBDIR "/bootloader.c" );
     359                PASS( "Code Gen", CodeGen::generate( translationUnit, *output, ! genproto, prettycodegenp, true, linemarks ) );
     360
     361                CodeGen::FixMain::fix( *output, (PreludeDirector + "/bootloader.c").c_str() );
    346362                if ( output != &cout ) {
    347363                        delete output;
     
    357373                        delete output;
    358374                } // if
    359                 return 1;
     375                return EXIT_FAILURE;
    360376        } catch ( UnimplementedError &e ) {
    361377                cout << "Sorry, " << e.get_what() << " is not currently implemented" << endl;
     
    363379                        delete output;
    364380                } // if
    365                 return 1;
     381                return EXIT_FAILURE;
    366382        } catch ( CompilerError &e ) {
    367383                cerr << "Compiler Error: " << e.get_what() << endl;
     
    370386                        delete output;
    371387                } // if
    372                 return 1;
    373         } catch(...) {
     388                return EXIT_FAILURE;
     389        } catch ( ... ) {
    374390                std::exception_ptr eptr = std::current_exception();
    375391                try {
    376392                        if (eptr) {
    377393                                std::rethrow_exception(eptr);
    378                         }
    379                         else {
    380                                 std::cerr << "Exception Uncaught and Unkown" << std::endl;
    381                         }
     394                        } else {
     395                                std::cerr << "Exception Uncaught and Unknown" << std::endl;
     396                        } // if
    382397                } catch(const std::exception& e) {
    383                         std::cerr << "Unaught Exception \"" << e.what() << "\"\n";
    384                 }
    385                 return 1;
    386         }// try
     398                        std::cerr << "Uncaught Exception \"" << e.what() << "\"\n";
     399                } // try
     400                return EXIT_FAILURE;
     401        } // try
    387402
    388403        deleteAll( translationUnit );
    389         if(!libcfap && !treep) HeapStats::printStats();
    390         return 0;
     404        Stats::print();
     405        return EXIT_SUCCESS;
    391406} // main
    392407
    393 void parse_cmdline( int argc, char * argv[], const char *& filename ) {
    394         enum { Ast, Bbox, Bresolver, CtorInitFix, DeclStats, Expr, ExprAlt, Grammar, LibCFA, Linemarks, Nolinemarks, Nopreamble, Parse, Prototypes, Resolver, Symbol, Tree, TupleExpansion, Validate, };
    395 
    396         static struct option long_opts[] = {
    397                 { "ast", no_argument, 0, Ast },
    398                 { "before-box", no_argument, 0, Bbox },
    399                 { "before-resolver", no_argument, 0, Bresolver },
    400                 { "ctorinitfix", no_argument, 0, CtorInitFix },
    401                 { "decl-stats", no_argument, 0, DeclStats },
    402                 { "expr", no_argument, 0, Expr },
    403                 { "expralt", no_argument, 0, ExprAlt },
    404                 { "grammar", no_argument, 0, Grammar },
    405                 { "libcfa", no_argument, 0, LibCFA },
    406                 { "line-marks", no_argument, 0, Linemarks },
    407                 { "no-line-marks", no_argument, 0, Nolinemarks },
    408                 { "no-preamble", no_argument, 0, Nopreamble },
    409                 { "parse", no_argument, 0, Parse },
    410                 { "no-prototypes", no_argument, 0, Prototypes },
    411                 { "resolver", no_argument, 0, Resolver },
    412                 { "symbol", no_argument, 0, Symbol },
    413                 { "tree", no_argument, 0, Tree },
    414                 { "tuple-expansion", no_argument, 0, TupleExpansion },
    415                 { "validate", no_argument, 0, Validate },
    416                 { 0, 0, 0, 0 }
    417         }; // long_opts
    418         int long_index;
    419 
     408
     409static const char optstring[] = ":hlLmNnpP:S:twW:D:";
     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        { "gdb", no_argument, nullptr, 'g' },
     425        { "", no_argument, nullptr, 0 },                                        // -w
     426        { "", no_argument, nullptr, 0 },                                        // -W
     427        { "", no_argument, nullptr, 0 },                                        // -D
     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        "building cfa standard lib",                                                                    // -t
     443        "wait for gdb to attach",                                                                       // -g
     444        "",                                                                                                     // -w
     445        "",                                                                                                     // -W
     446        "",                                                                                                     // -D
     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        { "ascodegen", codegenp, true, "print AST as codegen rather than AST" },
     458        { "asterr", errorp, true, "print AST on error" },
     459        { "declstats", declstatsp, true, "code property statistics" },
     460        { "parse", yydebug, true, "yacc (parsing) debug information" },
     461        { "pretty", prettycodegenp, true, "prettyprint for ascodegen flag" },
     462        { "rproto", resolvprotop, true, "resolver-proto instance" },
     463        { "rsteps", resolvep, true, "print resolver steps" },
     464        { "tree", parsep, true, "print parse tree" },
     465        // code dumps
     466        { "ast", astp, true, "print AST after parsing" },
     467        { "symevt", symtabp, true, "print AST after symbol table events" },
     468        { "altexpr", expraltp, true, "print alternatives for expressions" },
     469        { "astdecl", validp, true, "print AST after declaration validation pass" },
     470        { "resolver", bresolvep, true, "print AST before resolver step" },
     471        { "astexpr", exprp, true, "print AST after expression analysis" },
     472        { "ctordtor", ctorinitp, true, "print AST after ctor/dtor are replaced" },
     473        { "tuple", tuplep, true, "print AST after tuple expansion" },
     474        { "astgen", genericsp, true, "print AST after instantiate generics" },
     475        { "box", bboxp, true, "print AST before box step" },
     476        { "codegen", bcodegenp, true, "print AST before code generation" },
     477};
     478enum { printoptsSize = sizeof( printopts ) / sizeof( printopts[0] ) };
     479
     480static void usage( char *argv[] ) {
     481    cout << "Usage: " << argv[0] << " [options] [input-file (default stdin)] [output-file (default stdout)], where options are:" << endl;
     482        int i = 0, j = 1;                                                                       // j skips starting colon
     483        for ( ; long_opts[i].name != 0 && optstring[j] != '\0'; i += 1, j += 1 ) {
     484                if ( long_opts[i].name[0] != '\0' ) {                   // hidden option, internal usage only
     485                        if ( strcmp( long_opts[i].name, "prelude-dir" ) != 0 ) { // flag
     486                                cout << "  -" << optstring[j] << ",";
     487                        } else {                                                                        // no flag
     488                                j -= 1;                                                                 // compensate
     489                                cout << "     ";
     490                        } // if
     491                        cout << " --" << left << setw(12) << long_opts[i].name << "  ";
     492                        if ( strcmp( long_opts[i].name, "print" ) == 0 ) {
     493                                cout << "one of: " << endl;
     494                                for ( int i = 0; i < printoptsSize; i += 1 ) {
     495                                        cout << setw(10) << " " << left << setw(10) << printopts[i].name << "  " << printopts[i].descript << endl;
     496                                } // for
     497                        } else {
     498                                cout << description[i] << endl;
     499                        } // if
     500                } // if
     501                if ( optstring[j + 1] == ':' ) j += 1;
     502        } // for
     503        if ( long_opts[i].name != 0 || optstring[j] != '\0' ) assertf( false, "internal error, mismatch of option flags and names\n" );
     504    exit( EXIT_FAILURE );
     505} // usage
     506
     507static void parse_cmdline( int argc, char * argv[] ) {
    420508        opterr = 0;                                                                                     // (global) prevent getopt from printing error messages
    421509
    422510        bool Wsuppress = false, Werror = false;
    423511        int c;
    424         while ( (c = getopt_long( argc, argv, "abBcCdefgGlLmnNpqrstTvwW:yzZD:F:", long_opts, &long_index )) != -1 ) {
     512        while ( (c = getopt_long( argc, argv, optstring, long_opts, nullptr )) != -1 ) {
    425513                switch ( c ) {
    426                   case Ast:
    427                   case 'a':                                                                             // dump AST
    428                         astp = true;
    429                         break;
    430                   case Bresolver:
    431                   case 'b':                                                                             // print before resolver steps
    432                         bresolvep = true;
    433                         break;
    434                   case 'B':                                                                             // print before box steps
    435                         bboxp = true;
    436                         break;
    437                   case CtorInitFix:
    438                   case 'c':                                                                             // print after constructors and destructors are replaced
    439                         ctorinitp = true;
    440                         break;
    441                   case 'C':                                                                             // print before code generation
    442                         bcodegenp = true;
    443                         break;
    444                   case DeclStats:
    445                   case 'd':
    446                     declstatsp = true;
    447                         break;
    448                   case Expr:
    449                   case 'e':                                                                             // dump AST after expression analysis
    450                         exprp = true;
    451                         break;
    452                   case ExprAlt:
    453                   case 'f':                                                                             // print alternatives for expressions
    454                         expraltp = true;
    455                         break;
    456                   case Grammar:
    457                   case 'g':                                                                             // bison debugging info (grammar rules)
    458                         yydebug = true;
    459                         break;
    460                   case 'G':                                                                             // dump AST after instantiate generics
    461                         genericsp = true;
    462                         break;
    463                   case LibCFA:
     514                  case 'h':                                                                             // help message
     515                        usage( argv );                                                          // no return
     516                        break;
    464517                  case 'l':                                                                             // generate libcfa.c
    465518                        libcfap = true;
    466519                        break;
    467                   case Linemarks:
    468                   case 'L':                                                                             // print lines marks
     520                  case 'L':                                                                             // generate line marks
    469521                        linemarks = true;
    470522                        break;
    471                   case Nopreamble:
    472                   case 'n':                                                                             // do not read preamble
     523                  case 'm':                                                                             // do not replace main
     524                        nomainp = true;
     525                        break;
     526                  case 'N':                                                                             // do not generate line marks
     527                        linemarks = false;
     528                        break;
     529                  case 'n':                                                                             // do not read prelude
    473530                        nopreludep = true;
    474531                        break;
    475                   case Nolinemarks:
    476                   case 'N':                                                                             // suppress line marks
    477                         linemarks = false;
    478                         break;
    479                   case Prototypes:
    480                   case 'p':                                                                             // generate prototypes for preamble functions
    481                         noprotop = true;
    482                         break;
    483                   case 'm':                                                                             // don't replace the main
    484                         nomainp = true;
    485                         break;
    486                   case Parse:
    487                   case 'q':                                                                             // dump parse tree
    488                         parsep = true;
    489                         break;
    490                   case Resolver:
    491                   case 'r':                                                                             // print resolver steps
    492                         resolvep = true;
    493                         break;
    494                   case Symbol:
    495                   case 's':                                                                             // print symbol table events
    496                         symtabp = true;
    497                         break;
    498                   case Tree:
    499                   case 't':                                                                             // build in tree
     532                  case 'p':                                                                             // generate prototypes for prelude functions
     533                        genproto = true;
     534                        break;
     535                  case 'P':                                                                             // print options
     536                        for ( int i = 0;; i += 1 ) {
     537                                if ( i == printoptsSize ) {
     538                                        cout << "Unknown --print option " << optarg << endl;
     539                                        goto Default;
     540                                } // if
     541                                if ( strcmp( optarg, printopts[i].name ) == 0 ) {
     542                                        printopts[i].flag = printopts[i].val;
     543                                        break;
     544                                } // if
     545                        } // for
     546                        break;
     547                  case PreludeDir:                                                              // prelude directory for debug/nodebug, hidden
     548                        PreludeDirector = optarg;
     549                        break;
     550                  case 'S':                                                                             // enable profiling information, argument comma separated list of names
     551                        Stats::parse_params( optarg );
     552                        break;
     553                  case 't':                                                                             // building cfa stdlib
    500554                        treep = true;
    501555                        break;
    502                   case TupleExpansion:
    503                   case 'T':                                                                             // print after tuple expansion
    504                         tuplep = true;
    505                         break;
    506                   case 'v':                                                                             // dump AST after decl validation pass
    507                         validp = true;
    508                         break;
    509                   case 'w':
     556                  case 'g':                                                                             // wait for gdb
     557                        waiting_for_gdb = true;
     558                        break;
     559                  case 'w':                                                                             // suppress all warnings, hidden
    510560                        Wsuppress = true;
    511561                        break;
    512                   case 'W':
     562                  case 'W':                                                                             // coordinate gcc -W with CFA, hidden
    513563                        if ( strcmp( optarg, "all" ) == 0 ) {
    514564                                SemanticWarning_EnableAll();
     
    527577                        } // if
    528578                        break;
    529                   case 'y':                                                                             // dump AST on error
    530                         errorp = true;
    531                         break;
    532                   case 'z':                                                                             // dump as codegen rather than AST
    533                         codegenp = true;
    534                         break;
    535                         case 'Z':                                                                       // prettyprint during codegen (i.e. print unmangled names, etc.)
    536                         prettycodegenp = true;
    537                         break;
    538                   case 'D':                                                                             // ignore -Dxxx
    539                         break;
    540                   case 'F':                                                                             // source file-name without suffix
    541                         filename = optarg;
    542                         break;
    543                   case '?':
     579                  case 'D':                                                                             // ignore -Dxxx, forwarded by cpp, hidden
     580                        break;
     581                  case '?':                                                                             // unknown option
    544582                        if ( optopt ) {                                                         // short option ?
    545                                 assertf( false, "Unknown option: -%c\n", (char)optopt );
     583                                cout << "Unknown option -" << (char)optopt << endl;
    546584                        } else {
    547                                 assertf( false, "Unknown option: %s\n", argv[optind - 1] );
    548                         } // if
    549                         #if defined(__GNUC__) && __GNUC__ >= 7
    550                                 __attribute__((fallthrough));
    551                         #endif
     585                                cout << "Unknown option " << argv[optind - 1] << endl;
     586                        } // if
     587                        goto Default;
     588                  case ':':                                                                             // missing option
     589                        if ( optopt ) {                                                         // short option ?
     590                                cout << "Missing option for -" << (char)optopt << endl;
     591                        } else {
     592                                cout << "Missing option for " << argv[optind - 1] << endl;
     593                        } // if
     594                        goto Default;
     595                  Default:
    552596                  default:
    553                         abort();
     597                        usage( argv );                                                          // no return
    554598                } // switch
    555599        } // while
     
    589633        list< Declaration * > decls;
    590634
    591         if ( noprotop ) {
     635        if ( genproto ) {
    592636                filter( translationUnit.begin(), translationUnit.end(), back_inserter( decls ), notPrelude );
    593637        } else {
     
    597641        // depending on commandline options, either generate code or dump the AST
    598642        if ( codegenp ) {
    599                 CodeGen::generate( decls, out, ! noprotop, prettycodegenp );
     643                CodeGen::generate( decls, out, ! genproto, prettycodegenp );
    600644        } else {
    601645                printAll( decls, out );
    602         }
     646        } // if
    603647        deleteAll( translationUnit );
    604648} // dump
Note: See TracChangeset for help on using the changeset viewer.