Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/InitTweak/InitTweak.cc

    r16ba4a6f r07de76b  
    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 
    12689                struct InitFlattener_old : public WithShortCircuiting {
    12790                        void previsit( SingleInit * singleInit ) {
     
    161124        }
    162125
    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 
    175126std::vector< ast::ptr< ast::Expr > > makeInitList( const ast::Init * init ) {
    176127        ast::Pass< InitFlattener_new > flattener;
    177128        maybe_accept( init, flattener );
    178         return std::move( flattener.core.argList );
     129        return std::move( flattener.pass.argList );
    179130}
    180131
     
    407358                        if ( auto listInit = dynamic_cast< const ast::ListInit * >( init ) ) {
    408359                                for ( const ast::Init * init : *listInit ) {
    409                                         buildCallExpr( shallowCopy(callExpr), index, dimension, init, out );
     360                                        buildCallExpr( callExpr, index, dimension, init, out );
    410361                                }
    411362                        } else {
    412                                 buildCallExpr( shallowCopy(callExpr), index, dimension, init, out );
     363                                buildCallExpr( callExpr, index, dimension, init, out );
    413364                        }
    414365                } else {
     
    547498        }
    548499
    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 
    556500        bool tryConstruct( DeclarationWithType * dwt ) {
    557501                ObjectDecl * objDecl = dynamic_cast< ObjectDecl * >( dwt );
     
    567511        }
    568512
    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 
    583513        struct CallFinder_old {
    584514                CallFinder_old( const std::list< std::string > & names ) : names( names ) {}
     
    606536
    607537        struct CallFinder_new final {
    608                 std::vector< const ast::Expr * > matches;
     538                std::vector< ast::ptr< ast::Expr > > matches;
    609539                const std::vector< std::string > names;
    610540
     
    628558        }
    629559
    630         std::vector< const ast::Expr * > collectCtorDtorCalls( const ast::Stmt * stmt ) {
     560        std::vector< ast::ptr< ast::Expr > > collectCtorDtorCalls( const ast::Stmt * stmt ) {
    631561                ast::Pass< CallFinder_new > finder{ std::vector< std::string >{ "?{}", "^?{}" } };
    632562                maybe_accept( stmt, finder );
    633                 return std::move( finder.core.matches );
     563                return std::move( finder.pass.matches );
    634564        }
    635565
     
    766696                template <typename Predicate>
    767697                bool allofCtorDtor( const ast::Stmt * stmt, const Predicate & pred ) {
    768                         std::vector< const ast::Expr * > callExprs = collectCtorDtorCalls( stmt );
     698                        std::vector< ast::ptr< ast::Expr > > callExprs = collectCtorDtorCalls( stmt );
    769699                        return std::all_of( callExprs.begin(), callExprs.end(), pred );
    770700                }
     
    1009939        }
    1010940
    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 
    1038941        struct ConstExprChecker : public WithShortCircuiting {
    1039942                // most expressions are not const expr
     
    1076979        };
    1077980
    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 
    1121981        bool isConstExpr( Expression * expr ) {
    1122982                if ( expr ) {
     
    1138998        }
    1139999
    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 
    11591000        bool isConstructor( const std::string & str ) { return str == "?{}"; }
    11601001        bool isDestructor( const std::string & str ) { return str == "^?{}"; }
     
    11851026                if ( ftype->params.size() != 2 ) return false;
    11861027
    1187                 const ast::Type * t1 = getPointerBase( ftype->params.front() );
     1028                const ast::Type * t1 = getPointerBase( ftype->params.front()->get_type() );
    11881029                if ( ! t1 ) return false;
    1189                 const ast::Type * t2 = ftype->params.back();
     1030                const ast::Type * t2 = ftype->params.back()->get_type();
    11901031
    11911032                return ResolvExpr::typesCompatibleIgnoreQualifiers( t1, t2, ast::SymbolTable{} );
     
    12141055                return isCopyFunction( decl, "?{}" );
    12151056        }
    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 
    12311057}
Note: See TracChangeset for help on using the changeset viewer.