Changes in / [38f4953:c2a58cf]
- File:
-
- 1 edited
-
src/ResolvExpr/ResolveTypeof.cc (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/ResolveTypeof.cc
r38f4953 rc2a58cf 35 35 36 36 struct ResolveTypeof : public ast::WithShortCircuiting { 37 const ResolveContext & context;37 const ResolveContext & context; 38 38 39 ResolveTypeof( const ResolveContext & context ) : context( context ) {} 39 ResolveTypeof( const ResolveContext & context ) : 40 context( context ) {} 40 41 41 void previsit( const ast::TypeofType * ) { visit_children = false; }42 void previsit( const ast::TypeofType * ) { visit_children = false; } 42 43 43 const ast::Type * postvisit( const ast::TypeofType * typeofType ) {44 // pass on null expression45 if ( ! typeofType->expr ) return typeofType;44 const ast::Type * postvisit( const ast::TypeofType * typeofType ) { 45 // pass on null expression 46 if ( ! typeofType->expr ) return typeofType; 46 47 47 ast::ptr< ast::Type > newType;48 if ( auto tyExpr = typeofType->expr.as< ast::TypeExpr >() ) {49 // typeof wrapping type50 newType = tyExpr->type;51 } else {52 // typeof wrapping expression53 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 }48 ast::ptr< ast::Type > newType; 49 if ( auto tyExpr = typeofType->expr.as< ast::TypeExpr >() ) { 50 // typeof wrapping type 51 newType = tyExpr->type; 52 } else { 53 // typeof wrapping expression 54 ast::TypeEnvironment dummy; 55 ast::ptr< ast::Expr > newExpr = 56 resolveInVoidContext( typeofType->expr, context, dummy ); 57 assert( newExpr->result && ! newExpr->result->isVoid() ); 58 newType = newExpr->result; 59 } 59 60 60 // clear qualifiers for base, combine with typeoftype quals regardless61 if ( typeofType->kind == ast::TypeofType::Basetypeof ) {62 // replace basetypeof(<enum>) by int63 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 }61 // clear qualifiers for base, combine with typeoftype quals regardless 62 if ( typeofType->kind == ast::TypeofType::Basetypeof ) { 63 // replace basetypeof(<enum>) by int 64 if ( newType.as< ast::EnumInstType >() ) { 65 newType = new ast::BasicType{ 66 ast::BasicType::SignedInt, newType->qualifiers, copy(newType->attributes) }; 67 } 68 reset_qualifiers( 69 newType, 70 ( newType->qualifiers & ~ast::CV::EquivQualifiers ) | typeofType->qualifiers ); 71 } else { 72 add_qualifiers( newType, typeofType->qualifiers ); 73 } 73 74 74 return newType.release();75 }75 return newType.release(); 76 } 76 77 }; 77 78 … … 110 111 111 112 const ast::ObjectDecl * fixObjectType( const ast::ObjectDecl * decl , const ResolveContext & context ) { 112 if ( decl->isTypeFixed) {113 return decl;114 }113 if (decl->isTypeFixed) { 114 return decl; 115 } 115 116 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 }117 auto mutDecl = mutate(decl); 118 fixObjectInit(decl, context); 119 { 120 auto resolvedType = resolveTypeof(decl->type, context); 121 resolvedType = fixArrayType(resolvedType, context); 122 mutDecl->type = resolvedType; 123 } 123 124 124 // Do not mangle unnamed variables.125 if ( !mutDecl->name.empty()) {126 mutDecl->mangleName = Mangle::mangle(mutDecl);127 }125 // Do not mangle unnamed variables. 126 if (!mutDecl->name.empty()) { 127 mutDecl->mangleName = Mangle::mangle(mutDecl); 128 } 128 129 129 mutDecl->type = renameTyVars(mutDecl->type, RenameMode::GEN_EXPR_ID);130 mutDecl->isTypeFixed = true;131 return mutDecl;130 mutDecl->type = renameTyVars(mutDecl->type, RenameMode::GEN_EXPR_ID); 131 mutDecl->isTypeFixed = true; 132 return mutDecl; 132 133 } 133 134 134 const ast::ObjectDecl *fixObjectInit( 135 const ast::ObjectDecl *decl,const ResolveContext &context) {136 if ( decl->isTypeFixed) {137 return decl;138 }135 const ast::ObjectDecl *fixObjectInit(const ast::ObjectDecl *decl, 136 const ResolveContext &context) { 137 if (decl->isTypeFixed) { 138 return decl; 139 } 139 140 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; 141 auto mutDecl = mutate(decl); 146 142 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; 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; 180 189 } 181 190 182 } // namespace ResolvExpr191 } // namespace ResolvExpr 183 192 184 193 // Local Variables: //
Note:
See TracChangeset
for help on using the changeset viewer.