Changeset df9317b


Ignore:
Timestamp:
Jun 24, 2019, 3:36:31 PM (2 years ago)
Author:
Andrew Beach <ajbeach@…>
Branches:
arm-eh, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr
Children:
1335e6f
Parents:
e98c7ab
Message:

Filled in the definition of PtrsAssignable?.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/PtrsAssignable.cc

    re98c7ab rdf9317b  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 11:44:11 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Mar  2 17:36:05 2016
    13 // Update Count     : 8
    14 //
    15 
    16 #include "AST/Fwd.hpp"
     11// Last Modified By : Andrew
     12// Last Modified On : Mon Jun 24 15:29:00 2019
     13// Update Count     : 9
     14//
     15
     16#include "typeops.h"
     17
     18#include "AST/Pass.hpp"
     19#include "AST/Type.hpp"
     20#include "AST/TypeEnvironment.hpp"
    1721#include "Common/PassVisitor.h"
    1822#include "ResolvExpr/TypeEnvironment.h"  // for EqvClass, TypeEnvironment
     
    108112        void PtrsAssignable::postvisit(  __attribute__((unused)) OneType *oneType ) {}
    109113
     114// TODO: Get rid of the `_new` suffix when the old version is removed.
     115struct PtrsAssignable_new : public ast::WithShortCircuiting {
     116        const ast::Type * dst;
     117        const ast::TypeEnvironment & typeEnv;
     118        int result;
     119
     120        PtrsAssignable_new( const ast::Type * dst, const ast::TypeEnvironment & env ) :
     121                dst( dst ), typeEnv( env ), result( 0 ) {}
     122
     123        void previsit( Type * ) { visit_children = false; }
     124
     125        void postvisit( const ast::EnumInstType * ) {
     126                if ( dynamic_cast< const ast::BasicType * >( dst ) ) {
     127                        // int * = E *, etc. is safe. This isn't technically correct, as each
     128                        // enum has one basic type that it is compatible with, an that type can
     129                        // differ from enum to enum. Without replicating GCC's internal logic,
     130                        // there is no way to know which type this particular enum is compatible
     131                        // with, so punt on this for now.
     132                        result = 1;
     133                }
     134        }
     135        void postvisit( const ast::TypeInstType * inst ) {
     136                if ( const ast::EqvClass * eqv = typeEnv.lookup( inst->name ) ) {
     137                        if ( eqv->bound ) {
     138                                // T * = S * for any S depends on the type bound to T
     139                                result = ptrsAssignable( eqv->bound, dst, typeEnv );
     140                        }
     141                }
     142        }
     143};
     144
    110145int ptrsAssignable( const ast::Type * src, const ast::Type * dst,
    111146                const ast::TypeEnvironment & env ) {
    112         #warning unimplemented
    113         (void)src;
    114         (void)dst;
    115         (void)env;
    116         assert(0);
     147        if ( const ast::TypeInstType * dstAsInst = dynamic_cast< const ast::TypeInstType * >( dst ) ) {
     148                if ( const ast::EqvClass * eqv = env.lookup( dstAsInst->name ) ) {
     149                        return ptrsAssignable( src, eqv->bound, env );
     150                }
     151        }
     152        if ( dynamic_cast< const ast::VoidType * >( dst ) ) {
     153                return -1;
     154        } else {
     155                ast::Pass<PtrsAssignable_new> visitor( dst, env );
     156                src->accept( visitor );
     157                return visitor.pass.result;
     158        }
     159
     160// see ticket #136 (this should be able to replace the visitor).
     161#if 0
     162        if ( const ast::TypeInstType * dstAsTypeInst =
     163                        dynamic_cast< const ast::TypeInstType* >( dst ) ) {
     164                if ( const ast::EqvClass * eqv = env.lookup( dstAsTypeInst->get_name() ) ) {
     165                        return ptrsAssignable( src, eqv->type, env );
     166                } // if
     167        } // if
     168        if ( dynamic_cast< VoidType* >( dst ) ) {
     169                // void * = T * for any T is unsafe
     170                // xxx - this should be safe, but that currently breaks the build
     171                return -1;
     172        } else if ( dynamic_cast< EnumInstType * >( src ) ) {
     173                if ( dynamic_cast< BasicType * >( dst ) ) {
     174                        // int * = E *, etc. is safe. This isn't technically correct, as each
     175                        // enum has one basic type that it is compatible with, an that type can
     176                        // differ from enum to enum. Without replicating GCC's internal logic,
     177                        // there is no way to know which type this particular enum is compatible
     178                        // with, so punt on this for now.
     179                        return 1;
     180                }
     181        } else if ( const ast::TypeInstType * typeInstType =
     182                        dynamic_cast< const ast::TypeInstType * >( src ) ) {
     183                if ( const ast::EqvClass * eqv = env.lookup( typeInstType->name ) ) {
     184                        if ( eqv->bound ) {
     185                                // T * = S * for any S depends on the type bound to T
     186                                return ptrsAssignable( eqv->bound, dst, env );
     187                        }
     188                }
     189        }
    117190        return 0;
     191#endif
    118192}
    119193
Note: See TracChangeset for help on using the changeset viewer.