source: src/ResolvExpr/RenameVars.cc@ 417117e

ADT arm-eh ast-experimental enum forall-pointer-decay jacob/cs343-translation new-ast new-ast-unique-expr pthread-emulation qualifiedEnum
Last change on this file since 417117e was e0e9a0b, checked in by Aaron Moss <a3moss@…>, 6 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.