Changeset 2b59f55 for src/ResolvExpr


Ignore:
Timestamp:
Jun 6, 2019, 5:46:10 PM (5 years ago)
Author:
Aaron Moss <a3moss@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
5684736
Parents:
1a4323e
Message:

More resolver porting

Location:
src/ResolvExpr
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/CurrentObject.cc

    r1a4323e r2b59f55  
    2020#include <string>                      // for string, operator<<, allocator
    2121
     22#include "AST/Expr.hpp"                // for InitAlternative
     23#include "AST/Init.hpp"                // for Designation
     24#include "AST/Node.hpp"                // for readonly
    2225#include "Common/Indenter.h"           // for Indenter, operator<<
    2326#include "Common/SemanticError.h"      // for SemanticError
     
    585588        public:
    586589                virtual ~MemberIterator() {}
     590
     591                /// retrieve the list of possible (Type,Designation) pairs for the current position in the
     592                /// current object
     593                virtual std::vector< InitAlternative > operator* () const = 0;
     594       
     595        protected:
     596                /// helper for operator*; aggregates must add designator to each init alternative, but
     597                /// adding designators in operator* creates duplicates
     598                virtual std::vector< InitAlternative > first() const = 0;
    587599        };
    588600
    589601        /// Iterates "other" types (e.g. basic, pointer) which do not change at list initializer entry
    590602        class SimpleIterator final : public MemberIterator {
    591                 const Type * type = nullptr;
    592         public:
    593                 SimpleIterator( const Type * t ) : type( t ) {}
    594         };
    595 
    596         CurrentObject::CurrentObject( const ast::Type * type ) : objStack() {
    597                 objStack.emplace_back( new SimpleIterator{ type } );
    598         }
    599 
    600         #warning ast::CurrentObject port incomplete
     603                CodeLocation location;
     604                readonly< Type > type = nullptr;
     605        public:
     606                SimpleIterator( const CodeLocation & loc, const Type * t ) : location( loc ), type( t ) {}
     607
     608                std::vector< InitAlternative > operator* () const override { return first(); }
     609
     610        protected:
     611                std::vector< InitAlternative > first() const override {
     612                        if ( type ) return { InitAlternative{ type, new Designation{ location } } };
     613                        return {};
     614                }
     615        };
     616
     617        CurrentObject::CurrentObject( const CodeLocation & loc, const Type * type ) : objStack() {
     618                objStack.emplace_back( new SimpleIterator{ loc, type } );
     619        }
     620
     621        std::vector< InitAlternative > CurrentObject::getOptions() {
     622                PRINT( std::cerr << "____getting current options" << std::endl; )
     623                assertf( ! objStack.empty(), "objstack empty in getOptions" );
     624                return **objStack.back();
     625        }
    601626}
    602627
  • src/ResolvExpr/CurrentObject.h

    r1a4323e r2b59f55  
    2020#include <stack>  // for stack
    2121#include <vector>
     22
     23#include "Common/CodeLocation.h"
    2224
    2325class Designation;
     
    6971        public:
    7072                CurrentObject() = default;
    71                 CurrentObject( const Type * type );
     73                CurrentObject( const CodeLocation & loc, const Type * type );
     74
     75                /// produces a list of alternatives (Type *, Designation *) for the current sub-object's
     76                /// initializer.
     77                std::vector< InitAlternative > getOptions();
    7278        };
    7379} // namespace ast
  • src/ResolvExpr/Resolver.cc

    r1a4323e r2b59f55  
    11311131                /// lowest cost, returning the resolved version
    11321132                ast::ptr< ast::Expr > findKindExpression(
    1133                         const ast::Expr * untyped, const ast::SymbolTable & symtab, const std::string & kind,
    1134                         std::function<bool(const Candidate &)> pred, ResolvMode mode = {}
     1133                        const ast::Expr * untyped, const ast::SymbolTable & symtab,
     1134                        std::function<bool(const Candidate &)> pred = anyCandidate,
     1135                        const std::string & kind = "", ResolvMode mode = {}
    11351136                ) {
    11361137                        if ( ! untyped ) return {};
     
    11481149                        assert( untyped && type );
    11491150                        const ast::Expr * castExpr = new ast::CastExpr{ untyped->location, untyped, type };
    1150                         ast::ptr< ast::Expr > newExpr =
    1151                                 findKindExpression( castExpr, symtab, "", anyCandidate );
     1151                        ast::ptr< ast::Expr > newExpr = findKindExpression( castExpr, symtab );
    11521152                        removeExtraneousCast( newExpr, symtab );
    11531153                        return newExpr;
     
    11731173                        const ast::Expr * untyped, const ast::SymbolTable & symtab
    11741174                ) {
    1175                         return findKindExpression( untyped, symtab, "condition", hasIntegralType );
     1175                        return findKindExpression( untyped, symtab, hasIntegralType, "condition" );
    11761176                }
    11771177        }
     
    11831183
    11841184                ast::ptr< ast::Type > functionReturn = nullptr;
    1185                 ast::CurrentObject currentObject = nullptr;
     1185                ast::CurrentObject currentObject;
    11861186                bool inEnumDecl = false;
    11871187
     
    11991199                void previsit( const ast::PointerType * );
    12001200
    1201                 const ast::ExprStmt * previsit( const ast::ExprStmt * );
    1202                 const ast::AsmExpr * previsit( const ast::AsmExpr * );
    1203                 void previsit( const ast::AsmStmt * );
    1204                 const ast::IfStmt * previsit( const ast::IfStmt * );
    1205                 const ast::WhileStmt * previsit( const ast::WhileStmt * );
    1206                 const ast::ForStmt * previsit( const ast::ForStmt * );
     1201                const ast::ExprStmt *   previsit( const ast::ExprStmt * );
     1202                const ast::AsmExpr *    previsit( const ast::AsmExpr * );
     1203                const ast::AsmStmt *    previsit( const ast::AsmStmt * );
     1204                const ast::IfStmt *     previsit( const ast::IfStmt * );
     1205                const ast::WhileStmt *  previsit( const ast::WhileStmt * );
     1206                const ast::ForStmt *    previsit( const ast::ForStmt * );
    12071207                const ast::SwitchStmt * previsit( const ast::SwitchStmt * );
    1208                 const ast::CaseStmt * previsit( const ast::CaseStmt * );
     1208                const ast::CaseStmt *   previsit( const ast::CaseStmt * );
    12091209                const ast::BranchStmt * previsit( const ast::BranchStmt * );
    1210                 void previsit( const ast::ReturnStmt * );
    1211                 void previsit( const ast::ThrowStmt * );
    1212                 void previsit( const ast::CatchStmt * );
     1210                const ast::ReturnStmt * previsit( const ast::ReturnStmt * );
     1211                const ast::ThrowStmt * previsit( const ast::ThrowStmt * );
     1212                const ast::CatchStmt * previsit( const ast::CatchStmt * );
    12131213                void previsit( const ast::WaitForStmt * );
    12141214
     
    12611261                // selecting the RHS.
    12621262                GuardValue( currentObject );
    1263                 currentObject = ast::CurrentObject{ objectDecl->get_type() };
     1263                currentObject = ast::CurrentObject{ objectDecl->location, objectDecl->get_type() };
    12641264                if ( inEnumDecl && dynamic_cast< const ast::EnumInstType * >( objectDecl->get_type() ) ) {
    12651265                        // enumerator initializers should not use the enum type to initialize, since the
    12661266                        // enum type is still incomplete at this point. Use `int` instead.
    1267                         currentObject = ast::CurrentObject{ new ast::BasicType{ ast::BasicType::SignedInt } };
     1267                        currentObject = ast::CurrentObject{
     1268                                objectDecl->location, new ast::BasicType{ ast::BasicType::SignedInt } };
    12681269                }
    12691270        }
     
    13201321        }
    13211322
    1322         void Resolver_new::previsit( const ast::AsmStmt * asmStmt ) {
    1323                 #warning unimplemented; Resolver port in progress
    1324                 (void)asmStmt;
    1325                 assert(false);
     1323        const ast::AsmStmt * Resolver_new::previsit( const ast::AsmStmt * asmStmt ) {
     1324                visitor->maybe_accept( asmStmt, &ast::AsmStmt::input );
     1325                visitor->maybe_accept( asmStmt, &ast::AsmStmt::output );
     1326                visit_children = false;
     1327                return asmStmt;
    13261328        }
    13271329
     
    13551357                        switchStmt, &ast::SwitchStmt::cond,
    13561358                        findIntegralExpression( switchStmt->cond, symtab ) );
    1357                 currentObject = ast::CurrentObject{ switchStmt->cond->result };
     1359                currentObject = ast::CurrentObject{ switchStmt->location, switchStmt->cond->result };
    13581360                return switchStmt;
    13591361        }
     
    13611363        const ast::CaseStmt * Resolver_new::previsit( const ast::CaseStmt * caseStmt ) {
    13621364                if ( caseStmt->cond ) {
    1363                         #warning unimplemented, depends on currentObject implementation
    1364                         assert(false);
     1365                        std::vector< ast::InitAlternative > initAlts = currentObject.getOptions();
     1366                        assertf( initAlts.size() == 1, "SwitchStmt did not correctly resolve an integral "
     1367                                "expression." );
     1368                       
     1369                        const ast::Expr * untyped =
     1370                                new ast::CastExpr{ caseStmt->location, caseStmt->cond, initAlts.front().type };
     1371                        ast::ptr< ast::Expr > newExpr = findKindExpression( untyped, symtab );
     1372                       
     1373                        // case condition cannot have a cast in C, so it must be removed here, regardless of
     1374                        // whether it would perform a conversion.
     1375                        if ( const ast::CastExpr * castExpr = newExpr.as< ast::CastExpr >() ) {
     1376                                ast::ptr< ast::TypeSubstitution > env = castExpr->env;
     1377                                newExpr.set_and_mutate( castExpr->arg )->env = env;
     1378                        }
     1379                       
     1380                        caseStmt = ast::mutate_field( caseStmt, &ast::CaseStmt::cond, newExpr );
    13651381                }
    13661382                return caseStmt;
     
    13811397        }
    13821398
    1383         void Resolver_new::previsit( const ast::ReturnStmt * returnStmt ) {
    1384                 #warning unimplemented; Resolver port in progress
    1385                 (void)returnStmt;
    1386                 assert(false);
    1387         }
    1388 
    1389         void Resolver_new::previsit( const ast::ThrowStmt * throwStmt ) {
    1390                 #warning unimplemented; Resolver port in progress
    1391                 (void)throwStmt;
    1392                 assert(false);
    1393         }
    1394 
    1395         void Resolver_new::previsit( const ast::CatchStmt * catchStmt ) {
    1396                 #warning unimplemented; Resolver port in progress
    1397                 (void)catchStmt;
    1398                 assert(false);
     1399        const ast::ReturnStmt * Resolver_new::previsit( const ast::ReturnStmt * returnStmt ) {
     1400                visit_children = false;
     1401                if ( returnStmt->expr ) {
     1402                        returnStmt = ast::mutate_field(
     1403                                returnStmt, &ast::ReturnStmt::expr,
     1404                                findSingleExpression( returnStmt->expr, functionReturn, symtab ) );
     1405                }
     1406                return returnStmt;
     1407        }
     1408
     1409        const ast::ThrowStmt * Resolver_new::previsit( const ast::ThrowStmt * throwStmt ) {
     1410                visit_children = false;
     1411                if ( throwStmt->expr ) {
     1412                        const ast::StructDecl * exceptionDecl =
     1413                                symtab.lookupStruct( "__cfaabi_ehm__base_exception_t" );
     1414                        assert( exceptionDecl );
     1415                        ast::ptr< ast::Type > exceptType =
     1416                                new ast::PointerType{ new ast::StructInstType{ exceptionDecl } };
     1417                        throwStmt = ast::mutate_field(
     1418                                throwStmt, &ast::ThrowStmt::expr,
     1419                                findSingleExpression( throwStmt->expr, exceptType, symtab ) );
     1420                }
     1421                return throwStmt;
     1422        }
     1423
     1424        const ast::CatchStmt * Resolver_new::previsit( const ast::CatchStmt * catchStmt ) {
     1425                if ( catchStmt->cond ) {
     1426                        ast::ptr< ast::Type > boolType = new ast::BasicType{ ast::BasicType::Bool };
     1427                        catchStmt = ast::mutate_field(
     1428                                catchStmt, &ast::CatchStmt::cond,
     1429                                findSingleExpression( catchStmt->cond, boolType, symtab ) );
     1430                }
     1431                return catchStmt;
    13991432        }
    14001433
Note: See TracChangeset for help on using the changeset viewer.