// // Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo // // The contents of this file are covered under the licence agreement in the // file "LICENCE" distributed with Cforall. // // TypeSubstitution.cc -- // // Author : Richard C. Bilson // Created On : Mon May 18 07:44:20 2015 // Last Modified By : Rob Schluntz // Last Modified On : Tue Apr 26 11:15:29 2016 // Update Count : 3 // #include "Type.h" #include "TypeSubstitution.h" TypeSubstitution::TypeSubstitution() { } TypeSubstitution::TypeSubstitution( const TypeSubstitution &other ) { initialize( other, *this ); } TypeSubstitution::~TypeSubstitution() { for ( TypeEnvType::iterator i = typeEnv.begin(); i != typeEnv.end(); ++i ) { delete( i->second ); } for ( VarEnvType::iterator i = varEnv.begin(); i != varEnv.end(); ++i ) { delete( i->second ); } } TypeSubstitution &TypeSubstitution::operator=( const TypeSubstitution &other ) { if ( this == &other ) return *this; initialize( other, *this ); return *this; } void TypeSubstitution::initialize( const TypeSubstitution &src, TypeSubstitution &dest ) { dest.typeEnv.clear(); dest.varEnv.clear(); dest.add( src ); } void TypeSubstitution::add( const TypeSubstitution &other ) { for ( TypeEnvType::const_iterator i = other.typeEnv.begin(); i != other.typeEnv.end(); ++i ) { typeEnv[ i->first ] = i->second->clone(); } // for for ( VarEnvType::const_iterator i = other.varEnv.begin(); i != other.varEnv.end(); ++i ) { varEnv[ i->first ] = i->second->clone(); } // for } void TypeSubstitution::add( std::string formalType, Type *actualType ) { TypeEnvType::iterator i = typeEnv.find( formalType ); if ( i != typeEnv.end() ) { delete i->second; } // if typeEnv[ formalType ] = actualType->clone(); } void TypeSubstitution::remove( std::string formalType ) { TypeEnvType::iterator i = typeEnv.find( formalType ); if ( i != typeEnv.end() ) { delete i->second; typeEnv.erase( formalType ); } // if } Type *TypeSubstitution::lookup( std::string formalType ) const { TypeEnvType::const_iterator i = typeEnv.find( formalType ); // break on not in substitution set if ( i == typeEnv.end() ) return 0; // attempt to transitively follow TypeInstType links. while ( TypeInstType *actualType = dynamic_cast< TypeInstType* >( i->second ) ) { const std::string& typeName = actualType->get_name(); // break cycles in the transitive follow if ( formalType == typeName ) break; // Look for the type this maps to, returning previous mapping if none-such i = typeEnv.find( typeName ); if ( i == typeEnv.end() ) return actualType; } // return type from substitution set return i->second; #if 0 if ( i == typeEnv.end() ) { return 0; } else { return i->second; } // if #endif } bool TypeSubstitution::empty() const { return typeEnv.empty() && varEnv.empty(); } void TypeSubstitution::normalize() { do { subCount = 0; freeOnly = true; for ( TypeEnvType::iterator i = typeEnv.begin(); i != typeEnv.end(); ++i ) { i->second = i->second->acceptMutator( *this ); } } while ( subCount ); } Type * TypeSubstitution::mutate( TypeInstType *inst ) { BoundVarsType::const_iterator bound = boundVars.find( inst->get_name() ); if ( bound != boundVars.end() ) return inst; TypeEnvType::const_iterator i = typeEnv.find( inst->get_name() ); if ( i == typeEnv.end() ) { return inst; } else { /// std::cout << "found " << inst->get_name() << ", replacing with "; /// i->second->print( std::cout ); /// std::cout << std::endl; subCount++; Type *newtype = i->second->clone(); newtype->get_qualifiers() += inst->get_qualifiers(); delete inst; return newtype; } // if } Expression * TypeSubstitution::mutate( NameExpr *nameExpr ) { VarEnvType::const_iterator i = varEnv.find( nameExpr->get_name() ); if ( i == varEnv.end() ) { return nameExpr; } else { subCount++; delete nameExpr; return i->second->clone(); } // if } template< typename TypeClass > Type *TypeSubstitution::handleType( TypeClass *type ) { BoundVarsType oldBoundVars( boundVars ); // bind type variables from forall-qualifiers if ( freeOnly ) { for ( std::list< TypeDecl* >::const_iterator tyvar = type->get_forall().begin(); tyvar != type->get_forall().end(); ++tyvar ) { boundVars.insert( (*tyvar )->get_name() ); } // for } // if Type *ret = Mutator::mutate( type ); boundVars = oldBoundVars; return ret; } template< typename TypeClass > Type *TypeSubstitution::handleAggregateType( TypeClass *type ) { BoundVarsType oldBoundVars( boundVars ); // bind type variables from forall-qualifiers if ( freeOnly ) { for ( std::list< TypeDecl* >::const_iterator tyvar = type->get_forall().begin(); tyvar != type->get_forall().end(); ++tyvar ) { boundVars.insert( (*tyvar )->get_name() ); } // for } // if // bind type variables from generic type instantiations std::list< TypeDecl* > *baseParameters = type->get_baseParameters(); if ( baseParameters && ! type->get_parameters().empty() ) { for ( std::list< TypeDecl* >::const_iterator tyvar = baseParameters->begin(); tyvar != baseParameters->end(); ++tyvar ) { boundVars.insert( (*tyvar)->get_name() ); } // for } // if Type *ret = Mutator::mutate( type ); boundVars = oldBoundVars; return ret; } Type * TypeSubstitution::mutate( VoidType *basicType ) { return handleType( basicType ); } Type * TypeSubstitution::mutate( BasicType *basicType ) { return handleType( basicType ); } Type * TypeSubstitution::mutate( PointerType *pointerType ) { return handleType( pointerType ); } Type * TypeSubstitution::mutate( ArrayType *arrayType ) { return handleType( arrayType ); } Type * TypeSubstitution::mutate( FunctionType *functionType ) { return handleType( functionType ); } Type * TypeSubstitution::mutate( StructInstType *aggregateUseType ) { return handleAggregateType( aggregateUseType ); } Type * TypeSubstitution::mutate( UnionInstType *aggregateUseType ) { return handleAggregateType( aggregateUseType ); } Type * TypeSubstitution::mutate( EnumInstType *aggregateUseType ) { return handleType( aggregateUseType ); } Type * TypeSubstitution::mutate( TraitInstType *aggregateUseType ) { return handleType( aggregateUseType ); } Type * TypeSubstitution::mutate( TupleType *tupleType ) { return handleType( tupleType ); } Type * TypeSubstitution::mutate( VarArgsType *varArgsType ) { return handleType( varArgsType ); } void TypeSubstitution::print( std::ostream &os, int indent ) const { os << std::string( indent, ' ' ) << "Types:" << std::endl; for ( TypeEnvType::const_iterator i = typeEnv.begin(); i != typeEnv.end(); ++i ) { os << std::string( indent+2, ' ' ) << i->first << " -> "; i->second->print( os, indent+4 ); os << std::endl; } // for os << std::string( indent, ' ' ) << "Non-types:" << std::endl; for ( VarEnvType::const_iterator i = varEnv.begin(); i != varEnv.end(); ++i ) { os << std::string( indent+2, ' ' ) << i->first << " -> "; i->second->print( os, indent+4 ); os << std::endl; } // for } std::ostream & operator<<( std::ostream & out, const TypeSubstitution & sub ) { sub.print( out ); return out; } // Local Variables: // // tab-width: 4 // // mode: c++ // // compile-command: "make install" // // End: //