Changeset 642bc83


Ignore:
Timestamp:
Aug 2, 2018, 11:09:03 AM (6 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, no_list, persistent-indexer, pthread-emulation, qualifiedEnum
Children:
4285544e
Parents:
3bbd012
Message:

Modify name mangling scheme to more closely resembly itanium C++ name mangling

Location:
src/SymTab
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • src/SymTab/Mangler.cc

    r3bbd012 r642bc83  
    7373                                bool mangleGenericParams;       ///< Include generic parameters in name mangling if true
    7474                                bool inFunctionType = false;    ///< Include type qualifiers if false.
     75                                bool inQualifiedType = false;   ///< Add start/end delimiters around qualified type
    7576
    7677                                void mangleDecl( DeclarationWithType *declaration );
     
    110111                                        isTopLevel = false;
    111112                                } // if
    112                                 mangleName << "__";
     113                                mangleName << Encoding::manglePrefix;
    113114                                CodeGen::OperatorInfo opInfo;
    114115                                if ( operatorLookup( declaration->get_name(), opInfo ) ) {
    115                                         mangleName << opInfo.outputName;
     116                                        mangleName << opInfo.outputName.size() << opInfo.outputName;
    116117                                } else {
    117                                         mangleName << declaration->get_name();
    118                                 } // if
    119                                 mangleName << nameSeparator;
     118                                        mangleName << declaration->name.size() << declaration->name;
     119                                } // if
    120120                                maybeAccept( declaration->get_type(), *visitor );
    121121                                if ( mangleOverridable && LinkageSpec::isOverridable( declaration->get_linkage() ) ) {
     
    123123                                        // so they need a different name mangling
    124124                                        if ( declaration->get_linkage() == LinkageSpec::AutoGen ) {
    125                                                 mangleName << "autogen__";
     125                                                mangleName << Encoding::autogen;
    126126                                        } else if ( declaration->get_linkage() == LinkageSpec::Intrinsic ) {
    127                                                 mangleName << "intrinsic__";
     127                                                mangleName << Encoding::intrinsic;
    128128                                        } else {
    129129                                                // if we add another kind of overridable function, this has to change
     
    144144                        void Mangler::postvisit( VoidType * voidType ) {
    145145                                printQualifiers( voidType );
    146                                 mangleName << "v";
     146                                mangleName << Encoding::voidType;
    147147                        }
    148148
    149149                        void Mangler::postvisit( BasicType * basicType ) {
    150150                                printQualifiers( basicType );
    151                                 assert( basicType->get_kind() < numBtLetter );
    152                                 mangleName << btLetter[ basicType->get_kind() ];
     151                                assert( basicType->get_kind() < BasicType::NUMBER_OF_BASIC_TYPES );
     152                                mangleName << Encoding::basicTypes[ basicType->get_kind() ];
    153153                        }
    154154
     
    156156                                printQualifiers( pointerType );
    157157                                // mangle void (*f)() and void f() to the same name to prevent overloading on functions and function pointers
    158                                 if ( ! dynamic_cast<FunctionType *>( pointerType->base ) ) mangleName << "P";
     158                                if ( ! dynamic_cast<FunctionType *>( pointerType->base ) ) mangleName << Encoding::pointer;
    159159                                maybeAccept( pointerType->base, *visitor );
    160160                        }
     
    163163                                // TODO: encode dimension
    164164                                printQualifiers( arrayType );
    165                                 mangleName << "A0";
     165                                mangleName << Encoding::array << "0";
    166166                                maybeAccept( arrayType->base, *visitor );
    167167                        }
     
    188188                        void Mangler::postvisit( FunctionType * functionType ) {
    189189                                printQualifiers( functionType );
    190                                 mangleName << "F";
     190                                mangleName << Encoding::function;
    191191                                // turn on inFunctionType so that printQualifiers does not print most qualifiers for function parameters,
    192192                                // since qualifiers on outermost parameter type do not differentiate function types, e.g.,
     
    195195                                inFunctionType = true;
    196196                                std::list< Type* > returnTypes = getTypes( functionType->returnVals );
    197                                 if (returnTypes.empty()) mangleName << "v";
     197                                if (returnTypes.empty()) mangleName << Encoding::voidType;
    198198                                else acceptAll( returnTypes, *visitor );
    199199                                mangleName << "_";
     
    206206                                printQualifiers( refType );
    207207
    208                                 mangleName << ( refType->name.length() + prefix.length() ) << prefix << refType->name;
     208                                mangleName << prefix << refType->name.length() << refType->name;
    209209
    210210                                if ( mangleGenericParams ) {
     
    261261                        void Mangler::postvisit( TraitInstType * inst ) {
    262262                                printQualifiers( inst );
    263                                 mangleName << "_Y" << inst->name << "_";
     263                                mangleName << inst->name.size() << inst->name;
    264264                        }
    265265
    266266                        void Mangler::postvisit( TupleType * tupleType ) {
    267267                                printQualifiers( tupleType );
    268                                 mangleName << "T";
     268                                mangleName << Encoding::tuple << tupleType->types.size();
    269269                                acceptAll( tupleType->types, *visitor );
    270                                 mangleName << "_";
    271270                        }
    272271
    273272                        void Mangler::postvisit( VarArgsType * varArgsType ) {
    274273                                printQualifiers( varArgsType );
    275                                 mangleName << "VARGS";
     274                                static const std::string vargs = "__builtin_va_list";
     275                                mangleName << vargs.size() << vargs;
    276276                        }
    277277
    278278                        void Mangler::postvisit( ZeroType * ) {
    279                                 mangleName << "Z";
     279                                mangleName << Encoding::zero;
    280280                        }
    281281
    282282                        void Mangler::postvisit( OneType * ) {
    283                                 mangleName << "O";
     283                                mangleName << Encoding::one;
    284284                        }
    285285
    286286                        void Mangler::postvisit( QualifiedType * qualType ) {
     287                                bool inqual = inQualifiedType;
     288                                if (! inqual ) {
     289                                        // N marks the start of a qualified type
     290                                        inQualifiedType = true;
     291                                        mangleName << Encoding::qualifiedTypeStart;
     292                                }
    287293                                maybeAccept( qualType->parent, *visitor );
    288                                 mangleName << "__";
    289294                                maybeAccept( qualType->child, *visitor );
     295                                if ( ! inqual ) {
     296                                        // E marks the end of a qualified type
     297                                        inQualifiedType = false;
     298                                        mangleName << Encoding::qualifiedTypeEnd;
     299                                }
    290300                        }
    291301
     
    339349                                        // these qualifiers do not distinguish the outermost type of a function parameter
    340350                                        if ( type->get_const() ) {
    341                                                 mangleName << "C";
     351                                                mangleName << Encoding::qualifiers.at(Type::Const);
    342352                                        } // if
    343353                                        if ( type->get_volatile() ) {
    344                                                 mangleName << "V";
     354                                                mangleName << Encoding::qualifiers.at(Type::Volatile);
    345355                                        } // if
    346356                                        // Removed due to restrict not affecting function compatibility in GCC
     
    349359                                        // } // if
    350360                                        if ( type->get_atomic() ) {
    351                                                 mangleName << "A";
     361                                                mangleName << Encoding::qualifiers.at(Type::Atomic);
    352362                                        } // if
    353363                                }
    354364                                if ( type->get_mutex() ) {
    355                                         mangleName << "M";
     365                                        mangleName << Encoding::qualifiers.at(Type::Mutex);
    356366                                } // if
    357367                                if ( type->get_lvalue() ) {
    358368                                        // mangle based on whether the type is lvalue, so that the resolver can differentiate lvalues and rvalues
    359                                         mangleName << "L";
     369                                        mangleName << Encoding::qualifiers.at(Type::Lvalue);
    360370                                }
    361371
  • src/SymTab/Mangler.h

    r3bbd012 r642bc83  
    2424#include "SynTree/Visitor.h"  // for Visitor, maybeAccept
    2525
     26// https://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangling
     27// The CFA name mangling scheme is based closely on the itanium C++ name mangling scheme, with the following key differences:
     28// * Variable names are also mangled to include type information, not just functions
     29// * CFA does not have template expansion, so the rules for function specialization do not apply.
     30// * CFA instead has to handle type parameters and assertion parameters.
     31// * Currently name compression is not implemented.
     32
    2633namespace SymTab {
    2734        namespace Mangler {
     
    3441                std::string mangleConcrete( Type* ty );
    3542
    36                 extern const char *btLetter[];
    37                 extern const int numBtLetter;
    38                 extern const std::map<int, const char *> qualifierLetter;
    39                 extern const std::string nameSeparator;
     43                namespace Encoding {
     44                        extern const std::string manglePrefix;
     45                        extern const std::string basicTypes[];
     46                        extern const std::map<int, std::string> qualifiers;
     47
     48                        extern const std::string voidType;
     49                        extern const std::string zero;
     50                        extern const std::string one;
     51
     52                        extern const std::string function;
     53                        extern const std::string tuple;
     54                        extern const std::string pointer;
     55                        extern const std::string array;
     56                        extern const std::string qualifiedTypeStart;
     57                        extern const std::string qualifiedTypeEnd;
     58
     59                        extern const std::string autogen;
     60                        extern const std::string intrinsic;
     61                };
    4062        } // Mangler
    4163} // SymTab
  • src/SymTab/ManglerCommon.cc

    r3bbd012 r642bc83  
    1919namespace SymTab {
    2020        namespace Mangler {
    21                 const char * btLetter[] = {
    22                         "b",  // Bool
    23                         "c",  // Char
    24                         "Sc", // SignedChar
    25                         "Uc", // UnsignedChar
    26                         "s",  // ShortSignedInt
    27                         "Us", // ShortUnsignedInt
    28                         "i",  // SignedInt
    29                         "Ui", // UnsignedInt
    30                         "l",  // LongSignedInt
    31                         "Ul", // LongUnsignedInt
    32                         "q",  // LongLongSignedInt
    33                         "Uq", // LongLongUnsignedInt
    34                         "f",  // Float
    35                         "d",  // Double
    36                         "r",  // LongDouble
    37                         "Xf", // FloatComplex
    38                         "Xd", // DoubleComplex
    39                         "Xr", // LongDoubleComplex
    40                         "If", // FloatImaginary
    41                         "Id", // DoubleImaginary
    42                         "Ir", // LongDoubleImaginary
    43                         "w",  // SignedInt128
    44                         "Uw", // UnsignedInt128
    45                         "x",  // Float80
    46                         "y",  // Float128
    47                 };
    48                 const int numBtLetter = sizeof(btLetter)/sizeof(btLetter[0]);
    49                 static_assert(
    50                         numBtLetter == BasicType::NUMBER_OF_BASIC_TYPES,
    51                         "Each basic type kind should have a corresponding mangler letter"
    52                 );
     21                namespace Encoding {
     22                        const std::string manglePrefix = "_X";
    5323
    54                 const std::map<int, const char *> qualifierLetter = {
    55                         { Type::Const, "C" },
    56                         { Type::Volatile, "V" },
    57                         { Type::Atomic, "A" }, // A = Atomic, A0 = Array and forall parameter...
    58                         { Type::Mutex, "M" },
    59                         { Type::Lvalue, "L" },
    60                 };
     24                        const std::string basicTypes[] = {
     25                                "b",  // Bool
     26                                "c",  // Char
     27                                "a",  // SignedChar
     28                                "h",  // UnsignedChar
     29                                "s",  // ShortSignedInt
     30                                "t",  // ShortUnsignedInt
     31                                "i",  // SignedInt
     32                                "j",  // UnsignedInt
     33                                "l",  // LongSignedInt
     34                                "m",  // LongUnsignedInt
     35                                "x",  // LongLongSignedInt
     36                                "y",  // LongLongUnsignedInt
     37                                "f",  // Float
     38                                "d",  // Double
     39                                "e",  // LongDouble
     40                                "Cf", // FloatComplex
     41                                "Cd", // DoubleComplex
     42                                "Ce", // LongDoubleComplex
     43                                // Note: imaginary is not an overloadable type in C++
     44                                "If", // FloatImaginary
     45                                "Id", // DoubleImaginary
     46                                "Ie", // LongDoubleImaginary
     47                                "n",  // SignedInt128
     48                                "o",  // UnsignedInt128
     49                                "Dq",  // Float80 -- TODO: itanium says Float80 and LongDouble both encode to "e", but doing this causes problems with constructing long double, because the cost tables are incorrect
     50                                "g",  // Float128
     51                                // "z", // ellipsis
     52                                // "Dd" // # IEEE 754r decimal floating point (64 bits)
     53                                // "De" // # IEEE 754r decimal floating point (128 bits)
     54                                // "Df" // # IEEE 754r decimal floating point (32 bits)
     55                                // "Dh" // # IEEE 754r half-precision floating point (16 bits)
     56                                // "DF"N_ // # ISO/IEC TS 18661 binary floating point type _FloatN (N bits)
     57                                // "Di" // char32_t
     58                                // "Ds" // char16_t
     59                        };
     60                        static_assert(
     61                                sizeof(basicTypes)/sizeof(basicTypes[0]) == BasicType::NUMBER_OF_BASIC_TYPES,
     62                                "Each basic type kind should have a corresponding mangler letter"
     63                        );
    6164
    62                 const std::string nameSeparator = "__cfa__";
     65                        const std::map<int, std::string> qualifiers = {
     66                                { Type::Const, "C" },
     67                                { Type::Volatile, "V" },
     68                                { Type::Atomic, "A" }, // A = Atomic, A0 = Array and forall parameter...
     69                                { Type::Mutex, "M" },
     70                                { Type::Lvalue, "L" },
     71                        };
     72
     73                        const std::string voidType = "v";
     74                        const std::string zero = "Z";
     75                        const std::string one = "O";
     76
     77                        const std::string function = "F";
     78                        const std::string tuple = "T";
     79                        const std::string pointer = "P";
     80                        const std::string array = "A";
     81                        const std::string qualifiedTypeStart = "N";
     82                        const std::string qualifiedTypeEnd = "E";
     83
     84                        const std::string autogen = "autogen__";
     85                        const std::string intrinsic = "intrinsic__";
     86                } // namespace Encoding
    6387        } // namespace Mangler
    6488} // namespace SymTab
Note: See TracChangeset for help on using the changeset viewer.