source: src/ResolvExpr/PtrsAssignable.cc @ 0b6089f

Last change on this file since 0b6089f was 2908f08, checked in by Andrew Beach <ajbeach@…>, 12 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
Line 
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//
7// PtrsAssignable.cc --
8//
9// Author           : Richard C. Bilson
10// Created On       : Sun May 17 11:44:11 2015
11// Last Modified By : Andrew
12// Last Modified On : Mon Jun 24 15:29:00 2019
13// Update Count     : 9
14//
15
16#include "PtrsAssignable.hpp"
17
18#include "AST/Pass.hpp"
19#include "AST/Type.hpp"
20#include "AST/TypeEnvironment.hpp"
21
22namespace ResolvExpr {
23
24namespace {
25
26struct PtrsAssignable : public ast::WithShortCircuiting {
27        const ast::Type * dst;
28        const ast::TypeEnvironment & typeEnv;
29        int result;
30
31        PtrsAssignable( const ast::Type * dst, const ast::TypeEnvironment & env ) :
32                dst( dst ), typeEnv( env ), result( 0 ) {}
33
34        void previsit( ast::Type * ) { visit_children = false; }
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 ) {
47                if ( const ast::EqvClass * eqv = typeEnv.lookup( *inst ) ) {
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
56} // namespace
57
58int ptrsAssignable( const ast::Type * src, const ast::Type * dst,
59                const ast::TypeEnvironment & env ) {
60        if ( const ast::TypeInstType * dstAsInst = dynamic_cast< const ast::TypeInstType * >( dst ) ) {
61                if ( const ast::EqvClass * eqv = env.lookup( *dstAsInst ) ) {
62                        return ptrsAssignable( src, eqv->bound, env );
63                }
64        }
65        if ( dynamic_cast< const ast::VoidType * >( dst ) ) {
66                return -1;
67        } else {
68                ast::Pass<PtrsAssignable> visitor( dst, env );
69                src->accept( visitor );
70                return visitor.core.result;
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        }
103        return 0;
104#endif
105}
106
107} // namespace ResolvExpr
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.