source: src/GenPoly/GenPoly.cc @ b940dc71

ADTaaron-thesisarm-ehast-experimentalcleanup-dtorsdeferred_resndemanglerenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprnew-envno_listpersistent-indexerpthread-emulationqualifiedEnumresolv-newwith_gc
Last change on this file since b940dc71 was 1aa4b71, checked in by Rob Schluntz <rschlunt@…>, 7 years ago

added case for ConditionalExpr? in getBaseVar

  • Property mode set to 100644
File size: 9.3 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// GenPoly.cc --
8//
9// Author           : Richard C. Bilson
10// Created On       : Mon May 18 07:44:20 2015
11// Last Modified By : Peter A. Buhr
12// Last Modified On : Wed Jun 29 21:45:53 2016
13// Update Count     : 14
14//
15
16#include "GenPoly.h"
17
18#include "SynTree/Expression.h"
19#include "SynTree/Type.h"
20
21#include <iostream>
22using namespace std;
23
24namespace GenPoly {
25        namespace {
26                /// Checks a parameter list for polymorphic parameters; will substitute according to env if present
27                bool hasPolyParams( std::list< Expression* >& params, const TypeSubstitution *env ) {
28                        for ( std::list< Expression* >::iterator param = params.begin(); param != params.end(); ++param ) {
29                                TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param );
30                                assert(paramType && "Aggregate parameters should be type expressions");
31                                if ( isPolyType( paramType->get_type(), env ) ) return true;
32                        }
33                        return false;
34                }
35
36                /// Checks a parameter list for polymorphic parameters from tyVars; will substitute according to env if present
37                bool hasPolyParams( std::list< Expression* >& params, const TyVarMap &tyVars, const TypeSubstitution *env ) {
38                        for ( std::list< Expression* >::iterator param = params.begin(); param != params.end(); ++param ) {
39                                TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param );
40                                assert(paramType && "Aggregate parameters should be type expressions");
41                                if ( isPolyType( paramType->get_type(), tyVars, env ) ) return true;
42                        }
43                        return false;
44                }
45
46                /// Checks a parameter list for dynamic-layout parameters from tyVars; will substitute according to env if present
47                bool hasDynParams( std::list< Expression* >& params, const TyVarMap &tyVars, const TypeSubstitution *env ) {
48                        for ( std::list< Expression* >::iterator param = params.begin(); param != params.end(); ++param ) {
49                                TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param );
50                                assert(paramType && "Aggregate parameters should be type expressions");
51                                if ( isDynType( paramType->get_type(), tyVars, env ) ) return true;
52                        }
53                        return false;
54                }
55        }
56
57        Type* replaceTypeInst( Type* type, const TypeSubstitution* env ) {
58                if ( ! env ) return type;
59                if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( type ) ) {
60                        Type *newType = env->lookup( typeInst->get_name() );
61                        if ( newType ) return newType;
62                }
63                return type;
64        }
65
66        Type *isPolyType( Type *type, const TypeSubstitution *env ) {
67                type = replaceTypeInst( type, env );
68
69                if ( dynamic_cast< TypeInstType * >( type ) ) {
70                        return type;
71                } else if ( StructInstType *structType = dynamic_cast< StructInstType* >( type ) ) {
72                        if ( hasPolyParams( structType->get_parameters(), env ) ) return type;
73                } else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( type ) ) {
74                        if ( hasPolyParams( unionType->get_parameters(), env ) ) return type;
75                }
76                return 0;
77        }
78
79        Type *isPolyType( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env ) {
80                type = replaceTypeInst( type, env );
81
82                if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( type ) ) {
83                        if ( tyVars.find( typeInst->get_name() ) != tyVars.end() ) {
84                                return type;
85                        }
86                } else if ( StructInstType *structType = dynamic_cast< StructInstType* >( type ) ) {
87                        if ( hasPolyParams( structType->get_parameters(), tyVars, env ) ) return type;
88                } else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( type ) ) {
89                        if ( hasPolyParams( unionType->get_parameters(), tyVars, env ) ) return type;
90                }
91                return 0;
92        }
93
94        ReferenceToType *isDynType( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env ) {
95                type = replaceTypeInst( type, env );
96
97                if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( type ) ) {
98                        auto var = tyVars.find( typeInst->get_name() );
99                        if ( var != tyVars.end() && var->second.isComplete ) {
100                                return typeInst;
101                        }
102                } else if ( StructInstType *structType = dynamic_cast< StructInstType* >( type ) ) {
103                        if ( hasDynParams( structType->get_parameters(), tyVars, env ) ) return structType;
104                } else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( type ) ) {
105                        if ( hasDynParams( unionType->get_parameters(), tyVars, env ) ) return unionType;
106                }
107                return 0;
108        }
109
110        ReferenceToType *isDynRet( FunctionType *function, const TyVarMap &forallTypes ) {
111                if ( function->get_returnVals().empty() ) return 0;
112
113                return (ReferenceToType*)isDynType( function->get_returnVals().front()->get_type(), forallTypes );
114        }
115
116        ReferenceToType *isDynRet( FunctionType *function ) {
117                if ( function->get_returnVals().empty() ) return 0;
118
119                TyVarMap forallTypes( TypeDecl::Data{} );
120                makeTyVarMap( function, forallTypes );
121                return (ReferenceToType*)isDynType( function->get_returnVals().front()->get_type(), forallTypes );
122        }
123
124        bool needsAdapter( FunctionType *adaptee, const TyVarMap &tyVars ) {
125//              if ( ! adaptee->get_returnVals().empty() && isPolyType( adaptee->get_returnVals().front()->get_type(), tyVars ) ) {
126//                      return true;
127//              } // if
128                if ( isDynRet( adaptee, tyVars ) ) return true;
129
130                for ( std::list< DeclarationWithType* >::const_iterator innerArg = adaptee->get_parameters().begin(); innerArg != adaptee->get_parameters().end(); ++innerArg ) {
131//                      if ( isPolyType( (*innerArg)->get_type(), tyVars ) ) {
132                        if ( isDynType( (*innerArg)->get_type(), tyVars ) ) {
133                                return true;
134                        } // if
135                } // for
136                return false;
137        }
138
139        Type *isPolyPtr( Type *type, const TypeSubstitution *env ) {
140                type = replaceTypeInst( type, env );
141
142                if ( PointerType *ptr = dynamic_cast< PointerType *>( type ) ) {
143                        return isPolyType( ptr->get_base(), env );
144                }
145                return 0;
146        }
147
148        Type *isPolyPtr( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env ) {
149                type = replaceTypeInst( type, env );
150
151                if ( PointerType *ptr = dynamic_cast< PointerType *>( type ) ) {
152                        return isPolyType( ptr->get_base(), tyVars, env );
153                }
154                return 0;
155        }
156
157        Type * hasPolyBase( Type *type, int *levels, const TypeSubstitution *env ) {
158                int dummy;
159                if ( ! levels ) { levels = &dummy; }
160                *levels = 0;
161
162                while ( true ) {
163                        type = replaceTypeInst( type, env );
164
165                        if ( PointerType *ptr = dynamic_cast< PointerType *>( type ) ) {
166                                type = ptr->get_base();
167                                ++(*levels);
168                        } else break;
169                }
170
171                return isPolyType( type, env );
172        }
173
174        Type * hasPolyBase( Type *type, const TyVarMap &tyVars, int *levels, const TypeSubstitution *env ) {
175                int dummy;
176                if ( ! levels ) { levels = &dummy; }
177                *levels = 0;
178
179                while ( true ) {
180                        type = replaceTypeInst( type, env );
181
182                        if ( PointerType *ptr = dynamic_cast< PointerType *>( type ) ) {
183                                type = ptr->get_base();
184                                ++(*levels);
185                        } else break;
186                }
187
188                return isPolyType( type, tyVars, env );
189        }
190
191        FunctionType * getFunctionType( Type *ty ) {
192                PointerType *ptrType;
193                if ( ( ptrType = dynamic_cast< PointerType* >( ty ) ) ) {
194                        return dynamic_cast< FunctionType* >( ptrType->get_base() ); // pointer if FunctionType, NULL otherwise
195                } else {
196                        return dynamic_cast< FunctionType* >( ty ); // pointer if FunctionType, NULL otherwise
197                }
198        }
199
200        VariableExpr * getBaseVar( Expression *expr, int *levels ) {
201                int dummy;
202                if ( ! levels ) { levels = &dummy; }
203                *levels = 0;
204
205                while ( true ) {
206                        if ( VariableExpr *varExpr = dynamic_cast< VariableExpr* >( expr ) ) {
207                                return varExpr;
208                        } else if ( MemberExpr *memberExpr = dynamic_cast< MemberExpr* >( expr ) ) {
209                                expr = memberExpr->get_aggregate();
210                        } else if ( AddressExpr *addressExpr = dynamic_cast< AddressExpr* >( expr ) ) {
211                                expr = addressExpr->get_arg();
212                        } else if ( UntypedExpr *untypedExpr = dynamic_cast< UntypedExpr* >( expr ) ) {
213                                // look for compiler-inserted dereference operator
214                                NameExpr *fn = dynamic_cast< NameExpr* >( untypedExpr->get_function() );
215                                if ( ! fn || fn->get_name() != std::string("*?") ) return 0;
216                                expr = *untypedExpr->begin_args();
217                        } else if ( CommaExpr *commaExpr = dynamic_cast< CommaExpr* >( expr ) ) {
218                                // copy constructors insert comma exprs, look at second argument which contains the variable
219                                expr = commaExpr->get_arg2();
220                                continue;
221                        } else if ( ConditionalExpr * condExpr = dynamic_cast< ConditionalExpr * >( expr ) ) {
222                                int lvl1;
223                                int lvl2;
224                                VariableExpr * var1 = getBaseVar( condExpr->get_arg2(), &lvl1 );
225                                VariableExpr * var2 = getBaseVar( condExpr->get_arg3(), &lvl2 );
226                                if ( lvl1 == lvl2 && var1 && var2 && var1->get_var() == var2->get_var() ) {
227                                        *levels = lvl1;
228                                        return var1;
229                                }
230                                break;
231                        } else break;
232
233                        ++(*levels);
234                }
235
236                return 0;
237        }
238
239        void addToTyVarMap( TypeDecl * tyVar, TyVarMap &tyVarMap ) {
240                tyVarMap[ tyVar->get_name() ] = TypeDecl::Data{ tyVar };
241        }
242
243        void makeTyVarMap( Type *type, TyVarMap &tyVarMap ) {
244                for ( Type::ForallList::const_iterator tyVar = type->get_forall().begin(); tyVar != type->get_forall().end(); ++tyVar ) {
245                        assert( *tyVar );
246                        addToTyVarMap( *tyVar, tyVarMap );
247                }
248                if ( PointerType *pointer = dynamic_cast< PointerType* >( type ) ) {
249                        makeTyVarMap( pointer->get_base(), tyVarMap );
250                }
251        }
252
253        void printTyVarMap( std::ostream &os, const TyVarMap &tyVarMap ) {
254                for ( TyVarMap::const_iterator i = tyVarMap.begin(); i != tyVarMap.end(); ++i ) {
255                        os << i->first << " (" << i->second << ") ";
256                } // for
257                os << std::endl;
258        }
259
260} // namespace GenPoly
261
262// Local Variables: //
263// tab-width: 4 //
264// mode: c++ //
265// compile-command: "make install" //
266// End: //
Note: See TracBrowser for help on using the repository browser.