Ignore:
Timestamp:
Apr 30, 2018, 11:07:21 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, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, with_gc
Children:
1a3eab8
Parents:
1da22500
Message:

Remove reference type mangling to prevent reference and non-reference overloading

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/SymTab/Mangler.cc

    r1da22500 rc0453ca3  
    3535                namespace {
    3636                        /// Mangles names to a unique C identifier
    37                         struct Mangler : public WithShortCircuiting, public WithVisitorRef<Mangler> {
     37                        struct Mangler : public WithShortCircuiting, public WithVisitorRef<Mangler>, public WithGuards {
    3838                                Mangler( bool mangleOverridable, bool typeMode, bool mangleGenericParams );
    3939                                Mangler( const Mangler & ) = delete;
     
    7070                                bool typeMode;                  ///< Produce a unique mangled name for a type
    7171                                bool mangleGenericParams;       ///< Include generic parameters in name mangling if true
     72                                bool inFunctionType = false;    ///< Include type qualifiers if false.
    7273
    7374                                void mangleDecl( DeclarationWithType *declaration );
     
    189190
    190191                        void Mangler::postvisit( ReferenceType * refType ) {
     192                                // don't print prefix (e.g. 'R') for reference types so that references and non-references do not overload.
     193                                // Further, do not print the qualifiers for a reference type (but do run printQualifers because of TypeDecls, etc.),
     194                                // by pretending every reference type is a function parameter.
     195                                GuardValue( inFunctionType );
     196                                inFunctionType = true;
    191197                                printQualifiers( refType );
    192                                 mangleName << "R";
    193198                                maybeAccept( refType->base, *visitor );
    194199                        }
     
    206211                                printQualifiers( functionType );
    207212                                mangleName << "F";
     213                                // turn on inFunctionType so that printQualifiers does not print most qualifiers for function parameters,
     214                                // since qualifiers on outermost parameter type do not differentiate function types, e.g.,
     215                                // void (*)(const int) and void (*)(int) are the same type, but void (*)(const int *) and void (*)(int *) are different
     216                                GuardValue( inFunctionType );
     217                                inFunctionType = true;
    208218                                std::list< Type* > returnTypes = getTypes( functionType->get_returnVals() );
    209219                                acceptAll( returnTypes, *visitor );
     
    304314                                // skip if not including qualifiers
    305315                                if ( typeMode ) return;
    306 
    307316                                if ( ! type->get_forall().empty() ) {
    308317                                        std::list< std::string > assertionNames;
     
    337346                                        mangleName << "_";
    338347                                } // if
    339                                 if ( type->get_const() ) {
    340                                         mangleName << "C";
    341                                 } // if
    342                                 if ( type->get_volatile() ) {
    343                                         mangleName << "V";
    344                                 } // if
     348                                if ( ! inFunctionType ) {
     349                                        // these qualifiers do not distinguish the outermost type of a function parameter
     350                                        if ( type->get_const() ) {
     351                                                mangleName << "C";
     352                                        } // if
     353                                        if ( type->get_volatile() ) {
     354                                                mangleName << "V";
     355                                        } // if
     356                                        // Removed due to restrict not affecting function compatibility in GCC
     357                                        // if ( type->get_isRestrict() ) {
     358                                        //      mangleName << "E";
     359                                        // } // if
     360                                        if ( type->get_atomic() ) {
     361                                                mangleName << "A";
     362                                        } // if
     363                                }
    345364                                if ( type->get_mutex() ) {
    346365                                        mangleName << "M";
    347366                                } // if
    348                                 // Removed due to restrict not affecting function compatibility in GCC
    349                 //              if ( type->get_isRestrict() ) {
    350                 //                      mangleName << "E";
    351                 //              } // if
    352367                                if ( type->get_lvalue() ) {
    353368                                        // mangle based on whether the type is lvalue, so that the resolver can differentiate lvalues and rvalues
    354369                                        mangleName << "L";
    355370                                }
    356                                 if ( type->get_atomic() ) {
    357                                         mangleName << "A";
    358                                 } // if
     371
     372                                if ( inFunctionType ) {
     373                                        // turn off inFunctionType so that types can be differentiated for nested qualifiers
     374                                        GuardValue( inFunctionType );
     375                                        inFunctionType = false;
     376                                }
    359377                        }
    360378                }       // namespace
Note: See TracChangeset for help on using the changeset viewer.