Changeset 28f3a19 for src/SymTab


Ignore:
Timestamp:
Jun 27, 2018, 3:28:41 PM (6 years ago)
Author:
Aaron Moss <a3moss@…>
Branches:
new-env, with_gc
Children:
b21c77a
Parents:
0182bfa (diff), 63238a4 (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' into with_gc

Location:
src/SymTab
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • src/SymTab/Indexer.cc

    r0182bfa r28f3a19  
    106106                if ( ! CodeGen::isCtorDtorAssign( id ) ) return;
    107107
    108                 // helpful data structure
     108                // helpful data structure to organize properties for a type
    109109                struct ValueType {
    110                         struct DeclBall {
     110                        struct DeclBall { // properties for this particular decl
    111111                                IdData decl;
    112                                 bool isUserDefinedFunc; // properties for this particular decl
    113                                 bool isDefaultCtor;
    114                                 bool isDtor;
     112                                bool isUserDefinedFunc;
    115113                                bool isCopyFunc;
    116114                        };
    117115                        // properties for this type
    118                         bool existsUserDefinedFunc = false;    // any user-defined function found
    119                         bool existsUserDefinedCtor = false;    // any user-defined constructor found
    120                         bool existsUserDefinedDtor = false;    // any user-defined destructor found
    121116                        bool existsUserDefinedCopyFunc = false;    // user-defined copy ctor found
    122                         bool existsUserDefinedDefaultCtor = false; // user-defined default ctor found
     117                        BaseSyntaxNode * deleteStmt = nullptr;     // non-null if a user-defined function is found
    123118                        std::list< DeclBall > decls;
    124119
     
    127122                        ValueType & operator+=( IdData data ) {
    128123                                DeclarationWithType * function = data.id;
    129                                 bool isUserDefinedFunc = ! LinkageSpec::isOverridable( function->get_linkage() );
    130                                 bool isDefaultCtor = InitTweak::isDefaultConstructor( function );
    131                                 bool isDtor = InitTweak::isDestructor( function );
    132                                 bool isCopyFunc = InitTweak::isCopyFunction( function, function->get_name() );
    133                                 decls.push_back( DeclBall{ data, isUserDefinedFunc, isDefaultCtor, isDtor, isCopyFunc } );
    134                                 existsUserDefinedFunc = existsUserDefinedFunc || isUserDefinedFunc;
    135                                 existsUserDefinedCtor = existsUserDefinedCtor || (isUserDefinedFunc && CodeGen::isConstructor( function->get_name() ) );
    136                                 existsUserDefinedDtor = existsUserDefinedDtor || (isUserDefinedFunc && isDtor);
     124                                bool isUserDefinedFunc = ! LinkageSpec::isOverridable( function->linkage );
     125                                bool isCopyFunc = InitTweak::isCopyFunction( function, function->name );
     126                                decls.push_back( DeclBall{ data, isUserDefinedFunc, isCopyFunc } );
    137127                                existsUserDefinedCopyFunc = existsUserDefinedCopyFunc || (isUserDefinedFunc && isCopyFunc);
    138                                 existsUserDefinedDefaultCtor = existsUserDefinedDefaultCtor || (isUserDefinedFunc && isDefaultCtor);
     128                                if ( isUserDefinedFunc && ! deleteStmt ) {
     129                                        // any user-defined function can act as an implicit delete statement for generated constructors.
     130                                        // a delete stmt should not act as an implicit delete statement.
     131                                        deleteStmt = data.id;
     132                                }
    139133                                return *this;
    140134                        }
     
    148142                for ( auto decl : copy ) {
    149143                        if ( FunctionDecl * function = dynamic_cast< FunctionDecl * >( decl.id ) ) {
    150                                 std::list< DeclarationWithType * > & params = function->get_functionType()->get_parameters();
     144                                std::list< DeclarationWithType * > & params = function->type->parameters;
    151145                                assert( ! params.empty() );
    152146                                // use base type of pointer, so that qualifiers on the pointer type aren't considered.
     
    160154
    161155                // if a type contains user defined ctor/dtor/assign, then special rules trigger, which determine
    162                 // the set of ctor/dtor/assign that are seen by the requester. In particular, if the user defines
    163                 // a default ctor, then the generated default ctor should never be seen, likewise for copy ctor
    164                 // and dtor. If the user defines any ctor/dtor, then no generated field ctors should be seen.
    165                 // If the user defines any ctor then the generated default ctor should not be seen (intrinsic default
    166                 // ctor must be overridden exactly).
     156                // the set of ctor/dtor/assign that can be used  by the requester. In particular, if the user defines
     157                // a default ctor, then the generated default ctor is unavailable, likewise for copy ctor
     158                // and dtor. If the user defines any ctor/dtor, then no generated field ctors are available.
     159                // If the user defines any ctor then the generated default ctor is unavailable (intrinsic default
     160                // ctor must be overridden exactly). If the user defines anything that looks like a copy constructor,
     161                // then the generated copy constructor is unavailable, and likewise for the assignment operator.
    167162                for ( std::pair< const std::string, ValueType > & pair : funcMap ) {
    168163                        ValueType & val = pair.second;
    169164                        for ( ValueType::DeclBall ball : val.decls ) {
    170                                 bool noUserDefinedFunc = ! val.existsUserDefinedFunc;
    171                                 bool isUserDefinedFunc = ball.isUserDefinedFunc;
    172                                 bool isAcceptableDefaultCtor = (! val.existsUserDefinedCtor || (! val.existsUserDefinedDefaultCtor && ball.decl.id->get_linkage() == LinkageSpec::Intrinsic)) && ball.isDefaultCtor; // allow default constructors only when no user-defined constructors exist, except in the case of intrinsics, which require exact overrides
    173                                 bool isAcceptableCopyFunc = ! val.existsUserDefinedCopyFunc && ball.isCopyFunc; // handles copy ctor and assignment operator
    174                                 bool isAcceptableDtor = ! val.existsUserDefinedDtor && ball.isDtor;
    175                                 if ( noUserDefinedFunc || isUserDefinedFunc || isAcceptableDefaultCtor || isAcceptableCopyFunc || isAcceptableDtor ) {
    176                                         // decl conforms to the rules described above, so it should be seen by the requester
    177                                         out.push_back( ball.decl );
     165                                bool isNotUserDefinedFunc = ! ball.isUserDefinedFunc && ball.decl.id->linkage != LinkageSpec::Intrinsic;
     166                                bool isCopyFunc = ball.isCopyFunc;
     167                                bool existsUserDefinedCopyFunc = val.existsUserDefinedCopyFunc;
     168
     169                                // only implicitly delete non-user defined functions that are not intrinsic, and are
     170                                // not copy functions (assignment or copy constructor). If a  user-defined copy function exists,
     171                                // do not pass along the non-user-defined copy functions since signatures do not have to match,
     172                                // and the generated functions will often be cheaper.
     173                                if ( isNotUserDefinedFunc ) {
     174                                        if ( isCopyFunc ) {
     175                                                // Skip over non-user-defined copy functions when there is a user-defined copy function.
     176                                                // Since their signatures do not have to be exact, deleting them is the wrong choice.
     177                                                if ( existsUserDefinedCopyFunc ) continue;
     178                                        } else {
     179                                                // delete non-user-defined non-copy functions if applicable.
     180                                                // deleteStmt will be non-null only if a user-defined function is found.
     181                                                ball.decl.deleteStmt = val.deleteStmt;
     182                                        }
    178183                                }
     184                                out.push_back( ball.decl );
    179185                        }
    180186                }
     
    471477        void Indexer::addId( DeclarationWithType * decl, Expression * baseExpr ) {
    472478                // default handling of conflicts is to raise an error
    473                 addId( decl, [decl](IdData &, const std::string & msg) { SemanticError( decl, msg ); return true; }, baseExpr );
     479                addId( decl, [decl](IdData &, const std::string & msg) { SemanticError( decl, msg ); return true; }, baseExpr, decl->isDeleted ? decl : nullptr );
    474480        }
    475481
  • src/SymTab/Mangler.cc

    r0182bfa r28f3a19  
    171171                                        "w",    // SignedInt128
    172172                                        "Uw",   // UnsignedInt128
     173                                        "x",   // Float80
     174                                        "y",   // Float128
    173175                                };
     176                                static_assert(
     177                                        sizeof(btLetter)/sizeof(btLetter[0]) == BasicType::NUMBER_OF_BASIC_TYPES,
     178                                        "Each basic type kind should have a corresponding mangler letter"
     179                                );
    174180
    175181                                printQualifiers( basicType );
     182                                assert( basicType->get_kind() < sizeof(btLetter)/sizeof(btLetter[0]) );
    176183                                mangleName << btLetter[ basicType->get_kind() ];
    177184                        }
     
    218225                                GuardValue( inFunctionType );
    219226                                inFunctionType = true;
    220                                 std::list< Type* > returnTypes = getTypes( functionType->get_returnVals() );
     227                                std::list< Type* > returnTypes = getTypes( functionType->returnVals );
    221228                                acceptAll( returnTypes, *visitor );
    222229                                mangleName << "_";
    223                                 std::list< Type* > paramTypes = getTypes( functionType->get_parameters() );
     230                                std::list< Type* > paramTypes = getTypes( functionType->parameters );
    224231                                acceptAll( paramTypes, *visitor );
    225232                                mangleName << "_";
     
    229236                                printQualifiers( refType );
    230237
    231                                 mangleName << ( refType->get_name().length() + prefix.length() ) << prefix << refType->get_name();
     238                                mangleName << ( refType->name.length() + prefix.length() ) << prefix << refType->name;
    232239
    233240                                if ( mangleGenericParams ) {
    234                                         std::list< Expression* >& params = refType->get_parameters();
     241                                        std::list< Expression* >& params = refType->parameters;
    235242                                        if ( ! params.empty() ) {
    236243                                                mangleName << "_";
    237244                                                for ( std::list< Expression* >::const_iterator param = params.begin(); param != params.end(); ++param ) {
    238245                                                        TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param );
    239                                                         assertf(paramType, "Aggregate parameters should be type expressions: %s", toString(*param).c_str());
    240                                                         maybeAccept( paramType->get_type(), *visitor );
     246                                                        assertf(paramType, "Aggregate parameters should be type expressions: %s", toCString(*param));
     247                                                        maybeAccept( paramType->type, *visitor );
    241248                                                }
    242249                                                mangleName << "_";
  • src/SymTab/Validate.cc

    r0182bfa r28f3a19  
    4949#include "CodeGen/OperatorTable.h"     // for isCtorDtor, isCtorDtorAssign
    5050#include "Common/GC.h"                 // for new_static_root, register_static_root
     51#include "ControlStruct/Mutate.h"      // for ForExprMutator
    5152#include "Common/PassVisitor.h"        // for PassVisitor, WithDeclsToAdd
    5253#include "Common/ScopedMap.h"          // for ScopedMap
     
    7778class SwitchStmt;
    7879
    79 
    8080#define debugPrint( x ) if ( doDebug ) { std::cout << x; }
    8181
     
    275275                Concurrency::applyKeywords( translationUnit );
    276276                acceptAll( translationUnit, fpd ); // must happen before autogenerateRoutines, after Concurrency::applyKeywords because uniqueIds must be set on declaration before resolution
     277                ControlStruct::hoistControlDecls( translationUnit );  // hoist initialization out of for statements; must happen before autogenerateRoutines
    277278                autogenerateRoutines( translationUnit ); // moved up, used to be below compoundLiteral - currently needs EnumAndPointerDecay
    278279                Concurrency::implementMutexFuncs( translationUnit );
Note: See TracChangeset for help on using the changeset viewer.