source: src/SymTab/TypeEquality.cc @ 89e6ffc

aaron-thesisarm-ehcleanup-dtorsdeferred_resndemanglerenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprnew-envno_listpersistent-indexerresolv-newwith_gc
Last change on this file since 89e6ffc was 89e6ffc, checked in by Aaron Moss <a3moss@…>, 6 years ago

Added support for ZeroType? and OneType? to all relevant visitors

  • Property mode set to 100644
File size: 6.4 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// TypeEquality.cc --
8//
9// Author           : Rob Schluntz
10// Created On       : Tue Jul 07 16:28:29 2015
11// Last Modified By : Rob Schluntz
12// Last Modified On : Mon Jul 20 14:16:11 2015
13// Update Count     : 37
14//
15
16#include <list>
17#include <iterator>
18#include "Validate.h"
19#include "SynTree/Visitor.h"
20#include "SynTree/Type.h"
21#include "SynTree/Statement.h"
22#include "SynTree/TypeSubstitution.h"
23#include "Indexer.h"
24#include "TypeEquality.h"
25
26namespace SymTab {
27        class TypeEquality : public Visitor {
28  public:
29                TypeEquality( Type * other, bool vlaErr ) : result( true ), other( other ), 
30                        vlaErr( vlaErr ) {}
31                bool result;
32
33  private:
34                virtual void visit( FunctionType *funcType );
35                virtual void visit( VoidType *voidType );
36                virtual void visit( BasicType *basicType );
37                virtual void visit( PointerType *pointerType );
38                virtual void visit( ArrayType *arrayType );
39                virtual void visit( StructInstType *structInst );
40                virtual void visit( UnionInstType *unionInst );
41                virtual void visit( EnumInstType *enumInst );
42                virtual void visit( TypeInstType *typeInst );
43                virtual void visit( VarArgsType *varArgsType );
44                virtual void visit( ZeroType *zeroType );
45                virtual void visit( OneType *oneType );
46
47                void handleQualifiers( Type * t );
48
49                Type * other;
50                bool vlaErr;
51        };
52
53        bool typeEquals( Type * t1, Type * t2, bool vlaErr ) {
54                TypeEquality teq( t2, vlaErr );
55                t1->accept( teq );
56                return teq.result;
57        }
58
59        void TypeEquality::handleQualifiers( Type * t ) {
60                result = result && t->get_qualifiers() == other->get_qualifiers();
61        }
62
63        void TypeEquality::visit( VoidType *voidType ) {
64                handleQualifiers( voidType );
65                if ( ! dynamic_cast< VoidType * >( other ) ) {
66                        result = false;
67                }
68        }
69
70        void TypeEquality::visit( BasicType *basicType ) {
71                handleQualifiers( basicType );
72                if ( BasicType * bt = dynamic_cast< BasicType * >( other ) ) {
73                        result = result && basicType->get_kind() == bt->get_kind(); 
74                } else {
75                        result = false;
76                }
77        }
78
79        void TypeEquality::visit( PointerType *pointerType ) {
80                handleQualifiers( pointerType );
81                if ( PointerType * pt = dynamic_cast< PointerType * >( other ) ) {
82                        other = pt->get_base();
83                        pointerType->get_base()->accept( *this );
84                } else {
85                        result = false;
86                }
87        }
88
89        void TypeEquality::visit( ArrayType *arrayType ) {
90                handleQualifiers( arrayType );
91
92                if ( ArrayType * at = dynamic_cast< ArrayType * >( other ) ) {
93                        // to be equal, array types must both be VLA or both not VLA
94                        // and must both have a dimension expression or not have a dimension
95                        result = result && arrayType->get_isVarLen() == at->get_isVarLen()
96                                && ((arrayType->get_dimension() != 0 && at->get_dimension() != 0)
97                                        || (arrayType->get_dimension() == 0 && at->get_dimension() == 0));
98
99                        if ( vlaErr ) {
100                                // useful for comparing typedef types - in this case, we
101                                // want types to appear distinct if either is a VLA type
102                                if ( arrayType->get_isVarLen() || at->get_isVarLen() ) {
103                                        result = false;
104                                }
105                        }
106
107                        if ( ! arrayType->get_isVarLen() && ! at->get_isVarLen() &&
108                                arrayType->get_dimension() != 0 && at->get_dimension() != 0 ) {
109                                ConstantExpr * ce1 = dynamic_cast< ConstantExpr * >( arrayType->get_dimension() );
110                                ConstantExpr * ce2 = dynamic_cast< ConstantExpr * >( at->get_dimension() );
111                                assert(ce1 && ce2);
112
113                                Constant * c1 = ce1->get_constant();
114                                Constant * c2 = ce2->get_constant();
115
116                                result = result && c1->get_value() == c2->get_value();
117                        }
118
119                        other = at->get_base();
120                        arrayType->get_base()->accept( *this );
121                } else {
122                        result = false;
123                }
124        }
125
126        void TypeEquality::visit( FunctionType *funcType ) {
127                handleQualifiers( funcType );
128
129                if ( FunctionType * ft = dynamic_cast< FunctionType * >( other ) ) {
130                        // function types must have the same number of return types
131                        // and parameters to be equivalent
132                        result = result && funcType->get_returnVals().size() == ft->get_returnVals().size()
133                                && funcType->get_parameters().size() == ft->get_parameters().size()
134                                && funcType->get_isVarArgs() == ft->get_isVarArgs();
135
136                        std::list< DeclarationWithType * >::iterator it1, it2;
137
138                        // return types must be equivalent
139                        it1 = funcType->get_returnVals().begin();
140                        it2 = ft->get_returnVals().begin();
141                        for ( ; it1 != funcType->get_returnVals().end(); ++it1, ++it2 ) {
142                                if ( ! result ) return;
143                                other = (*it2)->get_type();
144                                (*it1)->get_type()->accept( *this );
145                        }
146
147                        // parameter types must be equivalent
148                        it1 = funcType->get_parameters().begin(); 
149                        it2 = ft->get_parameters().begin();
150                        for ( ; it1 != funcType->get_parameters().end(); ++it1, ++it2 ) {
151                                if ( ! result ) return;
152                                other = (*it2)->get_type();
153                                (*it1)->get_type()->accept( *this );
154                        }
155                } else {
156                        result = false;
157                }
158        }
159
160        // aggregate types only need to have the same name
161        void TypeEquality::visit( StructInstType *structInst )  {
162                handleQualifiers( structInst );
163                if ( StructInstType * st = dynamic_cast< StructInstType * >( other ) ) {
164                        result = result && structInst->get_name() == st->get_name();
165                } else {
166                        result = false;
167                }
168        }
169
170        void TypeEquality::visit( UnionInstType *unionInst ) {
171                handleQualifiers( unionInst );
172                if ( UnionInstType * ut = dynamic_cast< UnionInstType * >( other ) ) {
173                        result = result && unionInst->get_name() == ut->get_name();
174                } else {
175                        result = false;
176                }
177        }
178
179        void TypeEquality::visit( EnumInstType *enumInst ) {
180                handleQualifiers( enumInst );
181                if ( EnumInstType * et = dynamic_cast< EnumInstType * >( other ) ) {
182                        result = result && enumInst->get_name() == et->get_name();
183                } else {
184                        result = false;
185                }
186        }
187
188        void TypeEquality::visit( TypeInstType *typeInst ) {
189                handleQualifiers( typeInst );
190                if ( TypeInstType * tt = dynamic_cast< TypeInstType * >( other ) ) {
191                        result = result && typeInst->get_name() == tt->get_name();
192                } else {
193                        result = false;
194                }
195        }
196
197        void TypeEquality::visit( VarArgsType *varArgsType ) {
198                handleQualifiers( varArgsType );
199                if ( ! dynamic_cast< VarArgsType * >( other ) ) {
200                        result = false;
201                }
202        }
203
204        void TypeEquality::visit( ZeroType *zeroType ) {
205                handleQualifiers( zeroType );
206                if ( ! dynamic_cast< ZeroType * >( other ) ) {
207                        result = false;
208                }
209        }
210
211        void TypeEquality::visit( OneType *oneType ) {
212                handleQualifiers( oneType );
213                if ( ! dynamic_cast< OneType * >( other ) ) {
214                        result = false;
215                }
216        }
217} // namespace SymTab
Note: See TracBrowser for help on using the repository browser.