source: src/ResolvExpr/RenameVars.cc@ 033ff37

ADT arm-eh ast-experimental enum forall-pointer-decay jacob/cs343-translation jenkins-sandbox new-ast new-ast-unique-expr pthread-emulation qualifiedEnum
Last change on this file since 033ff37 was f5edcb4, checked in by Andrew Beach <ajbeach@…>, 6 years ago

RenameVars needed a rather significant rework for the new AST.

  • Property mode set to 100644
File size: 4.7 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/Pass.hpp"
22#include "AST/Type.hpp"
23#include "Common/PassVisitor.h"
24#include "Common/ScopedMap.h"
25#include "Common/SemanticError.h" // for SemanticError
26#include "RenameVars.h"
27#include "SynTree/Declaration.h" // for DeclarationWithType, TypeDecl, Dec...
28#include "SynTree/Expression.h" // for Expression
29#include "SynTree/Type.h" // for Type, TypeInstType, TraitInstType
30#include "SynTree/Visitor.h" // for acceptAll, maybeAccept
31
32namespace ResolvExpr {
33
34namespace {
35 class RenamingData {
36 int level = 0;
37 int resetCount = 0;
38 ScopedMap< std::string, std::string > nameMap;
39
40 public:
41 void reset() {
42 level = 0;
43 ++resetCount;
44 }
45
46 using mapConstIterator = ScopedMap< std::string, std::string >::const_iterator;
47
48 void rename( TypeInstType * type ) {
49 mapConstIterator 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 // acceptAll( td->assertions, *this );
68 } // for
69 } // if
70 }
71
72 void closeLevel( Type * type ) {
73 if ( !type->forall.empty() ) {
74 nameMap.endScope();
75 }
76 }
77
78 const ast::TypeInstType * rename( const ast::TypeInstType * type ) {
79 mapConstIterator it = nameMap.find( type->name );
80 if ( it != nameMap.end() ) {
81 ast::TypeInstType * mutType = ast::mutate( type );
82 mutType->name = it->second;
83 type = mutType;
84 }
85 return type;
86 }
87
88 template<typename NodeT>
89 const NodeT * openLevel( const NodeT * type ) {
90 if ( !type->forall.empty() ) {
91 nameMap.beginScope();
92 // Load new names from this forall clause and perform renaming.
93 NodeT * mutType = ast::mutate( type );
94 for ( ast::ptr< ast::TypeDecl > & td : mutType->forall ) {
95 std::ostringstream output;
96 output << "_" << resetCount << "_" << level << "_" << td->name;
97 std::string newname( output.str() );
98 nameMap[ td->name ] = newname;
99 ++level;
100
101 ast::TypeDecl * decl = ast::mutate( td.get() );
102 decl->name = newname;
103 td = decl;
104 }
105 }
106 return type;
107 }
108
109 template<typename NodeT>
110 const NodeT * closeLevel( const NodeT * type ) {
111 if ( !type->forall.empty() ) {
112 nameMap.endScope();
113 }
114 return type;
115 }
116 };
117
118 // Global State:
119 RenamingData renaming;
120
121 struct RenameVars {
122 void previsit( TypeInstType * instType ) {
123 renaming.openLevel( (Type*)instType );
124 renaming.rename( instType );
125 }
126 void previsit( Type * type ) {
127 renaming.openLevel( type );
128 }
129 void postvisit( Type * type ) {
130 renaming.closeLevel( type );
131 }
132
133 const ast::FunctionType * previsit( const ast::FunctionType * type ) {
134 return renaming.openLevel( type );
135 }
136 const ast::StructInstType * previsit( const ast::StructInstType * type ) {
137 return renaming.openLevel( type );
138 }
139 const ast::UnionInstType * previsit( const ast::UnionInstType * type ) {
140 return renaming.openLevel( type );
141 }
142 const ast::TraitInstType * previsit( const ast::TraitInstType * type ) {
143 return renaming.openLevel( type );
144 }
145 const ast::TypeInstType * previsit( const ast::TypeInstType * type ) {
146 return renaming.rename( renaming.openLevel( type ) );
147 }
148 const ast::ParameterizedType * postvisit( const ast::ParameterizedType * type ) {
149 return renaming.closeLevel( type );
150 }
151 };
152
153} // namespace
154
155void renameTyVars( Type * t ) {
156 PassVisitor<RenameVars> renamer;
157 t->accept( renamer );
158}
159
160const ast::Type * renameTyVars( const ast::Type * t ) {
161 ast::Pass<RenameVars> renamer;
162 return t->accept( renamer );
163}
164
165void resetTyVarRenaming() {
166 renaming.reset();
167}
168
169} // namespace ResolvExpr
170
171// Local Variables: //
172// tab-width: 4 //
173// mode: c++ //
174// compile-command: "make install" //
175// End: //
Note: See TracBrowser for help on using the repository browser.