Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Parser/DeclarationNode.cc

    raf60383 r4eb3a7c5  
    8282
    8383DeclarationNode::~DeclarationNode() {
    84         delete name;
    85 
    8684//      delete variable.name;
    8785        delete variable.assertions;
     
    10199DeclarationNode * DeclarationNode::clone() const {
    102100        DeclarationNode * newnode = new DeclarationNode;
    103         newnode->next = maybeCopy( next );
     101        newnode->set_next( maybeCopy( get_next() ) );
    104102        newnode->name = name ? new string( *name ) : nullptr;
    105103
     104        newnode->builtin = NoBuiltinType;
    106105        newnode->type = maybeCopy( type );
    107106        newnode->inLine = inLine;
     
    171170
    172171void DeclarationNode::printList( std::ostream & os, int indent ) const {
    173         ParseList::printList( os, indent );
     172        ParseNode::printList( os, indent );
    174173        if ( hasEllipsis ) {
    175174                os << string( indent, ' ' )  << "and a variable number of other arguments" << endl;
     
    434433        DeclarationNode * newnode = new DeclarationNode;
    435434        newnode->type = new TypeData( TypeData::Builtin );
    436         newnode->type->builtintype = bt;
     435        newnode->builtin = bt;
     436        newnode->type->builtintype = newnode->builtin;
    437437        return newnode;
    438438} // DeclarationNode::newBuiltinType
     
    554554} // DeclarationNode::copySpecifiers
    555555
     556static void addQualifiersToType( TypeData *& src, TypeData * dst ) {
     557        if ( dst->base ) {
     558                addQualifiersToType( src, dst->base );
     559        } else if ( dst->kind == TypeData::Function ) {
     560                dst->base = src;
     561                src = nullptr;
     562        } else {
     563                dst->qualifiers |= src->qualifiers;
     564        } // if
     565} // addQualifiersToType
     566
    556567DeclarationNode * DeclarationNode::addQualifiers( DeclarationNode * q ) {
    557568        if ( ! q ) { return this; }                                                     // empty qualifier
     
    569580        } // if
    570581
     582        if ( q->type->forall ) {                                                        // forall qualifier ?
     583                if ( type->forall ) {                                                   // polymorphic routine ?
     584                        type->forall->appendList( q->type->forall ); // augment forall qualifier
     585                } else {
     586                        if ( type->kind == TypeData::Aggregate ) {      // struct/union ?
     587                                if ( type->aggregate.params ) {                 // polymorphic ?
     588                                        type->aggregate.params->appendList( q->type->forall ); // augment forall qualifier
     589                                } else {                                                                // not polymorphic
     590                                        type->aggregate.params = q->type->forall; // set forall qualifier
     591                                } // if
     592                        } else {                                                                        // not polymorphic
     593                                type->forall = q->type->forall;                 // make polymorphic routine
     594                        } // if
     595                } // if
     596                q->type->forall = nullptr;                                              // forall qualifier moved
     597        } // if
     598
    571599        checkQualifiers( type, q->type );
    572         BuiltinType const builtin = type->builtintype;
    573600        if ( (builtin == Zero || builtin == One) && q->type->qualifiers.any() && error.length() == 0 ) {
    574601                SemanticWarning( yylloc, Warning::BadQualifiersZeroOne, builtinTypeNames[builtin] );
    575602        } // if
    576         type = ::addQualifiers( q->type, type );
    577         q->type = nullptr;
     603        addQualifiersToType( q->type, type );
    578604
    579605        delete q;
     
    581607} // addQualifiers
    582608
     609static void addTypeToType( TypeData *& src, TypeData *& dst ) {
     610        if ( src->forall && dst->kind == TypeData::Function ) {
     611                if ( dst->forall ) {
     612                        dst->forall->appendList( src->forall );
     613                } else {
     614                        dst->forall = src->forall;
     615                } // if
     616                src->forall = nullptr;
     617        } // if
     618        if ( dst->base ) {
     619                addTypeToType( src, dst->base );
     620        } else {
     621                switch ( dst->kind ) {
     622                case TypeData::Unknown:
     623                        src->qualifiers |= dst->qualifiers;
     624                        dst = src;
     625                        src = nullptr;
     626                        break;
     627                case TypeData::Basic:
     628                        dst->qualifiers |= src->qualifiers;
     629                        if ( src->kind != TypeData::Unknown ) {
     630                                assert( src->kind == TypeData::Basic );
     631
     632                                if ( dst->basictype == DeclarationNode::NoBasicType ) {
     633                                        dst->basictype = src->basictype;
     634                                } else if ( src->basictype != DeclarationNode::NoBasicType )
     635                                        SemanticError( yylloc, "multiple declaration types \"%s\" and \"%s\".",
     636                                                                   DeclarationNode::basicTypeNames[ dst->basictype ],
     637                                                                   DeclarationNode::basicTypeNames[ src->basictype ] );
     638                                if ( dst->complextype == DeclarationNode::NoComplexType ) {
     639                                        dst->complextype = src->complextype;
     640                                } else if ( src->complextype != DeclarationNode::NoComplexType )
     641                                        SemanticError( yylloc, "multiple declaration types \"%s\" and \"%s\".",
     642                                                                   DeclarationNode::complexTypeNames[ src->complextype ],
     643                                                                   DeclarationNode::complexTypeNames[ src->complextype ] );
     644                                if ( dst->signedness == DeclarationNode::NoSignedness ) {
     645                                        dst->signedness = src->signedness;
     646                                } else if ( src->signedness != DeclarationNode::NoSignedness )
     647                                        SemanticError( yylloc, "conflicting type specifier \"%s\" and \"%s\".",
     648                                                                   DeclarationNode::signednessNames[ dst->signedness ],
     649                                                                   DeclarationNode::signednessNames[ src->signedness ] );
     650                                if ( dst->length == DeclarationNode::NoLength ) {
     651                                        dst->length = src->length;
     652                                } else if ( dst->length == DeclarationNode::Long && src->length == DeclarationNode::Long ) {
     653                                        dst->length = DeclarationNode::LongLong;
     654                                } else if ( src->length != DeclarationNode::NoLength )
     655                                        SemanticError( yylloc, "conflicting type specifier \"%s\" and \"%s\".",
     656                                                                   DeclarationNode::lengthNames[ dst->length ],
     657                                                                   DeclarationNode::lengthNames[ src->length ] );
     658                        } // if
     659                        break;
     660                default:
     661                        switch ( src->kind ) {
     662                        case TypeData::Aggregate:
     663                        case TypeData::Enum:
     664                                dst->base = new TypeData( TypeData::AggregateInst );
     665                                dst->base->aggInst.aggregate = src;
     666                                if ( src->kind == TypeData::Aggregate ) {
     667                                        dst->base->aggInst.params = maybeCopy( src->aggregate.actuals );
     668                                } // if
     669                                dst->base->qualifiers |= src->qualifiers;
     670                                src = nullptr;
     671                                break;
     672                        default:
     673                                if ( dst->forall ) {
     674                                        dst->forall->appendList( src->forall );
     675                                } else {
     676                                        dst->forall = src->forall;
     677                                } // if
     678                                src->forall = nullptr;
     679                                dst->base = src;
     680                                src = nullptr;
     681                        } // switch
     682                } // switch
     683        } // if
     684}
     685
    583686DeclarationNode * DeclarationNode::addType( DeclarationNode * o, bool copyattr ) {
    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 
     687        if ( o ) {
     688                checkSpecifiers( o );
     689                copySpecifiers( o, copyattr );
     690                if ( o->type ) {
     691                        if ( ! type ) {
     692                                if ( o->type->kind == TypeData::Aggregate || o->type->kind == TypeData::Enum ) {
     693                                        // Hide type information aggregate instances.
     694                                        type = new TypeData( TypeData::AggregateInst );
     695                                        type->aggInst.aggregate = o->type;      // change ownership
     696                                        type->aggInst.aggregate->aggregate.attributes.swap( o->attributes ); // change ownership                                       
     697                                        if ( o->type->kind == TypeData::Aggregate ) {
     698                                                type->aggInst.hoistType = o->type->aggregate.body;
     699                                                type->aggInst.params = maybeCopy( o->type->aggregate.actuals );
     700                                        } else {
     701                                                type->aggInst.hoistType = o->type->enumeration.body;
     702                                        } // if
     703                                        type->qualifiers |= o->type->qualifiers;
     704                                } else {
     705                                        type = o->type;
     706                                } // if
     707                                o->type = nullptr;                                              // change ownership
     708                        } else {
     709                                addTypeToType( o->type, type );
     710                        } // if
     711                } // if
     712                if ( o->bitfieldWidth ) {
     713                        bitfieldWidth = o->bitfieldWidth;
     714                } // if
     715
     716                // there may be typedefs chained onto the type
     717                if ( o->get_next() ) {
     718                        set_last( o->get_next()->clone() );
     719                } // if
     720        } // if
    601721        delete o;
     722
    602723        return this;
    603724}
    604725
    605726DeclarationNode * DeclarationNode::addEnumBase( DeclarationNode * o ) {
    606         if ( o && o->type ) {
    607                 type->base = o->type;
     727        if ( o && o->type) {
     728                type->base= o->type;
    608729        } // if
    609730        delete o;
     
    624745        if ( variable.tyClass != ast::TypeDecl::NUMBER_OF_KINDS ) {
    625746                if ( variable.assertions ) {
    626                         variable.assertions->set_last( assertions );
     747                        variable.assertions->appendList( assertions );
    627748                } else {
    628749                        variable.assertions = assertions;
     
    635756        case TypeData::Symbolic:
    636757                if ( type->symbolic.assertions ) {
    637                         type->symbolic.assertions->set_last( assertions );
     758                        type->symbolic.assertions->appendList( assertions );
    638759                } else {
    639760                        type->symbolic.assertions = assertions;
     
    689810DeclarationNode * DeclarationNode::setBase( TypeData * newType ) {
    690811        if ( type ) {
    691                 type->setLastBase( newType );
     812                TypeData * prevBase = type;
     813                TypeData * curBase = type->base;
     814                while ( curBase != nullptr ) {
     815                        prevBase = curBase;
     816                        curBase = curBase->base;
     817                } // while
     818                prevBase->base = newType;
    692819        } else {
    693820                type = newType;
     
    730857                assert( p->type->kind == TypeData::Pointer || p->type->kind == TypeData::Reference );
    731858                if ( type ) {
    732                         p->type->base = makeNewBase( type );
     859                        switch ( type->kind ) {
     860                        case TypeData::Aggregate:
     861                        case TypeData::Enum:
     862                                p->type->base = new TypeData( TypeData::AggregateInst );
     863                                p->type->base->aggInst.aggregate = type;
     864                                if ( type->kind == TypeData::Aggregate ) {
     865                                        p->type->base->aggInst.params = maybeCopy( type->aggregate.actuals );
     866                                } // if
     867                                p->type->base->qualifiers |= type->qualifiers;
     868                                break;
     869
     870                        default:
     871                                p->type->base = type;
     872                        } // switch
    733873                        type = nullptr;
    734874                } // if
     
    740880}
    741881
     882static TypeData * findLast( TypeData * a ) {
     883        assert( a );
     884        TypeData * cur = a;
     885        while ( cur->base ) {
     886                cur = cur->base;
     887        } // while
     888        return cur;
     889}
     890
    742891DeclarationNode * DeclarationNode::addNewArray( DeclarationNode * a ) {
    743892        if ( ! a ) return this;
    744893        assert( a->type->kind == TypeData::Array );
     894        TypeData * lastArray = findLast( a->type );
    745895        if ( type ) {
    746                 a->type->setLastBase( makeNewBase( type ) );
     896                switch ( type->kind ) {
     897                case TypeData::Aggregate:
     898                case TypeData::Enum:
     899                        lastArray->base = new TypeData( TypeData::AggregateInst );
     900                        lastArray->base->aggInst.aggregate = type;
     901                        if ( type->kind == TypeData::Aggregate ) {
     902                                lastArray->base->aggInst.params = maybeCopy( type->aggregate.actuals );
     903                        } // if
     904                        lastArray->base->qualifiers |= type->qualifiers;
     905                        break;
     906                default:
     907                        lastArray->base = type;
     908                } // switch
    747909                type = nullptr;
    748910        } // if
     
    798960DeclarationNode * DeclarationNode::cloneBaseType( DeclarationNode * o, bool copyattr ) {
    799961        if ( ! o ) return nullptr;
     962
    800963        o->copySpecifiers( this, copyattr );
    801964        if ( type ) {
    802                 o->type = ::cloneBaseType( type, o->type );
     965                TypeData * srcType = type;
     966
     967                // search for the base type by scanning off pointers and array designators
     968                while ( srcType->base ) {
     969                        srcType = srcType->base;
     970                } // while
     971
     972                TypeData * newType = srcType->clone();
     973                if ( newType->kind == TypeData::AggregateInst ) {
     974                        // don't duplicate members
     975                        if ( newType->aggInst.aggregate->kind == TypeData::Enum ) {
     976                                delete newType->aggInst.aggregate->enumeration.constants;
     977                                newType->aggInst.aggregate->enumeration.constants = nullptr;
     978                                newType->aggInst.aggregate->enumeration.body = false;
     979                        } else {
     980                                assert( newType->aggInst.aggregate->kind == TypeData::Aggregate );
     981                                delete newType->aggInst.aggregate->aggregate.fields;
     982                                newType->aggInst.aggregate->aggregate.fields = nullptr;
     983                                newType->aggInst.aggregate->aggregate.body = false;
     984                        } // if
     985                        // don't hoist twice
     986                        newType->aggInst.hoistType = false;
     987                } // if
     988
     989                newType->forall = maybeCopy( type->forall );
     990                if ( ! o->type ) {
     991                        o->type = newType;
     992                } else {
     993                        addTypeToType( newType, o->type );
     994                        delete newType;
     995                } // if
    803996        } // if
    804997        return o;
     
    9061099        std::back_insert_iterator<std::vector<ast::ptr<ast::Decl>>> out( outputList );
    9071100
    908         for ( const DeclarationNode * cur = firstNode ; cur ; cur = cur->next ) {
     1101        for ( const DeclarationNode * cur = firstNode ; cur ; cur = strict_next( cur ) ) {
    9091102                try {
    9101103                        bool extracted_named = false;
     
    9741167        std::back_insert_iterator<std::vector<ast::ptr<ast::DeclWithType>>> out( outputList );
    9751168
    976         for ( const DeclarationNode * cur = firstNode; cur; cur = cur->next ) {
     1169        for ( const DeclarationNode * cur = firstNode; cur; cur = strict_next( cur ) ) {
    9771170                try {
    9781171                        ast::Decl * decl = cur->build();
     
    10241217        std::back_insert_iterator<std::vector<ast::ptr<ast::Type>>> out( outputList );
    10251218
    1026         for ( const DeclarationNode * cur = firstNode ; cur ; cur = cur->next ) {
     1219        for ( const DeclarationNode * cur = firstNode ; cur ; cur = strict_next( cur ) ) {
    10271220                try {
    10281221                        * out++ = cur->buildType();
Note: See TracChangeset for help on using the changeset viewer.