source: src/ResolvExpr/RenameVars.cc @ b982fb2

ADTarm-ehast-experimentalenumforall-pointer-decayjacob/cs343-translationnew-ast-unique-exprpthread-emulationqualifiedEnum
Last change on this file since b982fb2 was 4e13e2a, checked in by Thierry Delisle <tdelisle@…>, 5 years ago

Added setting of result in Comma expression.
Added asserts in candidate finder to catch null pointers earlier.
ForAll? substituter now properly uses ShallowCopy?.
Added missing makefile.in

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