Changeset 81e1f32


Ignore:
Timestamp:
Jan 23, 2018, 10:49:53 AM (4 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
aaron-thesis, arm-eh, cleanup-dtors, deferred_resn, demangler, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, resolv-new, with_gc
Children:
15d248e, f7d6bb0
Parents:
d2d50d7 (diff), fc67d6f (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:
1 added
2 deleted
25 edited

Legend:

Unmodified
Added
Removed
  • src/CodeGen/GenType.cc

    rd2d50d7 r81e1f32  
    2626
    2727namespace CodeGen {
    28         class GenType : public Visitor {
    29           public:
     28        struct GenType : public WithVisitorRef<GenType>, public WithShortCircuiting {
    3029                GenType( const std::string &typeString, bool pretty = false, bool genC = false, bool lineMarks = false );
    3130                std::string get_typeString() const { return typeString; }
    3231                void set_typeString( const std::string &newValue ) { typeString = newValue; }
    3332
    34                 virtual void visit( FunctionType *funcType );
    35                 virtual void visit( VoidType *voidType );
    36                 virtual void visit( BasicType *basicType );
    37                 virtual void visit( PointerType *pointerType );
    38                 virtual void visit( ArrayType *arrayType );
    39                 virtual void visit( ReferenceType *refType );
    40                 virtual void visit( StructInstType *structInst );
    41                 virtual void visit( UnionInstType *unionInst );
    42                 virtual void visit( EnumInstType *enumInst );
    43                 virtual void visit( TypeInstType *typeInst );
    44                 virtual void visit( TupleType * tupleType );
    45                 virtual void visit( VarArgsType *varArgsType );
    46                 virtual void visit( ZeroType *zeroType );
    47                 virtual void visit( OneType *oneType );
     33                void previsit( BaseSyntaxNode * );
     34                void postvisit( BaseSyntaxNode * );
     35
     36                void postvisit( FunctionType * funcType );
     37                void postvisit( VoidType * voidType );
     38                void postvisit( BasicType * basicType );
     39                void postvisit( PointerType * pointerType );
     40                void postvisit( ArrayType * arrayType );
     41                void postvisit( ReferenceType * refType );
     42                void postvisit( StructInstType * structInst );
     43                void postvisit( UnionInstType * unionInst );
     44                void postvisit( EnumInstType * enumInst );
     45                void postvisit( TypeInstType * typeInst );
     46                void postvisit( TupleType  * tupleType );
     47                void postvisit( VarArgsType * varArgsType );
     48                void postvisit( ZeroType * zeroType );
     49                void postvisit( OneType * oneType );
    4850
    4951          private:
     
    5961
    6062        std::string genType( Type *type, const std::string &baseString, bool pretty, bool genC , bool lineMarks ) {
    61                 GenType gt( baseString, pretty, genC, lineMarks );
     63                PassVisitor<GenType> gt( baseString, pretty, genC, lineMarks );
    6264                std::ostringstream os;
    6365
     
    6870
    6971                type->accept( gt );
    70                 return os.str() + gt.get_typeString();
     72                return os.str() + gt.pass.get_typeString();
    7173        }
    7274
     
    7779        GenType::GenType( const std::string &typeString, bool pretty, bool genC, bool lineMarks ) : typeString( typeString ), pretty( pretty ), genC( genC ), lineMarks( lineMarks ) {}
    7880
    79         void GenType::visit( VoidType *voidType ) {
     81        // *** BaseSyntaxNode
     82        void GenType::previsit( BaseSyntaxNode * ) {
     83                // turn off automatic recursion for all nodes, to allow each visitor to
     84                // precisely control the order in which its children are visited.
     85                visit_children = false;
     86        }
     87
     88        void GenType::postvisit( BaseSyntaxNode * node ) {
     89                std::stringstream ss;
     90                node->print( ss );
     91                assertf( false, "Unhandled node reached in GenType: %s", ss.str().c_str() );
     92        }
     93
     94        void GenType::postvisit( VoidType * voidType ) {
    8095                typeString = "void " + typeString;
    8196                handleQualifiers( voidType );
    8297        }
    8398
    84         void GenType::visit( BasicType *basicType ) {
    85                 BasicType::Kind kind = basicType->get_kind();
     99        void GenType::postvisit( BasicType * basicType ) {
     100                BasicType::Kind kind = basicType->kind;
    86101                assert( 0 <= kind && kind < BasicType::NUMBER_OF_BASIC_TYPES );
    87102                typeString = std::string( BasicType::typeNames[kind] ) + " " + typeString;
     
    89104        }
    90105
    91         void GenType::genArray( const Type::Qualifiers &qualifiers, Type *base, Expression *dimension, bool isVarLen, bool isStatic ) {
     106        void GenType::genArray( const Type::Qualifiers & qualifiers, Type * base, Expression *dimension, bool isVarLen, bool isStatic ) {
    92107                std::ostringstream os;
    93108                if ( typeString != "" ) {
     
    126141                typeString = os.str();
    127142
    128                 base->accept( *this );
    129         }
    130 
    131         void GenType::visit( PointerType *pointerType ) {
    132                 assert( pointerType->get_base() != 0);
    133                 if ( pointerType->get_isStatic() || pointerType->get_isVarLen() || pointerType->get_dimension() ) {
    134                         genArray( pointerType->get_qualifiers(), pointerType->get_base(), pointerType->get_dimension(), pointerType->get_isVarLen(), pointerType->get_isStatic() );
     143                base->accept( *visitor );
     144        }
     145
     146        void GenType::postvisit( PointerType * pointerType ) {
     147                assert( pointerType->base != 0);
     148                if ( pointerType->get_isStatic() || pointerType->get_isVarLen() || pointerType->dimension ) {
     149                        genArray( pointerType->get_qualifiers(), pointerType->base, pointerType->dimension, pointerType->get_isVarLen(), pointerType->get_isStatic() );
    135150                } else {
    136151                        handleQualifiers( pointerType );
     
    140155                                typeString = "*" + typeString;
    141156                        } // if
    142                         pointerType->get_base()->accept( *this );
    143                 } // if
    144         }
    145 
    146         void GenType::visit( ArrayType *arrayType ) {
    147                 genArray( arrayType->get_qualifiers(), arrayType->get_base(), arrayType->get_dimension(), arrayType->get_isVarLen(), arrayType->get_isStatic() );
    148         }
    149 
    150         void GenType::visit( ReferenceType *refType ) {
    151                 assert( refType->get_base() != 0);
     157                        pointerType->base->accept( *visitor );
     158                } // if
     159        }
     160
     161        void GenType::postvisit( ArrayType * arrayType ) {
     162                genArray( arrayType->get_qualifiers(), arrayType->base, arrayType->dimension, arrayType->get_isVarLen(), arrayType->get_isStatic() );
     163        }
     164
     165        void GenType::postvisit( ReferenceType * refType ) {
     166                assert( refType->base != 0);
    152167                assertf( ! genC, "Reference types should not reach code generation." );
    153168                handleQualifiers( refType );
    154169                typeString = "&" + typeString;
    155                 refType->get_base()->accept( *this );
    156         }
    157 
    158         void GenType::visit( FunctionType *funcType ) {
     170                refType->base->accept( *visitor );
     171        }
     172
     173        void GenType::postvisit( FunctionType * funcType ) {
    159174                std::ostringstream os;
    160175
     
    169184                /************* parameters ***************/
    170185
    171                 const std::list<DeclarationWithType *> &pars = funcType->get_parameters();
     186                const std::list<DeclarationWithType *> &pars = funcType->parameters;
    172187
    173188                if ( pars.empty() ) {
     
    191206                typeString = os.str();
    192207
    193                 if ( funcType->get_returnVals().size() == 0 ) {
     208                if ( funcType->returnVals.size() == 0 ) {
    194209                        typeString = "void " + typeString;
    195210                } else {
    196                         funcType->get_returnVals().front()->get_type()->accept( *this );
     211                        funcType->returnVals.front()->get_type()->accept( *visitor );
    197212                } // if
    198213
    199214                // add forall
    200                 if( ! funcType->get_forall().empty() && ! genC ) {
     215                if( ! funcType->forall.empty() && ! genC ) {
    201216                        // assertf( ! genC, "Aggregate type parameters should not reach code generation." );
    202217                        std::ostringstream os;
    203218                        PassVisitor<CodeGenerator> cg( os, pretty, genC, lineMarks );
    204219                        os << "forall(";
    205                         cg.pass.genCommaList( funcType->get_forall().begin(), funcType->get_forall().end() );
     220                        cg.pass.genCommaList( funcType->forall.begin(), funcType->forall.end() );
    206221                        os << ")" << std::endl;
    207222                        typeString = os.str() + typeString;
     
    221236        }
    222237
    223         void GenType::visit( StructInstType *structInst )  {
    224                 typeString = structInst->get_name() + handleGeneric( structInst ) + " " + typeString;
     238        void GenType::postvisit( StructInstType * structInst )  {
     239                typeString = structInst->name + handleGeneric( structInst ) + " " + typeString;
    225240                if ( genC ) typeString = "struct " + typeString;
    226241                handleQualifiers( structInst );
    227242        }
    228243
    229         void GenType::visit( UnionInstType *unionInst ) {
    230                 typeString = unionInst->get_name() + handleGeneric( unionInst ) + " " + typeString;
     244        void GenType::postvisit( UnionInstType * unionInst ) {
     245                typeString = unionInst->name + handleGeneric( unionInst ) + " " + typeString;
    231246                if ( genC ) typeString = "union " + typeString;
    232247                handleQualifiers( unionInst );
    233248        }
    234249
    235         void GenType::visit( EnumInstType *enumInst ) {
    236                 typeString = enumInst->get_name() + " " + typeString;
     250        void GenType::postvisit( EnumInstType * enumInst ) {
     251                typeString = enumInst->name + " " + typeString;
    237252                if ( genC ) typeString = "enum " + typeString;
    238253                handleQualifiers( enumInst );
    239254        }
    240255
    241         void GenType::visit( TypeInstType *typeInst ) {
    242                 typeString = typeInst->get_name() + " " + typeString;
     256        void GenType::postvisit( TypeInstType * typeInst ) {
     257                typeString = typeInst->name + " " + typeString;
    243258                handleQualifiers( typeInst );
    244259        }
    245260
    246         void GenType::visit( TupleType * tupleType ) {
     261        void GenType::postvisit( TupleType * tupleType ) {
    247262                assertf( ! genC, "Tuple types should not reach code generation." );
    248263                unsigned int i = 0;
     
    257272        }
    258273
    259         void GenType::visit( VarArgsType *varArgsType ) {
     274        void GenType::postvisit( VarArgsType * varArgsType ) {
    260275                typeString = "__builtin_va_list " + typeString;
    261276                handleQualifiers( varArgsType );
    262277        }
    263278
    264         void GenType::visit( ZeroType *zeroType ) {
     279        void GenType::postvisit( ZeroType * zeroType ) {
    265280                // ideally these wouldn't hit codegen at all, but should be safe to make them ints
    266281                typeString = (pretty ? "zero_t " : "long int ") + typeString;
     
    268283        }
    269284
    270         void GenType::visit( OneType *oneType ) {
     285        void GenType::postvisit( OneType * oneType ) {
    271286                // ideally these wouldn't hit codegen at all, but should be safe to make them ints
    272287                typeString = (pretty ? "one_t " : "long int ") + typeString;
     
    274289        }
    275290
    276         void GenType::handleQualifiers( Type *type ) {
     291        void GenType::handleQualifiers( Type * type ) {
    277292                if ( type->get_const() ) {
    278293                        typeString = "const " + typeString;
  • src/CodeTools/DeclStats.cc

    rd2d50d7 r81e1f32  
    2323#include <utility>                 // for pair, make_pair
    2424
     25#include "Common/PassVisitor.h"
    2526#include "Common/SemanticError.h"  // for SemanticError
    2627#include "Common/VectorMap.h"      // for VectorMap
     
    3536namespace CodeTools {
    3637
    37         class DeclStats : public Visitor {
     38        struct DeclStats : public WithShortCircuiting {
    3839                template<typename T>
    3940                static void sum(T& a, const T& b) { a += b; }
     
    6162
    6263                struct ArgPackStats {
    63                         VectorMap<unsigned> n;                 ///< Count of decls with each number of elements
    64                         VectorMap<unsigned> n_basic;           ///< Count of decls with each number of basic type elements
    65                         VectorMap<unsigned> n_poly;            ///< Count of decls with each number of polymorphic elements
    66                         std::map<unsigned, unsigned> p_basic;  ///< Count of decls with each percentage of basic type elements
    67                         std::map<unsigned, unsigned> p_poly;   ///< Count of decls with each percentage of polymorphic elements
    68                         VectorMap<unsigned> n_types;           ///< Count of decls with each number of distinct types in the pack
     64                        VectorMap<unsigned> n;                   ///< Count of decls with each number of elements
     65                        VectorMap<unsigned> n_basic;             ///< Count of decls with each number of basic type elements
     66                        VectorMap<unsigned> n_generic;           ///< Count of decls with each number of generic type elements
     67                        VectorMap<unsigned> n_poly;              ///< Count of decls with each number of polymorphic elements
     68                        VectorMap<unsigned> n_compound;          ///< Count of decls with each number of non-generic compound types
     69                        std::map<unsigned, unsigned> p_basic;    ///< Count of decls with each percentage of basic type elements
     70                        std::map<unsigned, unsigned> p_generic;  ///< Count of decls with each percentage of generic type elements
     71                        std::map<unsigned, unsigned> p_poly;     ///< Count of decls with each percentage of polymorphic elements
     72                        std::map<unsigned, unsigned> p_compound; ///< Count of decls with each percentage of non-generic compound type elements
     73                        VectorMap<unsigned> n_types;             ///< Count of decls with each number of distinct types in the pack
    6974                        /// Count of decls with each percentage of new types in lists.
    7075                        /// Types used in the parameter list that recur in the return list are not considered to be new.
     
    7479                                sum(n, o.n);
    7580                                sum(n_basic, o.n_basic);
     81                                sum(n_generic, o.n_generic);
    7682                                sum(n_poly, o.n_poly);
     83                                sum(n_compound, o.n_compound);
    7784                                sum(p_basic, o.p_basic);
     85                                sum(p_generic, o.p_generic);
    7886                                sum(p_poly, o.p_poly);
     87                                sum(p_compound, o.p_compound);
    7988                                sum(n_types, o.n_types);
    8089                                sum(p_new, o.p_new);
     
    8897                        /// Count of declarations with each number of assertion parameters
    8998                        VectorMap<unsigned> n_type_params;
     99                        /// Count of generic types with each number of type parameters
     100                        VectorMap<unsigned> n_generic_params;
     101                        /// Count of maximum nesting depth of types
     102                        VectorMap<unsigned> n_generic_nesting;
    90103                        /// Count of declarations with each name
    91104                        std::unordered_map<std::string, unsigned> by_name;
    92105                        /// Count of uses of each basic type
    93106                        std::unordered_map<std::string, unsigned> basic_type_names;
    94                         /// Count of uses of each non-basic type
     107                        /// Count of uses of each generic type name (includes "*", "[]", "(*)", "[,]")
     108                        std::unordered_map<std::string, unsigned> generic_type_names;
     109                        /// Count of uses of each non-generic aggregate type
    95110                        std::unordered_map<std::string, unsigned> compound_type_names;
    96111                        /// Count of decls using each basic type
    97112                        std::unordered_map<std::string, unsigned> basic_type_decls;
     113                        /// Count of decls using each generic type (includes "*", "[]", "(*)", "[,]")
     114                        std::unordered_map<std::string, unsigned> generic_type_decls;
    98115                        /// Count of decls using each compound type
    99116                        std::unordered_map<std::string, unsigned> compound_type_decls;
     
    110127                        ArgPackStats assn_returns;
    111128
    112                         Stats() : n_decls(0), n_type_params(), by_name(), basic_type_names(), compound_type_names(), basic_type_decls(), compound_type_decls(), params(), returns(), n_assns(), assn_params(), assn_returns() {}
     129                        Stats() : n_decls(0), n_type_params(), n_generic_params(), n_generic_nesting(),
     130                                by_name(), basic_type_names(), generic_type_names(), compound_type_names(),
     131                                basic_type_decls(), generic_type_decls(), compound_type_decls(), params(),
     132                                returns(), n_assns(), assn_params(), assn_returns() {}
    113133
    114134                public:
     
    116136                                sum( n_decls, o.n_decls );
    117137                                sum( n_type_params, o.n_type_params );
     138                                sum( n_generic_params, o.n_generic_params );
     139                                sum( n_generic_nesting, o.n_generic_nesting );
    118140                                sum( by_name, o.by_name );
    119141                                sum( basic_type_names, o.basic_type_names );
     142                                sum( generic_type_names, o.generic_type_names );
    120143                                sum( compound_type_names, o.compound_type_names );
    121144                                sum( basic_type_decls, o.basic_type_decls );
     145                                sum( generic_type_decls, o.generic_type_decls );
    122146                                sum( compound_type_decls, o.compound_type_decls );
    123147                                sum( params, o.params );
     
    131155                };
    132156
    133                 Stats for_linkage[LinkageSpec::NoOfSpecs];   ///< Stores separate stats per linkage
     157                /// number of counting bins for linkages
     158                static const unsigned n_named_specs = 8;
     159                /// map from total number of specs to bins
     160                static const unsigned ind_for_linkage[16];
     161
     162                Stats for_linkage[n_named_specs];            ///< Stores separate stats per linkage
    134163                std::unordered_set<std::string> seen_names;  ///< Stores manglenames already seen to avoid double-counting
    135164                Stats total;
     
    137166                std::map<std::pair<unsigned, unsigned>, unsigned> exprs_by_fanout_at_depth;
    138167
     168                void countType( const std::string& name, unsigned& n, std::unordered_map<std::string,
     169                                unsigned>& names, std::unordered_map<std::string, unsigned>& decls,
     170                                std::unordered_set<std::string>& elSeen ) {
     171                        ++n;
     172                        ++names[ name ];
     173                        if ( elSeen.insert( name ).second ) { ++decls[ name ]; }
     174                }
     175
     176                void update_max( unsigned& max, unsigned crnt ) {
     177                        if ( crnt > max ) max = crnt;
     178                }
     179
     180                void analyzeSubtype( Type* ty, Stats& stats, std::unordered_set<std::string>& elSeen,
     181                                unsigned& n_poly, bool& seen_poly, unsigned& max_depth, unsigned depth ) {
     182                        unsigned x;
     183                        analyzeType( ty, stats, elSeen, x, x, n_poly, x, seen_poly, max_depth, depth + 1 );
     184                }
     185
     186                void analyzeSubtypes( std::list<DeclarationWithType*>& tys, Stats& stats,
     187                                std::unordered_set<std::string>& elSeen, unsigned& n_poly, bool& seen_poly,
     188                                unsigned& max_depth, unsigned depth, unsigned& n_subs ) {
     189                        for ( DeclarationWithType* dwt : tys ) {
     190                                Type* ty = dwt->get_type();
     191                                n_subs += (unsigned)( dynamic_cast<VoidType*>(ty) != nullptr );
     192                                analyzeSubtype( ty, stats, elSeen, n_poly, seen_poly, max_depth, depth );
     193                        }
     194                }
     195
     196                void analyzeSubtypes( std::list<Expression*>& tys, Stats& stats,
     197                                std::unordered_set<std::string>& elSeen, unsigned& n_poly, bool& seen_poly,
     198                                unsigned& max_depth, unsigned depth ) {
     199                        for ( Expression* expr : tys ) {
     200                                TypeExpr* texpr = dynamic_cast<TypeExpr*>(expr);
     201                                if ( ! texpr ) continue;
     202                                Type* ty = texpr->get_type();
     203                                analyzeSubtype( ty, stats, elSeen, n_poly, seen_poly, max_depth, depth );
     204                        }
     205                }
     206
     207                void analyzeSubtypes( std::list<Type*>& tys, Stats& stats,
     208                                std::unordered_set<std::string>& elSeen, unsigned& n_poly, bool& seen_poly,
     209                                unsigned& max_depth, unsigned depth ) {
     210                        for ( Type* ty : tys ) {
     211                                analyzeSubtype( ty, stats, elSeen, n_poly, seen_poly, max_depth, depth );
     212                        }
     213                }
     214
     215                void analyzeType( Type* ty, Stats& stats, std::unordered_set<std::string>& elSeen,
     216                                unsigned& n_basic, unsigned& n_generic, unsigned& n_poly, unsigned& n_agg,
     217                                bool& seen_poly, unsigned& max_depth, unsigned depth = 0 ) {
     218                        if ( BasicType* bt = dynamic_cast<BasicType*>(ty) ) {
     219                                std::string name = BasicType::typeNames[ bt->get_kind() ];
     220                                countType( name, n_basic, stats.basic_type_names, stats.basic_type_decls, elSeen );
     221                                update_max( max_depth, depth );
     222                        } else if ( PointerType* pt = dynamic_cast<PointerType*>(ty) ) {
     223                                std::string name = "*";
     224                                countType(
     225                                        name, n_generic, stats.generic_type_names, stats.generic_type_decls, elSeen);
     226                                analyzeSubtype(
     227                                        pt->get_base(), stats, elSeen, n_poly, seen_poly, max_depth, depth );
     228                                ++stats.n_generic_params.at( 1 );
     229                        } else if ( ArrayType* at = dynamic_cast<ArrayType*>(ty) ) {
     230                                std::string name = "[]";
     231                                countType(
     232                                        name, n_generic, stats.generic_type_names, stats.generic_type_decls, elSeen);
     233                                analyzeSubtype(
     234                                        at->get_base(), stats, elSeen, n_poly, seen_poly, max_depth, depth );
     235                                ++stats.n_generic_params.at( 1 );
     236                        } else if ( ReferenceType* rt = dynamic_cast<ReferenceType*>(ty) ) {
     237                                std::string name = "&";
     238                                countType(
     239                                        name, n_generic, stats.generic_type_names, stats.generic_type_decls, elSeen);
     240                                analyzeSubtype(
     241                                        rt->get_base(), stats, elSeen, n_poly, seen_poly, max_depth, depth );
     242                                ++stats.n_generic_params.at( 1 );
     243                        } else if ( FunctionType* ft = dynamic_cast<FunctionType*>(ty) ) {
     244                                std::string name = "(*)";
     245                                countType(
     246                                        name, n_generic, stats.generic_type_names, stats.generic_type_decls, elSeen);
     247                                unsigned n_subs = 0;
     248                                analyzeSubtypes(
     249                                        ft->get_returnVals(), stats, elSeen, n_poly, seen_poly, max_depth, depth,
     250                                        n_subs );
     251                                analyzeSubtypes(
     252                                        ft->get_parameters(), stats, elSeen, n_poly, seen_poly, max_depth, depth,
     253                                        n_subs );
     254                                ++stats.n_generic_params.at( n_subs );
     255                        } else if ( TypeInstType* vt = dynamic_cast<TypeInstType*>(ty) ) {
     256                                if ( ! seen_poly ) {
     257                                        ++n_poly;
     258                                        seen_poly = true;
     259                                }
     260                                countType(
     261                                        vt->get_name(), n_agg, stats.compound_type_names, stats.compound_type_decls,
     262                                        elSeen );
     263                                update_max( max_depth, depth );
     264                        } else if ( ReferenceToType* st = dynamic_cast<ReferenceToType*>(ty) ) {
     265                                std::list<Expression*>& params = st->get_parameters();
     266                                if ( params.empty() ) {
     267                                        countType(
     268                                                st->get_name(), n_agg, stats.compound_type_names,
     269                                                stats.compound_type_decls, elSeen );
     270                                        update_max( max_depth, depth );
     271                                } else {
     272                                        countType(
     273                                                st->get_name(), n_generic, stats.generic_type_names,
     274                                                stats.generic_type_decls, elSeen);
     275                                        analyzeSubtypes( params, stats, elSeen, n_poly, seen_poly, max_depth, depth );
     276                                        ++stats.n_generic_params.at( params.size() );
     277                                }
     278                        } else if ( TupleType* tt = dynamic_cast<TupleType*>(ty) ) {
     279                                std::string name = "[,]";
     280                                countType(
     281                                        name, n_generic, stats.generic_type_names, stats.generic_type_decls, elSeen);
     282                                analyzeSubtypes(
     283                                        tt->get_types(), stats, elSeen, n_poly, seen_poly, max_depth, depth );
     284                                ++stats.n_generic_params.at( tt->size() );
     285                        } else if ( dynamic_cast<VarArgsType*>(ty) ) {
     286                                std::string name = "...";
     287                                countType(
     288                                        name, n_agg, stats.compound_type_names, stats.compound_type_decls, elSeen );
     289                                update_max( max_depth, depth );
     290                        } else if ( dynamic_cast<ZeroType*>(ty) ) {
     291                                std::string name = "0";
     292                                countType( name, n_basic, stats.basic_type_names, stats.basic_type_decls, elSeen );
     293                                update_max( max_depth, depth );
     294                        } else if ( dynamic_cast<OneType*>(ty) ) {
     295                                std::string name = "1";
     296                                countType( name, n_basic, stats.basic_type_names, stats.basic_type_decls, elSeen );
     297                                update_max( max_depth, depth );
     298                        }
     299                }
     300
    139301                /// Update arg pack stats based on a declaration list
    140                 void analyze( Stats& stats, std::unordered_set<std::string>& seen, ArgPackStats& pstats, std::list<DeclarationWithType*>& decls ) {
     302                void analyze( Stats& stats, std::unordered_set<std::string>& seen,
     303                                std::unordered_set<std::string>& elSeen, ArgPackStats& pstats,
     304                                std::list<DeclarationWithType*>& decls ) {
    141305                        std::unordered_set<std::string> types;
    142                         unsigned n = 0;        ///< number of args/returns
    143                         unsigned n_basic = 0;  ///< number of basic types
    144                         unsigned n_poly = 0;   ///< number of polymorphic types
    145                         unsigned n_new = 0;    ///< number of new types
     306                        unsigned n = 0;                 ///< number of args/returns
     307                        unsigned n_basic = 0;           ///< number of basic types
     308                        unsigned n_generic = 0;         ///< number of generic types (includes "*", "&", "[]", "(*)", "[,]")
     309                        unsigned n_poly = 0;            ///< number of polymorphic types
     310                        unsigned n_agg = 0;             ///< number of non-generic aggregate types
     311                        unsigned n_new = 0;             ///< number of new types
     312
    146313                        for ( auto decl : decls ) {
    147314                                Type* dt = decl->get_type();
     
    152319                                dt->print( ss );
    153320                                types.insert( ss.str() );
    154                                 bool this_new = seen.insert( ss.str() ).second;
    155                                 if ( this_new ) { ++n_new; }
    156 
    157                                 if ( dynamic_cast<BasicType*>( dt ) ) {
    158                                         ++n_basic;
    159                                         ++stats.basic_type_names[ ss.str() ];
    160                                         if ( this_new ) {
    161                                                 ++stats.basic_type_decls[ ss.str() ];
    162                                         }
    163                                 } else if ( GenPoly::hasPolyBase( dt ) ) {
    164                                         ++n_poly;
    165                                 } else {
    166                                         ++stats.compound_type_names[ ss.str() ];
    167                                         if ( this_new ) {
    168                                                 ++stats.compound_type_decls[ ss.str() ];
    169                                         }
    170                                 }
    171                         }
     321                                if ( seen.insert( ss.str() ).second ) { ++n_new; }
     322
     323                                bool seen_poly = false;
     324                                unsigned max_depth = 0;
     325                                analyzeType(
     326                                        dt, stats, elSeen, n_basic, n_generic, n_poly, n_agg, seen_poly, max_depth );
     327                                ++stats.n_generic_nesting.at( max_depth );
     328                        }
     329
    172330                        ++pstats.n.at( n );
    173331                        ++pstats.n_basic.at( n_basic );
     332                        ++pstats.n_generic.at( n_generic );
    174333                        ++pstats.n_poly.at( n_poly );
     334                        ++pstats.n_compound.at( n_agg );
    175335                        if ( n > 0 ) {
    176336                                ++pstats.p_basic[ n_basic*100/n ];
     337                                ++pstats.p_generic[ n_generic*100/n ];
    177338                                ++pstats.p_poly[ n_poly*100/n ];
    178                                 ++pstats.p_new[ n_new*100/n ];
     339                                ++pstats.p_compound[ n_agg*100/n ];
     340                                if ( n > 1 ) ++pstats.p_new[ (n_new-1)*100/(n-1) ];
    179341                        }
    180342                        ++pstats.n_types.at( types.size() );
     
    183345                void analyzeFunc( FunctionType* fnTy, Stats& stats, ArgPackStats& params, ArgPackStats& returns ) {
    184346                        std::unordered_set<std::string> seen;
    185                         analyze( stats, seen, params, fnTy->get_parameters() );
    186                         analyze( stats, seen, returns, fnTy->get_returnVals() );
     347                        std::unordered_set<std::string> elSeen;
     348                        analyze( stats, seen, elSeen, params, fnTy->get_parameters() );
     349                        analyze( stats, seen, elSeen, returns, fnTy->get_returnVals() );
    187350                }
    188351
     
    200363
    201364        public:
    202                 using Visitor::visit;
    203 
    204                 virtual void visit( FunctionDecl *decl ) {
     365                void previsit( FunctionDecl *decl ) {
    205366                        // skip if already seen declaration for this function
    206                         const std::string& mangleName = decl->get_mangleName().empty() ? decl->get_name() : decl->get_mangleName();
    207                         if ( ! seen_names.insert( mangleName ).second ) {
    208                                 maybeAccept( decl->get_statements(), *this );
    209                                 return;
    210                         }
    211 
    212                         Stats& stats = for_linkage[ decl->get_linkage() ];
    213 
    214                         ++stats.n_decls;
    215                         FunctionType* fnTy = decl->get_functionType();
    216                         const Type::ForallList& forall = fnTy->get_forall();
    217                         ++stats.n_type_params.at( forall.size() );
    218                         unsigned n_assns = 0;
    219                         for ( TypeDecl* fdecl : forall ) {
    220                                 n_assns += fdecl->get_assertions().size();
    221                                 for ( DeclarationWithType* assn : fdecl->get_assertions() ) {
    222                                         FunctionType *assnTy = 0;
    223                                         if ( ObjectDecl *assnObj = dynamic_cast<ObjectDecl*>(assn) ) {
    224                                                 if ( PointerType *ptrTy = dynamic_cast<PointerType*>(assnObj->get_type()) ) {
    225                                                         assnTy = dynamic_cast<FunctionType*>(ptrTy->get_base());
    226                                                 } else assnTy = dynamic_cast<FunctionType*>(assnObj->get_type());
    227                                         } else if ( FunctionDecl *assnDecl = dynamic_cast<FunctionDecl*>(assn) ) {
    228                                                 assnTy = assnDecl->get_functionType();
     367                        const std::string& mangleName = decl->get_mangleName().empty() ? decl->name : decl->get_mangleName();
     368                        if ( seen_names.insert( mangleName ).second ) {
     369                                Stats& stats = for_linkage[ ind_for_linkage[ decl->linkage ] ];
     370
     371                                ++stats.n_decls;
     372                                FunctionType* fnTy = decl->type;
     373                                const Type::ForallList& forall = fnTy->forall;
     374                                ++stats.n_type_params.at( forall.size() );
     375                                unsigned n_assns = 0;
     376                                for ( TypeDecl* fdecl : forall ) {
     377                                        n_assns += fdecl->assertions.size();
     378                                        for ( DeclarationWithType* assn : fdecl->assertions ) {
     379                                                FunctionType *assnTy = nullptr;
     380                                                if ( ObjectDecl *assnObj = dynamic_cast<ObjectDecl*>(assn) ) {
     381                                                        if ( PointerType *ptrTy = dynamic_cast<PointerType*>(assnObj->get_type()) ) {
     382                                                                assnTy = dynamic_cast<FunctionType*>(ptrTy->base);
     383                                                        } else assnTy = dynamic_cast<FunctionType*>(assnObj->get_type());
     384                                                } else if ( FunctionDecl *assnDecl = dynamic_cast<FunctionDecl*>(assn) ) {
     385                                                        assnTy = assnDecl->type;
     386                                                }
     387                                                if ( assnTy ) analyzeFunc( assnTy, stats, stats.assn_params, stats.assn_returns );
    229388                                        }
    230                                         if ( assnTy ) analyzeFunc( assnTy, stats, stats.assn_params, stats.assn_returns );
    231                                 }
    232                         }
    233                         ++stats.n_assns[ n_assns ];
    234 
    235                         ++stats.by_name[ decl->get_name() ];
    236 
    237                         analyzeFunc( fnTy, stats, stats.params, stats.returns );
    238 
    239                         // analyze expressions in decl statements
    240                         maybeAccept( decl->get_statements(), *this );
    241                 }
    242 
    243                 virtual void visit( UntypedExpr *expr ) {
     389                                }
     390                                ++stats.n_assns[ n_assns ];
     391                                ++stats.by_name[ decl->name ];
     392                                analyzeFunc( fnTy, stats, stats.params, stats.returns );
     393                        }
     394                }
     395
     396                void previsit( UntypedExpr *expr ) {
     397                        visit_children = false;
    244398                        analyzeExpr( expr, 0 );
    245399                }
     
    272426                template<typename F>
    273427                void printAllHisto( const std::string& name, F extract ) {
    274                         VectorMap<unsigned> histos[LinkageSpec::NoOfSpecs];
     428                        VectorMap<unsigned> histos[n_named_specs];
    275429                        VectorMap<unsigned> thisto;
    276430
    277431                        for ( const auto& entry : extract(total) ) { ++thisto.at( entry.second ); }
    278432
    279                         for ( unsigned i = 0; i < LinkageSpec::NoOfSpecs; ++i ) {
     433                        for ( unsigned i = 0; i < n_named_specs; ++i ) {
    280434                                // can't be a higher count in one of the sub-histograms than the total
    281435                                histos[i].reserve( thisto.size() );
     
    295449                template<typename F>
    296450                void printAllSparseHisto( const std::string& name, F extract ) {
    297                         std::map<unsigned, unsigned> histos[LinkageSpec::NoOfSpecs];
     451                        std::map<unsigned, unsigned> histos[n_named_specs];
    298452                        std::map<unsigned, unsigned> thisto;
    299453
    300454                        for ( const auto& entry : extract(total) ) { ++thisto[ entry.second ]; }
    301455
    302                         for ( unsigned i = 0; i < LinkageSpec::NoOfSpecs; ++i ) {
     456                        for ( unsigned i = 0; i < n_named_specs; ++i ) {
    303457                                for ( const auto& entry : extract(for_linkage[i]) ) { ++histos[i][entry.second]; }
    304458                        }
     
    307461                                const auto& key = entry.first;
    308462                                std::cout << "\"" << name << "\"," << key;
    309                                 for ( unsigned i = 0; i < LinkageSpec::NoOfSpecs; ++i ) {
     463                                for ( unsigned i = 0; i < n_named_specs; ++i ) {
    310464                                        auto it = histos[i].find( key );
    311465                                        if ( it == histos[i].end() ) std::cout << ",0";
     
    319473                void printAllPack( const std::string& name, F extract ) {
    320474                        printAllMap("n_basic_" + name, [&extract](const Stats& stats) { return extract(stats).n_basic; });
     475                        printAllMap("n_generic_" + name, [&extract](const Stats& stats) { return extract(stats).n_generic; });
    321476                        printAllMap("n_poly_" + name, [&extract](const Stats& stats) { return extract(stats).n_poly; });
     477                        printAllMap("n_compound_" + name, [&extract](const Stats& stats) { return extract(stats).n_compound; });
    322478                        printAllMap("n_" + name, [&extract](const Stats& stats) { return extract(stats).n; });
    323479                        printAllMap("%_basic_" + name, [&extract](const Stats& stats) { return extract(stats).p_basic; });
     480                        printAllMap("%_generic_" + name, [&extract](const Stats& stats) { return extract(stats).p_generic; });
    324481                        printAllMap("%_poly_" + name, [&extract](const Stats& stats) { return extract(stats).p_poly; });
     482                        printAllMap("%_compound_" + name, [&extract](const Stats& stats) { return extract(stats).p_compound; });
    325483                        printAllMap("n_distinct_types_" + name, [&extract](const Stats& stats) { return extract(stats).n_types; });
    326484                        printAllMap("%_new_types_in_" + name, [&extract](const Stats& stats) { return extract(stats).p_new; });
     
    342500                        }
    343501
    344                         std::cout << ",,\"intrinsic\",\"Cforall\",\"C\",\"autogen\",\"builtin\",\"TOTAL\"" << std::endl;
     502                        std::cout << ",,\"intrinsic\",\"Cforall\",\"C\",\"autogen\",\"compiler\",\"builtinCFA\",\"builtinC\",\"other\",\"TOTAL\"" << std::endl;
    345503
    346504                        printAllMap("n_type_params", [](const Stats& stats) { return stats.n_type_params; });
     505                        printAllMap("n_generic_params", [](const Stats& stats) { return stats.n_generic_params; });
     506                        printAllMap("n_generic_nesting", [](const Stats& stats) { return stats.n_generic_nesting; });
    347507                        printAll("n_decls", [](const Stats& stats) { return stats.n_decls; });
    348508                        printAll("unique_names", [](const Stats& stats) { return stats.by_name.size(); });
     
    351511                        printAllSparseHisto("basic_type_uses", [](const Stats& stats) { return stats.basic_type_names; });
    352512                        printAllSparseHisto("decls_using_basic_type", [](const Stats& stats) { return stats.basic_type_decls; });
     513                        printAll("generic_type_names", [](const Stats& stats) { return stats.generic_type_names.size(); });
     514                        printAllSparseHisto("generic_type_uses", [](const Stats& stats) { return stats.generic_type_names; });
     515                        printAllSparseHisto("decls_using_generic_type", [](const Stats& stats) { return stats.generic_type_decls; });
    353516                        printAll("compound_type_names", [](const Stats& stats) { return stats.compound_type_names.size(); });
    354517                        printAllSparseHisto("compound_type_uses", [](const Stats& stats) { return stats.compound_type_names; });
     
    365528        };
    366529
     530        const unsigned DeclStats::ind_for_linkage[]
     531                = { 7, 7, 2, 1,   7, 7, 7, 3,   4, 7, 6, 5,   7, 7, 7, 0 };
     532
    367533        void printDeclStats( std::list< Declaration * > &translationUnit ) {
    368                 DeclStats stats;
     534                PassVisitor<DeclStats> stats;
    369535                acceptAll( translationUnit, stats );
    370                 stats.print();
     536                stats.pass.print();
    371537        }
    372538
  • src/Common/PassVisitor.h

    rd2d50d7 r81e1f32  
    119119        virtual void visit( StmtExpr *  stmtExpr ) override final;
    120120        virtual void visit( UniqueExpr *  uniqueExpr ) override final;
     121        virtual void visit( UntypedInitExpr *  initExpr ) override final;
     122        virtual void visit( InitExpr *  initExpr ) override final;
    121123
    122124        virtual void visit( VoidType * basicType ) override final;
     
    211213        virtual Expression * mutate( StmtExpr *  stmtExpr ) override final;
    212214        virtual Expression * mutate( UniqueExpr *  uniqueExpr ) override final;
     215        virtual Expression * mutate( UntypedInitExpr *  initExpr ) override final;
     216        virtual Expression * mutate( InitExpr *  initExpr ) override final;
    213217
    214218        virtual Type * mutate( VoidType * basicType ) override final;
  • src/Common/PassVisitor.impl.h

    rd2d50d7 r81e1f32  
    18531853}
    18541854
     1855//--------------------------------------------------------------------------
     1856// UntypedInitExpr
     1857template< typename pass_type >
     1858void PassVisitor< pass_type >::visit( UntypedInitExpr * node ) {
     1859        VISIT_START( node );
     1860
     1861        indexerScopedAccept( node->result, *this );
     1862        maybeAccept_impl   ( node->expr  , *this );
     1863        // not currently visiting initAlts, but this doesn't matter since this node is only used in the resolver.
     1864
     1865        VISIT_END( node );
     1866}
     1867
     1868template< typename pass_type >
     1869Expression * PassVisitor< pass_type >::mutate( UntypedInitExpr * node ) {
     1870        MUTATE_START( node );
     1871
     1872        indexerScopedMutate( node->env   , *this );
     1873        indexerScopedMutate( node->result, *this );
     1874        maybeMutate_impl   ( node->expr  , *this );
     1875        // not currently visiting initAlts, but this doesn't matter since this node is only used in the resolver.
     1876
     1877        MUTATE_END( Expression, node );
     1878}
     1879
     1880//--------------------------------------------------------------------------
     1881// InitExpr
     1882template< typename pass_type >
     1883void PassVisitor< pass_type >::visit( InitExpr * node ) {
     1884        VISIT_START( node );
     1885
     1886        indexerScopedAccept( node->result, *this );
     1887        maybeAccept_impl   ( node->expr  , *this );
     1888        maybeAccept_impl   ( node->designation, *this );
     1889
     1890        VISIT_END( node );
     1891}
     1892
     1893template< typename pass_type >
     1894Expression * PassVisitor< pass_type >::mutate( InitExpr * node ) {
     1895        MUTATE_START( node );
     1896
     1897        indexerScopedMutate( node->env   , *this );
     1898        indexerScopedMutate( node->result, *this );
     1899        maybeMutate_impl   ( node->expr  , *this );
     1900        maybeMutate_impl   ( node->designation, *this );
     1901
     1902        MUTATE_END( Expression, node );
     1903}
     1904
    18551905template< typename pass_type >
    18561906void PassVisitor< pass_type >::visit( VoidType * node ) {
  • src/ControlStruct/ExceptTranslate.cc

    rd2d50d7 r81e1f32  
    316316                                VarExprReplacer::DeclMap mapping;
    317317                                mapping[ handler_decl ] = local_except;
    318                                 VarExprReplacer mapper( mapping );
    319                                 handler->get_body()->accept( mapper );
     318                                VarExprReplacer::replace( handler->body, mapping );
    320319                        }
    321320
  • src/ResolvExpr/AlternativeFinder.cc

    rd2d50d7 r81e1f32  
    6060
    6161namespace ResolvExpr {
     62        struct AlternativeFinder::Finder : public WithShortCircuiting {
     63                Finder( AlternativeFinder & altFinder ) : altFinder( altFinder ), indexer( altFinder.indexer ), alternatives( altFinder.alternatives ), env( altFinder.env ), targetType( altFinder.targetType )  {}
     64
     65                void previsit( BaseSyntaxNode * ) { visit_children = false; }
     66
     67                void postvisit( ApplicationExpr * applicationExpr );
     68                void postvisit( UntypedExpr * untypedExpr );
     69                void postvisit( AddressExpr * addressExpr );
     70                void postvisit( LabelAddressExpr * labelExpr );
     71                void postvisit( CastExpr * castExpr );
     72                void postvisit( VirtualCastExpr * castExpr );
     73                void postvisit( UntypedMemberExpr * memberExpr );
     74                void postvisit( MemberExpr * memberExpr );
     75                void postvisit( NameExpr * variableExpr );
     76                void postvisit( VariableExpr * variableExpr );
     77                void postvisit( ConstantExpr * constantExpr );
     78                void postvisit( SizeofExpr * sizeofExpr );
     79                void postvisit( AlignofExpr * alignofExpr );
     80                void postvisit( UntypedOffsetofExpr * offsetofExpr );
     81                void postvisit( OffsetofExpr * offsetofExpr );
     82                void postvisit( OffsetPackExpr * offsetPackExpr );
     83                void postvisit( AttrExpr * attrExpr );
     84                void postvisit( LogicalExpr * logicalExpr );
     85                void postvisit( ConditionalExpr * conditionalExpr );
     86                void postvisit( CommaExpr * commaExpr );
     87                void postvisit( ImplicitCopyCtorExpr  * impCpCtorExpr );
     88                void postvisit( ConstructorExpr  * ctorExpr );
     89                void postvisit( RangeExpr  * rangeExpr );
     90                void postvisit( UntypedTupleExpr * tupleExpr );
     91                void postvisit( TupleExpr * tupleExpr );
     92                void postvisit( TupleIndexExpr * tupleExpr );
     93                void postvisit( TupleAssignExpr * tupleExpr );
     94                void postvisit( UniqueExpr * unqExpr );
     95                void postvisit( StmtExpr * stmtExpr );
     96                void postvisit( UntypedInitExpr * initExpr );
     97
     98                /// Adds alternatives for anonymous members
     99                void addAnonConversions( const Alternative & alt );
     100                /// Adds alternatives for member expressions, given the aggregate, conversion cost for that aggregate, and name of the member
     101                template< typename StructOrUnionType > void addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member );
     102                /// Adds alternatives for member expressions where the left side has tuple type
     103                void addTupleMembers( TupleType * tupleType, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member );
     104                /// Adds alternatives for offsetof expressions, given the base type and name of the member
     105                template< typename StructOrUnionType > void addOffsetof( StructOrUnionType *aggInst, const std::string &name );
     106                /// Takes a final result and checks if its assertions can be satisfied
     107                template<typename OutputIterator>
     108                void validateFunctionAlternative( const Alternative &func, ArgPack& result, const std::vector<ArgPack>& results, OutputIterator out );
     109                /// Finds matching alternatives for a function, given a set of arguments
     110                template<typename OutputIterator>
     111                void makeFunctionAlternatives( const Alternative &func, FunctionType *funcType, const ExplodedArgs& args, OutputIterator out );
     112                /// Checks if assertion parameters match for a new alternative
     113                template< typename OutputIterator >
     114                void inferParameters( const AssertionSet &need, AssertionSet &have, const Alternative &newAlt, OpenVarSet &openVars, OutputIterator out );
     115        private:
     116                AlternativeFinder & altFinder;
     117                const SymTab::Indexer &indexer;
     118                AltList & alternatives;
     119                const TypeEnvironment &env;
     120                Type *& targetType;
     121        };
     122
    62123        Expression *resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer, TypeEnvironment &env ) {
    63124                CastExpr *castToVoid = new CastExpr( expr );
     
    152213
    153214                void renameTypes( Expression *expr ) {
    154                         expr->get_result()->accept( global_renamer );
     215                        renameTyVars( expr->result );
    155216                }
    156217        } // namespace
     
    185246
    186247        void AlternativeFinder::find( Expression *expr, bool adjust, bool prune, bool failFast ) {
    187                 expr->accept( *this );
     248                PassVisitor<Finder> finder( *this );
     249                expr->accept( finder );
    188250                if ( failFast && alternatives.empty() ) {
    189251                        PRINT(
     
    244306        }
    245307
    246         void AlternativeFinder::addAnonConversions( const Alternative & alt ) {
     308        void AlternativeFinder::Finder::addAnonConversions( const Alternative & alt ) {
    247309                // adds anonymous member interpretations whenever an aggregate value type is seen.
    248310                // it's okay for the aggregate expression to have reference type -- cast it to the base type to treat the aggregate as the referenced value
     
    265327
    266328        template< typename StructOrUnionType >
    267         void AlternativeFinder::addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member ) {
     329        void AlternativeFinder::Finder::addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member ) {
    268330                // by this point, member must be a name expr
    269331                NameExpr * nameExpr = dynamic_cast< NameExpr * >( member );
     
    284346        }
    285347
    286         void AlternativeFinder::addTupleMembers( TupleType * tupleType, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member ) {
     348        void AlternativeFinder::Finder::addTupleMembers( TupleType * tupleType, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member ) {
    287349                if ( ConstantExpr * constantExpr = dynamic_cast< ConstantExpr * >( member ) ) {
    288350                        // get the value of the constant expression as an int, must be between 0 and the length of the tuple type to have meaning
     
    308370        }
    309371
    310         void AlternativeFinder::visit( ApplicationExpr *applicationExpr ) {
     372        void AlternativeFinder::Finder::postvisit( ApplicationExpr *applicationExpr ) {
    311373                alternatives.push_back( Alternative( applicationExpr->clone(), env, Cost::zero ) );
    312374        }
     
    485547                        Type *adjType = candidate->get_type()->clone();
    486548                        adjustExprType( adjType, newEnv, indexer );
    487                         adjType->accept( global_renamer );
     549                        renameTyVars( adjType );
    488550                        PRINT(
    489551                                std::cerr << "unifying ";
     
    541603
    542604        template< typename OutputIterator >
    543         void AlternativeFinder::inferParameters( const AssertionSet &need, AssertionSet &have, const Alternative &newAlt, OpenVarSet &openVars, OutputIterator out ) {
     605        void AlternativeFinder::Finder::inferParameters( const AssertionSet &need, AssertionSet &have, const Alternative &newAlt, OpenVarSet &openVars, OutputIterator out ) {
    544606//      PRINT(
    545607//          std::cerr << "inferParameters: assertions needed are" << std::endl;
     
    595657
    596658                ArgPack()
    597                         : parent(0), expr(), cost(Cost::zero), env(), need(), have(), openVars(), nextArg(0), 
     659                        : parent(0), expr(), cost(Cost::zero), env(), need(), have(), openVars(), nextArg(0),
    598660                          tupleStart(0), nextExpl(0), explAlt(0) {}
    599661
     
    706768
    707769                                                if ( nTuples > 0 || ! results[i].expr ) {
    708                                                         // first iteration or no expression to clone, 
     770                                                        // first iteration or no expression to clone,
    709771                                                        // push empty tuple expression
    710772                                                        newResult.parent = i;
     
    892954
    893955        template<typename OutputIterator>
    894         void AlternativeFinder::validateFunctionAlternative( const Alternative &func, ArgPack& result,
     956        void AlternativeFinder::Finder::validateFunctionAlternative( const Alternative &func, ArgPack& result,
    895957                        const std::vector<ArgPack>& results, OutputIterator out ) {
    896958                ApplicationExpr *appExpr = new ApplicationExpr( func.expr->clone() );
     
    915977
    916978        template<typename OutputIterator>
    917         void AlternativeFinder::makeFunctionAlternatives( const Alternative &func,
     979        void AlternativeFinder::Finder::makeFunctionAlternatives( const Alternative &func,
    918980                        FunctionType *funcType, const ExplodedArgs &args, OutputIterator out ) {
    919981                OpenVarSet funcOpenVars;
     
    10221084        }
    10231085
    1024         void AlternativeFinder::visit( UntypedExpr *untypedExpr ) {
     1086        void AlternativeFinder::Finder::postvisit( UntypedExpr *untypedExpr ) {
    10251087                AlternativeFinder funcFinder( indexer, env );
    10261088                funcFinder.findWithAdjustment( untypedExpr->get_function() );
     
    10291091
    10301092                std::vector< AlternativeFinder > argAlternatives;
    1031                 findSubExprs( untypedExpr->begin_args(), untypedExpr->end_args(),
     1093                altFinder.findSubExprs( untypedExpr->begin_args(), untypedExpr->end_args(),
    10321094                        back_inserter( argAlternatives ) );
    10331095
    10341096                // take care of possible tuple assignments
    10351097                // if not tuple assignment, assignment is taken care of as a normal function call
    1036                 Tuples::handleTupleAssignment( *this, untypedExpr, argAlternatives );
     1098                Tuples::handleTupleAssignment( altFinder, untypedExpr, argAlternatives );
    10371099
    10381100                // find function operators
     
    11721234                        // fix this issue in a more robust way.
    11731235                        targetType = nullptr;
    1174                         visit( untypedExpr );
     1236                        postvisit( untypedExpr );
    11751237                }
    11761238        }
     
    11811243        }
    11821244
    1183         void AlternativeFinder::visit( AddressExpr *addressExpr ) {
     1245        void AlternativeFinder::Finder::postvisit( AddressExpr *addressExpr ) {
    11841246                AlternativeFinder finder( indexer, env );
    11851247                finder.find( addressExpr->get_arg() );
     
    11921254        }
    11931255
    1194         void AlternativeFinder::visit( LabelAddressExpr * expr ) {
     1256        void AlternativeFinder::Finder::postvisit( LabelAddressExpr * expr ) {
    11951257                alternatives.push_back( Alternative{ expr->clone(), env, Cost::zero } );
    11961258        }
     
    12231285        }
    12241286
    1225         void AlternativeFinder::visit( CastExpr *castExpr ) {
     1287        void AlternativeFinder::Finder::postvisit( CastExpr *castExpr ) {
    12261288                Type *& toType = castExpr->get_result();
    12271289                assert( toType );
     
    12781340        }
    12791341
    1280         void AlternativeFinder::visit( VirtualCastExpr * castExpr ) {
     1342        void AlternativeFinder::Finder::postvisit( VirtualCastExpr * castExpr ) {
    12811343                assertf( castExpr->get_result(), "Implicate virtual cast targets not yet supported." );
    12821344                AlternativeFinder finder( indexer, env );
     
    12901352        }
    12911353
    1292         void AlternativeFinder::visit( UntypedMemberExpr *memberExpr ) {
     1354        void AlternativeFinder::Finder::postvisit( UntypedMemberExpr *memberExpr ) {
    12931355                AlternativeFinder funcFinder( indexer, env );
    12941356                funcFinder.findWithAdjustment( memberExpr->get_aggregate() );
     
    13121374        }
    13131375
    1314         void AlternativeFinder::visit( MemberExpr *memberExpr ) {
     1376        void AlternativeFinder::Finder::postvisit( MemberExpr *memberExpr ) {
    13151377                alternatives.push_back( Alternative( memberExpr->clone(), env, Cost::zero ) );
    13161378        }
    13171379
    1318         void AlternativeFinder::visit( NameExpr *nameExpr ) {
     1380        void AlternativeFinder::Finder::postvisit( NameExpr *nameExpr ) {
    13191381                std::list< SymTab::Indexer::IdData > declList;
    13201382                indexer.lookupId( nameExpr->get_name(), declList );
     
    13371399        }
    13381400
    1339         void AlternativeFinder::visit( VariableExpr *variableExpr ) {
     1401        void AlternativeFinder::Finder::postvisit( VariableExpr *variableExpr ) {
    13401402                // not sufficient to clone here, because variable's type may have changed
    13411403                // since the VariableExpr was originally created.
     
    13431405        }
    13441406
    1345         void AlternativeFinder::visit( ConstantExpr *constantExpr ) {
     1407        void AlternativeFinder::Finder::postvisit( ConstantExpr *constantExpr ) {
    13461408                alternatives.push_back( Alternative( constantExpr->clone(), env, Cost::zero ) );
    13471409        }
    13481410
    1349         void AlternativeFinder::visit( SizeofExpr *sizeofExpr ) {
     1411        void AlternativeFinder::Finder::postvisit( SizeofExpr *sizeofExpr ) {
    13501412                if ( sizeofExpr->get_isType() ) {
    13511413                        Type * newType = sizeofExpr->get_type()->clone();
     
    13681430        }
    13691431
    1370         void AlternativeFinder::visit( AlignofExpr *alignofExpr ) {
     1432        void AlternativeFinder::Finder::postvisit( AlignofExpr *alignofExpr ) {
    13711433                if ( alignofExpr->get_isType() ) {
    13721434                        Type * newType = alignofExpr->get_type()->clone();
     
    13901452
    13911453        template< typename StructOrUnionType >
    1392         void AlternativeFinder::addOffsetof( StructOrUnionType *aggInst, const std::string &name ) {
     1454        void AlternativeFinder::Finder::addOffsetof( StructOrUnionType *aggInst, const std::string &name ) {
    13931455                std::list< Declaration* > members;
    13941456                aggInst->lookup( name, members );
     
    14031465        }
    14041466
    1405         void AlternativeFinder::visit( UntypedOffsetofExpr *offsetofExpr ) {
     1467        void AlternativeFinder::Finder::postvisit( UntypedOffsetofExpr *offsetofExpr ) {
    14061468                AlternativeFinder funcFinder( indexer, env );
    14071469                // xxx - resolveTypeof?
     
    14131475        }
    14141476
    1415         void AlternativeFinder::visit( OffsetofExpr *offsetofExpr ) {
     1477        void AlternativeFinder::Finder::postvisit( OffsetofExpr *offsetofExpr ) {
    14161478                alternatives.push_back( Alternative( offsetofExpr->clone(), env, Cost::zero ) );
    14171479        }
    14181480
    1419         void AlternativeFinder::visit( OffsetPackExpr *offsetPackExpr ) {
     1481        void AlternativeFinder::Finder::postvisit( OffsetPackExpr *offsetPackExpr ) {
    14201482                alternatives.push_back( Alternative( offsetPackExpr->clone(), env, Cost::zero ) );
    14211483        }
     
    14441506        }
    14451507
    1446         void AlternativeFinder::visit( AttrExpr *attrExpr ) {
     1508        void AlternativeFinder::Finder::postvisit( AttrExpr *attrExpr ) {
    14471509                // assume no 'pointer-to-attribute'
    14481510                NameExpr *nameExpr = dynamic_cast< NameExpr* >( attrExpr->get_attr() );
     
    14581520                                        if ( function->get_parameters().size() == 1 ) {
    14591521                                                if ( attrExpr->get_isType() ) {
    1460                                                         resolveAttr( data, function, attrExpr->get_type(), env, *this );
     1522                                                        resolveAttr( data, function, attrExpr->get_type(), env, altFinder);
    14611523                                                } else {
    14621524                                                        AlternativeFinder finder( indexer, env );
     
    14641526                                                        for ( AltList::iterator choice = finder.alternatives.begin(); choice != finder.alternatives.end(); ++choice ) {
    14651527                                                                if ( choice->expr->get_result()->size() == 1 ) {
    1466                                                                         resolveAttr(data, function, choice->expr->get_result(), choice->env, *this );
     1528                                                                        resolveAttr(data, function, choice->expr->get_result(), choice->env, altFinder );
    14671529                                                                } // fi
    14681530                                                        } // for
     
    14791541        }
    14801542
    1481         void AlternativeFinder::visit( LogicalExpr *logicalExpr ) {
     1543        void AlternativeFinder::Finder::postvisit( LogicalExpr *logicalExpr ) {
    14821544                AlternativeFinder firstFinder( indexer, env );
    14831545                firstFinder.findWithAdjustment( logicalExpr->get_arg1() );
     
    14921554        }
    14931555
    1494         void AlternativeFinder::visit( ConditionalExpr *conditionalExpr ) {
     1556        void AlternativeFinder::Finder::postvisit( ConditionalExpr *conditionalExpr ) {
    14951557                // find alternatives for condition
    14961558                AlternativeFinder firstFinder( indexer, env );
     
    15241586        }
    15251587
    1526         void AlternativeFinder::visit( CommaExpr *commaExpr ) {
     1588        void AlternativeFinder::Finder::postvisit( CommaExpr *commaExpr ) {
    15271589                TypeEnvironment newEnv( env );
    15281590                Expression *newFirstArg = resolveInVoidContext( commaExpr->get_arg1(), indexer, newEnv );
     
    15351597        }
    15361598
    1537         void AlternativeFinder::visit( RangeExpr * rangeExpr ) {
     1599        void AlternativeFinder::Finder::postvisit( RangeExpr * rangeExpr ) {
    15381600                // resolve low and high, accept alternatives whose low and high types unify
    15391601                AlternativeFinder firstFinder( indexer, env );
     
    15571619        }
    15581620
    1559         void AlternativeFinder::visit( UntypedTupleExpr *tupleExpr ) {
     1621        void AlternativeFinder::Finder::postvisit( UntypedTupleExpr *tupleExpr ) {
    15601622                std::vector< AlternativeFinder > subExprAlternatives;
    1561                 findSubExprs( tupleExpr->get_exprs().begin(), tupleExpr->get_exprs().end(),
     1623                altFinder.findSubExprs( tupleExpr->get_exprs().begin(), tupleExpr->get_exprs().end(),
    15621624                        back_inserter( subExprAlternatives ) );
    15631625                std::vector< AltList > possibilities;
     
    15751637        }
    15761638
    1577         void AlternativeFinder::visit( TupleExpr *tupleExpr ) {
     1639        void AlternativeFinder::Finder::postvisit( TupleExpr *tupleExpr ) {
    15781640                alternatives.push_back( Alternative( tupleExpr->clone(), env, Cost::zero ) );
    15791641        }
    15801642
    1581         void AlternativeFinder::visit( ImplicitCopyCtorExpr * impCpCtorExpr ) {
     1643        void AlternativeFinder::Finder::postvisit( ImplicitCopyCtorExpr * impCpCtorExpr ) {
    15821644                alternatives.push_back( Alternative( impCpCtorExpr->clone(), env, Cost::zero ) );
    15831645        }
    15841646
    1585         void AlternativeFinder::visit( ConstructorExpr * ctorExpr ) {
     1647        void AlternativeFinder::Finder::postvisit( ConstructorExpr * ctorExpr ) {
    15861648                AlternativeFinder finder( indexer, env );
    15871649                // don't prune here, since it's guaranteed all alternatives will have the same type
     
    15931655        }
    15941656
    1595         void AlternativeFinder::visit( TupleIndexExpr *tupleExpr ) {
     1657        void AlternativeFinder::Finder::postvisit( TupleIndexExpr *tupleExpr ) {
    15961658                alternatives.push_back( Alternative( tupleExpr->clone(), env, Cost::zero ) );
    15971659        }
    15981660
    1599         void AlternativeFinder::visit( TupleAssignExpr *tupleAssignExpr ) {
     1661        void AlternativeFinder::Finder::postvisit( TupleAssignExpr *tupleAssignExpr ) {
    16001662                alternatives.push_back( Alternative( tupleAssignExpr->clone(), env, Cost::zero ) );
    16011663        }
    16021664
    1603         void AlternativeFinder::visit( UniqueExpr *unqExpr ) {
     1665        void AlternativeFinder::Finder::postvisit( UniqueExpr *unqExpr ) {
    16041666                AlternativeFinder finder( indexer, env );
    16051667                finder.findWithAdjustment( unqExpr->get_expr() );
     
    16111673        }
    16121674
    1613         void AlternativeFinder::visit( StmtExpr *stmtExpr ) {
     1675        void AlternativeFinder::Finder::postvisit( StmtExpr *stmtExpr ) {
    16141676                StmtExpr * newStmtExpr = stmtExpr->clone();
    16151677                ResolvExpr::resolveStmtExpr( newStmtExpr, indexer );
     
    16181680        }
    16191681
    1620         void AlternativeFinder::visit( UntypedInitExpr *initExpr ) {
     1682        void AlternativeFinder::Finder::postvisit( UntypedInitExpr *initExpr ) {
    16211683                // handle each option like a cast
    16221684                AltList candidates;
    1623                 PRINT( std::cerr << "untyped init expr: " << initExpr << std::endl; )
     1685                PRINT(
     1686                        std::cerr << "untyped init expr: " << initExpr << std::endl;
     1687                )
    16241688                // O(N^2) checks of d-types with e-types
    16251689                for ( InitAlternative & initAlt : initExpr->get_initAlts() ) {
     
    16371701                                AssertionSet needAssertions, haveAssertions;
    16381702                                OpenVarSet openVars;  // find things in env that don't have a "representative type" and claim those are open vars?
    1639                                 PRINT( std::cerr << "  @ " << toType << " " << initAlt.designation << std::endl; )
     1703                                PRINT(
     1704                                        std::cerr << "  @ " << toType << " " << initAlt.designation << std::endl;
     1705                                 )
    16401706                                // It's possible that a cast can throw away some values in a multiply-valued expression.  (An example is a
    16411707                                // cast-to-void, which casts from one value to zero.)  Figure out the prefix of the subexpression results
  • src/ResolvExpr/AlternativeFinder.h

    rd2d50d7 r81e1f32  
    3838        using ExplodedArgs = std::vector< std::vector< ExplodedActual > >;
    3939
    40         class AlternativeFinder : public Visitor {
     40        class AlternativeFinder {
    4141          public:
    4242                AlternativeFinder( const SymTab::Indexer &indexer, const TypeEnvironment &env );
     
    9494                void findSubExprs( InputIterator begin, InputIterator end, OutputIterator out );
    9595          private:
    96                 virtual void visit( ApplicationExpr *applicationExpr );
    97                 virtual void visit( UntypedExpr *untypedExpr );
    98                 virtual void visit( AddressExpr *addressExpr );
    99                 virtual void visit( LabelAddressExpr *labelExpr );
    100                 virtual void visit( CastExpr *castExpr );
    101                 virtual void visit( VirtualCastExpr *castExpr );
    102                 virtual void visit( UntypedMemberExpr *memberExpr );
    103                 virtual void visit( MemberExpr *memberExpr );
    104                 virtual void visit( NameExpr *variableExpr );
    105                 virtual void visit( VariableExpr *variableExpr );
    106                 virtual void visit( ConstantExpr *constantExpr );
    107                 virtual void visit( SizeofExpr *sizeofExpr );
    108                 virtual void visit( AlignofExpr *alignofExpr );
    109                 virtual void visit( UntypedOffsetofExpr *offsetofExpr );
    110                 virtual void visit( OffsetofExpr *offsetofExpr );
    111                 virtual void visit( OffsetPackExpr *offsetPackExpr );
    112                 virtual void visit( AttrExpr *attrExpr );
    113                 virtual void visit( LogicalExpr *logicalExpr );
    114                 virtual void visit( ConditionalExpr *conditionalExpr );
    115                 virtual void visit( CommaExpr *commaExpr );
    116                 virtual void visit( ImplicitCopyCtorExpr * impCpCtorExpr );
    117                 virtual void visit( ConstructorExpr * ctorExpr );
    118                 virtual void visit( RangeExpr * rangeExpr );
    119                 virtual void visit( UntypedTupleExpr *tupleExpr );
    120                 virtual void visit( TupleExpr *tupleExpr );
    121                 virtual void visit( TupleIndexExpr *tupleExpr );
    122                 virtual void visit( TupleAssignExpr *tupleExpr );
    123                 virtual void visit( UniqueExpr *unqExpr );
    124                 virtual void visit( StmtExpr *stmtExpr );
    125                 virtual void visit( UntypedInitExpr *initExpr );
    126 
    127                 /// Adds alternatives for anonymous members
    128                 void addAnonConversions( const Alternative & alt );
    129                 /// Adds alternatives for member expressions, given the aggregate, conversion cost for that aggregate, and name of the member
    130                 template< typename StructOrUnionType > void addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member );
    131                 /// Adds alternatives for member expressions where the left side has tuple type
    132                 void addTupleMembers( TupleType * tupleType, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member );
    133                 /// Adds alternatives for offsetof expressions, given the base type and name of the member
    134                 template< typename StructOrUnionType > void addOffsetof( StructOrUnionType *aggInst, const std::string &name );
    135                 /// Takes a final result and checks if its assertions can be satisfied
    136                 template<typename OutputIterator>
    137                 void validateFunctionAlternative( const Alternative &func, ArgPack& result, const std::vector<ArgPack>& results, OutputIterator out );
    138                 /// Finds matching alternatives for a function, given a set of arguments
    139                 template<typename OutputIterator>
    140                 void makeFunctionAlternatives( const Alternative &func, FunctionType *funcType, const ExplodedArgs& args, OutputIterator out );
    141                 /// Checks if assertion parameters match for a new alternative
    142                 template< typename OutputIterator >
    143                 void inferParameters( const AssertionSet &need, AssertionSet &have, const Alternative &newAlt, OpenVarSet &openVars, OutputIterator out );
    144 
     96                struct Finder;
    14597                const SymTab::Indexer &indexer;
    14698                AltList alternatives;
  • src/ResolvExpr/CommonType.cc

    rd2d50d7 r81e1f32  
    1818#include <utility>                       // for pair
    1919
     20#include "Common/PassVisitor.h"
    2021#include "ResolvExpr/TypeEnvironment.h"  // for OpenVarSet, AssertionSet
    2122#include "SymTab/Indexer.h"              // for Indexer
     
    2930
    3031namespace ResolvExpr {
    31         class CommonType : public Visitor {
    32           public:
     32        struct CommonType : public WithShortCircuiting {
    3333                CommonType( Type *type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars );
    3434                Type *get_result() const { return result; }
     35
     36                void previsit( BaseSyntaxNode * ) { visit_children = false; }
     37
     38                void postvisit( VoidType * voidType );
     39                void postvisit( BasicType * basicType );
     40                void postvisit( PointerType * pointerType );
     41                void postvisit( ArrayType * arrayType );
     42                void postvisit( ReferenceType * refType );
     43                void postvisit( FunctionType * functionType );
     44                void postvisit( StructInstType * aggregateUseType );
     45                void postvisit( UnionInstType * aggregateUseType );
     46                void postvisit( EnumInstType * aggregateUseType );
     47                void postvisit( TraitInstType * aggregateUseType );
     48                void postvisit( TypeInstType * aggregateUseType );
     49                void postvisit( TupleType * tupleType );
     50                void postvisit( VarArgsType * varArgsType );
     51                void postvisit( ZeroType * zeroType );
     52                void postvisit( OneType * oneType );
     53
    3554          private:
    36                 virtual void visit( VoidType *voidType );
    37                 virtual void visit( BasicType *basicType );
    38                 virtual void visit( PointerType *pointerType );
    39                 virtual void visit( ArrayType *arrayType );
    40                 virtual void visit( ReferenceType *refType );
    41                 virtual void visit( FunctionType *functionType );
    42                 virtual void visit( StructInstType *aggregateUseType );
    43                 virtual void visit( UnionInstType *aggregateUseType );
    44                 virtual void visit( EnumInstType *aggregateUseType );
    45                 virtual void visit( TraitInstType *aggregateUseType );
    46                 virtual void visit( TypeInstType *aggregateUseType );
    47                 virtual void visit( TupleType *tupleType );
    48                 virtual void visit( VarArgsType *varArgsType );
    49                 virtual void visit( ZeroType *zeroType );
    50                 virtual void visit( OneType *oneType );
    51 
    5255                template< typename Pointer > void getCommonWithVoidPointer( Pointer* voidPointer, Pointer* otherPointer );
    5356                template< typename RefType > void handleRefType( RefType *inst, Type *other );
     
    8083
    8184        Type *commonType( Type *type1, Type *type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars ) {
    82                 CommonType visitor( type2, widenFirst, widenSecond, indexer, env, openVars );
     85                PassVisitor<CommonType> visitor( type2, widenFirst, widenSecond, indexer, env, openVars );
    8386
    8487                int depth1 = type1->referenceDepth();
     
    116119
    117120                type1->accept( visitor );
    118                 Type *result = visitor.get_result();
     121                Type *result = visitor.pass.get_result();
    119122                if ( ! result ) {
    120123                        // this appears to be handling for opaque type declarations
     
    188191        }
    189192
    190         void CommonType::visit( VoidType * ) {}
    191 
    192         void CommonType::visit( BasicType *basicType ) {
     193        void CommonType::postvisit( VoidType * ) {}
     194
     195        void CommonType::postvisit( BasicType *basicType ) {
    193196                if ( BasicType *otherBasic = dynamic_cast< BasicType* >( type2 ) ) {
    194197                        BasicType::Kind newType = combinedType[ basicType->get_kind() ][ otherBasic->get_kind() ];
     
    219222        }
    220223
    221         void CommonType::visit( PointerType *pointerType ) {
     224        void CommonType::postvisit( PointerType *pointerType ) {
    222225                if ( PointerType *otherPointer = dynamic_cast< PointerType* >( type2 ) ) {
    223226                        // std::cerr << "commonType: two pointers: " << pointerType << " / " << otherPointer << std::endl;
     
    254257        }
    255258
    256         void CommonType::visit( ArrayType * ) {}
    257 
    258         void CommonType::visit( ReferenceType *refType ) {
     259        void CommonType::postvisit( ArrayType * ) {}
     260
     261        void CommonType::postvisit( ReferenceType *refType ) {
    259262                if ( ReferenceType *otherRef = dynamic_cast< ReferenceType* >( type2 ) ) {
    260263                        // std::cerr << "commonType: both references: " << refType << " / " << otherRef << std::endl;
     
    291294        }
    292295
    293         void CommonType::visit( FunctionType * ) {}
    294         void CommonType::visit( StructInstType * ) {}
    295         void CommonType::visit( UnionInstType * ) {}
    296 
    297         void CommonType::visit( EnumInstType *enumInstType ) {
     296        void CommonType::postvisit( FunctionType * ) {}
     297        void CommonType::postvisit( StructInstType * ) {}
     298        void CommonType::postvisit( UnionInstType * ) {}
     299
     300        void CommonType::postvisit( EnumInstType *enumInstType ) {
    298301                if ( dynamic_cast< BasicType * >( type2 ) || dynamic_cast< ZeroType* >( type2 ) || dynamic_cast< OneType* >( type2 ) ) {
    299302                        // reuse BasicType, EnumInstType code by swapping type2 with enumInstType
    300                         ValueGuard< Type * > temp( type2 );
    301                         type2 = enumInstType;
    302                         temp.old->accept( *this );
    303                 } // if
    304         }
    305 
    306         void CommonType::visit( TraitInstType * ) {
    307         }
    308 
    309         void CommonType::visit( TypeInstType *inst ) {
     303                        result = commonType( type2, enumInstType, widenSecond, widenFirst, indexer, env, openVars );
     304                } // if
     305        }
     306
     307        void CommonType::postvisit( TraitInstType * ) {
     308        }
     309
     310        void CommonType::postvisit( TypeInstType *inst ) {
    310311                if ( widenFirst ) {
    311312                        NamedTypeDecl *nt = indexer.lookupType( inst->get_name() );
     
    329330        }
    330331
    331         void CommonType::visit( TupleType * ) {}
    332         void CommonType::visit( VarArgsType * ) {}
    333 
    334         void CommonType::visit( ZeroType *zeroType ) {
     332        void CommonType::postvisit( TupleType * ) {}
     333        void CommonType::postvisit( VarArgsType * ) {}
     334
     335        void CommonType::postvisit( ZeroType *zeroType ) {
    335336                if ( widenFirst ) {
    336337                        if ( dynamic_cast< BasicType* >( type2 ) || dynamic_cast< PointerType* >( type2 ) || dynamic_cast< EnumInstType* >( type2 ) ) {
     
    346347        }
    347348
    348         void CommonType::visit( OneType *oneType ) {
     349        void CommonType::postvisit( OneType *oneType ) {
    349350                if ( widenFirst ) {
    350351                        if ( dynamic_cast< BasicType* >( type2 ) || dynamic_cast< EnumInstType* >( type2 ) ) {
  • src/ResolvExpr/CurrentObject.cc

    rd2d50d7 r81e1f32  
    443443                                return new UnionIterator( uit );
    444444                        } else {
    445                                 assertf( dynamic_cast< TypeInstType * >( type ), "some other reftotype" );
     445                                assertf( dynamic_cast< EnumInstType * >( type ) || dynamic_cast< TypeInstType * >( type ), "Encountered unhandled ReferenceToType in createMemberIterator: %s", toString( type ).c_str() );
    446446                                return new SimpleIterator( type );
    447447                        }
  • src/ResolvExpr/PtrsAssignable.cc

    rd2d50d7 r81e1f32  
    1414//
    1515
     16#include "Common/PassVisitor.h"
    1617#include "ResolvExpr/TypeEnvironment.h"  // for EqvClass, TypeEnvironment
    1718#include "SynTree/Type.h"                // for TypeInstType, Type, BasicType
     
    2021
    2122namespace ResolvExpr {
    22         class PtrsAssignable : public Visitor {
    23           public:
     23        struct PtrsAssignable : public WithShortCircuiting {
    2424                PtrsAssignable( Type *dest, const TypeEnvironment &env );
    2525
    2626                int get_result() const { return result; }
    2727
    28                 virtual void visit( VoidType *voidType );
    29                 virtual void visit( BasicType *basicType );
    30                 virtual void visit( PointerType *pointerType );
    31                 virtual void visit( ArrayType *arrayType );
    32                 virtual void visit( FunctionType *functionType );
    33                 virtual void visit( StructInstType *inst );
    34                 virtual void visit( UnionInstType *inst );
    35                 virtual void visit( EnumInstType *inst );
    36                 virtual void visit( TraitInstType *inst );
    37                 virtual void visit( TypeInstType *inst );
    38                 virtual void visit( TupleType *tupleType );
    39                 virtual void visit( VarArgsType *varArgsType );
    40                 virtual void visit( ZeroType *zeroType );
    41                 virtual void visit( OneType *oneType );
     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 );
    4244          private:
    4345                Type *dest;
     
    5961                        return -1;
    6062                } else {
    61                         PtrsAssignable ptrs( dest, env );
     63                        PassVisitor<PtrsAssignable> ptrs( dest, env );
    6264                        src->accept( ptrs );
    63                         return ptrs.get_result();
     65                        return ptrs.pass.get_result();
    6466                } // if
    6567        }
     
    6769        PtrsAssignable::PtrsAssignable( Type *dest, const TypeEnvironment &env ) : dest( dest ), result( 0 ), env( env ) {}
    6870
    69         void PtrsAssignable::visit( VoidType * ) {
     71        void PtrsAssignable::postvisit( VoidType * ) {
    7072                // T * = void * is disallowed - this is a change from C, where any
    7173                // void * can be assigned or passed to a non-void pointer without a cast.
    7274        }
    7375
    74         void PtrsAssignable::visit( __attribute__((unused)) BasicType *basicType ) {}
    75         void PtrsAssignable::visit( __attribute__((unused)) PointerType *pointerType ) {}
    76         void PtrsAssignable::visit( __attribute__((unused)) ArrayType *arrayType ) {}
    77         void PtrsAssignable::visit( __attribute__((unused)) FunctionType *functionType ) {}
     76        void PtrsAssignable::postvisit( __attribute__((unused)) BasicType *basicType ) {}
     77        void PtrsAssignable::postvisit( __attribute__((unused)) PointerType *pointerType ) {}
     78        void PtrsAssignable::postvisit( __attribute__((unused)) ArrayType *arrayType ) {}
     79        void PtrsAssignable::postvisit( __attribute__((unused)) FunctionType *functionType ) {}
    7880
    79         void PtrsAssignable::visit(  __attribute__((unused)) StructInstType *inst ) {}
    80         void PtrsAssignable::visit(  __attribute__((unused)) UnionInstType *inst ) {}
     81        void PtrsAssignable::postvisit(  __attribute__((unused)) StructInstType *inst ) {}
     82        void PtrsAssignable::postvisit(  __attribute__((unused)) UnionInstType *inst ) {}
    8183
    82         void PtrsAssignable::visit( EnumInstType * ) {
     84        void PtrsAssignable::postvisit( EnumInstType * ) {
    8385                if ( dynamic_cast< BasicType* >( dest ) ) {
    8486                        // int * = E *, etc. is safe. This isn't technically correct, as each
     
    9193        }
    9294
    93         void PtrsAssignable::visit(  __attribute__((unused)) TraitInstType *inst ) {}
    94         void PtrsAssignable::visit( TypeInstType *inst ) {
     95        void PtrsAssignable::postvisit(  __attribute__((unused)) TraitInstType *inst ) {}
     96        void PtrsAssignable::postvisit( TypeInstType *inst ) {
    9597                EqvClass eqvClass;
    9698                if ( env.lookup( inst->get_name(), eqvClass ) && eqvClass.type ) {
     
    100102        }
    101103
    102         void PtrsAssignable::visit(  __attribute__((unused)) TupleType *tupleType ) {}
    103         void PtrsAssignable::visit(  __attribute__((unused)) VarArgsType *varArgsType ) {}
    104         void PtrsAssignable::visit(  __attribute__((unused)) ZeroType *zeroType ) {}
    105         void PtrsAssignable::visit(  __attribute__((unused)) OneType *oneType ) {}
     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 ) {}
    106108
    107109} // namespace ResolvExpr
  • src/ResolvExpr/PtrsCastable.cc

    rd2d50d7 r81e1f32  
    1414//
    1515
     16#include "Common/PassVisitor.h"
    1617#include "ResolvExpr/TypeEnvironment.h"  // for EqvClass, TypeEnvironment
    1718#include "SymTab/Indexer.h"              // for Indexer
     
    2122#include "typeops.h"                     // for ptrsAssignable
    2223
    23 
    2424namespace ResolvExpr {
    25         class PtrsCastable : public Visitor {
     25        struct PtrsCastable : public WithShortCircuiting {
    2626          public:
    2727                PtrsCastable( Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer );
     
    2929                int get_result() const { return result; }
    3030
    31                 virtual void visit(VoidType *voidType);
    32                 virtual void visit(BasicType *basicType);
    33                 virtual void visit(PointerType *pointerType);
    34                 virtual void visit(ArrayType *arrayType);
    35                 virtual void visit(FunctionType *functionType);
    36                 virtual void visit(StructInstType *inst);
    37                 virtual void visit(UnionInstType *inst);
    38                 virtual void visit(EnumInstType *inst);
    39                 virtual void visit(TraitInstType *inst);
    40                 virtual void visit(TypeInstType *inst);
    41                 virtual void visit(TupleType *tupleType);
    42                 virtual void visit(VarArgsType *varArgsType);
    43                 virtual void visit(ZeroType *zeroType);
    44                 virtual void visit(OneType *oneType);
     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 );
    4547          private:
    4648                Type *dest;
     
    7981                        EqvClass eqvClass;
    8082                        if ( env.lookup( destAsTypeInst->get_name(), eqvClass ) ) {
     83                                // xxx - should this be ptrsCastable?
    8184                                return ptrsAssignable( src, eqvClass.type, env );
    8285                        } // if
     
    8588                        return objectCast( src, env, indexer );
    8689                } else {
    87                         PtrsCastable ptrs( dest, env, indexer );
     90                        PassVisitor<PtrsCastable> ptrs( dest, env, indexer );
    8891                        src->accept( ptrs );
    89                         return ptrs.get_result();
     92                        return ptrs.pass.get_result();
    9093                } // if
    9194        }
     
    9598        }
    9699
    97         void PtrsCastable::visit( VoidType * ) {
     100        void PtrsCastable::postvisit( VoidType * ) {
    98101                result = objectCast( dest, env, indexer );
    99102        }
    100103
    101         void PtrsCastable::visit( BasicType * ) {
     104        void PtrsCastable::postvisit( BasicType * ) {
    102105                result = objectCast( dest, env, indexer );
    103106        }
    104107
    105         void PtrsCastable::visit( PointerType * ) {
     108        void PtrsCastable::postvisit( PointerType * ) {
    106109                result = objectCast( dest, env, indexer );
    107110        }
    108111
    109         void PtrsCastable::visit( ArrayType * ) {
     112        void PtrsCastable::postvisit( ArrayType * ) {
    110113                result = objectCast( dest, env, indexer );
    111114        }
    112115
    113         void PtrsCastable::visit( FunctionType * ) {
     116        void PtrsCastable::postvisit( FunctionType * ) {
    114117                // result = -1;
    115118                result = functionCast( dest, env, indexer );
    116119        }
    117120
    118         void PtrsCastable::visit( StructInstType * ) {
     121        void PtrsCastable::postvisit( StructInstType * ) {
    119122                result = objectCast( dest, env, indexer );
    120123        }
    121124
    122         void PtrsCastable::visit( UnionInstType * ) {
     125        void PtrsCastable::postvisit( UnionInstType * ) {
    123126                result = objectCast( dest, env, indexer );
    124127        }
    125128
    126         void PtrsCastable::visit( EnumInstType * ) {
     129        void PtrsCastable::postvisit( EnumInstType * ) {
    127130                if ( dynamic_cast< EnumInstType* >( dest ) ) {
    128131                        result = 1;
     
    138141        }
    139142
    140         void PtrsCastable::visit( TraitInstType * ) {}
     143        void PtrsCastable::postvisit( TraitInstType * ) {}
    141144
    142         void PtrsCastable::visit(TypeInstType *inst) {
     145        void PtrsCastable::postvisit(TypeInstType *inst) {
    143146                //result = objectCast( inst, env, indexer ) > 0 && objectCast( dest, env, indexer ) > 0 ? 1 : -1;
    144147                result = objectCast( inst, env, indexer ) == objectCast( dest, env, indexer ) ? 1 : -1;
    145148        }
    146149
    147         void PtrsCastable::visit( TupleType * ) {
     150        void PtrsCastable::postvisit( TupleType * ) {
    148151                result = objectCast( dest, env, indexer );
    149152        }
    150153
    151         void PtrsCastable::visit( VarArgsType * ) {
     154        void PtrsCastable::postvisit( VarArgsType * ) {
    152155                result = objectCast( dest, env, indexer );
    153156        }
    154157
    155         void PtrsCastable::visit( ZeroType * ) {
     158        void PtrsCastable::postvisit( ZeroType * ) {
    156159                result = objectCast( dest, env, indexer );
    157160        }
    158161
    159         void PtrsCastable::visit( OneType * ) {
     162        void PtrsCastable::postvisit( OneType * ) {
    160163                result = objectCast( dest, env, indexer );
    161164        }
  • src/ResolvExpr/RenameVars.cc

    rd2d50d7 r81e1f32  
    1919#include <utility>                 // for pair
    2020
     21#include "Common/PassVisitor.h"
    2122#include "Common/SemanticError.h"  // for SemanticError
    2223#include "RenameVars.h"
     
    2728
    2829namespace ResolvExpr {
    29         RenameVars global_renamer;
     30        namespace {
     31                struct RenameVars {
     32                        RenameVars();
     33                        void reset();
    3034
    31         RenameVars::RenameVars() : level( 0 ), resetCount( 0 ) {
    32                 mapStack.push_front( std::map< std::string, std::string >() );
     35                        void previsit( TypeInstType * instType );
     36                        void previsit( Type * );
     37                        void postvisit( Type * );
     38
     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 );
    3349        }
    3450
    35         void RenameVars::reset() {
    36                 level = 0;
    37                 resetCount++;
     51        void resetTyVarRenaming() {
     52                global_renamer.pass.reset();
    3853        }
    3954
    40         void RenameVars::visit( VoidType *voidType ) {
    41                 typeBefore( voidType );
    42                 typeAfter( voidType );
    43         }
     55        namespace {
     56                RenameVars::RenameVars() : level( 0 ), resetCount( 0 ) {
     57                        mapStack.push_front( std::map< std::string, std::string >() );
     58                }
    4459
    45         void RenameVars::visit( BasicType *basicType ) {
    46                 typeBefore( basicType );
    47                 typeAfter( basicType );
    48         }
     60                void RenameVars::reset() {
     61                        level = 0;
     62                        resetCount++;
     63                }
    4964
    50         void RenameVars::visit( PointerType *pointerType ) {
    51                 typeBefore( pointerType );
    52                 maybeAccept( pointerType->get_base(), *this );
    53                 typeAfter( pointerType );
    54         }
     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                }
    5572
    56         void RenameVars::visit( ArrayType *arrayType ) {
    57                 typeBefore( arrayType );
    58                 maybeAccept( arrayType->get_dimension(), *this );
    59                 maybeAccept( arrayType->get_base(), *this );
    60                 typeAfter( arrayType );
    61         }
     73                void RenameVars::previsit( Type * type ) {
     74                        if ( ! type->forall.empty() ) {
     75                                // copies current name mapping into new mapping
     76                                mapStack.push_front( mapStack.front() );
     77                                // renames all "forall" type names to `_${level}_${name}'
     78                                for ( auto td : type->forall ) {
     79                                        std::ostringstream output;
     80                                        output << "_" << resetCount << "_" << level << "_" << td->name;
     81                                        std::string newname( output.str() );
     82                                        mapStack.front()[ td->get_name() ] = newname;
     83                                        td->name = newname;
     84                                        // ditto for assertion names, the next level in
     85                                        level++;
     86                                        // acceptAll( td->assertions, *this );
     87                                } // for
     88                        } // if
     89                }
    6290
    63         void RenameVars::visit( FunctionType *functionType ) {
    64                 typeBefore( functionType );
    65                 acceptAll( functionType->get_returnVals(), *this );
    66                 acceptAll( functionType->get_parameters(), *this );
    67                 typeAfter( functionType );
    68         }
    69 
    70         void RenameVars::visit( StructInstType *aggregateUseType ) {
    71                 typeBefore( aggregateUseType );
    72                 acceptAll( aggregateUseType->get_parameters(), *this );
    73                 typeAfter( aggregateUseType );
    74         }
    75 
    76         void RenameVars::visit( UnionInstType *aggregateUseType ) {
    77                 typeBefore( aggregateUseType );
    78                 acceptAll( aggregateUseType->get_parameters(), *this );
    79                 typeAfter( aggregateUseType );
    80         }
    81 
    82         void RenameVars::visit( EnumInstType *aggregateUseType ) {
    83                 typeBefore( aggregateUseType );
    84                 acceptAll( aggregateUseType->get_parameters(), *this );
    85                 typeAfter( aggregateUseType );
    86         }
    87 
    88         void RenameVars::visit( TraitInstType *aggregateUseType ) {
    89                 typeBefore( aggregateUseType );
    90                 acceptAll( aggregateUseType->get_parameters(), *this );
    91                 typeAfter( aggregateUseType );
    92         }
    93 
    94         void RenameVars::visit( TypeInstType *instType ) {
    95                 typeBefore( instType );
    96                 std::map< std::string, std::string >::const_iterator i = mapStack.front().find( instType->get_name() );
    97                 if ( i != mapStack.front().end() ) {
    98                         instType->set_name( i->second );
    99                 } else {
    100                 } // if
    101                 acceptAll( instType->get_parameters(), *this );
    102                 typeAfter( instType );
    103         }
    104 
    105         void RenameVars::visit( TupleType *tupleType ) {
    106                 typeBefore( tupleType );
    107                 acceptAll( tupleType->get_types(), *this );
    108                 typeAfter( tupleType );
    109         }
    110 
    111         void RenameVars::visit( VarArgsType *varArgsType ) {
    112                 typeBefore( varArgsType );
    113                 typeAfter( varArgsType );
    114         }
    115 
    116         void RenameVars::visit( ZeroType *zeroType ) {
    117                 typeBefore( zeroType );
    118                 typeAfter( zeroType );
    119         }
    120 
    121         void RenameVars::visit( OneType *oneType ) {
    122                 typeBefore( oneType );
    123                 typeAfter( oneType );
    124         }
    125 
    126         void RenameVars::typeBefore( Type *type ) {
    127                 if ( ! type->get_forall().empty() ) {
    128                         // copies current name mapping into new mapping
    129                         mapStack.push_front( mapStack.front() );
    130                         // renames all "forall" type names to `_${level}_${name}'
    131                         for ( Type::ForallList::iterator i = type->get_forall().begin(); i != type->get_forall().end(); ++i ) {
    132                                 std::ostringstream output;
    133                                 output << "_" << resetCount << "_" << level << "_" << (*i)->get_name();
    134                                 std::string newname( output.str() );
    135                                 mapStack.front()[ (*i)->get_name() ] = newname;
    136                                 (*i)->set_name( newname );
    137                                 // ditto for assertion names, the next level in
    138                                 level++;
    139                                 acceptAll( (*i)->get_assertions(), *this );
    140                         } // for
    141                 } // if
    142         }
    143 
    144         void RenameVars::typeAfter( Type *type ) {
    145                 // clears name mapping added by typeBefore()
    146                 if ( ! type->get_forall().empty() ) {
    147                         mapStack.pop_front();
    148                 } // if
    149         }
    150 
     91                void RenameVars::postvisit( Type * type ) {
     92                        // clears name mapping added by typeBefore()
     93                        if ( ! type->forall.empty() ) {
     94                                mapStack.pop_front();
     95                        } // if
     96                }
     97        } // namespace
    15198} // namespace ResolvExpr
    15299
  • src/ResolvExpr/RenameVars.h

    rd2d50d7 r81e1f32  
    2424
    2525namespace ResolvExpr {
     26        /// Provides a consistent renaming of forall type names in a hierarchy by prefixing them with a unique "level" ID
     27        void renameTyVars( Type * );
    2628
    27         /// Provides a consistent renaming of forall type names in a hierarchy by prefixing them with a unique "level" ID
    28         class RenameVars : public Visitor {
    29           public:
    30                 RenameVars();
    31                 void reset();
    32           private:
    33                 virtual void visit( VoidType *basicType );
    34                 virtual void visit( BasicType *basicType );
    35                 virtual void visit( PointerType *pointerType );
    36                 virtual void visit( ArrayType *arrayType );
    37                 virtual void visit( FunctionType *functionType );
    38                 virtual void visit( StructInstType *aggregateUseType );
    39                 virtual void visit( UnionInstType *aggregateUseType );
    40                 virtual void visit( EnumInstType *aggregateUseType );
    41                 virtual void visit( TraitInstType *aggregateUseType );
    42                 virtual void visit( TypeInstType *aggregateUseType );
    43                 virtual void visit( TupleType *tupleType );
    44                 virtual void visit( VarArgsType *varArgsType );
    45                 virtual void visit( ZeroType *zeroType );
    46                 virtual void visit( OneType *oneType );
    47 
    48                 void typeBefore( Type *type );
    49                 void typeAfter( Type *type );
    50                 int level, resetCount;
    51                 std::list< std::map< std::string, std::string > > mapStack;
    52         };
    53 
    54         extern RenameVars global_renamer;
     29        /// resets internal state of renamer to avoid overflow
     30        void resetTyVarRenaming();
    5531} // namespace ResolvExpr
    5632
  • src/ResolvExpr/Resolver.cc

    rd2d50d7 r81e1f32  
    132132
    133133        void findVoidExpression( Expression *& untyped, const SymTab::Indexer &indexer ) {
    134                 global_renamer.reset();
     134                resetTyVarRenaming();
    135135                TypeEnvironment env;
    136136                Expression *newExpr = resolveInVoidContext( untyped, indexer, env );
  • src/ResolvExpr/Unify.cc

    rd2d50d7 r81e1f32  
    4444namespace ResolvExpr {
    4545
    46         class Unify : public Visitor {
    47           public:
     46        struct Unify : public WithShortCircuiting {
    4847                Unify( Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer );
    4948
    5049                bool get_result() const { return result; }
     50
     51                void previsit( BaseSyntaxNode * ) { visit_children = false; }
     52
     53                void postvisit( VoidType * voidType );
     54                void postvisit( BasicType * basicType );
     55                void postvisit( PointerType * pointerType );
     56                void postvisit( ArrayType * arrayType );
     57                void postvisit( ReferenceType * refType );
     58                void postvisit( FunctionType * functionType );
     59                void postvisit( StructInstType * aggregateUseType );
     60                void postvisit( UnionInstType * aggregateUseType );
     61                void postvisit( EnumInstType * aggregateUseType );
     62                void postvisit( TraitInstType * aggregateUseType );
     63                void postvisit( TypeInstType * aggregateUseType );
     64                void postvisit( TupleType * tupleType );
     65                void postvisit( VarArgsType * varArgsType );
     66                void postvisit( ZeroType * zeroType );
     67                void postvisit( OneType * oneType );
     68
    5169          private:
    52                 virtual void visit(VoidType *voidType);
    53                 virtual void visit(BasicType *basicType);
    54                 virtual void visit(PointerType *pointerType);
    55                 virtual void visit(ArrayType *arrayType);
    56                 virtual void visit(ReferenceType *refType);
    57                 virtual void visit(FunctionType *functionType);
    58                 virtual void visit(StructInstType *aggregateUseType);
    59                 virtual void visit(UnionInstType *aggregateUseType);
    60                 virtual void visit(EnumInstType *aggregateUseType);
    61                 virtual void visit(TraitInstType *aggregateUseType);
    62                 virtual void visit(TypeInstType *aggregateUseType);
    63                 virtual void visit(TupleType *tupleType);
    64                 virtual void visit(VarArgsType *varArgsType);
    65                 virtual void visit(ZeroType *zeroType);
    66                 virtual void visit(OneType *oneType);
    67 
    6870                template< typename RefType > void handleRefType( RefType *inst, Type *other );
    6971                template< typename RefType > void handleGenericRefType( RefType *inst, Type *other );
     
    325327                        result = bindVar( var2, type1, entry2->second, env, needAssertions, haveAssertions, openVars, widenMode, indexer );
    326328                } else {
    327                         Unify comparator( type2, env, needAssertions, haveAssertions, openVars, widenMode, indexer );
     329                        PassVisitor<Unify> comparator( type2, env, needAssertions, haveAssertions, openVars, widenMode, indexer );
    328330                        type1->accept( comparator );
    329                         result = comparator.get_result();
     331                        result = comparator.pass.get_result();
    330332                } // if
    331333#ifdef DEBUG
     
    404406        }
    405407
    406         void Unify::visit( __attribute__((unused)) VoidType *voidType) {
     408        void Unify::postvisit( __attribute__((unused)) VoidType *voidType) {
    407409                result = dynamic_cast< VoidType* >( type2 );
    408410        }
    409411
    410         void Unify::visit(BasicType *basicType) {
     412        void Unify::postvisit(BasicType *basicType) {
    411413                if ( BasicType *otherBasic = dynamic_cast< BasicType* >( type2 ) ) {
    412414                        result = basicType->get_kind() == otherBasic->get_kind();
     
    436438        }
    437439
    438         void Unify::visit(PointerType *pointerType) {
     440        void Unify::postvisit(PointerType *pointerType) {
    439441                if ( PointerType *otherPointer = dynamic_cast< PointerType* >( type2 ) ) {
    440442                        result = unifyExact( pointerType->get_base(), otherPointer->get_base(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
     
    444446        }
    445447
    446         void Unify::visit(ReferenceType *refType) {
     448        void Unify::postvisit(ReferenceType *refType) {
    447449                if ( ReferenceType *otherRef = dynamic_cast< ReferenceType* >( type2 ) ) {
    448450                        result = unifyExact( refType->get_base(), otherRef->get_base(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer );
     
    452454        }
    453455
    454         void Unify::visit(ArrayType *arrayType) {
     456        void Unify::postvisit(ArrayType *arrayType) {
    455457                ArrayType *otherArray = dynamic_cast< ArrayType* >( type2 );
    456458                // to unify, array types must both be VLA or both not VLA
     
    567569        }
    568570
    569         void Unify::visit(FunctionType *functionType) {
     571        void Unify::postvisit(FunctionType *functionType) {
    570572                FunctionType *otherFunction = dynamic_cast< FunctionType* >( type2 );
    571573                if ( otherFunction && functionType->get_isVarArgs() == otherFunction->get_isVarArgs() ) {
     
    669671        }
    670672
    671         void Unify::visit(StructInstType *structInst) {
     673        void Unify::postvisit(StructInstType *structInst) {
    672674                handleGenericRefType( structInst, type2 );
    673675        }
    674676
    675         void Unify::visit(UnionInstType *unionInst) {
     677        void Unify::postvisit(UnionInstType *unionInst) {
    676678                handleGenericRefType( unionInst, type2 );
    677679        }
    678680
    679         void Unify::visit(EnumInstType *enumInst) {
     681        void Unify::postvisit(EnumInstType *enumInst) {
    680682                handleRefType( enumInst, type2 );
    681683        }
    682684
    683         void Unify::visit(TraitInstType *contextInst) {
     685        void Unify::postvisit(TraitInstType *contextInst) {
    684686                handleRefType( contextInst, type2 );
    685687        }
    686688
    687         void Unify::visit(TypeInstType *typeInst) {
     689        void Unify::postvisit(TypeInstType *typeInst) {
    688690                assert( openVars.find( typeInst->get_name() ) == openVars.end() );
    689691                TypeInstType *otherInst = dynamic_cast< TypeInstType* >( type2 );
     
    740742        }
    741743
    742         void Unify::visit(TupleType *tupleType) {
     744        void Unify::postvisit(TupleType *tupleType) {
    743745                if ( TupleType *otherTuple = dynamic_cast< TupleType* >( type2 ) ) {
    744746                        std::unique_ptr<TupleType> flat1( tupleType->clone() );
     
    757759        }
    758760
    759         void Unify::visit( __attribute__((unused)) VarArgsType *varArgsType ) {
     761        void Unify::postvisit( __attribute__((unused)) VarArgsType *varArgsType ) {
    760762                result = dynamic_cast< VarArgsType* >( type2 );
    761763        }
    762764
    763         void Unify::visit( __attribute__((unused)) ZeroType *zeroType ) {
     765        void Unify::postvisit( __attribute__((unused)) ZeroType *zeroType ) {
    764766                result = dynamic_cast< ZeroType* >( type2 );
    765767        }
    766768
    767         void Unify::visit( __attribute__((unused)) OneType *oneType ) {
     769        void Unify::postvisit( __attribute__((unused)) OneType *oneType ) {
    768770                result = dynamic_cast< OneType* >( type2 );
    769771        }
  • src/SymTab/Mangler.cc

    rd2d50d7 r81e1f32  
    2323
    2424#include "CodeGen/OperatorTable.h"  // for OperatorInfo, operatorLookup
     25#include "Common/PassVisitor.h"
    2526#include "Common/SemanticError.h"   // for SemanticError
    2627#include "Common/utility.h"         // for toString
     
    3132
    3233namespace SymTab {
    33         std::string Mangler::mangleType( Type * ty ) {
    34                 Mangler mangler( false, true, true );
    35                 maybeAccept( ty, mangler );
    36                 return mangler.get_mangleName();
    37         }
    38 
    39         std::string Mangler::mangleConcrete( Type* ty ) {
    40                 Mangler mangler( false, false, false );
    41                 maybeAccept( ty, mangler );
    42                 return mangler.get_mangleName();
    43         }
    44 
    45         Mangler::Mangler( bool mangleOverridable, bool typeMode, bool mangleGenericParams )
    46                 : nextVarNum( 0 ), isTopLevel( true ), mangleOverridable( mangleOverridable ), typeMode( typeMode ), mangleGenericParams( mangleGenericParams ) {}
    47 
    48         Mangler::Mangler( const Mangler &rhs ) : mangleName() {
    49                 varNums = rhs.varNums;
    50                 nextVarNum = rhs.nextVarNum;
    51                 isTopLevel = rhs.isTopLevel;
    52                 mangleOverridable = rhs.mangleOverridable;
    53                 typeMode = rhs.typeMode;
    54         }
    55 
    56         void Mangler::mangleDecl( DeclarationWithType * declaration ) {
    57                 bool wasTopLevel = isTopLevel;
    58                 if ( isTopLevel ) {
    59                         varNums.clear();
    60                         nextVarNum = 0;
    61                         isTopLevel = false;
    62                 } // if
    63                 mangleName << "__";
    64                 CodeGen::OperatorInfo opInfo;
    65                 if ( operatorLookup( declaration->get_name(), opInfo ) ) {
    66                         mangleName << opInfo.outputName;
    67                 } else {
    68                         mangleName << declaration->get_name();
    69                 } // if
    70                 mangleName << "__";
    71                 maybeAccept( declaration->get_type(), *this );
    72                 if ( mangleOverridable && LinkageSpec::isOverridable( declaration->get_linkage() ) ) {
    73                         // want to be able to override autogenerated and intrinsic routines,
    74                         // so they need a different name mangling
    75                         if ( declaration->get_linkage() == LinkageSpec::AutoGen ) {
    76                                 mangleName << "autogen__";
    77                         } else if ( declaration->get_linkage() == LinkageSpec::Intrinsic ) {
    78                                 mangleName << "intrinsic__";
    79                         } else {
    80                                 // if we add another kind of overridable function, this has to change
    81                                 assert( false && "unknown overrideable linkage" );
    82                         } // if
     34        namespace Mangler {
     35                namespace {
     36                        /// Mangles names to a unique C identifier
     37                        struct Mangler : public WithShortCircuiting, public WithVisitorRef<Mangler> {
     38                                Mangler( bool mangleOverridable, bool typeMode, bool mangleGenericParams );
     39                                Mangler( const Mangler & );
     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( TupleType * tupleType );
     58                                void postvisit( VarArgsType * varArgsType );
     59                                void postvisit( ZeroType * zeroType );
     60                                void postvisit( OneType * oneType );
     61
     62                                std::string get_mangleName() { return mangleName.str(); }
     63                          private:
     64                                std::ostringstream mangleName;  ///< Mangled name being constructed
     65                                typedef std::map< std::string, std::pair< int, int > > VarMapType;
     66                                VarMapType varNums;             ///< Map of type variables to indices
     67                                int nextVarNum;                 ///< Next type variable index
     68                                bool isTopLevel;                ///< Is the Mangler at the top level
     69                                bool mangleOverridable;         ///< Specially mangle overridable built-in methods
     70                                bool typeMode;                  ///< Produce a unique mangled name for a type
     71                                bool mangleGenericParams;       ///< Include generic parameters in name mangling if true
     72
     73                                void mangleDecl( DeclarationWithType *declaration );
     74                                void mangleRef( ReferenceToType *refType, std::string prefix );
     75
     76                                void printQualifiers( Type *type );
     77                        }; // Mangler
     78                } // namespace
     79
     80                std::string mangle( BaseSyntaxNode * decl, bool mangleOverridable, bool typeMode, bool mangleGenericParams ) {
     81                        PassVisitor<Mangler> mangler( mangleOverridable, typeMode, mangleGenericParams );
     82                        maybeAccept( decl, mangler );
     83                        return mangler.pass.get_mangleName();
    8384                }
    84                 isTopLevel = wasTopLevel;
    85         }
    86 
    87         void Mangler::visit( ObjectDecl * declaration ) {
    88                 mangleDecl( declaration );
    89         }
    90 
    91         void Mangler::visit( FunctionDecl * declaration ) {
    92                 mangleDecl( declaration );
    93         }
    94 
    95         void Mangler::visit( VoidType * voidType ) {
    96                 printQualifiers( voidType );
    97                 mangleName << "v";
    98         }
    99 
    100         void Mangler::visit( BasicType * basicType ) {
    101                 static const char *btLetter[] = {
    102                         "b",    // Bool
    103                         "c",    // Char
    104                         "Sc",   // SignedChar
    105                         "Uc",   // UnsignedChar
    106                         "s",    // ShortSignedInt
    107                         "Us",   // ShortUnsignedInt
    108                         "i",    // SignedInt
    109                         "Ui",   // UnsignedInt
    110                         "l",    // LongSignedInt
    111                         "Ul",   // LongUnsignedInt
    112                         "q",    // LongLongSignedInt
    113                         "Uq",   // LongLongUnsignedInt
    114                         "f",    // Float
    115                         "d",    // Double
    116                         "r",    // LongDouble
    117                         "Xf",   // FloatComplex
    118                         "Xd",   // DoubleComplex
    119                         "Xr",   // LongDoubleComplex
    120                         "If",   // FloatImaginary
    121                         "Id",   // DoubleImaginary
    122                         "Ir",   // LongDoubleImaginary
    123                         "w",    // SignedInt128
    124                         "Uw",   // UnsignedInt128
    125                 };
    126 
    127                 printQualifiers( basicType );
    128                 mangleName << btLetter[ basicType->get_kind() ];
    129         }
    130 
    131         void Mangler::visit( PointerType * pointerType ) {
    132                 printQualifiers( pointerType );
    133                 mangleName << "P";
    134                 maybeAccept( pointerType->get_base(), *this );
    135         }
    136 
    137         void Mangler::visit( ArrayType * arrayType ) {
    138                 // TODO: encode dimension
    139                 printQualifiers( arrayType );
    140                 mangleName << "A0";
    141                 maybeAccept( arrayType->get_base(), *this );
    142         }
    143 
    144         void Mangler::visit( ReferenceType * refType ) {
    145                 printQualifiers( refType );
    146                 mangleName << "R";
    147                 maybeAccept( refType->get_base(), *this );
    148         }
    149 
    150         namespace {
    151                 inline std::list< Type* > getTypes( const std::list< DeclarationWithType* > decls ) {
    152                         std::list< Type* > ret;
    153                         std::transform( decls.begin(), decls.end(), std::back_inserter( ret ),
    154                                                         std::mem_fun( &DeclarationWithType::get_type ) );
    155                         return ret;
     85
     86                std::string mangleType( Type * ty ) {
     87                        PassVisitor<Mangler> mangler( false, true, true );
     88                        maybeAccept( ty, mangler );
     89                        return mangler.pass.get_mangleName();
    15690                }
    157         }
    158 
    159         void Mangler::visit( FunctionType * functionType ) {
    160                 printQualifiers( functionType );
    161                 mangleName << "F";
    162                 std::list< Type* > returnTypes = getTypes( functionType->get_returnVals() );
    163                 acceptAll( returnTypes, *this );
    164                 mangleName << "_";
    165                 std::list< Type* > paramTypes = getTypes( functionType->get_parameters() );
    166                 acceptAll( paramTypes, *this );
    167                 mangleName << "_";
    168         }
    169 
    170         void Mangler::mangleRef( ReferenceToType * refType, std::string prefix ) {
    171                 printQualifiers( refType );
    172 
    173                 mangleName << ( refType->get_name().length() + prefix.length() ) << prefix << refType->get_name();
    174 
    175                 if ( mangleGenericParams ) {
    176                         std::list< Expression* >& params = refType->get_parameters();
    177                         if ( ! params.empty() ) {
     91
     92                std::string mangleConcrete( Type * ty ) {
     93                        PassVisitor<Mangler> mangler( false, false, false );
     94                        maybeAccept( ty, mangler );
     95                        return mangler.pass.get_mangleName();
     96                }
     97
     98                namespace {
     99                        Mangler::Mangler( bool mangleOverridable, bool typeMode, bool mangleGenericParams )
     100                                : nextVarNum( 0 ), isTopLevel( true ), mangleOverridable( mangleOverridable ), typeMode( typeMode ), mangleGenericParams( mangleGenericParams ) {}
     101
     102                        Mangler::Mangler( const Mangler &rhs ) : mangleName() {
     103                                varNums = rhs.varNums;
     104                                nextVarNum = rhs.nextVarNum;
     105                                isTopLevel = rhs.isTopLevel;
     106                                mangleOverridable = rhs.mangleOverridable;
     107                                typeMode = rhs.typeMode;
     108                        }
     109
     110                        void Mangler::mangleDecl( DeclarationWithType * declaration ) {
     111                                bool wasTopLevel = isTopLevel;
     112                                if ( isTopLevel ) {
     113                                        varNums.clear();
     114                                        nextVarNum = 0;
     115                                        isTopLevel = false;
     116                                } // if
     117                                mangleName << "__";
     118                                CodeGen::OperatorInfo opInfo;
     119                                if ( operatorLookup( declaration->get_name(), opInfo ) ) {
     120                                        mangleName << opInfo.outputName;
     121                                } else {
     122                                        mangleName << declaration->get_name();
     123                                } // if
     124                                mangleName << "__";
     125                                maybeAccept( declaration->get_type(), *visitor );
     126                                if ( mangleOverridable && LinkageSpec::isOverridable( declaration->get_linkage() ) ) {
     127                                        // want to be able to override autogenerated and intrinsic routines,
     128                                        // so they need a different name mangling
     129                                        if ( declaration->get_linkage() == LinkageSpec::AutoGen ) {
     130                                                mangleName << "autogen__";
     131                                        } else if ( declaration->get_linkage() == LinkageSpec::Intrinsic ) {
     132                                                mangleName << "intrinsic__";
     133                                        } else {
     134                                                // if we add another kind of overridable function, this has to change
     135                                                assert( false && "unknown overrideable linkage" );
     136                                        } // if
     137                                }
     138                                isTopLevel = wasTopLevel;
     139                        }
     140
     141                        void Mangler::postvisit( ObjectDecl * declaration ) {
     142                                mangleDecl( declaration );
     143                        }
     144
     145                        void Mangler::postvisit( FunctionDecl * declaration ) {
     146                                mangleDecl( declaration );
     147                        }
     148
     149                        void Mangler::postvisit( VoidType * voidType ) {
     150                                printQualifiers( voidType );
     151                                mangleName << "v";
     152                        }
     153
     154                        void Mangler::postvisit( BasicType * basicType ) {
     155                                static const char *btLetter[] = {
     156                                        "b",    // Bool
     157                                        "c",    // Char
     158                                        "Sc",   // SignedChar
     159                                        "Uc",   // UnsignedChar
     160                                        "s",    // ShortSignedInt
     161                                        "Us",   // ShortUnsignedInt
     162                                        "i",    // SignedInt
     163                                        "Ui",   // UnsignedInt
     164                                        "l",    // LongSignedInt
     165                                        "Ul",   // LongUnsignedInt
     166                                        "q",    // LongLongSignedInt
     167                                        "Uq",   // LongLongUnsignedInt
     168                                        "f",    // Float
     169                                        "d",    // Double
     170                                        "r",    // LongDouble
     171                                        "Xf",   // FloatComplex
     172                                        "Xd",   // DoubleComplex
     173                                        "Xr",   // LongDoubleComplex
     174                                        "If",   // FloatImaginary
     175                                        "Id",   // DoubleImaginary
     176                                        "Ir",   // LongDoubleImaginary
     177                                        "w",    // SignedInt128
     178                                        "Uw",   // UnsignedInt128
     179                                };
     180
     181                                printQualifiers( basicType );
     182                                mangleName << btLetter[ basicType->get_kind() ];
     183                        }
     184
     185                        void Mangler::postvisit( PointerType * pointerType ) {
     186                                printQualifiers( pointerType );
     187                                mangleName << "P";
     188                                maybeAccept( pointerType->get_base(), *visitor );
     189                        }
     190
     191                        void Mangler::postvisit( ArrayType * arrayType ) {
     192                                // TODO: encode dimension
     193                                printQualifiers( arrayType );
     194                                mangleName << "A0";
     195                                maybeAccept( arrayType->get_base(), *visitor );
     196                        }
     197
     198                        void Mangler::postvisit( ReferenceType * refType ) {
     199                                printQualifiers( refType );
     200                                mangleName << "R";
     201                                maybeAccept( refType->get_base(), *visitor );
     202                        }
     203
     204                        namespace {
     205                                inline std::list< Type* > getTypes( const std::list< DeclarationWithType* > decls ) {
     206                                        std::list< Type* > ret;
     207                                        std::transform( decls.begin(), decls.end(), std::back_inserter( ret ),
     208                                                                        std::mem_fun( &DeclarationWithType::get_type ) );
     209                                        return ret;
     210                                }
     211                        }
     212
     213                        void Mangler::postvisit( FunctionType * functionType ) {
     214                                printQualifiers( functionType );
     215                                mangleName << "F";
     216                                std::list< Type* > returnTypes = getTypes( functionType->get_returnVals() );
     217                                acceptAll( returnTypes, *visitor );
    178218                                mangleName << "_";
    179                                 for ( std::list< Expression* >::const_iterator param = params.begin(); param != params.end(); ++param ) {
    180                                         TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param );
    181                                         assertf(paramType, "Aggregate parameters should be type expressions: %s", toString(*param).c_str());
    182                                         maybeAccept( paramType->get_type(), *this );
     219                                std::list< Type* > paramTypes = getTypes( functionType->get_parameters() );
     220                                acceptAll( paramTypes, *visitor );
     221                                mangleName << "_";
     222                        }
     223
     224                        void Mangler::mangleRef( ReferenceToType * refType, std::string prefix ) {
     225                                printQualifiers( refType );
     226
     227                                mangleName << ( refType->get_name().length() + prefix.length() ) << prefix << refType->get_name();
     228
     229                                if ( mangleGenericParams ) {
     230                                        std::list< Expression* >& params = refType->get_parameters();
     231                                        if ( ! params.empty() ) {
     232                                                mangleName << "_";
     233                                                for ( std::list< Expression* >::const_iterator param = params.begin(); param != params.end(); ++param ) {
     234                                                        TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param );
     235                                                        assertf(paramType, "Aggregate parameters should be type expressions: %s", toString(*param).c_str());
     236                                                        maybeAccept( paramType->get_type(), *visitor );
     237                                                }
     238                                                mangleName << "_";
     239                                        }
    183240                                }
     241                        }
     242
     243                        void Mangler::postvisit( StructInstType * aggregateUseType ) {
     244                                mangleRef( aggregateUseType, "s" );
     245                        }
     246
     247                        void Mangler::postvisit( UnionInstType * aggregateUseType ) {
     248                                mangleRef( aggregateUseType, "u" );
     249                        }
     250
     251                        void Mangler::postvisit( EnumInstType * aggregateUseType ) {
     252                                mangleRef( aggregateUseType, "e" );
     253                        }
     254
     255                        void Mangler::postvisit( TypeInstType * typeInst ) {
     256                                VarMapType::iterator varNum = varNums.find( typeInst->get_name() );
     257                                if ( varNum == varNums.end() ) {
     258                                        mangleRef( typeInst, "t" );
     259                                } else {
     260                                        printQualifiers( typeInst );
     261                                        std::ostringstream numStream;
     262                                        numStream << varNum->second.first;
     263                                        switch ( (TypeDecl::Kind )varNum->second.second ) {
     264                                          case TypeDecl::Dtype:
     265                                                mangleName << "d";
     266                                                break;
     267                                          case TypeDecl::Ftype:
     268                                                mangleName << "f";
     269                                                break;
     270                                                case TypeDecl::Ttype:
     271                                                mangleName << "tVARGS";
     272                                                break;
     273                                                default:
     274                                                assert( false );
     275                                        } // switch
     276                                        mangleName << numStream.str();
     277                                } // if
     278                        }
     279
     280                        void Mangler::postvisit( TupleType * tupleType ) {
     281                                printQualifiers( tupleType );
     282                                mangleName << "T";
     283                                acceptAll( tupleType->types, *visitor );
    184284                                mangleName << "_";
    185285                        }
    186                 }
    187         }
    188 
    189         void Mangler::visit( StructInstType * aggregateUseType ) {
    190                 mangleRef( aggregateUseType, "s" );
    191         }
    192 
    193         void Mangler::visit( UnionInstType * aggregateUseType ) {
    194                 mangleRef( aggregateUseType, "u" );
    195         }
    196 
    197         void Mangler::visit( EnumInstType * aggregateUseType ) {
    198                 mangleRef( aggregateUseType, "e" );
    199         }
    200 
    201         void Mangler::visit( TypeInstType * typeInst ) {
    202                 VarMapType::iterator varNum = varNums.find( typeInst->get_name() );
    203                 if ( varNum == varNums.end() ) {
    204                         mangleRef( typeInst, "t" );
    205                 } else {
    206                         printQualifiers( typeInst );
    207                         std::ostringstream numStream;
    208                         numStream << varNum->second.first;
    209                         switch ( (TypeDecl::Kind )varNum->second.second ) {
    210                           case TypeDecl::Dtype:
    211                                 mangleName << "d";
    212                                 break;
    213                           case TypeDecl::Ftype:
    214                                 mangleName << "f";
    215                                 break;
    216                                 case TypeDecl::Ttype:
    217                                 mangleName << "tVARGS";
    218                                 break;
    219                                 default:
    220                                 assert( false );
    221                         } // switch
    222                         mangleName << numStream.str();
    223                 } // if
    224         }
    225 
    226         void Mangler::visit( TupleType * tupleType ) {
    227                 printQualifiers( tupleType );
    228                 mangleName << "T";
    229                 acceptAll( tupleType->types, *this );
    230                 mangleName << "_";
    231         }
    232 
    233         void Mangler::visit( VarArgsType * varArgsType ) {
    234                 printQualifiers( varArgsType );
    235                 mangleName << "VARGS";
    236         }
    237 
    238         void Mangler::visit( ZeroType * ) {
    239                 mangleName << "Z";
    240         }
    241 
    242         void Mangler::visit( OneType * ) {
    243                 mangleName << "O";
    244         }
    245 
    246         void Mangler::visit( TypeDecl * decl ) {
    247                 static const char *typePrefix[] = { "BT", "BD", "BF" };
    248                 mangleName << typePrefix[ decl->get_kind() ] << ( decl->name.length() + 1 ) << decl->name;
    249         }
    250 
    251         void printVarMap( const std::map< std::string, std::pair< int, int > > &varMap, std::ostream &os ) {
    252                 for ( std::map< std::string, std::pair< int, int > >::const_iterator i = varMap.begin(); i != varMap.end(); ++i ) {
    253                         os << i->first << "(" << i->second.first << "/" << i->second.second << ")" << std::endl;
    254                 } // for
    255         }
    256 
    257         void Mangler::printQualifiers( Type * type ) {
    258                 // skip if not including qualifiers
    259                 if ( typeMode ) return;
    260 
    261                 if ( ! type->get_forall().empty() ) {
    262                         std::list< std::string > assertionNames;
    263                         int tcount = 0, dcount = 0, fcount = 0, vcount = 0;
    264                         mangleName << "A";
    265                         for ( Type::ForallList::iterator i = type->forall.begin(); i != type->forall.end(); ++i ) {
    266                                 switch ( (*i)->get_kind() ) {
    267                                   case TypeDecl::Dtype:
    268                                         dcount++;
    269                                         break;
    270                                   case TypeDecl::Ftype:
    271                                         fcount++;
    272                                         break;
    273                                   case TypeDecl::Ttype:
    274                                         vcount++;
    275                                         break;
    276                                   default:
    277                                         assert( false );
    278                                 } // switch
    279                                 varNums[ (*i)->name ] = std::pair< int, int >( nextVarNum++, (int)(*i)->get_kind() );
    280                                 for ( std::list< DeclarationWithType* >::iterator assert = (*i)->assertions.begin(); assert != (*i)->assertions.end(); ++assert ) {
    281                                         Mangler sub_mangler( mangleOverridable, typeMode, mangleGenericParams );
    282                                         sub_mangler.nextVarNum = nextVarNum;
    283                                         sub_mangler.isTopLevel = false;
    284                                         sub_mangler.varNums = varNums;
    285                                         (*assert)->accept( sub_mangler );
    286                                         assertionNames.push_back( sub_mangler.mangleName.str() );
     286
     287                        void Mangler::postvisit( VarArgsType * varArgsType ) {
     288                                printQualifiers( varArgsType );
     289                                mangleName << "VARGS";
     290                        }
     291
     292                        void Mangler::postvisit( ZeroType * ) {
     293                                mangleName << "Z";
     294                        }
     295
     296                        void Mangler::postvisit( OneType * ) {
     297                                mangleName << "O";
     298                        }
     299
     300                        void Mangler::postvisit( TypeDecl * decl ) {
     301                                static const char *typePrefix[] = { "BT", "BD", "BF" };
     302                                mangleName << typePrefix[ decl->get_kind() ] << ( decl->name.length() + 1 ) << decl->name;
     303                        }
     304
     305                        __attribute__((unused)) void printVarMap( const std::map< std::string, std::pair< int, int > > &varMap, std::ostream &os ) {
     306                                for ( std::map< std::string, std::pair< int, int > >::const_iterator i = varMap.begin(); i != varMap.end(); ++i ) {
     307                                        os << i->first << "(" << i->second.first << "/" << i->second.second << ")" << std::endl;
    287308                                } // for
    288                         } // for
    289                         mangleName << tcount << "_" << dcount << "_" << fcount << "_" << vcount << "_";
    290                         std::copy( assertionNames.begin(), assertionNames.end(), std::ostream_iterator< std::string >( mangleName, "" ) );
    291                         mangleName << "_";
    292                 } // if
    293                 if ( type->get_const() ) {
    294                         mangleName << "C";
    295                 } // if
    296                 if ( type->get_volatile() ) {
    297                         mangleName << "V";
    298                 } // if
    299                 if ( type->get_mutex() ) {
    300                         mangleName << "M";
    301                 } // if
    302                 // Removed due to restrict not affecting function compatibility in GCC
    303 //              if ( type->get_isRestrict() ) {
    304 //                      mangleName << "E";
    305 //              } // if
    306                 if ( type->get_lvalue() ) {
    307                         // mangle based on whether the type is lvalue, so that the resolver can differentiate lvalues and rvalues
    308                         mangleName << "L";
    309                 }
    310                 if ( type->get_atomic() ) {
    311                         mangleName << "A";
    312                 } // if
    313         }
     309                        }
     310
     311                        void Mangler::printQualifiers( Type * type ) {
     312                                // skip if not including qualifiers
     313                                if ( typeMode ) return;
     314
     315                                if ( ! type->get_forall().empty() ) {
     316                                        std::list< std::string > assertionNames;
     317                                        int tcount = 0, dcount = 0, fcount = 0, vcount = 0;
     318                                        mangleName << "A";
     319                                        for ( Type::ForallList::iterator i = type->forall.begin(); i != type->forall.end(); ++i ) {
     320                                                switch ( (*i)->get_kind() ) {
     321                                                  case TypeDecl::Dtype:
     322                                                        dcount++;
     323                                                        break;
     324                                                  case TypeDecl::Ftype:
     325                                                        fcount++;
     326                                                        break;
     327                                                  case TypeDecl::Ttype:
     328                                                        vcount++;
     329                                                        break;
     330                                                  default:
     331                                                        assert( false );
     332                                                } // switch
     333                                                varNums[ (*i)->name ] = std::pair< int, int >( nextVarNum++, (int)(*i)->get_kind() );
     334                                                for ( std::list< DeclarationWithType* >::iterator assert = (*i)->assertions.begin(); assert != (*i)->assertions.end(); ++assert ) {
     335                                                        PassVisitor<Mangler> sub_mangler( mangleOverridable, typeMode, mangleGenericParams );
     336                                                        sub_mangler.pass.nextVarNum = nextVarNum;
     337                                                        sub_mangler.pass.isTopLevel = false;
     338                                                        sub_mangler.pass.varNums = varNums;
     339                                                        (*assert)->accept( sub_mangler );
     340                                                        assertionNames.push_back( sub_mangler.pass.mangleName.str() );
     341                                                } // for
     342                                        } // for
     343                                        mangleName << tcount << "_" << dcount << "_" << fcount << "_" << vcount << "_";
     344                                        std::copy( assertionNames.begin(), assertionNames.end(), std::ostream_iterator< std::string >( mangleName, "" ) );
     345                                        mangleName << "_";
     346                                } // if
     347                                if ( type->get_const() ) {
     348                                        mangleName << "C";
     349                                } // if
     350                                if ( type->get_volatile() ) {
     351                                        mangleName << "V";
     352                                } // if
     353                                if ( type->get_mutex() ) {
     354                                        mangleName << "M";
     355                                } // if
     356                                // Removed due to restrict not affecting function compatibility in GCC
     357                //              if ( type->get_isRestrict() ) {
     358                //                      mangleName << "E";
     359                //              } // if
     360                                if ( type->get_lvalue() ) {
     361                                        // mangle based on whether the type is lvalue, so that the resolver can differentiate lvalues and rvalues
     362                                        mangleName << "L";
     363                                }
     364                                if ( type->get_atomic() ) {
     365                                        mangleName << "A";
     366                                } // if
     367                        }
     368                }       // namespace
     369        } // namespace Mangler
    314370} // namespace SymTab
    315371
  • src/SymTab/Mangler.h

    rd2d50d7 r81e1f32  
    2525
    2626namespace SymTab {
    27         /// Mangles names to a unique C identifier
    28         class Mangler : public Visitor {
    29           public:
     27        namespace Mangler {
    3028                /// Mangle syntax tree object; primary interface to clients
    31                 template< typename SynTreeClass >
    32             static std::string mangle( SynTreeClass *decl, bool mangleOverridable = true, bool typeMode = false, bool mangleGenericParams = true );
     29                std::string mangle( BaseSyntaxNode * decl, bool mangleOverridable = true, bool typeMode = false, bool mangleGenericParams = true );
     30
    3331                /// Mangle a type name; secondary interface
    34                 static std::string mangleType( Type* ty );
     32                std::string mangleType( Type* ty );
    3533                /// Mangle ignoring generic type parameters
    36                 static std::string mangleConcrete( Type* ty );
    37 
    38 
    39                 virtual void visit( ObjectDecl *declaration );
    40                 virtual void visit( FunctionDecl *declaration );
    41                 virtual void visit( TypeDecl *declaration );
    42 
    43                 virtual void visit( VoidType *voidType );
    44                 virtual void visit( BasicType *basicType );
    45                 virtual void visit( PointerType *pointerType );
    46                 virtual void visit( ArrayType *arrayType );
    47                 virtual void visit( ReferenceType *refType );
    48                 virtual void visit( FunctionType *functionType );
    49                 virtual void visit( StructInstType *aggregateUseType );
    50                 virtual void visit( UnionInstType *aggregateUseType );
    51                 virtual void visit( EnumInstType *aggregateUseType );
    52                 virtual void visit( TypeInstType *aggregateUseType );
    53                 virtual void visit( TupleType *tupleType );
    54                 virtual void visit( VarArgsType *varArgsType );
    55                 virtual void visit( ZeroType *zeroType );
    56                 virtual void visit( OneType *oneType );
    57 
    58                 std::string get_mangleName() { return mangleName.str(); }
    59           private:
    60                 std::ostringstream mangleName;  ///< Mangled name being constructed
    61                 typedef std::map< std::string, std::pair< int, int > > VarMapType;
    62                 VarMapType varNums;             ///< Map of type variables to indices
    63                 int nextVarNum;                 ///< Next type variable index
    64                 bool isTopLevel;                ///< Is the Mangler at the top level
    65                 bool mangleOverridable;         ///< Specially mangle overridable built-in methods
    66                 bool typeMode;                  ///< Produce a unique mangled name for a type
    67                 bool mangleGenericParams;       ///< Include generic parameters in name mangling if true
    68 
    69                 Mangler( bool mangleOverridable, bool typeMode, bool mangleGenericParams );
    70                 Mangler( const Mangler & );
    71 
    72                 void mangleDecl( DeclarationWithType *declaration );
    73                 void mangleRef( ReferenceToType *refType, std::string prefix );
    74 
    75                 void printQualifiers( Type *type );
    76         }; // Mangler
    77 
    78         template< typename SynTreeClass >
    79         std::string Mangler::mangle( SynTreeClass *decl, bool mangleOverridable, bool typeMode, bool mangleGenericParams ) {
    80                 Mangler mangler( mangleOverridable, typeMode, mangleGenericParams );
    81                 maybeAccept( decl, mangler );
    82                 return mangler.get_mangleName();
    83         }
     34                std::string mangleConcrete( Type* ty );
     35        } // Mangler
    8436} // SymTab
    8537
  • src/SynTree/CompoundStmt.cc

    rd2d50d7 r81e1f32  
    6464        }
    6565        if ( ! declMap.empty() ) {
    66                 VarExprReplacer replacer( declMap );
    67                 accept( replacer );
     66                VarExprReplacer::replace( this, declMap );
    6867        }
    6968}
  • src/SynTree/FunctionDecl.cc

    rd2d50d7 r81e1f32  
    4949        }
    5050        if ( ! declMap.empty() ) {
    51                 VarExprReplacer replacer( declMap );
    52                 accept( replacer );
     51                VarExprReplacer::replace( this, declMap );
    5352        }
    5453}
  • src/SynTree/VarExprReplacer.cc

    rd2d50d7 r81e1f32  
    1616#include <iostream>       // for operator<<, basic_ostream, ostream, basic_o...
    1717
     18#include "Common/PassVisitor.h"
    1819#include "Declaration.h"  // for operator<<, DeclarationWithType
    1920#include "Expression.h"   // for VariableExpr
    2021#include "VarExprReplacer.h"
    2122
    22 VarExprReplacer::VarExprReplacer( const DeclMap & declMap, bool debug ) : declMap( declMap ), debug( debug ) {}
     23namespace VarExprReplacer {
     24        namespace {
     25                /// Visitor that replaces the declarations that VariableExprs refer to, according to the supplied mapping
     26                struct VarExprReplacer {
     27                private:
     28                        const DeclMap & declMap;
     29                        bool debug;
     30                public:
     31                        VarExprReplacer( const DeclMap & declMap, bool debug = false );
    2332
    24 // replace variable with new node from decl map
    25 void VarExprReplacer::visit( VariableExpr * varExpr ) {
    26         // 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)
    27         if ( declMap.count( varExpr->get_var() ) ) {
    28                 if ( debug ) {
    29                         std::cerr << "replacing variable reference: " << (void*)varExpr->get_var() << " " << varExpr->get_var() << " with " << (void*)declMap.at( varExpr->get_var() ) << " " << declMap.at( varExpr->get_var() ) << std::endl;
     33                        // replace variable with new node from decl map
     34                        void previsit( VariableExpr * varExpr );
     35                };
     36        }
     37
     38        void replace( BaseSyntaxNode * node, const DeclMap & declMap, bool debug ) {
     39                PassVisitor<VarExprReplacer> replacer( declMap, debug );
     40                maybeAccept( node, replacer );
     41        }
     42
     43        namespace {
     44                VarExprReplacer::VarExprReplacer( const DeclMap & declMap, bool debug ) : declMap( declMap ), debug( debug ) {}
     45
     46                // replace variable with new node from decl map
     47                void VarExprReplacer::previsit( VariableExpr * varExpr ) {
     48                        // 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)
     49                        if ( declMap.count( varExpr->var ) ) {
     50                                if ( debug ) {
     51                                        std::cerr << "replacing variable reference: " << (void*)varExpr->var << " " << varExpr->var << " with " << (void*)declMap.at( varExpr->var ) << " " << declMap.at( varExpr->var ) << std::endl;
     52                                }
     53                                varExpr->var = declMap.at( varExpr->var );
     54                        }
    3055                }
    31                 varExpr->set_var( declMap.at( varExpr->get_var() ) );
    3256        }
    33 }
     57} // namespace VarExprReplacer
     58
     59
     60
     61
     62
     63
     64
  • src/SynTree/VarExprReplacer.h

    rd2d50d7 r81e1f32  
    2323class VariableExpr;
    2424
    25 /// Visitor that replaces the declarations that VariableExprs refer to, according to the supplied mapping
    26 class VarExprReplacer : public Visitor {
    27 public:
     25namespace VarExprReplacer {
    2826        typedef std::map< DeclarationWithType *, DeclarationWithType * > DeclMap;
    29 private:
    30         const DeclMap & declMap;
    31         bool debug;
    32 public:
    33         VarExprReplacer( const DeclMap & declMap, bool debug = false );
    3427
    35         // replace variable with new node from decl map
    36         virtual void visit( VariableExpr * varExpr );
    37 
    38         static void replace( BaseSyntaxNode * node, const DeclMap & declMap, bool debug = false ) {
    39                 VarExprReplacer replacer( declMap, debug );
    40                 maybeAccept( node, replacer );
    41         }
    42 };
     28        void replace( BaseSyntaxNode * node, const DeclMap & declMap, bool debug = false );
     29}
    4330
    4431// Local Variables: //
  • src/tests/.expect/alloc-ERROR.txt

    rd2d50d7 r81e1f32  
    11alloc.c:264:1 error: No reasonable alternatives for expression Applying untyped:
     2  Name: ?=?
     3...to:
     4  Name: p
     5  Applying untyped:
     6    Name: realloc
     7  ...to:
     8    Name: stp
     9    Applying untyped:
     10      Name: ?*?
     11    ...to:
     12      Name: dim
     13      Sizeof Expression on: Applying untyped:
     14          Name: *?
     15        ...to:
     16          Name: stp
     17
     18
     19
     20
     21alloc.c:265:1 error: No reasonable alternatives for expression Applying untyped:
    222  Name: ?=?
    323...to:
     
    1939
    2040
    21 alloc.c:265:1 error: No reasonable alternatives for expression Applying untyped:
     41alloc.c:266:1 error: No reasonable alternatives for expression Applying untyped:
    2242  Name: ?=?
    2343...to:
     
    3050
    3151
    32 alloc.c:266:1 error: No reasonable alternatives for expression Applying untyped:
     52alloc.c:267:1 error: No reasonable alternatives for expression Applying untyped:
    3353  Name: ?=?
    3454...to:
  • src/tests/.expect/alloc.txt

    rd2d50d7 r81e1f32  
    6060pointer arithmetic 0
    6161CFA deep malloc 0xdeadbeef
    62 
    63 SHOULD FAIL
  • src/tests/alloc.c

    rd2d50d7 r81e1f32  
    1010// Created On       : Wed Feb  3 07:56:22 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Nov 24 23:06:42 2017
    13 // Update Count     : 319
     12// Last Modified On : Mon Jan 22 21:26:40 2018
     13// Update Count     : 326
    1414//
    1515
     
    3232        // allocation, non-array types
    3333
    34         // int &r = malloc();
     34        // int & r = malloc();
    3535        // r = 0xdeadbeef;
    3636        // printf( "C   malloc %#x\n", r );
    3737        // free( &r );
    3838
    39         p = (int *)(void *)malloc( sizeof(*p) );                        // C malloc, type unsafe
     39        p = (int *)malloc( sizeof(*p) );                                        // C malloc, type unsafe
    4040        *p = 0xdeadbeef;
    4141        printf( "C   malloc %#x\n", *p );
     
    8888        printf( "\n" );
    8989
    90         p = (int *)(void *)realloc( p, dim * sizeof(*p) );      // C realloc
     90        p = (int *)realloc( p, dim * sizeof(*p) );                      // C realloc
    9191        for ( int i = 0; i < dim; i += 1 ) { p[i] = 0xdeadbeef; }
    9292        printf( "C   realloc\n" );
     
    259259        free( p );
    260260
     261#ifdef ERR1
    261262        stp = malloc();
    262263        printf( "\nSHOULD FAIL\n" );
    263 #ifdef ERR1
    264         p = alloc( stp, dim * sizeof(*stp) );
     264        p = realloc( stp, dim * sizeof( *stp ) );
     265        p = alloc( stp, dim * sizeof( *stp ) );
    265266        p = memset( stp, 10 );
    266267        p = memcpy( &st1, &st );
  • src/tests/vector.c

    rd2d50d7 r81e1f32  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // libcfa_vector.c --
     7// vector.c --
    88//
    99// Author           : Thierry Delisle
    1010// Created On       : Mon Jul  4 23:36:19 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Jul  5 15:08:05 2016
    13 // Update Count     : 26
     12// Last Modified On : Thu Jan 18 17:08:08 2018
     13// Update Count     : 27
    1414//
    1515
     
    6363// Local Variables: //
    6464// tab-width: 4 //
    65 // compile-command: "cfa libcfa_vector.c" //
     65// compile-command: "cfa vector.c" //
    6666// End: //
Note: See TracChangeset for help on using the changeset viewer.