Changeset 3403534 for src/SymTab


Ignore:
Timestamp:
Sep 4, 2016, 10:34:35 PM (10 years ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, 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, stuck-waitfor-destruct, with_gc
Children:
f04a8b81
Parents:
28307be (diff), b16898e (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' of plg2:software/cfa/cfa-cc

Location:
src/SymTab
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • src/SymTab/Autogen.cc

    r28307be r3403534  
    6464
    6565        template< typename OutputIterator >
    66         void makeUnionFieldsAssignment( ObjectDecl *srcParam, ObjectDecl *dstParam, UnionInstType *unionType, OutputIterator out ) {
     66        void makeUnionFieldsAssignment( ObjectDecl *srcParam, ObjectDecl *dstParam, OutputIterator out ) {
    6767                UntypedExpr *copy = new UntypedExpr( new NameExpr( "__builtin_memcpy" ) );
    6868                copy->get_args().push_back( new VariableExpr( dstParam ) );
     
    413413                dtorDecl->fixUniqueId();
    414414
    415                 makeUnionFieldsAssignment( srcParam, dstParam, cloneWithParams( refType, unionParams ), back_inserter( assignDecl->get_statements()->get_kids() ) );
    416                 if ( isDynamicLayout ) makeUnionFieldsAssignment( srcParam, returnVal, cloneWithParams( refType, unionParams ), back_inserter( assignDecl->get_statements()->get_kids() ) );
     415                makeUnionFieldsAssignment( srcParam, dstParam, back_inserter( assignDecl->get_statements()->get_kids() ) );
     416                if ( isDynamicLayout ) makeUnionFieldsAssignment( srcParam, returnVal, back_inserter( assignDecl->get_statements()->get_kids() ) );
    417417                else assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
    418418
     
    434434                                ctor->fixUniqueId();
    435435
    436                                 makeUnionFieldsAssignment( srcParam, dstParam, cloneWithParams( refType, unionParams ), back_inserter( ctor->get_statements()->get_kids() ) );
     436                                makeUnionFieldsAssignment( srcParam, dstParam, back_inserter( ctor->get_statements()->get_kids() ) );
    437437                                memCtors.push_back( ctor );
    438438                                // only generate a ctor for the first field
  • src/SymTab/Autogen.h

    r28307be r3403534  
    102102                }
    103103
    104                 ObjectDecl *index = new ObjectDecl( indexName.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), NULL );
    105 
    106                 UntypedExpr *init = new UntypedExpr( new NameExpr( "?=?" ) );
    107                 init->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) );
    108                 init->get_args().push_back( begin );
    109                 index->set_init( new SingleInit( init, std::list<Expression*>() ) );
     104                ObjectDecl *index = new ObjectDecl( indexName.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), new SingleInit( begin, std::list<Expression*>() ) );
    110105
    111106                UntypedExpr *cond = new UntypedExpr( cmp );
  • src/SymTab/Indexer.cc

    r28307be r3403534  
    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
  • src/SymTab/Indexer.h

    r28307be r3403534  
    128128                static void deleteRef( Impl *toFree );
    129129
     130                // Removes matching autogenerated constructors and destructors
     131                // so that they will not be selected
     132                // void removeSpecialOverrides( FunctionDecl *decl );
     133                void removeSpecialOverrides( const std::string &id, std::list< DeclarationWithType * > & out ) const;
     134
    130135                /// Ensures that tables variable is writable (i.e. allocated, uniquely owned by this Indexer, and at the current scope)
    131136                void makeWritable();
  • src/SymTab/Validate.cc

    r28307be r3403534  
    8686
    8787        /// Replaces enum types by int, and function or array types in function parameter and return lists by appropriate pointers.
    88         class Pass1 : public Visitor {
     88        class EnumAndPointerDecayPass : public Visitor {
    8989                typedef Visitor Parent;
    9090                virtual void visit( EnumDecl *aggregateDecl );
     
    189189
    190190        void validate( std::list< Declaration * > &translationUnit, bool doDebug ) {
    191                 Pass1 pass1;
     191                EnumAndPointerDecayPass epc;
    192192                Pass2 pass2( doDebug, 0 );
    193193                Pass3 pass3( 0 );
     
    196196                EliminateTypedef::eliminateTypedef( translationUnit );
    197197                HoistStruct::hoistStruct( translationUnit );
    198                 autogenerateRoutines( translationUnit ); // moved up, used to be below compoundLiteral - currently needs Pass1
    199                 acceptAll( translationUnit, pass1 );
     198                autogenerateRoutines( translationUnit ); // moved up, used to be below compoundLiteral - currently needs EnumAndPointerDecayPass
     199                acceptAll( translationUnit, epc );
    200200                acceptAll( translationUnit, pass2 );
    201201                ReturnChecker::checkFunctionReturns( translationUnit );
     
    206206
    207207        void validateType( Type *type, const Indexer *indexer ) {
    208                 Pass1 pass1;
     208                EnumAndPointerDecayPass epc;
    209209                Pass2 pass2( false, indexer );
    210210                Pass3 pass3( indexer );
    211                 type->accept( pass1 );
     211                type->accept( epc );
    212212                type->accept( pass2 );
    213213                type->accept( pass3 );
     
    272272        }
    273273
    274         void Pass1::visit( EnumDecl *enumDecl ) {
     274        void EnumAndPointerDecayPass::visit( EnumDecl *enumDecl ) {
    275275                // Set the type of each member of the enumeration to be EnumConstant
    276276                for ( std::list< Declaration * >::iterator i = enumDecl->get_members().begin(); i != enumDecl->get_members().end(); ++i ) {
     
    296296                                DWTIterator j = i;
    297297                                ++i;
     298                                delete *j;
    298299                                dwts.erase( j );
    299300                                if ( i != end ) {
     
    313314        }
    314315
    315         void Pass1::visit( FunctionType *func ) {
     316        void EnumAndPointerDecayPass::visit( FunctionType *func ) {
    316317                // Fix up parameters and return types
    317318                fixFunctionList( func->get_parameters(), func );
Note: See TracChangeset for help on using the changeset viewer.