Changeset 64ac636 for src/InitTweak


Ignore:
Timestamp:
Mar 17, 2017, 1:14:07 PM (7 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, resolv-new, with_gc
Children:
b2f5082
Parents:
1fbab5a
Message:

fix missing line numbers in some places, including member constructor generation

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/InitTweak/FixInit.cc

    r1fbab5a r64ac636  
    232232                        void handleFirstParam( Expression * firstParam );
    233233                        template< typename... Params >
    234                         void emit( const Params &... params );
     234                        void emit( CodeLocation, const Params &... params );
    235235
    236236                        FunctionDecl * function = 0;
    237                         std::set< DeclarationWithType * > unhandled, usedUninit;
     237                        std::set< DeclarationWithType * > unhandled;
     238                        std::map< DeclarationWithType *, CodeLocation > usedUninit;
    238239                        ObjectDecl * thisParam = 0;
    239240                        bool isCtor = false; // true if current function is a constructor
     
    336337                        GenStructMemberCalls warner;
    337338                        acceptAll( translationUnit, warner );
    338 
    339                         // visitor doesn't throw so that it can collect all errors
    340                         if ( ! warner.errors.isEmpty() ) {
    341                                 throw warner.errors;
    342                         }
    343339                }
    344340
     
    940936                        ValueGuard< FunctionDecl * > oldFunction( funcDecl );
    941937                        ValueGuard< std::set< DeclarationWithType * > > oldUnhandled( unhandled );
    942                         ValueGuard< std::set< DeclarationWithType * > > oldUsedUninit( usedUninit );
     938                        ValueGuard< std::map< DeclarationWithType *, CodeLocation > > oldUsedUninit( usedUninit );
    943939                        ValueGuard< ObjectDecl * > oldThisParam( thisParam );
    944940                        ValueGuard< bool > oldIsCtor( isCtor );
    945941                        ValueGuard< StructDecl * > oldStructDecl( structDecl );
     942                        errors = SemanticError();  // clear previous errors
    946943
    947944                        // need to start with fresh sets
     
    972969                        // remove the unhandled objects from usedUninit, because a call is inserted
    973970                        // to handle them - only objects that are later constructed are used uninitialized.
    974                         std::set< DeclarationWithType * > diff;
    975                         std::set_difference( usedUninit.begin(), usedUninit.end(), unhandled.begin(), unhandled.end(), std::inserter( diff, diff.begin() ) );
    976                         for ( DeclarationWithType * member : diff ) {
    977                                 emit( "in ", CodeGen::genPrettyType( function->get_functionType(), function->get_name() ), ", field ", member->get_name(), " used before being constructed" );
     971                        std::map< DeclarationWithType *, CodeLocation > diff;
     972                        // need the comparator since usedUninit and unhandled have different types
     973                        struct comp_t {
     974                                typedef decltype(usedUninit)::value_type usedUninit_t;
     975                                typedef decltype(unhandled)::value_type unhandled_t;
     976                                bool operator()(usedUninit_t x, unhandled_t y) { return x.first < y; }
     977                                bool operator()(unhandled_t x, usedUninit_t y) { return x < y.first; }
     978                        } comp;
     979                        std::set_difference( usedUninit.begin(), usedUninit.end(), unhandled.begin(), unhandled.end(), std::inserter( diff, diff.begin() ), comp );
     980                        for ( auto p : diff ) {
     981                                DeclarationWithType * member = p.first;
     982                                CodeLocation loc = p.second;
     983                                // xxx - make error message better by also tracking the location that the object is constructed at?
     984                                emit( loc, "in ", CodeGen::genPrettyType( function->get_functionType(), function->get_name() ), ", field ", member->get_name(), " used before being constructed" );
    978985                        }
    979986
     
    10201027                                                        }
    10211028                                                } catch ( SemanticError & error ) {
    1022                                                         emit( "in ", CodeGen::genPrettyType( function->get_functionType(), function->get_name() ), ", field ", field->get_name(), " not explicitly ", isCtor ? "constructed" : "destructed",  " and no ", isCtor ? "default constructor" : "destructor", " found" );
     1029                                                        emit( funcDecl->location, "in ", CodeGen::genPrettyType( function->get_functionType(), function->get_name() ), ", field ", field->get_name(), " not explicitly ", isCtor ? "constructed" : "destructed",  " and no ", isCtor ? "default constructor" : "destructor", " found" );
    10231030                                                }
    10241031                                        }
    10251032                                }
    10261033                                leaveScope();
     1034                        }
     1035                        if (! errors.isEmpty()) {
     1036                                throw errors;
    10271037                        }
    10281038                }
     
    10791089                                                        if ( unhandled.count( memberExpr->get_member() ) ) {
    10801090                                                                // emit a warning because a member was used before it was constructed
    1081                                                                 usedUninit.insert( memberExpr->get_member() );
     1091                                                                usedUninit.insert( { memberExpr->get_member(), memberExpr->location } );
    10821092                                                        }
    10831093                                                }
     
    10891099
    10901100                template< typename Visitor, typename... Params >
    1091                 void error( Visitor & v, const Params &... params ) {
    1092                         v.errors.append( toString( params... ) );
     1101                void error( Visitor & v, CodeLocation loc, const Params &... params ) {
     1102                        SemanticError err( toString( params... ) );
     1103                        err.set_location( loc );
     1104                        v.errors.append( err );
    10931105                }
    10941106
    10951107                template< typename... Params >
    1096                 void GenStructMemberCalls::emit( const Params &... params ) {
     1108                void GenStructMemberCalls::emit( CodeLocation loc, const Params &... params ) {
    10971109                        // toggle warnings vs. errors here.
    10981110                        // warn( params... );
    1099                         error( *this, params... );
     1111                        error( *this, loc, params... );
    11001112                }
    11011113
Note: See TracChangeset for help on using the changeset viewer.