Changeset eba74ba for src/SymTab


Ignore:
Timestamp:
May 25, 2018, 2:51:06 PM (7 years ago)
Author:
Aaron Moss <a3moss@…>
Branches:
new-env, with_gc
Children:
cdc4d43
Parents:
3ef35bd (diff), 58e822a (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 remote-tracking branch 'origin/master' into with_gc

Location:
src/SymTab
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • src/SymTab/Indexer.cc

    r3ef35bd reba74ba  
    2626#include "Common/SemanticError.h"  // for SemanticError
    2727#include "Common/utility.h"        // for cloneAll
     28#include "GenPoly/GenPoly.h"
    2829#include "InitTweak/InitTweak.h"   // for isConstructor, isCopyFunction, isC...
    2930#include "Mangler.h"               // for Mangler
     
    377378        }
    378379
     380        bool isFunction( DeclarationWithType * decl ) {
     381                return GenPoly::getFunctionType( decl->get_type() );
     382        }
     383
     384        bool isObject( DeclarationWithType * decl ) {
     385                return ! isFunction( decl );
     386        }
     387
     388        bool isDefinition( DeclarationWithType * decl ) {
     389                if ( FunctionDecl * func = dynamic_cast< FunctionDecl * >( decl ) ) {
     390                        // a function is a definition if it has a body
     391                        return func->statements;
     392                } else {
     393                        // an object is a definition if it is not marked extern.
     394                        // both objects must be marked extern
     395                        return ! decl->get_storageClasses().is_extern;
     396                }
     397        }
     398
    379399        bool addedIdConflicts( Indexer::IdData & existing, DeclarationWithType *added, BaseSyntaxNode * deleteStmt, Indexer::ConflictFunction handleConflicts ) {
    380400                // if we're giving the same name mangling to things of different types then there is something wrong
    381                 assert( (dynamic_cast<ObjectDecl*>( added ) && dynamic_cast<ObjectDecl*>( existing.id ) )
    382                         || (dynamic_cast<FunctionDecl*>( added ) && dynamic_cast<FunctionDecl*>( existing.id ) ) );
     401                assert( (isObject( added ) && isObject( existing.id ) )
     402                        || ( isFunction( added ) && isFunction( existing.id ) ) );
    383403
    384404                if ( LinkageSpec::isOverridable( existing.id->get_linkage() ) ) {
     
    394414                        }
    395415
    396                         // typesCompatible doesn't really do the right thing here. When checking compatibility of function types,
    397                         // we should ignore outermost pointer qualifiers, except _Atomic?
    398                         FunctionDecl * newentry = dynamic_cast< FunctionDecl * >( added );
    399                         FunctionDecl * oldentry = dynamic_cast< FunctionDecl * >( existing.id );
    400                         if ( newentry && oldentry ) {
    401                                 if ( newentry->get_statements() && oldentry->get_statements() ) {
     416                        if ( isDefinition( added ) && isDefinition( existing.id ) ) {
     417                                if ( isFunction( added ) ) {
    402418                                        return handleConflicts( existing, "duplicate function definition for " );
    403                                 } // if
    404                         } else {
    405                                 // two objects with the same mangled name defined in the same scope.
    406                                 // both objects must be marked extern or both must be intrinsic for this to be okay
    407                                 // xxx - perhaps it's actually if either is intrinsic then this is okay?
    408                                 //       might also need to be same storage class?
    409                                 ObjectDecl * newobj = dynamic_cast< ObjectDecl * >( added );
    410                                 ObjectDecl * oldobj = dynamic_cast< ObjectDecl * >( existing.id );
    411                                 if ( ! newobj->get_storageClasses().is_extern && ! oldobj->get_storageClasses().is_extern ) {
     419                                } else {
    412420                                        return handleConflicts( existing, "duplicate object definition for " );
    413421                                } // if
  • src/SymTab/Mangler.cc

    r3ef35bd reba74ba  
    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;
     
    5555                                void postvisit( EnumInstType * aggregateUseType );
    5656                                void postvisit( TypeInstType * aggregateUseType );
     57                                void postvisit( TraitInstType * inst );
    5758                                void postvisit( TupleType * tupleType );
    5859                                void postvisit( VarArgsType * varArgsType );
     
    7071                                bool typeMode;                  ///< Produce a unique mangled name for a type
    7172                                bool mangleGenericParams;       ///< Include generic parameters in name mangling if true
     73                                bool inFunctionType = false;    ///< Include type qualifiers if false.
    7274
    7375                                void mangleDecl( DeclarationWithType *declaration );
     
    177179                        void Mangler::postvisit( PointerType * pointerType ) {
    178180                                printQualifiers( pointerType );
    179                                 mangleName << "P";
     181                                // mangle void (*f)() and void f() to the same name to prevent overloading on functions and function pointers
     182                                if ( ! dynamic_cast<FunctionType *>( pointerType->base ) ) mangleName << "P";
    180183                                maybeAccept( pointerType->base, *visitor );
    181184                        }
     
    189192
    190193                        void Mangler::postvisit( ReferenceType * refType ) {
     194                                // don't print prefix (e.g. 'R') for reference types so that references and non-references do not overload.
     195                                // Further, do not print the qualifiers for a reference type (but do run printQualifers because of TypeDecls, etc.),
     196                                // by pretending every reference type is a function parameter.
     197                                GuardValue( inFunctionType );
     198                                inFunctionType = true;
    191199                                printQualifiers( refType );
    192                                 mangleName << "R";
    193200                                maybeAccept( refType->base, *visitor );
    194201                        }
     
    206213                                printQualifiers( functionType );
    207214                                mangleName << "F";
     215                                // turn on inFunctionType so that printQualifiers does not print most qualifiers for function parameters,
     216                                // since qualifiers on outermost parameter type do not differentiate function types, e.g.,
     217                                // void (*)(const int) and void (*)(int) are the same type, but void (*)(const int *) and void (*)(int *) are different
     218                                GuardValue( inFunctionType );
     219                                inFunctionType = true;
    208220                                std::list< Type* > returnTypes = getTypes( functionType->get_returnVals() );
    209221                                acceptAll( returnTypes, *visitor );
     
    270282                        }
    271283
     284                        void Mangler::postvisit( TraitInstType * inst ) {
     285                                printQualifiers( inst );
     286                                mangleName << "_Y" << inst->name << "_";
     287                        }
     288
    272289                        void Mangler::postvisit( TupleType * tupleType ) {
    273290                                printQualifiers( tupleType );
     
    304321                                // skip if not including qualifiers
    305322                                if ( typeMode ) return;
    306 
    307323                                if ( ! type->get_forall().empty() ) {
    308324                                        std::list< std::string > assertionNames;
     
    337353                                        mangleName << "_";
    338354                                } // if
    339                                 if ( type->get_const() ) {
    340                                         mangleName << "C";
    341                                 } // if
    342                                 if ( type->get_volatile() ) {
    343                                         mangleName << "V";
    344                                 } // if
     355                                if ( ! inFunctionType ) {
     356                                        // these qualifiers do not distinguish the outermost type of a function parameter
     357                                        if ( type->get_const() ) {
     358                                                mangleName << "C";
     359                                        } // if
     360                                        if ( type->get_volatile() ) {
     361                                                mangleName << "V";
     362                                        } // if
     363                                        // Removed due to restrict not affecting function compatibility in GCC
     364                                        // if ( type->get_isRestrict() ) {
     365                                        //      mangleName << "E";
     366                                        // } // if
     367                                        if ( type->get_atomic() ) {
     368                                                mangleName << "A";
     369                                        } // if
     370                                }
    345371                                if ( type->get_mutex() ) {
    346372                                        mangleName << "M";
    347373                                } // if
    348                                 // Removed due to restrict not affecting function compatibility in GCC
    349                 //              if ( type->get_isRestrict() ) {
    350                 //                      mangleName << "E";
    351                 //              } // if
    352374                                if ( type->get_lvalue() ) {
    353375                                        // mangle based on whether the type is lvalue, so that the resolver can differentiate lvalues and rvalues
    354376                                        mangleName << "L";
    355377                                }
    356                                 if ( type->get_atomic() ) {
    357                                         mangleName << "A";
    358                                 } // if
     378
     379                                if ( inFunctionType ) {
     380                                        // turn off inFunctionType so that types can be differentiated for nested qualifiers
     381                                        GuardValue( inFunctionType );
     382                                        inFunctionType = false;
     383                                }
    359384                        }
    360385                }       // namespace
Note: See TracChangeset for help on using the changeset viewer.