source: src/ResolvExpr/TypeMap.h @ 0b5d871

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 0b5d871 was 6b0b624, checked in by Peter A. Buhr <pabuhr@…>, 7 years ago

change #ifndef to #pragma once

  • Property mode set to 100644
File size: 7.0 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// ScopedMap.h --
8//
9// Author           : Aaron B. Moss
10// Created On       : Fri Feb 19 13:55:00 2016
11// Last Modified By : Peter A. Buhr
12// Last Modified On : Sat Jul 22 09:37:19 2017
13// Update Count     : 2
14//
15
16#pragma once
17
18#include <map>
19#include <string>
20#include <utility>
21#include <vector>
22
23#include "SynTree/Type.h"
24#include "SynTree/Visitor.h"
25
26namespace ResolvExpr {
27
28        /// A map from types to some value; lookup is done by structural decomposition on types.
29        /// The TypeMap stores its values by reference, so stored objects should be kept alive by the caller.
30        /// The scoping mechanism essentially by keeping a list of changes to roll back, then rolling them back
31        /// WARNING: This map is only incompletely and approximately consistent with the resolution rules in Unify.cc;
32        /// it has potential, if extended, to form the basis of a resolver that is more performant than the current
33        /// linear-search-by-unification approach, but is only currently used for finding assignment operators in GenPoly::box.
34        template< typename Value >
35        class TypeMap {
36                /// Map of names to types
37                typedef typename std::map< std::string, Value* > ValueMap;
38                typedef typename ValueMap::iterator ValueMapIterator;
39
40                Value *voidValue;                                     ///< Value for void type
41                Value *basicValue[BasicType::NUMBER_OF_BASIC_TYPES];  ///< Values for basic types
42                Value *pointerValue;                                  ///< Value for all pointer types
43                Value *voidPointerValue;                              ///< Value for void* types
44                Value *functionPointerValue;                          ///< Value for all function pointer types
45                ValueMap structValue;                                 ///< Values for struct types, indexed by name
46                ValueMap unionValue;                                  ///< Values for struct types, indexed by name
47                ValueMap enumValue;                                   ///< Values for struct types, indexed by name
48
49                /// Information needed to roll back one scope change
50                struct Rollback {
51                        /// One scope of pointer rollbacks
52                        typedef std::vector< std::pair< Value **, Value* > > PointerScope;
53                        /// One scope of map rollbacks
54                        typedef std::vector< std::pair< ValueMapIterator, Value* > > MapScope;
55
56                        PointerScope pointers;  ///< Value pointers to roll back to their previous state
57                        MapScope mapNodes;      ///< Value map iterators to roll back to their previous state
58
59                        void addRollback( Value **loc, Value *old ) {
60                                pointers.push_back( std::make_pair( loc, old ) );
61                        }
62
63                        void addRollback( ValueMapIterator loc, Value *old ) {
64                                mapNodes.push_back( std::make_pair( loc, old ) );
65                        }
66                };
67
68                std::vector< Rollback > scopes;  ///< Scope rollback information
69
70                struct Lookup : public Visitor {
71                        Lookup( TypeMap<Value> &typeMap ) : typeMap( typeMap ), found( 0 ), toInsert( 0 ) {}
72
73                        /// Inserts a new value into the map; returns the old value (if set, NULL otherwise).
74                        /// key must be non-null.
75                        Value *insert( Type *key, Value *val ) {
76                                toInsert = val;
77                                key->accept( *this );
78                                return found;
79                        }
80
81                        /// Looks up a value in the map.
82                        /// key must be non-null.
83                        Value *find( Type *key ) {
84                                //toInsert = 0;
85                                key->accept( *this );
86                                return found;
87                        }
88
89                        void findAndReplace( Value *&loc ) {
90                                found = loc;
91                                if ( toInsert ) {
92                                        typeMap.scopes.back().addRollback( &loc, found );
93                                        loc = toInsert;
94                                }
95                        }
96
97                        void findAndReplace( ValueMap &map, const std::string &name ) {
98                                ValueMapIterator loc = map.find( name );
99                                if ( loc != map.end() ) {
100                                        found = loc->second;
101                                        if ( toInsert ) {
102                                                typeMap.scopes.back().addRollback( loc, found );
103                                                loc->second = toInsert;
104                                        }
105                                } else if ( toInsert ) {
106                                        loc = map.insert( loc, std::make_pair( name, toInsert ) );
107                                        typeMap.scopes.back().addRollback( loc, found );
108                                }
109                        }
110
111                        virtual void visit( __attribute__((unused)) VoidType *voidType ) {
112                                findAndReplace( typeMap.voidValue );
113                        }
114
115                        virtual void visit( BasicType *basicType ) {
116                                findAndReplace( typeMap.basicValue[basicType->get_kind()] );
117                        }
118
119                        virtual void visit( PointerType *pointerType ) {
120                                // NOTE This is one of the places where the apporoximation of the resolver is (deliberately) poor;
121                                // A better version would likely not equate all pointer types to a match.
122                                if ( dynamic_cast< FunctionType* >( pointerType->get_base() ) ) {
123                                        findAndReplace( typeMap.functionPointerValue );
124                                } else if ( dynamic_cast< VoidType* >( pointerType->get_base() ) ) {
125                                        findAndReplace( typeMap.voidPointerValue );
126                                } else {
127                                        findAndReplace( typeMap.pointerValue );
128                                }
129                        }
130
131                        virtual void visit( ArrayType *arrayType ) {
132                                if ( dynamic_cast< FunctionType* >( arrayType->get_base() ) ) {
133                                        findAndReplace( typeMap.functionPointerValue );
134                                } else {
135                                        findAndReplace( typeMap.pointerValue );
136                                }
137                        }
138
139                        virtual void visit( __attribute__((unused)) FunctionType *functionType ) {
140                                findAndReplace( typeMap.functionPointerValue );
141                        }
142
143                        virtual void visit( StructInstType *structType ) {
144                                findAndReplace( typeMap.structValue, structType->get_name() );
145                        }
146
147                        virtual void visit( UnionInstType *unionType ) {
148                                findAndReplace( typeMap.unionValue, unionType->get_name() );
149                        }
150
151                        virtual void visit( EnumInstType *enumType ) {
152                                findAndReplace( typeMap.enumValue, enumType->get_name() );
153                        }
154
155                        TypeMap<Value> &typeMap;  ///< map storage
156                        Value *found;             ///< Value found (NULL if none yet)
157                        Value *toInsert;          ///< Value to insert (NULL if a lookup)
158                };  // struct Lookup
159                friend struct Lookup;
160
161        public:
162                /// Starts a new scope
163                void beginScope() {
164                        Rollback scope;
165                        scopes.push_back(scope);
166                }
167
168                /// Ends a scope; rolls back any changes made during that scope
169                void endScope() {
170                        Rollback &scope = scopes.back();
171                        /// Roll back pointer changes
172                        for (unsigned i = 0; i < scope.pointers.size(); ++i) {
173                                *scope.pointers[i].first = scope.pointers[i].second;
174                        }
175                        /// Roll back map changes
176                        for (unsigned i = 0; i < scope.mapNodes.size(); ++i) {
177                                scope.mapNodes[i].first->second = scope.mapNodes[i].second;
178                        }
179                        scopes.pop_back();
180                }
181
182                TypeMap() : voidValue( 0 ), pointerValue( 0 ), voidPointerValue( 0 ), functionPointerValue( 0 ), structValue(), unionValue(), enumValue(), scopes() {
183                        beginScope();
184                        for (int i = 0; i < BasicType::NUMBER_OF_BASIC_TYPES; ++i) { basicValue[i] = 0; }
185                }
186
187                /// Inserts a new value into the map; returns the old value (if set, NULL otherwise).
188                /// key, val must be non-null.
189                Value *insert( Type *key, Value *val ) {
190                        Lookup searcher( *this );
191                        return searcher.insert( key, val );
192                }
193
194                /// Looks up a value in the map.
195                /// key must be non-null
196                Value *find( Type *key ) {
197                        Lookup searcher( *this );
198                        return searcher.find( key );
199                }
200
201        }; // class TypeMap
202
203}  // namespace ResolvExpr
204
205// Local Variables: //
206// tab-width: 4 //
207// mode: c++ //
208// compile-command: "make install" //
209// End: //
Note: See TracBrowser for help on using the repository browser.