source: src/ResolvExpr/PtrsAssignable.cc

Last change on this file was 2908f08, checked in by Andrew Beach <ajbeach@…>, 4 months ago

Most of ResolvExpr? was written before the new style standard. Some files updated, focus on headers.

  • Property mode set to 100644
File size: 3.5 KB
RevLine 
[a32b204]1//
2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
[5ccb10d]7// PtrsAssignable.cc --
[a32b204]8//
9// Author           : Richard C. Bilson
10// Created On       : Sun May 17 11:44:11 2015
[df9317bd]11// Last Modified By : Andrew
12// Last Modified On : Mon Jun 24 15:29:00 2019
13// Update Count     : 9
[a32b204]14//
15
[5bf3976]16#include "PtrsAssignable.hpp"
[df9317bd]17
18#include "AST/Pass.hpp"
19#include "AST/Type.hpp"
20#include "AST/TypeEnvironment.hpp"
[51b7345]21
22namespace ResolvExpr {
[5ccb10d]23
[2908f08]24namespace {
25
[0bd3faf]26struct PtrsAssignable : public ast::WithShortCircuiting {
[df9317bd]27        const ast::Type * dst;
28        const ast::TypeEnvironment & typeEnv;
29        int result;
30
[0bd3faf]31        PtrsAssignable( const ast::Type * dst, const ast::TypeEnvironment & env ) :
[df9317bd]32                dst( dst ), typeEnv( env ), result( 0 ) {}
33
[0bd3faf]34        void previsit( ast::Type * ) { visit_children = false; }
[df9317bd]35
36        void postvisit( const ast::EnumInstType * ) {
37                if ( dynamic_cast< const ast::BasicType * >( dst ) ) {
38                        // int * = E *, etc. is safe. This isn't technically correct, as each
39                        // enum has one basic type that it is compatible with, an that type can
40                        // differ from enum to enum. Without replicating GCC's internal logic,
41                        // there is no way to know which type this particular enum is compatible
42                        // with, so punt on this for now.
43                        result = 1;
44                }
45        }
46        void postvisit( const ast::TypeInstType * inst ) {
[3e5dd913]47                if ( const ast::EqvClass * eqv = typeEnv.lookup( *inst ) ) {
[df9317bd]48                        if ( eqv->bound ) {
49                                // T * = S * for any S depends on the type bound to T
50                                result = ptrsAssignable( eqv->bound, dst, typeEnv );
51                        }
52                }
53        }
54};
55
[2908f08]56} // namespace
57
[fb2bde4]58int ptrsAssignable( const ast::Type * src, const ast::Type * dst,
59                const ast::TypeEnvironment & env ) {
[df9317bd]60        if ( const ast::TypeInstType * dstAsInst = dynamic_cast< const ast::TypeInstType * >( dst ) ) {
[3e5dd913]61                if ( const ast::EqvClass * eqv = env.lookup( *dstAsInst ) ) {
[df9317bd]62                        return ptrsAssignable( src, eqv->bound, env );
63                }
64        }
65        if ( dynamic_cast< const ast::VoidType * >( dst ) ) {
66                return -1;
67        } else {
[0bd3faf]68                ast::Pass<PtrsAssignable> visitor( dst, env );
[df9317bd]69                src->accept( visitor );
[7ff3e522]70                return visitor.core.result;
[df9317bd]71        }
72
73// see ticket #136 (this should be able to replace the visitor).
74#if 0
75        if ( const ast::TypeInstType * dstAsTypeInst =
76                        dynamic_cast< const ast::TypeInstType* >( dst ) ) {
77                if ( const ast::EqvClass * eqv = env.lookup( dstAsTypeInst->get_name() ) ) {
78                        return ptrsAssignable( src, eqv->type, env );
79                } // if
80        } // if
81        if ( dynamic_cast< VoidType* >( dst ) ) {
82                // void * = T * for any T is unsafe
83                // xxx - this should be safe, but that currently breaks the build
84                return -1;
85        } else if ( dynamic_cast< EnumInstType * >( src ) ) {
86                if ( dynamic_cast< BasicType * >( dst ) ) {
87                        // int * = E *, etc. is safe. This isn't technically correct, as each
88                        // enum has one basic type that it is compatible with, an that type can
89                        // differ from enum to enum. Without replicating GCC's internal logic,
90                        // there is no way to know which type this particular enum is compatible
91                        // with, so punt on this for now.
92                        return 1;
93                }
94        } else if ( const ast::TypeInstType * typeInstType =
95                        dynamic_cast< const ast::TypeInstType * >( src ) ) {
96                if ( const ast::EqvClass * eqv = env.lookup( typeInstType->name ) ) {
97                        if ( eqv->bound ) {
98                                // T * = S * for any S depends on the type bound to T
99                                return ptrsAssignable( eqv->bound, dst, env );
100                        }
101                }
102        }
[fb2bde4]103        return 0;
[df9317bd]104#endif
[fb2bde4]105}
106
[51b7345]107} // namespace ResolvExpr
[a32b204]108
109// Local Variables: //
110// tab-width: 4 //
111// mode: c++ //
112// compile-command: "make install" //
113// End: //
Note: See TracBrowser for help on using the repository browser.