Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/SymTab/Mangler.cc

    rc6b4432 r9feb34b  
    2222#include <string>                        // for string, char_traits, operator<<
    2323
    24 #include "AST/Pass.hpp"
    2524#include "CodeGen/OperatorTable.h"       // for OperatorInfo, operatorLookup
     25#include "Common/PassVisitor.h"
    2626#include "Common/ToString.hpp"           // for toCString
    2727#include "Common/SemanticError.h"        // for SemanticError
     28#include "ResolvExpr/TypeEnvironment.h"  // for TypeEnvironment
     29#include "SynTree/LinkageSpec.h"         // for Spec, isOverridable, AutoGen, Int...
     30#include "SynTree/Declaration.h"         // for TypeDecl, DeclarationWithType
     31#include "SynTree/Expression.h"          // for TypeExpr, Expression, operator<<
     32#include "SynTree/Type.h"                // for Type, ReferenceToType, Type::Fora...
     33
     34#include "AST/Pass.hpp"
     35
     36namespace SymTab {
     37        namespace Mangler {
     38                namespace {
     39                        /// Mangles names to a unique C identifier
     40                        struct Mangler_old : public WithShortCircuiting, public WithVisitorRef<Mangler_old>, public WithGuards {
     41                                Mangler_old( bool mangleOverridable, bool typeMode, bool mangleGenericParams );
     42                                Mangler_old( const Mangler_old & ) = delete;
     43
     44                                void previsit( const BaseSyntaxNode * ) { visit_children = false; }
     45
     46                                void postvisit( const ObjectDecl * declaration );
     47                                void postvisit( const FunctionDecl * declaration );
     48                                void postvisit( const TypeDecl * declaration );
     49
     50                                void postvisit( const VoidType * voidType );
     51                                void postvisit( const BasicType * basicType );
     52                                void postvisit( const PointerType * pointerType );
     53                                void postvisit( const ArrayType * arrayType );
     54                                void postvisit( const ReferenceType * refType );
     55                                void postvisit( const FunctionType * functionType );
     56                                void postvisit( const StructInstType * aggregateUseType );
     57                                void postvisit( const UnionInstType * aggregateUseType );
     58                                void postvisit( const EnumInstType * aggregateUseType );
     59                                void postvisit( const TypeInstType * aggregateUseType );
     60                                void postvisit( const TraitInstType * inst );
     61                                void postvisit( const TupleType * tupleType );
     62                                void postvisit( const VarArgsType * varArgsType );
     63                                void postvisit( const ZeroType * zeroType );
     64                                void postvisit( const OneType * oneType );
     65                                void postvisit( const QualifiedType * qualType );
     66
     67                                std::string get_mangleName() { return mangleName; }
     68                          private:
     69                                std::string mangleName;         ///< Mangled name being constructed
     70                                typedef std::map< std::string, std::pair< int, int > > VarMapType;
     71                                VarMapType varNums;             ///< Map of type variables to indices
     72                                int nextVarNum;                 ///< Next type variable index
     73                                bool isTopLevel;                ///< Is the Mangler at the top level
     74                                bool mangleOverridable;         ///< Specially mangle overridable built-in methods
     75                                bool typeMode;                  ///< Produce a unique mangled name for a type
     76                                bool mangleGenericParams;       ///< Include generic parameters in name mangling if true
     77                                bool inFunctionType = false;    ///< Include type qualifiers if false.
     78                                bool inQualifiedType = false;   ///< Add start/end delimiters around qualified type
     79
     80                          public:
     81                                Mangler_old( bool mangleOverridable, bool typeMode, bool mangleGenericParams,
     82                                        int nextVarNum, const VarMapType& varNums );
     83
     84                          private:
     85                                void mangleDecl( const DeclarationWithType * declaration );
     86                                void mangleRef( const ReferenceToType * refType, std::string prefix );
     87
     88                                void printQualifiers( const Type *type );
     89                        }; // Mangler_old
     90                } // namespace
     91
     92                std::string mangle( const BaseSyntaxNode * decl, bool mangleOverridable, bool typeMode, bool mangleGenericParams ) {
     93                        PassVisitor<Mangler_old> mangler( mangleOverridable, typeMode, mangleGenericParams );
     94                        maybeAccept( decl, mangler );
     95                        return mangler.pass.get_mangleName();
     96                }
     97
     98                std::string mangleType( const Type * ty ) {
     99                        PassVisitor<Mangler_old> mangler( false, true, true );
     100                        maybeAccept( ty, mangler );
     101                        return mangler.pass.get_mangleName();
     102                }
     103
     104                std::string mangleConcrete( const Type * ty ) {
     105                        PassVisitor<Mangler_old> mangler( false, false, false );
     106                        maybeAccept( ty, mangler );
     107                        return mangler.pass.get_mangleName();
     108                }
     109
     110                namespace {
     111                        Mangler_old::Mangler_old( bool mangleOverridable, bool typeMode, bool mangleGenericParams )
     112                                : nextVarNum( 0 ), isTopLevel( true ),
     113                                mangleOverridable( mangleOverridable ), typeMode( typeMode ),
     114                                mangleGenericParams( mangleGenericParams ) {}
     115
     116                        Mangler_old::Mangler_old( bool mangleOverridable, bool typeMode, bool mangleGenericParams,
     117                                int nextVarNum, const VarMapType& varNums )
     118                                : varNums( varNums ), nextVarNum( nextVarNum ), isTopLevel( false ),
     119                                mangleOverridable( mangleOverridable ), typeMode( typeMode ),
     120                                mangleGenericParams( mangleGenericParams ) {}
     121
     122                        void Mangler_old::mangleDecl( const DeclarationWithType * declaration ) {
     123                                bool wasTopLevel = isTopLevel;
     124                                if ( isTopLevel ) {
     125                                        varNums.clear();
     126                                        nextVarNum = 0;
     127                                        isTopLevel = false;
     128                                } // if
     129                                mangleName += Encoding::manglePrefix;
     130                                const CodeGen::OperatorInfo * opInfo = CodeGen::operatorLookup( declaration->get_name() );
     131                                if ( opInfo ) {
     132                                        mangleName += std::to_string( opInfo->outputName.size() ) + opInfo->outputName;
     133                                } else {
     134                                        mangleName += std::to_string( declaration->name.size() ) + declaration->name;
     135                                } // if
     136                                maybeAccept( declaration->get_type(), *visitor );
     137                                if ( mangleOverridable && LinkageSpec::isOverridable( declaration->get_linkage() ) ) {
     138                                        // want to be able to override autogenerated and intrinsic routines,
     139                                        // so they need a different name mangling
     140                                        if ( declaration->get_linkage() == LinkageSpec::AutoGen ) {
     141                                                mangleName += Encoding::autogen;
     142                                        } else if ( declaration->get_linkage() == LinkageSpec::Intrinsic ) {
     143                                                mangleName += Encoding::intrinsic;
     144                                        } else {
     145                                                // if we add another kind of overridable function, this has to change
     146                                                assert( false && "unknown overrideable linkage" );
     147                                        } // if
     148                                }
     149                                isTopLevel = wasTopLevel;
     150                        }
     151
     152                        void Mangler_old::postvisit( const ObjectDecl * declaration ) {
     153                                mangleDecl( declaration );
     154                        }
     155
     156                        void Mangler_old::postvisit( const FunctionDecl * declaration ) {
     157                                mangleDecl( declaration );
     158                        }
     159
     160                        void Mangler_old::postvisit( const VoidType * voidType ) {
     161                                printQualifiers( voidType );
     162                                mangleName += Encoding::void_t;
     163                        }
     164
     165                        void Mangler_old::postvisit( const BasicType * basicType ) {
     166                                printQualifiers( basicType );
     167                                assertf( basicType->kind < BasicType::NUMBER_OF_BASIC_TYPES, "Unhandled basic type: %d", basicType->kind );
     168                                mangleName += Encoding::basicTypes[ basicType->kind ];
     169                        }
     170
     171                        void Mangler_old::postvisit( const PointerType * pointerType ) {
     172                                printQualifiers( pointerType );
     173                                // mangle void (*f)() and void f() to the same name to prevent overloading on functions and function pointers
     174                                if ( ! dynamic_cast<FunctionType *>( pointerType->base ) ) mangleName += Encoding::pointer;
     175                                maybeAccept( pointerType->base, *visitor );
     176                        }
     177
     178                        void Mangler_old::postvisit( const ArrayType * arrayType ) {
     179                                // TODO: encode dimension
     180                                printQualifiers( arrayType );
     181                                mangleName += Encoding::array + "0";
     182                                maybeAccept( arrayType->base, *visitor );
     183                        }
     184
     185                        void Mangler_old::postvisit( const ReferenceType * refType ) {
     186                                // don't print prefix (e.g. 'R') for reference types so that references and non-references do not overload.
     187                                // Further, do not print the qualifiers for a reference type (but do run printQualifers because of TypeDecls, etc.),
     188                                // by pretending every reference type is a function parameter.
     189                                GuardValue( inFunctionType );
     190                                inFunctionType = true;
     191                                printQualifiers( refType );
     192                                maybeAccept( refType->base, *visitor );
     193                        }
     194
     195                        namespace {
     196                                inline std::list< Type* > getTypes( const std::list< DeclarationWithType* > decls ) {
     197                                        std::list< Type* > ret;
     198                                        std::transform( decls.begin(), decls.end(), std::back_inserter( ret ),
     199                                                                        std::mem_fun( &DeclarationWithType::get_type ) );
     200                                        return ret;
     201                                }
     202                        }
     203
     204                        void Mangler_old::postvisit( const FunctionType * functionType ) {
     205                                printQualifiers( functionType );
     206                                mangleName += Encoding::function;
     207                                // turn on inFunctionType so that printQualifiers does not print most qualifiers for function parameters,
     208                                // since qualifiers on outermost parameter type do not differentiate function types, e.g.,
     209                                // void (*)(const int) and void (*)(int) are the same type, but void (*)(const int *) and void (*)(int *) are different
     210                                GuardValue( inFunctionType );
     211                                inFunctionType = true;
     212                                std::list< Type* > returnTypes = getTypes( functionType->returnVals );
     213                                if (returnTypes.empty()) mangleName += Encoding::void_t;
     214                                else acceptAll( returnTypes, *visitor );
     215                                mangleName += "_";
     216                                std::list< Type* > paramTypes = getTypes( functionType->parameters );
     217                                acceptAll( paramTypes, *visitor );
     218                                mangleName += "_";
     219                        }
     220
     221                        void Mangler_old::mangleRef( const ReferenceToType * refType, std::string prefix ) {
     222                                printQualifiers( refType );
     223
     224                                mangleName += prefix + std::to_string( refType->name.length() ) + refType->name;
     225
     226                                if ( mangleGenericParams ) {
     227                                        const std::list< Expression* > & params = refType->parameters;
     228                                        if ( ! params.empty() ) {
     229                                                mangleName += "_";
     230                                                for ( const Expression * param : params ) {
     231                                                        const TypeExpr * paramType = dynamic_cast< const TypeExpr * >( param );
     232                                                        assertf(paramType, "Aggregate parameters should be type expressions: %s", toCString(param));
     233                                                        maybeAccept( paramType->type, *visitor );
     234                                                }
     235                                                mangleName += "_";
     236                                        }
     237                                }
     238                        }
     239
     240                        void Mangler_old::postvisit( const StructInstType * aggregateUseType ) {
     241                                mangleRef( aggregateUseType, Encoding::struct_t );
     242                        }
     243
     244                        void Mangler_old::postvisit( const UnionInstType * aggregateUseType ) {
     245                                mangleRef( aggregateUseType, Encoding::union_t );
     246                        }
     247
     248                        void Mangler_old::postvisit( const EnumInstType * aggregateUseType ) {
     249                                mangleRef( aggregateUseType, Encoding::enum_t );
     250                        }
     251
     252                        void Mangler_old::postvisit( const TypeInstType * typeInst ) {
     253                                VarMapType::iterator varNum = varNums.find( typeInst->get_name() );
     254                                if ( varNum == varNums.end() ) {
     255                                        mangleRef( typeInst, Encoding::type );
     256                                } else {
     257                                        printQualifiers( typeInst );
     258                                        // Note: Can't use name here, since type variable names do not actually disambiguate a function, e.g.
     259                                        //   forall(dtype T) void f(T);
     260                                        //   forall(dtype S) void f(S);
     261                                        // are equivalent and should mangle the same way. This is accomplished by numbering the type variables when they
     262                                        // are first found and prefixing with the appropriate encoding for the type class.
     263                                        assertf( varNum->second.second < TypeDecl::NUMBER_OF_KINDS, "Unhandled type variable kind: %d", varNum->second.second );
     264                                        mangleName += Encoding::typeVariables[varNum->second.second] + std::to_string( varNum->second.first );
     265                                } // if
     266                        }
     267
     268                        void Mangler_old::postvisit( const TraitInstType * inst ) {
     269                                printQualifiers( inst );
     270                                mangleName += std::to_string( inst->name.size() ) + inst->name;
     271                        }
     272
     273                        void Mangler_old::postvisit( const TupleType * tupleType ) {
     274                                printQualifiers( tupleType );
     275                                mangleName += Encoding::tuple + std::to_string( tupleType->types.size() );
     276                                acceptAll( tupleType->types, *visitor );
     277                        }
     278
     279                        void Mangler_old::postvisit( const VarArgsType * varArgsType ) {
     280                                printQualifiers( varArgsType );
     281                                static const std::string vargs = "__builtin_va_list";
     282                                mangleName += Encoding::type + std::to_string( vargs.size() ) + vargs;
     283                        }
     284
     285                        void Mangler_old::postvisit( const ZeroType * ) {
     286                                mangleName += Encoding::zero;
     287                        }
     288
     289                        void Mangler_old::postvisit( const OneType * ) {
     290                                mangleName += Encoding::one;
     291                        }
     292
     293                        void Mangler_old::postvisit( const QualifiedType * qualType ) {
     294                                bool inqual = inQualifiedType;
     295                                if (! inqual ) {
     296                                        // N marks the start of a qualified type
     297                                        inQualifiedType = true;
     298                                        mangleName += Encoding::qualifiedTypeStart;
     299                                }
     300                                maybeAccept( qualType->parent, *visitor );
     301                                maybeAccept( qualType->child, *visitor );
     302                                if ( ! inqual ) {
     303                                        // E marks the end of a qualified type
     304                                        inQualifiedType = false;
     305                                        mangleName += Encoding::qualifiedTypeEnd;
     306                                }
     307                        }
     308
     309                        void Mangler_old::postvisit( const TypeDecl * decl ) {
     310                                // TODO: is there any case where mangling a TypeDecl makes sense? If so, this code needs to be
     311                                // fixed to ensure that two TypeDecls mangle to the same name when they are the same type and vice versa.
     312                                // Note: The current scheme may already work correctly for this case, I have not thought about this deeply
     313                                // and the case has not yet come up in practice. Alternatively, if not then this code can be removed
     314                                // aside from the assert false.
     315                                assertf( false, "Mangler_old should not visit typedecl: %s", toCString(decl));
     316                                assertf( decl->kind < TypeDecl::NUMBER_OF_KINDS, "Unhandled type variable kind: %d", decl->kind );
     317                                mangleName += Encoding::typeVariables[ decl->kind ] + std::to_string( decl->name.length() ) + decl->name;
     318                        }
     319
     320                        __attribute__((unused)) void printVarMap( const std::map< std::string, std::pair< int, int > > &varMap, std::ostream &os ) {
     321                                for ( std::map< std::string, std::pair< int, int > >::const_iterator i = varMap.begin(); i != varMap.end(); ++i ) {
     322                                        os << i->first << "(" << i->second.first << "/" << i->second.second << ")" << std::endl;
     323                                } // for
     324                        }
     325
     326                        void Mangler_old::printQualifiers( const Type * type ) {
     327                                // skip if not including qualifiers
     328                                if ( typeMode ) return;
     329                                if ( ! type->forall.empty() ) {
     330                                        std::list< std::string > assertionNames;
     331                                        int dcount = 0, fcount = 0, vcount = 0, acount = 0;
     332                                        mangleName += Encoding::forall;
     333                                        for ( const TypeDecl * i : type->forall ) {
     334                                                switch ( i->kind ) {
     335                                                  case TypeDecl::Dtype:
     336                                                        dcount++;
     337                                                        break;
     338                                                  case TypeDecl::Ftype:
     339                                                        fcount++;
     340                                                        break;
     341                                                  case TypeDecl::Ttype:
     342                                                        vcount++;
     343                                                        break;
     344                                                  default:
     345                                                        assertf( false, "unimplemented kind for type variable %s", SymTab::Mangler::Encoding::typeVariables[i->kind].c_str() );
     346                                                } // switch
     347                                                varNums[ i->name ] = std::make_pair( nextVarNum, (int)i->kind );
     348                                                for ( const DeclarationWithType * assert : i->assertions ) {
     349                                                        PassVisitor<Mangler_old> sub_mangler(
     350                                                                mangleOverridable, typeMode, mangleGenericParams, nextVarNum, varNums );
     351                                                        assert->accept( sub_mangler );
     352                                                        assertionNames.push_back( sub_mangler.pass.get_mangleName() );
     353                                                        acount++;
     354                                                } // for
     355                                        } // for
     356                                        mangleName += std::to_string( dcount ) + "_" + std::to_string( fcount ) + "_" + std::to_string( vcount ) + "_" + std::to_string( acount ) + "_";
     357                                        for(const auto & a : assertionNames) mangleName += a;
     358//                                      std::copy( assertionNames.begin(), assertionNames.end(), std::ostream_iterator< std::string >( mangleName, "" ) );
     359                                        mangleName += "_";
     360                                } // if
     361                                if ( ! inFunctionType ) {
     362                                        // these qualifiers do not distinguish the outermost type of a function parameter
     363                                        if ( type->get_const() ) {
     364                                                mangleName += Encoding::qualifiers.at(Type::Const);
     365                                        } // if
     366                                        if ( type->get_volatile() ) {
     367                                                mangleName += Encoding::qualifiers.at(Type::Volatile);
     368                                        } // if
     369                                        // Removed due to restrict not affecting function compatibility in GCC
     370                                        // if ( type->get_isRestrict() ) {
     371                                        //      mangleName += "E";
     372                                        // } // if
     373                                        if ( type->get_atomic() ) {
     374                                                mangleName += Encoding::qualifiers.at(Type::Atomic);
     375                                        } // if
     376                                }
     377                                if ( type->get_mutex() ) {
     378                                        mangleName += Encoding::qualifiers.at(Type::Mutex);
     379                                } // if
     380                                if ( inFunctionType ) {
     381                                        // turn off inFunctionType so that types can be differentiated for nested qualifiers
     382                                        GuardValue( inFunctionType );
     383                                        inFunctionType = false;
     384                                }
     385                        }
     386                } // namespace
     387        } // namespace Mangler
     388} // namespace SymTab
    28389
    29390namespace Mangle {
     
    115476                                mangleName += std::to_string( decl->name.size() ) + decl->name;
    116477                        } // if
    117                         decl->get_type()->accept( *visitor );
     478                        maybeAccept( decl->get_type(), *visitor );
    118479                        if ( mangleOverridable && decl->linkage.is_overrideable ) {
    119480                                // want to be able to override autogenerated and intrinsic routines,
     
    161522                        printQualifiers( arrayType );
    162523                        mangleName += Encoding::array + "0";
    163                         arrayType->base->accept( *visitor );
     524                        maybeAccept( arrayType->base.get(), *visitor );
    164525                }
    165526
     
    171532                        inFunctionType = true;
    172533                        printQualifiers( refType );
    173                         refType->base->accept( *visitor );
     534                        maybeAccept( refType->base.get(), *visitor );
    174535                }
    175536
     
    200561                                        auto paramType = dynamic_cast< const ast::TypeExpr * >( param );
    201562                                        assertf(paramType, "Aggregate parameters should be type expressions: %s", toCString(param));
    202                                         paramType->type->accept( *visitor );
     563                                        maybeAccept( paramType->type.get(), *visitor );
    203564                                }
    204565                                mangleName += "_";
     
    229590                                // are equivalent and should mangle the same way. This is accomplished by numbering the type variables when they
    230591                                // are first found and prefixing with the appropriate encoding for the type class.
    231                                 assertf( varNum->second.second < ast::TypeDecl::NUMBER_OF_KINDS, "Unhandled type variable kind: %d", varNum->second.second );
     592                                assertf( varNum->second.second < TypeDecl::NUMBER_OF_KINDS, "Unhandled type variable kind: %d", varNum->second.second );
    232593                                mangleName += Encoding::typeVariables[varNum->second.second] + std::to_string( varNum->second.first );
    233594                        } // if
     
    261622                void Mangler_new::postvisit( const ast::QualifiedType * qualType ) {
    262623                        bool inqual = inQualifiedType;
    263                         if ( !inqual ) {
     624                        if (! inqual ) {
    264625                                // N marks the start of a qualified type
    265626                                inQualifiedType = true;
    266627                                mangleName += Encoding::qualifiedTypeStart;
    267628                        }
    268                         qualType->parent->accept( *visitor );
    269                         qualType->child->accept( *visitor );
    270                         if ( !inqual ) {
     629                        maybeAccept( qualType->parent.get(), *visitor );
     630                        maybeAccept( qualType->child.get(), *visitor );
     631                        if ( ! inqual ) {
    271632                                // E marks the end of a qualified type
    272633                                inQualifiedType = false;
     
    330691                                // these qualifiers do not distinguish the outermost type of a function parameter
    331692                                if ( type->is_const() ) {
    332                                         mangleName += Encoding::qualifiers.at( ast::CV::Const );
     693                                        mangleName += Encoding::qualifiers.at(Type::Const);
    333694                                } // if
    334695                                if ( type->is_volatile() ) {
    335                                         mangleName += Encoding::qualifiers.at( ast::CV::Volatile );
     696                                        mangleName += Encoding::qualifiers.at(Type::Volatile);
    336697                                } // if
    337698                                // Removed due to restrict not affecting function compatibility in GCC
     
    340701                                // } // if
    341702                                if ( type->is_atomic() ) {
    342                                         mangleName += Encoding::qualifiers.at( ast::CV::Atomic );
     703                                        mangleName += Encoding::qualifiers.at(Type::Atomic);
    343704                                } // if
    344705                        }
    345706                        if ( type->is_mutex() ) {
    346                                 mangleName += Encoding::qualifiers.at( ast::CV::Mutex );
     707                                mangleName += Encoding::qualifiers.at(Type::Mutex);
    347708                        } // if
    348709                        if ( inFunctionType ) {
Note: See TracChangeset for help on using the changeset viewer.