#include "typeops.h" #include "SynTree/Type.h" #include "TypeEnvironment.h" #include "SymTab/Indexer.h" namespace ResolvExpr { class AdjustExprType : public Mutator { typedef Mutator Parent; public: AdjustExprType( const TypeEnvironment &env, const SymTab::Indexer &indexer ); private: virtual Type* mutate(VoidType *voidType); virtual Type* mutate(BasicType *basicType); virtual Type* mutate(PointerType *pointerType); virtual Type* mutate(ArrayType *arrayType); virtual Type* mutate(FunctionType *functionType); virtual Type* mutate(StructInstType *aggregateUseType); virtual Type* mutate(UnionInstType *aggregateUseType); virtual Type* mutate(EnumInstType *aggregateUseType); virtual Type* mutate(ContextInstType *aggregateUseType); virtual Type* mutate(TypeInstType *aggregateUseType); virtual Type* mutate(TupleType *tupleType); const TypeEnvironment &env; const SymTab::Indexer &indexer; }; void adjustExprType( Type *&type, const TypeEnvironment &env, const SymTab::Indexer &indexer ) { AdjustExprType adjuster( env, indexer ); Type *newType = type->acceptMutator( adjuster ); type = newType; } AdjustExprType::AdjustExprType( const TypeEnvironment &env, const SymTab::Indexer &indexer ) : env( env ), indexer( indexer ) { } Type *AdjustExprType::mutate(VoidType *voidType) { return voidType; } Type *AdjustExprType::mutate(BasicType *basicType) { return basicType; } Type *AdjustExprType::mutate(PointerType *pointerType) { return pointerType; } Type *AdjustExprType::mutate(ArrayType *arrayType) { PointerType *pointerType = new PointerType( arrayType->get_qualifiers(), arrayType->get_base()->clone() ); delete arrayType; return pointerType; } Type *AdjustExprType::mutate(FunctionType *functionType) { PointerType *pointerType = new PointerType( Type::Qualifiers(), functionType ); return pointerType; } Type *AdjustExprType::mutate(StructInstType *aggregateUseType) { return aggregateUseType; } Type *AdjustExprType::mutate(UnionInstType *aggregateUseType) { return aggregateUseType; } Type *AdjustExprType::mutate(EnumInstType *aggregateUseType) { return aggregateUseType; } Type *AdjustExprType::mutate(ContextInstType *aggregateUseType) { return aggregateUseType; } Type *AdjustExprType::mutate(TypeInstType *typeInst) { EqvClass eqvClass; if ( env.lookup( typeInst->get_name(), eqvClass ) ) { if ( eqvClass.kind == TypeDecl::Ftype ) { PointerType *pointerType = new PointerType( Type::Qualifiers(), typeInst ); return pointerType; } } else if ( NamedTypeDecl *ntDecl = indexer.lookupType( typeInst->get_name() ) ) { if ( TypeDecl *tyDecl = dynamic_cast< TypeDecl* >( ntDecl ) ) { if ( tyDecl->get_kind() == TypeDecl::Ftype ) { PointerType *pointerType = new PointerType( Type::Qualifiers(), typeInst ); return pointerType; } } } return typeInst; } Type *AdjustExprType::mutate(TupleType *tupleType) { return tupleType; } } // namespace ResolvExpr