Ignore:
Timestamp:
Mar 5, 2024, 10:17:17 AM (4 months ago)
Author:
Andrew Beach <ajbeach@…>
Branches:
master
Children:
f6e8c67
Parents:
44adf1b
Message:

Moved a field and functions from DeclarationNode? to TypeData?. Trying to make the line between them cleaner.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Parser/TypeData.cc

    r44adf1b raf60383  
    476476        } // switch
    477477        assert(false);
     478}
     479
     480
     481TypeData * TypeData::getLastBase() {
     482        TypeData * cur = this;
     483        while ( cur->base ) cur = cur->base;
     484        return cur;
     485}
     486
     487void TypeData::setLastBase( TypeData * newBase ) {
     488        getLastBase()->base = newBase;
     489}
     490
     491// Takes ownership of src.
     492static 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.
     505TypeData * 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.
     524static 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.
     607TypeData * 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.
     632TypeData * 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
     659TypeData * 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
    478674}
    479675
Note: See TracChangeset for help on using the changeset viewer.