Ignore:
Timestamp:
Jun 2, 2022, 3:11:21 PM (3 years ago)
Author:
caparsons <caparson@…>
Branches:
ADT, ast-experimental, master, pthread-emulation, qualifiedEnum
Children:
ced5e2a
Parents:
015925a (diff), fc134a48 (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.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/CommonType.cc

    r015925a re5d9274  
    497497                                result = new BasicType( basicType->tq | otherBasic->tq, newType );
    498498                        } // if
    499                 } else if ( dynamic_cast< EnumInstType * > ( type2 ) || dynamic_cast< ZeroType * >( type2 ) || dynamic_cast< OneType * >( type2 ) ) {
     499                } else if ( dynamic_cast< ZeroType * >( type2 ) || dynamic_cast< OneType * >( type2 ) ) {
    500500                        // use signed int in lieu of the enum/zero/one type
    501501                        BasicType::Kind newType = commonTypes[ basicType->get_kind() ][ BasicType::SignedInt ];
     
    503503                                result = new BasicType( basicType->tq | type2->tq, newType );
    504504                        } // if
    505                 } // if
     505                } else if ( const EnumInstType * enumInst = dynamic_cast< const EnumInstType * > ( type2 ) ) {
     506                        const EnumDecl* enumDecl = enumInst->baseEnum;
     507                        if ( const Type* baseType = enumDecl->base ) {
     508                                result = baseType->clone();
     509                        } else {
     510                                BasicType::Kind newType = commonTypes[ basicType->get_kind() ][ BasicType::SignedInt ];
     511                                if ( ( ( newType == basicType->get_kind() && basicType->tq >= type2->tq ) || widenFirst ) && ( ( newType != basicType->get_kind() && basicType->tq <= type2->tq ) || widenSecond ) ) {
     512                                        result = new BasicType( basicType->tq | type2->tq, newType );
     513                                } // if
     514                        }
     515                }
    506516        }
    507517
     
    691701                                }
    692702                        } else if (
    693                                 dynamic_cast< const ast::EnumInstType * >( type2 )
    694                                 || dynamic_cast< const ast::ZeroType * >( type2 )
     703                                dynamic_cast< const ast::ZeroType * >( type2 )
    695704                                || dynamic_cast< const ast::OneType * >( type2 )
    696705                        ) {
     
    705714                                        result = new ast::BasicType{ kind, basic->qualifiers | type2->qualifiers };
    706715                                }
     716                        } else if ( const ast::EnumInstType * enumInst = dynamic_cast< const ast::EnumInstType * >( type2 ) ) {
     717                                #warning remove casts when `commonTypes` moved to new AST
     718                                const ast::EnumDecl* enumDecl = enumInst->base;
     719                                if ( enumDecl->base ) {
     720                                        result = enumDecl->base.get();
     721                                } else {
     722                                        ast::BasicType::Kind kind = (ast::BasicType::Kind)(int)commonTypes[ (BasicType::Kind)(int)basic->kind ][ (BasicType::Kind)(int)ast::BasicType::SignedInt ];
     723                                        if (
     724                                                ( ( kind == basic->kind && basic->qualifiers >= type2->qualifiers )
     725                                                        || widen.first )
     726                                                && ( ( kind != basic->kind && basic->qualifiers <= type2->qualifiers )
     727                                                        || widen.second )
     728                                        ) {
     729                                                result = new ast::BasicType{ kind, basic->qualifiers | type2->qualifiers };
     730                                        }
     731                                }
    707732                        }
    708733                }
     
    723748                        result = voidPtr;
    724749                        add_qualifiers( result, oPtr->qualifiers );
     750                }
     751
     752                // For a typed enum, we want to unify type1 with the base type of the enum
     753                bool tryResolveWithTypedEnum( const ast::Type * type1 ) {
     754                        if (auto enumInst = dynamic_cast<const ast::EnumInstType *> (type2) ) {
     755                                ast::AssertionSet have, need; // unused
     756                                ast::OpenVarSet newOpen{ open };
     757                                if (enumInst->base->base
     758                                && unifyExact(type1, enumInst->base->base, tenv, need, have, newOpen, widen, symtab)) {
     759                                        result = type1;
     760                                        return true;
     761                                }
     762                        }
     763                        return false;
    725764                }
    726765
     
    768807                                result = pointer;
    769808                                add_qualifiers( result, type2->qualifiers );
    770                         }
    771                 }
    772 
    773                 void postvisit( const ast::ArrayType * ) {}
     809                        } else {
     810                                tryResolveWithTypedEnum( pointer );
     811                        }
     812                }
     813
     814                void postvisit( const ast::ArrayType * arr ) {
     815                        // xxx - does it make sense?
     816                        tryResolveWithTypedEnum( arr );
     817                }
    774818
    775819                void postvisit( const ast::ReferenceType * ref ) {
     
    810854                                result = ref;
    811855                                add_qualifiers( result, type2->qualifiers );
    812                         }
    813                 }
    814 
    815                 void postvisit( const ast::FunctionType * ) {}
    816 
    817                 void postvisit( const ast::StructInstType * ) {}
    818 
    819                 void postvisit( const ast::UnionInstType * ) {}
     856                        } else {
     857                                // xxx - does unifying a ref with typed enumInst makes sense?
     858                                if (!dynamic_cast<const ast::EnumInstType *>(type2))
     859                                        result = commonType( type2, ref, widen, symtab, tenv, open );
     860                        }
     861                }
     862
     863                void postvisit( const ast::FunctionType * func) {
     864                        tryResolveWithTypedEnum( func );
     865                }
     866
     867                void postvisit( const ast::StructInstType * inst ) {
     868                        tryResolveWithTypedEnum( inst );
     869                }
     870
     871                void postvisit( const ast::UnionInstType * inst ) {
     872                        tryResolveWithTypedEnum( inst );
     873                }
    820874
    821875                void postvisit( const ast::EnumInstType * enumInst ) {
    822                         if (
    823                                 dynamic_cast< const ast::BasicType * >( type2 )
    824                                 || dynamic_cast< const ast::ZeroType * >( type2 )
    825                                 || dynamic_cast< const ast::OneType * >( type2 )
    826                         ) {
    827                                 // reuse BasicType/EnumInstType common type by swapping
     876                        // reuse BasicType/EnumInstType common type by swapping
     877                        // xxx - is this already handled by unify?
     878                        if (!dynamic_cast<const ast::EnumInstType *>(type2))
    828879                                result = commonType( type2, enumInst, widen, symtab, tenv, open );
    829                         }
    830880                }
    831881
     
    850900                                                result = type2;
    851901                                                reset_qualifiers( result, q1 | q2 );
     902                                        } else {
     903                                                tryResolveWithTypedEnum( t1 );
    852904                                        }
    853905                                }
     
    855907                }
    856908
    857                 void postvisit( const ast::TupleType * ) {}
     909                void postvisit( const ast::TupleType * tuple) {
     910                        tryResolveWithTypedEnum( tuple );
     911                }
    858912
    859913                void postvisit( const ast::VarArgsType * ) {}
     
    861915                void postvisit( const ast::ZeroType * zero ) {
    862916                        if ( ! widen.first ) return;
    863                         if (
    864                                 dynamic_cast< const ast::BasicType * >( type2 )
    865                                 || dynamic_cast< const ast::PointerType * >( type2 )
    866                                 || dynamic_cast< const ast::EnumInstType * >( type2 )
    867                         ) {
     917                        if ( dynamic_cast< const ast::BasicType * >( type2 )
     918                                || dynamic_cast< const ast::PointerType * >( type2 ) ) {
    868919                                if ( widen.second || zero->qualifiers <= type2->qualifiers ) {
    869920                                        result = type2;
     
    873924                                result = new ast::BasicType{
    874925                                        ast::BasicType::SignedInt, zero->qualifiers | type2->qualifiers };
     926                        } else if ( const ast::EnumInstType * enumInst = dynamic_cast< const ast::EnumInstType * >( type2 ) ) {
     927                                const ast::EnumDecl * enumDecl = enumInst->base;
     928                                if ( enumDecl->base ) {
     929                                        if ( tryResolveWithTypedEnum( zero ) )
     930                                                add_qualifiers( result, zero->qualifiers );
     931                                } else {
     932                                        if ( widen.second || zero->qualifiers <= type2->qualifiers ) {
     933                                                result = type2;
     934                                                add_qualifiers( result, zero->qualifiers );
     935                                        }
     936                                }
    875937                        }
    876938                }
     
    878940                void postvisit( const ast::OneType * one ) {
    879941                        if ( ! widen.first ) return;
    880                         if (
    881                                 dynamic_cast< const ast::BasicType * >( type2 )
    882                                 || dynamic_cast< const ast::EnumInstType * >( type2 )
    883                         ) {
     942                        if ( dynamic_cast< const ast::BasicType * >( type2 ) ) {
    884943                                if ( widen.second || one->qualifiers <= type2->qualifiers ) {
    885944                                        result = type2;
     
    889948                                result = new ast::BasicType{
    890949                                        ast::BasicType::SignedInt, one->qualifiers | type2->qualifiers };
     950                        } else if ( const ast::EnumInstType * enumInst = dynamic_cast< const ast::EnumInstType * >( type2 ) ) {
     951                                const ast::EnumDecl * enumBase = enumInst->base;
     952                                if ( enumBase->base ) {
     953                                        if ( tryResolveWithTypedEnum( one ))
     954                                                add_qualifiers( result, one->qualifiers );
     955                                } else {
     956                                        if ( widen.second || one->qualifiers <= type2->qualifiers ) {
     957                                                result = type2;
     958                                                add_qualifiers( result, one->qualifiers );
     959                                        }
     960                                }
    891961                        }
    892962                }
Note: See TracChangeset for help on using the changeset viewer.