/* * This file is part of the Cforall project * * $Id: GenType.cc,v 1.6 2005/08/29 20:14:12 rcbilson Exp $ * */ #include #include #include "GenType.h" #include "CodeGenerator2.h" #include "SynTree/Visitor.h" #include "SynTree/Type.h" #include "SynTree/Expression.h" namespace CodeGen { class GenType : public Visitor { public: GenType( const std::string &typeString ); std::string get_typeString() const { return typeString; } void set_typeString( const std::string &newValue ) { typeString = newValue; } virtual void visit( FunctionType *funcType ); virtual void visit( VoidType *voidType ); virtual void visit( BasicType *basicType ); virtual void visit( PointerType *pointerType ); virtual void visit( ArrayType *arrayType ); virtual void visit( StructInstType *structInst ); virtual void visit( UnionInstType *unionInst ); virtual void visit( EnumInstType *enumInst ); virtual void visit( TypeInstType *typeInst ); private: void handleQualifiers( Type *type ); void genArray( const Type::Qualifiers &qualifiers, Type *base, Expression *dimension, bool isVarLen, bool isStatic ); std::string typeString; }; std::string genType( Type *type, const std::string &baseString ) { GenType gt( baseString ); type->accept( gt ); return gt.get_typeString(); } GenType::GenType( const std::string &typeString ) : typeString( typeString ) { } void GenType::visit(VoidType *voidType){ typeString = "void " + typeString; handleQualifiers( voidType ); } void GenType::visit(BasicType *basicType) { std::string typeWords; switch(basicType->get_kind()){ case BasicType::Bool: typeWords = "bool"; break; case BasicType::Char: case BasicType::SignedChar: typeWords = "char"; break; case BasicType::UnsignedChar: typeWords = "unsigned char"; break; case BasicType::ShortSignedInt: typeWords = "short"; break; case BasicType::ShortUnsignedInt: typeWords = "short unsigned"; break; case BasicType::SignedInt: typeWords = "int"; break; case BasicType::UnsignedInt: typeWords = "unsigned int"; break; case BasicType::LongSignedInt: typeWords = "long int"; break; case BasicType::LongUnsignedInt: typeWords = "long unsigned int"; break; case BasicType::LongLongSignedInt: typeWords = "long long int"; break; case BasicType::LongLongUnsignedInt: typeWords = "long long unsigned int"; break; case BasicType::Float: typeWords = "float"; break; case BasicType::Double: typeWords = "double"; break; case BasicType::LongDouble: typeWords = "long double"; break; case BasicType::FloatComplex: typeWords = "float _Complex"; break; case BasicType::DoubleComplex: typeWords = "double _Complex"; break; case BasicType::LongDoubleComplex: typeWords = "long double _Complex"; break; case BasicType::FloatImaginary: typeWords = "float _Imaginary"; break; case BasicType::DoubleImaginary: typeWords = "double _Imaginary"; break; case BasicType::LongDoubleImaginary: typeWords = "long double _Imaginary"; break; default: assert( false ); } typeString = typeWords + " " + typeString; handleQualifiers( basicType ); } void GenType::genArray( const Type::Qualifiers &qualifiers, Type *base, Expression *dimension, bool isVarLen, bool isStatic ) { std::ostrstream os; if( typeString != "" ) { if( typeString[ 0 ] == '*' ) { os << "(" << typeString << ")"; } else { os << typeString; } } os << "["; if( isStatic ) { os << "static "; } if( qualifiers.isConst ) { os << "const "; } if( qualifiers.isVolatile ) { os << "volatile "; } if( isVarLen ) { os << "*"; } if( dimension != 0 ) { CodeGenerator2 cg( os ); dimension->accept( cg ); } os << "]"; typeString = std::string( os.str(), os.pcount() ); base->accept ( *this ); } void GenType::visit(PointerType *pointerType) { assert(pointerType->get_base() != 0); if( pointerType->get_isStatic() || pointerType->get_isVarLen() || pointerType->get_dimension() ) { genArray( pointerType->get_qualifiers(), pointerType->get_base(), pointerType->get_dimension(), pointerType->get_isVarLen(), pointerType->get_isStatic() ); } else { handleQualifiers( pointerType ); if( typeString[ 0 ] == '?' ) { typeString = "* " + typeString; } else { typeString = "*" + typeString; } pointerType->get_base()->accept ( *this ); } } void GenType::visit(ArrayType *arrayType){ genArray( arrayType->get_qualifiers(), arrayType->get_base(), arrayType->get_dimension(), arrayType->get_isVarLen(), arrayType->get_isStatic() ); } void GenType::visit(FunctionType *funcType) { std::ostrstream os; if( typeString != "" ) { if( typeString[ 0 ] == '*' ) { os << "(" << typeString << ")"; } else { os << typeString; } } /************* parameters ***************/ const std::list &pars = funcType->get_parameters(); if( pars.empty() ) { if( funcType->get_isVarArgs() ) { os << "()"; } else { os << "(void)"; } } else { CodeGenerator2 cg( os ); os << "(" ; cg.genCommaList( pars.begin(), pars.end() ); if( funcType->get_isVarArgs() ){ os << ", ..."; } os << ")"; } typeString = std::string( os.str(), os.pcount() ); if( funcType->get_returnVals().size() == 0 ) { typeString = "void " + typeString; } else { funcType->get_returnVals().front()->get_type()->accept( *this ); } } void GenType::visit( StructInstType *structInst ) { typeString = "struct " + structInst->get_name() + " " + typeString; handleQualifiers( structInst ); } void GenType::visit( UnionInstType *unionInst ) { typeString = "union " + unionInst->get_name() + " " + typeString; handleQualifiers( unionInst ); } void GenType::visit( EnumInstType *enumInst ) { typeString = "enum " + enumInst->get_name() + " " + typeString; handleQualifiers( enumInst ); } void GenType::visit( TypeInstType *typeInst ) { typeString = typeInst->get_name() + " " + typeString; handleQualifiers( typeInst ); } void GenType::handleQualifiers( Type *type ) { if( type->get_isConst() ) { typeString = "const " + typeString; } if( type->get_isVolatile() ) { typeString = "volatile " + typeString; } if( type->get_isRestrict() ) { typeString = "__restrict " + typeString; } } } // namespace CodeGen