Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/GenPoly/Box.cc

    r83794e1 racd7c5dd  
    2727#include "Box.h"
    2828#include "DeclMutator.h"
     29#include "Lvalue.h"
     30#include "FindFunction.h"
    2931#include "PolyMutator.h"
    30 #include "FindFunction.h"
    3132#include "ScopedSet.h"
    3233#include "ScrubTyVars.h"
     
    5556#include "Common/UniqueName.h"
    5657#include "Common/utility.h"
    57 
    58 #include "CodeGen/OperatorTable.h"
    5958
    6059#include "InitTweak/InitTweak.h"
     
    204203                };
    205204
    206                 /// Replaces initialization of polymorphic values with alloca, declaration of dtype/ftype with appropriate void expression, and sizeof expressions of polymorphic types with the proper variable
     205                /// Replaces initialization of polymorphic values with alloca, declaration of dtype/ftype with appropriate void expression, sizeof expressions of polymorphic types with the proper variable, and strips fields from generic struct declarations.
    207206                class Pass3 final : public PolyMutator {
    208207                  public:
     
    212211                        using PolyMutator::mutate;
    213212                        virtual DeclarationWithType *mutate( FunctionDecl *functionDecl ) override;
     213                        virtual Declaration *mutate( StructDecl *structDecl ) override;
     214                        virtual Declaration *mutate( UnionDecl *unionDecl ) override;
    214215                        virtual ObjectDecl *mutate( ObjectDecl *objectDecl ) override;
    215216                        virtual TypedefDecl *mutate( TypedefDecl *objectDecl ) override;
     
    569570                        // To compound the issue, the right side can be *x, etc. because of lvalue-returning functions
    570571                        if ( UntypedExpr * assign = dynamic_cast< UntypedExpr * >( commaExpr->get_arg1() ) ) {
    571                                 if ( CodeGen::isAssignment( InitTweak::getFunctionName( assign ) ) ) {
     572                                if ( InitTweak::isAssignment( InitTweak::getFunctionName( assign ) ) ) {
    572573                                        assert( assign->get_args().size() == 2 );
    573574                                        if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * > ( assign->get_args().back() ) ) {
     
    609610                                                }
    610611                                        } else {
    611                                                 throw SemanticError( "Cannot pass non-struct type for generic struct: ", argBaseType );
     612                                                throw SemanticError( "Cannot pass non-struct type for generic struct" );
    612613                                        }
    613614                                }
     
    757758                        assertf( arg->has_result(), "arg does not have result: %s", toString( arg ).c_str() );
    758759                        if ( isPolyType( param, exprTyVars ) ) {
    759                                 if ( isPolyType( arg->get_result() ) ) {
     760                                Type * newType = arg->get_result()->clone();
     761                                if ( env ) env->apply( newType );
     762                                std::auto_ptr<Type> manager( newType );
     763                                if ( isPolyType( newType ) ) {
    760764                                        // if the argument's type is polymorphic, we don't need to box again!
    761765                                        return;
    762                                 } else if ( arg->get_result()->get_lvalue() ) {  // xxx - is this still right??
    763                                 // xxx - dynamic_cast<ReferenceType *>( arg->get_result() )??
    764                                         // VariableExpr and MemberExpr are lvalues; need to check this isn't coming from the second arg of a comma expression though (not an lvalue)
    765                                         // xxx - need to test that this code is still reachable
    766                                         if ( CommaExpr *commaArg = dynamic_cast< CommaExpr* >( arg ) ) {
    767                                                 commaArg->set_arg2( new AddressExpr( commaArg->get_arg2() ) );
    768                                         } else {
    769                                                 arg = new AddressExpr( arg );
    770                                         }
     766                                } else if ( arg->get_result()->get_lvalue() ) {
     767                                        // argument expression may be CFA lvalue, but not C lvalue -- apply generalizedLvalue transformations.
     768                                        arg =  generalizedLvalue( new AddressExpr( arg ) );
    771769                                        if ( ! ResolvExpr::typesCompatible( param, arg->get_result(), SymTab::Indexer() ) ) {
    772770                                                // silence warnings by casting boxed parameters when the actual type does not match up with the formal type.
     
    10271025                                                } // if
    10281026                                                if ( baseType1 || baseType2 ) {
    1029                                                         delete ret->get_result();
    10301027                                                        ret->set_result( appExpr->get_result()->clone() );
    10311028                                                        if ( appExpr->get_env() ) {
     
    10411038                                                assert( ! appExpr->get_args().empty() );
    10421039                                                if ( isPolyType( appExpr->get_result(), scopeTyVars, env ) ) {
    1043                                                         // remove dereference from polymorphic types since they are boxed.
    10441040                                                        Expression *ret = appExpr->get_args().front();
    1045                                                         // fix expr type to remove pointer
    10461041                                                        delete ret->get_result();
    10471042                                                        ret->set_result( appExpr->get_result()->clone() );
     
    11331128
    11341129                        assert( appExpr->get_function()->has_result() );
    1135                         FunctionType * function = getFunctionType( appExpr->get_function()->get_result() );
    1136                         assertf( function, "ApplicationExpr has non-function type: %s", toString( appExpr->get_function()->get_result() ).c_str() );
     1130                        PointerType *pointer = safe_dynamic_cast< PointerType *>( appExpr->get_function()->get_result() );
     1131                        FunctionType *function = safe_dynamic_cast< FunctionType *>( pointer->get_base() );
    11371132
    11381133                        if ( Expression *newExpr = handleIntrinsics( appExpr ) ) {
     
    12111206                                                        if ( ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( expr->get_args().front() ) ) {
    12121207                                                                assert( appExpr->get_function()->has_result() );
    1213                                                                 FunctionType *function = getFunctionType( appExpr->get_function()->get_result() );
    1214                                                                 assert( function );
     1208                                                                PointerType *pointer = safe_dynamic_cast< PointerType *>( appExpr->get_function()->get_result() );
     1209                                                                FunctionType *function = safe_dynamic_cast< FunctionType *>( pointer->get_base() );
    12151210                                                                needs = needsAdapter( function, scopeTyVars );
    12161211                                                        } // if
     
    12211216                        // isPolyType check needs to happen before mutating addrExpr arg, so pull it forward
    12221217                        // out of the if condition.
     1218                        bool polytype = isPolyType( addrExpr->get_arg()->get_result(), scopeTyVars, env );
    12231219                        addrExpr->set_arg( mutateExpression( addrExpr->get_arg() ) );
    1224                         // ... but must happen after mutate, since argument might change (e.g. intrinsic *?, ?[?]) - re-evaluate above comment
    1225                         bool polytype = isPolyType( addrExpr->get_arg()->get_result(), scopeTyVars, env );
    12261220                        if ( polytype || needs ) {
    12271221                                Expression *ret = addrExpr->get_arg();
     
    12901284                                if ( adaptersDone.find( mangleName ) == adaptersDone.end() ) {
    12911285                                        std::string adapterName = makeAdapterName( mangleName );
    1292                                         // adapter may not be used in body, pass along with unused attribute.
    1293                                         paramList.push_front( new ObjectDecl( adapterName, Type::StorageClasses(), LinkageSpec::C, 0, new PointerType( Type::Qualifiers(), makeAdapterType( *funType, scopeTyVars ) ), 0, { new Attribute( "unused" ) } ) );
     1286                                        paramList.push_front( new ObjectDecl( adapterName, Type::StorageClasses(), LinkageSpec::C, 0, new PointerType( Type::Qualifiers(), makeAdapterType( *funType, scopeTyVars ) ), 0 ) );
    12941287                                        adaptersDone.insert( adaptersDone.begin(), mangleName );
    12951288                                }
     
    13971390                        std::list< DeclarationWithType *>::iterator last = funcType->get_parameters().begin();
    13981391                        std::list< DeclarationWithType *> inferredParams;
    1399                         // size/align/offset parameters may not be used in body, pass along with unused attribute.
    1400                         ObjectDecl newObj( "", Type::StorageClasses(), LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), 0,
    1401                                            { new Attribute( "unused" ) } );
     1392                        ObjectDecl newObj( "", Type::StorageClasses(), LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), 0 );
    14021393                        ObjectDecl newPtr( "", Type::StorageClasses(), LinkageSpec::C, 0,
    14031394                                           new PointerType( Type::Qualifiers(), new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) ), 0 );
     
    14221413                                for ( std::list< DeclarationWithType *>::iterator assert = (*tyParm)->get_assertions().begin(); assert != (*tyParm)->get_assertions().end(); ++assert ) {
    14231414//      *assert = (*assert)->acceptMutator( *this );
    1424                                         // assertion parameters may not be used in body, pass along with unused attribute.
    1425                                         (*assert)->get_attributes().push_back( new Attribute( "unused" ) );
    14261415                                        inferredParams.push_back( *assert );
    14271416                                }
     
    17601749
    17611750                Expression *PolyGenericCalculator::mutate( SizeofExpr *sizeofExpr ) {
    1762                         Type *ty = sizeofExpr->get_type();
     1751                        Type *ty = sizeofExpr->get_isType() ? sizeofExpr->get_type() : sizeofExpr->get_expr()->get_result();
    17631752                        if ( findGeneric( ty ) ) {
    17641753                                Expression *ret = new NameExpr( sizeofName( mangleType( ty ) ) );
     
    17701759
    17711760                Expression *PolyGenericCalculator::mutate( AlignofExpr *alignofExpr ) {
    1772                         Type *ty = alignofExpr->get_type();
     1761                        Type *ty = alignofExpr->get_isType() ? alignofExpr->get_type() : alignofExpr->get_expr()->get_result();
    17731762                        if ( findGeneric( ty ) ) {
    17741763                                Expression *ret = new NameExpr( alignofName( mangleType( ty ) ) );
     
    18801869                }
    18811870
     1871                /// Strips the members from a generic aggregate
     1872                void stripGenericMembers(AggregateDecl* decl) {
     1873                        if ( ! decl->get_parameters().empty() ) decl->get_members().clear();
     1874                }
     1875
     1876                Declaration *Pass3::mutate( StructDecl *structDecl ) {
     1877                        stripGenericMembers( structDecl );
     1878                        return structDecl;
     1879                }
     1880
     1881                Declaration *Pass3::mutate( UnionDecl *unionDecl ) {
     1882                        stripGenericMembers( unionDecl );
     1883                        return unionDecl;
     1884                }
     1885
    18821886                TypeDecl * Pass3::mutate( TypeDecl *typeDecl ) {
    18831887//   Initializer *init = 0;
Note: See TracChangeset for help on using the changeset viewer.