Ignore:
Timestamp:
Jan 7, 2021, 3:27:00 PM (5 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
2b4daf2, 64aeca0
Parents:
3c64c668 (diff), eef8dfb (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' into park_unpark

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/Resolver.cc

    r3c64c668 r58fe85a  
    99// Author           : Aaron B. Moss
    1010// Created On       : Sun May 17 12:17:01 2015
    11 // Last Modified By : Aaron B. Moss
    12 // Last Modified On : Wed May 29 11:00:00 2019
    13 // Update Count     : 241
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Fri Mar 27 11:58:00 2020
     13// Update Count     : 242
    1414//
    1515
     
    2626#include "RenameVars.h"                  // for RenameVars, global_renamer
    2727#include "Resolver.h"
     28#include "ResolveTypeof.h"
    2829#include "ResolvMode.h"                  // for ResolvMode
    2930#include "typeops.h"                     // for extractResultType
    3031#include "Unify.h"                       // for unify
     32#include "CompilationState.h"
    3133#include "AST/Chain.hpp"
    3234#include "AST/Decl.hpp"
     
    3840#include "Common/PassVisitor.h"          // for PassVisitor
    3941#include "Common/SemanticError.h"        // for SemanticError
     42#include "Common/Stats/ResolveTime.h"    // for ResolveTime::start(), ResolveTime::stop()
    4043#include "Common/utility.h"              // for ValueGuard, group_iterate
    4144#include "InitTweak/GenInit.h"
     
    4447#include "SymTab/Autogen.h"              // for SizeType
    4548#include "SymTab/Indexer.h"              // for Indexer
     49#include "SymTab/Mangler.h"              // for Mangler
    4650#include "SynTree/Declaration.h"         // for ObjectDecl, TypeDecl, Declar...
    4751#include "SynTree/Expression.h"          // for Expression, CastExpr, InitExpr
     
    560564                // TODO: Replace *exception type with &exception type.
    561565                if ( throwStmt->get_expr() ) {
    562                         const StructDecl * exception_decl = indexer.lookupStruct( "__cfaabi_ehm__base_exception_t" );
     566                        const StructDecl * exception_decl = indexer.lookupStruct( "__cfaehm_base_exception_t" );
    563567                        assert( exception_decl );
    564568                        Type * exceptType = new PointerType( noQualifiers, new StructInstType( noQualifiers, const_cast<StructDecl *>(exception_decl) ) );
     
    964968        namespace {
    965969                /// Finds deleted expressions in an expression tree
    966                 struct DeleteFinder_new final : public ast::WithShortCircuiting {
    967                         const ast::DeletedExpr * delExpr = nullptr;
     970                struct DeleteFinder_new final : public ast::WithShortCircuiting, public ast::WithVisitorRef<DeleteFinder_new> {
     971                        const ast::DeletedExpr * result = nullptr;
    968972
    969973                        void previsit( const ast::DeletedExpr * expr ) {
    970                                 if ( delExpr ) { visit_children = false; }
    971                                 else { delExpr = expr; }
    972                         }
    973 
    974                         void previsit( const ast::Expr * ) {
    975                                 if ( delExpr ) { visit_children = false; }
     974                                if ( result ) { visit_children = false; }
     975                                else { result = expr; }
     976                        }
     977
     978                        void previsit( const ast::Expr * expr ) {
     979                                if ( result ) { visit_children = false; }
     980                                if (expr->inferred.hasParams()) {
     981                                        for (auto & imp : expr->inferred.inferParams() ) {
     982                                                imp.second.expr->accept(*visitor);
     983                                        }
     984                                }
    976985                        }
    977986                };
    978987        } // anonymous namespace
    979 
    980988        /// Check if this expression is or includes a deleted expression
    981989        const ast::DeletedExpr * findDeletedExpr( const ast::Expr * expr ) {
    982                 ast::Pass<DeleteFinder_new> finder;
    983                 expr->accept( finder );
    984                 return finder.pass.delExpr;
     990                return ast::Pass<DeleteFinder_new>::read( expr );
    985991        }
    986992
     
    10721078                /// Strips extraneous casts out of an expression
    10731079                struct StripCasts_new final {
    1074                         const ast::Expr * postmutate( const ast::CastExpr * castExpr ) {
     1080                        const ast::Expr * postvisit( const ast::CastExpr * castExpr ) {
    10751081                                if (
    1076                                         castExpr->isGenerated
     1082                                        castExpr->isGenerated == ast::GeneratedCast
    10771083                                        && typesCompatible( castExpr->arg->result, castExpr->result )
    10781084                                ) {
     
    11061112                }
    11071113
    1108                 /// Establish post-resolver invariants for expressions
     1114               
     1115        } // anonymous namespace
     1116/// Establish post-resolver invariants for expressions
    11091117                void finishExpr(
    11101118                        ast::ptr< ast::Expr > & expr, const ast::TypeEnvironment & env,
     
    11191127                        StripCasts_new::strip( expr );
    11201128                }
    1121         } // anonymous namespace
    1122 
    11231129
    11241130        ast::ptr< ast::Expr > resolveInVoidContext(
     
    11281134
    11291135                // set up and resolve expression cast to void
    1130                 ast::CastExpr * untyped = new ast::CastExpr{ expr };
     1136                ast::ptr< ast::CastExpr > untyped = new ast::CastExpr{ expr };
    11311137                CandidateRef choice = findUnfinishedKindExpression(
    11321138                        untyped, symtab, "", anyCandidate, ResolvMode::withAdjustment() );
     
    11401146        }
    11411147
    1142         namespace {
    1143                 /// Resolve `untyped` to the expression whose candidate is the best match for a `void`
     1148        /// Resolve `untyped` to the expression whose candidate is the best match for a `void`
    11441149                /// context.
    11451150                ast::ptr< ast::Expr > findVoidExpression(
    11461151                        const ast::Expr * untyped, const ast::SymbolTable & symtab
    11471152                ) {
    1148                         resetTyVarRenaming();
    11491153                        ast::TypeEnvironment env;
    11501154                        ast::ptr< ast::Expr > newExpr = resolveInVoidContext( untyped, symtab, env );
     
    11521156                        return newExpr;
    11531157                }
     1158
     1159        namespace {
     1160               
    11541161
    11551162                /// resolve `untyped` to the expression whose candidate satisfies `pred` with the
     
    11631170                        CandidateRef choice =
    11641171                                findUnfinishedKindExpression( untyped, symtab, kind, pred, mode );
    1165                         finishExpr( choice->expr, choice->env, untyped->env );
     1172                        ResolvExpr::finishExpr( choice->expr, choice->env, untyped->env );
    11661173                        return std::move( choice->expr );
    11671174                }
     
    11711178                        const ast::Expr * untyped, const ast::SymbolTable & symtab
    11721179                ) {
    1173                         return findKindExpression( untyped, symtab );
     1180                        Stats::ResolveTime::start( untyped );
     1181                        auto res = findKindExpression( untyped, symtab );
     1182                        Stats::ResolveTime::stop();
     1183                        return res;
    11741184                }
    11751185        } // anonymous namespace
    11761186
    1177                 ast::ptr< ast::Expr > findSingleExpression(
    1178                         const ast::Expr * untyped, const ast::Type * type, const ast::SymbolTable & symtab
    1179                 ) {
    1180                         assert( untyped && type );
    1181                         ast::ptr< ast::Expr > castExpr = new ast::CastExpr{ untyped, type };
    1182                         ast::ptr< ast::Expr > newExpr = findSingleExpression( castExpr, symtab );
    1183                         removeExtraneousCast( newExpr, symtab );
    1184                         return newExpr;
    1185                 }
     1187        ast::ptr< ast::Expr > findSingleExpression(
     1188                const ast::Expr * untyped, const ast::Type * type, const ast::SymbolTable & symtab
     1189        ) {
     1190                assert( untyped && type );
     1191                ast::ptr< ast::Expr > castExpr = new ast::CastExpr{ untyped, type };
     1192                ast::ptr< ast::Expr > newExpr = findSingleExpression( castExpr, symtab );
     1193                removeExtraneousCast( newExpr, symtab );
     1194                return newExpr;
     1195        }
    11861196
    11871197        namespace {
     1198                bool structOrUnion( const Candidate & i ) {
     1199                        const ast::Type * t = i.expr->result->stripReferences();
     1200                        return dynamic_cast< const ast::StructInstType * >( t ) || dynamic_cast< const ast::UnionInstType * >( t );
     1201                }
    11881202                /// Predicate for "Candidate has integral type"
    11891203                bool hasIntegralType( const Candidate & i ) {
     
    12211235                template<typename Iter>
    12221236                inline bool nextMutex( Iter & it, const Iter & end ) {
    1223                         while ( it != end && ! (*it)->get_type()->is_mutex() ) { ++it; }
     1237                        while ( it != end && ! (*it)->is_mutex() ) { ++it; }
    12241238                        return it != end;
    12251239                }
     
    12331247                ast::ptr< ast::Type > functionReturn = nullptr;
    12341248                ast::CurrentObject currentObject;
     1249                // for work previously in GenInit
     1250                static InitTweak::ManagedTypes_new managedTypes;
     1251
    12351252                bool inEnumDecl = false;
    12361253
    12371254        public:
     1255                static size_t traceId;
    12381256                Resolver_new() = default;
    12391257                Resolver_new( const ast::SymbolTable & syms ) { symtab = syms; }
    12401258
    1241                 void previsit( const ast::FunctionDecl * );
     1259                const ast::FunctionDecl * previsit( const ast::FunctionDecl * );
    12421260                const ast::FunctionDecl * postvisit( const ast::FunctionDecl * );
    1243                 void previsit( const ast::ObjectDecl * );
     1261                const ast::ObjectDecl * previsit( const ast::ObjectDecl * );
     1262                void previsit( const ast::AggregateDecl * );
     1263                void previsit( const ast::StructDecl * );
    12441264                void previsit( const ast::EnumDecl * );
    12451265                const ast::StaticAssertDecl * previsit( const ast::StaticAssertDecl * );
     
    12601280                const ast::ThrowStmt *       previsit( const ast::ThrowStmt * );
    12611281                const ast::CatchStmt *       previsit( const ast::CatchStmt * );
     1282                const ast::CatchStmt *       postvisit( const ast::CatchStmt * );
    12621283                const ast::WaitForStmt *     previsit( const ast::WaitForStmt * );
     1284                const ast::WithStmt *        previsit( const ast::WithStmt * );
    12631285
    12641286                const ast::SingleInit *      previsit( const ast::SingleInit * );
    12651287                const ast::ListInit *        previsit( const ast::ListInit * );
    12661288                const ast::ConstructorInit * previsit( const ast::ConstructorInit * );
     1289
     1290                void resolveWithExprs(std::vector<ast::ptr<ast::Expr>> & exprs, std::list<ast::ptr<ast::Stmt>> & stmtsToAdd);
     1291
     1292                void beginScope() { managedTypes.beginScope(); }
     1293                void endScope() { managedTypes.endScope(); }
     1294                bool on_error(ast::ptr<ast::Decl> & decl);
    12671295        };
    1268 
    1269         void resolve( std::list< ast::ptr<ast::Decl> >& translationUnit ) {
    1270                 ast::Pass< Resolver_new > resolver;
    1271                 accept_all( translationUnit, resolver );
     1296        // size_t Resolver_new::traceId = Stats::Heap::new_stacktrace_id("Resolver");
     1297
     1298        InitTweak::ManagedTypes_new Resolver_new::managedTypes;
     1299
     1300        void resolve( ast::TranslationUnit& translationUnit ) {
     1301                ast::Pass< Resolver_new >::run( translationUnit );
    12721302        }
    12731303
     
    12801310        }
    12811311
    1282         ast::ptr< ast::Expr > resolveStmtExpr(
     1312        const ast::Expr * resolveStmtExpr(
    12831313                const ast::StmtExpr * stmtExpr, const ast::SymbolTable & symtab
    12841314        ) {
    12851315                assert( stmtExpr );
    12861316                ast::Pass< Resolver_new > resolver{ symtab };
    1287                 ast::ptr< ast::Expr > ret = stmtExpr;
    1288                 ret = ret->accept( resolver );
    1289                 strict_dynamic_cast< ast::StmtExpr * >( ret.get_and_mutate() )->computeResult();
     1317                auto ret = mutate(stmtExpr->accept(resolver));
     1318                strict_dynamic_cast< ast::StmtExpr * >( ret )->computeResult();
    12901319                return ret;
    12911320        }
    12921321
    1293         void Resolver_new::previsit( const ast::FunctionDecl * functionDecl ) {
     1322        namespace {
     1323                const ast::Attribute * handleAttribute(const CodeLocation & loc, const ast::Attribute * attr, const ast::SymbolTable & symtab) {
     1324                        std::string name = attr->normalizedName();
     1325                        if (name == "constructor" || name == "destructor") {
     1326                                if (attr->params.size() == 1) {
     1327                                        auto arg = attr->params.front();
     1328                                        auto resolved = ResolvExpr::findSingleExpression( arg, new ast::BasicType( ast::BasicType::LongLongSignedInt ), symtab );
     1329                                        auto result = eval(arg);
     1330
     1331                                        auto mutAttr = mutate(attr);
     1332                                        mutAttr->params.front() = resolved;
     1333                                        if (! result.second) {
     1334                                                SemanticWarning(loc, Warning::GccAttributes,
     1335                                                        toCString( name, " priorities must be integers from 0 to 65535 inclusive: ", arg ) );
     1336                                        }
     1337                                        else {
     1338                                                auto priority = result.first;
     1339                                                if (priority < 101) {
     1340                                                        SemanticWarning(loc, Warning::GccAttributes,
     1341                                                                toCString( name, " priorities from 0 to 100 are reserved for the implementation" ) );
     1342                                                } else if (priority < 201 && ! buildingLibrary()) {
     1343                                                        SemanticWarning(loc, Warning::GccAttributes,
     1344                                                                toCString( name, " priorities from 101 to 200 are reserved for the implementation" ) );
     1345                                                }
     1346                                        }
     1347                                        return mutAttr;
     1348                                } else if (attr->params.size() > 1) {
     1349                                        SemanticWarning(loc, Warning::GccAttributes, toCString( "too many arguments to ", name, " attribute" ) );
     1350                                } else {
     1351                                        SemanticWarning(loc, Warning::GccAttributes, toCString( "too few arguments to ", name, " attribute" ) );
     1352                                }
     1353                        }
     1354                        return attr;
     1355                }
     1356        }
     1357
     1358        const ast::FunctionDecl * Resolver_new::previsit( const ast::FunctionDecl * functionDecl ) {
    12941359                GuardValue( functionReturn );
     1360
     1361                assert (functionDecl->unique());
     1362                if (!functionDecl->has_body() && !functionDecl->withExprs.empty()) {
     1363                        SemanticError(functionDecl->location, functionDecl, "Function without body has with declarations");
     1364                }
     1365
     1366                if (!functionDecl->isTypeFixed) {
     1367                        auto mutDecl = mutate(functionDecl);
     1368                        auto mutType = mutDecl->type.get_and_mutate();
     1369
     1370                        for (auto & attr: mutDecl->attributes) {
     1371                                attr = handleAttribute(mutDecl->location, attr, symtab);
     1372                        }
     1373
     1374                        // handle assertions
     1375
     1376                        symtab.enterScope();
     1377                        mutType->forall.clear();
     1378                        mutType->assertions.clear();
     1379                        for (auto & typeParam : mutDecl->type_params) {
     1380                                symtab.addType(typeParam);
     1381                                mutType->forall.emplace_back(new ast::TypeInstType(typeParam->name, typeParam));
     1382                        }
     1383                        for (auto & asst : mutDecl->assertions) {
     1384                                asst = fixObjectType(asst.strict_as<ast::ObjectDecl>(), symtab);
     1385                                symtab.addId(asst);
     1386                                mutType->assertions.emplace_back(new ast::VariableExpr(functionDecl->location, asst));
     1387                        }
     1388
     1389                        // temporarily adds params to symbol table.
     1390                        // actual scoping rules for params and withexprs differ - see Pass::visit(FunctionDecl)
     1391
     1392                        std::vector<ast::ptr<ast::Type>> paramTypes;
     1393                        std::vector<ast::ptr<ast::Type>> returnTypes;
     1394
     1395                        for (auto & param : mutDecl->params) {
     1396                                param = fixObjectType(param.strict_as<ast::ObjectDecl>(), symtab);
     1397                                symtab.addId(param);
     1398                                paramTypes.emplace_back(param->get_type());
     1399                        }
     1400                        for (auto & ret : mutDecl->returns) {
     1401                                ret = fixObjectType(ret.strict_as<ast::ObjectDecl>(), symtab);
     1402                                returnTypes.emplace_back(ret->get_type());
     1403                        }
     1404                        // since function type in decl is just a view of param types, need to update that as well
     1405                        mutType->params = std::move(paramTypes);
     1406                        mutType->returns = std::move(returnTypes);
     1407
     1408                        auto renamedType = strict_dynamic_cast<const ast::FunctionType *>(renameTyVars(mutType, RenameMode::GEN_EXPR_ID));
     1409
     1410                        std::list<ast::ptr<ast::Stmt>> newStmts;
     1411                        resolveWithExprs (mutDecl->withExprs, newStmts);
     1412
     1413                        if (mutDecl->stmts) {
     1414                                auto mutStmt = mutDecl->stmts.get_and_mutate();
     1415                                mutStmt->kids.splice(mutStmt->kids.begin(), std::move(newStmts));
     1416                                mutDecl->stmts = mutStmt;
     1417                        }
     1418
     1419                        symtab.leaveScope();
     1420
     1421                        mutDecl->type = renamedType;
     1422                        mutDecl->mangleName = Mangle::mangle(mutDecl);
     1423                        mutDecl->isTypeFixed = true;
     1424                        functionDecl = mutDecl;
     1425                }
     1426                managedTypes.handleDWT(functionDecl);
     1427
    12951428                functionReturn = extractResultType( functionDecl->type );
     1429                return functionDecl;
    12961430        }
    12971431
     
    12991433                // default value expressions have an environment which shouldn't be there and trips up
    13001434                // later passes.
    1301                 ast::ptr< ast::FunctionDecl > ret = functionDecl;
    1302                 for ( unsigned i = 0; i < functionDecl->type->params.size(); ++i ) {
    1303                         const ast::ptr<ast::DeclWithType> & d = functionDecl->type->params[i];
    1304 
    1305                         if ( const ast::ObjectDecl * obj = d.as< ast::ObjectDecl >() ) {
     1435                assert( functionDecl->unique() );
     1436                ast::FunctionType * mutType = mutate( functionDecl->type.get() );
     1437
     1438                for ( unsigned i = 0 ; i < mutType->params.size() ; ++i ) {
     1439                        if ( const ast::ObjectDecl * obj = mutType->params[i].as< ast::ObjectDecl >() ) {
    13061440                                if ( const ast::SingleInit * init = obj->init.as< ast::SingleInit >() ) {
    13071441                                        if ( init->value->env == nullptr ) continue;
    13081442                                        // clone initializer minus the initializer environment
    1309                                         ast::chain_mutate( ret )
    1310                                                 ( &ast::FunctionDecl::type )
    1311                                                         ( &ast::FunctionType::params )[i]
    1312                                                                 ( &ast::ObjectDecl::init )
    1313                                                                         ( &ast::SingleInit::value )->env = nullptr;
    1314 
    1315                                         assert( functionDecl != ret.get() || functionDecl->unique() );
    1316                                         assert( ! ret->type->params[i].strict_as< ast::ObjectDecl >()->init.strict_as< ast::SingleInit >()->value->env );
     1443                                        auto mutParam = mutate( mutType->params[i].strict_as< ast::ObjectDecl >() );
     1444                                        auto mutInit = mutate( mutParam->init.strict_as< ast::SingleInit >() );
     1445                                        auto mutValue = mutate( mutInit->value.get() );
     1446
     1447                                        mutValue->env = nullptr;
     1448                                        mutInit->value = mutValue;
     1449                                        mutParam->init = mutInit;
     1450                                        mutType->params[i] = mutParam;
     1451
     1452                                        assert( ! mutType->params[i].strict_as< ast::ObjectDecl >()->init.strict_as< ast::SingleInit >()->value->env);
    13171453                                }
    13181454                        }
    13191455                }
    1320                 return ret.get();
    1321         }
    1322 
    1323         void Resolver_new::previsit( const ast::ObjectDecl * objectDecl ) {
     1456                mutate_field(functionDecl, &ast::FunctionDecl::type, mutType);
     1457                return functionDecl;
     1458        }
     1459
     1460        const ast::ObjectDecl * Resolver_new::previsit( const ast::ObjectDecl * objectDecl ) {
    13241461                // To handle initialization of routine pointers [e.g. int (*fp)(int) = foo()],
    13251462                // class-variable `initContext` is changed multiple times because the LHS is analyzed
     
    13291466                // selecting the RHS.
    13301467                GuardValue( currentObject );
    1331                 currentObject = ast::CurrentObject{ objectDecl->location, objectDecl->get_type() };
     1468
    13321469                if ( inEnumDecl && dynamic_cast< const ast::EnumInstType * >( objectDecl->get_type() ) ) {
    13331470                        // enumerator initializers should not use the enum type to initialize, since the
    13341471                        // enum type is still incomplete at this point. Use `int` instead.
     1472                        objectDecl = fixObjectType(objectDecl, symtab);
    13351473                        currentObject = ast::CurrentObject{
    13361474                                objectDecl->location, new ast::BasicType{ ast::BasicType::SignedInt } };
    13371475                }
     1476                else {
     1477                        if (!objectDecl->isTypeFixed) {
     1478                                auto newDecl = fixObjectType(objectDecl, symtab);
     1479                                auto mutDecl = mutate(newDecl);
     1480
     1481                                // generate CtorInit wrapper when necessary.
     1482                                // in certain cases, fixObjectType is called before reaching
     1483                                // this object in visitor pass, thus disabling CtorInit codegen.
     1484                                // this happens on aggregate members and function parameters.
     1485                                if ( InitTweak::tryConstruct( mutDecl ) && ( managedTypes.isManaged( mutDecl ) || ((! isInFunction() || mutDecl->storage.is_static ) && ! InitTweak::isConstExpr( mutDecl->init ) ) ) ) {
     1486                                        // constructed objects cannot be designated
     1487                                        if ( InitTweak::isDesignated( mutDecl->init ) ) SemanticError( mutDecl, "Cannot include designations in the initializer for a managed Object. If this is really what you want, then initialize with @=.\n" );
     1488                                        // constructed objects should not have initializers nested too deeply
     1489                                        if ( ! InitTweak::checkInitDepth( mutDecl ) ) SemanticError( mutDecl, "Managed object's initializer is too deep " );
     1490
     1491                                        mutDecl->init = InitTweak::genCtorInit( mutDecl->location, mutDecl );
     1492                                }
     1493
     1494                                objectDecl = mutDecl;
     1495                        }
     1496                        currentObject = ast::CurrentObject{ objectDecl->location, objectDecl->get_type() };
     1497                }
     1498
     1499                return objectDecl;
     1500        }
     1501
     1502        void Resolver_new::previsit( const ast::AggregateDecl * _aggDecl ) {
     1503                auto aggDecl = mutate(_aggDecl);
     1504                assertf(aggDecl == _aggDecl, "type declarations must be unique");
     1505
     1506                for (auto & member: aggDecl->members) {
     1507                        // nested type decls are hoisted already. no need to do anything
     1508                        if (auto obj = member.as<ast::ObjectDecl>()) {
     1509                                member = fixObjectType(obj, symtab);
     1510                        }
     1511                }
     1512        }
     1513
     1514        void Resolver_new::previsit( const ast::StructDecl * structDecl ) {
     1515                previsit(static_cast<const ast::AggregateDecl *>(structDecl));
     1516                managedTypes.handleStruct(structDecl);
    13381517        }
    13391518
     
    13411520                // in case we decide to allow nested enums
    13421521                GuardValue( inEnumDecl );
    1343                 inEnumDecl = false;
    1344         }
     1522                inEnumDecl = true;
     1523                // don't need to fix types for enum fields
     1524        }
     1525
    13451526
    13461527        const ast::StaticAssertDecl * Resolver_new::previsit(
     
    13551536        const PtrType * handlePtrType( const PtrType * type, const ast::SymbolTable & symtab ) {
    13561537                if ( type->dimension ) {
    1357                         #warning should use new equivalent to Validate::SizeType rather than sizeType here
    1358                         ast::ptr< ast::Type > sizeType = new ast::BasicType{ ast::BasicType::LongUnsignedInt };
     1538                        ast::ptr< ast::Type > sizeType = ast::sizeType;
    13591539                        ast::mutate_field(
    13601540                                type, &PtrType::dimension,
     
    14771657                if ( throwStmt->expr ) {
    14781658                        const ast::StructDecl * exceptionDecl =
    1479                                 symtab.lookupStruct( "__cfaabi_ehm__base_exception_t" );
     1659                                symtab.lookupStruct( "__cfaehm_base_exception_t" );
    14801660                        assert( exceptionDecl );
    14811661                        ast::ptr< ast::Type > exceptType =
     
    14891669
    14901670        const ast::CatchStmt * Resolver_new::previsit( const ast::CatchStmt * catchStmt ) {
    1491                 // TODO: This will need a fix for the decl/cond scoping problem.
     1671                // Until we are very sure this invarent (ifs that move between passes have thenPart)
     1672                // holds, check it. This allows a check for when to decode the mangling.
     1673                if ( auto ifStmt = catchStmt->body.as<ast::IfStmt>() ) {
     1674                        assert( ifStmt->thenPart );
     1675                }
     1676                // Encode the catchStmt so the condition can see the declaration.
    14921677                if ( catchStmt->cond ) {
    1493                         ast::ptr< ast::Type > boolType = new ast::BasicType{ ast::BasicType::Bool };
    1494                         catchStmt = ast::mutate_field(
    1495                                 catchStmt, &ast::CatchStmt::cond,
    1496                                 findSingleExpression( catchStmt->cond, boolType, symtab ) );
     1678                        ast::CatchStmt * stmt = mutate( catchStmt );
     1679                        stmt->body = new ast::IfStmt( stmt->location, stmt->cond, nullptr, stmt->body );
     1680                        stmt->cond = nullptr;
     1681                        return stmt;
     1682                }
     1683                return catchStmt;
     1684        }
     1685
     1686        const ast::CatchStmt * Resolver_new::postvisit( const ast::CatchStmt * catchStmt ) {
     1687                // Decode the catchStmt so everything is stored properly.
     1688                const ast::IfStmt * ifStmt = catchStmt->body.as<ast::IfStmt>();
     1689                if ( nullptr != ifStmt && nullptr == ifStmt->thenPart ) {
     1690                        assert( ifStmt->cond );
     1691                        assert( ifStmt->elsePart );
     1692                        ast::CatchStmt * stmt = ast::mutate( catchStmt );
     1693                        stmt->cond = ifStmt->cond;
     1694                        stmt->body = ifStmt->elsePart;
     1695                        // ifStmt should be implicately deleted here.
     1696                        return stmt;
    14971697                }
    14981698                return catchStmt;
     
    16111811                                                                // Check if the argument matches the parameter type in the current
    16121812                                                                // scope
    1613                                                                 ast::ptr< ast::Type > paramType = (*param)->get_type();
     1813                                                                // ast::ptr< ast::Type > paramType = (*param)->get_type();
    16141814                                                                if (
    16151815                                                                        ! unify(
    1616                                                                                 arg->expr->result, paramType, resultEnv, need, have, open,
     1816                                                                                arg->expr->result, *param, resultEnv, need, have, open,
    16171817                                                                                symtab )
    16181818                                                                ) {
     
    16211821                                                                        ss << "candidate function not viable: no known conversion "
    16221822                                                                                "from '";
    1623                                                                         ast::print( ss, (*param)->get_type() );
     1823                                                                        ast::print( ss, *param );
    16241824                                                                        ss << "' to '";
    16251825                                                                        ast::print( ss, arg->expr->result );
     
    17511951        }
    17521952
     1953        const ast::WithStmt * Resolver_new::previsit( const ast::WithStmt * withStmt ) {
     1954                auto mutStmt = mutate(withStmt);
     1955                resolveWithExprs(mutStmt->exprs, stmtsToAddBefore);
     1956                return mutStmt;
     1957        }
     1958
     1959        void Resolver_new::resolveWithExprs(std::vector<ast::ptr<ast::Expr>> & exprs, std::list<ast::ptr<ast::Stmt>> & stmtsToAdd) {
     1960                for (auto & expr : exprs) {
     1961                        // only struct- and union-typed expressions are viable candidates
     1962                        expr = findKindExpression( expr, symtab, structOrUnion, "with expression" );
     1963
     1964                        // if with expression might be impure, create a temporary so that it is evaluated once
     1965                        if ( Tuples::maybeImpure( expr ) ) {
     1966                                static UniqueName tmpNamer( "_with_tmp_" );
     1967                                const CodeLocation loc = expr->location;
     1968                                auto tmp = new ast::ObjectDecl(loc, tmpNamer.newName(), expr->result, new ast::SingleInit(loc, expr ) );
     1969                                expr = new ast::VariableExpr( loc, tmp );
     1970                                stmtsToAdd.push_back( new ast::DeclStmt(loc, tmp ) );
     1971                                if ( InitTweak::isConstructable( tmp->type ) ) {
     1972                                        // generate ctor/dtor and resolve them
     1973                                        tmp->init = InitTweak::genCtorInit( loc, tmp );
     1974                                }
     1975                                // since tmp is freshly created, this should modify tmp in-place
     1976                                tmp->accept( *visitor );
     1977                        }
     1978                }
     1979        }
    17531980
    17541981
     
    18462073        }
    18472074
     2075        // suppress error on autogen functions and mark invalid autogen as deleted.
     2076        bool Resolver_new::on_error(ast::ptr<ast::Decl> & decl) {
     2077                if (auto functionDecl = decl.as<ast::FunctionDecl>()) {
     2078                        // xxx - can intrinsic gen ever fail?
     2079                        if (functionDecl->linkage == ast::Linkage::AutoGen) {
     2080                                auto mutDecl = mutate(functionDecl);
     2081                                mutDecl->isDeleted = true;
     2082                                mutDecl->stmts = nullptr;
     2083                                decl = mutDecl;
     2084                                return false;
     2085                        }
     2086                }
     2087                return true;
     2088        }
     2089
    18482090} // namespace ResolvExpr
    18492091
Note: See TracChangeset for help on using the changeset viewer.