Changeset af60383 for src/Parser/TypeData.cc
- Timestamp:
- Mar 5, 2024, 10:17:17 AM (4 months ago)
- Branches:
- master
- Children:
- f6e8c67
- Parents:
- 44adf1b
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Parser/TypeData.cc
r44adf1b raf60383 476 476 } // switch 477 477 assert(false); 478 } 479 480 481 TypeData * TypeData::getLastBase() { 482 TypeData * cur = this; 483 while ( cur->base ) cur = cur->base; 484 return cur; 485 } 486 487 void TypeData::setLastBase( TypeData * newBase ) { 488 getLastBase()->base = newBase; 489 } 490 491 // Takes ownership of src. 492 static void addQualifiersToType( TypeData * dst, TypeData * src ) { 493 if ( dst->base ) { 494 addQualifiersToType( dst->base, src ); 495 } else if ( dst->kind == TypeData::Function ) { 496 dst->base = src; 497 src = nullptr; 498 } else { 499 dst->qualifiers |= src->qualifiers; 500 delete src; 501 } // if 502 } 503 504 // Takes ownership of all arguments, gives ownership of return value. 505 TypeData * addQualifiers( TypeData * ltype, TypeData * rtype ) { 506 if ( ltype->forall ) { 507 if ( rtype->forall ) { 508 rtype->forall->set_last( ltype->forall ); 509 } else if ( TypeData::Aggregate != rtype->kind ) { 510 rtype->forall = ltype->forall; 511 } else if ( rtype->aggregate.params ) { 512 rtype->aggregate.params->set_last( ltype->forall ); 513 } else { 514 rtype->aggregate.params = ltype->forall; 515 } 516 ltype->forall = nullptr; 517 } 518 519 addQualifiersToType( rtype, ltype ); 520 return rtype; 521 } 522 523 // Helper for addType and cloneBaseType. 524 static void addTypeToType( TypeData *& dst, TypeData *& src ) { 525 if ( src->forall && dst->kind == TypeData::Function ) { 526 if ( dst->forall ) { 527 dst->forall->set_last( src->forall ); 528 } else { 529 dst->forall = src->forall; 530 } // if 531 src->forall = nullptr; 532 } // if 533 if ( dst->base ) { 534 addTypeToType( dst->base, src ); 535 return; 536 } 537 switch ( dst->kind ) { 538 case TypeData::Unknown: 539 src->qualifiers |= dst->qualifiers; 540 // LEAKS dst? 541 dst = src; 542 src = nullptr; 543 break; 544 case TypeData::Basic: 545 dst->qualifiers |= src->qualifiers; 546 if ( src->kind != TypeData::Unknown ) { 547 assert( src->kind == TypeData::Basic ); 548 549 if ( dst->basictype == DeclarationNode::NoBasicType ) { 550 dst->basictype = src->basictype; 551 } else if ( src->basictype != DeclarationNode::NoBasicType ) { 552 SemanticError( yylloc, "multiple declaration types \"%s\" and \"%s\".", 553 DeclarationNode::basicTypeNames[ dst->basictype ], 554 DeclarationNode::basicTypeNames[ src->basictype ] ); 555 } 556 if ( dst->complextype == DeclarationNode::NoComplexType ) { 557 dst->complextype = src->complextype; 558 } else if ( src->complextype != DeclarationNode::NoComplexType ) { 559 SemanticError( yylloc, "multiple declaration types \"%s\" and \"%s\".", 560 DeclarationNode::complexTypeNames[ src->complextype ], 561 DeclarationNode::complexTypeNames[ src->complextype ] ); 562 } 563 if ( dst->signedness == DeclarationNode::NoSignedness ) { 564 dst->signedness = src->signedness; 565 } else if ( src->signedness != DeclarationNode::NoSignedness ) { 566 SemanticError( yylloc, "conflicting type specifier \"%s\" and \"%s\".", 567 DeclarationNode::signednessNames[ dst->signedness ], 568 DeclarationNode::signednessNames[ src->signedness ] ); 569 } 570 if ( dst->length == DeclarationNode::NoLength ) { 571 dst->length = src->length; 572 } else if ( dst->length == DeclarationNode::Long && src->length == DeclarationNode::Long ) { 573 dst->length = DeclarationNode::LongLong; 574 } else if ( src->length != DeclarationNode::NoLength ) { 575 SemanticError( yylloc, "conflicting type specifier \"%s\" and \"%s\".", 576 DeclarationNode::lengthNames[ dst->length ], 577 DeclarationNode::lengthNames[ src->length ] ); 578 } 579 } // if 580 break; 581 default: 582 switch ( src->kind ) { 583 case TypeData::Aggregate: 584 case TypeData::Enum: 585 dst->base = new TypeData( TypeData::AggregateInst ); 586 dst->base->aggInst.aggregate = src; 587 if ( src->kind == TypeData::Aggregate ) { 588 dst->base->aggInst.params = maybeCopy( src->aggregate.actuals ); 589 } // if 590 dst->base->qualifiers |= src->qualifiers; 591 src = nullptr; 592 break; 593 default: 594 if ( dst->forall ) { 595 dst->forall->set_last( src->forall ); 596 } else { 597 dst->forall = src->forall; 598 } // if 599 src->forall = nullptr; 600 dst->base = src; 601 src = nullptr; 602 } // switch 603 } // switch 604 } 605 606 // Takes ownership of all arguments, gives ownership of return value. 607 TypeData * addType( TypeData * ltype, TypeData * rtype, std::vector<ast::ptr<ast::Attribute>> & attributes ) { 608 if ( rtype ) { 609 addTypeToType( rtype, ltype ); 610 return rtype; 611 } else { 612 if ( ltype->kind == TypeData::Aggregate || ltype->kind == TypeData::Enum ) { 613 // Hide type information aggregate instances. 614 rtype = new TypeData( TypeData::AggregateInst ); 615 rtype->aggInst.aggregate = ltype; 616 rtype->aggInst.aggregate->aggregate.attributes.swap( attributes ); // change ownership 617 if ( ltype->kind == TypeData::Aggregate ) { 618 rtype->aggInst.hoistType = ltype->aggregate.body; 619 rtype->aggInst.params = maybeCopy( ltype->aggregate.actuals ); 620 } else { 621 rtype->aggInst.hoistType = ltype->enumeration.body; 622 } // if 623 rtype->qualifiers |= ltype->qualifiers; 624 } else { 625 rtype = ltype; 626 } // if 627 return rtype; 628 } // if 629 } 630 631 // Takes ownership of both arguments, gives ownership of return value. 632 TypeData * cloneBaseType( TypeData * type, TypeData * other ) { 633 TypeData * newType = type->getLastBase()->clone(); 634 if ( newType->kind == TypeData::AggregateInst ) { 635 // don't duplicate members 636 if ( newType->aggInst.aggregate->kind == TypeData::Enum ) { 637 delete newType->aggInst.aggregate->enumeration.constants; 638 newType->aggInst.aggregate->enumeration.constants = nullptr; 639 newType->aggInst.aggregate->enumeration.body = false; 640 } else { 641 assert( newType->aggInst.aggregate->kind == TypeData::Aggregate ); 642 delete newType->aggInst.aggregate->aggregate.fields; 643 newType->aggInst.aggregate->aggregate.fields = nullptr; 644 newType->aggInst.aggregate->aggregate.body = false; 645 } // if 646 // don't hoist twice 647 newType->aggInst.hoistType = false; 648 } // if 649 newType->forall = maybeCopy( type->forall ); 650 651 if ( other ) { 652 addTypeToType( other, newType ); 653 delete newType; 654 return other; 655 } // if 656 return newType; 657 } 658 659 TypeData * makeNewBase( TypeData * type ) { 660 switch ( type->kind ) { 661 case TypeData::Aggregate: 662 case TypeData::Enum: { 663 TypeData * out = new TypeData( TypeData::AggregateInst ); 664 out->aggInst.aggregate = type; 665 if ( TypeData::Aggregate == type->kind ) { 666 out->aggInst.params = maybeCopy( type->aggregate.actuals ); 667 } 668 out->qualifiers |= type->qualifiers; 669 return out; 670 } 671 default: 672 return type; 673 } // switch 478 674 } 479 675
Note: See TracChangeset
for help on using the changeset viewer.