Changeset 62c6cfa for src/ResolvExpr
- Timestamp:
- Sep 23, 2023, 10:50:18 PM (19 months ago)
- Branches:
- master
- Children:
- c7616dd
- Parents:
- deda7e6
- Location:
- src/ResolvExpr
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
TabularUnified src/ResolvExpr/ResolveTypeof.cc ¶
rdeda7e6 r62c6cfa 24 24 #include "AST/Type.hpp" 25 25 #include "AST/TypeEnvironment.hpp" 26 #include "Common/PassVisitor.h" // for PassVisitor 27 #include "Common/SemanticError.h" // for SemanticError 28 #include "Common/utility.h" // for copy 29 #include "InitTweak/InitTweak.h" // for isConstExpr 26 #include "Common/PassVisitor.h" // for PassVisitor 27 #include "Common/utility.h" // for copy 28 #include "InitTweak/InitTweak.h" // for isConstExpr 30 29 #include "RenameVars.h" 31 30 #include "Resolver.h" // for resolveInVoidContext … … 51 50 } 52 51 #endif 53 } // namespace 52 } 54 53 55 54 class ResolveTypeof_old : public WithShortCircuiting { 56 55 public: 57 ResolveTypeof_old(const SymTab::Indexer &indexer) : indexer(indexer) {}58 void premutate(TypeofType *typeofType);59 Type *postmutate(TypeofType *typeofType);56 ResolveTypeof_old( const SymTab::Indexer &indexer ) : indexer( indexer ) {} 57 void premutate( TypeofType *typeofType ); 58 Type * postmutate( TypeofType *typeofType ); 60 59 61 60 private: … … 63 62 }; 64 63 65 Type *resolveTypeof(Type *type, const SymTab::Indexer &indexer) { 66 PassVisitor<ResolveTypeof_old> mutator(indexer); 67 return type->acceptMutator(mutator); 68 } 69 70 void ResolveTypeof_old::premutate(TypeofType *) { visit_children = false; } 71 72 Type *ResolveTypeof_old::postmutate(TypeofType *typeofType) { 64 Type * resolveTypeof( Type *type, const SymTab::Indexer &indexer ) { 65 PassVisitor<ResolveTypeof_old> mutator( indexer ); 66 return type->acceptMutator( mutator ); 67 } 68 69 void ResolveTypeof_old::premutate( TypeofType * ) { 70 visit_children = false; 71 } 72 73 Type * ResolveTypeof_old::postmutate( TypeofType *typeofType ) { 73 74 #if 0 74 75 std::cerr << "resolving typeof: "; … … 77 78 #endif 78 79 // pass on null expression 79 if (!typeofType->expr) return typeofType;80 if ( ! typeofType->expr ) return typeofType; 80 81 81 82 bool isBasetypeof = typeofType->is_basetypeof; … … 83 84 84 85 Type* newType; 85 if ( TypeExpr* tyExpr = dynamic_cast<TypeExpr*>( typeofType->expr) ) {86 if ( TypeExpr* tyExpr = dynamic_cast<TypeExpr*>(typeofType->expr) ) { 86 87 // typeof wrapping type 87 88 newType = tyExpr->type; … … 90 91 } else { 91 92 // typeof wrapping expression 92 Expression *newExpr = resolveInVoidContext(typeofType->expr, indexer);93 assert(newExpr->result && !newExpr->result->isVoid());93 Expression * newExpr = resolveInVoidContext( typeofType->expr, indexer ); 94 assert( newExpr->result && ! newExpr->result->isVoid() ); 94 95 newType = newExpr->result; 95 96 newExpr->result = nullptr; … … 99 100 100 101 // clear qualifiers for base, combine with typeoftype quals in any case 101 if (isBasetypeof) { 102 // replace basetypeof(<enum>) by int 103 if (dynamic_cast<EnumInstType *>(newType)) { 104 Type *newerType = 105 new BasicType{newType->get_qualifiers(), BasicType::SignedInt, 106 newType->attributes}; 107 delete newType; 108 newType = newerType; 109 } 110 newType->get_qualifiers().val = 111 (newType->get_qualifiers().val & ~Type::Qualifiers::Mask) | 112 oldQuals; 113 } else { 102 if ( isBasetypeof ) { 103 // replace basetypeof(<enum>) by int 104 if ( dynamic_cast<EnumInstType*>(newType) ) { 105 Type* newerType = 106 new BasicType{ newType->get_qualifiers(), BasicType::SignedInt, 107 newType->attributes }; 108 delete newType; 109 newType = newerType; 110 } 111 newType->get_qualifiers().val 112 = ( newType->get_qualifiers().val & ~Type::Qualifiers::Mask ) | oldQuals; 113 } else { 114 114 newType->get_qualifiers().val |= oldQuals; 115 115 } … … 120 120 namespace { 121 121 struct ResolveTypeof_new : public ast::WithShortCircuiting { 122 const ResolveContext &context; 123 124 ResolveTypeof_new(const ResolveContext &context) : context(context) {} 125 126 void previsit(const ast::TypeofType *) { visit_children = false; } 127 128 const ast::Type *postvisit(const ast::TypeofType *typeofType) { 122 const ResolveContext & context; 123 124 ResolveTypeof_new( const ResolveContext & context ) : 125 context( context ) {} 126 127 void previsit( const ast::TypeofType * ) { visit_children = false; } 128 129 const ast::Type * postvisit( const ast::TypeofType * typeofType ) { 129 130 // pass on null expression 130 if (!typeofType->expr) return typeofType;131 132 ast::ptr<ast::Type> newType;133 if (auto tyExpr = typeofType->expr.as<ast::TypeExpr>()) {131 if ( ! typeofType->expr ) return typeofType; 132 133 ast::ptr< ast::Type > newType; 134 if ( auto tyExpr = typeofType->expr.as< ast::TypeExpr >() ) { 134 135 // typeof wrapping type 135 136 newType = tyExpr->type; … … 137 138 // typeof wrapping expression 138 139 ast::TypeEnvironment dummy; 139 ast::ptr< ast::Expr> newExpr =140 resolveInVoidContext( typeofType->expr, context, dummy);141 assert( newExpr->result && !newExpr->result->isVoid());140 ast::ptr< ast::Expr > newExpr = 141 resolveInVoidContext( typeofType->expr, context, dummy ); 142 assert( newExpr->result && ! newExpr->result->isVoid() ); 142 143 newType = newExpr->result; 143 144 } 144 145 145 146 // clear qualifiers for base, combine with typeoftype quals regardless 146 if ( typeofType->kind == ast::TypeofType::Basetypeof) {147 if ( typeofType->kind == ast::TypeofType::Basetypeof ) { 147 148 // replace basetypeof(<enum>) by int 148 if (newType.as<ast::EnumInstType>()) { 149 newType = new ast::BasicType{ast::BasicType::SignedInt, 150 newType->qualifiers, 151 copy(newType->attributes)}; 149 if ( newType.as< ast::EnumInstType >() ) { 150 newType = new ast::BasicType{ 151 ast::BasicType::SignedInt, newType->qualifiers, copy(newType->attributes) }; 152 152 } 153 reset_qualifiers(newType, 154 (newType->qualifiers & ~ast::CV::EquivQualifiers) | 155 typeofType->qualifiers);153 reset_qualifiers( 154 newType, 155 ( newType->qualifiers & ~ast::CV::EquivQualifiers ) | typeofType->qualifiers ); 156 156 } else { 157 add_qualifiers(newType, typeofType->qualifiers);157 add_qualifiers( newType, typeofType->qualifiers ); 158 158 } 159 159 … … 161 161 } 162 162 }; 163 } // anonymous namespace 164 165 const ast::Type *resolveTypeof(const ast::Type *type, 166 const ResolveContext &context) { 167 ast::Pass<ResolveTypeof_new> mutator(context); 168 return type->accept(mutator); 163 } // anonymous namespace 164 165 const ast::Type * resolveTypeof( const ast::Type * type , const ResolveContext & context ) { 166 ast::Pass< ResolveTypeof_new > mutator( context ); 167 return type->accept( mutator ); 169 168 } 170 169 171 170 struct FixArrayDimension { 172 const ResolveContext &context; 173 FixArrayDimension(const ResolveContext &context) : context(context) {} 174 175 const ast::ArrayType *previsit(const ast::ArrayType *arrayType) { 176 if (!arrayType->dimension) return arrayType; 177 auto mutType = mutate(arrayType); 178 auto globalSizeType = context.global.sizeType; 179 ast::ptr<ast::Type> sizetype = 180 globalSizeType 181 ? globalSizeType 182 : new ast::BasicType(ast::BasicType::LongUnsignedInt); 183 mutType->dimension = 184 findSingleExpression(arrayType->dimension, sizetype, context); 185 186 if (InitTweak::isConstExpr(mutType->dimension)) { 187 mutType->isVarLen = ast::LengthFlag::FixedLen; 188 } else { 189 mutType->isVarLen = ast::LengthFlag::VariableLen; 190 } 191 return mutType; 192 } 171 const ResolveContext & context; 172 FixArrayDimension(const ResolveContext & context) : context( context ) {} 173 174 const ast::ArrayType * previsit (const ast::ArrayType * arrayType) { 175 if (!arrayType->dimension) return arrayType; 176 auto mutType = mutate(arrayType); 177 auto globalSizeType = context.global.sizeType; 178 ast::ptr<ast::Type> sizetype = globalSizeType ? globalSizeType : new ast::BasicType(ast::BasicType::LongUnsignedInt); 179 mutType->dimension = findSingleExpression(arrayType->dimension, sizetype, context ); 180 181 if (InitTweak::isConstExpr(mutType->dimension)) { 182 mutType->isVarLen = ast::LengthFlag::FixedLen; 183 } 184 else { 185 mutType->isVarLen = ast::LengthFlag::VariableLen; 186 } 187 return mutType; 188 } 193 189 }; 194 190 195 struct FixEnumeratedArray { 196 const ResolveContext &context; 197 const ast::ListInit *init; 198 FixEnumeratedArray(const ResolveContext &context, const ast::ListInit *init) 199 : context(context), init(init) {} 200 201 const ast::ArrayType *previsit(const ast::ArrayType *arrayType) { 202 return arrayType; 203 } 204 205 // Enum Defined as inline field of array needs initalizer to define its 206 // members 207 const ast::EnumDecl *previsit(const ast::EnumDecl *enumDecl) { 208 auto mutType = mutate(enumDecl); 209 for (auto designation : init->designations) { 210 std::deque<ast::ptr<ast::Expr>> designatorList = 211 designation->designators; 212 if (designatorList.size() != 1) { 213 SemanticError(mutType, 214 "Multiple Initialization in enumerated array is " 215 "not supported."); 216 } 217 ast::ptr<ast::Expr> designator = designatorList.at(0); 218 ast::ptr<ast::NameExpr> designatorAsName = 219 designator.as<ast::NameExpr>(); 220 ast::ObjectDecl *memberDecl = 221 new ast::ObjectDecl(enumDecl->location, designatorAsName->name, 222 new ast::EnumInstType("", ast::CV::Const)); 223 mutType->members.push_back(memberDecl); 224 // mutType->members.push_back( ) 225 } 226 return mutType; 227 } 228 }; 229 230 const ast::Type *fixArrayType(const ast::Type *type, 231 const ResolveContext &context) { 232 ast::Pass<FixArrayDimension> visitor(context); 233 return type->accept(visitor); 234 } 235 236 const ast::ObjectDecl *fixObjectType(const ast::ObjectDecl *decl, 237 const ResolveContext &context) { 191 const ast::Type * fixArrayType( const ast::Type * type, const ResolveContext & context ) { 192 ast::Pass<FixArrayDimension> visitor(context); 193 return type->accept(visitor); 194 } 195 196 const ast::ObjectDecl * fixObjectType( const ast::ObjectDecl * decl , const ResolveContext & context ) { 238 197 if (decl->isTypeFixed) { 239 198 return decl; … … 260 219 const ast::ObjectDecl *fixObjectInit(const ast::ObjectDecl *decl, 261 220 const ResolveContext &context) { 262 if ( decl->isTypeFixed) {221 if (decl->isTypeFixed) { 263 222 return decl; 264 223 } 265 224 266 auto mutDecl = mutate( decl ); 267 268 if ( const ast::ListInit * listInit = mutDecl->init.as<ast::ListInit>() ) { 269 ast::ListInit * mutListInit = mutate( listInit ); 270 // ListInit::designations is std::vector<ptr<Designation>> 271 // ((ast::ListInit)mutDecl->init).designations = newDesignations 272 std::vector<ast::ptr<ast::Designation>> newDesignations; 273 274 // The loop iterates over ListInit::designations and push member to newDesignations 275 for ( ast::ptr<ast::Designation> des : listInit->designations ) { 276 ast::Designation * newDesignation = mutate( des.get() ); 277 278 std::deque<ast::ptr<ast::Expr>> newDesignators; 279 for ( const ast::Expr *designator : des->designators ) { 280 if ( const ast::NameExpr *designatorName = dynamic_cast<const ast::NameExpr *>(designator) ) { 281 auto candidates = context.symtab.lookupId(designatorName->name); 282 if ( candidates.size() == 0 ) { 283 newDesignators.push_back(designator); 284 } else { 285 auto candidate = candidates.at(0); 286 if ( const ast::EnumInstType *enumInst = dynamic_cast<const ast::EnumInstType *>(candidate.id->get_type()) ) { 287 const ast::EnumDecl * baseEnum = enumInst->base; 288 // // Need to iterate over all enum value to find the 289 // // initializer to swap 290 for (size_t m = 0; m < baseEnum->members.size(); ++m) { 291 const ast::ObjectDecl *mem = baseEnum->members.at(m).as<const ast::ObjectDecl>(); 292 if (baseEnum->members.at(m)->name == designatorName->name) { 293 assert(mem); 294 newDesignators.push_back( ast::ConstantExpr::from_int(des->location, m )); 295 } 296 } // for 297 assert(newDesignators.size() > 0); 298 } else { 299 newDesignators.push_back(designator); 300 } //if 301 } 225 auto mutDecl = mutate(decl); 226 227 if ( auto mutListInit = mutDecl->init.as<ast::ListInit>() ) { 228 // std::list<ast::Designation *> newDesignations; 229 230 for ( size_t k = 0; k < mutListInit->designations.size(); k++ ) { 231 const ast::Designation *des = mutListInit->designations[k].get(); 232 // Desination here 233 ast::Designation * newDesination = new ast::Designation(des->location); 234 235 if (des->designators.size() == 0) continue; 236 237 // The designator I want to replace 238 const ast::Expr * designator = des->designators.at(0); 239 // Stupid flag variable for development, to be removed 240 bool mutated = false; 241 if ( const ast::NameExpr * designatorName = dynamic_cast<const ast::NameExpr *>(designator) ) { 242 auto candidates = context.symtab.lookupId(designatorName->name); 243 // Does not work for the overloading case currently 244 // assert( candidates.size() == 1 ); 245 if ( candidates.size() != 1 ) return mutDecl; 246 auto candidate = candidates.at(0); 247 if ( const ast::EnumInstType * enumInst = dynamic_cast<const ast::EnumInstType *>(candidate.id->get_type())) { 248 // determine that is an enumInst, swap it with its const value 249 assert( candidates.size() == 1 ); 250 const ast::EnumDecl * baseEnum = enumInst->base; 251 // Need to iterate over all enum value to find the initializer to swap 252 for ( size_t m = 0; m < baseEnum->members.size(); ++m ) { 253 const ast::ObjectDecl * mem = baseEnum->members.at(m).as<const ast::ObjectDecl>(); 254 if ( baseEnum->members.at(m)->name == designatorName->name ) { 255 assert(mem); 256 if ( mem->init ) { 257 const ast::SingleInit * memInit = mem->init.as<const ast::SingleInit>(); 258 ast::Expr * initValue = shallowCopy( memInit->value.get() ); 259 newDesination->designators.push_back( initValue ); 260 mutated = true; 261 } 262 break; 263 } 264 } 302 265 } else { 303 newDesignators.push_back(designator); 304 } // if 305 } // for 306 307 newDesignation->designators = newDesignators; 308 newDesignations.push_back( newDesignation ); 309 } // for 310 // mutListInit->designations = newDesignations; 311 ast::mutate_field( mutListInit, &ast::ListInit::designations, newDesignations ); 312 ast::mutate_field( mutDecl, &ast::ObjectDecl::init, mutListInit ); 313 } // if 266 newDesination->designators.push_back( des->designators.at(0) ); 267 } 268 } else { 269 newDesination->designators.push_back( des->designators.at(0) ); 270 } 271 if ( mutated ) { 272 mutListInit = ast::mutate_field_index(mutListInit, &ast::ListInit::designations, k, newDesination); 273 } 274 } 275 } 314 276 return mutDecl; 315 277 } -
TabularUnified src/ResolvExpr/ResolveTypeof.h ¶
rdeda7e6 r62c6cfa 17 17 18 18 class Type; 19 class ListInit;20 19 namespace SymTab { 21 20 class Indexer; … … 23 22 namespace ast { 24 23 class Type; 25 class ListInit;26 24 class ObjectDecl; 27 25 } … … 30 28 struct ResolveContext; 31 29 32 Type *resolveTypeof( Type 30 Type *resolveTypeof( Type*, const SymTab::Indexer &indexer ); 33 31 const ast::Type * resolveTypeof( const ast::Type *, const ResolveContext & ); 34 const ast::Type * fixArrayType( const ast::Type *, const ResolveContext &, const ast::ListInit * ); 35 const ast::Type * fixEnumeratedArray( const ast::Type *, const ResolveContext & ); 32 const ast::Type * fixArrayType( const ast::Type *, const ResolveContext & ); 36 33 const ast::ObjectDecl * fixObjectType( const ast::ObjectDecl * decl , const ResolveContext & ); 37 const ast::ObjectDecl * fixObjectInit( const ast::ObjectDecl * decl , const ResolveContext & 34 const ast::ObjectDecl * fixObjectInit( const ast::ObjectDecl * decl , const ResolveContext &); 38 35 } // namespace ResolvExpr 39 36
Note: See TracChangeset
for help on using the changeset viewer.