Changeset af60383


Ignore:
Timestamp:
Mar 5, 2024, 10:17:17 AM (3 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.

Location:
src/Parser
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • src/Parser/DeclarationNode.cc

    r44adf1b raf60383  
    104104        newnode->name = name ? new string( *name ) : nullptr;
    105105
    106         newnode->builtin = NoBuiltinType;
    107106        newnode->type = maybeCopy( type );
    108107        newnode->inLine = inLine;
     
    435434        DeclarationNode * newnode = new DeclarationNode;
    436435        newnode->type = new TypeData( TypeData::Builtin );
    437         newnode->builtin = bt;
    438         newnode->type->builtintype = newnode->builtin;
     436        newnode->type->builtintype = bt;
    439437        return newnode;
    440438} // DeclarationNode::newBuiltinType
     
    556554} // DeclarationNode::copySpecifiers
    557555
    558 static void addQualifiersToType( TypeData *& src, TypeData * dst ) {
    559         if ( dst->base ) {
    560                 addQualifiersToType( src, dst->base );
    561         } else if ( dst->kind == TypeData::Function ) {
    562                 dst->base = src;
    563                 src = nullptr;
    564         } else {
    565                 dst->qualifiers |= src->qualifiers;
    566         } // if
    567 } // addQualifiersToType
    568 
    569556DeclarationNode * DeclarationNode::addQualifiers( DeclarationNode * q ) {
    570557        if ( ! q ) { return this; }                                                     // empty qualifier
     
    582569        } // if
    583570
    584         if ( q->type->forall ) {                                                        // forall qualifier ?
    585                 if ( type->forall ) {                                                   // polymorphic routine ?
    586                         type->forall->set_last( q->type->forall ); // augment forall qualifier
    587                 } else {
    588                         if ( type->kind == TypeData::Aggregate ) {      // struct/union ?
    589                                 if ( type->aggregate.params ) {                 // polymorphic ?
    590                                         type->aggregate.params->set_last( q->type->forall ); // augment forall qualifier
    591                                 } else {                                                                // not polymorphic
    592                                         type->aggregate.params = q->type->forall; // set forall qualifier
    593                                 } // if
    594                         } else {                                                                        // not polymorphic
    595                                 type->forall = q->type->forall;                 // make polymorphic routine
    596                         } // if
    597                 } // if
    598                 q->type->forall = nullptr;                                              // forall qualifier moved
    599         } // if
    600 
    601571        checkQualifiers( type, q->type );
     572        BuiltinType const builtin = type->builtintype;
    602573        if ( (builtin == Zero || builtin == One) && q->type->qualifiers.any() && error.length() == 0 ) {
    603574                SemanticWarning( yylloc, Warning::BadQualifiersZeroOne, builtinTypeNames[builtin] );
    604575        } // if
    605         addQualifiersToType( q->type, type );
     576        type = ::addQualifiers( q->type, type );
     577        q->type = nullptr;
    606578
    607579        delete q;
     
    609581} // addQualifiers
    610582
    611 static void addTypeToType( TypeData *& src, TypeData *& dst ) {
    612         if ( src->forall && dst->kind == TypeData::Function ) {
    613                 if ( dst->forall ) {
    614                         dst->forall->set_last( src->forall );
    615                 } else {
    616                         dst->forall = src->forall;
    617                 } // if
    618                 src->forall = nullptr;
    619         } // if
    620         if ( dst->base ) {
    621                 addTypeToType( src, dst->base );
    622         } else {
    623                 switch ( dst->kind ) {
    624                 case TypeData::Unknown:
    625                         src->qualifiers |= dst->qualifiers;
    626                         dst = src;
    627                         src = nullptr;
    628                         break;
    629                 case TypeData::Basic:
    630                         dst->qualifiers |= src->qualifiers;
    631                         if ( src->kind != TypeData::Unknown ) {
    632                                 assert( src->kind == TypeData::Basic );
    633 
    634                                 if ( dst->basictype == DeclarationNode::NoBasicType ) {
    635                                         dst->basictype = src->basictype;
    636                                 } else if ( src->basictype != DeclarationNode::NoBasicType )
    637                                         SemanticError( yylloc, "multiple declaration types \"%s\" and \"%s\".",
    638                                                                    DeclarationNode::basicTypeNames[ dst->basictype ],
    639                                                                    DeclarationNode::basicTypeNames[ src->basictype ] );
    640                                 if ( dst->complextype == DeclarationNode::NoComplexType ) {
    641                                         dst->complextype = src->complextype;
    642                                 } else if ( src->complextype != DeclarationNode::NoComplexType )
    643                                         SemanticError( yylloc, "multiple declaration types \"%s\" and \"%s\".",
    644                                                                    DeclarationNode::complexTypeNames[ src->complextype ],
    645                                                                    DeclarationNode::complexTypeNames[ src->complextype ] );
    646                                 if ( dst->signedness == DeclarationNode::NoSignedness ) {
    647                                         dst->signedness = src->signedness;
    648                                 } else if ( src->signedness != DeclarationNode::NoSignedness )
    649                                         SemanticError( yylloc, "conflicting type specifier \"%s\" and \"%s\".",
    650                                                                    DeclarationNode::signednessNames[ dst->signedness ],
    651                                                                    DeclarationNode::signednessNames[ src->signedness ] );
    652                                 if ( dst->length == DeclarationNode::NoLength ) {
    653                                         dst->length = src->length;
    654                                 } else if ( dst->length == DeclarationNode::Long && src->length == DeclarationNode::Long ) {
    655                                         dst->length = DeclarationNode::LongLong;
    656                                 } else if ( src->length != DeclarationNode::NoLength )
    657                                         SemanticError( yylloc, "conflicting type specifier \"%s\" and \"%s\".",
    658                                                                    DeclarationNode::lengthNames[ dst->length ],
    659                                                                    DeclarationNode::lengthNames[ src->length ] );
    660                         } // if
    661                         break;
    662                 default:
    663                         switch ( src->kind ) {
    664                         case TypeData::Aggregate:
    665                         case TypeData::Enum:
    666                                 dst->base = new TypeData( TypeData::AggregateInst );
    667                                 dst->base->aggInst.aggregate = src;
    668                                 if ( src->kind == TypeData::Aggregate ) {
    669                                         dst->base->aggInst.params = maybeCopy( src->aggregate.actuals );
    670                                 } // if
    671                                 dst->base->qualifiers |= src->qualifiers;
    672                                 src = nullptr;
    673                                 break;
    674                         default:
    675                                 if ( dst->forall ) {
    676                                         dst->forall->set_last( src->forall );
    677                                 } else {
    678                                         dst->forall = src->forall;
    679                                 } // if
    680                                 src->forall = nullptr;
    681                                 dst->base = src;
    682                                 src = nullptr;
    683                         } // switch
    684                 } // switch
    685         } // if
    686 }
    687 
    688583DeclarationNode * DeclarationNode::addType( DeclarationNode * o, bool copyattr ) {
    689         if ( o ) {
    690                 checkSpecifiers( o );
    691                 copySpecifiers( o, copyattr );
    692                 if ( o->type ) {
    693                         if ( ! type ) {
    694                                 if ( o->type->kind == TypeData::Aggregate || o->type->kind == TypeData::Enum ) {
    695                                         // Hide type information aggregate instances.
    696                                         type = new TypeData( TypeData::AggregateInst );
    697                                         type->aggInst.aggregate = o->type;      // change ownership
    698                                         type->aggInst.aggregate->aggregate.attributes.swap( o->attributes ); // change ownership                                       
    699                                         if ( o->type->kind == TypeData::Aggregate ) {
    700                                                 type->aggInst.hoistType = o->type->aggregate.body;
    701                                                 type->aggInst.params = maybeCopy( o->type->aggregate.actuals );
    702                                         } else {
    703                                                 type->aggInst.hoistType = o->type->enumeration.body;
    704                                         } // if
    705                                         type->qualifiers |= o->type->qualifiers;
    706                                 } else {
    707                                         type = o->type;
    708                                 } // if
    709                                 o->type = nullptr;                                              // change ownership
    710                         } else {
    711                                 addTypeToType( o->type, type );
    712                         } // if
    713                 } // if
    714                 if ( o->bitfieldWidth ) {
    715                         bitfieldWidth = o->bitfieldWidth;
    716                 } // if
    717 
    718                 // there may be typedefs chained onto the type
    719                 if ( o->next ) {
    720                         set_last( o->next->clone() );
    721                 } // if
    722         } // if
     584        if ( !o ) return this;
     585
     586        checkSpecifiers( o );
     587        copySpecifiers( o, copyattr );
     588        if ( o->type ) {
     589                type = ::addType( o->type, type, o->attributes );
     590                o->type = nullptr;
     591        } // if
     592        if ( o->bitfieldWidth ) {
     593                bitfieldWidth = o->bitfieldWidth;
     594        } // if
     595
     596        // there may be typedefs chained onto the type
     597        if ( o->next ) {
     598                set_last( o->next->clone() );
     599        } // if
     600
    723601        delete o;
    724 
    725602        return this;
    726603}
    727604
    728605DeclarationNode * DeclarationNode::addEnumBase( DeclarationNode * o ) {
    729         if ( o && o->type) {
    730                 type->base= o->type;
     606        if ( o && o->type ) {
     607                type->base = o->type;
    731608        } // if
    732609        delete o;
     
    812689DeclarationNode * DeclarationNode::setBase( TypeData * newType ) {
    813690        if ( type ) {
    814                 TypeData * prevBase = type;
    815                 TypeData * curBase = type->base;
    816                 while ( curBase != nullptr ) {
    817                         prevBase = curBase;
    818                         curBase = curBase->base;
    819                 } // while
    820                 prevBase->base = newType;
     691                type->setLastBase( newType );
    821692        } else {
    822693                type = newType;
     
    859730                assert( p->type->kind == TypeData::Pointer || p->type->kind == TypeData::Reference );
    860731                if ( type ) {
    861                         switch ( type->kind ) {
    862                         case TypeData::Aggregate:
    863                         case TypeData::Enum:
    864                                 p->type->base = new TypeData( TypeData::AggregateInst );
    865                                 p->type->base->aggInst.aggregate = type;
    866                                 if ( type->kind == TypeData::Aggregate ) {
    867                                         p->type->base->aggInst.params = maybeCopy( type->aggregate.actuals );
    868                                 } // if
    869                                 p->type->base->qualifiers |= type->qualifiers;
    870                                 break;
    871 
    872                         default:
    873                                 p->type->base = type;
    874                         } // switch
     732                        p->type->base = makeNewBase( type );
    875733                        type = nullptr;
    876734                } // if
     
    882740}
    883741
    884 static TypeData * findLast( TypeData * a ) {
    885         assert( a );
    886         TypeData * cur = a;
    887         while ( cur->base ) {
    888                 cur = cur->base;
    889         } // while
    890         return cur;
    891 }
    892 
    893742DeclarationNode * DeclarationNode::addNewArray( DeclarationNode * a ) {
    894743        if ( ! a ) return this;
    895744        assert( a->type->kind == TypeData::Array );
    896         TypeData * lastArray = findLast( a->type );
    897745        if ( type ) {
    898                 switch ( type->kind ) {
    899                 case TypeData::Aggregate:
    900                 case TypeData::Enum:
    901                         lastArray->base = new TypeData( TypeData::AggregateInst );
    902                         lastArray->base->aggInst.aggregate = type;
    903                         if ( type->kind == TypeData::Aggregate ) {
    904                                 lastArray->base->aggInst.params = maybeCopy( type->aggregate.actuals );
    905                         } // if
    906                         lastArray->base->qualifiers |= type->qualifiers;
    907                         break;
    908                 default:
    909                         lastArray->base = type;
    910                 } // switch
     746                a->type->setLastBase( makeNewBase( type ) );
    911747                type = nullptr;
    912748        } // if
     
    962798DeclarationNode * DeclarationNode::cloneBaseType( DeclarationNode * o, bool copyattr ) {
    963799        if ( ! o ) return nullptr;
    964 
    965800        o->copySpecifiers( this, copyattr );
    966801        if ( type ) {
    967                 TypeData * srcType = type;
    968 
    969                 // search for the base type by scanning off pointers and array designators
    970                 while ( srcType->base ) {
    971                         srcType = srcType->base;
    972                 } // while
    973 
    974                 TypeData * newType = srcType->clone();
    975                 if ( newType->kind == TypeData::AggregateInst ) {
    976                         // don't duplicate members
    977                         if ( newType->aggInst.aggregate->kind == TypeData::Enum ) {
    978                                 delete newType->aggInst.aggregate->enumeration.constants;
    979                                 newType->aggInst.aggregate->enumeration.constants = nullptr;
    980                                 newType->aggInst.aggregate->enumeration.body = false;
    981                         } else {
    982                                 assert( newType->aggInst.aggregate->kind == TypeData::Aggregate );
    983                                 delete newType->aggInst.aggregate->aggregate.fields;
    984                                 newType->aggInst.aggregate->aggregate.fields = nullptr;
    985                                 newType->aggInst.aggregate->aggregate.body = false;
    986                         } // if
    987                         // don't hoist twice
    988                         newType->aggInst.hoistType = false;
    989                 } // if
    990 
    991                 newType->forall = maybeCopy( type->forall );
    992                 if ( ! o->type ) {
    993                         o->type = newType;
    994                 } else {
    995                         addTypeToType( newType, o->type );
    996                         delete newType;
    997                 } // if
     802                o->type = ::cloneBaseType( type, o->type );
    998803        } // if
    999804        return o;
  • src/Parser/DeclarationNode.h

    r44adf1b raf60383  
    141141        StaticAssert_t assert;
    142142
    143         BuiltinType builtin = NoBuiltinType;
    144 
    145143        TypeData * type = nullptr;
    146144
  • 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
  • src/Parser/TypeData.h

    r44adf1b raf60383  
    111111
    112112        const std::string * leafName() const;
     113
     114        TypeData * getLastBase();
     115        void setLastBase( TypeData * );
    113116};
     117
     118TypeData * addQualifiers( TypeData * ltype, TypeData * rtype );
     119TypeData * addType( TypeData * ltype, TypeData * rtype, std::vector<ast::ptr<ast::Attribute>> & );
     120TypeData * cloneBaseType( TypeData * type, TypeData * other );
     121TypeData * makeNewBase( TypeData * type );
    114122
    115123ast::Type * typebuild( const TypeData * );
Note: See TracChangeset for help on using the changeset viewer.