source: src/AST/TypeSubstitution.hpp@ 246c245

ADT arm-eh ast-experimental cleanup-dtors enum forall-pointer-decay jacob/cs343-translation jenkins-sandbox new-ast new-ast-unique-expr pthread-emulation qualifiedEnum
Last change on this file since 246c245 was acd80b4, checked in by Thierry Delisle <tdelisle@…>, 6 years ago

Fixed several compilation errors

  • Property mode set to 100644
File size: 6.9 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// TypeSubstitution.h --
8//
9// Author : Richard C. Bilson
10// Created On : Mon May 18 07:44:20 2015
11// Last Modified By : Peter A. Buhr
12// Last Modified On : Tue Apr 30 22:52:47 2019
13// Update Count : 9
14//
15
16#pragma once
17
18#include <cassert> // for assert
19#include <list> // for list<>::iterator, _List_iterator
20#include <unordered_map>
21#include <unordered_set>
22#include <string> // for string, operator!=
23#include <utility> // for pair
24
25#include "Fwd.hpp" // for UniqueId
26#include "ParseNode.hpp"
27#include "Type.hpp" // for ptr<Type>
28#include "Common/SemanticError.h" // for SemanticError
29#include "Visitor.hpp"
30#include "Decl.hpp"
31#include "Expr.hpp"
32
33namespace ast {
34
35class TypeSubstitution : public Node {
36 public:
37 TypeSubstitution();
38 template< typename FormalIterator, typename ActualIterator >
39 TypeSubstitution( FormalIterator formalBegin, FormalIterator formalEnd, ActualIterator actualBegin );
40 TypeSubstitution( const TypeSubstitution &other );
41 virtual ~TypeSubstitution();
42
43 TypeSubstitution &operator=( const TypeSubstitution &other );
44
45 template< typename SynTreeClass > int apply( SynTreeClass *&input ) const;
46 template< typename SynTreeClass > int applyFree( SynTreeClass *&input ) const;
47
48 void add( std::string formalType, const Type *actualType );
49 void add( const TypeSubstitution &other );
50 void remove( std::string formalType );
51 const Type *lookup( std::string formalType ) const;
52 bool empty() const;
53
54 template< typename FormalIterator, typename ActualIterator >
55 void add( FormalIterator formalBegin, FormalIterator formalEnd, ActualIterator actualBegin );
56
57 /// create a new TypeSubstitution using bindings from env containing all of the type variables in expr
58 static TypeSubstitution * newFromExpr( const Expr * expr, const TypeSubstitution * env );
59
60 void normalize();
61
62 const TypeSubstitution * accept( Visitor & v ) const override { return v.visit( this ); }
63
64 TypeSubstitution * clone() const override { return new TypeSubstitution( *this ); }
65
66 private:
67
68 // Mutator that performs the substitution
69 struct Substituter;
70
71 // TODO: worry about traversing into a forall-qualified function type or type decl with assertions
72
73 void initialize( const TypeSubstitution &src, TypeSubstitution &dest );
74
75 template<typename pass_type>
76 friend class Pass;
77
78 typedef std::unordered_map< std::string, ptr<Type> > TypeEnvType;
79 typedef std::unordered_map< std::string, ptr<Expr> > VarEnvType;
80 TypeEnvType typeEnv;
81 VarEnvType varEnv;
82
83 public:
84 // has to come after declaration of typeEnv
85 auto begin() -> decltype( typeEnv.begin() ) { return typeEnv.begin(); }
86 auto end() -> decltype( typeEnv. end() ) { return typeEnv. end(); }
87 auto begin() const -> decltype( typeEnv.begin() ) { return typeEnv.begin(); }
88 auto end() const -> decltype( typeEnv. end() ) { return typeEnv. end(); }
89};
90
91template< typename FormalIterator, typename ActualIterator >
92void TypeSubstitution::add( FormalIterator formalBegin, FormalIterator formalEnd, ActualIterator actualBegin ) {
93 // FormalIterator points to a TypeDecl
94 // ActualIterator points to a Type
95 FormalIterator formalIt = formalBegin;
96 ActualIterator actualIt = actualBegin;
97 for ( ; formalIt != formalEnd; ++formalIt, ++actualIt ) {
98 if ( const TypeDecl *formal = formalIt->template as<TypeDecl>() ) {
99 if ( const TypeExpr *actual = actualIt->template as<TypeExpr>() ) {
100 if ( formal->name != "" ) {
101 typeEnv[ formal->name ] = actual->type;
102 } // if
103 } else {
104 SemanticError( formal, toString( "Attempt to provide non-type parameter: ", toString( *actualIt ).c_str(), " for type parameter " ) );
105 } // if
106 } else {
107 // TODO: type check the formal and actual parameters
108 if ( (*formalIt)->name != "" ) {
109 varEnv[ (*formalIt)->name ] = *actualIt;
110 } // if
111 } // if
112 } // for
113}
114
115template< typename FormalIterator, typename ActualIterator >
116TypeSubstitution::TypeSubstitution( FormalIterator formalBegin, FormalIterator formalEnd, ActualIterator actualBegin ) {
117 add( formalBegin, formalEnd, actualBegin );
118}
119
120} // namespace ast
121
122// include needs to happen after TypeSubstitution is defined so that both TypeSubstitution and
123// PassVisitor are defined before PassVisitor implementation accesses TypeSubstitution internals.
124#include "Pass.hpp"
125
126namespace ast {
127
128// definitition must happen after PassVisitor is included so that WithGuards can be used
129struct TypeSubstitution::Substituter : public WithGuards, public WithVisitorRef<Substituter> {
130
131 Substituter( const TypeSubstitution & sub, bool freeOnly ) : sub( sub ), freeOnly( freeOnly ) {}
132
133#if TIME_TO_CONVERT_PASSES
134
135 Type * postmutate( TypeInstType * aggregateUseType );
136 Expression * postmutate( NameExpr * nameExpr );
137
138 /// Records type variable bindings from forall-statements
139 void premutate( Type * type );
140 /// Records type variable bindings from forall-statements and instantiations of generic types
141 template< typename TypeClass > void handleAggregateType( TypeClass * type );
142
143 void premutate( StructInstType * aggregateUseType );
144 void premutate( UnionInstType * aggregateUseType );
145
146#endif
147
148 const TypeSubstitution & sub;
149 int subCount = 0;
150 bool freeOnly;
151 typedef std::unordered_set< std::string > BoundVarsType;
152 BoundVarsType boundVars;
153
154};
155
156template< typename SynTreeClass >
157int TypeSubstitution::apply( SynTreeClass *&input ) const {
158 assert( input );
159 Pass<Substituter> sub( *this, false );
160 input = dynamic_cast< SynTreeClass * >( input->acceptMutator( sub ) );
161 assert( input );
162/// std::cerr << "substitution result is: ";
163/// newType->print( std::cerr );
164/// std::cerr << std::endl;
165 return sub.pass.subCount;
166}
167
168template< typename SynTreeClass >
169int TypeSubstitution::applyFree( SynTreeClass *&input ) const {
170 assert( input );
171 Pass<Substituter> sub( *this, true );
172 input = dynamic_cast< SynTreeClass * >( input->acceptMutator( sub ) );
173 assert( input );
174/// std::cerr << "substitution result is: ";
175/// newType->print( std::cerr );
176/// std::cerr << std::endl;
177 return sub.pass.subCount;
178}
179
180/// Instantiate each member of the context given the actual parameters specified, and store the
181/// instantiations for use by the indexer
182template< typename FormalIterator, typename ActualIterator, typename MemberIterator, typename OutputIterator >
183void applySubstitution( FormalIterator formalBegin, FormalIterator formalEnd, ActualIterator actual, MemberIterator memberBegin, MemberIterator memberEnd, OutputIterator out ) {
184 TypeSubstitution sub = TypeSubstitution( formalBegin, formalEnd, actual );
185 for ( auto i = memberBegin; i != memberEnd; ++i ) {
186 sub.apply( *i );
187 *out++ = *i;
188 } // for
189}
190
191} // namespace ast
192
193// Local Variables: //
194// tab-width: 4 //
195// mode: c++ //
196// compile-command: "make install" //
197// End: //
Note: See TracBrowser for help on using the repository browser.