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/InitTweak/InitTweak.cc

    r3c64c668 r58fe85a  
    8787                };
    8888
     89                struct HasDesignations_new : public ast::WithShortCircuiting {
     90                        bool result = false;
     91
     92                        void previsit( const ast::Node * ) {
     93                                // short circuit if we already know there are designations
     94                                if ( result ) visit_children = false;
     95                        }
     96
     97                        void previsit( const ast::Designation * des ) {
     98                                // short circuit if we already know there are designations
     99                                if ( result ) visit_children = false;
     100                                else if ( ! des->designators.empty() ) {
     101                                        result = true;
     102                                        visit_children = false;
     103                                }
     104                        }
     105                };
     106
     107                struct InitDepthChecker_new : public ast::WithGuards {
     108                        bool result = true;
     109                        const ast::Type * type;
     110                        int curDepth = 0, maxDepth = 0;
     111                        InitDepthChecker_new( const ast::Type * type ) : type( type ) {
     112                                const ast::Type * t = type;
     113                                while ( auto at = dynamic_cast< const ast::ArrayType * >( t ) ) {
     114                                        maxDepth++;
     115                                        t = at->base;
     116                                }
     117                                maxDepth++;
     118                        }
     119                        void previsit( ListInit * ) {
     120                                curDepth++;
     121                                GuardAction( [this]() { curDepth--; } );
     122                                if ( curDepth > maxDepth ) result = false;
     123                        }
     124                };
     125
    89126                struct InitFlattener_old : public WithShortCircuiting {
    90127                        void previsit( SingleInit * singleInit ) {
     
    124161        }
    125162
     163        bool isDesignated( const ast::Init * init ) {
     164                ast::Pass<HasDesignations_new> finder;
     165                maybe_accept( init, finder );
     166                return finder.core.result;
     167        }
     168
     169        bool checkInitDepth( const ast::ObjectDecl * objDecl ) {
     170                ast::Pass<InitDepthChecker_new> checker( objDecl->type );
     171                maybe_accept( objDecl->init.get(), checker );
     172                return checker.core.result;
     173        }
     174
    126175std::vector< ast::ptr< ast::Expr > > makeInitList( const ast::Init * init ) {
    127176        ast::Pass< InitFlattener_new > flattener;
    128177        maybe_accept( init, flattener );
    129         return std::move( flattener.pass.argList );
     178        return std::move( flattener.core.argList );
    130179}
    131180
     
    358407                        if ( auto listInit = dynamic_cast< const ast::ListInit * >( init ) ) {
    359408                                for ( const ast::Init * init : *listInit ) {
    360                                         buildCallExpr( callExpr, index, dimension, init, out );
     409                                        buildCallExpr( shallowCopy(callExpr), index, dimension, init, out );
    361410                                }
    362411                        } else {
    363                                 buildCallExpr( callExpr, index, dimension, init, out );
     412                                buildCallExpr( shallowCopy(callExpr), index, dimension, init, out );
    364413                        }
    365414                } else {
     
    498547        }
    499548
     549        const ast::ObjectDecl * getParamThis(const ast::FunctionDecl * func) {
     550                assertf( func, "getParamThis: nullptr ftype" );
     551                auto & params = func->params;
     552                assertf( ! params.empty(), "getParamThis: ftype with 0 parameters: %s", toString( func ).c_str());
     553                return params.front().strict_as<ast::ObjectDecl>();
     554        }
     555
    500556        bool tryConstruct( DeclarationWithType * dwt ) {
    501557                ObjectDecl * objDecl = dynamic_cast< ObjectDecl * >( dwt );
     
    511567        }
    512568
     569        bool tryConstruct( const ast::DeclWithType * dwt ) {
     570                auto objDecl = dynamic_cast< const ast::ObjectDecl * >( dwt );
     571                if ( ! objDecl ) return false;
     572                return (objDecl->init == nullptr ||
     573                                ( objDecl->init != nullptr && objDecl->init->maybeConstructed ))
     574                        && ! objDecl->storage.is_extern
     575                        && isConstructable( objDecl->type );
     576        }
     577
     578        bool isConstructable( const ast::Type * type ) {
     579                return ! dynamic_cast< const ast::VarArgsType * >( type ) && ! dynamic_cast< const ast::ReferenceType * >( type )
     580                && ! dynamic_cast< const ast::FunctionType * >( type ) && ! Tuples::isTtype( type );
     581        }
     582
    513583        struct CallFinder_old {
    514584                CallFinder_old( const std::list< std::string > & names ) : names( names ) {}
     
    536606
    537607        struct CallFinder_new final {
    538                 std::vector< ast::ptr< ast::Expr > > matches;
     608                std::vector< const ast::Expr * > matches;
    539609                const std::vector< std::string > names;
    540610
     
    558628        }
    559629
    560         std::vector< ast::ptr< ast::Expr > > collectCtorDtorCalls( const ast::Stmt * stmt ) {
     630        std::vector< const ast::Expr * > collectCtorDtorCalls( const ast::Stmt * stmt ) {
    561631                ast::Pass< CallFinder_new > finder{ std::vector< std::string >{ "?{}", "^?{}" } };
    562632                maybe_accept( stmt, finder );
    563                 return std::move( finder.pass.matches );
     633                return std::move( finder.core.matches );
    564634        }
    565635
     
    696766                template <typename Predicate>
    697767                bool allofCtorDtor( const ast::Stmt * stmt, const Predicate & pred ) {
    698                         std::vector< ast::ptr< ast::Expr > > callExprs = collectCtorDtorCalls( stmt );
     768                        std::vector< const ast::Expr * > callExprs = collectCtorDtorCalls( stmt );
    699769                        return std::all_of( callExprs.begin(), callExprs.end(), pred );
    700770                }
     
    9391009        }
    9401010
     1011        // looks like some other such codegen uses UntypedExpr and does not create fake function. should revisit afterwards
     1012        // following passes may accidentally resolve this expression if returned as untyped...
     1013        ast::Expr * createBitwiseAssignment (const ast::Expr * dst, const ast::Expr * src) {
     1014                static ast::ptr<ast::FunctionDecl> assign = nullptr;
     1015                if (!assign) {
     1016                        auto td = new ast::TypeDecl({}, "T", {}, nullptr, ast::TypeDecl::Dtype, true);
     1017                        assign = new ast::FunctionDecl({}, "?=?", {},
     1018                        { new ast::ObjectDecl({}, "_dst", new ast::ReferenceType(new ast::TypeInstType("T", td))),
     1019                          new ast::ObjectDecl({}, "_src", new ast::TypeInstType("T", td))},
     1020                        { new ast::ObjectDecl({}, "_ret", new ast::TypeInstType("T", td))}, nullptr, {}, ast::Linkage::Intrinsic);
     1021                }
     1022                if (dst->result.as<ast::ReferenceType>()) {
     1023                        for (int depth = dst->result->referenceDepth(); depth > 0; depth--) {
     1024                                dst = new ast::AddressExpr(dst);
     1025                        }
     1026                }
     1027                else {
     1028                        dst = new ast::CastExpr(dst, new ast::ReferenceType(dst->result, {}));
     1029                }
     1030                if (src->result.as<ast::ReferenceType>()) {
     1031                        for (int depth = src->result->referenceDepth(); depth > 0; depth--) {
     1032                                src = new ast::AddressExpr(src);
     1033                        }
     1034                }
     1035                return new ast::ApplicationExpr(dst->location, ast::VariableExpr::functionPointer(dst->location, assign), {dst, src});
     1036        }
     1037
    9411038        struct ConstExprChecker : public WithShortCircuiting {
    9421039                // most expressions are not const expr
     
    9791076        };
    9801077
     1078        struct ConstExprChecker_new : public ast::WithShortCircuiting {
     1079                // most expressions are not const expr
     1080                void previsit( const ast::Expr * ) { result = false; visit_children = false; }
     1081
     1082                void previsit( const ast::AddressExpr *addressExpr ) {
     1083                        visit_children = false;
     1084                        const ast::Expr * arg = addressExpr->arg;
     1085
     1086                        // address of a variable or member expression is constexpr
     1087                        if ( ! dynamic_cast< const ast::NameExpr * >( arg )
     1088                        && ! dynamic_cast< const ast::VariableExpr * >( arg )
     1089                        && ! dynamic_cast< const ast::MemberExpr * >( arg )
     1090                        && ! dynamic_cast< const ast::UntypedMemberExpr * >( arg ) ) result = false;
     1091                }
     1092
     1093                // these expressions may be const expr, depending on their children
     1094                void previsit( const ast::SizeofExpr * ) {}
     1095                void previsit( const ast::AlignofExpr * ) {}
     1096                void previsit( const ast::UntypedOffsetofExpr * ) {}
     1097                void previsit( const ast::OffsetofExpr * ) {}
     1098                void previsit( const ast::OffsetPackExpr * ) {}
     1099                void previsit( const ast::CommaExpr * ) {}
     1100                void previsit( const ast::LogicalExpr * ) {}
     1101                void previsit( const ast::ConditionalExpr * ) {}
     1102                void previsit( const ast::CastExpr * ) {}
     1103                void previsit( const ast::ConstantExpr * ) {}
     1104
     1105                void previsit( const ast::VariableExpr * varExpr ) {
     1106                        visit_children = false;
     1107
     1108                        if ( auto inst = varExpr->result.as<ast::EnumInstType>() ) {
     1109                                long long int value;
     1110                                if ( inst->base->valueOf( varExpr->var, value ) ) {
     1111                                        // enumerators are const expr
     1112                                        return;
     1113                                }
     1114                        }
     1115                        result = false;
     1116                }
     1117
     1118                bool result = true;
     1119        };
     1120
    9811121        bool isConstExpr( Expression * expr ) {
    9821122                if ( expr ) {
     
    9981138        }
    9991139
     1140        bool isConstExpr( const ast::Expr * expr ) {
     1141                if ( expr ) {
     1142                        ast::Pass<ConstExprChecker_new> checker;
     1143                        expr->accept( checker );
     1144                        return checker.core.result;
     1145                }
     1146                return true;
     1147        }
     1148
     1149        bool isConstExpr( const ast::Init * init ) {
     1150                if ( init ) {
     1151                        ast::Pass<ConstExprChecker_new> checker;
     1152                        init->accept( checker );
     1153                        return checker.core.result;
     1154                } // if
     1155                // for all intents and purposes, no initializer means const expr
     1156                return true;
     1157        }
     1158
    10001159        bool isConstructor( const std::string & str ) { return str == "?{}"; }
    10011160        bool isDestructor( const std::string & str ) { return str == "^?{}"; }
     
    10261185                if ( ftype->params.size() != 2 ) return false;
    10271186
    1028                 const ast::Type * t1 = getPointerBase( ftype->params.front()->get_type() );
     1187                const ast::Type * t1 = getPointerBase( ftype->params.front() );
    10291188                if ( ! t1 ) return false;
    1030                 const ast::Type * t2 = ftype->params.back()->get_type();
     1189                const ast::Type * t2 = ftype->params.back();
    10311190
    10321191                return ResolvExpr::typesCompatibleIgnoreQualifiers( t1, t2, ast::SymbolTable{} );
     
    10551214                return isCopyFunction( decl, "?{}" );
    10561215        }
     1216
     1217        void addDataSectonAttribute( ObjectDecl * objDecl ) {
     1218                Type *strLitT = new PointerType( Type::Qualifiers( ),
     1219                        new BasicType( Type::Qualifiers( ), BasicType::Char ) );
     1220                std::list< Expression * > attr_params;
     1221                attr_params.push_back(
     1222                        new ConstantExpr( Constant( strLitT, "\".data#\"", std::nullopt ) ) );
     1223                objDecl->attributes.push_back(new Attribute("section", attr_params));
     1224        }
     1225
     1226        void addDataSectionAttribute( ast::ObjectDecl * objDecl ) {
     1227                auto strLitT = new ast::PointerType(new ast::BasicType(ast::BasicType::Char));
     1228                objDecl->attributes.push_back(new ast::Attribute("section", {new ast::ConstantExpr(objDecl->location, strLitT, "\".data#\"", std::nullopt)}));
     1229        }
     1230
    10571231}
Note: See TracChangeset for help on using the changeset viewer.