Changeset b0845f9 for src/SymTab


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

Reformating and clean-up in SymTab? directory.

Location:
src/SymTab
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • src/SymTab/FixFunction.cc

    re580aa5 rb0845f9  
    2626
    2727namespace {
    28         struct FixFunction final : public ast::WithShortCircuiting {
    29                 bool isVoid = false;
    3028
    31                 void previsit( const ast::FunctionDecl * ) { visit_children = false; }
     29struct FixFunction final : public ast::WithShortCircuiting {
     30        bool isVoid = false;
    3231
    33                 const ast::DeclWithType * postvisit( const ast::FunctionDecl * func ) {
    34                         // Cannot handle cases with asserions.
    35                         assert( func->assertions.empty() );
    36                         return new ast::ObjectDecl{
    37                                 func->location, func->name, new ast::PointerType( func->type ), nullptr,
    38                                 func->storage, func->linkage, nullptr, copy( func->attributes ) };
    39                 }
     32        void previsit( const ast::FunctionDecl * ) { visit_children = false; }
    4033
    41                 void previsit( const ast::ArrayType * ) { visit_children = false; }
     34        const ast::DeclWithType * postvisit( const ast::FunctionDecl * func ) {
     35                // Cannot handle cases with asserions.
     36                assert( func->assertions.empty() );
     37                return new ast::ObjectDecl{
     38                        func->location, func->name, new ast::PointerType( func->type ), nullptr,
     39                        func->storage, func->linkage, nullptr, copy( func->attributes ) };
     40        }
    4241
    43                 const ast::Type * postvisit( const ast::ArrayType * array ) {
    44                         return new ast::PointerType{
    45                                 array->base, array->dimension, array->isVarLen, array->isStatic,
    46                                 array->qualifiers };
    47                 }
     42        void previsit( const ast::ArrayType * ) { visit_children = false; }
    4843
    49                 void previsit( const ast::FunctionType * ) { visit_children = false; }
     44        const ast::Type * postvisit( const ast::ArrayType * array ) {
     45                return new ast::PointerType{
     46                        array->base, array->dimension, array->isVarLen, array->isStatic,
     47                        array->qualifiers };
     48        }
    5049
    51                 const ast::Type * postvisit( const ast::FunctionType * type ) {
    52                         return new ast::PointerType( type );
    53                 }
     50        void previsit( const ast::FunctionType * ) { visit_children = false; }
    5451
    55                 void previsit( const ast::VoidType * ) { isVoid = true; }
     52        const ast::Type * postvisit( const ast::FunctionType * type ) {
     53                return new ast::PointerType( type );
     54        }
    5655
    57                 void previsit( const ast::BasicType * ) { visit_children = false; }
    58                 void previsit( const ast::PointerType * ) { visit_children = false; }
    59                 void previsit( const ast::StructInstType * ) { visit_children = false; }
    60                 void previsit( const ast::UnionInstType * ) { visit_children = false; }
    61                 void previsit( const ast::EnumInstType * ) { visit_children = false; }
    62                 void previsit( const ast::TraitInstType * ) { visit_children = false; }
    63                 void previsit( const ast::TypeInstType * ) { visit_children = false; }
    64                 void previsit( const ast::TupleType * ) { visit_children = false; }
    65                 void previsit( const ast::VarArgsType * ) { visit_children = false; }
    66                 void previsit( const ast::ZeroType * ) { visit_children = false; }
    67                 void previsit( const ast::OneType * ) { visit_children = false; }
    68         };
     56        void previsit( const ast::VoidType * ) { isVoid = true; }
     57
     58        void previsit( const ast::BasicType * ) { visit_children = false; }
     59        void previsit( const ast::PointerType * ) { visit_children = false; }
     60        void previsit( const ast::StructInstType * ) { visit_children = false; }
     61        void previsit( const ast::UnionInstType * ) { visit_children = false; }
     62        void previsit( const ast::EnumInstType * ) { visit_children = false; }
     63        void previsit( const ast::TraitInstType * ) { visit_children = false; }
     64        void previsit( const ast::TypeInstType * ) { visit_children = false; }
     65        void previsit( const ast::TupleType * ) { visit_children = false; }
     66        void previsit( const ast::VarArgsType * ) { visit_children = false; }
     67        void previsit( const ast::ZeroType * ) { visit_children = false; }
     68        void previsit( const ast::OneType * ) { visit_children = false; }
     69};
     70
    6971} // anonymous namespace
    7072
  • src/SymTab/FixFunction.h

    re580aa5 rb0845f9  
    2222
    2323namespace SymTab {
    24         /// Returns declaration with function and array types replaced by equivalent pointer types.
    25         /// Sets isVoid to true if type is void
    26         const ast::DeclWithType * fixFunction( const ast::DeclWithType * dwt, bool & isVoid );
    27         const ast::Type * fixFunction( const ast::Type * type, bool & isVoid );
     24
     25/// Returns declaration with function and array types replaced by equivalent pointer types.
     26/// Sets isVoid to true if type is void.
     27const ast::DeclWithType * fixFunction( const ast::DeclWithType * dwt, bool & isVoid );
     28const ast::Type * fixFunction( const ast::Type * type, bool & isVoid );
     29
    2830} // namespace SymTab
    2931
  • 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
  • src/SymTab/Mangler.h

    re580aa5 rb0845f9  
    3434}
    3535
    36 namespace SymTab {
    37         namespace Mangler {
    38                 namespace Encoding {
    39                         extern const std::string manglePrefix;
    40                         extern const std::string basicTypes[];
    41                         extern const std::map<int, std::string> qualifiers;
     36namespace Mangle {
    4237
    43                         extern const std::string void_t;
    44                         extern const std::string zero;
    45                         extern const std::string one;
     38/// Bitflags for mangle Mode:
     39enum {
     40        NoOverrideable  = 1 << 0,
     41        Type            = 1 << 1,
     42        NoGenericParams = 1 << 2
     43};
    4644
    47                         extern const std::string function;
    48                         extern const std::string tuple;
    49                         extern const std::string pointer;
    50                         extern const std::string array;
    51                         extern const std::string qualifiedTypeStart;
    52                         extern const std::string qualifiedTypeEnd;
    53 
    54                         extern const std::string forall;
    55                         extern const std::string typeVariables[];
    56 
    57                         extern const std::string struct_t;
    58                         extern const std::string union_t;
    59                         extern const std::string enum_t;
    60                         extern const std::string type;
    61 
    62                         extern const std::string autogen;
    63                         extern const std::string intrinsic;
     45/// Bitflag type for mangle Mode:
     46struct mangle_flags {
     47        union {
     48                unsigned int val;
     49                struct {
     50                        bool no_overrideable   : 1;
     51                        bool type              : 1;
     52                        bool no_generic_params : 1;
    6453                };
    65         } // Mangler
    66 } // SymTab
    67 
    68 namespace Mangle {
    69         /// Bitflags for mangle modes
    70         enum {
    71                 NoOverrideable  = 1 << 0,
    72                 Type            = 1 << 1,
    73                 NoGenericParams = 1 << 2
    7454        };
    7555
    76         /// Bitflag type for mangler modes
    77         struct mangle_flags {
    78                 union {
    79                         unsigned int val;
    80                         struct {
    81                                 bool no_overrideable   : 1;
    82                                 bool type              : 1;
    83                                 bool no_generic_params : 1;
    84                         };
    85                 };
     56        constexpr mangle_flags( unsigned int val ) : val(val) {}
     57};
    8658
    87                 constexpr mangle_flags( unsigned int val ) : val(val) {}
    88         };
     59using Mode = bitfield<mangle_flags>;
    8960
    90         using Mode = bitfield<mangle_flags>;
     61/// Mangle declaration name.
     62std::string mangle( const ast::Node * decl, Mode mode = {} );
    9163
    92         /// Mangle declaration name.
    93         std::string mangle( const ast::Node * decl, Mode mode = {} );
     64/// Most common mangle configuration for types.
     65static inline std::string mangleType( const ast::Node * type ) {
     66        return mangle( type, { NoOverrideable | Type } );
     67}
    9468
    95         /// Most common mangle configuration for types.
    96         static inline std::string mangleType( const ast::Node * type ) {
    97                 return mangle( type, { NoOverrideable | Type } );
    98         }
     69/// The substrings used in name mangling and demangling.
     70namespace Encoding {
     71        extern const std::string manglePrefix;
     72        extern const std::string basicTypes[];
     73        extern const std::map<int, std::string> qualifiers;
    9974
    100         namespace Encoding {
    101                 using namespace SymTab::Mangler::Encoding;
    102         };
     75        extern const std::string void_t;
     76        extern const std::string zero;
     77        extern const std::string one;
     78
     79        extern const std::string function;
     80        extern const std::string tuple;
     81        extern const std::string pointer;
     82        extern const std::string array;
     83        extern const std::string qualifiedTypeStart;
     84        extern const std::string qualifiedTypeEnd;
     85
     86        extern const std::string forall;
     87        extern const std::string typeVariables[];
     88
     89        extern const std::string struct_t;
     90        extern const std::string union_t;
     91        extern const std::string enum_t;
     92        extern const std::string type;
     93
     94        extern const std::string autogen;
     95        extern const std::string intrinsic;
     96}
     97
    10398}
    10499
  • src/SymTab/ManglerCommon.cc

    re580aa5 rb0845f9  
    1919#include "AST/Type.hpp"
    2020
    21 namespace SymTab {
    22         namespace Mangler {
    23                 namespace Encoding {
    24                         const std::string manglePrefix = "_X";
     21namespace Mangle {
    2522
    26                         // GENERATED START, DO NOT EDIT
    27                         // GENERATED BY BasicTypes-gen.cc
    28                         // NOTES ON MANGLING:
    29                         // * Itanium spec says that Float80 encodes to "e" (like LongDouble), but the distinct lengths cause resolution problems.
    30                         // * Float128 is supposed to encode to "g", but I wanted it to mangle equal to LongDouble.
    31                         // * Mangling for non-standard complex types is by best guess
    32                         // * _FloatN is supposed to encode as "DF"N"_"; modified for same reason as above.
    33                         // * unused mangling identifiers:
    34                         //   - "z" ellipsis
    35                         //   - "Dd" IEEE 754r 64-bit decimal floating point (borrowed for _Float32x)
    36                         //   - "De" IEEE 754r 128-bit decimal floating point
    37                         //   - "Df" IEEE 754r 32-bit decimal floating point
    38                         //   - "Dh" IEEE 754r 16-bit decimal floating point (borrowed for _Float16)
    39                         //   - "DF"N"_" ISO/IEC TS 18661 N-bit binary floating point (_FloatN)
    40                         //   - "Di" char32_t
    41                         //   - "Ds" char16_t
    42                         const std::string basicTypes[ast::BasicType::NUMBER_OF_BASIC_TYPES] = {
    43                                 "b",        // _Bool
    44                                 "c",        // char
    45                                 "a",        // signed char
    46                                 "h",        // unsigned char
    47                                 "s",        // signed short int
    48                                 "t",        // unsigned short int
    49                                 "i",        // signed int
    50                                 "j",        // unsigned int
    51                                 "l",        // signed long int
    52                                 "m",        // unsigned long int
    53                                 "x",        // signed long long int
    54                                 "y",        // unsigned long long int
    55                                 "n",        // __int128
    56                                 "o",        // unsigned __int128
    57                                 "DF16_",    // _Float16
    58                                 "CDF16_",   // _Float16 _Complex
    59                                 "DF32_",    // _Float32
    60                                 "CDF32_",   // _Float32 _Complex
    61                                 "f",        // float
    62                                 "Cf",       // float _Complex
    63                                 "DF32x_",   // _Float32x
    64                                 "CDF32x_",  // _Float32x _Complex
    65                                 "DF64_",    // _Float64
    66                                 "CDF64_",   // _Float64 _Complex
    67                                 "d",        // double
    68                                 "Cd",       // double _Complex
    69                                 "DF64x_",   // _Float64x
    70                                 "CDF64x_",  // _Float64x _Complex
    71                                 "Dq",       // __float80
    72                                 "DF128_",   // _Float128
    73                                 "CDF128_",  // _Float128 _Complex
    74                                 "g",        // __float128
    75                                 "e",        // long double
    76                                 "Ce",       // long double _Complex
    77                                 "DF128x_",  // _Float128x
    78                                 "CDF128x_", // _Float128x _Complex
    79                         }; // basicTypes
    80                         // GENERATED END
    81                         static_assert(
    82                                 sizeof(basicTypes)/sizeof(basicTypes[0]) == ast::BasicType::NUMBER_OF_BASIC_TYPES,
    83                                 "Each basic type kind should have a corresponding mangler letter"
    84                         );
     23namespace Encoding {
    8524
    86                         const std::map<int, std::string> qualifiers = {
    87                                 { ast::CV::Const, "K" },
    88                                 { ast::CV::Volatile, "V" },
    89                                 { ast::CV::Atomic, "DA" }, // A is array, so need something unique for atmoic. For now, go with multiletter DA
    90                                 { ast::CV::Mutex, "X" },
    91                         };
     25const std::string manglePrefix = "_X";
    9226
    93                         const std::string void_t = "v";
    94                         const std::string zero = "Z";
    95                         const std::string one = "O";
     27// GENERATED START, DO NOT EDIT
     28// GENERATED BY BasicTypes-gen.cc
     29// NOTES ON MANGLING:
     30// * Itanium spec says that Float80 encodes to "e" (like LongDouble), but the distinct lengths cause resolution problems.
     31// * Float128 is supposed to encode to "g", but I wanted it to mangle equal to LongDouble.
     32// * Mangling for non-standard complex types is by best guess
     33// * _FloatN is supposed to encode as "DF"N"_"; modified for same reason as above.
     34// * unused mangling identifiers:
     35//   - "z" ellipsis
     36//   - "Dd" IEEE 754r 64-bit decimal floating point (borrowed for _Float32x)
     37//   - "De" IEEE 754r 128-bit decimal floating point
     38//   - "Df" IEEE 754r 32-bit decimal floating point
     39//   - "Dh" IEEE 754r 16-bit decimal floating point (borrowed for _Float16)
     40//   - "DF"N"_" ISO/IEC TS 18661 N-bit binary floating point (_FloatN)
     41//   - "Di" char32_t
     42//   - "Ds" char16_t
     43const std::string basicTypes[ast::BasicType::NUMBER_OF_BASIC_TYPES] = {
     44        "b",        // _Bool
     45        "c",        // char
     46        "a",        // signed char
     47        "h",        // unsigned char
     48        "s",        // signed short int
     49        "t",        // unsigned short int
     50        "i",        // signed int
     51        "j",        // unsigned int
     52        "l",        // signed long int
     53        "m",        // unsigned long int
     54        "x",        // signed long long int
     55        "y",        // unsigned long long int
     56        "n",        // __int128
     57        "o",        // unsigned __int128
     58        "DF16_",    // _Float16
     59        "CDF16_",   // _Float16 _Complex
     60        "DF32_",    // _Float32
     61        "CDF32_",   // _Float32 _Complex
     62        "f",        // float
     63        "Cf",       // float _Complex
     64        "DF32x_",   // _Float32x
     65        "CDF32x_",  // _Float32x _Complex
     66        "DF64_",    // _Float64
     67        "CDF64_",   // _Float64 _Complex
     68        "d",        // double
     69        "Cd",       // double _Complex
     70        "DF64x_",   // _Float64x
     71        "CDF64x_",  // _Float64x _Complex
     72        "Dq",       // __float80
     73        "DF128_",   // _Float128
     74        "CDF128_",  // _Float128 _Complex
     75        "g",        // __float128
     76        "e",        // long double
     77        "Ce",       // long double _Complex
     78        "DF128x_",  // _Float128x
     79        "CDF128x_", // _Float128x _Complex
     80}; // basicTypes
     81// GENERATED END
     82static_assert(
     83        sizeof(basicTypes) / sizeof(basicTypes[0]) == ast::BasicType::NUMBER_OF_BASIC_TYPES,
     84        "Each basic type kind should have a corresponding mangler letter"
     85);
    9686
    97                         const std::string function = "F";
    98                         const std::string tuple = "T";
    99                         const std::string pointer = "P";
    100                         const std::string array = "A";
    101                         const std::string qualifiedTypeStart = "N";
    102                         const std::string qualifiedTypeEnd = "E";
     87const std::map<int, std::string> qualifiers = {
     88        { ast::CV::Const, "K" },
     89        { ast::CV::Volatile, "V" },
     90        { ast::CV::Atomic, "DA" }, // A is array, so need something unique for atmoic. For now, go with multiletter DA
     91        { ast::CV::Mutex, "X" },
     92};
    10393
    104                         const std::string forall = "Q";
    105                         const std::string typeVariables[] = {
    106                                 "BD", // dtype
    107                                 "BDS", // dtype + sized
    108                                 "BO", // otype
    109                                 "BF", // ftype
    110                                 "BT", // ttype
    111                                 "BAL", // array length type
    112                         };
    113                         static_assert(
    114                                 sizeof(typeVariables) / sizeof(typeVariables[0]) == ast::TypeDecl::NUMBER_OF_KINDS,
    115                                 "Each type variable kind should have a corresponding mangler prefix"
    116                         );
     94const std::string void_t = "v";
     95const std::string zero = "Z";
     96const std::string one = "O";
    11797
    118                         const std::string struct_t = "S";
    119                         const std::string union_t = "U";
    120                         const std::string enum_t = "M";
    121                         const std::string type = "Y";
     98const std::string function = "F";
     99const std::string tuple = "T";
     100const std::string pointer = "P";
     101const std::string array = "A";
     102const std::string qualifiedTypeStart = "N";
     103const std::string qualifiedTypeEnd = "E";
    122104
    123                         const std::string autogen = "autogen__";
    124                         const std::string intrinsic = "intrinsic__";
    125                 } // namespace Encoding
    126         } // namespace Mangler
    127 } // namespace SymTab
     105const std::string forall = "Q";
     106const std::string typeVariables[] = {
     107        "BD", // dtype
     108        "BDS", // dtype + sized
     109        "BO", // otype
     110        "BF", // ftype
     111        "BT", // ttype
     112        "BAL", // array length type
     113};
     114static_assert(
     115        sizeof(typeVariables) / sizeof(typeVariables[0]) == ast::TypeDecl::NUMBER_OF_KINDS,
     116        "Each type variable kind should have a corresponding mangler prefix"
     117);
     118
     119const std::string struct_t = "S";
     120const std::string union_t = "U";
     121const std::string enum_t = "M";
     122const std::string type = "Y";
     123
     124const std::string autogen = "autogen__";
     125const std::string intrinsic = "intrinsic__";
     126
     127} // namespace Encoding
     128
     129} // namespace Mangle
Note: See TracChangeset for help on using the changeset viewer.