Ignore:
Timestamp:
Nov 17, 2023, 10:40:21 AM (6 months ago)
Author:
Andrew Beach <ajbeach@…>
Branches:
master
Children:
0f6d2884
Parents:
e580aa5
Message:

Reformating and clean-up in SymTab? directory.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/SymTab/Mangler.cc

    re580aa5 rb0845f9  
    2828
    2929namespace Mangle {
    30         namespace {
    31                 /// Mangles names to a unique C identifier
    32                 struct Mangler : public ast::WithShortCircuiting, public ast::WithVisitorRef<Mangler>, public ast::WithGuards {
    33                         Mangler( Mangle::Mode mode );
    34                         Mangler( const Mangler & ) = delete;
    35 
    36                         void previsit( const ast::Node * ) { visit_children = false; }
    37 
    38                         void postvisit( const ast::ObjectDecl * declaration );
    39                         void postvisit( const ast::FunctionDecl * declaration );
    40                         void postvisit( const ast::TypeDecl * declaration );
    41 
    42                         void postvisit( const ast::VoidType * voidType );
    43                         void postvisit( const ast::BasicType * basicType );
    44                         void postvisit( const ast::PointerType * pointerType );
    45                         void postvisit( const ast::ArrayType * arrayType );
    46                         void postvisit( const ast::ReferenceType * refType );
    47                         void postvisit( const ast::FunctionType * functionType );
    48                         void postvisit( const ast::StructInstType * aggregateUseType );
    49                         void postvisit( const ast::UnionInstType * aggregateUseType );
    50                         void postvisit( const ast::EnumInstType * aggregateUseType );
    51                         void postvisit( const ast::TypeInstType * aggregateUseType );
    52                         void postvisit( const ast::TraitInstType * inst );
    53                         void postvisit( const ast::TupleType * tupleType );
    54                         void postvisit( const ast::VarArgsType * varArgsType );
    55                         void postvisit( const ast::ZeroType * zeroType );
    56                         void postvisit( const ast::OneType * oneType );
    57                         void postvisit( const ast::QualifiedType * qualType );
    58 
    59                         /// The result is the current constructed mangled name.
    60                         std::string result() const { return mangleName; }
    61                   private:
    62                         std::string mangleName;         ///< Mangled name being constructed
    63                         typedef std::map< std::string, std::pair< int, int > > VarMapType;
    64                         VarMapType varNums;             ///< Map of type variables to indices
    65                         int nextVarNum;                 ///< Next type variable index
    66                         bool isTopLevel;                ///< Is the Mangler at the top level
    67                         bool mangleOverridable;         ///< Specially mangle overridable built-in methods
    68                         bool typeMode;                  ///< Produce a unique mangled name for a type
    69                         bool mangleGenericParams;       ///< Include generic parameters in name mangling if true
    70                         bool inFunctionType = false;    ///< Include type qualifiers if false.
    71                         bool inQualifiedType = false;   ///< Add start/end delimiters around qualified type
    72 
    73                   private:
    74                         Mangler( bool mangleOverridable, bool typeMode, bool mangleGenericParams,
    75                                 int nextVarNum, const VarMapType& varNums );
    76                         friend class ast::Pass<Mangler>;
    77 
    78                   private:
    79                         void mangleDecl( const ast::DeclWithType *declaration );
    80                         void mangleRef( const ast::BaseInstType *refType, const std::string & prefix );
    81 
    82                         void printQualifiers( const ast::Type *type );
    83                 }; // Mangler
    84         } // namespace
    85 
    86         std::string mangle( const ast::Node * decl, Mangle::Mode mode ) {
    87                 return ast::Pass<Mangler>::read( decl, mode );
    88         }
    89 
    90         namespace {
    91                 Mangler::Mangler( Mangle::Mode mode )
    92                         : nextVarNum( 0 ), isTopLevel( true ),
    93                         mangleOverridable  ( ! mode.no_overrideable   ),
    94                         typeMode           (   mode.type              ),
    95                         mangleGenericParams( ! mode.no_generic_params ) {}
    96 
    97                 Mangler::Mangler( bool mangleOverridable, bool typeMode, bool mangleGenericParams,
    98                         int nextVarNum, const VarMapType& varNums )
    99                         : varNums( varNums ), nextVarNum( nextVarNum ), isTopLevel( false ),
    100                         mangleOverridable( mangleOverridable ), typeMode( typeMode ),
    101                         mangleGenericParams( mangleGenericParams ) {}
    102 
    103                 void Mangler::mangleDecl( const ast::DeclWithType * decl ) {
    104                         bool wasTopLevel = isTopLevel;
    105                         if ( isTopLevel ) {
    106                                 varNums.clear();
    107                                 nextVarNum = 0;
    108                                 isTopLevel = false;
    109                         } // if
    110                         mangleName += Encoding::manglePrefix;
    111                         const CodeGen::OperatorInfo * opInfo = CodeGen::operatorLookup( decl->name );
    112                         if ( opInfo ) {
    113                                 mangleName += std::to_string( opInfo->outputName.size() ) + opInfo->outputName;
    114                         } else {
    115                                 mangleName += std::to_string( decl->name.size() ) + decl->name;
    116                         } // if
    117                         decl->get_type()->accept( *visitor );
    118                         if ( mangleOverridable && decl->linkage.is_overrideable ) {
    119                                 // want to be able to override autogenerated and intrinsic routines,
    120                                 // so they need a different name mangling
    121                                 if ( decl->linkage == ast::Linkage::AutoGen ) {
    122                                         mangleName += Encoding::autogen;
    123                                 } else if ( decl->linkage == ast::Linkage::Intrinsic ) {
    124                                         mangleName += Encoding::intrinsic;
    125                                 } else {
    126                                         // if we add another kind of overridable function, this has to change
    127                                         assert( false && "unknown overrideable linkage" );
    128                                 } // if
     30
     31namespace {
     32
     33/// Mangles names to a unique C identifier.
     34struct Mangler : public ast::WithShortCircuiting, public ast::WithVisitorRef<Mangler>, public ast::WithGuards {
     35        Mangler( Mangle::Mode mode );
     36        Mangler( const Mangler & ) = delete;
     37
     38        void previsit( const ast::Node * ) { visit_children = false; }
     39
     40        void postvisit( const ast::ObjectDecl * declaration );
     41        void postvisit( const ast::FunctionDecl * declaration );
     42        void postvisit( const ast::TypeDecl * declaration );
     43
     44        void postvisit( const ast::VoidType * voidType );
     45        void postvisit( const ast::BasicType * basicType );
     46        void postvisit( const ast::PointerType * pointerType );
     47        void postvisit( const ast::ArrayType * arrayType );
     48        void postvisit( const ast::ReferenceType * refType );
     49        void postvisit( const ast::FunctionType * functionType );
     50        void postvisit( const ast::StructInstType * aggregateUseType );
     51        void postvisit( const ast::UnionInstType * aggregateUseType );
     52        void postvisit( const ast::EnumInstType * aggregateUseType );
     53        void postvisit( const ast::TypeInstType * aggregateUseType );
     54        void postvisit( const ast::TraitInstType * inst );
     55        void postvisit( const ast::TupleType * tupleType );
     56        void postvisit( const ast::VarArgsType * varArgsType );
     57        void postvisit( const ast::ZeroType * zeroType );
     58        void postvisit( const ast::OneType * oneType );
     59        void postvisit( const ast::QualifiedType * qualType );
     60
     61        /// The result is the current constructed mangled name.
     62        std::string result() const { return mangleName; }
     63private:
     64        std::string mangleName;         ///< Mangled name being constructed
     65        typedef std::map< std::string, std::pair< int, int > > VarMapType;
     66        VarMapType varNums;             ///< Map of type variables to indices
     67        int nextVarNum;                 ///< Next type variable index
     68        bool isTopLevel;                ///< Is the Mangler at the top level
     69        bool mangleOverridable;         ///< Specially mangle overridable built-in methods
     70        bool typeMode;                  ///< Produce a unique mangled name for a type
     71        bool mangleGenericParams;       ///< Include generic parameters in name mangling if true
     72        bool inFunctionType = false;    ///< Include type qualifiers if false.
     73        bool inQualifiedType = false;   ///< Add start/end delimiters around qualified type
     74
     75private:
     76        Mangler( bool mangleOverridable, bool typeMode, bool mangleGenericParams,
     77                int nextVarNum, const VarMapType& varNums );
     78        friend class ast::Pass<Mangler>;
     79
     80private:
     81        void mangleDecl( const ast::DeclWithType *declaration );
     82        void mangleRef( const ast::BaseInstType *refType, const std::string & prefix );
     83
     84        void printQualifiers( const ast::Type *type );
     85}; // Mangler
     86
     87Mangler::Mangler( Mangle::Mode mode )
     88        : nextVarNum( 0 ), isTopLevel( true ),
     89        mangleOverridable  ( ! mode.no_overrideable   ),
     90        typeMode           (   mode.type              ),
     91        mangleGenericParams( ! mode.no_generic_params ) {}
     92
     93Mangler::Mangler( bool mangleOverridable, bool typeMode, bool mangleGenericParams,
     94        int nextVarNum, const VarMapType& varNums )
     95        : varNums( varNums ), nextVarNum( nextVarNum ), isTopLevel( false ),
     96        mangleOverridable( mangleOverridable ), typeMode( typeMode ),
     97        mangleGenericParams( mangleGenericParams ) {}
     98
     99void Mangler::mangleDecl( const ast::DeclWithType * decl ) {
     100        bool wasTopLevel = isTopLevel;
     101        if ( isTopLevel ) {
     102                varNums.clear();
     103                nextVarNum = 0;
     104                isTopLevel = false;
     105        }
     106        mangleName += Encoding::manglePrefix;
     107        if ( auto opInfo = CodeGen::operatorLookup( decl->name ) ) {
     108                mangleName += std::to_string( opInfo->outputName.size() ) + opInfo->outputName;
     109        } else {
     110                mangleName += std::to_string( decl->name.size() ) + decl->name;
     111        }
     112        decl->get_type()->accept( *visitor );
     113        if ( mangleOverridable && decl->linkage.is_overrideable ) {
     114                // want to be able to override autogenerated and intrinsic routines,
     115                // so they need a different name mangling
     116                if ( decl->linkage == ast::Linkage::AutoGen ) {
     117                        mangleName += Encoding::autogen;
     118                } else if ( decl->linkage == ast::Linkage::Intrinsic ) {
     119                        mangleName += Encoding::intrinsic;
     120                } else {
     121                        // if we add another kind of overridable function, this has to change
     122                        assert( false && "unknown overrideable linkage" );
     123                }
     124        }
     125        isTopLevel = wasTopLevel;
     126}
     127
     128void Mangler::postvisit( const ast::ObjectDecl * decl ) {
     129        mangleDecl( decl );
     130}
     131
     132void Mangler::postvisit( const ast::FunctionDecl * decl ) {
     133        mangleDecl( decl );
     134}
     135
     136void Mangler::postvisit( const ast::VoidType * voidType ) {
     137        printQualifiers( voidType );
     138        mangleName += Encoding::void_t;
     139}
     140
     141void Mangler::postvisit( const ast::BasicType * basicType ) {
     142        printQualifiers( basicType );
     143        assertf( basicType->kind < ast::BasicType::NUMBER_OF_BASIC_TYPES, "Unhandled basic type: %d", basicType->kind );
     144        mangleName += Encoding::basicTypes[ basicType->kind ];
     145}
     146
     147void Mangler::postvisit( const ast::PointerType * pointerType ) {
     148        printQualifiers( pointerType );
     149        // Mangle void (*f)() and void f() to the same name to prevent overloading on functions and function pointers.
     150        if ( !pointerType->base.as<ast::FunctionType>() ) mangleName += Encoding::pointer;
     151        maybe_accept( pointerType->base.get(), *visitor );
     152}
     153
     154void Mangler::postvisit( const ast::ArrayType * arrayType ) {
     155        // TODO: encode dimension
     156        printQualifiers( arrayType );
     157        mangleName += Encoding::array + "0";
     158        arrayType->base->accept( *visitor );
     159}
     160
     161void Mangler::postvisit( const ast::ReferenceType * refType ) {
     162        // Don't print prefix (e.g. 'R') for reference types so that references and non-references do not overload.
     163        // Further, do not print the qualifiers for a reference type (but do run printQualifers because of TypeDecls, etc.),
     164        // by pretending every reference type is a function parameter.
     165        GuardValue( inFunctionType ) = true;
     166        printQualifiers( refType );
     167        refType->base->accept( *visitor );
     168}
     169
     170void Mangler::postvisit( const ast::FunctionType * functionType ) {
     171        printQualifiers( functionType );
     172        mangleName += Encoding::function;
     173        // Turn on inFunctionType so that printQualifiers does not print most qualifiers for function parameters,
     174        // since qualifiers on outermost parameter type do not differentiate function types, e.g.,
     175        // void (*)(const int) and void (*)(int) are the same type, but void (*)(const int *) and void (*)(int *) are different.
     176        GuardValue( inFunctionType ) = true;
     177        if (functionType->returns.empty()) mangleName += Encoding::void_t;
     178        else accept_each( functionType->returns, *visitor );
     179        mangleName += "_";
     180        accept_each( functionType->params, *visitor );
     181        mangleName += "_";
     182}
     183
     184void Mangler::mangleRef(
     185                const ast::BaseInstType * refType, const std::string & prefix ) {
     186        printQualifiers( refType );
     187
     188        mangleName += prefix + std::to_string( refType->name.length() ) + refType->name;
     189
     190        if ( mangleGenericParams && ! refType->params.empty() ) {
     191                mangleName += "_";
     192                for ( const ast::Expr * param : refType->params ) {
     193                        auto paramType = dynamic_cast< const ast::TypeExpr * >( param );
     194                        assertf(paramType, "Aggregate parameters should be type expressions: %s", toCString(param));
     195                        paramType->type->accept( *visitor );
     196                }
     197                mangleName += "_";
     198        }
     199}
     200
     201void Mangler::postvisit( const ast::StructInstType * aggregateUseType ) {
     202        mangleRef( aggregateUseType, Encoding::struct_t );
     203}
     204
     205void Mangler::postvisit( const ast::UnionInstType * aggregateUseType ) {
     206        mangleRef( aggregateUseType, Encoding::union_t );
     207}
     208
     209void Mangler::postvisit( const ast::EnumInstType * aggregateUseType ) {
     210        mangleRef( aggregateUseType, Encoding::enum_t );
     211}
     212
     213void Mangler::postvisit( const ast::TypeInstType * typeInst ) {
     214        VarMapType::iterator varNum = varNums.find( typeInst->name );
     215        if ( varNum == varNums.end() ) {
     216                mangleRef( typeInst, Encoding::type );
     217        } else {
     218                printQualifiers( typeInst );
     219                // Note: Can't use name here, since type variable names do not actually disambiguate a function, e.g.
     220                //   forall(dtype T) void f(T);
     221                //   forall(dtype S) void f(S);
     222                // are equivalent and should mangle the same way. This is accomplished by numbering the type variables when they
     223                // are first found and prefixing with the appropriate encoding for the type class.
     224                assertf( varNum->second.second < ast::TypeDecl::NUMBER_OF_KINDS, "Unhandled type variable kind: %d", varNum->second.second );
     225                mangleName += Encoding::typeVariables[varNum->second.second] + std::to_string( varNum->second.first );
     226        }
     227}
     228
     229void Mangler::postvisit( const ast::TraitInstType * inst ) {
     230        printQualifiers( inst );
     231        mangleName += std::to_string( inst->name.size() ) + inst->name;
     232}
     233
     234void Mangler::postvisit( const ast::TupleType * tupleType ) {
     235        printQualifiers( tupleType );
     236        mangleName += Encoding::tuple + std::to_string( tupleType->types.size() );
     237        accept_each( tupleType->types, *visitor );
     238}
     239
     240void Mangler::postvisit( const ast::VarArgsType * varArgsType ) {
     241        printQualifiers( varArgsType );
     242        static const std::string vargs = "__builtin_va_list";
     243        mangleName += Encoding::type + std::to_string( vargs.size() ) + vargs;
     244}
     245
     246void Mangler::postvisit( const ast::ZeroType * ) {
     247        mangleName += Encoding::zero;
     248}
     249
     250void Mangler::postvisit( const ast::OneType * ) {
     251        mangleName += Encoding::one;
     252}
     253
     254void Mangler::postvisit( const ast::QualifiedType * qualType ) {
     255        bool inqual = inQualifiedType;
     256        if ( !inqual ) {
     257                // N marks the start of a qualified type.
     258                inQualifiedType = true;
     259                mangleName += Encoding::qualifiedTypeStart;
     260        }
     261        qualType->parent->accept( *visitor );
     262        qualType->child->accept( *visitor );
     263        if ( !inqual ) {
     264                // E marks the end of a qualified type.
     265                inQualifiedType = false;
     266                mangleName += Encoding::qualifiedTypeEnd;
     267        }
     268}
     269
     270void Mangler::postvisit( const ast::TypeDecl * decl ) {
     271        // TODO: is there any case where mangling a TypeDecl makes sense? If so, this code needs to be
     272        // fixed to ensure that two TypeDecls mangle to the same name when they are the same type and vice versa.
     273        // Note: The current scheme may already work correctly for this case, I have not thought about this deeply
     274        // and the case has not yet come up in practice. Alternatively, if not then this code can be removed
     275        // aside from the assert false.
     276        assertf(false, "Mangler should not visit typedecl: %s", toCString(decl));
     277        assertf( decl->kind < ast::TypeDecl::Kind::NUMBER_OF_KINDS, "Unhandled type variable kind: %d", decl->kind );
     278        mangleName += Encoding::typeVariables[ decl->kind ] + std::to_string( decl->name.length() ) + decl->name;
     279}
     280
     281// For debugging:
     282__attribute__((unused)) void printVarMap( const std::map< std::string, std::pair< int, int > > &varMap, std::ostream &os ) {
     283        for ( std::map< std::string, std::pair< int, int > >::const_iterator i = varMap.begin(); i != varMap.end(); ++i ) {
     284                os << i->first << "(" << i->second.first << "/" << i->second.second << ")" << std::endl;
     285        }
     286}
     287
     288void Mangler::printQualifiers( const ast::Type * type ) {
     289        // Skip if not including qualifiers:
     290        if ( typeMode ) return;
     291        auto funcType = dynamic_cast<const ast::FunctionType *>( type );
     292        if ( funcType && !funcType->forall.empty() ) {
     293                std::list< std::string > assertionNames;
     294                int dcount = 0, fcount = 0, vcount = 0, acount = 0;
     295                mangleName += Encoding::forall;
     296                for ( auto & decl : funcType->forall ) {
     297                        switch ( decl->kind ) {
     298                        case ast::TypeDecl::Dtype:
     299                                dcount++;
     300                                break;
     301                        case ast::TypeDecl::Ftype:
     302                                fcount++;
     303                                break;
     304                        case ast::TypeDecl::Ttype:
     305                                vcount++;
     306                                break;
     307                        default:
     308                                assertf( false, "unimplemented kind for type variable %s", Encoding::typeVariables[decl->kind].c_str() );
    129309                        }
    130                         isTopLevel = wasTopLevel;
    131                 }
    132 
    133                 void Mangler::postvisit( const ast::ObjectDecl * decl ) {
    134                         mangleDecl( decl );
    135                 }
    136 
    137                 void Mangler::postvisit( const ast::FunctionDecl * decl ) {
    138                         mangleDecl( decl );
    139                 }
    140 
    141                 void Mangler::postvisit( const ast::VoidType * voidType ) {
    142                         printQualifiers( voidType );
    143                         mangleName += Encoding::void_t;
    144                 }
    145 
    146                 void Mangler::postvisit( const ast::BasicType * basicType ) {
    147                         printQualifiers( basicType );
    148                         assertf( basicType->kind < ast::BasicType::NUMBER_OF_BASIC_TYPES, "Unhandled basic type: %d", basicType->kind );
    149                         mangleName += Encoding::basicTypes[ basicType->kind ];
    150                 }
    151 
    152                 void Mangler::postvisit( const ast::PointerType * pointerType ) {
    153                         printQualifiers( pointerType );
    154                         // mangle void (*f)() and void f() to the same name to prevent overloading on functions and function pointers
    155                         if ( ! pointerType->base.as<ast::FunctionType>() ) mangleName += Encoding::pointer;
    156                         maybe_accept( pointerType->base.get(), *visitor );
    157                 }
    158 
    159                 void Mangler::postvisit( const ast::ArrayType * arrayType ) {
    160                         // TODO: encode dimension
    161                         printQualifiers( arrayType );
    162                         mangleName += Encoding::array + "0";
    163                         arrayType->base->accept( *visitor );
    164                 }
    165 
    166                 void Mangler::postvisit( const ast::ReferenceType * refType ) {
    167                         // don't print prefix (e.g. 'R') for reference types so that references and non-references do not overload.
    168                         // Further, do not print the qualifiers for a reference type (but do run printQualifers because of TypeDecls, etc.),
    169                         // by pretending every reference type is a function parameter.
    170                         GuardValue( inFunctionType );
    171                         inFunctionType = true;
    172                         printQualifiers( refType );
    173                         refType->base->accept( *visitor );
    174                 }
    175 
    176                 void Mangler::postvisit( const ast::FunctionType * functionType ) {
    177                         printQualifiers( functionType );
    178                         mangleName += Encoding::function;
    179                         // turn on inFunctionType so that printQualifiers does not print most qualifiers for function parameters,
    180                         // since qualifiers on outermost parameter type do not differentiate function types, e.g.,
    181                         // void (*)(const int) and void (*)(int) are the same type, but void (*)(const int *) and void (*)(int *) are different
    182                         GuardValue( inFunctionType );
    183                         inFunctionType = true;
    184                         if (functionType->returns.empty()) mangleName += Encoding::void_t;
    185                         else accept_each( functionType->returns, *visitor );
    186                         mangleName += "_";
    187                         accept_each( functionType->params, *visitor );
    188                         mangleName += "_";
    189                 }
    190 
    191                 void Mangler::mangleRef(
    192                                 const ast::BaseInstType * refType, const std::string & prefix ) {
    193                         printQualifiers( refType );
    194 
    195                         mangleName += prefix + std::to_string( refType->name.length() ) + refType->name;
    196 
    197                         if ( mangleGenericParams && ! refType->params.empty() ) {
    198                                 mangleName += "_";
    199                                 for ( const ast::Expr * param : refType->params ) {
    200                                         auto paramType = dynamic_cast< const ast::TypeExpr * >( param );
    201                                         assertf(paramType, "Aggregate parameters should be type expressions: %s", toCString(param));
    202                                         paramType->type->accept( *visitor );
    203                                 }
    204                                 mangleName += "_";
    205                         }
    206                 }
    207 
    208                 void Mangler::postvisit( const ast::StructInstType * aggregateUseType ) {
    209                         mangleRef( aggregateUseType, Encoding::struct_t );
    210                 }
    211 
    212                 void Mangler::postvisit( const ast::UnionInstType * aggregateUseType ) {
    213                         mangleRef( aggregateUseType, Encoding::union_t );
    214                 }
    215 
    216                 void Mangler::postvisit( const ast::EnumInstType * aggregateUseType ) {
    217                         mangleRef( aggregateUseType, Encoding::enum_t );
    218                 }
    219 
    220                 void Mangler::postvisit( const ast::TypeInstType * typeInst ) {
    221                         VarMapType::iterator varNum = varNums.find( typeInst->name );
    222                         if ( varNum == varNums.end() ) {
    223                                 mangleRef( typeInst, Encoding::type );
    224                         } else {
    225                                 printQualifiers( typeInst );
    226                                 // Note: Can't use name here, since type variable names do not actually disambiguate a function, e.g.
    227                                 //   forall(dtype T) void f(T);
    228                                 //   forall(dtype S) void f(S);
    229                                 // are equivalent and should mangle the same way. This is accomplished by numbering the type variables when they
    230                                 // 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 );
    232                                 mangleName += Encoding::typeVariables[varNum->second.second] + std::to_string( varNum->second.first );
    233                         } // if
    234                 }
    235 
    236                 void Mangler::postvisit( const ast::TraitInstType * inst ) {
    237                         printQualifiers( inst );
    238                         mangleName += std::to_string( inst->name.size() ) + inst->name;
    239                 }
    240 
    241                 void Mangler::postvisit( const ast::TupleType * tupleType ) {
    242                         printQualifiers( tupleType );
    243                         mangleName += Encoding::tuple + std::to_string( tupleType->types.size() );
    244                         accept_each( tupleType->types, *visitor );
    245                 }
    246 
    247                 void Mangler::postvisit( const ast::VarArgsType * varArgsType ) {
    248                         printQualifiers( varArgsType );
    249                         static const std::string vargs = "__builtin_va_list";
    250                         mangleName += Encoding::type + std::to_string( vargs.size() ) + vargs;
    251                 }
    252 
    253                 void Mangler::postvisit( const ast::ZeroType * ) {
    254                         mangleName += Encoding::zero;
    255                 }
    256 
    257                 void Mangler::postvisit( const ast::OneType * ) {
    258                         mangleName += Encoding::one;
    259                 }
    260 
    261                 void Mangler::postvisit( const ast::QualifiedType * qualType ) {
    262                         bool inqual = inQualifiedType;
    263                         if ( !inqual ) {
    264                                 // N marks the start of a qualified type
    265                                 inQualifiedType = true;
    266                                 mangleName += Encoding::qualifiedTypeStart;
    267                         }
    268                         qualType->parent->accept( *visitor );
    269                         qualType->child->accept( *visitor );
    270                         if ( !inqual ) {
    271                                 // E marks the end of a qualified type
    272                                 inQualifiedType = false;
    273                                 mangleName += Encoding::qualifiedTypeEnd;
    274                         }
    275                 }
    276 
    277                 void Mangler::postvisit( const ast::TypeDecl * decl ) {
    278                         // TODO: is there any case where mangling a TypeDecl makes sense? If so, this code needs to be
    279                         // fixed to ensure that two TypeDecls mangle to the same name when they are the same type and vice versa.
    280                         // Note: The current scheme may already work correctly for this case, I have not thought about this deeply
    281                         // and the case has not yet come up in practice. Alternatively, if not then this code can be removed
    282                         // aside from the assert false.
    283                         assertf(false, "Mangler should not visit typedecl: %s", toCString(decl));
    284                         assertf( decl->kind < ast::TypeDecl::Kind::NUMBER_OF_KINDS, "Unhandled type variable kind: %d", decl->kind );
    285                         mangleName += Encoding::typeVariables[ decl->kind ] + std::to_string( decl->name.length() ) + decl->name;
    286                 }
    287 
    288                 // For debugging:
    289                 __attribute__((unused)) void printVarMap( const std::map< std::string, std::pair< int, int > > &varMap, std::ostream &os ) {
    290                         for ( std::map< std::string, std::pair< int, int > >::const_iterator i = varMap.begin(); i != varMap.end(); ++i ) {
    291                                 os << i->first << "(" << i->second.first << "/" << i->second.second << ")" << std::endl;
    292                         } // for
    293                 }
    294 
    295                 void Mangler::printQualifiers( const ast::Type * type ) {
    296                         // skip if not including qualifiers
    297                         if ( typeMode ) return;
    298                         auto funcType = dynamic_cast<const ast::FunctionType *>( type );
    299                         if ( funcType && !funcType->forall.empty() ) {
    300                                 std::list< std::string > assertionNames;
    301                                 int dcount = 0, fcount = 0, vcount = 0, acount = 0;
    302                                 mangleName += Encoding::forall;
    303                                 for ( auto & decl : funcType->forall ) {
    304                                         switch ( decl->kind ) {
    305                                         case ast::TypeDecl::Dtype:
    306                                                 dcount++;
    307                                                 break;
    308                                         case ast::TypeDecl::Ftype:
    309                                                 fcount++;
    310                                                 break;
    311                                         case ast::TypeDecl::Ttype:
    312                                                 vcount++;
    313                                                 break;
    314                                         default:
    315                                                 assertf( false, "unimplemented kind for type variable %s", SymTab::Mangler::Encoding::typeVariables[decl->kind].c_str() );
    316                                         } // switch
    317                                         varNums[ decl->name ] = std::make_pair( nextVarNum, (int)decl->kind );
    318                                 } // for
    319                                 for ( auto & assert : funcType->assertions ) {
    320                                         assertionNames.push_back( ast::Pass<Mangler>::read(
    321                                                 assert->var.get(),
    322                                                 mangleOverridable, typeMode, mangleGenericParams, nextVarNum, varNums ) );
    323                                         acount++;
    324                                 } // for
    325                                 mangleName += std::to_string( dcount ) + "_" + std::to_string( fcount ) + "_" + std::to_string( vcount ) + "_" + std::to_string( acount ) + "_";
    326                                 for ( const auto & a : assertionNames ) mangleName += a;
    327                                 mangleName += "_";
    328                         } // if
    329                         if ( ! inFunctionType ) {
    330                                 // these qualifiers do not distinguish the outermost type of a function parameter
    331                                 if ( type->is_const() ) {
    332                                         mangleName += Encoding::qualifiers.at( ast::CV::Const );
    333                                 } // if
    334                                 if ( type->is_volatile() ) {
    335                                         mangleName += Encoding::qualifiers.at( ast::CV::Volatile );
    336                                 } // if
    337                                 // Removed due to restrict not affecting function compatibility in GCC
    338                                 // if ( type->get_isRestrict() ) {
    339                                 //      mangleName += "E";
    340                                 // } // if
    341                                 if ( type->is_atomic() ) {
    342                                         mangleName += Encoding::qualifiers.at( ast::CV::Atomic );
    343                                 } // if
    344                         }
    345                         if ( type->is_mutex() ) {
    346                                 mangleName += Encoding::qualifiers.at( ast::CV::Mutex );
    347                         } // if
    348                         if ( inFunctionType ) {
    349                                 // turn off inFunctionType so that types can be differentiated for nested qualifiers
    350                                 GuardValue( inFunctionType );
    351                                 inFunctionType = false;
    352                         }
    353                 }
    354         }       // namespace
     310                        varNums[ decl->name ] = std::make_pair( nextVarNum, (int)decl->kind );
     311                }
     312                for ( auto & assert : funcType->assertions ) {
     313                        assertionNames.push_back( ast::Pass<Mangler>::read(
     314                                assert->var.get(),
     315                                mangleOverridable, typeMode, mangleGenericParams, nextVarNum, varNums ) );
     316                        acount++;
     317                }
     318                mangleName += std::to_string( dcount ) + "_" + std::to_string( fcount ) + "_" + std::to_string( vcount ) + "_" + std::to_string( acount ) + "_";
     319                for ( const auto & a : assertionNames ) mangleName += a;
     320                mangleName += "_";
     321        }
     322        if ( !inFunctionType ) {
     323                // These qualifiers do not distinguish the outermost type of a function parameter.
     324                if ( type->is_const() ) {
     325                        mangleName += Encoding::qualifiers.at( ast::CV::Const );
     326                }
     327                if ( type->is_volatile() ) {
     328                        mangleName += Encoding::qualifiers.at( ast::CV::Volatile );
     329                }
     330                if ( type->is_atomic() ) {
     331                        mangleName += Encoding::qualifiers.at( ast::CV::Atomic );
     332                }
     333        }
     334        if ( type->is_mutex() ) {
     335                mangleName += Encoding::qualifiers.at( ast::CV::Mutex );
     336        }
     337        if ( inFunctionType ) {
     338                // Turn off inFunctionType so that types can be differentiated for nested qualifiers.
     339                GuardValue( inFunctionType ) = false;
     340        }
     341}
     342
     343}       // namespace
     344
     345std::string mangle( const ast::Node * decl, Mangle::Mode mode ) {
     346        return ast::Pass<Mangler>::read( decl, mode );
     347}
     348
    355349} // namespace Mangle
    356350
Note: See TracChangeset for help on using the changeset viewer.