source: src/ResolvExpr/RenameVars.cc @ e0e9a0b

arm-ehenumforall-pointer-decayjacob/cs343-translationnew-astnew-ast-unique-exprpthread-emulationqualifiedEnum
Last change on this file since e0e9a0b was e0e9a0b, checked in by Aaron Moss <a3moss@…>, 4 years ago

Somewhat deeper clone for types with forall qualifiers.

  • Property mode set to 100644
File size: 5.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// RenameVars.cc --
8//
9// Author           : Richard C. Bilson
10// Created On       : Sun May 17 12:05:18 2015
11// Last Modified By : Andrew Beach
12// Last Modified On : Thr Jun 20 17:39:00 2019
13// Update Count     : 8
14//
15
16#include <ext/alloc_traits.h>      // for __alloc_traits<>::value_type
17#include <memory>                  // for allocator_traits<>::value_type
18#include <sstream>                 // for operator<<, basic_ostream, ostring...
19#include <utility>                 // for pair
20
21#include "AST/ForallSubstitutionTable.hpp"
22#include "AST/Pass.hpp"
23#include "AST/Type.hpp"
24#include "Common/PassVisitor.h"
25#include "Common/ScopedMap.h"
26#include "Common/SemanticError.h"  // for SemanticError
27#include "RenameVars.h"
28#include "SynTree/Declaration.h"   // for DeclarationWithType, TypeDecl, Dec...
29#include "SynTree/Expression.h"    // for Expression
30#include "SynTree/Type.h"          // for Type, TypeInstType, TraitInstType
31#include "SynTree/Visitor.h"       // for acceptAll, maybeAccept
32
33namespace ResolvExpr {
34
35namespace {
36        class RenamingData {
37                int level = 0;
38                int resetCount = 0;
39                ScopedMap< std::string, std::string > nameMap;
40        public:
41                ast::ForallSubstitutionTable subs;
42
43                void reset() {
44                        level = 0;
45                        ++resetCount;
46                }
47
48                void rename( TypeInstType * type ) {
49                        auto it = nameMap.find( type->name );
50                        if ( it != nameMap.end() ) {
51                                type->name = it->second;
52                        }
53                }
54
55                void openLevel( Type * type ) {
56                        if ( ! type->forall.empty() ) {
57                                nameMap.beginScope();
58                                // renames all "forall" type names to `_${level}_${name}'
59                                for ( auto td : type->forall ) {
60                                        std::ostringstream output;
61                                        output << "_" << resetCount << "_" << level << "_" << td->name;
62                                        std::string newname( output.str() );
63                                        nameMap[ td->get_name() ] = newname;
64                                        td->name = newname;
65                                        // ditto for assertion names, the next level in
66                                        level++;
67                                }
68                        }
69                }
70
71                void closeLevel( Type * type ) {
72                        if ( !type->forall.empty() ) {
73                                nameMap.endScope();
74                        }
75                }
76
77                const ast::TypeInstType * rename( const ast::TypeInstType * type ) {
78                        // re-linking of base type handled by WithForallSubstitutor
79
80                        // rename
81                        auto it = nameMap.find( type->name );
82                        if ( it != nameMap.end() ) {
83                                // unconditionally mutate because map will *always* have different name,
84                                // if this mutates, will *always* have been mutated by ForallSubstitutor above
85                                ast::TypeInstType * mut = ast::mutate( type );
86                                mut->name = it->second;
87                    type = mut;
88                        }
89
90                        return type;
91                }
92
93                template<typename NodeT>
94                const NodeT * openLevel( const NodeT * type ) {
95                        if ( type->forall.empty() ) return type;
96                       
97                        nameMap.beginScope();
98
99                        // Load new names from this forall clause and perform renaming.
100                        NodeT * mutType = ast::mutate( type );
101                        assert( type == mutType && "mutated type must be unique from ForallSubstitutor" );
102                        for ( ast::ptr< ast::TypeDecl > & td : mutType->forall ) {
103                                std::ostringstream output;
104                                output << "_" << resetCount << "_" << level << "_" << td->name;
105                                std::string newname =  output.str();
106                                nameMap[ td->name ] = newname;
107                                ++level;
108
109                                ast::TypeDecl * mutDecl = ast::mutate( td.get() );
110                                assert( td == mutDecl && "mutated decl must be unique from ForallSubstitutor" );
111                                mutDecl->name = newname;
112                                // assertion above means `td = mutDecl;` is unnecessary
113                        }
114                        // assertion above means `type = mutType;` is unnecessary
115
116                        return type;
117                }
118
119                void closeLevel( const ast::ParameterizedType * type ) {
120                        if ( type->forall.empty() ) return;
121                       
122                        nameMap.endScope();
123                }
124        };
125
126        // Global State:
127        RenamingData renaming;
128
129        struct RenameVars_old {
130                void previsit( TypeInstType * instType ) {
131                        renaming.openLevel( (Type*)instType );
132                        renaming.rename( instType );
133                }
134                void previsit( Type * type ) {
135                        renaming.openLevel( type );
136                }
137                void postvisit( Type * type ) {
138                        renaming.closeLevel( type );
139                }
140        };
141       
142        struct RenameVars_new /*: public ast::WithForallSubstitutor*/ {
143                #warning when old RenameVars goes away, replace hack below with global pass inheriting from WithForallSubstitutor
144                ast::ForallSubstitutionTable & subs = renaming.subs;
145
146                const ast::FunctionType * previsit( const ast::FunctionType * type ) {
147                        return renaming.openLevel( type );
148                }
149                const ast::StructInstType * previsit( const ast::StructInstType * type ) {
150                        return renaming.openLevel( type );
151                }
152                const ast::UnionInstType * previsit( const ast::UnionInstType * type ) {
153                        return renaming.openLevel( type );
154                }
155                const ast::TraitInstType * previsit( const ast::TraitInstType * type ) {
156                        return renaming.openLevel( type );
157                }
158                const ast::TypeInstType * previsit( const ast::TypeInstType * type ) {
159                        return renaming.rename( renaming.openLevel( type ) );
160                }
161                void postvisit( const ast::ParameterizedType * type ) {
162                        renaming.closeLevel( type );
163                }
164        };
165
166} // namespace
167
168void renameTyVars( Type * t ) {
169        PassVisitor<RenameVars_old> renamer;
170        t->accept( renamer );
171}
172
173const ast::Type * renameTyVars( const ast::Type * t ) {
174        ast::Pass<RenameVars_new> renamer;
175        return t->accept( renamer );
176}
177
178void resetTyVarRenaming() {
179        renaming.reset();
180}
181
182} // namespace ResolvExpr
183
184// Local Variables: //
185// tab-width: 4 //
186// mode: c++ //
187// compile-command: "make install" //
188// End: //
Note: See TracBrowser for help on using the repository browser.