Changeset 58fe85a for src/InitTweak/InitTweak.cc
- Timestamp:
- Jan 7, 2021, 3:27:00 PM (5 years ago)
- 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. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/InitTweak/InitTweak.cc
r3c64c668 r58fe85a 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 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 89 126 struct InitFlattener_old : public WithShortCircuiting { 90 127 void previsit( SingleInit * singleInit ) { … … 124 161 } 125 162 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 126 175 std::vector< ast::ptr< ast::Expr > > makeInitList( const ast::Init * init ) { 127 176 ast::Pass< InitFlattener_new > flattener; 128 177 maybe_accept( init, flattener ); 129 return std::move( flattener. pass.argList );178 return std::move( flattener.core.argList ); 130 179 } 131 180 … … 358 407 if ( auto listInit = dynamic_cast< const ast::ListInit * >( init ) ) { 359 408 for ( const ast::Init * init : *listInit ) { 360 buildCallExpr( callExpr, index, dimension, init, out );409 buildCallExpr( shallowCopy(callExpr), index, dimension, init, out ); 361 410 } 362 411 } else { 363 buildCallExpr( callExpr, index, dimension, init, out );412 buildCallExpr( shallowCopy(callExpr), index, dimension, init, out ); 364 413 } 365 414 } else { … … 498 547 } 499 548 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 500 556 bool tryConstruct( DeclarationWithType * dwt ) { 501 557 ObjectDecl * objDecl = dynamic_cast< ObjectDecl * >( dwt ); … … 511 567 } 512 568 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 513 583 struct CallFinder_old { 514 584 CallFinder_old( const std::list< std::string > & names ) : names( names ) {} … … 536 606 537 607 struct CallFinder_new final { 538 std::vector< ast::ptr< ast::Expr >> matches;608 std::vector< const ast::Expr * > matches; 539 609 const std::vector< std::string > names; 540 610 … … 558 628 } 559 629 560 std::vector< ast::ptr< ast::Expr >> collectCtorDtorCalls( const ast::Stmt * stmt ) {630 std::vector< const ast::Expr * > collectCtorDtorCalls( const ast::Stmt * stmt ) { 561 631 ast::Pass< CallFinder_new > finder{ std::vector< std::string >{ "?{}", "^?{}" } }; 562 632 maybe_accept( stmt, finder ); 563 return std::move( finder. pass.matches );633 return std::move( finder.core.matches ); 564 634 } 565 635 … … 696 766 template <typename Predicate> 697 767 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 ); 699 769 return std::all_of( callExprs.begin(), callExprs.end(), pred ); 700 770 } … … 939 1009 } 940 1010 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 941 1038 struct ConstExprChecker : public WithShortCircuiting { 942 1039 // most expressions are not const expr … … 979 1076 }; 980 1077 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 981 1121 bool isConstExpr( Expression * expr ) { 982 1122 if ( expr ) { … … 998 1138 } 999 1139 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 1000 1159 bool isConstructor( const std::string & str ) { return str == "?{}"; } 1001 1160 bool isDestructor( const std::string & str ) { return str == "^?{}"; } … … 1026 1185 if ( ftype->params.size() != 2 ) return false; 1027 1186 1028 const ast::Type * t1 = getPointerBase( ftype->params.front() ->get_type());1187 const ast::Type * t1 = getPointerBase( ftype->params.front() ); 1029 1188 if ( ! t1 ) return false; 1030 const ast::Type * t2 = ftype->params.back() ->get_type();1189 const ast::Type * t2 = ftype->params.back(); 1031 1190 1032 1191 return ResolvExpr::typesCompatibleIgnoreQualifiers( t1, t2, ast::SymbolTable{} ); … … 1055 1214 return isCopyFunction( decl, "?{}" ); 1056 1215 } 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 1057 1231 }
Note:
See TracChangeset
for help on using the changeset viewer.