Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/Resolver.cc

    rd76c588 r99d4584  
    2121#include "Alternative.h"                 // for Alternative, AltList
    2222#include "AlternativeFinder.h"           // for AlternativeFinder, resolveIn...
     23#include "Candidate.hpp"
     24#include "CandidateFinder.hpp"
    2325#include "CurrentObject.h"               // for CurrentObject
    2426#include "RenameVars.h"                  // for RenameVars, global_renamer
     
    2729#include "typeops.h"                     // for extractResultType
    2830#include "Unify.h"                       // for unify
     31#include "AST/Decl.hpp"
     32#include "AST/Init.hpp"
    2933#include "AST/Pass.hpp"
     34#include "AST/Print.hpp"
    3035#include "AST/SymbolTable.hpp"
    3136#include "Common/PassVisitor.h"          // for PassVisitor
     
    4550#include "SynTree/Visitor.h"             // for acceptAll, maybeAccept
    4651#include "Tuples/Tuples.h"
     52#include "Validate/FindSpecialDecls.h"   // for SizeType
    4753
    4854using namespace std;
     
    112118
    113119        namespace {
    114                 struct DeleteFinder : public WithShortCircuiting        {
     120                struct DeleteFinder_old : public WithShortCircuiting    {
    115121                        DeletedExpr * delExpr = nullptr;
    116122                        void previsit( DeletedExpr * expr ) {
     
    126132
    127133        DeletedExpr * findDeletedExpr( Expression * expr ) {
    128                 PassVisitor<DeleteFinder> finder;
     134                PassVisitor<DeleteFinder_old> finder;
    129135                expr->accept( finder );
    130136                return finder.pass.delExpr;
     
    132138
    133139        namespace {
    134                 struct StripCasts {
     140                struct StripCasts_old {
    135141                        Expression * postmutate( CastExpr * castExpr ) {
    136142                                if ( castExpr->isGenerated && ResolvExpr::typesCompatible( castExpr->arg->result, castExpr->result, SymTab::Indexer() ) ) {
     
    145151
    146152                        static void strip( Expression *& expr ) {
    147                                 PassVisitor<StripCasts> stripper;
     153                                PassVisitor<StripCasts_old> stripper;
    148154                                expr = expr->acceptMutator( stripper );
    149155                        }
     
    153159                        expr->env = oldenv ? oldenv->clone() : new TypeSubstitution;
    154160                        env.makeSubstitution( *expr->env );
    155                         StripCasts::strip( expr ); // remove unnecessary casts that may be buried in an expression
     161                        StripCasts_old::strip( expr ); // remove unnecessary casts that may be buried in an expression
    156162                }
    157163
     
    237243                                winner.cost = winner.cvtCost;
    238244                        }
    239                        
     245
    240246                        // produce ambiguous errors, if applicable
    241247                        if ( winners.size() != 1 ) {
     
    257263
    258264                        // xxx - check for ambiguous expressions
    259                        
     265
    260266                        // output selected choice
    261267                        alt = std::move( choice );
     
    421427        void Resolver_old::handlePtrType( PtrType * type ) {
    422428                if ( type->get_dimension() ) {
    423                         findSingleExpression( type->dimension, SymTab::SizeType->clone(), indexer );
     429                        findSingleExpression( type->dimension, Validate::SizeType->clone(), indexer );
    424430                }
    425431        }
     
    446452                // default value expressions have an environment which shouldn't be there and trips up
    447453                // later passes.
    448                 // xxx - it might be necessary to somehow keep the information from this environment, but I 
     454                // xxx - it might be necessary to somehow keep the information from this environment, but I
    449455                // can't currently see how it's useful.
    450456                for ( Declaration * d : functionDecl->type->parameters ) {
     
    797803                initExpr->expr = nullptr;
    798804                std::swap( initExpr->env, newExpr->env );
    799                 // InitExpr may have inferParams in the case where the expression specializes a function 
    800                 // pointer, and newExpr may already have inferParams of its own, so a simple swap is not 
     805                // InitExpr may have inferParams in the case where the expression specializes a function
     806                // pointer, and newExpr may already have inferParams of its own, so a simple swap is not
    801807                // sufficient.
    802808                newExpr->spliceInferParams( initExpr );
    803809                delete initExpr;
    804810
    805                 // get the actual object's type (may not exactly match what comes back from the resolver 
     811                // get the actual object's type (may not exactly match what comes back from the resolver
    806812                // due to conversions)
    807813                Type * initContext = currentObject.getCurrentType();
     
    816822                                        if ( isCharType( pt->get_base() ) ) {
    817823                                                if ( CastExpr * ce = dynamic_cast< CastExpr * >( newExpr ) ) {
    818                                                         // strip cast if we're initializing a char[] with a char *, 
     824                                                        // strip cast if we're initializing a char[] with a char *,
    819825                                                        // e.g.  char x[] = "hello";
    820826                                                        newExpr = ce->get_arg();
     
    839845                // move cursor into brace-enclosed initializer-list
    840846                currentObject.enterListInit();
    841                 // xxx - fix this so that the list isn't copied, iterator should be used to change current 
     847                // xxx - fix this so that the list isn't copied, iterator should be used to change current
    842848                // element
    843849                std::list<Designation *> newDesignations;
    844850                for ( auto p : group_iterate(listInit->get_designations(), listInit->get_initializers()) ) {
    845                         // iterate designations and initializers in pairs, moving the cursor to the current 
     851                        // iterate designations and initializers in pairs, moving the cursor to the current
    846852                        // designated object and resolving the initializer against that object.
    847853                        Designation * des = std::get<0>(p);
     
    936942        ///////////////////////////////////////////////////////////////////////////
    937943
     944        namespace {
     945                /// Finds deleted expressions in an expression tree
     946                struct DeleteFinder_new final : public ast::WithShortCircuiting {
     947                        const ast::DeletedExpr * delExpr = nullptr;
     948
     949                        void previsit( const ast::DeletedExpr * expr ) {
     950                                if ( delExpr ) { visit_children = false; }
     951                                else { delExpr = expr; }
     952                        }
     953
     954                        void previsit( const ast::Expr * ) {
     955                                if ( delExpr ) { visit_children = false; }
     956                        }
     957                };
     958
     959                /// Check if this expression is or includes a deleted expression
     960                const ast::DeletedExpr * findDeletedExpr( const ast::Expr * expr ) {
     961                        ast::Pass<DeleteFinder_new> finder;
     962                        expr->accept( finder );
     963                        return finder.pass.delExpr;
     964                }
     965
     966                /// Calls the CandidateFinder and finds the single best candidate
     967                CandidateRef findUnfinishedKindExpression(
     968                        const ast::Expr * untyped, const ast::SymbolTable & symtab, const std::string & kind,
     969                        std::function<bool(const Candidate &)> pred, ResolvMode mode = {}
     970                ) {
     971                        if ( ! untyped ) return nullptr;
     972
     973                        // xxx - this isn't thread-safe, but should work until we parallelize the resolver
     974                        static unsigned recursion_level = 0;
     975
     976                        ++recursion_level;
     977                        ast::TypeEnvironment env;
     978                        CandidateFinder finder{ symtab, env };
     979                        finder.find( untyped, recursion_level == 1 ? mode.atTopLevel() : mode );
     980                        --recursion_level;
     981
     982                        // produce a filtered list of candidates
     983                        CandidateList candidates;
     984                        for ( auto & cand : finder.candidates ) {
     985                                if ( pred( *cand ) ) { candidates.emplace_back( cand ); }
     986                        }
     987
     988                        // produce invalid error if no candidates
     989                        if ( candidates.empty() ) {
     990                                SemanticError( untyped,
     991                                        toString( "No reasonable alternatives for ", kind, (kind != "" ? " " : ""),
     992                                        "expression: ") );
     993                        }
     994
     995                        // search for cheapest candidate
     996                        CandidateList winners;
     997                        bool seen_undeleted = false;
     998                        for ( CandidateRef & cand : candidates ) {
     999                                int c = winners.empty() ? -1 : cand->cost.compare( winners.front()->cost );
     1000
     1001                                if ( c > 0 ) continue;  // skip more expensive than winner
     1002
     1003                                if ( c < 0 ) {
     1004                                        // reset on new cheapest
     1005                                        seen_undeleted = ! findDeletedExpr( cand->expr );
     1006                                        winners.clear();
     1007                                } else /* if ( c == 0 ) */ {
     1008                                        if ( findDeletedExpr( cand->expr ) ) {
     1009                                                // skip deleted expression if already seen one equivalent-cost not
     1010                                                if ( seen_undeleted ) continue;
     1011                                        } else if ( ! seen_undeleted ) {
     1012                                                // replace list of equivalent-cost deleted expressions with one non-deleted
     1013                                                winners.clear();
     1014                                                seen_undeleted = true;
     1015                                        }
     1016                                }
     1017
     1018                                winners.emplace_back( std::move( cand ) );
     1019                        }
     1020
     1021                        // promote candidate.cvtCost to .cost
     1022                        for ( CandidateRef & cand : winners ) {
     1023                                cand->cost = cand->cvtCost;
     1024                        }
     1025
     1026                        // produce ambiguous errors, if applicable
     1027                        if ( winners.size() != 1 ) {
     1028                                std::ostringstream stream;
     1029                                stream << "Cannot choose between " << winners.size() << " alternatives for "
     1030                                        << kind << (kind != "" ? " " : "") << "expression\n";
     1031                                ast::print( stream, untyped );
     1032                                stream << " Alternatives are:\n";
     1033                                print( stream, winners, 1 );
     1034                                SemanticError( untyped->location, stream.str() );
     1035                        }
     1036
     1037                        // single selected choice
     1038                        CandidateRef & choice = winners.front();
     1039
     1040                        // fail on only expression deleted
     1041                        if ( ! seen_undeleted ) {
     1042                                SemanticError( untyped->location, choice->expr.get(), "Unique best alternative "
     1043                                "includes deleted identifier in " );
     1044                        }
     1045
     1046                        return std::move( choice );
     1047                }
     1048
     1049                /// Strips extraneous casts out of an expression
     1050                struct StripCasts_new final {
     1051                        const ast::Expr * postmutate( const ast::CastExpr * castExpr ) {
     1052                                if (
     1053                                        castExpr->isGenerated
     1054                                        && typesCompatible( castExpr->arg->result, castExpr->result )
     1055                                ) {
     1056                                        // generated cast is the same type as its argument, remove it after keeping env
     1057                                        ast::ptr<ast::Expr> arg = castExpr->arg;
     1058                                        arg.get_and_mutate()->env = castExpr->env;
     1059                                        return arg;
     1060                                }
     1061                                return castExpr;
     1062                        }
     1063
     1064                        static void strip( ast::ptr< ast::Expr > & expr ) {
     1065                                ast::Pass< StripCasts_new > stripper;
     1066                                expr = expr->accept( stripper );
     1067                        }
     1068                };
     1069
     1070                /// Establish post-resolver invariants for expressions
     1071                void finishExpr(
     1072                        ast::ptr< ast::Expr > & expr, const ast::TypeEnvironment & env,
     1073                        const ast::TypeSubstitution * oldenv = nullptr
     1074                ) {
     1075                        // set up new type substitution for expression
     1076                        ast::ptr< ast::TypeSubstitution > newenv =
     1077                                 oldenv ? oldenv : new ast::TypeSubstitution{};
     1078                        env.writeToSubstitution( *newenv.get_and_mutate() );
     1079                        expr.get_and_mutate()->env = std::move( newenv );
     1080                        // remove unncecessary casts
     1081                        StripCasts_new::strip( expr );
     1082                }
     1083               
     1084                /// resolve `untyped` to the expression whose candidate satisfies `pred` with the
     1085                /// lowest cost, returning the resolved version
     1086                ast::ptr< ast::Expr > findKindExpression(
     1087                        const ast::Expr * untyped, const ast::SymbolTable & symtab, const std::string & kind,
     1088                        std::function<bool(const Candidate &)> pred, ResolvMode mode = {}
     1089                ) {
     1090                        if ( ! untyped ) return {};
     1091                        CandidateRef choice =
     1092                                findUnfinishedKindExpression( untyped, symtab, kind, pred, mode );
     1093                        finishExpr( choice->expr, choice->env, untyped->env );
     1094                        return std::move( choice->expr );
     1095                }
     1096
     1097                /// Predicate for "Candidate has integral type"
     1098                bool hasIntegralType( const Candidate & i ) {
     1099                        const ast::Type * type = i.expr->result;
     1100                       
     1101                        if ( auto bt = dynamic_cast< const ast::BasicType * >( type ) ) {
     1102                                return bt->isInteger();
     1103                        } else if (
     1104                                dynamic_cast< const ast::EnumInstType * >( type )
     1105                                || dynamic_cast< const ast::ZeroType * >( type )
     1106                                || dynamic_cast< const ast::OneType * >( type )
     1107                        ) {
     1108                                return true;
     1109                        } else return false;
     1110                }
     1111
     1112                /// Resolve `untyped` as an integral expression, returning the resolved version
     1113                ast::ptr< ast::Expr > findIntegralExpression(
     1114                        const ast::Expr * untyped, const ast::SymbolTable & symtab
     1115                ) {
     1116                        return findKindExpression( untyped, symtab, "condition", hasIntegralType );
     1117                }
     1118        }
     1119
    9381120        class Resolver_new final
    939         : public ast::WithIndexer, public ast::WithGuards, public ast::WithVisitorRef<Resolver_new>,
    940           public ast::WithShortCircuiting, public ast::WithStmtsToAdd<> {
    941                  
     1121        : public ast::WithSymbolTable, public ast::WithGuards,
     1122          public ast::WithVisitorRef<Resolver_new>, public ast::WithShortCircuiting,
     1123          public ast::WithStmtsToAdd<> {
     1124       
     1125                ast::ptr< ast::Type > functionReturn = nullptr;
     1126                // ast::CurrentObject currentObject = nullptr;
     1127                bool inEnumDecl = false;
     1128
    9421129        public:
    9431130                Resolver_new() = default;
    944                 Resolver_new( const ast::SymbolTable & syms ) { /*symtab = syms;*/ }
    945 
    946                 void previsit( ast::FunctionDecl * functionDecl );
    947                 ast::DeclWithType * postvisit( ast::FunctionDecl * functionDecl );
    948                 void previsit( ast::ObjectDecl * objectDecl );
    949                 void previsit( ast::EnumDecl * enumDecl );
    950                 void previsit( ast::StaticAssertDecl * assertDecl );
    951 
    952                 void previsit( ast::ArrayType * at );
    953                 void previsit( ast::PointerType * pt );
    954 
    955                 void previsit( ast::ExprStmt * exprStmt );
    956                 void previsit( ast::AsmExpr * asmExpr );
    957                 void previsit( ast::AsmStmt * asmStmt );
    958                 void previsit( ast::IfStmt * ifStmt );
    959                 void previsit( ast::WhileStmt * whileStmt );
    960                 void previsit( ast::ForStmt * forStmt );
    961                 void previsit( ast::SwitchStmt * switchStmt );
    962                 void previsit( ast::CaseStmt * caseStmt );
    963                 void previsit( ast::BranchStmt * branchStmt );
    964                 void previsit( ast::ReturnStmt * returnStmt );
    965                 void previsit( ast::ThrowStmt * throwStmt );
    966                 void previsit( ast::CatchStmt * catchStmt );
    967                 void previsit( ast::WaitForStmt * stmt );
    968 
    969                 void previsit( ast::SingleInit * singleInit );
    970                 void previsit( ast::ListInit * listInit );
    971                 void previsit( ast::ConstructorInit * ctorInit );
     1131                Resolver_new( const ast::SymbolTable & syms ) { symtab = syms; }
     1132
     1133                void previsit( const ast::FunctionDecl * );
     1134                const ast::FunctionDecl * postvisit( const ast::FunctionDecl * );
     1135                void previsit( const ast::ObjectDecl * );
     1136                void previsit( const ast::EnumDecl * );
     1137                const ast::StaticAssertDecl * previsit( const ast::StaticAssertDecl * );
     1138
     1139                void previsit( const ast::ArrayType * );
     1140                void previsit( const ast::PointerType * );
     1141
     1142                void previsit( const ast::ExprStmt * );
     1143                void previsit( const ast::AsmExpr * );
     1144                void previsit( const ast::AsmStmt * );
     1145                void previsit( const ast::IfStmt * );
     1146                void previsit( const ast::WhileStmt * );
     1147                void previsit( const ast::ForStmt * );
     1148                void previsit( const ast::SwitchStmt * );
     1149                void previsit( const ast::CaseStmt * );
     1150                void previsit( const ast::BranchStmt * );
     1151                void previsit( const ast::ReturnStmt * );
     1152                void previsit( const ast::ThrowStmt * );
     1153                void previsit( const ast::CatchStmt * );
     1154                void previsit( const ast::WaitForStmt * );
     1155
     1156                void previsit( const ast::SingleInit * );
     1157                void previsit( const ast::ListInit * );
     1158                void previsit( const ast::ConstructorInit * );
    9721159        };
    9731160
     
    9771164        }
    9781165
    979         void previsit( ast::FunctionDecl * functionDecl ) {
    980                 #warning unimplemented; Resolver port in progress
    981                 (void)functionDecl;
    982                 assert(false);
    983         }
    984 
    985         ast::DeclWithType * postvisit( ast::FunctionDecl * functionDecl ) {
    986                 #warning unimplemented; Resolver port in progress
    987                 (void)functionDecl;
    988                 assert(false);
    989                 return nullptr;
    990         }
    991 
    992         void previsit( ast::ObjectDecl * objectDecl ) {
     1166        void Resolver_new::previsit( const ast::FunctionDecl * functionDecl ) {
     1167                GuardValue( functionReturn );
     1168                functionReturn = extractResultType( functionDecl->type );
     1169        }
     1170
     1171        const ast::FunctionDecl * Resolver_new::postvisit( const ast::FunctionDecl * functionDecl ) {
     1172                // default value expressions have an environment which shouldn't be there and trips up
     1173                // later passes.
     1174                ast::ptr< ast::FunctionDecl > ret = functionDecl;
     1175                for ( unsigned i = 0; i < functionDecl->type->params.size(); ++i ) {
     1176                        const ast::ptr<ast::DeclWithType> & d = functionDecl->type->params[i];
     1177                       
     1178                        if ( const ast::ObjectDecl * obj = d.as< ast::ObjectDecl >() ) {
     1179                                if ( const ast::SingleInit * init = obj->init.as< ast::SingleInit >() ) {
     1180                                        if ( init->value->env == nullptr ) continue;
     1181                                        // clone initializer minus the initializer environment
     1182                                        strict_dynamic_cast< ast::SingleInit * >(
     1183                                                strict_dynamic_cast< ast::ObjectDecl * >(
     1184                                                        ret.get_and_mutate()->type.get_and_mutate()->params[i].get_and_mutate()
     1185                                                )->init.get_and_mutate()
     1186                                        )->value.get_and_mutate()->env = nullptr;
     1187                                }
     1188                        }
     1189                }
     1190                return ret.get();
     1191        }
     1192
     1193        void Resolver_new::previsit( const ast::ObjectDecl * objectDecl ) {
    9931194                #warning unimplemented; Resolver port in progress
    9941195                (void)objectDecl;
     
    9961197        }
    9971198
    998         void previsit( ast::EnumDecl * enumDecl ) {
    999                 #warning unimplemented; Resolver port in progress
    1000                 (void)enumDecl;
    1001                 assert(false);
    1002         }
    1003 
    1004         void previsit( ast::StaticAssertDecl * assertDecl ) {
    1005                 #warning unimplemented; Resolver port in progress
    1006                 (void)assertDecl;
    1007                 assert(false);
    1008         }
    1009 
    1010         void previsit( ast::ArrayType * at ) {
     1199        void Resolver_new::previsit( const ast::EnumDecl * ) {
     1200                // in case we decide to allow nested enums
     1201                GuardValue( inEnumDecl );
     1202                inEnumDecl = false;
     1203        }
     1204
     1205        const ast::StaticAssertDecl * Resolver_new::previsit(
     1206                const ast::StaticAssertDecl * assertDecl
     1207        ) {
     1208                ast::ptr< ast::Expr > cond = findIntegralExpression( assertDecl->cond, symtab );
     1209                if ( cond == assertDecl->cond ) return assertDecl;
     1210               
     1211                ast::StaticAssertDecl * ret = mutate( assertDecl );
     1212                ret->cond = cond;
     1213                return ret;
     1214        }
     1215
     1216        void Resolver_new::previsit( const ast::ArrayType * at ) {
    10111217                #warning unimplemented; Resolver port in progress
    10121218                (void)at;
     
    10141220        }
    10151221
    1016         void previsit( ast::PointerType * pt ) {
     1222        void Resolver_new::previsit( const ast::PointerType * pt ) {
    10171223                #warning unimplemented; Resolver port in progress
    10181224                (void)pt;
     
    10201226        }
    10211227
    1022         void previsit( ast::ExprStmt * exprStmt ) {
     1228        void Resolver_new::previsit( const ast::ExprStmt * exprStmt ) {
    10231229                #warning unimplemented; Resolver port in progress
    10241230                (void)exprStmt;
     
    10261232        }
    10271233
    1028         void previsit( ast::AsmExpr * asmExpr ) {
     1234        void Resolver_new::previsit( const ast::AsmExpr * asmExpr ) {
    10291235                #warning unimplemented; Resolver port in progress
    10301236                (void)asmExpr;
     
    10321238        }
    10331239
    1034         void previsit( ast::AsmStmt * asmStmt ) {
     1240        void Resolver_new::previsit( const ast::AsmStmt * asmStmt ) {
    10351241                #warning unimplemented; Resolver port in progress
    10361242                (void)asmStmt;
     
    10381244        }
    10391245
    1040         void previsit( ast::IfStmt * ifStmt ) {
     1246        void Resolver_new::previsit( const ast::IfStmt * ifStmt ) {
    10411247                #warning unimplemented; Resolver port in progress
    10421248                (void)ifStmt;
     
    10441250        }
    10451251
    1046         void previsit( ast::WhileStmt * whileStmt ) {
     1252        void Resolver_new::previsit( const ast::WhileStmt * whileStmt ) {
    10471253                #warning unimplemented; Resolver port in progress
    10481254                (void)whileStmt;
     
    10501256        }
    10511257
    1052         void previsit( ast::ForStmt * forStmt ) {
     1258        void Resolver_new::previsit( const ast::ForStmt * forStmt ) {
    10531259                #warning unimplemented; Resolver port in progress
    10541260                (void)forStmt;
     
    10561262        }
    10571263
    1058         void previsit( ast::SwitchStmt * switchStmt ) {
     1264        void Resolver_new::previsit( const ast::SwitchStmt * switchStmt ) {
    10591265                #warning unimplemented; Resolver port in progress
    10601266                (void)switchStmt;
     
    10621268        }
    10631269
    1064         void previsit( ast::CaseStmt * caseStmt ) {
     1270        void Resolver_new::previsit( const ast::CaseStmt * caseStmt ) {
    10651271                #warning unimplemented; Resolver port in progress
    10661272                (void)caseStmt;
     
    10681274        }
    10691275
    1070         void previsit( ast::BranchStmt * branchStmt ) {
     1276        void Resolver_new::previsit( const ast::BranchStmt * branchStmt ) {
    10711277                #warning unimplemented; Resolver port in progress
    10721278                (void)branchStmt;
     
    10741280        }
    10751281
    1076         void previsit( ast::ReturnStmt * returnStmt ) {
     1282        void Resolver_new::previsit( const ast::ReturnStmt * returnStmt ) {
    10771283                #warning unimplemented; Resolver port in progress
    10781284                (void)returnStmt;
     
    10801286        }
    10811287
    1082         void previsit( ast::ThrowStmt * throwStmt ) {
     1288        void Resolver_new::previsit( const ast::ThrowStmt * throwStmt ) {
    10831289                #warning unimplemented; Resolver port in progress
    10841290                (void)throwStmt;
     
    10861292        }
    10871293
    1088         void previsit( ast::CatchStmt * catchStmt ) {
     1294        void Resolver_new::previsit( const ast::CatchStmt * catchStmt ) {
    10891295                #warning unimplemented; Resolver port in progress
    10901296                (void)catchStmt;
     
    10921298        }
    10931299
    1094         void previsit( ast::WaitForStmt * stmt ) {
     1300        void Resolver_new::previsit( const ast::WaitForStmt * stmt ) {
    10951301                #warning unimplemented; Resolver port in progress
    10961302                (void)stmt;
     
    10981304        }
    10991305
    1100         void previsit( ast::SingleInit * singleInit ) {
     1306        void Resolver_new::previsit( const ast::SingleInit * singleInit ) {
    11011307                #warning unimplemented; Resolver port in progress
    11021308                (void)singleInit;
     
    11041310        }
    11051311
    1106         void previsit( ast::ListInit * listInit ) {
     1312        void Resolver_new::previsit( const ast::ListInit * listInit ) {
    11071313                #warning unimplemented; Resolver port in progress
    11081314                (void)listInit;
     
    11101316        }
    11111317
    1112         void previsit( ast::ConstructorInit * ctorInit ) {
     1318        void Resolver_new::previsit( const ast::ConstructorInit * ctorInit ) {
    11131319                #warning unimplemented; Resolver port in progress
    11141320                (void)ctorInit;
Note: See TracChangeset for help on using the changeset viewer.