source: src/GenPoly/GenPoly.cc @ 8f60f0b

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 8f60f0b was 1aa4b71, checked in by Rob Schluntz <rschlunt@…>, 8 years ago

added case for ConditionalExpr? in getBaseVar

  • Property mode set to 100644
File size: 9.3 KB
RevLine 
[51587aa]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//
[540de412]7// GenPoly.cc --
[51587aa]8//
9// Author           : Richard C. Bilson
10// Created On       : Mon May 18 07:44:20 2015
[ca35c51]11// Last Modified By : Peter A. Buhr
12// Last Modified On : Wed Jun 29 21:45:53 2016
13// Update Count     : 14
[51587aa]14//
[51b7345]15
16#include "GenPoly.h"
[ffad73a]17
18#include "SynTree/Expression.h"
[51b7345]19#include "SynTree/Type.h"
20
[b1a6d6b]21#include <iostream>
22using namespace std;
[51b7345]23
24namespace GenPoly {
[ffad73a]25        namespace {
[0f889a77]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
[ffad73a]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                }
[3bb195cb]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                }
[c2ad3c9]55        }
[83de11e]56
[c2ad3c9]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;
[e24955a]62                }
[c2ad3c9]63                return type;
[ffad73a]64        }
[0f889a77]65
66        Type *isPolyType( Type *type, const TypeSubstitution *env ) {
[e24955a]67                type = replaceTypeInst( type, env );
[83de11e]68
[ca35c51]69                if ( dynamic_cast< TypeInstType * >( type ) ) {
[0f889a77]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        }
[540de412]78
[ffad73a]79        Type *isPolyType( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env ) {
[e24955a]80                type = replaceTypeInst( type, env );
[83de11e]81
[e56cfdb0]82                if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( type ) ) {
[ffad73a]83                        if ( tyVars.find( typeInst->get_name() ) != tyVars.end() ) {
84                                return type;
[0f889a77]85                        }
[ffad73a]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;
[01aeade]92        }
[b1a6d6b]93
[33a7b6d]94        ReferenceToType *isDynType( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env ) {
[3bb195cb]95                type = replaceTypeInst( type, env );
96
97                if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( type ) ) {
98                        auto var = tyVars.find( typeInst->get_name() );
[2c57025]99                        if ( var != tyVars.end() && var->second.isComplete ) {
[33a7b6d]100                                return typeInst;
[3bb195cb]101                        }
102                } else if ( StructInstType *structType = dynamic_cast< StructInstType* >( type ) ) {
[33a7b6d]103                        if ( hasDynParams( structType->get_parameters(), tyVars, env ) ) return structType;
[3bb195cb]104                } else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( type ) ) {
[33a7b6d]105                        if ( hasDynParams( unionType->get_parameters(), tyVars, env ) ) return unionType;
[3bb195cb]106                }
107                return 0;
108        }
109
110        ReferenceToType *isDynRet( FunctionType *function, const TyVarMap &forallTypes ) {
111                if ( function->get_returnVals().empty() ) return 0;
[8c49c0e]112
[3bb195cb]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
[2c57025]119                TyVarMap forallTypes( TypeDecl::Data{} );
[3bb195cb]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;
[8c49c0e]129
[3bb195cb]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
[0f889a77]139        Type *isPolyPtr( Type *type, const TypeSubstitution *env ) {
[e24955a]140                type = replaceTypeInst( type, env );
[83de11e]141
[0f889a77]142                if ( PointerType *ptr = dynamic_cast< PointerType *>( type ) ) {
143                        return isPolyType( ptr->get_base(), env );
[e24955a]144                }
[0f889a77]145                return 0;
146        }
[540de412]147
[ffad73a]148        Type *isPolyPtr( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env ) {
[e24955a]149                type = replaceTypeInst( type, env );
[83de11e]150
[ffad73a]151                if ( PointerType *ptr = dynamic_cast< PointerType *>( type ) ) {
152                        return isPolyType( ptr->get_base(), tyVars, env );
[e24955a]153                }
[ffad73a]154                return 0;
[bdf1954]155        }
156
[8488c715]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 ) {
[e24955a]163                        type = replaceTypeInst( type, env );
[83de11e]164
[8488c715]165                        if ( PointerType *ptr = dynamic_cast< PointerType *>( type ) ) {
166                                type = ptr->get_base();
167                                ++(*levels);
168                        } else break;
[05d47278]169                }
170
171                return isPolyType( type, env );
172        }
[540de412]173
[8488c715]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 ) {
[e24955a]180                        type = replaceTypeInst( type, env );
[83de11e]181
[8488c715]182                        if ( PointerType *ptr = dynamic_cast< PointerType *>( type ) ) {
183                                type = ptr->get_base();
184                                ++(*levels);
185                        } else break;
[05d47278]186                }
187
188                return isPolyType( type, tyVars, env );
189        }
190
[7754cde]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
[8488c715]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;
[d9f1b2d]208                        } else if ( MemberExpr *memberExpr = dynamic_cast< MemberExpr* >( expr ) ) {
209                                expr = memberExpr->get_aggregate();
[8488c715]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();
[540de412]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;
[1aa4b71]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;
[8488c715]231                        } else break;
232
233                        ++(*levels);
234                }
235
236                return 0;
[05d47278]237        }
238
[2c57025]239        void addToTyVarMap( TypeDecl * tyVar, TyVarMap &tyVarMap ) {
240                tyVarMap[ tyVar->get_name() ] = TypeDecl::Data{ tyVar };
241        }
242
[aadc9a4]243        void makeTyVarMap( Type *type, TyVarMap &tyVarMap ) {
[8c49c0e]244                for ( Type::ForallList::const_iterator tyVar = type->get_forall().begin(); tyVar != type->get_forall().end(); ++tyVar ) {
[aadc9a4]245                        assert( *tyVar );
[2c57025]246                        addToTyVarMap( *tyVar, tyVarMap );
[aadc9a4]247                }
248                if ( PointerType *pointer = dynamic_cast< PointerType* >( type ) ) {
249                        makeTyVarMap( pointer->get_base(), tyVarMap );
250                }
251        }
[540de412]252
[01aeade]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        }
[ffad73a]259
[51b7345]260} // namespace GenPoly
[01aeade]261
[51587aa]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.