Changeset f431ab26 for src/ResolvExpr
- Timestamp:
- Feb 13, 2024, 10:43:53 AM (13 months ago)
- Branches:
- master
- Children:
- 38f4953
- Parents:
- e7b04a3
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/ResolveTypeof.cc
re7b04a3 rf431ab26 35 35 36 36 struct ResolveTypeof : public ast::WithShortCircuiting { 37 37 const ResolveContext & context; 38 38 39 ResolveTypeof( const ResolveContext & context ) : 40 context( context ) {} 39 ResolveTypeof( const ResolveContext & context ) : context( context ) {} 41 40 42 41 void previsit( const ast::TypeofType * ) { visit_children = false; } 43 42 44 45 46 43 const ast::Type * postvisit( const ast::TypeofType * typeofType ) { 44 // pass on null expression 45 if ( ! typeofType->expr ) return typeofType; 47 46 48 49 50 51 52 53 54 55 56 57 58 59 47 ast::ptr< ast::Type > newType; 48 if ( auto tyExpr = typeofType->expr.as< ast::TypeExpr >() ) { 49 // typeof wrapping type 50 newType = tyExpr->type; 51 } else { 52 // typeof wrapping expression 53 ast::TypeEnvironment dummy; 54 ast::ptr< ast::Expr > newExpr = 55 resolveInVoidContext( typeofType->expr, context, dummy ); 56 assert( newExpr->result && ! newExpr->result->isVoid() ); 57 newType = newExpr->result; 58 } 60 59 61 62 63 64 65 newType = new ast::BasicType{66 ast::BasicType::SignedInt, newType->qualifiers, copy(newType->attributes) };67 68 69 70 71 72 73 60 // clear qualifiers for base, combine with typeoftype quals regardless 61 if ( typeofType->kind == ast::TypeofType::Basetypeof ) { 62 // replace basetypeof(<enum>) by int 63 if ( newType.as< ast::EnumInstType >() ) { 64 newType = new ast::BasicType( 65 ast::BasicType::SignedInt, newType->qualifiers, copy(newType->attributes) ); 66 } 67 reset_qualifiers( 68 newType, 69 ( newType->qualifiers & ~ast::CV::EquivQualifiers ) | typeofType->qualifiers ); 70 } else { 71 add_qualifiers( newType, typeofType->qualifiers ); 72 } 74 73 75 76 74 return newType.release(); 75 } 77 76 }; 78 77 … … 111 110 112 111 const ast::ObjectDecl * fixObjectType( const ast::ObjectDecl * decl , const ResolveContext & context ) { 113 if (decl->isTypeFixed) {114 115 112 if ( decl->isTypeFixed ) { 113 return decl; 114 } 116 115 117 118 119 120 121 122 123 116 auto mutDecl = mutate(decl); 117 fixObjectInit(decl, context); 118 { 119 auto resolvedType = resolveTypeof(decl->type, context); 120 resolvedType = fixArrayType(resolvedType, context); 121 mutDecl->type = resolvedType; 122 } 124 123 125 126 if (!mutDecl->name.empty()) {127 128 124 // Do not mangle unnamed variables. 125 if ( !mutDecl->name.empty() ) { 126 mutDecl->mangleName = Mangle::mangle(mutDecl); 127 } 129 128 130 131 132 129 mutDecl->type = renameTyVars(mutDecl->type, RenameMode::GEN_EXPR_ID); 130 mutDecl->isTypeFixed = true; 131 return mutDecl; 133 132 } 134 133 135 const ast::ObjectDecl *fixObjectInit( const ast::ObjectDecl *decl,136 137 if (decl->isTypeFixed) {138 139 134 const ast::ObjectDecl *fixObjectInit( 135 const ast::ObjectDecl *decl, const ResolveContext &context) { 136 if ( decl->isTypeFixed ) { 137 return decl; 138 } 140 139 141 auto mutDecl = mutate(decl); 140 if ( auto listInit = decl->init.as<ast::ListInit>() ) { 141 for ( size_t k = 0; k < listInit->designations.size(); k++ ) { 142 const ast::Designation *des = listInit->designations[k].get(); 143 // Desination here 144 ast::Designation * newDesignation = new ast::Designation(des->location); 145 std::deque<ast::ptr<ast::Expr>> newDesignators; 142 146 143 if ( auto mutListInit = mutDecl->init.as<ast::ListInit>() ) { 144 // std::list<ast::Designation *> newDesignations; 145 146 for ( size_t k = 0; k < mutListInit->designations.size(); k++ ) { 147 const ast::Designation *des = mutListInit->designations[k].get(); 148 // Desination here 149 ast::Designation * newDesignation = new ast::Designation(des->location); 150 std::deque<ast::ptr<ast::Expr>> newDesignators; 151 152 for ( ast::ptr<ast::Expr> designator : des->designators ) { 153 // Stupid flag variable for development, to be removed 154 // bool mutated = false; 155 if ( const ast::NameExpr * designatorName = designator.as<ast::NameExpr>() ) { 156 auto candidates = context.symtab.lookupId(designatorName->name); 157 // Does not work for the overloading case currently 158 // assert( candidates.size() == 1 ); 159 if ( candidates.size() != 1 ) return mutDecl; 160 auto candidate = candidates.at(0); 161 if ( const ast::EnumInstType * enumInst = dynamic_cast<const ast::EnumInstType *>(candidate.id->get_type())) { 162 // determine that is an enumInst, swap it with its const value 163 assert( candidates.size() == 1 ); 164 const ast::EnumDecl * baseEnum = enumInst->base; 165 // Need to iterate over all enum value to find the initializer to swap 166 for ( size_t m = 0; m < baseEnum->members.size(); ++m ) { 167 const ast::ObjectDecl * mem = baseEnum->members.at(m).as<const ast::ObjectDecl>(); 168 if ( baseEnum->members.at(m)->name == designatorName->name ) { 169 assert(mem); 170 newDesignators.push_back( ast::ConstantExpr::from_int(designator->location, m) ); 171 // mutated = true; 172 break; 173 } 174 } 175 } else { 176 newDesignators.push_back( des->designators.at(0) ); 177 } 178 } else { 179 newDesignators.push_back( des->designators.at(0) ); 180 } 181 } 182 183 newDesignation->designators = newDesignators; 184 mutListInit = ast::mutate_field_index(mutListInit, &ast::ListInit::designations, k, newDesignation); 185 186 } 187 } 188 return mutDecl; 147 for ( ast::ptr<ast::Expr> designator : des->designators ) { 148 // Stupid flag variable for development, to be removed 149 if ( const ast::NameExpr * designatorName = designator.as<ast::NameExpr>() ) { 150 auto candidates = context.symtab.lookupId(designatorName->name); 151 // Does not work for the overloading case currently 152 // assert( candidates.size() == 1 ); 153 if ( candidates.size() != 1 ) return decl; 154 auto candidate = candidates.at(0); 155 if ( const ast::EnumInstType * enumInst = dynamic_cast<const ast::EnumInstType *>(candidate.id->get_type())) { 156 // determine that is an enumInst, swap it with its const value 157 assert( candidates.size() == 1 ); 158 const ast::EnumDecl * baseEnum = enumInst->base; 159 // Need to iterate over all enum value to find the initializer to swap 160 for ( size_t m = 0; m < baseEnum->members.size(); ++m ) { 161 const ast::ObjectDecl * mem = baseEnum->members.at(m).as<const ast::ObjectDecl>(); 162 if ( baseEnum->members.at(m)->name == designatorName->name ) { 163 assert( mem ); 164 newDesignators.push_back( ast::ConstantExpr::from_int(designator->location, m) ); 165 break; 166 } 167 } 168 } else { 169 newDesignators.push_back( des->designators.at(0) ); 170 } 171 } else { 172 newDesignators.push_back( des->designators.at(0) ); 173 } 174 } 175 newDesignation->designators = newDesignators; 176 listInit = ast::mutate_field_index(listInit, &ast::ListInit::designations, k, newDesignation); 177 } 178 } 179 return decl; 189 180 } 190 181 191 } 182 } // namespace ResolvExpr 192 183 193 184 // Local Variables: //
Note: See TracChangeset
for help on using the changeset viewer.