// // 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. // // Mangler.cc -- // // Author : Richard C. Bilson // Created On : Sun May 17 21:40:29 2015 // Last Modified By : Peter A. Buhr // Last Modified On : Mon Sep 25 15:49:26 2017 // Update Count : 23 // #include "Mangler.h" #include // for copy, transform #include // for assert, assertf #include // for const_mem_fun_t, mem_fun #include // for ostream_iterator, back_insert_ite... #include // for _List_iterator, list, _List_const... #include // for string, char_traits, operator<< #include "CodeGen/OperatorTable.h" // for OperatorInfo, operatorLookup #include "Common/SemanticError.h" // for SemanticError #include "Common/utility.h" // for toString #include "Parser/LinkageSpec.h" // for Spec, isOverridable, AutoGen, Int... #include "SynTree/Declaration.h" // for TypeDecl, DeclarationWithType #include "SynTree/Expression.h" // for TypeExpr, Expression, operator<< #include "SynTree/Type.h" // for Type, ReferenceToType, Type::Fora... namespace SymTab { std::string Mangler::mangleType( Type * ty ) { Mangler mangler( false, true, true ); maybeAccept( ty, mangler ); return mangler.get_mangleName(); } std::string Mangler::mangleConcrete( Type* ty ) { Mangler mangler( false, false, false ); maybeAccept( ty, mangler ); return mangler.get_mangleName(); } Mangler::Mangler( bool mangleOverridable, bool typeMode, bool mangleGenericParams ) : nextVarNum( 0 ), isTopLevel( true ), mangleOverridable( mangleOverridable ), typeMode( typeMode ), mangleGenericParams( mangleGenericParams ) {} Mangler::Mangler( const Mangler &rhs ) : mangleName() { varNums = rhs.varNums; nextVarNum = rhs.nextVarNum; isTopLevel = rhs.isTopLevel; mangleOverridable = rhs.mangleOverridable; typeMode = rhs.typeMode; } void Mangler::mangleDecl( DeclarationWithType * declaration ) { bool wasTopLevel = isTopLevel; if ( isTopLevel ) { varNums.clear(); nextVarNum = 0; isTopLevel = false; } // if mangleName << "__"; CodeGen::OperatorInfo opInfo; if ( operatorLookup( declaration->get_name(), opInfo ) ) { mangleName << opInfo.outputName; } else { mangleName << declaration->get_name(); } // if mangleName << "__"; maybeAccept( declaration->get_type(), *this ); if ( mangleOverridable && LinkageSpec::isOverridable( declaration->get_linkage() ) ) { // want to be able to override autogenerated and intrinsic routines, // so they need a different name mangling if ( declaration->get_linkage() == LinkageSpec::AutoGen ) { mangleName << "autogen__"; } else if ( declaration->get_linkage() == LinkageSpec::Intrinsic ) { mangleName << "intrinsic__"; } else { // if we add another kind of overridable function, this has to change assert( false && "unknown overrideable linkage" ); } // if } isTopLevel = wasTopLevel; } void Mangler::visit( ObjectDecl * declaration ) { mangleDecl( declaration ); } void Mangler::visit( FunctionDecl * declaration ) { mangleDecl( declaration ); } void Mangler::visit( VoidType * voidType ) { printQualifiers( voidType ); mangleName << "v"; } void Mangler::visit( BasicType * basicType ) { static const char *btLetter[] = { "b", // Bool "c", // Char "Sc", // SignedChar "Uc", // UnsignedChar "s", // ShortSignedInt "Us", // ShortUnsignedInt "i", // SignedInt "Ui", // UnsignedInt "l", // LongSignedInt "Ul", // LongUnsignedInt "q", // LongLongSignedInt "Uq", // LongLongUnsignedInt "f", // Float "d", // Double "r", // LongDouble "Xf", // FloatComplex "Xd", // DoubleComplex "Xr", // LongDoubleComplex "If", // FloatImaginary "Id", // DoubleImaginary "Ir", // LongDoubleImaginary "w", // SignedInt128 "Uw", // UnsignedInt128 }; printQualifiers( basicType ); mangleName << btLetter[ basicType->get_kind() ]; } void Mangler::visit( PointerType * pointerType ) { printQualifiers( pointerType ); mangleName << "P"; maybeAccept( pointerType->get_base(), *this ); } void Mangler::visit( ArrayType * arrayType ) { // TODO: encode dimension printQualifiers( arrayType ); mangleName << "A0"; maybeAccept( arrayType->get_base(), *this ); } void Mangler::visit( ReferenceType * refType ) { printQualifiers( refType ); mangleName << "R"; maybeAccept( refType->get_base(), *this ); } namespace { inline std::list< Type* > getTypes( const std::list< DeclarationWithType* > decls ) { std::list< Type* > ret; std::transform( decls.begin(), decls.end(), std::back_inserter( ret ), std::mem_fun( &DeclarationWithType::get_type ) ); return ret; } } void Mangler::visit( FunctionType * functionType ) { printQualifiers( functionType ); mangleName << "F"; std::list< Type* > returnTypes = getTypes( functionType->get_returnVals() ); acceptAll( returnTypes, *this ); mangleName << "_"; std::list< Type* > paramTypes = getTypes( functionType->get_parameters() ); acceptAll( paramTypes, *this ); mangleName << "_"; } void Mangler::mangleRef( ReferenceToType * refType, std::string prefix ) { printQualifiers( refType ); mangleName << ( refType->get_name().length() + prefix.length() ) << prefix << refType->get_name(); if ( mangleGenericParams ) { std::list< Expression* >& params = refType->get_parameters(); if ( ! params.empty() ) { mangleName << "_"; for ( std::list< Expression* >::const_iterator param = params.begin(); param != params.end(); ++param ) { TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param ); assertf(paramType, "Aggregate parameters should be type expressions: %s", toString(*param).c_str()); maybeAccept( paramType->get_type(), *this ); } mangleName << "_"; } } } void Mangler::visit( StructInstType * aggregateUseType ) { mangleRef( aggregateUseType, "s" ); } void Mangler::visit( UnionInstType * aggregateUseType ) { mangleRef( aggregateUseType, "u" ); } void Mangler::visit( EnumInstType * aggregateUseType ) { mangleRef( aggregateUseType, "e" ); } void Mangler::visit( TypeInstType * typeInst ) { VarMapType::iterator varNum = varNums.find( typeInst->get_name() ); if ( varNum == varNums.end() ) { mangleRef( typeInst, "t" ); } else { printQualifiers( typeInst ); std::ostringstream numStream; numStream << varNum->second.first; switch ( (TypeDecl::Kind )varNum->second.second ) { case TypeDecl::Dtype: mangleName << "d"; break; case TypeDecl::Ftype: mangleName << "f"; break; case TypeDecl::Ttype: mangleName << "tVARGS"; break; default: assert( false ); } // switch mangleName << numStream.str(); } // if } void Mangler::visit( TupleType * tupleType ) { printQualifiers( tupleType ); mangleName << "T"; acceptAll( tupleType->types, *this ); mangleName << "_"; } void Mangler::visit( VarArgsType * varArgsType ) { printQualifiers( varArgsType ); mangleName << "VARGS"; } void Mangler::visit( ZeroType * ) { mangleName << "Z"; } void Mangler::visit( OneType * ) { mangleName << "O"; } void Mangler::visit( TypeDecl * decl ) { static const char *typePrefix[] = { "BT", "BD", "BF" }; mangleName << typePrefix[ decl->get_kind() ] << ( decl->name.length() + 1 ) << decl->name; } void printVarMap( const std::map< std::string, std::pair< int, int > > &varMap, std::ostream &os ) { for ( std::map< std::string, std::pair< int, int > >::const_iterator i = varMap.begin(); i != varMap.end(); ++i ) { os << i->first << "(" << i->second.first << "/" << i->second.second << ")" << std::endl; } // for } void Mangler::printQualifiers( Type * type ) { // skip if not including qualifiers if ( typeMode ) return; if ( ! type->get_forall().empty() ) { std::list< std::string > assertionNames; int tcount = 0, dcount = 0, fcount = 0, vcount = 0; mangleName << "A"; for ( Type::ForallList::iterator i = type->forall.begin(); i != type->forall.end(); ++i ) { switch ( (*i)->get_kind() ) { case TypeDecl::Dtype: dcount++; break; case TypeDecl::Ftype: fcount++; break; case TypeDecl::Ttype: vcount++; break; default: assert( false ); } // switch varNums[ (*i)->name ] = std::pair< int, int >( nextVarNum++, (int)(*i)->get_kind() ); for ( std::list< DeclarationWithType* >::iterator assert = (*i)->assertions.begin(); assert != (*i)->assertions.end(); ++assert ) { Mangler sub_mangler( mangleOverridable, typeMode, mangleGenericParams ); sub_mangler.nextVarNum = nextVarNum; sub_mangler.isTopLevel = false; sub_mangler.varNums = varNums; (*assert)->accept( sub_mangler ); assertionNames.push_back( sub_mangler.mangleName.str() ); } // for } // for mangleName << tcount << "_" << dcount << "_" << fcount << "_" << vcount << "_"; std::copy( assertionNames.begin(), assertionNames.end(), std::ostream_iterator< std::string >( mangleName, "" ) ); mangleName << "_"; } // if if ( type->get_const() ) { mangleName << "C"; } // if if ( type->get_volatile() ) { mangleName << "V"; } // if if ( type->get_mutex() ) { mangleName << "M"; } // if // Removed due to restrict not affecting function compatibility in GCC // if ( type->get_isRestrict() ) { // mangleName << "E"; // } // if if ( type->get_lvalue() ) { // mangle based on whether the type is lvalue, so that the resolver can differentiate lvalues and rvalues mangleName << "L"; } if ( type->get_atomic() ) { mangleName << "A"; } // if } } // namespace SymTab // Local Variables: // // tab-width: 4 // // mode: c++ // // compile-command: "make install" // // End: //