Changeset cdbab55 for src/SymTab


Ignore:
Timestamp:
Aug 21, 2018, 2:24:29 PM (7 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, no_list, persistent-indexer, pthread-emulation, qualifiedEnum
Children:
2a6292d
Parents:
2b79a70 (diff), efa8b6a (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg.uwaterloo.ca:/u/cforall/software/cfa/cfa-cc

Location:
src/SymTab
Files:
3 added
3 edited

Legend:

Unmodified
Added
Removed
  • src/SymTab/Mangler.cc

    r2b79a70 rcdbab55  
    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 << "__";
     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::void_t;
    147147                        }
    148148
    149149                        void Mangler::postvisit( BasicType * basicType ) {
    150                                 static const char *btLetter[] = {
    151                                         "b",    // Bool
    152                                         "c",    // Char
    153                                         "Sc",   // SignedChar
    154                                         "Uc",   // UnsignedChar
    155                                         "s",    // ShortSignedInt
    156                                         "Us",   // ShortUnsignedInt
    157                                         "i",    // SignedInt
    158                                         "Ui",   // UnsignedInt
    159                                         "l",    // LongSignedInt
    160                                         "Ul",   // LongUnsignedInt
    161                                         "q",    // LongLongSignedInt
    162                                         "Uq",   // LongLongUnsignedInt
    163                                         "f",    // Float
    164                                         "d",    // Double
    165                                         "r",    // LongDouble
    166                                         "Xf",   // FloatComplex
    167                                         "Xd",   // DoubleComplex
    168                                         "Xr",   // LongDoubleComplex
    169                                         "If",   // FloatImaginary
    170                                         "Id",   // DoubleImaginary
    171                                         "Ir",   // LongDoubleImaginary
    172                                         "w",    // SignedInt128
    173                                         "Uw",   // UnsignedInt128
    174                                         "x",    // Float80
    175                                         "y",    // Float128
    176                                 };
    177                                 static_assert(
    178                                         sizeof(btLetter)/sizeof(btLetter[0]) == BasicType::NUMBER_OF_BASIC_TYPES,
    179                                         "Each basic type kind should have a corresponding mangler letter"
    180                                 );
    181 
    182150                                printQualifiers( basicType );
    183                                 assert( basicType->get_kind() < sizeof(btLetter)/sizeof(btLetter[0]) );
    184                                 mangleName << btLetter[ basicType->get_kind() ];
     151                                assertf( basicType->get_kind() < BasicType::NUMBER_OF_BASIC_TYPES, "Unhandled basic type: %d", basicType->get_kind() );
     152                                mangleName << Encoding::basicTypes[ basicType->get_kind() ];
    185153                        }
    186154
     
    188156                                printQualifiers( pointerType );
    189157                                // mangle void (*f)() and void f() to the same name to prevent overloading on functions and function pointers
    190                                 if ( ! dynamic_cast<FunctionType *>( pointerType->base ) ) mangleName << "P";
     158                                if ( ! dynamic_cast<FunctionType *>( pointerType->base ) ) mangleName << Encoding::pointer;
    191159                                maybeAccept( pointerType->base, *visitor );
    192160                        }
     
    195163                                // TODO: encode dimension
    196164                                printQualifiers( arrayType );
    197                                 mangleName << "A0";
     165                                mangleName << Encoding::array << "0";
    198166                                maybeAccept( arrayType->base, *visitor );
    199167                        }
     
    220188                        void Mangler::postvisit( FunctionType * functionType ) {
    221189                                printQualifiers( functionType );
    222                                 mangleName << "F";
     190                                mangleName << Encoding::function;
    223191                                // turn on inFunctionType so that printQualifiers does not print most qualifiers for function parameters,
    224192                                // since qualifiers on outermost parameter type do not differentiate function types, e.g.,
     
    227195                                inFunctionType = true;
    228196                                std::list< Type* > returnTypes = getTypes( functionType->returnVals );
    229                                 acceptAll( returnTypes, *visitor );
     197                                if (returnTypes.empty()) mangleName << Encoding::void_t;
     198                                else acceptAll( returnTypes, *visitor );
    230199                                mangleName << "_";
    231200                                std::list< Type* > paramTypes = getTypes( functionType->parameters );
     
    237206                                printQualifiers( refType );
    238207
    239                                 mangleName << ( refType->name.length() + prefix.length() ) << prefix << refType->name;
     208                                mangleName << prefix << refType->name.length() << refType->name;
    240209
    241210                                if ( mangleGenericParams ) {
     
    254223
    255224                        void Mangler::postvisit( StructInstType * aggregateUseType ) {
    256                                 mangleRef( aggregateUseType, "s" );
     225                                mangleRef( aggregateUseType, Encoding::struct_t );
    257226                        }
    258227
    259228                        void Mangler::postvisit( UnionInstType * aggregateUseType ) {
    260                                 mangleRef( aggregateUseType, "u" );
     229                                mangleRef( aggregateUseType, Encoding::union_t );
    261230                        }
    262231
    263232                        void Mangler::postvisit( EnumInstType * aggregateUseType ) {
    264                                 mangleRef( aggregateUseType, "e" );
     233                                mangleRef( aggregateUseType, Encoding::enum_t );
    265234                        }
    266235
     
    268237                                VarMapType::iterator varNum = varNums.find( typeInst->get_name() );
    269238                                if ( varNum == varNums.end() ) {
    270                                         mangleRef( typeInst, "t" );
     239                                        mangleRef( typeInst, Encoding::type );
    271240                                } else {
    272241                                        printQualifiers( typeInst );
    273                                         std::ostringstream numStream;
    274                                         numStream << varNum->second.first;
    275                                         switch ( (TypeDecl::Kind )varNum->second.second ) {
    276                                           case TypeDecl::Dtype:
    277                                                 mangleName << "d";
    278                                                 break;
    279                                           case TypeDecl::Ftype:
    280                                                 mangleName << "f";
    281                                                 break;
    282                                                 case TypeDecl::Ttype:
    283                                                 mangleName << "tVARGS";
    284                                                 break;
    285                                                 default:
    286                                                 assert( false );
    287                                         } // switch
    288                                         mangleName << numStream.str();
     242                                        // Note: Can't use name here, since type variable names do not actually disambiguate a function, e.g.
     243                                        //   forall(dtype T) void f(T);
     244                                        //   forall(dtype S) void f(S);
     245                                        // are equivalent and should mangle the same way. This is accomplished by numbering the type variables when they
     246                                        // are first found and prefixing with the appropriate encoding for the type class.
     247                                        assertf( varNum->second.second < TypeDecl::NUMBER_OF_KINDS, "Unhandled type variable kind: %d", varNum->second.second );
     248                                        mangleName << Encoding::typeVariables[varNum->second.second] << varNum->second.first;
    289249                                } // if
    290250                        }
     
    292252                        void Mangler::postvisit( TraitInstType * inst ) {
    293253                                printQualifiers( inst );
    294                                 mangleName << "_Y" << inst->name << "_";
     254                                mangleName << inst->name.size() << inst->name;
    295255                        }
    296256
    297257                        void Mangler::postvisit( TupleType * tupleType ) {
    298258                                printQualifiers( tupleType );
    299                                 mangleName << "T";
     259                                mangleName << Encoding::tuple << tupleType->types.size();
    300260                                acceptAll( tupleType->types, *visitor );
    301                                 mangleName << "_";
    302261                        }
    303262
    304263                        void Mangler::postvisit( VarArgsType * varArgsType ) {
    305264                                printQualifiers( varArgsType );
    306                                 mangleName << "VARGS";
     265                                static const std::string vargs = "__builtin_va_list";
     266                                mangleName << Encoding::type << vargs.size() << vargs;
    307267                        }
    308268
    309269                        void Mangler::postvisit( ZeroType * ) {
    310                                 mangleName << "Z";
     270                                mangleName << Encoding::zero;
    311271                        }
    312272
    313273                        void Mangler::postvisit( OneType * ) {
    314                                 mangleName << "O";
     274                                mangleName << Encoding::one;
    315275                        }
    316276
    317277                        void Mangler::postvisit( QualifiedType * qualType ) {
     278                                bool inqual = inQualifiedType;
     279                                if (! inqual ) {
     280                                        // N marks the start of a qualified type
     281                                        inQualifiedType = true;
     282                                        mangleName << Encoding::qualifiedTypeStart;
     283                                }
    318284                                maybeAccept( qualType->parent, *visitor );
    319                                 mangleName << "__";
    320285                                maybeAccept( qualType->child, *visitor );
     286                                if ( ! inqual ) {
     287                                        // E marks the end of a qualified type
     288                                        inQualifiedType = false;
     289                                        mangleName << Encoding::qualifiedTypeEnd;
     290                                }
    321291                        }
    322292
    323293                        void Mangler::postvisit( TypeDecl * decl ) {
    324                                 static const char *typePrefix[] = { "BT", "BD", "BF" };
    325                                 mangleName << typePrefix[ decl->get_kind() ] << ( decl->name.length() + 1 ) << decl->name;
     294                                // TODO: is there any case where mangling a TypeDecl makes sense? If so, this code needs to be
     295                                // fixed to ensure that two TypeDecls mangle to the same name when they are the same type and vice versa.
     296                                // Note: The current scheme may already work correctly for this case, I have not thought about this deeply
     297                                // and the case has not yet come up in practice. Alternatively, if not then this code can be removed
     298                                // aside from the assert false.
     299                                assertf(false, "Mangler should not visit typedecl: %s", toCString(decl));
     300                                assertf( decl->get_kind() < TypeDecl::NUMBER_OF_KINDS, "Unhandled type variable kind: %d", decl->get_kind() );
     301                                mangleName << Encoding::typeVariables[ decl->get_kind() ] << ( decl->name.length() ) << decl->name;
    326302                        }
    327303
     
    337313                                if ( ! type->get_forall().empty() ) {
    338314                                        std::list< std::string > assertionNames;
    339                                         int tcount = 0, dcount = 0, fcount = 0, vcount = 0;
    340                                         mangleName << "A";
     315                                        int dcount = 0, fcount = 0, vcount = 0, acount = 0;
     316                                        mangleName << Encoding::forall;
    341317                                        for ( Type::ForallList::iterator i = type->forall.begin(); i != type->forall.end(); ++i ) {
    342318                                                switch ( (*i)->get_kind() ) {
     
    361337                                                        (*assert)->accept( sub_mangler );
    362338                                                        assertionNames.push_back( sub_mangler.pass.mangleName.str() );
     339                                                        acount++;
    363340                                                } // for
    364341                                        } // for
    365                                         mangleName << tcount << "_" << dcount << "_" << fcount << "_" << vcount << "_";
     342                                        mangleName << dcount << "_" << fcount << "_" << vcount << "_" << acount << "_";
    366343                                        std::copy( assertionNames.begin(), assertionNames.end(), std::ostream_iterator< std::string >( mangleName, "" ) );
    367344                                        mangleName << "_";
     
    370347                                        // these qualifiers do not distinguish the outermost type of a function parameter
    371348                                        if ( type->get_const() ) {
    372                                                 mangleName << "C";
     349                                                mangleName << Encoding::qualifiers.at(Type::Const);
    373350                                        } // if
    374351                                        if ( type->get_volatile() ) {
    375                                                 mangleName << "V";
     352                                                mangleName << Encoding::qualifiers.at(Type::Volatile);
    376353                                        } // if
    377354                                        // Removed due to restrict not affecting function compatibility in GCC
     
    380357                                        // } // if
    381358                                        if ( type->get_atomic() ) {
    382                                                 mangleName << "A";
     359                                                mangleName << Encoding::qualifiers.at(Type::Atomic);
    383360                                        } // if
    384361                                }
    385362                                if ( type->get_mutex() ) {
    386                                         mangleName << "M";
     363                                        mangleName << Encoding::qualifiers.at(Type::Mutex);
    387364                                } // if
    388365                                if ( type->get_lvalue() ) {
    389366                                        // mangle based on whether the type is lvalue, so that the resolver can differentiate lvalues and rvalues
    390                                         mangleName << "L";
     367                                        mangleName << Encoding::qualifiers.at(Type::Lvalue);
    391368                                }
    392369
  • src/SymTab/Mangler.h

    r2b79a70 rcdbab55  
    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 {
     
    3340                /// Mangle ignoring generic type parameters
    3441                std::string mangleConcrete( Type* ty );
     42
     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 void_t;
     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 forall;
     60                        extern const std::string typeVariables[];
     61
     62                        extern const std::string struct_t;
     63                        extern const std::string union_t;
     64                        extern const std::string enum_t;
     65                        extern const std::string type;
     66
     67                        extern const std::string autogen;
     68                        extern const std::string intrinsic;
     69                };
    3570        } // Mangler
    3671} // SymTab
     72
     73extern "C" {
     74        char * cforall_demangle(const char *, int);
     75}
    3776
    3877// Local Variables: //
  • src/SymTab/module.mk

    r2b79a70 rcdbab55  
    1717SRC += SymTab/Indexer.cc \
    1818       SymTab/Mangler.cc \
     19       SymTab/ManglerCommon.cc \
    1920       SymTab/Validate.cc \
    2021       SymTab/FixFunction.cc \
Note: See TracChangeset for help on using the changeset viewer.