Changes in src/InitTweak/InitTweak.cc [16ba4a6f:07de76b]
- File:
-
- 1 edited
-
src/InitTweak/InitTweak.cc (modified) (13 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/InitTweak/InitTweak.cc
r16ba4a6f r07de76b 87 87 }; 88 88 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 designations94 if ( result ) visit_children = false;95 }96 97 void previsit( const ast::Designation * des ) {98 // short circuit if we already know there are designations99 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 126 89 struct InitFlattener_old : public WithShortCircuiting { 127 90 void previsit( SingleInit * singleInit ) { … … 161 124 } 162 125 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 175 126 std::vector< ast::ptr< ast::Expr > > makeInitList( const ast::Init * init ) { 176 127 ast::Pass< InitFlattener_new > flattener; 177 128 maybe_accept( init, flattener ); 178 return std::move( flattener. core.argList );129 return std::move( flattener.pass.argList ); 179 130 } 180 131 … … 407 358 if ( auto listInit = dynamic_cast< const ast::ListInit * >( init ) ) { 408 359 for ( const ast::Init * init : *listInit ) { 409 buildCallExpr( shallowCopy(callExpr), index, dimension, init, out );360 buildCallExpr( callExpr, index, dimension, init, out ); 410 361 } 411 362 } else { 412 buildCallExpr( shallowCopy(callExpr), index, dimension, init, out );363 buildCallExpr( callExpr, index, dimension, init, out ); 413 364 } 414 365 } else { … … 547 498 } 548 499 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 556 500 bool tryConstruct( DeclarationWithType * dwt ) { 557 501 ObjectDecl * objDecl = dynamic_cast< ObjectDecl * >( dwt ); … … 567 511 } 568 512 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_extern575 && 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 583 513 struct CallFinder_old { 584 514 CallFinder_old( const std::list< std::string > & names ) : names( names ) {} … … 606 536 607 537 struct CallFinder_new final { 608 std::vector< const ast::Expr *> matches;538 std::vector< ast::ptr< ast::Expr > > matches; 609 539 const std::vector< std::string > names; 610 540 … … 628 558 } 629 559 630 std::vector< const ast::Expr *> collectCtorDtorCalls( const ast::Stmt * stmt ) {560 std::vector< ast::ptr< ast::Expr > > collectCtorDtorCalls( const ast::Stmt * stmt ) { 631 561 ast::Pass< CallFinder_new > finder{ std::vector< std::string >{ "?{}", "^?{}" } }; 632 562 maybe_accept( stmt, finder ); 633 return std::move( finder. core.matches );563 return std::move( finder.pass.matches ); 634 564 } 635 565 … … 766 696 template <typename Predicate> 767 697 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 ); 769 699 return std::all_of( callExprs.begin(), callExprs.end(), pred ); 770 700 } … … 1009 939 } 1010 940 1011 // looks like some other such codegen uses UntypedExpr and does not create fake function. should revisit afterwards1012 // 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 1038 941 struct ConstExprChecker : public WithShortCircuiting { 1039 942 // most expressions are not const expr … … 1076 979 }; 1077 980 1078 struct ConstExprChecker_new : public ast::WithShortCircuiting {1079 // most expressions are not const expr1080 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 constexpr1087 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 children1094 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 expr1112 return;1113 }1114 }1115 result = false;1116 }1117 1118 bool result = true;1119 };1120 1121 981 bool isConstExpr( Expression * expr ) { 1122 982 if ( expr ) { … … 1138 998 } 1139 999 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 } // if1155 // for all intents and purposes, no initializer means const expr1156 return true;1157 }1158 1159 1000 bool isConstructor( const std::string & str ) { return str == "?{}"; } 1160 1001 bool isDestructor( const std::string & str ) { return str == "^?{}"; } … … 1185 1026 if ( ftype->params.size() != 2 ) return false; 1186 1027 1187 const ast::Type * t1 = getPointerBase( ftype->params.front() );1028 const ast::Type * t1 = getPointerBase( ftype->params.front()->get_type() ); 1188 1029 if ( ! t1 ) return false; 1189 const ast::Type * t2 = ftype->params.back() ;1030 const ast::Type * t2 = ftype->params.back()->get_type(); 1190 1031 1191 1032 return ResolvExpr::typesCompatibleIgnoreQualifiers( t1, t2, ast::SymbolTable{} ); … … 1214 1055 return isCopyFunction( decl, "?{}" ); 1215 1056 } 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 1231 1057 }
Note:
See TracChangeset
for help on using the changeset viewer.