source: src/AST/TypeSubstitution.hpp @ 675d816

ADTarm-ehast-experimentalcleanup-dtorsenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprpthread-emulationqualifiedEnum
Last change on this file since 675d816 was acd80b4, checked in by Thierry Delisle <tdelisle@…>, 5 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.