Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/SymTab/Indexer.cc

    r8884112 r1ba88a0  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 21:37:33 2015
    11 // Last Modified By : Rob Schluntz
    12 // Last Modified On : Fri Apr 22 15:25:43 2016
    13 // Update Count     : 11
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Tue Jul 12 17:47:47 2016
     13// Update Count     : 12
    1414//
    1515
     
    2121#include <unordered_set>
    2222#include <utility>
     23#include <algorithm>
    2324
    2425#include "Mangler.h"
     
    3334#include "SynTree/Initializer.h"
    3435#include "SynTree/Statement.h"
     36
     37#include "InitTweak/InitTweak.h"
    3538
    3639#define debugPrint(x) if ( doDebug ) { std::cout << x; }
     
    99102
    100103                if ( --toFree->refCount == 0 ) delete toFree;
     104        }
     105
     106        void Indexer::removeSpecialOverrides( const std::string &id, std::list< DeclarationWithType * > & out ) const {
     107                // only need to perform this step for constructors and destructors
     108                if ( ! InitTweak::isCtorDtor( id ) ) return;
     109
     110                // helpful data structure
     111                struct ValueType {
     112                        struct DeclBall {
     113                                FunctionDecl * decl;
     114                                bool isUserDefinedFunc; // properties for this particular decl
     115                                bool isDefaultFunc;
     116                                bool isCopyFunc;
     117                        };
     118                        // properties for this type
     119                        bool userDefinedFunc = false; // any user defined function found
     120                        bool userDefinedDefaultFunc = false; // user defined default ctor found
     121                        bool userDefinedCopyFunc = false; // user defined copy ctor found
     122                        std::list< DeclBall > decls;
     123
     124                        // another FunctionDecl for the current type was found - determine
     125                        // if it has special properties and update data structure accordingly
     126                        ValueType & operator+=( FunctionDecl * function ) {
     127                                bool isUserDefinedFunc = ! LinkageSpec::isOverridable( function->get_linkage() );
     128                                bool isDefaultFunc = function->get_functionType()->get_parameters().size() == 1;
     129                                bool isCopyFunc = InitTweak::isCopyConstructor( function );
     130                                decls.push_back( DeclBall{ function, isUserDefinedFunc, isDefaultFunc, isCopyFunc } );
     131                                userDefinedFunc = userDefinedFunc || isUserDefinedFunc;
     132                                userDefinedDefaultFunc = userDefinedDefaultFunc || (isUserDefinedFunc && isDefaultFunc);
     133                                userDefinedCopyFunc = userDefinedCopyFunc || (isUserDefinedFunc && isCopyFunc);
     134                                return *this;
     135                        }
     136                }; // ValueType
     137
     138                std::list< DeclarationWithType * > copy;
     139                copy.splice( copy.end(), out );
     140
     141                // organize discovered declarations by type
     142                std::unordered_map< std::string, ValueType > funcMap;
     143                for ( DeclarationWithType * decl : copy ) {
     144                        if ( FunctionDecl * function = dynamic_cast< FunctionDecl * >( decl ) ) {
     145                                std::list< DeclarationWithType * > params = function->get_functionType()->get_parameters();
     146                                assert( ! params.empty() );
     147                                funcMap[ Mangler::mangle( params.front()->get_type() ) ] += function;
     148                        } else {
     149                                out.push_back( decl );
     150                        }
     151                }
     152
     153                // if a type contains user defined ctor/dtors, then special rules trigger, which determine
     154                // the set of ctor/dtors that are seen by the requester. In particular, if the user defines
     155                // a default ctor, then the generated default ctor should never be seen, likewise for copy ctor
     156                // and dtor. If the user defines any ctor/dtor, then no generated field ctors should be seen.
     157                for ( std::pair< const std::string, ValueType > & pair : funcMap ) {
     158                        ValueType & val = pair.second;
     159                        for ( ValueType::DeclBall ball : val.decls ) {
     160                                if ( ! val.userDefinedFunc || ball.isUserDefinedFunc || (! val.userDefinedDefaultFunc && ball.isDefaultFunc) || (! val.userDefinedCopyFunc && ball.isCopyFunc) ) {
     161                                        // decl conforms to the rules described above, so it should be seen by the requester
     162                                        out.push_back( ball.decl );
     163                                }
     164                        }
     165                }
    101166        }
    102167
     
    461526                        searchTables = searchTables->base.tables;
    462527                }
     528
     529                // some special functions, e.g. constructors and destructors
     530                // remove autogenerated functions when they are defined so that
     531                // they can never be matched
     532                removeSpecialOverrides( id, out );
    463533        }
    464534
     
    520590                        const MangleTable &mangleTable = decls->second;
    521591                        for ( MangleTable::const_iterator decl = mangleTable.begin(); decl != mangleTable.end(); ++decl ) {
    522                                 // check for C decls with the same name, skipping
    523                                 // those with a compatible type (by mangleName)
     592                                // check for C decls with the same name, skipping those with a compatible type (by mangleName)
    524593                                if ( decl->second->get_linkage() == LinkageSpec::C && decl->first != mangleName ) return true;
    525594                        }
Note: See TracChangeset for help on using the changeset viewer.