source: src/SynTree/TypeSubstitution.h @ 447c356

ADTaaron-thesisarm-ehast-experimentalcleanup-dtorsdeferred_resndemanglerenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprnew-envno_listpersistent-indexerpthread-emulationqualifiedEnumresolv-newwith_gc
Last change on this file since 447c356 was 447c356, checked in by Rob Schluntz <rschlunt@…>, 7 years ago

Add support for TypeSubstitution? in PassVisitor?

  • Property mode set to 100644
File size: 7.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// 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 : Sat Jul 22 09:52:24 2017
13// Update Count     : 3
14//
15
16#pragma once
17
18#include <cassert>                 // for assert
19#include <iosfwd>                  // for ostream
20#include <list>                    // for list<>::iterator, _List_iterator
21#include <map>                     // for _Rb_tree_iterator, map, map<>::val...
22#include <set>                     // for set
23#include <string>                  // for string, operator!=
24#include <utility>                 // for pair
25
26#include "Common/SemanticError.h"  // for SemanticError
27#include "SynTree/Declaration.h"   // for TypeDecl, Declaration (ptr only)
28#include "SynTree/Expression.h"    // for Expression (ptr only), NameExpr (p...
29#include "SynTree/Mutator.h"       // for Mutator
30#include "SynTree/Type.h"          // for Type, ArrayType (ptr only), BasicT...
31
32class TypeSubstitution : public Mutator {
33        typedef Mutator Parent;
34  public:
35        TypeSubstitution();
36        template< typename FormalIterator, typename ActualIterator >
37        TypeSubstitution( FormalIterator formalBegin, FormalIterator formalEnd, ActualIterator actualBegin );
38        TypeSubstitution( const TypeSubstitution &other );
39        virtual ~TypeSubstitution();
40
41        TypeSubstitution &operator=( const TypeSubstitution &other );
42
43        template< typename SynTreeClass > int apply( SynTreeClass *&input );
44        template< typename SynTreeClass > int applyFree( SynTreeClass *&input );
45
46        void add( std::string formalType, Type *actualType );
47        void add( const TypeSubstitution &other );
48        void remove( std::string formalType );
49        Type *lookup( std::string formalType ) const;
50        bool empty() const;
51
52        template< typename FormalIterator, typename ActualIterator >
53        void add( FormalIterator formalBegin, FormalIterator formalEnd, ActualIterator actualBegin );
54
55        /// this function is unused...
56        template< typename TypeInstListIterator >
57        void extract( TypeInstListIterator begin, TypeInstListIterator end, TypeSubstitution &result );
58
59        void normalize();
60
61        TypeSubstitution * acceptMutator( Mutator & m ) { return m.mutate( this ); }
62
63        void print( std::ostream &os, Indenter indent = {} ) const;
64        TypeSubstitution *clone() const { return new TypeSubstitution( *this ); }
65  private:
66        virtual Type* mutate(TypeInstType *aggregateUseType);
67        virtual Expression* mutate(NameExpr *nameExpr);
68
69        /// Records type variable bindings from forall-statements
70        template< typename TypeClass > Type *handleType( TypeClass *type );
71        /// Records type variable bindings from forall-statements and instantiations of generic types
72        template< typename TypeClass > Type *handleAggregateType( TypeClass *type );
73
74        virtual Type* mutate(VoidType *basicType);
75        virtual Type* mutate(BasicType *basicType);
76        virtual Type* mutate(PointerType *pointerType);
77        virtual Type* mutate(ArrayType *arrayType);
78        virtual Type* mutate(FunctionType *functionType);
79        virtual Type* mutate(StructInstType *aggregateUseType);
80        virtual Type* mutate(UnionInstType *aggregateUseType);
81        virtual Type* mutate(EnumInstType *aggregateUseType);
82        virtual Type* mutate(TraitInstType *aggregateUseType);
83        virtual Type* mutate(TupleType *tupleType);
84        virtual Type* mutate(VarArgsType *varArgsType);
85        virtual Type* mutate(ZeroType *zeroType);
86        virtual Type* mutate(OneType *oneType);
87
88        // TODO: worry about traversing into a forall-qualified function type or type decl with assertions
89
90        void initialize( const TypeSubstitution &src, TypeSubstitution &dest );
91
92        friend class Mutator;
93
94        template<typename pass_type>
95        friend class PassVisitor;
96
97        typedef std::map< std::string, Type* > TypeEnvType;
98        typedef std::map< std::string, Expression* > VarEnvType;
99        typedef std::set< std::string > BoundVarsType;
100        TypeEnvType typeEnv;
101        VarEnvType varEnv;
102        BoundVarsType boundVars;
103        int subCount;
104        bool freeOnly;
105};
106
107template< typename FormalIterator, typename ActualIterator >
108void TypeSubstitution::add( FormalIterator formalBegin, FormalIterator formalEnd, ActualIterator actualBegin ) {
109        // FormalIterator points to a TypeDecl
110        // ActualIterator points to a Type
111        FormalIterator formalIt = formalBegin;
112        ActualIterator actualIt = actualBegin;
113        for ( ; formalIt != formalEnd; ++formalIt, ++actualIt ) {
114                if ( TypeDecl *formal = dynamic_cast< TypeDecl* >( *formalIt ) ) {
115                        if ( TypeExpr *actual = dynamic_cast< TypeExpr* >( *actualIt ) ) {
116                                if ( formal->get_name() != "" ) {
117                                        TypeEnvType::iterator i = typeEnv.find( formal->get_name() );
118                                        if ( i != typeEnv.end() ) {
119                                                delete i->second;
120                                        } // if
121                                        typeEnv[ formal->get_name() ] = actual->get_type()->clone();
122                                } // if
123                        } else {
124                                throw SemanticError( toString( "Attempt to provide non-type parameter: ", toString( *actualIt ).c_str(), " for type parameter " ), formal );
125                        } // if
126                } else {
127                        // TODO: type check the formal and actual parameters
128                        if ( (*formalIt)->get_name() != "" ) {
129                                varEnv[ (*formalIt)->get_name() ] = (*actualIt)->clone();
130                        } // if
131                } // if
132        } // for
133}
134
135template< typename FormalIterator, typename ActualIterator >
136TypeSubstitution::TypeSubstitution( FormalIterator formalBegin, FormalIterator formalEnd, ActualIterator actualBegin )
137{
138        add( formalBegin, formalEnd, actualBegin );
139}
140
141template< typename SynTreeClass >
142int TypeSubstitution::apply( SynTreeClass *&input ) {
143        assert( input );
144        subCount = 0;
145        freeOnly = false;
146        input = dynamic_cast< SynTreeClass *>( input->acceptMutator( *this ) );
147        assert( input );
148///     std::cout << "substitution result is: ";
149///     newType->print( std::cout );
150///     std::cout << std::endl;
151        return subCount;
152}
153
154template< typename SynTreeClass >
155int TypeSubstitution::applyFree( SynTreeClass *&input ) {
156        assert( input );
157        subCount = 0;
158        freeOnly = true;
159        input = dynamic_cast< SynTreeClass *>( input->acceptMutator( *this ) );
160        assert( input );
161///     std::cout << "substitution result is: ";
162///     newType->print( std::cout );
163///     std::cout << std::endl;
164        return subCount;
165}
166
167template< typename TypeInstListIterator >
168void TypeSubstitution::extract( TypeInstListIterator begin, TypeInstListIterator end, TypeSubstitution &result ) {
169        // xxx - this function doesn't extract varEnv - is this intentional?
170        while ( begin != end ) {
171                TypeEnvType::iterator cur = typeEnv.find( (*begin++)->get_name() );
172                if ( cur != typeEnv.end() ) {
173                        result.typeEnv[ cur->first ] = cur->second;
174                        typeEnv.erase( cur );
175                } // if
176        } // while
177}
178
179/// Instantiate each member of the context given the actual parameters specified, and store the
180/// instantiations for use by the indexer
181template< typename FormalIterator, typename ActualIterator, typename MemberIterator, typename OutputIterator >
182void applySubstitution( FormalIterator formalBegin, FormalIterator formalEnd, ActualIterator actual, MemberIterator memberBegin, MemberIterator memberEnd, OutputIterator out ) {
183        TypeSubstitution sub = TypeSubstitution( formalBegin, formalEnd, actual );
184        for ( auto i = memberBegin; i != memberEnd; ++i ) {
185                sub.apply( *i );
186                *out++ = *i;
187        } // for
188}
189
190std::ostream & operator<<( std::ostream & out, const TypeSubstitution & sub );
191
192// Local Variables: //
193// tab-width: 4 //
194// mode: c++ //
195// compile-command: "make install" //
196// End: //
Note: See TracBrowser for help on using the repository browser.