Changeset 082af5b
- Timestamp:
- Aug 12, 2022, 9:07:36 AM (3 years ago)
- Branches:
- ADT, ast-experimental, master, pthread-emulation
- Children:
- 181036c
- Parents:
- 283876d (diff), ccbc65c (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. - Location:
- src
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
TabularUnified src/Virtual/ExpandCasts.cc ¶
r283876d r082af5b 10 10 // Created On : Mon Jul 24 13:59:00 2017 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Fri Jul 31 10:29:00 202013 // Update Count : 412 // Last Modified On : Thu Aug 11 12:06:00 2022 13 // Update Count : 5 14 14 // 15 15 … … 20 20 #include <string> // for string, allocator, operator==, ope... 21 21 22 #include "AST/Decl.hpp" 23 #include "AST/Expr.hpp" 24 #include "AST/Pass.hpp" 22 25 #include "Common/PassVisitor.h" // for PassVisitor 23 26 #include "Common/ScopedMap.h" // for ScopedMap … … 32 35 namespace Virtual { 33 36 34 static bool is_prefix( const std::string & prefix, const std::string& entire ) { 37 namespace { 38 39 bool is_prefix( const std::string & prefix, const std::string& entire ) { 35 40 size_t const p_size = prefix.size(); 36 41 return (p_size < entire.size() && prefix == entire.substr(0, p_size)); 37 42 } 38 43 39 staticbool is_type_id_object( const ObjectDecl * objectDecl ) {44 bool is_type_id_object( const ObjectDecl * objectDecl ) { 40 45 const std::string & objectName = objectDecl->name; 41 46 return is_prefix( "__cfatid_", objectName ); 47 } 48 49 bool is_type_id_object( const ast::ObjectDecl * decl ) { 50 return is_prefix( "__cfatid_", decl->name ); 42 51 } 43 52 … … 124 133 } 125 134 } 126 127 namespace {128 135 129 136 /// Better error locations for generated casts. … … 229 236 } 230 237 231 } // namespace232 233 238 Expression * VirtualCastCore::postmutate( VirtualCastExpr * castExpr ) { 234 239 assertf( castExpr->result, "Virtual Cast target not found before expansion." ); … … 265 270 } 266 271 267 void expandCasts( std::list< Declaration * > & translationUnit ) { 268 PassVisitor<VirtualCastCore> translator; 269 mutateAll( translationUnit, translator ); 270 } 271 } 272 /// Better error locations for generated casts. 273 // TODO: Does the improved distribution of code locations make this unneeded? 274 CodeLocation castLocation( const ast::VirtualCastExpr * castExpr ) { 275 if ( castExpr->location.isSet() ) { 276 return castExpr->location; 277 } else if ( castExpr->arg->location.isSet() ) { 278 return castExpr->arg->location; 279 } else { 280 return CodeLocation(); 281 } 282 } 283 284 [[noreturn]] void castError( ast::VirtualCastExpr const * castExpr, std::string const & message ) { 285 SemanticError( castLocation( castExpr ), message ); 286 } 287 288 class TypeIdTable final { 289 ScopedMap<std::string, ast::ObjectDecl const *> instances; 290 public: 291 void enterScope() { instances.beginScope(); } 292 void leaveScope() { instances.endScope(); } 293 294 // Attempt to insert an instance into the map. If there is a conflict, 295 // returns the previous declaration for error messages. 296 ast::ObjectDecl const * insert( ast::ObjectDecl const * typeIdDecl ) { 297 std::string const & mangledName = 298 Mangle::mangle( typeIdDecl->type, Mangle::typeMode() ); 299 ast::ObjectDecl const *& value = instances[ mangledName ]; 300 if ( value ) { 301 if ( typeIdDecl->storage.is_extern ) { 302 return nullptr; 303 } else if ( !value->storage.is_extern ) { 304 return value; 305 } 306 } 307 value = typeIdDecl; 308 return nullptr; 309 } 310 311 ast::ObjectDecl const * lookup( ast::Type const * typeIdType ) { 312 std::string const & mangledName = 313 Mangle::mangle( typeIdType, Mangle::typeMode() ); 314 auto const it = instances.find( mangledName ); 315 return ( instances.end() == it ) ? nullptr : it->second; 316 } 317 }; 318 319 struct ExpandCastsCore { 320 void previsit( ast::FunctionDecl const * decl ); 321 void previsit( ast::StructDecl const * decl ); 322 void previsit( ast::ObjectDecl const * decl ); 323 ast::Expr const * postvisit( ast::VirtualCastExpr const * expr ); 324 325 ast::CastExpr const * cast_to_type_id( 326 ast::Expr const * expr, unsigned int level_of_indirection ); 327 328 ast::FunctionDecl const * vcast_decl = nullptr; 329 ast::StructDecl const * info_decl = nullptr; 330 331 TypeIdTable symtab; 332 }; 333 334 void ExpandCastsCore::previsit( ast::FunctionDecl const * decl ) { 335 if ( !vcast_decl && "__cfavir_virtual_cast" == decl->name ) { 336 vcast_decl = decl; 337 } 338 } 339 340 void ExpandCastsCore::previsit( ast::StructDecl const * decl ) { 341 if ( !info_decl && decl->body && "__cfavir_type_info" == decl->name ) { 342 info_decl = decl; 343 } 344 } 345 346 void ExpandCastsCore::previsit( ast::ObjectDecl const * decl ) { 347 if ( is_type_id_object( decl ) ) { 348 // Multiple definitions should be fine because of linkonce. 349 symtab.insert( decl ); 350 } 351 } 352 353 /// Get the base type from a pointer or reference. 354 ast::Type const * getBaseType( ast::ptr<ast::Type> const & type ) { 355 if ( auto target = type.as<ast::PointerType>() ) { 356 return target->base.get(); 357 } else if ( auto target = type.as<ast::ReferenceType>() ) { 358 return target->base.get(); 359 } else { 360 return nullptr; 361 } 362 } 363 364 ast::StructInstType * polyCopy( 365 ast::StructInstType const * oldType, 366 ast::StructInstType const * newType ) { 367 assert( oldType->params.size() == newType->params.size() ); 368 ast::StructInstType * retType = ast::deepCopy( newType ); 369 if ( ! oldType->params.empty() ) { 370 retType->params.clear(); 371 for ( auto oldParams : oldType->params ) { 372 retType->params.push_back( ast::deepCopy( oldParams ) ); 373 } 374 } 375 return retType; 376 } 377 378 /// Follow the "head" field of the structure to get the type that is pointed 379 /// to by that field. 380 ast::StructInstType const * followHeadPointerType( 381 CodeLocation const & errorLocation, 382 ast::StructInstType const * oldType, 383 std::string const & fieldName ) { 384 ast::StructDecl const * oldDecl = oldType->base; 385 assert( oldDecl ); 386 387 // Helper function for throwing semantic errors. 388 auto throwError = [&fieldName, &errorLocation, &oldDecl]( 389 std::string const & message ) { 390 std::string const & context = "While following head pointer of " + 391 oldDecl->name + " named '" + fieldName + "': "; 392 SemanticError( errorLocation, context + message ); 393 }; 394 395 if ( oldDecl->members.empty() ) { 396 throwError( "Type has no fields." ); 397 } 398 ast::ptr<ast::Decl> const & memberDecl = oldDecl->members.front(); 399 assert( memberDecl ); 400 ast::ObjectDecl const * fieldDecl = memberDecl.as<ast::ObjectDecl>(); 401 assert( fieldDecl ); 402 if ( fieldName != fieldDecl->name ) { 403 throwError( "Head field did not have expected name." ); 404 } 405 406 ast::ptr<ast::Type> const & fieldType = fieldDecl->type; 407 if ( nullptr == fieldType ) { 408 throwError( "Could not get head field." ); 409 } 410 auto ptrType = fieldType.as<ast::PointerType>(); 411 if ( nullptr == ptrType ) { 412 throwError( "First field is not a pointer type." ); 413 } 414 assert( ptrType->base ); 415 auto newType = ptrType->base.as<ast::StructInstType>(); 416 if ( nullptr == newType ) { 417 throwError( "First field does not point to a structure type." ); 418 } 419 420 return polyCopy( oldType, newType ); 421 } 422 423 /// Get the type-id type from a virtual type. 424 ast::StructInstType const * getTypeIdType( 425 CodeLocation const & errorLocation, 426 ast::Type const * type ) { 427 auto typeInst = dynamic_cast<ast::StructInstType const *>( type ); 428 if ( nullptr == typeInst ) { 429 return nullptr; 430 } 431 ast::ptr<ast::StructInstType> tableInst = 432 followHeadPointerType( errorLocation, typeInst, "virtual_table" ); 433 if ( nullptr == tableInst ) { 434 return nullptr; 435 } 436 ast::StructInstType const * typeIdInst = 437 followHeadPointerType( errorLocation, tableInst, "__cfavir_typeid" ); 438 return typeIdInst; 439 } 440 441 ast::Expr const * ExpandCastsCore::postvisit( 442 ast::VirtualCastExpr const * expr ) { 443 assertf( expr->result, "Virtual cast target not found before expansion." ); 444 445 assert( vcast_decl ); 446 assert( info_decl ); 447 448 ast::Type const * base_type = getBaseType( expr->result ); 449 if ( nullptr == base_type ) { 450 castError( expr, "Virtual cast target must be a pointer or reference type." ); 451 } 452 ast::StructInstType const * type_id_type = 453 getTypeIdType( castLocation( expr ), base_type ); 454 if ( nullptr == type_id_type ) { 455 castError( expr, "Ill formed virtual cast target type." ); 456 } 457 ast::ObjectDecl const * type_id = symtab.lookup( type_id_type ); 458 if ( nullptr == type_id ) { 459 // I'm trying to give a different error for polymorpic types as 460 // different things can go wrong there. 461 if ( type_id_type->params.empty() ) { 462 castError( expr, "Virtual cast does not target a virtual type." ); 463 } else { 464 castError( expr, "Virtual cast does not target a type with a " 465 "type id (possible missing virtual table)." ); 466 } 467 } 468 469 return new ast::CastExpr( expr->location, 470 new ast::ApplicationExpr( expr->location, 471 ast::VariableExpr::functionPointer( expr->location, vcast_decl ), 472 { 473 cast_to_type_id( 474 new ast::AddressExpr( expr->location, 475 new ast::VariableExpr( expr->location, type_id ) ), 476 1 ), 477 cast_to_type_id( expr->arg, 2 ), 478 } 479 ), 480 ast::deepCopy( expr->result ) 481 ); 482 } 483 484 ast::CastExpr const * ExpandCastsCore::cast_to_type_id( 485 ast::Expr const * expr, unsigned int level_of_indirection ) { 486 assert( info_decl ); 487 ast::Type * type = new ast::StructInstType( info_decl, ast::CV::Const ); 488 for ( unsigned int i = 0 ; i < level_of_indirection ; ++i ) { 489 type = new ast::PointerType( type ); 490 } 491 return new ast::CastExpr( expr->location, expr, type ); 492 } 493 494 } // namespace 495 496 void expandCasts( std::list< Declaration * > & translationUnit ) { 497 PassVisitor<VirtualCastCore> translator; 498 mutateAll( translationUnit, translator ); 499 } 500 501 void expandCasts( ast::TranslationUnit & translationUnit ) { 502 ast::Pass<ExpandCastsCore>::run( translationUnit ); 503 } 504 505 } // namespace Virtual -
TabularUnified src/Virtual/ExpandCasts.h ¶
r283876d r082af5b 10 10 // Created On : Mon Jul 24 13:54:00 2017 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Tus Jul 25 14:51:00 201713 // Update Count : 012 // Last Modified On : Fri Jul 29 14:40:00 2022 13 // Update Count : 1 14 14 // 15 15 … … 19 19 20 20 class Declaration; 21 namespace ast { 22 class TranslationUnit; 23 } 21 24 22 25 namespace Virtual { 23 void expandCasts( std::list< Declaration * > & translationUnit ); 24 // Breaks all virtual cast nodes up into translatable nodes. 26 void expandCasts( std::list< Declaration * > & translationUnit ); 27 void expandCasts( ast::TranslationUnit & translationUnit ); 28 // Breaks all virtual cast nodes up into translatable nodes. 25 29 26 30 // Later this might just set some information so it can happen at CodeGen. 27 31 28 32 } -
TabularUnified src/main.cc ¶
r283876d r082af5b 10 10 // Created On : Fri May 15 23:12:02 2015 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Mon Jul 18 11:08:00 202213 // Update Count : 67 612 // Last Modified On : Thu 11 12:18:00 2022 13 // Update Count : 677 14 14 // 15 15 … … 445 445 PASS( "Expand Tuples", Tuples::expandTuples( transUnit ) ); 446 446 447 if ( tuplep ) { 448 dump( move( transUnit ) ); 449 return EXIT_SUCCESS; 450 } // if 451 452 // Must come after Translate Tries. 453 PASS( "Virtual Expand Casts", Virtual::expandCasts( transUnit ) ); 454 447 455 translationUnit = convert( move( transUnit ) ); 448 456 } else { … … 520 528 PASS( "Convert Specializations", GenPoly::convertSpecializations( translationUnit ) ); // needs to happen before tuple types are expanded 521 529 PASS( "Expand Tuples", Tuples::expandTuples( translationUnit ) ); // xxx - is this the right place for this? 530 531 if ( tuplep ) { 532 dump( translationUnit ); 533 return EXIT_SUCCESS; 534 } // if 535 536 PASS( "Virtual Expand Casts", Virtual::expandCasts( translationUnit ) ); // Must come after translateEHM 522 537 } 523 524 if ( tuplep ) {525 dump( translationUnit );526 return EXIT_SUCCESS;527 } // if528 529 PASS( "Virtual Expand Casts", Virtual::expandCasts( translationUnit ) ); // Must come after translateEHM530 538 531 539 PASS( "Instantiate Generics", GenPoly::instantiateGeneric( translationUnit ) );
Note: See TracChangeset
for help on using the changeset viewer.